From 045c7279aace10c30aa64f025d6566eef61ed9b6 Mon Sep 17 00:00:00 2001 From: Jon Chery Date: Wed, 22 Jul 2026 22:02:09 +0000 Subject: [PATCH] docs(P28-38): create 11 phase plans for v1.8 ---ci--- project: acdl phase: 28-38 milestone: v1.8 status: plan ---/ci--- 11 phase plans created covering 24 requirements (REQ-76..99): P28: adapter WAF + resolver outputs (P1-4,5,7) P29: SSM KMS + invoke policy (P1-3,6) P30: run-platform isolation + API portability + S1 (P1-8,9,S1) P31: encryption-by-default + per-stack CMK P32: deletion-protection-by-default + L2 feature flag P33: uptime-kuma primitive + pipeline stage P34: decommission alias + CMDB validation P35: module engineering standards P36: schemas/adapters/pipelines READMEs P37: verify (4-layer) P38: review-audit-complete --- .ciagent/PLAN.md | 247 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 217 insertions(+), 30 deletions(-) diff --git a/.ciagent/PLAN.md b/.ciagent/PLAN.md index 2b165d6..e452b00 100644 --- a/.ciagent/PLAN.md +++ b/.ciagent/PLAN.md @@ -1,41 +1,228 @@ --- -phase: 16 -name: v1.2-capstone-e2e -milestone: v1.2 -requirements: [REQ-35] -type: feat/verify -branch: phase/16-v1.2-capstone-e2e +phase: 28-38 +name: v1.8-p1-remediation-uptime-standards-encryption-decommission-docs +milestone: v1.8 +requirements: [REQ-76, REQ-77, REQ-78, REQ-79, REQ-80, REQ-81, REQ-82, REQ-83, REQ-84, REQ-85, REQ-86, REQ-87, REQ-88, REQ-89, REQ-90, REQ-91, REQ-92, REQ-93, REQ-94, REQ-95, REQ-96, REQ-97, REQ-98, REQ-99] +type: fix/feat/docs --- -# Phase 16 — v1.2-capstone-e2e (v1.2) PLAN +# ACDL v1.8 — Phase Plans -## Goal +> Milestone: v1.8. Planner: ci-planner. Status: active. +> 11 phases (28–38), 24 requirements (REQ-76..99). -End-to-end verification of the v1.2 platform: consumer commit → pipeline → -`terraform apply` (dev) → live ECS service → evidence event → timeline. The -`terraform apply` is blocked by the IAM P0 (Phase 15); Phase 16 ships the -capstone verification of everything *up to* the apply + documents the -operator's unblock step. After the operator pushes the policy, the apply + -HTTP 200 check complete REQ-33/35. +## Phase 28 — adapter-waf-and-resolver-outputs -## Tasks +**Requirements:** REQ-76 (WAF nested rules + default_action), REQ-77 (L2 outputs resolution) +**Personas:** platform-engineer (lead), backend-engineer +**Type:** fix -### T-16.1 — Capstone verify script -`scripts/verify_phase16.sh` runs the full v1.2 platform flow (consumer -content → contract → IR → adapter → terraform validate + plan) + verifies -the v1.1 regression + the NFR improvements (run_platform.sh, IAM policy -expansion, P1-1 redaction) + the documentation (README accuracy). The -`terraform apply` + HTTP 200 check are documented as the operator's -post-unblock step. +### Tasks (Wave 1 — sequential): -### T-16.2 — Capstone evidence event -Write a `MILESTONE_CAPSTONE_VERIFIED` evidence event to the outbox (the -v1.2 platform is verified up to the IAM-blocked apply). +1. **platform-engineer:** Fix WAF `rules` emission in `adapters/terraform/adapter.py:346-348` — replace `rules = {_value_expr(...)}` with nested `rules { ... }` block emission per rule. Read `inputs.get("default_action")` (line 334) and emit `allow {}` / `block {}` based on input (default `allow` if absent). +2. **backend-engineer:** Implement L2 composition `outputs[]` processing in `core/contract_resolver.py` `resolve_l2()` — after building `resources` (line 232), parse `composition.get("outputs", [])`, resolve source via `child_outputs`, build `stack_instance["outputs"]` dict. +3. **platform-engineer:** Extend `adapter.py` `adapt()` to emit `output "" { value = }` blocks from `stack_instance.get("outputs", {})`. +4. **platform-engineer:** Add tests to `tests/test_adapter.py` (WAF custom rules, default_action block, output blocks) + `tests/test_contract_resolver.py` (L2 outputs for static-assets). -### T-16.3 — Phase 16 README update -Update README to reflect the v1.2 status (Phase 15 partial, Phase 16 -capstone, the IAM unblock step). +### Must-haves: +- WAF with custom rules emits `rules {` blocks, not `rules = [` +- WAF `default_action: block` emits `block {}` +- L2 resolution yields `stack.outputs.*` +- Adapter emits `output` blocks +- `pytest` passes (275 → ~285) -## Ship +--- -Merge → `main` (--no-ff). Tag `v1.2.6`. \ No newline at end of file +## Phase 29 — ssm-kms-and-invoke-policy + +**Requirements:** REQ-78 (SSM fail-loud), REQ-79 (Terraform-rendered invoke policy) +**Personas:** backend-engineer (lead), lambda-engineer, security-engineer +**Type:** fix + +### Tasks (Wave 1): + +1. **backend-engineer:** Change `core/output_publisher.py:54-55` `_kms_key_id()` — raise `RuntimeError` when `ACDL_KMS_KEY_ID` unset; add `ACDL_ALLOW_DEFAULT_KMS=1` escape hatch. +2. **lambda-engineer:** Convert `terraform/platform/consumer_invoke_policy.json` to Terraform-rendered template — add `terraform/platform/variables.tf` with `data "aws_caller_identity" "current" {}` + `templatestring` or `replace()` for account ID injection. +3. **backend-engineer:** Add `tests/test_output_publisher.py` cases: `test_kms_unset_raises`, `test_kms_unset_allow_default_kms`. Add `tests/test_invoke_policy.py` asserting rendered policy has no `000000000000`. + +### Must-haves: +- SSM raises RuntimeError without CMK; escape hatch works +- Rendered invoke policy has live account ID +- `pytest` passes (~290) + +--- + +## Phase 30 — run-platform-isolation-and-api-portability + +**Requirements:** REQ-80 (temp dir), REQ-81 (forge-agnostic URLs), REQ-82 (static-key override) +**Personas:** backend-engineer (lead), lambda-engineer +**Type:** fix + +### Tasks (Wave 1 — parallel): + +1. **backend-engineer:** Change `scripts/run_platform.sh:122` adapter target from `terraform/spike` to `$WORK/tf`. Update all downstream references. Remove committed `terraform/spike/*.tf`. Update `tests/test_pipeline.py`. Update deploy.yml artifact upload path. +2. **lambda-engineer:** Add `_github_api_base()` + `_forge_type()` to `core/lambda/contract_ingestor.py`. Replace hardcoded URLs at lines 109, 149, 163. Add `tests/test_contract_ingestor.py` Gitea base URL test. +3. **backend-engineer:** Restructure `configure-aws-credentials` step in both deploy workflows (byte-identical) — single conditional step with `access-key`/`secret-key` inputs when static key present. Update `tests/test_pipeline_contract.py`. + +### Must-haves: +- `run_platform.sh --check-only` writes to temp dir +- `contract_ingestor.py` uses `GITHUB_API_BASE` +- Deploy workflow static-key override wired +- Both deploy workflows byte-identical +- `pytest` passes (~295) + +--- + +## Phase 31 — encryption-by-default-and-per-stack-cmk + +**Requirements:** REQ-83 (kms-key primitive), REQ-84 (encryption NFRs on all primitives), REQ-85 (L2 CMK wiring) +**Personas:** platform-engineer (lead), security-engineer +**Type:** feat + +### Tasks (Wave 1 — kms-key primitive + adapter): +1. **platform-engineer:** Create `modules/l1/kms-key/` with `interface.json` (type `aws:kms:key`, inputs: description/region/deletion_window_days, outputs: kms_key_arn/kms_key_id, NFRs: enable_rotation default true, deletion_protection default true) + `instance.json` + `README.md` + `examples/`. +2. **platform-engineer:** Add `aws:kms:key → aws_kms_key` + `aws:kms:alias → aws_kms_alias` to adapter TYPE_MAP. Emit `enable_key_rotation = true` + alias. + +### Tasks (Wave 2 — encryption NFRs on all primitives, after Wave 1): +3. **platform-engineer:** Add `encryption_enabled` NFR (default true) + `kms_key_arn` input to every L1 `interface.json` (s3, rds, ecr, ecs-service, ecs-cluster, alb, cloudfront, waf, vpc, iam-role). Update adapter to emit encryption blocks referencing the CMK when `kms_key_arn` is provided; managed KMS fallback with stderr warning when not. +4. **platform-engineer:** Update both L2 `composition.json` files — add `kms-key` child + wires connecting `kms_key_arn` output to each child's `kms_key_arn` input. +5. **platform-engineer:** Add `tests/test_encryption.py` — assert every primitive has encryption NFRs; assert adapter emits encryption blocks; assert L2 wires CMK; assert `enable_key_rotation = true`. + +### Must-haves: +- kms-key primitive exists + registered +- All primitives have `encryption_enabled` NFR + `kms_key_arn` input +- L2 modules wire per-stack CMK +- Adapter emits encryption blocks +- `pytest` passes (~310) + +--- + +## Phase 32 — deletion-protection-by-default-and-l2-feature-flag + +**Requirements:** REQ-86 (deletion_protection NFR on all primitives), REQ-87 (L2 feature flag) +**Personas:** platform-engineer (lead), backend-engineer +**Type:** feat + +### Tasks (Wave 1): +1. **platform-engineer:** Add `deletion_protection` NFR (boolean, default true) to every L1 `interface.json` (rds already has it). Update adapter to emit `lifecycle { prevent_destroy = true }` when NFR is true; omit when false. RDS gets BOTH `deletion_protection` arg + `prevent_destroy` lifecycle. +2. **backend-engineer:** Add `features` object support to `schemas/stack.schema.json` (optional `features.deletion_protection`). Update `core/contract_resolver.py` `resolve_l2()` to propagate `features.deletion_protection` to each child's `deletion_protection` NFR. Add `inputs.deletion_protection` to `schemas/contract.schema.json` (optional boolean). +3. **platform-engineer:** Add `tests/test_deletion_protection.py` — assert every primitive has the NFR; assert adapter emits `prevent_destroy`; assert L2 feature flag propagation. + +### Must-haves: +- Every primitive has `deletion_protection` NFR (default true) +- Adapter emits `prevent_destroy = true` when true +- L2 feature flag propagates +- `pytest` passes (~320) + +--- + +## Phase 33 — uptime-kuma-primitive + +**Requirements:** REQ-88 (uptime primitive), REQ-89 (deployed by default after L2), REQ-90 (feature flag), REQ-91 (pipeline stage) +**Personas:** platform-engineer (lead), backend-engineer +**Type:** feat + +### Tasks (Wave 1 — primitive + adapter): +1. **platform-engineer:** Create `modules/l1/uptime/` with `interface.json` (type `aws:ecs:uptime-service`, inputs: container_image/region/monitored_endpoints/static_checks/alert_channels/feature_flag_enabled/cpu/memory, outputs: uptime_url/service_arn/task_definition_arn, NFRs: deletion_protection/encryption_enabled) + `instance.json` + `README.md` + `examples/simple.yaml` + `examples/complex.yaml`. +2. **platform-engineer:** Add `aws:ecs:uptime-service` to adapter TYPE_MAP. Emit ECS Fargate task + service + ALB + listener + EFS volume + CloudWatch log group. When `feature_flag_enabled=false`, emit NO resources. Register in `registry.json`. + +### Tasks (Wave 2 — pipeline + script, after Wave 1): +3. **backend-engineer:** Add `deploy-uptime` stage to `pipelines/deploy.yaml` (after `publish-outputs`). Update both deploy workflows (byte-identical) with the stage. Add `scripts/seed_uptime_monitors.py` for post-deploy monitor seeding via uptime-kuma API. +4. **backend-engineer:** Update `scripts/run_platform.sh` — add `deploy-uptime` step: read L2 stack outputs, construct synthetic uptime contract with `monitored_endpoints` from outputs, run second terraform apply with separate state (`$WORK/uptime-tf/`), publish uptime URL via PR comment. Skip when `inputs.uptime_enabled=false`. +5. **backend-engineer:** Add `tests/test_uptime_primitive.py` — validate interface; assert adapter emits ECS service when flag=true; assert no resources when flag=false; assert `deploy-uptime` stage in pipeline contract. + +### Must-haves: +- Uptime primitive exists with feature flag + alert channels +- Deployed by default after L2 (separate state) +- Uptime URL published via PR comment +- Feature flag disables deployment +- `deploy-uptime` stage in deploy contract + byte-identical workflows +- `pytest` passes (~335) + +--- + +## Phase 34 — decommission-alias-and-cmdb-validation + +**Requirements:** REQ-92 (decommission mode), REQ-93 (CMDB validation), REQ-94 (consumer docs) +**Personas:** backend-engineer (lead), lambda-engineer, security-engineer +**Type:** feat + +### Tasks (Wave 1 — CMDB + Lambda, parallel): +1. **lambda-engineer:** Add `acdl-change-requests` DynamoDB table to `terraform/platform/main.tf` (PK changeRequestId, SK submittedAt, SSE via CMK, PITR). Add `validate_change_request` action to `core/lambda/contract_ingestor.py` — query table, assert status=approved + consumerRepo match, return CR details or 403. +2. **backend-engineer:** Add `decommission_transform(stack_instance)` to `core/contract_resolver.py` — zero all counts (desired_count=0 for ECS, etc.). + +### Tasks (Wave 2 — pipeline + docs, after Wave 1): +3. **backend-engineer:** Add `mode: decommission` to deploy workflow inputs. Add decommission stages to `pipelines/deploy.yaml`: validate-change-request → disable-deletion-protection (HITL SRE gate via GitHub environment) → zero-counts (second HITL SRE gate) → confirm-decommission. Update both deploy workflows (byte-identical). +4. **backend-engineer:** Update `docs/CONSUMER_GUIDE.md` with "Decommissioning a stack" section (request CR, trigger decommission, HITL gates, what happens). +5. **backend-engineer:** Add `tests/test_decommission.py` — assert `decommission_transform` zeroes counts; assert `validate_change_request` rejects invalid CRs; assert decommission stages in pipeline contract. + +### Must-haves: +- Decommission mode on existing deploy pipeline +- 2-step with HITL SRE gates +- CR ID validated against DynamoDB CMDB +- Documented in consumer guide +- `pytest` passes (~345) + +--- + +## Phase 35 — module-engineering-standards + +**Requirements:** REQ-95 (STANDARDS.md), REQ-96 (catalog fix + template update) +**Personas:** lead-developer (lead), platform-engineer, backend-engineer +**Type:** docs + refactor + +### Tasks (Wave 1): +1. **lead-developer:** Author `modules/STANDARDS.md` — comprehensive L1+L2 authoring + review standards (scanned from current modules per RESEARCH TARGET 6): required files, interface schema, input/output/NFR conventions, encryption + deletion protection as mandatory NFRs, naming, multi-resource pattern, adapter extension pattern, code review checklist. +2. **lead-developer:** Fix `modules/README.md` catalog index — add rds + uptime + kms-key to Primitives table. Update `modules/README-TEMPLATE.md` — add `## NFRs` section. +3. **backend-engineer:** Add `tests/test_module_standards.py` — automated enforcement: every L1 has `deletion_protection` + `encryption_enabled` NFRs; every L2 has valid structure; every module registered; every module has README + examples. + +### Must-haves: +- `modules/STANDARDS.md` exists with L1+L2 standards +- Catalog index includes all primitives +- Template has NFRs section +- Automated standards test passes +- `pytest` passes (~355) + +--- + +## Phase 36 — schemas-adapters-pipelines-readmes + +**Requirements:** REQ-97 (schemas README), REQ-98 (pipelines README), REQ-99 (adapters README) +**Personas:** lead-developer (lead), backend-engineer, platform-engineer +**Type:** docs + +### Tasks (Wave 1 — parallel): +1. **lead-developer:** Author `schemas/README.md` — how to write schemas, wire into platform, test in CI, dependencies, existing catalog. +2. **lead-developer:** Author `pipelines/README.md` — how to write pipeline contracts, wire into workflows, test, dependencies, catalog. +3. **lead-developer:** Author `adapters/README.md` — how to write adapters, wire into platform, test, dependencies, catalog. +4. **backend-engineer:** Add `tests/test_docs_coverage.py` — assert all 3 READMEs exist + contain required sections. + +### Must-haves: +- All 3 READMEs exist with comprehensive documentation +- CI validates presence +- `pytest` passes (~358) + +--- + +## Phase 37 — verify + +**Personas:** lead-developer (lead), all personas +**Type:** verify + +### Tasks: +1. Structural: all new files present. +2. Behavioral: `pytest` passes (~358); `run_ci.sh` exits 0; `run_platform.sh --check-only` exits 0. +3. Security: no secrets; CMK enforced; no placeholder account IDs; deletion protection on by default. +4. Quality: each P1 fix + each new feature has a dedicated test. + +--- + +## Phase 38 — review-audit-complete + +**Personas:** lead-developer (lead), all personas +**Type:** review + audit + complete + +### Tasks: +1. Review: 0 new P0/P1; all P1-3..P1-9 + S1 resolved; 3 new requirements delivered. +2. Audit: reconstruction, file discipline, branch hygiene, commit discipline. +3. Complete: update REQUIREMENTS.md (REQ-76..99), ROADMAP.md, PROJECT.md. Tag `v1.8.0`. Update floating `v1.8` + `v1` tags. Bump `uses:` to `@v1.8`. \ No newline at end of file