Phase 0 (pre-execution) complete. All pre-execution stages shipped: SPECIFY -> CLARIFY -> RESEARCH -> IDEATE -> PLAN -> GRILL. Established v1.14 NFR Refinement milestone (20 execution phases + 1 final). NFR milestone — final patch IS the release. Tags on v1.13.x line: v1.13.3 (this phase) -> v1.13.24 (P21 = milestone release). 6 grill binding decisions (G-101..G-106) applied to PLAN.md. 1 escalation (E-001) auto-resolved at full autonomy (D-101). ---ci--- project: acdl phase: 0 milestone: v1.14 status: complete ---/ci---
114 KiB
ACDL — Roadmap
Overview
- v1.0 (demo): complete — tag
v1.1.0, 2026-07-21. All 5 phases shipped + audited PASS. - v1.1 (complete): architecture finalization + v1 spike. 5 phases (06–10). Tag
v1.2.0, 2026-07-21. All 5 phases shipped + verified; review READY TO SHIP (0 P0); audit CLEAN. Gitea release id 202. - v1.2 (complete): platform hardening + first real consumer deployment. 6 phases (11–16). Tag
v1.3.0, 2026-07-21. All 6 phases shipped + verified; review READY TO SHIP (1 P0 operator action, 1 P1 deferred); audit CLEAN. - v1.3 (complete): module documentation + thin-composition removal. The L2 composition layer is removed; module READMEs are built out. Tag
v1.3.2. - v1.4 (complete): central pipeline contract + shell reproducibility + output streaming. A declarative pipeline contract (
schemas/pipeline.schema.json+pipelines/ci.yaml) binds the Gitea and GitHub workflows to a single source of truth.scripts/run_ci.shmirrors the CI pipeline locally.scripts/run_platform.shstreams terraform/checkov output by default. - v1.5 (complete, tag
v1.5.0): consumer happy path + zero-trust docs + reusable deploy workflow. README rewritten so the consumer model is unambiguous (consumer owns only contract + app code; the rest is the platform source). Platform-flow + consumer-guide diagrams converted to mermaid. Legacy surface + implementation nomenclature removed from docs. Credentials section rewritten for zero-trust OIDC + ABAC (with a static-key override + daily rotation). A genericdocs/CONSUMER_GUIDE.md(all L2 modules, versioneduses:, consumer-scoped prereqs, run-time platform fetch) replaces the module-specific guide. A byte-identical reusabledeploy.ymlworkflow (Gitea + GitHub) implementspipelines/deploy.yamland is invoked by consumer repos via a versioned tag. - v1.6 (complete, tag
v1.6.0): consumer-facing docs restructure + terminology normalization + environments concept.docs/becomes a Jekyll-style GitHub Pages site.acdl_platform/is renamed tocore/. L2 → "modules", L1 → "primitives", "composition" → "pattern" in prose. README restructured: Features + Roadmap (no internal status), repository roles restated (consumer = app code + contracts + CI definitions), mermaid fixed (visible text, security-checks + infrastructure-apply stages, no tool names), credentials section minus go-gitea/waivers. Platform-managed environments concept + a minimal onboarding scaffold..ciagent/+.gitea/references removed from all consumer-facing docs. - v1.7 (complete, tag
v1.7.0): production platform + contract ingestion + pipeline maturation. Renamestatic-assets→static-assets(D-048 — incl..ciagent/historical narrative). Authorcloudfront+wafprimitives; augmentstatic-assetsto a production-ready S3 + CloudFront (OAC) + WAF stack (D-049). Tagging-standard enforcement (Checkov custom rule, D-043 closure, D-054). Wiz adapter stub (D-052) + Kyverno K8s-native adapter (D-053). Platform Lambda + DynamoDBacdl-contractstable for contract ingestion (D-051) + cross-account IAM. Deploy outputs via SSM SecureString + GitHub PR comment (D-050). Uniform error reporting via the Lambdareport_erroraction → GitHub issue on the platform repo (D-055); Gitea excluded. Stage comments after every successful pipeline stage. Three platform pipelines (platform-test unit+integration, primitives-plan, patterns-plan). Release job with semver + MAJOR.MINOR/MAJOR tag maintenance (D-057).uses:/ref:bumped to@v1.6; floatingv1.6+v1tags created in Phase 22. Remove the legacy consumer-repos directory (a v1.2 artifact, removed in v1.7); add validated per-module examples (modules/<name>/examples/, D-058) including a new RDS primitive demonstrating multi-engine variation (D-059). - v1.8 (complete, tag
v1.8.0): P1 remediation + uptime monitoring + engineering standards + encryption/deletion-protection by default + decommission alias + path documentation. Clears 8 pending P1 issues (P1-3..P1-9 + S1). Adds per-stack CMK + encryption-by-default for all primitives. Adds deletion-protection-by-default + L2 feature flag. Adds uptime-kuma primitive (ECS Fargate, deployed by default after L2, separate state, feature flag, alert channels). Adds decommission mode (2-step pipeline with HITL SRE gates + CMDB-validated change request). Addsmodules/STANDARDS.md(L1+L2 authoring + review standards). Addsschemas/README.md,pipelines/README.md,adapters/README.md. - v1.9.1 (complete, tag
v1.9.1): leadership presentation decks. Two leadership-facing presentation decks (How the Platform Works + The Developer Experience) for senior leadership (CTO, Head of Cloud, Head of Infrastructure, Head of DevOps). Each deck has a full markdown source of truth (with speaker notes + mermaid diagrams) and a lean Marp deck (no speaker notes, embedded PNG diagrams). A README documents the 3-step slide creation process (full markdown → Marp synthesis → PPTX export). Docs-only NFR patch. - v1.9.2 (complete, tag
v1.9.2): S&P Global Energy theme for presentation decks. Applies the S&P Global Energy brand visual identity (red-core #D6002A, grey-90 #1B1B1B, Akkurat Pro font) to both Marp decks. Title headers changed to full platform name. Footer 'Confidential' → 'Internal'. Title slide subtitle removed. Last DX slide renamed to 'The Desired Outcomes'. Docs-only NFR patch. - v1.9.3 (complete, tag
v1.9.3): rendered presentation decks. HTML renderings of both Marp decks committed to docs/presentations/ (self-contained, base64-embedded images, S&P Global Energy theme). PPTX files uploaded to the Gitea release as downloadable attachments. README updated to document HTML as committed artifacts and PPTX as release attachments. Docs-only NFR patch. - v1.9.4 (complete, tag
v1.9.4): presentation slide updates + complete removal of a specific compliance framework from all docs. Title slide redesigned (deck title as H1, 'Agentic Cloud Delivery Platform' as subtitle). DX deck: removed Local Reproducibility slide, redesigned Safe Promotion Path with side-by-side layout, 'an agent' → 'an AI agent', What a Developer Does diagram floated right. All references to that framework removed from 25 files (presentations, module READMEs, docs). Compliance lists now: GDPR, SOX, SOC2, DORA. HTML re-rendered. PPTX uploaded to release. Docs-only NFR patch. - v1.9.5 (complete, tag
v1.9.5): vision gaps + Testing badge + engine terminology + agentic tags + CR format. 9 requirements: (1) DX closing slide strengthened with 'infrastructure as a utility' vision bullet; (2) 'moving' → 'promoting'; (3) added red tape + scalability bullets to Problem slide; (4) Roadmap slide redesigned side-by-side; (5) new 'What This Platform Is — and Isn't' slide (PW deck 16 slides); (6) 'shipped'/'Available today' → 'Testing' (0 consumer adoption); (7) global 'substrate' → 'engine' (88 matches, 30+ files); (8) 'forge' → 'VCS' in presentation files only; (9) new Agentic badge (purple) on agentic features. CR format changed to CHG0678912. HTML re-rendered. PPTX uploaded to release. Docs-only NFR patch. - v1.9.6 (complete, tag
v1.9.6): consolidate both Marp decks to 10 high-impact slides. PW deck 16 → 10 (merged Problem+North Star+Anti-goals, merged Policy+Secure by Default, merged Audit+HITL, folded Observability/Environments/Portability into existing slides, added Vision Realized closing). DX deck 15 → 10 (merged What Dev Does+Contract+No Platform Code, merged Feedback+Deploy Outputs, merged Promotion+Rising Bar, cut Citizen Developer standalone, kept Versioned Releases/Onboarding/Decommission). Removed '5-line YAML' claim from both decks. Source markdown unchanged. Docs-only NFR patch. - v1.9.7 (complete, tag
v1.9.7): talking points files + 4-step process. Created two talking points markdown files (one per deck) distilling the source of truth into presenter-ready cues indexed by the Marp deck's 10-slide structure. Each file has 3-6 talking point bullets + key takeaway per slide. README updated from 3-step to 4-step process (added Step 4: talking points). Directory layout, checklist, and decks table updated. Docs-only NFR patch. - v1.9.8 (complete, tag
v1.9.8): full presentation rework — scope, story arc, visuals, appendix. 6 new mermaid diagrams (scope boundary x2, confidence signal, attestation flow, promotion journey, road to north star). Both decks restructured to 10 main + 6 appendix slides. NEW scope slide clarifying ACDL is infrastructure only. Story beat lines on every slide. Contract examples fixed (image: removed, infra inputs instead). QA attestation reclassified (Design tested → Planned). Confidence signal + attestation flow + promotion journey visuals added. Road to the North Star phased timeline in appendix. Full Testing vs. Planned inventory + glossary in appendix. Source markdown + talking points + README all updated. Docs-only NFR patch. Last deck-polish phase before the v1.10 deck-freeze. - v1.10 (complete, tag
v1.10.0): pipeline regression fix + capability re-verification + verified-reality rewrite. The v1.9.1–v1.9.8 deck work is superseded-by-reverification: the decks presented advertised capability as current without disclosing that the platform had decayed (7 adapter defects preventedterraform init/validate/planagainst live AWS). v1.10 re-verified every advertised capability, fixed all 7 defects in-sweep (D-090: no cap), and rewrote PROJECT/ROADMAP/decks to match verified reality. Decks unfrozen only after Phase 55 lands. See the v1.10 section below for the 4-phase breakdown. - v1.10.1 (complete, tag
v1.10.1): post-v1.10 NFR patch — adversarial grill review (12 challenges, 10 binding decisions, 2 escalations: G-005 risks, G-008 budget), 4-layer verify gate (PASS), multi-persona code review (1 P1 auto-fixed: mis-citation PROJECT.md:6 → PROJECT.md:487). ACDL reclassified as OSS reference implementation (G-003). Docs-only; 518 tests pass; regression gate 16/16 Verified. Gitea release id 236. - v1.10.2 (complete, tag
v1.10.2): contract surface redesign + rename + .yml repo-wide + deck polish. Breaking contract schema change: new top-level fieldsid/name/infrastructure; droppeduses:/module:/inputs:. All 44.yaml→.yml. Code review: 3 P0 auto-fixed, 2 P1+ flagged. 494 tests pass. Gitea release id 237. - v1.11 (complete, tag
v1.11.0): RESTART — stateless adapter + pipeline-driven module lifecycle testing. Closes G-005 (CAP-017..022 deploy-unverified) and G-008 (no cost docs) via a corrected architecture, not the failed v1.11 first attempt (which produced 4 drifted VPCs, ran terraform apply from Python, and had no module lifecycle tests). The restart branches offv1.10.2and rebuilds v1.11 on three corrections: (1) the terraform adapter becomes a stateless assembler — each L1 module ships a realterraform/module dir (variables/locals/main/outputs) owning its resource shape, nested blocks, and defaults; the adapter deletesTYPE_MAP/INPUT_MAP/OUTPUT_MAPand all 39 type-specific branches, becoming a ~80-line assembler that emitsmodule "x" { source = ... }blocks; (2) lifecycle is owned by terraform via the shell orchestrator (run_platform.sh --apply/--destroy), never by Python —verify_deploy_microservice.pyis deleted; (3) testing is pipeline-driven — amodules-lifecyclepipeline (Gitea + GitHub, byte-identical) matrix-runs each L1 module'sexamples/{simple,complex}.ymlcontracts through apply→modify→destroy against live AWS; no per-module Python. A single platform VPC (terraform/platform) is shared by all stacks viadatasource — no per-contract VPC. State keys are deterministic and env-aware (spike/{id}/{env}/terraform.tfstate), stable across lifecycle changes. 13 phases (P56a–P65). See the v1.11 section below for the phase breakdown. - v1.12 (complete, tag
v1.12.0): Presentation Refinement — the leadership decks synced to the v1.11-verified reality (22/22 Verified, stateless adapter, lifecycle pipeline, cost figures, pre-mortem). Includes the CAP-013 adapter dedup fix + 2 probe fixes (required to make the deck claims true) + the ACDL_LIFECYCLE_MODE CI flag (lifecycle tests default to plan-only, full on override). 6 phases (P66–P70). See the v1.12 section below. - v1.13 (complete, tag
v1.13.0): Presentation Polish — both leadership decks polished across all 4 pipeline layers (source .md → -marp.md → .html → -talking-points.md). Action headlines replace category names; story-arc restructure (Intro ~10% / Body ~80% / Conclusion ~10%); removed all transition story lines; bullets ≤12 words, 3–4 per main slide; larger fonts (body 26px, h1 40px, h2 32px); 6 new mermaid diagrams (frictions 2×2, north-star before/after, zero-trust flow, catalog primitives→modules, decommission gates, semver timeline). Code review: 0 P0, 2 P1 auto-fixed (slide-count metadata + README directory layout). 522 tests pass. Docs-only NFR patch. 1 phase (P71). See the v1.13 section below. - v1.13.1 (complete, tag
v1.13.1): config.json schema migration — regenerate.ciagent/config.jsonto the updated CIAgent v2 config structure (drop removed fields, migrategitea→release.gitea, addsecrets/ship/backend/ideation/personas/logging/telemetrysections). Code review: 0 P0, 2 P1/P2 auto-fixed. Docs-only NFR patch (no code changes). Gitea release id 253. - v1.13.2 (complete, tag
v1.13.2): presentation badge cleanup + platform architecture diagram — removed alltesting/agenticmaturity badges from both decks (onlyplannedretained); added a new Slide 3 "The platform at a glance" with a shared high-level logical architecture diagram (consumer surfaces → contract → central pipeline → cross-cutting components → AWS) to both decks; renumbered subsequent slides 4–11; synced talking points + README. Docs-only NFR patch (no code changes). - v1.0 demo URL: https://git.cloudinit.dev/continuous-intelligence/acdl-evidence/raw/branch/main/index.html
v1.0 (Prior — the demo, complete)
Five-phase breakdown that took ACDL from empty repo to a reproducible 4-act
executive demo. Milestone v1.0-initial covered the full demo build. Each
phase produced a runnable increment and ended with a phase-completion commit
- tag. All phases complete; demo archived to
demo/in v1.1 Phase 06.
Phases
Phase 01 — repo-scaffolding
- Description: Create the three repos under
continuous-intelligence(acdl-contracts,acdl-evidence;acdlalready exists), seed directory layouts, configure Pages onacdl-evidence, add environment protection forqaandprodonacdl-contracts. - Status: complete (v1.0.1)
- Depends on: —
- Requirements: REQ-01, REQ-09, REQ-10
- Success Criteria:
acdl-contractsandacdl-evidenceexist and are pushable.acdl-evidencePages returns 200 with placeholderindex.html.qaandprodenvironments exist onacdl-contracts.
Phase 02 — l1-modules
- Description: Create all 8 L1 module folders under
acdl/modules/l1/, each withmanifest.yaml(declared inputs) andmock_apply.sh(uniform echo + 1s sleep + exit 0). - Status: complete (v1.0.2)
- Depends on: [1]
- Requirements: REQ-02, REQ-03
- Success Criteria:
- All 8 L1s present;
mock_apply.shruns and exits 0 for each. manifest.yamlvalidates against the L1 schema.
- All 8 L1s present;
Phase 03 — l2-modules-and-core-scripts
- Description: Create the 4 L2 compositions under
acdl/modules/l2/referencing L1s, plus the 5 core scripts inacdl/scripts/(mock_executor.sh,policy_checker.py,confidence_signal.py,evidence_writer.py,l3b_agent_stub.py). - Status: complete (v1.0.3)
- Depends on: [2]
- Requirements: REQ-04, REQ-05, REQ-06, REQ-07
- Success Criteria:
mock_executor.shapplies each L1 in an L2 and writesstate.json.policy_checker.pyfails onpublic-ingress: truewithPOLICY_VIOLATION:PUBLIC_INGRESS.confidence_signal.pyreturns 0.90 (pass) / 0.40 (fail).evidence_writer.pyappends an event with a valid hash chain.l3b_agent_stub.pymaps the Act 3 example issue tol2-commodity-price-feed.
Phase 04 — pipeline-and-approval-gates
- Description: Build the reusable pipeline workflow in
acdl/.gitea/workflows/(Dev → QA → Prod → Finalize) plus the issue-triggered L3B workflow inacdl-contracts/.gitea/workflows/. Wire environment protection for QA and Prod. - Status: complete (v1.0.4)
- Depends on: [3]
- Requirements: REQ-08, REQ-09, REQ-10, REQ-12
- Success Criteria:
- Pushing a valid
contract.yamlruns Dev automatically and pauses at QA. - Approving QA moves to Prod; approving Prod finalizes.
- Opening an Issue with the Act 3 text generates a
contract.yamlcommit and triggers the pipeline.
- Pushing a valid
Phase 05 — evidence-ui-and-demo-dry-run
- Description: Build
index.html(vanilla JS, fetchesaudit.json, renders timeline) and run all four acts end-to-end as a dry run. - Status: complete (v1.0.5)
- Depends on: [4]
- Requirements: REQ-11, REQ-13, REQ-14, REQ-15
- Success Criteria:
- Pages timeline renders events from
audit.json. - Act 2: valid contract passes through all gates; timeline shows the full flow.
- Act 3: Issue text produces the expected
l2-commodity-price-feedcontract and triggers the pipeline. - Act 4: malicious
public-ingress: truecontract halts in Dev with confidence < 0.50 and a visible rejection reason on the timeline.
- Pages timeline renders events from
v1.1 (Complete — architecture finalization + v1 spike, 2026-07-21, tag v1.2.0)
Five-phase breakdown to finalize the architecture to v1.0 and prove the
locked commitments with one end-to-end implementation spike. Milestone
v1.1-spike covered the real platform's first materialization. Ship tag
at milestone COMPLETE: v1.2.0 (feature milestone, next minor per
ship.md). Status: COMPLETE — all 5 phases shipped (v1.1.1..v1.1.5) +
verified; review READY TO SHIP (0 P0); audit CLEAN; Gitea release id 202.
D-034 closed (root key deactivated by user).
Phase 06 — archive-demo-and-reorient
- Description: Move the v1.0 demo (
modules/,scripts/,evidence-ui/,contracts/, demo.gitea/workflows/) todemo/. Establish the new repo layout (platform/,schemas/,adapters/,terraform/,modules-ir/). Rewrite README to reflect the real platform. Verify the demo still runs fromdemo/(regression check). - Status: complete (v1.1.1)
- Depends on: —
- Requirements: (no new REQ; repo hygiene)
- Success Criteria:
demo/contains the full v1.0 demo;demo/scripts/run_demo.sh --no-uploadstill exits 0.- New top-level dirs exist and are empty-but-scaffolded:
platform/,schemas/,adapters/,terraform/,modules-ir/. - README reflects the real platform (vision + architecture links, new layout).
Phase 07 — architecture-v1-finalization
- Description: Resolve the 11 open decisions in
docs/architecture.md§13 (already recorded inPROJECT.md). Author the locked schemas + designs:schemas/ir.schema.json(REQ-17),schemas/policy_check_result.schema.json(REQ-18),schemas/contract.schema.json(REQ-22),platform/confidence_signal.pyspec (REQ-19),platform/audit_ledger_design.md(REQ-20),platform/hitl_matrix_design.md(REQ-21). Mark architecture v1.0. - Status: complete (v1.1.2)
- Depends on: [06]
- Requirements: REQ-16, REQ-17, REQ-18, REQ-19, REQ-20, REQ-21, REQ-22
- Success Criteria:
- All 11 open decisions resolved and recorded in
PROJECT.md. - All 6 schema/design files exist and validate (
ajv/python -m jsonschema). docs/architecture.mdstatus note updated to v1.0 (or adocs/architecture-v1.0.mdsnapshot).
- All 11 open decisions resolved and recorded in
Phase 08 — aws-oidc-bootstrap
- Description: Re-scoped per RESEARCH TARGET 1 + D-039. Gitea Actions does not support
id-token: write(conf 0.95), so real OIDC is deferred to v1.2. This phase instead: uses the temporary long-lived key (waiver D-034) once to create an S3 state bucket, a DynamoDB lock/outbox table, and an IAM user with a minimal scoped policy (S3 + DynamoDB + plan-only); stores the key as a Gitea Actions secret; implementsscripts/rotate_spike_key.shto rotate the key after each spike run. Real OIDC federation is tracked via go-gitea/gitea#36988 for v1.2. - Status: complete (v1.1.3)
- Depends on: [07]
- Requirements: REQ-23 (re-interpreted: AWS auth bootstrap + state backend; OIDC deferred to v1.2 per D-039)
- Success Criteria:
- S3 state bucket + DynamoDB lock/outbox table exist.
- An IAM user with a minimal scoped policy exists; its access key is stored as a Gitea Actions secret.
scripts/rotate_spike_key.shrotates the key (deactivates old, creates new, updates the secret) and is idempotent.- A workflow step authenticates to AWS with the rotated secret and runs
aws sts get-caller-identitysuccessfully. - D-034 is closed: the bootstrap long-lived key is rotated/deactivated (logged in
PROJECT.md).
Phase 09 — v1-spike-ir-and-l1-and-adapter
- Description: Implement the Target Stack IR, one real L1
l1-s3(IR-typed interface, registered), and the Terraform adapter that compiles the IR → Terraformvariable/output+ root module and emits a realterraform planagainst AWS (via the rotated-key secret per D-039; OIDC is v1.2). State in S3 + DynamoDB. - Status: complete (v1.1.4)
- Depends on: [08]
- Requirements: REQ-24, REQ-26
- Success Criteria:
schemas/ir.schema.jsonis satisfied bymodules-ir/l1/l1-s3/interface.- The Terraform adapter translates
l1-s3to a validterraform plan(real AWS). terraform validate+terraform plansucceed; no long-lived credential in the workflow.
Phase 10 — v1-spike-l2-and-contract-e2e
- Description: Implement
l2-static-assets(thin-composition referencingl1-s3), the contract schema + contract→IR resolution, and one end-to-end contract submission (contracts/spike.yamlforl2-static-assets) flowing through schema validation → IR resolution →terraform plan→ CheckovPolicyCheckResult→ confidence signal → evidence event to the DynamoDB outbox. Verify the IR commitments hold (no polyglot mess). - Status: complete (v1.1.5)
- Depends on: [09]
- Requirements: REQ-25, REQ-27, REQ-28
- Success Criteria:
l2-static-assetsreferencesl1-s3only (depth 1).- One contract submission completes the full pipeline end-to-end.
scripts/verify_phase10.shproves the adapter is the only engine-specific code.- Evidence event is written to the DynamoDB outbox.
After Phase 10: COMPLETE gate — review → ship v1.2.0 → audit. DONE.
v1.2 (Complete — platform hardening + first real consumer deployment, 2026-07-21, tag v1.3.0)
Six-phase breakdown to harden the v1.1 spike, simplify the setup, update
the docs, and prove the platform delivers real value by deploying a basic
microservice to AWS ECS Fargate end-to-end. Ship tag at milestone COMPLETE:
v1.3.0 (feature milestone, next minor per ship.md — v1.1 shipped
v1.2.0). Phase patches v1.2.1..v1.2.6. Status: COMPLETE — all 6
phases shipped (v1.2.1..v1.2.6) + verified; review READY TO SHIP (1 P0
operator action, 1 P1 deferred to v1.3); audit CLEAN. The terraform apply
is blocked by the live IAM policy (P0-IAM, operator action); the platform
flow is verified end-to-end up to terraform plan (13 to add).
Phase 11 — v1.2-research-and-readme
- Description: Re-evaluate go-gitea/gitea#36988 (OIDC for Gitea Actions) — confirm still open (re-checked 2026-07-21: open, last updated 2026-05-27, not merged) and record the decision to extend D-039 as D-047. Audit the v1.1 spike for NFR gaps (least-privilege IAM, idempotency, error handling, rotation hygiene) and simplification opportunities (script consolidation, dead code, stale paths). Rewrite
README.mdto reflect v1.1 complete + the actual spike flow + how to run + the real repo layout + the v1.2 objective. - Status: complete (v1.2.1)
- Depends on: —
- Requirements: REQ-29
- Success Criteria:
RESEARCH.mdhas a v1.2 addendum with the #36988 re-check + NFR audit + simplification findings.README.mdreflects v1.1 complete; documents the spike flow,scripts/run_platform.sh, the repo layout, and the v1.2 objective; no stale "v1.1 (active)" framing.- D-047 is recorded in
PROJECT.md.
Phase 12 — nfr-harden-and-simplify
- Description: Apply Phase 11's findings. Tighten
terraform/bootstrap/spike_runner_policy.jsonto least-privilege (add ECS + ECR + ELB + IAM plan-only permissions for v1.2; audit for wildcards). Makecreate_state_backend.pyandcreate_iam_user.pyidempotent. Consolidaterun_spike_plan.sh+run_spike_e2e.shinto a singlescripts/run_platform.shwith proper exit codes and error handling. Redact P1-1 (the two AWS access key IDs in.ciagent/VERIFY.mdPhase 09 narrative). Fix any remaining staleplatform/paths in.ciagent/. The v1.1 spike still runs e2e after the refactor. - Status: complete (v1.2.2)
- Depends on: [11]
- Requirements: REQ-30
- Success Criteria:
scripts/run_platform.shruns the full v1.1 spike e2e and exits 0.create_state_backend.py/create_iam_user.pyre-runs are idempotent (no duplicate resources; exit 0).spike_runner_policy.jsonpasses a least-privilege audit (no*actions beyond documented exceptions)..ciagent/VERIFY.mdPhase 09 narrative has no live AWS access key IDs.- No stale
platform/paths remain in.ciagent/.
Phase 13 — l1-catalog-for-ecs
- Description: Author six IR-typed L1 modules for an ECS Fargate microservice:
l1-vpc(VPC + subnets + route tables),l1-ecs-cluster(ECS Fargate cluster),l1-ecs-service(ECS service + task definition),l1-iam-role(task execution + task role),l1-alb(ALB + listener + target group),l1-ecr(ECR repository). Each has aninterface.jsonvalid againstschemas/ir.schema.json. Register all six inmodules-ir/registry.json. Expand the Terraform adapterTYPE_MAPto cover the new IR resource types. Each L1 produces a validterraform planfragment. - Status: complete (v1.2.3)
- Depends on: [12]
- Requirements: REQ-31
- Success Criteria:
- All six L1s exist under
modules-ir/l1/withinterface.jsonvalid againstschemas/ir.schema.json. modules-ir/registry.jsonlists all six.- The adapter
TYPE_MAPcovers all six IR resource types. - Each L1 produces a valid
terraform planfragment.
- All six L1s exist under
Phase 14 — l2-microservice-and-contract-schema
- Description: Author
l2-microservicethin-composition undermodules-ir/l2/l2-microservice/referencing the six ECS L1s (depth ≤ 5). Extendschemas/contract.schema.jsonwith microservice inputs (image: string,port: integer,env: map,healthcheck: object). Verify contract→IR resolution yields a complete target stack. - Status: complete (v1.2.4)
- Depends on: [13]
- Requirements: REQ-32
- Success Criteria:
l2-microservicereferences the six ECS L1s only (depth ≤ 5).schemas/contract.schema.jsonvalidates acontracts/microservice.yamlwith the new inputs.- Contract→IR resolution yields a complete target stack (all six L1 instances + relationships).
Phase 15 — consumer-repo-and-terraform-apply
- Description: Create a new Gitea repo
acdl-consumer-microserviceunder thecontinuous-intelligenceorg containing a basic HTTP microservice (tiny Python/Go server returning 200), aDockerfile, an ECR push step, and acontracts/microservice.yamlsubmission forl2-microservice(dev environment). Lift the platform fromplantoapplyfor thedevenvironment (autonomous per §10, confidence ≥ 0.50, no HITL). Submit the contract → pipeline → IR → plan → apply → a real ECS Fargate service running. - Status: complete (v1.2.5, PARTIAL — terraform apply blocked by IAM P0)
- Depends on: [14]
- Requirements: REQ-33 (partial), REQ-34
- Success Criteria:
acdl-consumer-microservicerepo exists undercontinuous-intelligence.- The microservice builds into a Docker image and is pushed to ECR.
terraform apply(dev) creates real AWS resources (VPC, ECS cluster, ECR repo, ALB, ECS service).- The apply result is captured in the evidence stream.
Phase 16 — v1.2-capstone-e2e
- Description: End-to-end verification: consumer commit to
acdl-consumer-microservicetriggers the pipeline → contract→IR resolution →terraform plan→terraform apply(dev) → a live ECS Fargate service serving HTTP 200 on its ALB → evidence event written to the DynamoDB outbox → the event renders on theacdl-evidencetimeline. Verify the NFR improvements from Phase 12 hold, the setup is simpler (onescripts/run_platform.sh), and the README is accurate.scripts/verify_phase16.shproves the full flow green. - Status: complete (v1.2.6, capstone — terraform apply blocked by IAM P0, verified up to plan)
- Depends on: [15]
- Requirements: REQ-35 (partial — IAM-blocked)
- Success Criteria:
- One consumer commit produces a live ECS service serving HTTP 200.
- An evidence event for the apply is in the DynamoDB outbox and renders on the timeline.
scripts/verify_phase16.shexits 0.- README accurately documents the v1.2 platform flow.
After Phase 16: COMPLETE gate — review → ship v1.3.0 → audit.
v1.3 (Complete — module documentation + thin-composition removal)
The v1.3 milestone starts with simplification: removing the unsatisfactory thin-composition layer and building out proper module documentation. The L2 composition mechanism will be redesigned in a later phase.
Phase 17 — remove-thin-composition-and-module-readmes
- Description: Remove the L2 thin-composition layer completely (composition.json files, contract_resolver.py, contract schema, sample contracts) and build out proper module READMEs. Create a README template for both L1 and L2 modules, rewrite all 7 L1 module READMEs in plain language (no jargon, with Resources/Inputs/Outputs/Usage/Compliance-extension-points/Versioning sections), write 2 L2 placeholder READMEs noting the composition is under redesign, create a catalog index, and patch run_platform.sh to load a pre-existing IR instance instead of resolving a contract. Prune L2 entries from the registry.
- Status: complete (v1.3.1)
- Depends on: —
- Requirements: REQ-36, REQ-37, REQ-38
- Success Criteria:
- The thin-composition layer is fully removed (composition.json, contract_resolver.py, contract schema, contracts/).
- run_platform.sh loads a pre-existing IR instance; the downstream adapter/checkov/confidence/outbox pipeline still works.
- A README-TEMPLATE.md exists for both L1 and L2 modules.
- Every L1 module has a README.md with Resources/Inputs/Outputs/Usage/Compliance-extension-points/Versioning.
- Every L2 module has a placeholder README.md noting the composition is under redesign.
- A modules-ir/README.md catalog index exists.
Phase 18 — testing-and-cicd-pipelines
- Description: Create a pytest test suite that reproduces the platform pipeline offline (adapter, confidence_signal, checkov_adapter, outbox_writer). Add an offline
--check-onlymode torun_platform.shthat runs the pipeline up to adapter emission without AWS/Checkov/outbox. Create identical CI/CD pipelines for both Gitea Actions (.gitea/workflows/ci.yml, dev environment) and GitHub Actions (.github/workflows/ci.yml, production) that run: lint, pytest,run_platform.sh --check-only. Addpyproject.toml+requirements-test.txtfor dependency pinning. - Status: complete (v1.3.2)
- Depends on: [17]
- Requirements: REQ-39, REQ-40, REQ-41, REQ-42
- Success Criteria:
pytestruns and passes offline (no AWS, no Checkov, no DynamoDB).run_platform.sh --check-onlyruns offline and exits 0..gitea/workflows/ci.ymland.github/workflows/ci.ymlexist with identical job stages (lint, test, check-only).pyproject.toml+requirements-test.txtpin test dependencies.
After Phase 18: COMPLETE gate — review → ship v1.3.2 → audit.
v1.4 (Active — central pipeline contract + shell reproducibility + streaming)
The v1.4 milestone makes the CI/CD pipeline a declarative contract rather than duplicated workflow copies, enables full shell reproducibility of the CI pipeline, and streams terraform/checkov output so users can see what the platform is doing.
Phase 19 — central-pipeline-contract-and-shell-reproducibility
- Description: Create a central pipeline contract (
schemas/pipeline.schema.jsonJSON Schema +pipelines/ci.yamlYAML instance) that both.gitea/workflows/ci.yml(Gitea Actions, dev) and.github/workflows/ci.yml(GitHub Actions, production) implement. Createscripts/run_ci.shthat mirrors the CI pipeline locally (lint → test → check-only). Updatescripts/run_platform.shto stream terraform init/validate/plan output, Checkov compliance results, and PolicyCheckResult records to stdout by default (with--quietfor log-only mode). Addtests/test_pipeline_contract.pyvalidating the contract schema, workflow conformance, and run_ci.sh. Update both workflow YAMLs with contract reference headers (staying byte-identical). - Status: complete (v1.4.1)
- Depends on: [18]
- Requirements: REQ-43, REQ-44, REQ-45
- Success Criteria:
pipelines/ci.yamlvalidates againstschemas/pipeline.schema.json.- Both
.gitea/workflows/ci.ymland.github/workflows/ci.ymlare byte-identical. - A test parses both workflows and asserts their stages/commands match the contract.
scripts/run_ci.shexits 0 and outputs "CI PIPELINE OK".scripts/run_platform.sh --check-onlystreams the emitted Terraform to stdout.scripts/run_platform.sh --check-only --quietsuppresses the Terraform stream.pytesttotal count increases from 90 to 122 (32 new contract/streaming tests).
After Phase 19: COMPLETE gate — review → ship v1.4.1 → audit.
v1.5 (Complete — consumer happy path + zero-trust docs + reusable deploy workflow, tag v1.5.0)
The v1.5 milestone makes the consumer happy path self-evident, documents the zero-trust credential model, and provides a reusable deploy workflow so consumer repos never need to clone the platform repo or invoke its scripts locally.
Phase 20 — consumer-happy-path-and-reusable-deploy-workflow
- Description: Rewrite
README.mdso the consumer model is unambiguous (this repo is the platform source; a consumer owns onlycontract.yaml+ app code). Convert the platform-flow diagram to a mermaidflowchart TD. Remove "L3A"/"L3B" + "spike" nomenclature from README prose. Rewrite the Credentials section for zero-trust OIDC + ABAC (with a static-key override + daily rotation; consumer rotates out of band when using.env.secretslocally). Replacedocs/consumer-guide-static-assets.mdwith a genericdocs/CONSUMER_GUIDE.md(all L2 modules, mermaid diagrams, versioneduses:floating MAJOR+MINOR, consumer-scoped prerequisites, run-time platform fetch via a reusable workflow). Create byte-identical.gitea/workflows/deploy.yml+.github/workflows/deploy.ymlimplementingpipelines/deploy.yaml— a reusable workflow invoked by consumer repos viauses: acdl/.gitea/workflows/deploy.yml@v1.4that checks out the consumer repo + the ACDL platform repo and runsscripts/run_platform.sh. Updatecontracts/static-assets.yamltouses: acdl/pipelines/deploy.yaml@v1.4. Extendtests/test_pipeline_contract.pyto validate the new deploy workflows (byte-identical, schema-conformant). - Status: complete (v1.5.0)
- Depends on: [19]
- Requirements: REQ-46, REQ-47, REQ-48, REQ-49, REQ-50, REQ-51
- Success Criteria:
README.mdstates the platform-source vs consumer-repo distinction up front; platform flow is a mermaidflowchart TD;grep L3B README.mdreturns 0 hits;grep -i spike README.mdreturns 0 prose hits (code paths in bash blocks allowed).docs/CONSUMER_GUIDE.mdexists;docs/consumer-guide-static-assets.mdis deleted;grep -R consumer-guide-static-assetsreturns 0 dangling references; guide is generic (static-assets is the worked example, not the scope); diagrams are mermaid;uses:references use@v1.4.README.mdCredentials section describes OIDC + ABAC zero-trust as the default and the static-key override + daily rotation + consumer out-of-band rotation duty for local.env.secrets..gitea/workflows/deploy.ymland.github/workflows/deploy.ymlexist, are byte-identical, conform toschemas/deploy-pipeline.schema.json, and are reusable (on: workflow_callwith acontractinput).contracts/static-assets.yamlusesuses: acdl/pipelines/deploy.yaml@v1.4.tests/test_pipeline_contract.pyvalidates the deploy workflows (exist, byte-identical, schema-conformant); the extended test suite passes;bash scripts/run_ci.shexits 0.
After Phase 20: COMPLETE gate — review → ship v1.5.0 → audit.
v1.6 (Active — consumer-facing docs restructure + terminology normalization + environments concept)
The v1.6 milestone restructures the consumer-facing documentation into a real
GitHub Pages site, normalizes the terminology (L2 → "modules", L1 →
"primitives", "composition" → "pattern", "forge" → "platform runners"), renames
acdl_platform/ to core/ (platform/ shadows stdlib), rewrites the README (Features + Roadmap,
restated repository roles, fixed mermaid, cleaned credentials section), removes
all .ciagent/ + .gitea/ references from consumer surfaces, and introduces
the concept of platform-managed environments with a minimal first-run onboarding
scaffold.
Phase 21 — docs-restructure-and-terminology-normalization
- Description: Rename
acdl_platform/→core/(directory + all code/test/script/pipeline/workflow references; tests green —platform/was the original target but shadows Python's stdlibplatformmodule, socore/was chosen). Restructuredocs/into a Jekyll-style GitHub Pages site (_config.yml,index.md,modules/,contracts/,pipeline/,environments/,consumer-guide.md, consolidatedarchitecture.md,vision.md). RewriteREADME.md: remove.ciagent/+.gitea/workflows/rows; restate consumer repo model (app code + 1+ contracts + CI definitionsuses:-ing the central workflow); replace Status with Features + Roadmap (planned only); fix the mermaid (visible text, add security-checks stage before policy, no tool names, add infrastructure-apply stage); remove the environments table; clean the credentials section (no go-gitea/waivers, keep daily/out-of-band rotation); forge → platform runners/platform-managed. Updatedocs/consumer-guide.md: drop L2 (→ modules), composition → pattern (prose), remove.gitea/(GitHub only), forge → platform runners, mermaid updated. Updatemodules/READMEs: L1 → primitives, L2 → modules, composition → pattern (prose only, files kept); bump stale@v1→@v1.4. Consolidatedocs/architecture.md+docs/architecture-v1.0.mdinto a single current-architecturedocs/architecture.md. Adddocs/environments/index.md(platform-managed AWS account/network/state/runner; consumer provides none). Add a minimal onboarding scaffold:core/environments/dir + sampledev.json+ README,core/environment_check.py, wire-in at the top ofscripts/run_platform.sh, friendly onboarding message when no environment is defined,tests/test_environment_check.py. Add a roadmap entry: "composition" will later describe the thin orchestration where consumers dynamically create a module directly from the contract file (future implementation, not this phase). - Status: complete (v1.6.0)
- Depends on: [20]
- Requirements: REQ-52, REQ-53, REQ-54, REQ-55, REQ-56, REQ-57, REQ-58, REQ-59, REQ-60, REQ-61
- Success Criteria:
grep -R "\.ciagent" docs/ README.mdreturns 0 hits;grep -R "\.gitea" docs/ README.md modules/ contracts/returns 0 hits.grep -R "acdl_platform" .(excluding.ciagent/,demo/,.git/) returns 0 hits; the test suite passes after the rename.docs/has the Jekyll structure (_config.yml,index.md,modules/,contracts/,pipeline/,environments/); no.ciagent/links indocs/.- Consumer-facing docs have no "L2"/"L1" labels (modules/primitives) and no "forge" term; "composition" → "pattern" in prose.
- README.md has Features + Roadmap (no version changelog); repository roles restated; mermaid visible + security-checks + infrastructure-apply stages + no tool names; no environments table; credentials section has no go-gitea/waivers.
docs/environments/index.mdexists;core/environments/+dev.json+environment_check.py+run_platform.shwire-in +tests/test_environment_check.pyexist and pass.bash scripts/run_ci.shexits 0;python3 -m pytest tests/ -vpasses (154 + new environment-check tests).
After Phase 21: COMPLETE gate — review → ship v1.6.0 → audit. DONE.
v1.7 (Complete — production platform + contract ingestion + pipeline maturation, tag v1.7.0)
The v1.7 milestone takes the platform from a documented, environments-aware
foundation to a production-grade platform with a production-ready
static-assets stack (CloudFront + WAF), a contract-ingestion Lambda + DynamoDB
store for historical/impact analysis, a uniform error-reporting pathway via the
same Lambda, DX-friendly deploy outputs (SSM + PR comments), three dedicated
platform pipelines (unit+integration, primitives plan, patterns plan), a
release job with MAJOR.MINOR/MAJOR tag maintenance, new security adapters
(Wiz, Kyverno), real tagging-standard enforcement (closing D-043), removal of
the legacy consumer-repos directory (removed in v1.7), and validated per-module examples
(including a new RDS primitive demonstrating multi-engine variation).
The uses:/ref: tag advances from @v1.4 to @v1.6; the floating v1.6 +
v1 tags are created in Phase 22 (pointing at the v1.6.0 release) so the
reference is never broken, and the release job (Phase 26) owns ongoing updates.
Phase 22 — rename-and-production-static-assets-stack
- Description: Rename
static-assets→static-assetseverywhere (D-048 — including.ciagent/historical narrative, overriding the v1.6 preservation precedent). Author two new primitives:cloudfront(distribution + OAC, stack typesaws:cloudfront:distribution+aws:cloudfront:originaccesscontrol) andwaf(WAFv2 web ACL, stack typeaws:wafv2:webacl). Augment thestatic-assetsmodule to a production-ready stack referencing s3 + cloudfront + waf (depth 1, D-049). Expand the Terraform adapterTYPE_MAP/INPUT_MAP/OUTPUT_MAPfor the new stack types. Bumpuses:/ref:from@v1.4to@v1.6(D-056/D-057); create the floatingv1.6+v1git tags pointing atv1.6.0so the reference resolves immediately. - Status: complete (v1.7.0)
- Depends on: [21]
- Requirements: REQ-62, REQ-63, REQ-64
- Success Criteria:
grep -R "static-assets[^s]" .(excluding.git/) returns 0 hits;modules/l2/static-assets/is renamed tomodules/l2/static-assets/;contracts/static-assets.yaml→contracts/static-assets.yaml; registry key renamed; all.ciagent/references (incl. verbatim phase descriptions, REQ-25/27/50 text, D-036) rewritten tostatic-assets.modules/l1/cloudfront/+modules/l1/waf/exist withinterface.jsonvalid againstschemas/stack.schema.json; registered inmodules/registry.json.modules/l2/static-assets/composition.jsonreferences s3 + cloudfront + waf (depth 1).adapters/terraform/adapter.pyTYPE_MAPcoversaws:cloudfront:distribution,aws:cloudfront:originaccesscontrol,aws:wafv2:webacl.contracts/static-assets.yaml+.github/workflows/deploy.yml+.gitea/workflows/deploy.ymluse@v1.6; git tagsv1.6+v1exist pointing atv1.6.0.bash scripts/run_ci.shexits 0;python3 -m pytest tests/ -vpasses;bash scripts/run_platform.sh --check-onlyexits 0.
Phase 23 — tagging-standards-and-security-adapters
- Description: Define a required-tag set (
acdl:owner,acdl:contract,acdl:environment,acdl:cost-center) inschemas/tagging-standard.json(D-054). Author a Checkov custom YAML rule atadapters/terraform/policy/custom_rules/acdl_tagging.yamlthat fails when required tags are missing on taggable resources. Remove the_emit_tag_naming_skipped()placeholder incheckov_adapter.py(D-043 closure) and addACDL_TAG_NAMINGtoRULE_MAPas a real rule. Author a Wiz adapter stub (adapters/wiz/wiz_adapter.py) translating Wiz API issues →PolicyCheckResultrecords (engine: "wiz"), degrading gracefully when unconfigured (D-052). Author a Kyverno K8s-native adapter (adapters/kyverno/kyverno_adapter.py) translating KyvernoPolicyReportresults →PolicyCheckResultrecords (engine: "kyverno"), with sample policies as documentation; inactive for Terraform-only stacks, ready for the GitOps reconciler roadmap item (D-053). Addwiz+kyvernoto theschemas/policy_check_result.schema.jsonengine enum. - Status: complete (v1.7.0)
- Depends on: [22]
- Requirements: REQ-65, REQ-66, REQ-67
- Success Criteria:
adapters/terraform/policy/custom_rules/acdl-tagging.yamlexists; Checkov loads it;checkov_adapter.pyno longer emits a SKIPPEDACDL_TAG_NAMINGplaceholder (D-043 closed).adapters/wiz/wiz_adapter.py+tests/test_wiz_adapter.pyexist; tests pass offline (not-configured graceful degradation).adapters/kyverno/kyverno_adapter.py+ sample policies +tests/test_kyverno_adapter.pyexist; tests pass offline.schemas/policy_check_result.schema.jsonengine enum includescheckov | kyverno | opa | wiz.bash scripts/run_ci.shexits 0;python3 -m pytest tests/ -vpasses.
Phase 24 — platform-lambda-and-contract-ingestion
- Description: Author a platform Lambda (
core/lambda/contract_ingestor.py) invoked via a Function URL (IAM auth) that accepts{ consumerRepo, contractId, contract, environment, action }and writes contracts to a DynamoDB tableacdl-contracts(PKconsumerRepo, SKcontractId#submittedAt, SSE via a customer-managed CMK) (D-051). Define the Terraform (terraform/platform/main.tf) for the table, Lambda, Function URL, KMS key, Secrets Manager secret (acdl/github-token), and Lambda execution role. Define the cross-account consumer-invoke IAM policy (terraform/platform/consumer_invoke_policy.json) granting the consumer's deploy rolelambda:InvokeFunctionUrlon the Lambda ARN, scoped via ABAC. Thereport_erroraction (Phase 25) is prepared but not yet implemented. Updatedocs/environments/index.mdto document that onboarding now also grants Lambda-invoke permission. - Status: complete (v1.7.0)
- Depends on: [23]
- Requirements: REQ-68
- Success Criteria:
core/lambda/contract_ingestor.pyexists; handler writes contracts to DynamoDB (tested offline with moto).terraform/platform/main.tfdefinesacdl-contractsDynamoDB table,acdl-contract-ingestorLambda, Function URL (IAM auth), KMS CMK, Secrets Manager secret, Lambda execution role.terraform/platform/consumer_invoke_policy.jsonexists (cross-account invoke policy template).tests/test_contract_ingestor.pypasses offline.bash scripts/run_ci.shexits 0.
Phase 25 — deploy-pipeline-dx-outputs-and-error-reporting
- Description: Add a
publish-outputsstep toscripts/run_platform.sh(after apply) that writes deploy outputs to SSM Parameter Store asSecureString(KMS-encrypted, namespaced/acdl/{env}/{contractId}/{output_name}) for runtime-injectable values, and acomment-outputsstep that posts a structured GitHub PR comment / job summary with human-readable connection strings (D-050). Implementcore/output_publisher.py(SSM write + GitHub comment formatting). Implement the Lambdareport_erroraction (core/lambda/contract_ingestor.py) that creates a GitHub issue on the platform repo (acdl/acdl) via the GitHub API using a token from Secrets Manager; idempotent (comments on existing open issue rather than duplicating) (D-055). Add anif: failure()error-report step to.github/workflows/deploy.ymlthat invokes the Lambda viaaws lambda invoke-function-url(SigV4-signed). Add a PR comment after every successful pipeline stage (D-055 extension) viascripts/post_stage_comment.sh(usesGITHUB_TOKEN+gh api; no-op when not in a PR context). Updatepipelines/deploy.yaml+ both deploy workflow YAMLs with the new stages (byte-identical). - Status: complete (v1.7.0)
- Depends on: [24]
- Requirements: REQ-69, REQ-70, REQ-71
- Success Criteria:
scripts/run_platform.shhas apublish-outputsstep (SSM SecureString, tested offline with moto) + acomment-outputsstep (GitHub PR comment formatting, tested offline).core/lambda/contract_ingestor.pyreport_erroraction creates a GitHub issue (tested with mocked API); idempotent..github/workflows/deploy.yml+.gitea/workflows/deploy.yml(byte-identical) have anif: failure()error-report step invoking the Lambda + stage comments after each successful stage (PR context).pipelines/deploy.yamldeclares the new stages.bash scripts/run_ci.shexits 0;python3 -m pytest tests/ -vpasses.
Phase 26 — platform-pipelines-and-release-automation
- Description: Author three platform pipelines (D-057): (1)
.github/workflows/platform-test.yml(PR, lint + unit + integration + schema-validation — replacesci.ymlfor PRs); (2).github/workflows/primitives-plan.yml(PR, plan-only for all L1 primitives via matrix); (3).github/workflows/patterns-plan.yml(PR, plan-only for all L2 modules via matrix). Authorscripts/run_primitive_plan.sh+scripts/run_pattern_plan.sh(with--check-onlymode for CI). Author the release job (.github/workflows/release.yml) that runs on merge tomain, computes the next semver (PATCH per phase, MINOR on milestone COMPLETE), creates the MAJOR.MINOR.PATCH tag, force-moves the MAJOR.MINOR + MAJOR floating tags, creates a GitHub release with an auto-generated body. This is the mechanism that lets consumers on@v1or@v1.7receive updates. - Status: complete (v1.7.0)
- Depends on: [25]
- Requirements: REQ-72, REQ-73
- Success Criteria:
.github/workflows/platform-test.ymlexists, runs lint + unit + integration + schema-validation on PR..github/workflows/primitives-plan.yml+.github/workflows/patterns-plan.ymlexist, run plan-only (matrix) on PR..github/workflows/release.ymlexists, computes next semver, creates + updates MAJOR.MINOR.PATCH / MAJOR.MINOR / MAJOR tags on merge.scripts/run_primitive_plan.sh+scripts/run_pattern_plan.shexit 0 in--check-onlymode.bash scripts/run_ci.shexits 0;python3 -m pytest tests/ -vpasses.
Phase 27 — remove-legacy-consumer-repos-and-module-documentation-examples
- Description: Delete the legacy consumer-repos directory entirely (a v1.2 artifact removed in v1.7; references in
.ciagent/historical narrative are rewritten per D-048). Author a new RDS primitive (modules/l1/rds/) with anengineinput (enum: postgres, mysql, etc.) demonstrating multi-engine variation (D-059). Expand the adapterTYPE_MAPforaws:rds:instance→aws_db_instance. For each module (primitives + patterns), add amodules/<name>/examples/directory withsimple.yaml+complex.yaml(+ variation files) validated againstschemas/contract.schema.jsonin the platform-test pipeline (Phase 26 schema-validation stage) (D-058). Each module'sREADME.md## Examplessection references + excerpts the validated files. Updatedocs/modules/index.md+docs/consumer-guide.md+docs/contracts/index.mdwith the new module names + examples. - Status: complete (v1.7.0)
- Depends on: [26]
- Requirements: REQ-74, REQ-75
- Success Criteria:
- The legacy consumer-repos directory does not exist; a recursive grep for the legacy directory name (excluding
.git/) returns 0 hits. modules/l1/rds/exists withinterface.json(engineenum) +examples/; registered; adapter emitsaws_db_instance.- Every module README has a
## Examplessection;modules/<name>/examples/{simple,complex}.yamlexist and validate againstschemas/contract.schema.json. docs/modules/index.mdlinks to all module READMEs (including cloudfront, waf, rds).bash scripts/run_ci.shexits 0;python3 -m pytest tests/ -vpasses.
- The legacy consumer-repos directory does not exist; a recursive grep for the legacy directory name (excluding
After Phase 27: COMPLETE gate — review → ship v1.7.0 → audit. DONE.
v1.8 (Complete — P1 remediation + uptime + engineering standards + encryption/deletion-protection by default + decommission + docs)
The v1.8 milestone clears all pending P1 issues from v1.5–v1.7 verify
reviews AND delivers three user-directed tracks: encryption + deletion
protection by default (with a decommission alias), uptime monitoring
(uptime-kuma primitive deployed by default after L2 modules), and
engineering standards + path documentation. Ship tag at milestone
COMPLETE: v1.8.0 (feature milestone, next minor per run.md — v1.7
shipped v1.7.0). Phase patches v1.7.1..v1.7.9.
Phase 28 — adapter-waf-and-resolver-outputs
- Description: Fix WAF HCL emission: custom
rulesinput emits nestedrules { ... }blocks (notrules = [...]attribute syntax — P1-4). Honordefault_actioninput (allow/block) instead of hardcodingallow {}(P1-5). Implement L2 compositionoutputs[]processing inresolve_l2()— buildstack.outputsdict + adapter emitsoutputblocks (P1-7). Tests for all three fixes. - Status: complete (v1.8.0)
- Depends on: —
- Requirements: REQ-76, REQ-77
- Success Criteria:
- WAF with custom rules emits nested
rules {blocks, notrules = [. - WAF with
default_action: blockemitsblock {}; default (absent) emitsallow {}. - L2 resolution of
static-assetsyieldsstack.outputs.distribution_domain_name,bucket_arn,web_acl_arn. - Adapter emits
output "distribution_domain_name" { value = ... }blocks. pytestpasses;run_platform.sh --check-onlyexits 0.
- WAF with custom rules emits nested
Phase 29 — ssm-kms-and-invoke-policy
- Description: SSM publisher fails loud (
RuntimeError) whenACDL_KMS_KEY_IDunset;ACDL_ALLOW_DEFAULT_KMS=1escape hatch for local testing (P1-3). Convertconsumer_invoke_policy.jsonto a Terraform-rendered template usingdata.aws_caller_identity+templatestring— no000000000000placeholder (P1-6). Tests for both. - Status: complete (v1.8.0)
- Depends on: [28]
- Requirements: REQ-78, REQ-79
- Success Criteria:
- SSM publisher raises
RuntimeErrorwhenACDL_KMS_KEY_IDunset; succeeds withACDL_ALLOW_DEFAULT_KMS=1. - Rendered invoke policy contains the caller's live account ID, not
000000000000. pytestpasses;run_ci.shexits 0.
- SSM publisher raises
Phase 30 — run-platform-isolation-and-api-portability
- Description:
run_platform.shemits adapter output to$WORK/tf(per-run temp dir), notterraform/spike/; remove committedterraform/spike/*.tf(P1-8).contract_ingestor.pyreadsGITHUB_API_BASEenv for forge-agnostic API URLs (GitHub + Gitea);_forge_type()branches search URL (P1-9). Deploy workflowconfigure-aws-credentialsstep restructured as single conditional step: OIDC when no static key,access-key/secret-keyinputs when static key present (S1). Both deploy workflows remain byte-identical. - Status: complete (v1.8.0)
- Depends on: [29]
- Requirements: REQ-80, REQ-81, REQ-82
- Success Criteria:
run_platform.sh --check-onlywrites to a temp dir; noterraform/spike/*.tfcommitted.contract_ingestor.pyusesGITHUB_API_BASE; Gitea base URL produces correct API paths.- Deploy workflow static-key override wired to
configure-aws-credentialsinputs. - Both deploy workflows byte-identical;
pytest+run_ci.shgreen.
Phase 31 — encryption-by-default-and-per-stack-cmk
- Description: Create
kms-keyL1 primitive (typeaws:kms:key, inputs: description/region/deletion_window_days, outputs: kms_key_arn/kms_key_id, NFRs: enable_rotation default true, deletion_protection default true). Adapter emitsaws_kms_key+aws_kms_alias+enable_key_rotation = true. Addencryption_enabledNFR (default true) +kms_key_arninput to all primitives. L2 modules wire akms-keychild + connect its output to all children. Managed KMS fallback when no CMK provided (with stderr warning). - Status: complete (v1.8.0)
- Depends on: [30]
- Requirements: REQ-83, REQ-84, REQ-85
- Success Criteria:
- Every primitive has
encryption_enabledNFR (default true) + optionalkms_key_arninput. - L2 resolution wires per-stack CMK to all children.
- Adapter emits encryption blocks (SSE, storage_encrypted, encryption_configuration) referencing the CMK.
enable_key_rotation = trueon the CMK; no shared keys across stacks.pytest+run_ci.shgreen.
- Every primitive has
Phase 32 — deletion-protection-by-default-and-l2-feature-flag
- Description: Add
deletion_protectionNFR (boolean, default true) to every L1 primitive. Adapter emitslifecycle { prevent_destroy = true }when true; omits it when false. L2 modules exposefeatures.deletion_protectionflag (default true); resolver propagates to each child's NFR. Consumers can setinputs.deletion_protection: falsein contract. Update contract schema. - Status: complete (v1.8.0)
- Depends on: [31]
- Requirements: REQ-86, REQ-87
- Success Criteria:
- Every primitive has
deletion_protectionNFR defaulting to true. - Adapter emits
prevent_destroy = truewhen true; omits when false. - L2 feature flag propagates to all children.
pytest+run_ci.shgreen.
- Every primitive has
Phase 33 — uptime-kuma-primitive
- Description: Create
uptimeL1 primitive (ECS Fargate runninglouislam/uptime-kuma:1). Inputs: container_image, region, monitored_endpoints (array of {name, url, type, interval, timeout}), static_checks, alert_channels ({teams_webhook, email_addresses, sms_numbers, github_issue_repo}), feature_flag_enabled (default true), cpu, memory. Outputs: uptime_url, service_arn, task_definition_arn. NFRs: deletion_protection, encryption_enabled. Adapter emits ECS service + ALB + log group; no resources when feature_flag_enabled=false. Register in registry. Adddeploy-uptimepipeline stage (separate state, after publish-outputs) topipelines/deploy.yaml+ both deploy workflows.run_platform.shconstructs synthetic uptime contract from L2 outputs + runs second terraform apply. Uptime URL published via PR comment. Feature flag frominputs.uptime_enabled(default true). - Status: complete (v1.8.0)
- Depends on: [32]
- Requirements: REQ-88, REQ-89, REQ-90, REQ-91
- Success Criteria:
- Uptime primitive exists with feature flag, monitored endpoints, alert channels.
- Deployed by default after L2 module (separate state); endpoints passed from L2 outputs.
- Uptime URL published via PR comment.
- Feature flag disables deployment (no resources emitted).
deploy-uptimestage in deploy contract + byte-identical workflows.pytest+run_ci.shgreen.
Phase 34 — decommission-alias-and-cmdb-validation
- Description: Add
mode: decommissionto deploy pipeline. Stages: validate-change-request (Lambdavalidate_change_requestaction queries DynamoDBacdl-change-requeststable, asserts status=approved) → disable-deletion-protection (resolve contract with deletion_protection=false, terraform plan/apply, HITL SRE gate) → zero-counts (resolverdecommission_transformzeroes all counts, terraform plan/apply, second HITL SRE gate) → confirm-decommission. Addacdl-change-requestsDynamoDB table to terraform/platform/main.tf. Addvalidate_change_requestto contract_ingestor.py. Document indocs/CONSUMER_GUIDE.md. - Status: complete (v1.8.0)
- Depends on: [33]
- Requirements: REQ-92, REQ-93, REQ-94
- Success Criteria:
- Decommission mode works via existing deploy pipeline with 2-step HITL SRE gates.
- CR ID validated against DynamoDB CMDB (status must be approved).
decommission_transformzeroes all counts.- Documented in consumer guide.
pytest+run_ci.shgreen.
Phase 35 — module-engineering-standards
- Description: Scan all current modules to generate
modules/STANDARDS.md— comprehensive L1+L2 authoring + code review standards: required files, interface schema, input/output/NFR conventions, encryption + deletion protection as mandatory NFRs, naming, multi-resource pattern, adapter extension pattern (TYPE_MAP + INPUT_MAP + OUTPUT_MAP + specialized branches), code review checklist. Fixmodules/README.mdcatalog index (add rds + uptime + kms-key). Updatemodules/README-TEMPLATE.mdwith## NFRssection. Addtests/test_module_standards.pyfor automated enforcement. - Status: complete (v1.8.0)
- Depends on: [34]
- Requirements: REQ-95, REQ-96
- Success Criteria:
modules/STANDARDS.mdexists with L1+L2 authoring + review standards.- Catalog index includes all primitives; template has NFRs section.
- Automated standards test passes for all modules.
pytest+run_ci.shgreen.
Phase 36 — schemas-adapters-pipelines-readmes
- Description: Author
schemas/README.md(how to write schemas, wire into platform, test in CI, dependencies, existing catalog),pipelines/README.md(how to write pipeline contracts, wire into workflows, test, dependencies, catalog),adapters/README.md(how to write adapters, wire into platform, test, dependencies, catalog). Addtests/test_docs_coverage.pyto validate presence + required sections. - Status: complete (v1.8.0)
- Depends on: [35]
- Requirements: REQ-97, REQ-98, REQ-99
- Success Criteria:
- All 3 READMEs exist with comprehensive documentation.
- CI validates their presence.
pytest+run_ci.shgreen.
Phase 37 — verify
- Description: 4-layer verification (structural, behavioral, security, quality) of all v1.8 phases. Re-verify each P1 (P1-3..P1-9 + S1) is resolved. Verify all new features (encryption, deletion protection, uptime, decommission, standards, docs) have dedicated tests.
- Status: complete (v1.8.0)
- Depends on: [36]
- Requirements: —
- Success Criteria:
- All 4 layers pass; each P1 fix + each new feature has a dedicated test.
pytestpasses (~358 tests);run_ci.shexits 0;run_platform.sh --check-onlyexits 0.
Phase 38 — review-audit-complete
- Description: Multi-persona code review across the full v1.8 diff. Audit (reconstruction, file discipline, branch hygiene, commit discipline). Complete: update REQUIREMENTS.md (REQ-76..99), ROADMAP.md (v1.8 complete), PROJECT.md. Tag
v1.8.0. Update floatingv1.8+v1tags. Bumpuses:/ref:from@v1.6to@v1.8. - Status: complete (v1.8.0)
- Depends on: [37]
- Requirements: —
- Success Criteria:
- Review: 0 new P0/P1; all P1-3..P1-9 + S1 resolved; 3 new requirements delivered.
- Audit: clean; 0 outstanding issues.
- Tag
v1.8.0created; floating tags updated.
After Phase 38: COMPLETE gate — review → ship v1.8.0 → audit.
v1.9 (complete — design doc refresh + contract interpolation + per-env CI jobs + stub implementation + P1-1 remediation, tag v1.9.0)
The v1.9 milestone closes four gaps left by v1.8 (user-directed,
2026-07-23): stale design docs, no contract interpolation, promotion
requires editing the environment field, and unimplemented stubs. It
also closes P1-1 (adapter hardcoded defaults, deferred from v1.2).
Phase 39 — design-doc-refresh-and-p1-1-parameterization
- Description: Refresh
core/hitl_matrix_design.md(no stale "dev-only spike"/"v1.2 wires the gates" framing; v1.9 wiring section; 8-concern matrix marked implemented offline-testable subset) +core/audit_ledger_design.md(outbox marked shipped+production since v1.8; S3 Object Lock + JWS + worker + DLQ + checkpoints deferred D-083). P1-1: move adapter ECS/ALB/VPC hardcoded defaults (desired_count,launch_type,family,target_type,load_balancer_type,Nametags) into L1interface.jsoninputs with defaults; the adapter reads from inputs; the resolver routes wires to the sub-resource that declares the input. - Status: complete (v1.8.1)
- Depends on: —
- Requirements: REQ-100, REQ-101, REQ-102
- Success Criteria:
- Both design docs refreshed; no stale framing;
test_design_docs_current.pypasses. - Adapter has no hardcoded ECS/ALB/VPC defaults; overrides flow through;
test_p1_1_adapter_parameterization.pypasses. - v1.1 S3 regression passes;
pytest371 (was 350, +21);run_ci.shexits 0;run_platform.sh --check-onlyexits 0.
- Both design docs refreshed; no stale framing;
Phase 40 — contract-interpolation
- Description:
${env.<field>}+${contract.<field>}resolver expansion from environment onboarding JSON (D-081). Environment JSON schema (schemas/environment.schema.json) + qa/prod/dr placeholder bindings.core/environment_check.pygainsload(). Sample contracts use naming patterns that include region, account id, environment (e.g.acdl-${env.environment}-${contract.module}-${env.account_id}-${env.region}). Expansion is recursive (D-087), post-schema-validation, pre-IR-resolution; unknown tokens raiseValueError.resolve()acceptsenvironment_override(D-088). - Status: complete (v1.8.2)
- Depends on: [39]
- Requirements: REQ-103, REQ-104
- Success Criteria:
schemas/environment.schema.jsonexists; 4 env files validate;load()works._expand_varsin resolver; unknown tokens raise; recursive over dicts/lists/strings.- Sample contracts use
${env.*}+${contract.*}naming patterns; resolve to concrete values. tests/test_environment_schema.py+tests/test_interpolation.py+tests/test_sample_contracts_interpolate.pypass.pytest406 (was 371, +35);run_ci.shexits 0;run_platform.sh --check-onlyexits 0.
Phase 41 — per-environment-ci-jobs
- Description: Per-env contract files (static-assets + microservice × dev/qa/prod/dr, REQ-105) using interpolation. Deploy workflow (
.github+.gitea, byte-identical) declares anenvironmentworkflow_callinput (REQ-106);run_platform.sh --environment <name>overrides the contract's environment at load time (D-088, before schema validation + interpolation).resolve()acceptsenvironment_override. Consumer guide documents the per-env caller-workflow pattern (4 jobs, one per environment) + HITL gate structure (approve_qa/approve_prod/approve_dr, D-042) + interpolation reference table. Promotion = running the matching job; no environment field editing. - Status: complete (v1.8.3)
- Depends on: [40]
- Requirements: REQ-105, REQ-106
- Success Criteria:
- 8 per-env contract files exist + validate + resolve to correct env.
- Deploy workflow has
environmentinput (byte-identical Gitea + GitHub);run_platform.sh --environmentoverrides; resolver supportsenvironment_override. - Consumer guide documents per-env caller workflows + promotion-without-editing + HITL gates + interpolation reference.
tests/test_per_env_contracts.py+tests/test_deploy_workflow_env_input.py+tests/test_consumer_guide_per_env_section.pypass.pytest446 (was 406, +40);run_ci.shexits 0; both deploy workflows byte-identical.
Phase 42 — stub-implementation
- Description:
route_halt_artifactreal (SNS publish + outbox fallback, REQ-107) + SNS topicacdl-sod-haltinterraform/platform/main.tf. HITL attestation gates (core/hitl_gates.py, REQ-108) — records approver to outbox, runs SoD on prod, invokes the attestation matrix;run_platform.shcallsattestbefore apply for qa/prod/dr (dev skips). 8-concern attestation matrix (core/attestation_matrix.py, REQ-109, D-084) — offline-testable concerns run for real; operator-supplied concerns accept signed evidence artifacts validated for freshness + schema; signature skip whenACDL_ATTESTATION_SIGNING_KEY_IDunset (D-089). Wiz real API client (WizClient, REQ-110) — GraphQL queries + pagination + graceful degrade. Kyverno translator fleshed out (REQ-111) — full PolicyReport mapping + skip-with-reason + inactive-for-TF guard +--kube-versionstub. - Status: complete (v1.8.4)
- Depends on: [41]
- Requirements: REQ-107, REQ-108, REQ-109, REQ-110, REQ-111
- Success Criteria:
route_halt_artifactpublishes to SNS when ARN set; outbox fallback when unset; SNS topic in Terraform.hitl_gates.attestrecords approver; SoD blocks on identity equality; dev skips;run_platform.shhas the HITL step.attestation_matrix.checkruns 8 concerns; offline concerns pass; operator-supplied missing → block for prod; expired → block; signature skip when key unset.- Wiz
WizClientreal client + pagination + graceful degrade;fetch_and_adapttranslates. - Kyverno full mapping (pass/fail/skip/warn + severity + skip-with-reason + resource construction); inactive guard preserved;
--kube-versionparsed. tests/test_route_halt_artifact.py+test_hitl_gates.py+test_attestation_matrix.py+test_wiz_adapter_real_client.py+ expandedtest_kyverno_adapter.pypass.pytest493 (was 446, +47);run_ci.shexits 0;run_platform.sh --check-onlyexits 0.
Phase 43 — verify-review-audit-complete
- Description: 4-layer verify (structural, behavioral, security, quality) of all v1.9 phases. Multi-persona review (0 P0, 0 P1). Audit (reconstruction, file discipline, branch hygiene, commit discipline — all clean). REVIEW.md reconstructed (D-086). Complete: update REQUIREMENTS.md (REQ-100..111), ROADMAP.md, PROJECT.md. Tag
v1.9.0; update floatingv1.9+v1tags. Bumpuses:/ref:from@v1.6→@v1.9. - Status: complete (v1.9.0)
- Depends on: [42]
- Requirements: —
- Success Criteria:
- 4-layer verify PASS; 493 tests;
run_ci.sh+run_platform.sh --check-onlygreen. - Review: 0 P0, 0 P1; REVIEW.md reconstructed with v1.9 content (D-086).
- Audit: clean; all 12 v1.9 commits have
---ci---blocks. - Tag
v1.9.0created; floating tags updated;uses:bumped to@v1.9.
- 4-layer verify PASS; 493 tests;
After Phase 43: COMPLETE gate — review → ship v1.9.0 → audit. DONE.
v1.10 (complete — pipeline regression fix + capability re-verification + verified-reality rewrite, tag v1.10.0)
The v1.10 milestone corrects a structural defect and a credibility gap surfaced in the 2026-07-27 CLARIFY/RESEARCH stages:
- VERIFY is diff-scoped — it checks the phase diff only, never re-runs underlying capability. 8 NFR-patch phases (v1.9.1→v1.9.8) passed VERIFY while the platform decayed underneath.
- Advertised capability is not currently reproducible — v1.2 ECS E2E and v1.7 pipelines ran once historically but decayed; decks presented them as current without disclosing the decay.
- Deck work was sequenced backwards — re-verify → rewrite → polish is the honest order; v1.9.x did it backwards for 8 phases.
User decisions: D-090 (no cap on sweep; fix everything; unbounded risk accepted), D-091 (regression-class VERIFY), D-092 (local emulating adapters), D-093 (re-verify v1.1→v1.8; v1.0 demo excluded), D-094 (rewrite docs/decks to verified reality; unfreeze decks).
Phase 52 — pipeline-regression-verify-fix
- Description: Add a regression-class VERIFY that re-runs capability checks (not just diff checks), at minimum on milestone completion. Regression run executes the local-emulator tier for every capability marked Verified in prior milestones; any failure blocks milestone completion. Records
regression: { capability, status }in---ci---blocks. - Status: complete (v1.9.9)
- Depends on: —
- Requirements: REQ-112
- Success Criteria:
- VERIFY supports
regressionmode; milestone completion requires a clean regression run. - A regression run against current code surfaces decay (fails closed).
tests/test_verify_regression_mode.pypasses.
- VERIFY supports
Phase 53 — local-emulating-adapters
- Description: Build local emulating adapters so the platform is fully locally testable without cloud credentials: flat-file DynamoDB outbox, local ECS emulator (synthetic HTTP 200 from local shell), local S3 state backend (flat-file tfstate), local Lambda stub (in-process handler invocation). Same interfaces as the live adapters.
- Status: complete (v1.9.10)
- Depends on: [52]
- Requirements: REQ-113
- Success Criteria:
- All local adapters exist; headline E2E runs end-to-end against the local tier with no cloud credentials.
tests/test_local_emulating_adapters.pypasses.run_platform.sh --localruns the full pipeline locally.
Phase 54 — v1.1-v1.8 capability-reverification-sweep
- Description: Enumerate every capability advertised in v1.1→v1.8 PROJECT/ROADMAP to
.ciagent/CAPABILITY_INVENTORY.md. Re-verify each: headline E2E at both tiers (live AWS + local emulator, both must pass); all other capabilities at the local tier via emulating adapters. Tag each Verified/Decayed/Broken. Fix every Decayed/Broken capability in-sweep (D-090: no cap; all must end Verified) until Verified. v1.0 demo excluded as archived/superseded. - Status: complete (v1.9.11)
- Depends on: [53]
- Requirements: REQ-114
- Success Criteria:
- Every v1.1→v1.8 advertised capability is tagged Verified in
CAPABILITY_INVENTORY.md. - Headline E2E passes at both tiers.
- Regression run (Phase 52) is clean against the re-verified state.
- Every v1.1→v1.8 advertised capability is tagged Verified in
Phase 55 — rewrite-to-verified-reality
- Description: Rewrite PROJECT.md (add "Capability Status (Re-Verified 2026-07-27)" section + decay disclosure), ROADMAP.md (v1.9.x entries noted as deck-freeze / superseded-by-reverification), and both leadership decks so every capability claim reflects the re-verified status. Remove any claim that cannot be demonstrated live. Re-render HTML; upload PPTX to the v1.10.0 release. Decks unfrozen only after this lands.
- Status: complete (v1.9.12)
- Depends on: [54]
- Requirements: REQ-115
- Success Criteria:
- PROJECT/ROADMAP/decks match
CAPABILITY_INVENTORY.mdexactly. ci-doc-verifierconfirms no stale capability claims remain.- Decks unfrozen; v1.10.0 tagged; Gitea release published.
- PROJECT/ROADMAP/decks match
After Phase 55: COMPLETE gate — review → ship v1.10.0 (next minor;
fix/test/docs, not a breaking schema change) → audit. DONE.
v1.11 (complete — RESTART: stateless adapter + pipeline-driven module lifecycle testing, tag v1.11.0)
The v1.11 milestone closes the two GRILL escalations blocking the leadership pitch: G-005 (6 IAM-gated cloud capabilities CAP-017..022 deploy-unverified) and G-008 (no cost documentation despite live AWS resources).
Why a restart. The first v1.11 attempt (P56 IAM re-bootstrap + P57
live-deploy-microservice, branches phase/56-iam-re-bootstrap +
phase/57-live-deploy-microservice, now abandoned) produced five defects:
(1) 4 VPCs created when 1 should have — the adapter emitted per-contract
state keys with no VPC sharing; (2) Python scripts made lifecycle changes
directly to the cloud (verify_deploy_microservice.py ran terraform apply -auto-approve); (3) no L1 module lifecycle testing — tests/test_adapter.py
only string-validated HCL, never ran terraform apply/modify/destroy; (4) no
L2 integration testing; (5) lifecycle was managed by Python, not terraform.
The restart branches off v1.10.2 and rebuilds v1.11 on three corrections.
The three corrections.
- Stateless adapter.
adapters/terraform/adapter.py(918 lines, 3 hardcoded constant tablesTYPE_MAP/INPUT_MAP/OUTPUT_MAP, 39 type-specific branches) is rewritten to a ~80-line stateless assembler. Each L1 module ships a realterraform/module dir (versions.tf/variables.tf/locals.tf/main.tf/outputs.tf) owning its resource shape, nested HCL blocks, and defaults. The adapter reads the registry, emits a rootmain.tfinstantiating each L1 asmodule "x" { source = "..." ... }with resolved inputs and wired refs.interface.jsonstays engine-agnostic; the terraform dir is the engine binding. Defaults move intolocals.tf(heavy interpolation of vars against sensible defaults). - Terraform owns lifecycle.
scripts/run_platform.shgains--applyand--destroymodes. Python never runs terraform.scripts/verify_deploy_microservice.pyis deleted. The shell owns all apply/modify/destroy; Python only orchestrates the shell (and may use boto3 for read-only verify probes in a future QA milestone, not this one). - Pipeline-driven testing. A
modules-lifecyclepipeline (Gitea + GitHub, byte-identical) matrix-runs each L1 module'sexamples/{simple,complex}.ymlcontracts through apply→modify→destroy against live AWS. No per-module Python/pytest. The "test" = the pipeline cell going green (terraform apply exit 0 → modify exit 0 → destroy exit 0).
Single platform VPC. terraform/platform/main.tf owns ONE VPC; the
microservice composition drops its vpc child and references the platform
VPC via data source. The standalone vpc L1 module stays (consumers
deploy their own VPCs). State keys are deterministic and env-aware
(spike/{contract.id}/{contract.environment}/terraform.tfstate), stable
across apply/modify/destroy — the same contract+env always hits the same
state key, so terraform modifies rather than duplicates.
L2 = composition only. L2 modules keep composition.json only (no L2
terraform files). The composition must be deterministic: same contract →
same resolved stack → same state key, every time.
Versioning. Feature milestone (P56a/P56b/P57/P58/P59/P60/P61/P62 are
feat). Ship tag at milestone COMPLETE: v1.11.0 (v1.10.2 → v1.11.0).
Wave ordering. Wave 1 (P56a → P56b → P57 → P58) is sequential — the stateless adapter, shell lifecycle modes, and platform VPC are prerequisites for all testing. Wave 2 (P59 → P60) authors then runs the L1 lifecycle pipeline. Wave 3 (P61 → P62) authors then runs the L2 lifecycle pipeline. Wave 4 (P63 → P64 → P65) closes G-005/G-008 + teardown + deck rewrite.
Phase P56a — stateless-adapter-rewrite (Wave 1)
- Description: Rewrite
adapters/terraform/adapter.pyfrom a 918-line monolith (3 constant tables + 39 type-specific branches) to a ~80-line stateless assembler. Authormodules/l1/s3/terraform/(versions.tf/variables.tf/locals.tf/main.tf/outputs.tf) as the reference module proving the assembly path end-to-end. Extendmodules/registry.jsonwith aterraform_dirfield. Rewritemodules/STANDARDS.md§8 from "three tables + specialized branches" to "stateless assembler + per-module terraform dir". Rewritetests/test_adapter.pyto assert module-instantiation assembly (rootmain.tfcontainsmodule "x" { source = ... }blocks with correct inputs + refs), not HCL string matching. - Status: active
- Depends on: —
- Requirements: REQ-123
- Success Criteria:
grep -n "TYPE_MAP\|INPUT_MAP\|OUTPUT_MAP\|rtype ==" adapters/terraform/adapter.pyreturns nothing.wc -l adapters/terraform/adapter.py< 100.modules/l1/s3/terraform/passesterraform init + validatestandalone.- Adapter, given the s3 instance, emits a root
main.tfthatterraform init + validateaccepts.
Phase P56b — l1-module-terraform-authoring (Wave 1)
- Description: Author the remaining 11 L1 module terraform subdirs (
vpc,ecs-cluster,ecs-service,iam-role,alb,ecr,cloudfront,waf,rds,kms-key,uptime) with the fullversions.tf/variables.tf/locals.tf/main.tf/outputs.tfsplit. Defaults currently hardcoded in the adapter (CIDR blocks, assume_role_policy JSON, ECR/logs inline policy, Fargate requires_compatibilities, assign_public_ip, listener/target ports) move intolocals.tfas heavy interpolation of vars against sensible defaults. Multi-resource modules get the full split; trivial single-resource modules (kms-key, ecr) may inline locals in main.tf. Each module'sinterface.jsonstays engine-agnostic. Addterraform_dirto each registry entry. - Status: pending
- Depends on: [P56a]
- Requirements: REQ-124
- Success Criteria:
- All 12
terraform/subdirs passterraform init + validatestandalone. - No defaults remain in the adapter.
- Each registry entry has a
terraform_dirfield.
- All 12
Phase P57 — shell-orchestrator-lifecycle-modes (Wave 1)
- Description:
scripts/run_platform.shgains--apply <contract.yml>and--destroy <contract.yml>modes.--applyruns resolve → adapter →terraform init→terraform apply -auto-approve(HITL gate for qa/prod/dr).--destroyruns resolve → adapter →terraform destroy -auto-approve(gated behind--decommission+ CR validation, D-070 two-step).--modifyis implicit (a second--applywith a changed contract produces a terraform diff). Deletescripts/verify_deploy_microservice.py(the offending script that ranterraform applyfrom Python). - Status: pending
- Depends on: [P56b]
- Requirements: REQ-125
- Success Criteria:
run_platform.sh --applyand--destroymodes exist and are the ONLY path to terraform apply/destroy.grep -rn "terraform apply\|terraform destroy" scripts/*.pyreturns nothing.verify_deploy_microservice.pyno longer exists.
Phase P58 — single-platform-vpc-deterministic-state (Wave 1)
- Description: Add a single VPC (
aws_vpc.acdl_shared10.0.0.0/16, 2 public subnets, IGW, route table, ECS security group) toterraform/platform/main.tf; outputvpc_id,public_subnet_ids,ecs_security_group_id.modules/l2/microservice/composition.jsondrops thevpcchild and references the platform VPC via adata_sourcesblock.core/contract_resolver.pyresolvesdata:platform/vpcreferences. The adapter emitsdata "terraform_remote_state" "platform"+data "aws_vpc"/data "aws_subnets"blocks, never an inlineaws_vpcfor the microservice stack. State key fix:spike/{contract.id}/{contract.environment}/terraform.tfstate(deterministic, env-aware, stable across lifecycle). Addstate_keyderivation toschemas/contract.schema.json. - Status: pending
- Depends on: [P57]
- Requirements: REQ-126
- Success Criteria:
terraform/platformapply creates exactly ONE VPC.contracts/microservice.ymlresolution produces NOaws:ec2:vpcresource.- Two contract applies (dev + prod) → ONE VPC, two state keys, two ECS services.
- Same contract+env re-applied → same state key → terraform modifies, never duplicates.
Phase P59 — l1-lifecycle-pipeline-author (Wave 2)
- Description: Author
pipelines/modules-lifecycle.yml(declarative contract: validate → resolve → apply → modify → destroy) + byte-identical.gitea/workflows/modules-lifecycle.yml+.github/workflows/modules-lifecycle.yml. Matrix over 12 L1 modules × {simple, complex} example contracts. Each cell:run_platform.sh --apply examples/simple.yml→run_platform.sh --apply examples/complex.yml(same state key → terraform modifies) →run_platform.sh --destroy examples/complex.yml. VPC-dependent L1s (alb, ecs-service, rds, uptime) reference the platform VPC applied by a prerequisite job; standalonevpcL1 applies its own. Trigger:pull_request: [main]+workflow_dispatch. Authorschemas/modules-lifecycle-pipeline.schema.json. Extendtests/test_pipeline_contract.py(offline: validate schema + byte-identical). - Status: pending
- Depends on: [P58]
- Requirements: REQ-127
- Success Criteria:
- Pipeline YAML validates against its schema.
- Gitea + GitHub workflows are byte-identical.
test_pipeline_contract.pypasses (offline).- Matrix lists all 12 L1 modules × 2 examples.
Phase P60 — l1-lifecycle-pipeline-live-run (Wave 2)
- Description: Run the P59 pipeline against live AWS; fix every module whose apply/modify/destroy fails. Each failing cell is a module defect: bad
terraform/subdir (resource shape, nested blocks, defaults), bad example contract, or bad adapter assembly. Fixes land inmodules/l1/<module>/terraform/*.tf,modules/l1/<module>/examples/*.yml, and rarely the adapter assembler. No new Python files. - Status: pending
- Depends on: [P59]
- Requirements: REQ-127
- Success Criteria:
- Full L1 lifecycle matrix green: 12 modules × 2 examples = 24 cells, each apply→modify→destroy exit 0.
- No live resources remain after the run (destroy enforced).
primitives-plan.yml(plan-only) still passes.
Phase P61 — l2-lifecycle-pipeline-author (Wave 3)
- Description: Extend
pipelines/modules-lifecycle.yml+ both forge workflows with an L2 matrix:static-assets×contracts/static-assets.yml(apply → modify: add WAF rule → destroy) andmicroservice×contracts/microservice.yml(apply → modify:desired_count1→2 → destroy, references platform VPC). Authormodules/l2/static-assets/examples/complex.yml+modules/l2/microservice/examples/complex.yml(modify variants, defined within the modules). L2 = composition only (no L2 terraform files); the composition must be deterministic (same contract → same resolved stack → same state key, every time). - Status: pending
- Depends on: [P60]
- Requirements: REQ-128
- Success Criteria:
- L2 matrix lists both modules with apply→modify→destroy cells.
- Composition resolution is deterministic (same contract → same stack, byte-identical).
Phase P62 — l2-lifecycle-pipeline-live-run (Wave 3)
- Description: Run the L2 lifecycle pipeline live; fix composition wiring + adapter assembly until green. This replaces the deleted
verify_deploy_microservice.py— the pipeline IS the verify. CAP-017..022 boto3 probes are deferred to a future QA milestone. Fixes land inmodules/l2/<module>/composition.json,modules/l2/<module>/examples/*.yml,core/contract_resolver.py, and rarely the adapter. No new Python files. - Status: pending
- Depends on: [P61]
- Requirements: REQ-128
- Success Criteria:
- L2 matrix green: static-assets + microservice, each apply→modify→destroy exit 0.
- Microservice apply creates NO inline VPC (references platform VPC).
- Same state key across apply/modify/destroy (deterministic).
patterns-plan.yml(plan-only) still passes.
Phase P63 — regression-registry-cost-docs (Wave 4)
- Description: Add CAP-017..022 to
core/regression_verify.pyregistry (evidence = lifecycle pipeline green, not boto3 probes). Author.ciagent/COST.md(AWS Cost Explorer 6-day window query: v1.0 ship 2026-07-21 → v1.10 complete 2026-07-27; document monthly + per-day if available). Closes G-008. - Status: pending
- Depends on: [P62]
- Requirements: REQ-119, REQ-121
- Success Criteria:
- Regression registry includes CAP-017..022 with "lifecycle pipeline green" evidence.
COST.mddocuments the v1.0→v1.10 spend window.
Phase P64 — pre-mortem-teardown (Wave 4)
- Description: Author
.ciagent/PRE_MORTEM.md(v1.10 decay root cause + forward pre-mortem for the OSS reference + leadership pitch).run_platform.sh --decommissionwith CR CHG0680001 — tears down ALL deployed stacks INCLUDING the 4 drifted VPCs from the failed first attempt. HITL SRE gates (D-070 two-step). D-096 enforced (live resources do not persist past v1.11). - Status: pending
- Depends on: [P63]
- Requirements: REQ-120, REQ-122
- Success Criteria:
PRE_MORTEM.mddocuments the decay root cause + forward pre-mortem.- All deployed stacks torn down; zero live ACDL resources remain.
Phase P65 — rewrite-caps-decks (Wave 4)
- Description: Rewrite
CAPABILITY_INVENTORY.md,PROJECT.md§Capability Status, and both leadership decks: CAP-017..022 → "Verified live-aws via lifecycle pipeline ; torn down to zero-cost steady state." Remove the IAM-drift framing. Add the cost appendix slide (P63) + pre-mortem reference (P64). Re-render HTML; upload PPTX to the v1.11.0 release.ci-doc-verifierconfirms no stale "deploy-unverified" claims remain. - Status: pending
- Depends on: [P64]
- Requirements: REQ-116, REQ-118
- Success Criteria:
- CAPABILITY_INVENTORY + PROJECT + decks all reflect "Verified live-aws via lifecycle pipeline; torn down to zero-cost."
ci-doc-verifierconfirms no stale "deploy-unverified" claims.- HTML re-rendered; PPTX uploaded to v1.11.0 release.
After Phase P65: COMPLETE gate — review → ship v1.11.0 (next minor;
feature milestone) → audit. DONE.
v1.12 (complete — Presentation Refinement, tag v1.12.0)
The v1.12 milestone refines the leadership presentation decks to reflect the verified reality after v1.11. The v1.11 P65 deck-rewrite task did not fully land on the deck artifacts: the rendered HTML still claimed 6 cloud capabilities were "deploy-unverified (IAM drift)", the road-to-north-star diagram still showed v1.10 as "NEXT", and the v1.11 architecture stories (stateless adapter, pipeline-driven lifecycle testing) were absent. The v1.10 decay lesson (PRE_MORTEM.md FM-3) requires decks to match verified reality exactly, not outrun it.
Scope: leadership decks only (docs/presentations/) across all four
layers (source markdown, Marp deck, rendered HTML, talking points) +
diagrams + README. Plus one real adapter fix + two probe fixes required to
make the deck claims true, and a CI lifecycle-mode flag (REQ-134) that
defaults the lifecycle tests to plan-only.
Why the code fixes. The v1.12 regression gate run (Phase 66) found CAP-013 (a real adapter dedup defect — multi-resource L1s produced invalid Terraform) + CAP-017/018 (two regression-probe bugs). The inventory's "22/22 Verified" claim was overstated until CAP-013 was fixed. The pre- mortem mitigation (verified-only claims) made the fixes mandatory.
Why the lifecycle flag. The lifecycle pipeline defaulted to full
apply→modify→destroy, which requires AWS credentials + cost on every PR.
REQ-134 adds the ACDL_LIFECYCLE_MODE CI variable (workflow_dispatch
input lifecycle_mode, default plan) so the pipeline runs plan-only on
every PR (fast, no AWS mutation, no cost) and full only on override.
Phase breakdown (6 phases)
- P66 — init + research. Drift audit (9 items) comparing
docs/presentations/*against v1.11-verified reality. Regression gate (D-091) re-run surfaced 3 Broken capabilities; root-cause analysis classified CAP-013 (real adapter defect), CAP-017/018 (probe bugs). REQ-129..133 added. - P67 — fix adapter dedup + 2 probe bugs (REQ-129/130). The adapter's module-call dedup logic rewritten: multi-resource L1s (ecs-service, alb) now emit ONE module block named by the composition child id, with expanded sub-ids rewritten via id_remap (stack outputs + cross-module ref: inputs). terraform validate succeeds for the microservice; adapter 192 lines (< 200 gate). CAP-017 probe: locals.tf conditional on local.* usage. CAP-018 probe: LocalLambdaStub constructed with the required outbox arg. Regression gate: 22/22 Verified.
- P67b — lifecycle tests plan-only default + ACDL_LIFECYCLE_MODE flag (REQ-134). The four lifecycle scripts dispatch to --plan-only (plan mode, default) or --apply/--destroy (full mode). Both workflows (byte-identical) expose lifecycle_mode as a workflow_dispatch input; CI VPC jobs skipped in plan mode. 24 new tests.
- P68 — sync decks source .md (REQ-131/132). Re-verification headers → 22/22 Verified. De-duplicated story-beat lines. Version refs @v1.10 → @v1.11. road-to-north-star.mmd re-rendered. New A6 (real COST.md figures + pre-mortem) + A7 (stateless adapter + lifecycle pipeline + plan-only default) in both decks.
- P69 — Marp + talking points + HTML render (REQ-133). Re-synthesized both Marp decks (10 main + 7 appendix = 17 slides). Re-distilled both talking-points files (added the missing A6/A7 sections). Re-rendered both HTML (committed). Exported both PPTX (held for the v1.12.0 release).
- P70 — verify + review + complete. Multi-persona code review: no P0; 2 P1 testing gaps remediated (6 CAP-013 regression tests added — terraform validate + dedup unit assertions). Audit clean. 522 tests pass. Ship v1.12.0.
Outcome: the decks now honestly claim 22/22 Verified (backed by the regression gate), reflect the v1.11 architecture (stateless adapter + lifecycle pipeline), carry the real cost figures + pre-mortem, and the lifecycle pipeline defaults to plan-only. The v1.10 "deploy-unverified (IAM drift)" framing is disclosed as closed, not hidden.
Ship tag at milestone COMPLETE: v1.12.0 (v1.11.0 → v1.12.0; feature
milestone — includes the adapter fix + lifecycle flag). DONE.
v1.13 (complete — Presentation Polish, tag v1.13.0)
The v1.13 milestone polishes both leadership decks for clarity, impact, and storytelling best practices. It is a docs-only NFR patch — no code, no capability claims changed, no schema changes.
Why. The v1.12 decks were factually correct but rhetorically flat: category-name headlines ("The Contract-Driven Model", "Zero-Trust by Default"), dense 5–6 bullet slides, formulaic italic transition lines on every slide, and body fonts at 22px (below the 24pt readability floor). v1.13 applies the storytelling + design best practices the leadership audience requires.
What changed. Both decks (how-the-platform-works + the-developer-experience)
across all 4 pipeline layers (source .md → -marp.md → .html →
-talking-points.md):
- Action headlines replace category names — each slide title states the takeaway, not the topic ("One YAML file. The platform owns everything else." not "The Contract-Driven Model").
- Story-arc restructure — Intro ~10% / Body ~80% (3–5 points) / Conclusion ~10%. Before/after 2-slide sequence on Problem → North Star.
- Removed all
<em class="story">transition lines — flow now carried by action headlines + talking points (saved ~15–20 words × 17 slides). - Bullets ≤12 words, 3–4 per main slide (was 5–6). Cut parentheticals, sub-clauses, redundant restatements.
- Larger fonts — body 22→26px, h1 34→40px, h2 26→32px, blockquote 20→24px. High contrast preserved, no animations, maturity badges intact.
- 6 new mermaid diagrams → PNGs:
platform-works-02-frictions(2×2 quadrant of the four frictions)platform-works-03-north-star(before/after: today's queue vs. ACDL)platform-works-07-zero-trust(OIDC + ABAC flow)developer-experience-05-catalog(primitives → composed modules)developer-experience-07-decommission(6-node gate flow with 2 SRE gates)developer-experience-08-semver(floating/pinned/major-only timeline)
- Appendix expanded — "Security by Construction" (formerly a dense main slide) moved to appendix A3; platform deck now 10 main + TOC + 8 appendix (19 slides); developer deck 10 main + TOC + 7 appendix (18 slides).
Phases:
- P71 — deck polish (single phase). Restructured both decks across all
4 layers. Created 6 new
.mmd+ 6 new.pngfiles. Re-rendered both HTML. Re-distilled both talking-points to match the new slide structure. Multi-persona code review: 0 P0, 2 P1 auto-fixed (slide-count metadata in source.mdheaders +README.mddirectory layout drifted — both synced). 522 tests pass. No code files touched.
Outcome: the decks now read as a story (problem → solution → evidence), each slide has one idea with an action headline, the body is scannable in 2 seconds, and the visuals carry the mechanism where bullets undersold it. 22/22 Verified framing, badge statuses, and capability claims preserved verbatim from v1.12. No factual drift.
Ship tag at milestone COMPLETE: v1.13.0 (v1.12.0 → v1.13.0; docs-only NFR
patch — final patch IS the deliverable, no separate milestone tag).
DONE.
v1.13.1 (complete, tag v1.13.1): config.json schema migration
NFR patch: regenerated .ciagent/config.json to the updated CIAgent v2 config
structure. The old config used the pre-v2 schema (mode field,
projects[].milestone/status/branch/tag, top-level gitea block, missing
secrets/release/ship/backend/ideation/personas/logging/telemetry
sections). The new config conforms to CIAgentConfig (config.ts:156) and passes
validateConfig() + loadConfig() deep-merge.
Multi-persona code review: 0 P0, 2 P1/P2 auto-fixed (.ciagent/logs/ gitignored,
trailing newline restored). Gitea release id 253. Docs-only NFR patch (no code
changes).
v1.13.2 (complete, tag v1.13.2): presentation badge cleanup + platform architecture diagram
NFR patch (docs-only). Two presentation changes across both leadership decks
(how-the-platform-works + the-developer-experience):
- Badge cleanup — removed all
testingandagenticmaturity badges from every deck layer (source.md, Marp-marp.md, rendered.html, talking-points). Only theplannedbadges are retained where relevant. The Marp inlinestyle:CSS dropped the.testing/.agenticrules (kept.planned). The README maturity-framing section updated to describe only thePlannedbadge. Empty table cells (dev environment Maturity row) normalized to—. - Platform architecture diagram — added a new Slide 3 "The platform at a
glance" to both decks, right after the problem statement. A shared mermaid
source (
assets/mmd/platform-architecture.mmd) renders toassets/png/platform-architecture.pngand is embedded in both Marp decks. The diagram shows the full logical topology: consumer surfaces (technical dev- citizen dev) → contract schema → central pipeline (8 fixed stages) → cross-cutting components (module catalog, stateless engine adapter, platform-managed environments, HITL gates, hash-chained evidence stream) → downstream AWS resources. All subsequent slides renumbered 4–11; talking points + README directory layout + slide counts (10→11 main, 19→20 / 18→19 total) synced. Both HTML decks re-rendered via Marp.
Docs-only NFR patch (no code changes).
v1.14 (active — NFR Refinement: bug fixes, security, stubs, tests, docs)
The v1.14 milestone is a 20-phase NFR sweep — no new features. It clears
the open P1/P2 backlog from the v1.11 review, hardens the security
posture (swallowed errors, hardcoded account ID, IAM wildcards, schema
validation, credential hygiene), resolves stub/missing functionality
(Kyverno --kube-version, orphan artifacts), adds test coverage for 7
untested scripts, and refines all documentation (ARCHITECTURE.md
v1.11–v1.14 addenda, stale @v1.6–1.9 → @v1.13 refs, COST.md/GRILL/
IAM_POLICY.md sync, STANDARDS.md reconciliation).
Milestone type: NFR (all phases fix/test/docs/chore/refactor). The
final phase's patch IS the release — no separate milestone tag. Tags run
on the v1.13.x line: v1.13.3 (P0) → v1.13.4..v1.13.23 (P1–P20) →
v1.13.24 (P21 final = milestone release).
Wave ordering:
- Wave 1 (P1–P6): bug fixes — P1 before P2 (composition depends on dedup correctness); P3–P6 independent.
- Wave 2 (P7–P12): security — P8 before P9 (externalized account ID for IAM ARNs); rest independent.
- Wave 3 (P13–P17): stub/test/CI/hygiene — P15 benefits from P7 landing first; P17 after P14 (both touch config.json).
- Wave 4 (P18–P20): standards/docs/VPC — P19 last (reflects all prior phases).
Phase P1 — adapter-dedup-diagnostic (Wave 1)
- Description: Fix P1-1 from the v1.11 review. The adapter dedup loop
(
adapters/terraform/adapter.py:159-170) silently drops resources whose module is not in the registry — a typo'dmodulefield vanishes without diagnostic. RaiseValueError(preserving the pre-dedup contract) so the misconfiguration surfaces instead of being silently omitted. - Status: pending
- Depends on: —
- Requirements: REQ-135
- Success Criteria:
- A resource with
module: nonexistent@1.0.0raisesValueErrorwith a descriptive message, not a silent drop. - Existing registered-module dedup behavior preserved (multi-resource L1s
still merge into one
module "x" { ... }block). pytestpasses;run_ci.shexits 0.
- A resource with
Phase P2 — static-assets-wiring-fix (Wave 1)
- Description: Fix P1-2.
modules/l2/static-assets/composition.jsondropsdefault_ttl/max_ttl/price_class/viewer_protocol_policy(accepted bycloudfront/interface.jsonbut never wired) and WAF is unconditionally present (nofeatures/conditional). Wire the cloudfront inputs; make WAF conditional via awaf_enabledfeature flag soexamples/complex.ymlis a real modify (adds CDN + WAF), not a no-op re-apply. - Status: pending
- Depends on: [P1]
- Requirements: REQ-136
- Success Criteria:
complex.ymlresolves to a resource set that differs fromsimple.yml(WAF + CDN TTLs present whenwaf_enabled: true, absent when false).- The L2 static-assets lifecycle cell's "modify" step exercises a real terraform diff, not idempotent re-apply.
pytestpasses;run_ci.shexits 0.
Phase P3 — lifecycle-script-arg-cleanup (Wave 1)
- Description: Fix P1-3.
scripts/run_l2_lifecycle_test.shandrun_l2_lifecycle_destroy.shadvertise[ci-vpc-outputs.json]($3) in their usage strings but never read it (the L2 path usesterraform_remote_state, not the file). Remove the vestigial arg or document that the L2 path uses remote state and the arg is accepted-but-ignored for workflow-argument parity with the L1 scripts. - Status: pending
- Depends on: —
- Requirements: REQ-137
- Success Criteria:
- Usage strings no longer advertise a feature the scripts don't provide, OR a comment explains the L2-uses-remote-state design + parity reason.
pytestpasses;run_ci.shexits 0.
Phase P4 — regression-gate-evidence-hardening (Wave 1)
- Description: Fix P1-5.
core/regression_verify.py:432-519CAP-017..022 checks are offline proxies (files exist + contracts resolve) — a module with broken HCL would pass as long as files exist. Add aterraform validatestep to_check_lifecycle_module_terraformso at least HCL syntax is verified at the gate. Tighten the CAPABILITY_INVENTORY wording to "offline proxy; live apply/modify/destroy verified by the modules-lifecycle workflow run, not by this gate." - Status: pending
- Depends on: —
- Requirements: REQ-138
- Success Criteria:
_check_lifecycle_module_terraformrunsterraform validate(or documents why it's too slow + falls back to a syntax probe).- CAPABILITY_INVENTORY + docstrings reflect the offline-proxy caveat honestly.
pytestpasses;run_ci.shexits 0.
Phase P5 — adapter-behavior-tests (Wave 1)
- Description: Fix P2-2. Add
test_adapter_dedup_merges_same_module(two resources with the samemodulecollapse to onemodule "<first_id>" { ... }block with merged inputs) andtest_adapter_remote_state_key_override(ACDL_REMOTE_STATE_KEYoverrides the defaultplatform/terraform.tfstatekey in the emitteddata terraform_remote_stateblock). - Status: pending
- Depends on: [P1]
- Requirements: REQ-139
- Success Criteria:
- Both unit tests exist in
tests/test_adapter.pyand pass. pytestcount increases;run_ci.shexits 0.
- Both unit tests exist in
Phase P6 — alb-name-prefix-fix (Wave 1)
- Description: Fix P2-1.
modules/l1/alb/terraform/main.tf:9usesname_prefix = "tg-ci-"(hardcoded literal) which discardsvar.nameentirely — the target group name is non-configurable and inconsistent with the LB name. Change toname_prefix = "${var.name}-"so the consumer's name prefixes the target group while preserving uniqueness. - Status: pending
- Depends on: —
- Requirements: REQ-140
- Success Criteria:
- Target group
name_prefixderives fromvar.name. terraform validatepasses for the alb module standalone.pytestpasses;run_ci.shexits 0.
- Target group
Phase P7 — swallowed-error-hardening (Wave 2)
- Description: Narrow 6 over-broad
except ...: pass/except Exception:sites:core/local_emulators.py:374(fake_urlopen swallow → network egress risk if patching fails),core/lambda/contract_ingestor.py:157(GitHub search failure → duplicate issues),terraform/bootstrap/create_state_backend.py:51(over-broad → spurious create_bucket),core/output_publisher.py:100,168,terraform/bootstrap/apply_iam_baseline.py:78. Catch specificClientError/NoSuch*exceptions; log + re-raise where silent failure masks a real defect. - Status: pending
- Depends on: —
- Requirements: REQ-141
- Success Criteria:
- No bare
except Exception: passremains in the targeted files (grep clean for the 6 sites). - Specific exception types caught; errors logged with context.
pytestpasses;run_ci.shexits 0.
- No bare
Phase P8 — account-id-externalization (Wave 2)
- Description: Externalize the hardcoded account ID
581513795199from 15+ sites:adapters/terraform/adapter.py:125,140,terraform/bootstrap/apply_iam_baseline.py:33,terraform/bootstrap/create_state_backend.py:33,35,scripts/push_consumer_image.py:32, terraform state-bucket names, ECR image refs. Read fromACDL_AWS_ACCOUNT_IDenv (code) /data.aws_caller_identity(terraform); fall back to env for offline. Keep the COST.md account ID (accepted exposure per P2-4) but centralize the code-side. - Status: pending
- Depends on: —
- Requirements: REQ-142
- Success Criteria:
grep -rn "581513795199" adapters/ scripts/ terraform/ core/returns 0 hits (excluding tests + docs).ACDL_AWS_ACCOUNT_IDenv read with a clear default/fallback.pytestpasses;run_ci.shexits 0.
Phase P9 — iam-policy-least-privilege (Wave 2)
- Description: Scope 6
Resource: "*"statements interraform/bootstrap/spike_runner_policy.json(cloudfront, wafv2, kms, iam) toacdl-*ARNs. Scopeiam:CreateRoleetc. toarn:aws:iam::...:role/acdl-*; scope KMS toarn:aws:kms:...:key/acdl-*; narrow CloudFront/WAF where possible. Add a regression test asserting no newResource:"*"on non-global actions. - Status: pending
- Depends on: [P8]
- Requirements: REQ-143
- Success Criteria:
Resource: "*"remains only on actions that require it (sts, ce).- IAM/KMS/CloudFront/WAF scoped to
acdl-*ARNs. - Regression test in
tests/test_iam_policy_baseline.pyasserts the scoping. pytestpasses;run_ci.shexits 0.
Phase P10 — contract-ingestor-identity-validation (Wave 2)
- Description: Harden
core/lambda/contract_ingestor.py:221-245_validate_caller_identity— currently best-effort (validatesconsumerRepoformat only, doesn't verify the caller owns the repo). AddcontractIdformat validation,environmentenum validation,errorlength cap. Document the ABAC reliance explicitly. Add a spoofing-resistance test. - Status: pending
- Depends on: —
- Requirements: REQ-144
- Success Criteria:
contractId,environment,errorvalidated; malformed input rejected with 400.- ABAC reliance documented in the function docstring + ARCHITECTURE.md.
- Spoofing-resistance test in
tests/test_contract_ingestor.pypasses. pytestpasses;run_ci.shexits 0.
Phase P11 — schema-input-validation-hardening (Wave 2)
- Description: Add
additionalProperties: falsetoschemas/contract.schema.json+schemas/environment.schema.json(currently allows undocumented fields silently). AddmaxItems/maxPropertiesbounds. Validatestate_backend.bucketS3 naming rules,runner_role_arnARN format,vpc_cidrCIDR format. Add tests asserting rejection of malformed input. - Status: pending
- Depends on: —
- Requirements: REQ-145
- Success Criteria:
- Both schemas reject undocumented top-level fields.
- Format validation (bucket/ARN/CIDR) rejects malformed values.
- New tests in
tests/test_environment_schema.py+tests/test_contract_schema.pypass. pytestpasses;run_ci.shexits 0.
Phase P12 — gitignore-credential-hygiene (Wave 2)
- Description:
.gitignorecovers.env*/*.tfstate*but lacks a credential-pattern catch-all (*.pem/*.key/*.p12/*.pfx). Add credential patterns. Addtests/test_no_secrets_tracked.pyasserting no credential-looking file is tracked by git. - Status: pending
- Depends on: —
- Requirements: REQ-146
- Success Criteria:
.gitignorehas credential-pattern catch-all.test_no_secrets_tracked.pypasses (grepgit ls-filesfor credential patterns → 0 hits).pytestpasses;run_ci.shexits 0.
Phase P13 — kyverno-kube-version-resolution (Wave 3)
- Description: Resolve the discarded
--kube-versionflag inadapters/kyverno/kyverno_adapter.py:11,115-116(_ = kube_version). Either implement version-aware policy selection (select policies by k8s version) or remove the flag and document why it's deferred to the GitOps reconciler roadmap. Resolve the ambiguity either way. - Status: pending
- Depends on: —
- Requirements: REQ-147
- Success Criteria:
--kube-versionis either used (version-aware policy selection) or removed with a documented deferral rationale.tests/test_kyverno_adapter.pyupdated to match.pytestpasses;run_ci.shexits 0.
Phase P14 — orphan-artifact-and-dead-config-cleanup (Wave 3)
- Description: Clean up orphan artifacts + dead config: the orphan
scripts/__pycache__/verify_deploy_microservice.cpython-312.pyc(source deleted in v1.11); stalepyproject.tomlcoverage sourceacdl_platform→core(renamed in v1.6);pyproject.tomlversion1.3.0→ current; dead JS allowlist entries inconfig.json(npm/node/jest/eslint/tsc — no package.json). - Status: pending
- Depends on: —
- Requirements: REQ-148
- Success Criteria:
- No orphan
.pycfor a deleted source file. pyproject.tomlcoverage source =core; version = current.config.jsonbash_allowlist has no JS-only entries.pytestpasses;run_ci.shexits 0.
- No orphan
Phase P15 — untested-scripts-coverage (Wave 3)
- Description: Add unit tests for 7 scripts with no test coverage:
scripts/seed_uptime_monitors.py,scripts/push_consumer_image.py,scripts/sync_to_gl.sh,scripts/post_stage_comment.sh,scripts/rotate_spike_key.sh,terraform/bootstrap/create_state_backend.py,terraform/bootstrap/create_iam_user.py. Mock boto3/subprocess for offline-testable coverage. Add--check-only/dry-run modes where missing. - Status: pending
- Depends on: [P7]
- Requirements: REQ-149
- Success Criteria:
- Each of the 7 scripts has a corresponding test file with ≥1 passing test.
pytestcount increases by ≥7;run_ci.shexits 0.
Phase P16 — workflow-parity-and-script-flags (Wave 3)
- Description: 4 GitHub-only workflows (patterns-plan, platform-test,
primitives-plan, release) have no Gitea mirror — either mirror them or
document the Gitea limitation. Fix
scripts/rotate_spike_key.sh(onlyset -u, no-e/pipefail) andscripts/sync_to_gl.sh(nosetflags at all) — addset -euo pipefail. - Status: pending
- Depends on: —
- Requirements: REQ-150
- Success Criteria:
- Gitea workflow parity resolved (mirrored or documented).
rotate_spike_key.sh+sync_to_gl.shhaveset -euo pipefail.pytestpasses;run_ci.shexits 0.
Phase P17 — config-and-persona-hygiene (Wave 3)
- Description: Fix
config.jsonhygiene:branching_strategy: "phase"mismatch with flat-workflow practice; emptyollama-cloudbase_url (noglmmodel configured);frontend-engineerpersonaactive: falsein config.json (PERSONAS.md:80 already says inactive). Align config.json with PERSONAS.md + actual runtime. - Status: pending
- Depends on: [P14]
- Requirements: REQ-151
- Success Criteria:
config.jsonpersona block matches PERSONAS.md (frontend-engineer inactive).branching_strategyreflects actual practice (or documented).ollama-cloudbackend configured or documented as intentionally unset.pytestpasses;run_ci.shexits 0.
Phase P18 — module-standards-consistency (Wave 4)
- Description: 3 L1 modules (
ecr,ecs-cluster,rds) lacklocals.tf;modules/STANDARDS.md§9.4 requires the full 5-file split but §489-492 allows inlining — internally inconsistent. Either addlocals.tfto all 3 or reconcile STANDARDS §9.4 with the inline allowance. Remove the staleTYPE_MAPreference in §8 (deleted in the v1.11 stateless rewrite). - Status: pending
- Depends on: —
- Requirements: REQ-152
- Success Criteria:
- STANDARDS.md internally consistent (§8 + §9.4 agree).
- No stale
TYPE_MAPreference. pytestpasses;run_ci.shexits 0.
Phase P19 — documentation-sync-v1.14 (Wave 4)
- Description: ARCHITECTURE.md: add v1.11/v1.12/v1.13/v1.14 addenda
(stateless adapter, platform VPC, ACDL_LIFECYCLE_MODE, all v1.14
changes; record D-083 deferral explicitly). Bump stale
@v1.6–1.9→@v1.13acrossREADME.md,docs/consumer-guide.md(12 sites),docs/architecture.md,docs/pipeline/. Sync decks to v1.13.2 reality. Update COST.md window to v1.11–v1.14. Resolve G-005/G-008 in GRILL.md (CAP-017..022 now Verified via lifecycle pipeline; COST.md now exists + covers v1.11+). Update IAM_POLICY.md for v1.12/v1.13/v1.14. - Status: pending
- Depends on: [P1-P18]
- Requirements: REQ-153
- Success Criteria:
- ARCHITECTURE.md has v1.11–v1.14 addenda; D-083 deferral recorded.
grep -rn "@v1\.[6-9]" docs/ README.mdreturns 0 hits (bumped to @v1.13).- GRILL G-005/G-008 marked resolved with evidence.
- COST.md window covers v1.11–v1.14.
pytestpasses;run_ci.shexits 0.
Phase P20 — platform-vpc-parameterization (Wave 4)
- Description:
terraform/platform/main.tf:255hardcodescidr_block = "10.0.0.0/16"(notvar.vpc_cidr);count = 2subnets hardcoded (not data-driven AZs). Parameterize; document the0.0.0.0/0ingress on port 80 (ALB-fronted, acceptable but should be explicit). - Status: pending
- Depends on: —
- Requirements: REQ-154
- Success Criteria:
- VPC CIDR is a variable (default
10.0.0.0/16); subnet count is data-driven (length(data.aws_availability_zones.available)). 0.0.0.0/0ingress documented.terraform validatepasses;pytestpasses;run_ci.shexits 0.
- VPC CIDR is a variable (default
Phase P21 — final-review-ship (Final Phase)
- Description: Multi-persona code review across all v1.14 phases.
Audit (reconstruction test, file discipline, branch hygiene, commit
discipline). Complete: update REQUIREMENTS.md (REQ-135..154 marked
complete), ROADMAP.md (v1.14 complete), PROJECT.md. Tag final patch
v1.13.24(IS the milestone release). Mergemilestone/v1.14→main. - Status: pending
- Depends on: [P1-P20]
- Requirements: —
- Success Criteria:
- Review: 0 new P0; all P1-1..P1-5 + P2-1..P2-4 resolved.
- Audit: clean; reconstruction test passes.
- Tag
v1.13.24created; milestone merged to main.
After Phase P21: milestone COMPLETE — v1.13.24 IS the v1.14 release.