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
This commit is contained in:
Jon Chery
2026-07-22 22:02:09 +00:00
parent 7f1eff622d
commit 045c7279aa
+217 -30
View File
@@ -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 (2838), 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 "<outName>" { value = <ref> }` 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`.
## 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`.