1686 lines
127 KiB
Markdown
1686 lines
127 KiB
Markdown
# Nova — 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.sh` mirrors the CI pipeline locally. `scripts/run_platform.sh` streams 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 generic `docs/CONSUMER_GUIDE.md` (all L2 modules, versioned `uses:`, consumer-scoped prereqs, run-time platform fetch) replaces the module-specific guide. A byte-identical reusable `deploy.yml` workflow (Gitea + GitHub) implements `pipelines/deploy.yaml` and 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 to `core/`. 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. Rename `static-assets` → `static-assets` (D-048 — incl. `.ciagent/` historical narrative). Author `cloudfront` + `waf` primitives; augment `static-assets` to 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 + DynamoDB `acdl-contracts` table for contract ingestion (D-051) + cross-account IAM. Deploy outputs via SSM SecureString + GitHub PR comment (D-050). Uniform error reporting via the Lambda `report_error` action → 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`; floating `v1.6` + `v1` tags 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). Adds `modules/STANDARDS.md` (L1+L2 authoring + review standards). Adds `schemas/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 prevented `terraform init/validate/plan` against 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 fields `id`/`name`/`infrastructure`; dropped `uses:`/`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 off `v1.10.2` and rebuilds v1.11 on three corrections: (1) the terraform adapter becomes a stateless assembler — each L1 module ships a real `terraform/` module dir (variables/locals/main/outputs) owning its resource shape, nested blocks, and defaults; the adapter deletes `TYPE_MAP`/`INPUT_MAP`/`OUTPUT_MAP` and all 39 type-specific branches, becoming a ~80-line assembler that emits `module "x" { source = ... }` blocks; (2) lifecycle is owned by terraform via the shell orchestrator (`run_platform.sh --apply`/`--destroy`), never by Python — `verify_deploy_microservice.py` is deleted; (3) testing is pipeline-driven — a `modules-lifecycle` pipeline (Gitea + GitHub, byte-identical) matrix-runs each L1 module's `examples/{simple,complex}.yml` contracts through apply→modify→destroy against live AWS; no per-module Python. A single platform VPC (`terraform/platform`) is shared by all stacks via `data` source — 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.json` to the updated CIAgent v2 config structure (drop removed fields, migrate `gitea`→`release.gitea`, add `secrets`/`ship`/`backend`/`ideation`/`personas`/`logging`/`telemetry` sections). 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 all `testing`/`agentic` maturity badges from both decks (only `planned` retained); 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`; `acdl` already exists), seed directory layouts, configure Pages on `acdl-evidence`, add environment protection for `qa` and `prod` on `acdl-contracts`.
|
||
- **Status:** complete (v1.0.1)
|
||
- **Depends on:** —
|
||
- **Requirements:** REQ-01, REQ-09, REQ-10
|
||
- **Success Criteria:**
|
||
- `acdl-contracts` and `acdl-evidence` exist and are pushable.
|
||
- `acdl-evidence` Pages returns 200 with placeholder `index.html`.
|
||
- `qa` and `prod` environments exist on `acdl-contracts`.
|
||
|
||
### Phase 02 — l1-modules
|
||
- **Description:** Create all 8 L1 module folders under `acdl/modules/l1/`, each with `manifest.yaml` (declared inputs) and `mock_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.sh` runs and exits 0 for each.
|
||
- `manifest.yaml` validates against the L1 schema.
|
||
|
||
### Phase 03 — l2-modules-and-core-scripts
|
||
- **Description:** Create the 4 L2 compositions under `acdl/modules/l2/` referencing L1s, plus the 5 core scripts in `acdl/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.sh` applies each L1 in an L2 and writes `state.json`.
|
||
- `policy_checker.py` fails on `public-ingress: true` with `POLICY_VIOLATION:PUBLIC_INGRESS`.
|
||
- `confidence_signal.py` returns 0.90 (pass) / 0.40 (fail).
|
||
- `evidence_writer.py` appends an event with a valid hash chain.
|
||
- `l3b_agent_stub.py` maps the Act 3 example issue to `l2-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 in `acdl-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.yaml` runs 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.yaml` commit and triggers the pipeline.
|
||
|
||
### Phase 05 — evidence-ui-and-demo-dry-run
|
||
- **Description:** Build `index.html` (vanilla JS, fetches `audit.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-feed` contract and triggers the pipeline.
|
||
- Act 4: malicious `public-ingress: true` contract halts in Dev with confidence < 0.50 and a visible rejection reason on the timeline.
|
||
|
||
---
|
||
|
||
## 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/`) to `demo/`. Establish the new repo layout (`platform/`, `schemas/`, `adapters/`, `terraform/`, `modules-ir/`). Rewrite README to reflect the real platform. Verify the demo still runs from `demo/` (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-upload` still 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 in `PROJECT.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.py` spec (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.md` status note updated to v1.0 (or a `docs/architecture-v1.0.md` snapshot).
|
||
|
||
### 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; implements `scripts/rotate_spike_key.sh` to 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.sh` rotates 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-identity` successfully.
|
||
- 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 → Terraform `variable`/`output` + root module and emits a real `terraform plan` against 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.json` is satisfied by `modules-ir/l1/l1-s3/` interface.
|
||
- The Terraform adapter translates `l1-s3` to a valid `terraform plan` (real AWS).
|
||
- `terraform validate` + `terraform plan` succeed; no long-lived credential in the workflow.
|
||
|
||
### Phase 10 — v1-spike-l2-and-contract-e2e
|
||
- **Description:** Implement `l2-static-assets` (thin-composition referencing `l1-s3`), the contract schema + contract→IR resolution, and one end-to-end contract submission (`contracts/spike.yaml` for `l2-static-assets`) flowing through schema validation → IR resolution → `terraform plan` → Checkov `PolicyCheckResult` → 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-assets` references `l1-s3` only (depth 1).
|
||
- One contract submission completes the full pipeline end-to-end.
|
||
- `scripts/verify_phase10.sh` proves 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.md` to 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.md` has a v1.2 addendum with the #36988 re-check + NFR audit + simplification findings.
|
||
- `README.md` reflects 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.json` to least-privilege (add ECS + ECR + ELB + IAM plan-only permissions for v1.2; audit for wildcards). Make `create_state_backend.py` and `create_iam_user.py` idempotent. Consolidate `run_spike_plan.sh` + `run_spike_e2e.sh` into a single `scripts/run_platform.sh` with proper exit codes and error handling. Redact P1-1 (the two AWS access key IDs in `.ciagent/VERIFY.md` Phase 09 narrative). Fix any remaining stale `platform/` 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.sh` runs the full v1.1 spike e2e and exits 0.
|
||
- `create_state_backend.py` / `create_iam_user.py` re-runs are idempotent (no duplicate resources; exit 0).
|
||
- `spike_runner_policy.json` passes a least-privilege audit (no `*` actions beyond documented exceptions).
|
||
- `.ciagent/VERIFY.md` Phase 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 an `interface.json` valid against `schemas/ir.schema.json`. Register all six in `modules-ir/registry.json`. Expand the Terraform adapter `TYPE_MAP` to cover the new IR resource types. Each L1 produces a valid `terraform plan` fragment.
|
||
- **Status:** complete (v1.2.3)
|
||
- **Depends on:** [12]
|
||
- **Requirements:** REQ-31
|
||
- **Success Criteria:**
|
||
- All six L1s exist under `modules-ir/l1/` with `interface.json` valid against `schemas/ir.schema.json`.
|
||
- `modules-ir/registry.json` lists all six.
|
||
- The adapter `TYPE_MAP` covers all six IR resource types.
|
||
- Each L1 produces a valid `terraform plan` fragment.
|
||
|
||
### Phase 14 — l2-microservice-and-contract-schema
|
||
- **Description:** Author `l2-microservice` thin-composition under `modules-ir/l2/l2-microservice/` referencing the six ECS L1s (depth ≤ 5). Extend `schemas/contract.schema.json` with 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-microservice` references the six ECS L1s only (depth ≤ 5).
|
||
- `schemas/contract.schema.json` validates a `contracts/microservice.yaml` with 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-microservice` under the `continuous-intelligence` org containing a basic HTTP microservice (tiny Python/Go server returning 200), a `Dockerfile`, an ECR push step, and a `contracts/microservice.yaml` submission for `l2-microservice` (dev environment). Lift the platform from `plan` to **`apply`** for the `dev` environment (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-microservice` repo exists under `continuous-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-microservice` triggers 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 the `acdl-evidence` timeline. Verify the NFR improvements from Phase 12 hold, the setup is simpler (one `scripts/run_platform.sh`), and the README is accurate. `scripts/verify_phase16.sh` proves 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.sh` exits 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-only` mode to `run_platform.sh` that 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`. Add `pyproject.toml` + `requirements-test.txt` for dependency pinning.
|
||
- **Status:** complete (v1.3.2)
|
||
- **Depends on:** [17]
|
||
- **Requirements:** REQ-39, REQ-40, REQ-41, REQ-42
|
||
- **Success Criteria:**
|
||
- `pytest` runs and passes offline (no AWS, no Checkov, no DynamoDB).
|
||
- `run_platform.sh --check-only` runs offline and exits 0.
|
||
- `.gitea/workflows/ci.yml` and `.github/workflows/ci.yml` exist with identical job stages (lint, test, check-only).
|
||
- `pyproject.toml` + `requirements-test.txt` pin 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.json` JSON Schema + `pipelines/ci.yaml` YAML instance) that both `.gitea/workflows/ci.yml` (Gitea Actions, dev) and `.github/workflows/ci.yml` (GitHub Actions, production) implement. Create `scripts/run_ci.sh` that mirrors the CI pipeline locally (lint → test → check-only). Update `scripts/run_platform.sh` to stream terraform init/validate/plan output, Checkov compliance results, and PolicyCheckResult records to stdout by default (with `--quiet` for log-only mode). Add `tests/test_pipeline_contract.py` validating 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.yaml` validates against `schemas/pipeline.schema.json`.
|
||
- Both `.gitea/workflows/ci.yml` and `.github/workflows/ci.yml` are byte-identical.
|
||
- A test parses both workflows and asserts their stages/commands match the contract.
|
||
- `scripts/run_ci.sh` exits 0 and outputs "CI PIPELINE OK".
|
||
- `scripts/run_platform.sh --check-only` streams the emitted Terraform to stdout.
|
||
- `scripts/run_platform.sh --check-only --quiet` suppresses the Terraform stream.
|
||
- `pytest` total 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.md` so the consumer model is unambiguous (this repo is the platform source; a consumer owns only `contract.yaml` + app code). Convert the platform-flow diagram to a mermaid `flowchart 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.secrets` locally). Replace `docs/consumer-guide-static-assets.md` with a generic `docs/CONSUMER_GUIDE.md` (all L2 modules, mermaid diagrams, versioned `uses:` floating MAJOR+MINOR, consumer-scoped prerequisites, run-time platform fetch via a reusable workflow). Create byte-identical `.gitea/workflows/deploy.yml` + `.github/workflows/deploy.yml` implementing `pipelines/deploy.yaml` — a reusable workflow invoked by consumer repos via `uses: acdl/.gitea/workflows/deploy.yml@v1.4` that checks out the consumer repo + the ACDL platform repo and runs `scripts/run_platform.sh`. Update `contracts/static-assets.yaml` to `uses: acdl/pipelines/deploy.yaml@v1.4`. Extend `tests/test_pipeline_contract.py` to 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.md` states the platform-source vs consumer-repo distinction up front; platform flow is a mermaid `flowchart TD`; `grep L3B README.md` returns 0 hits; `grep -i spike README.md` returns 0 prose hits (code paths in bash blocks allowed).
|
||
- `docs/CONSUMER_GUIDE.md` exists; `docs/consumer-guide-static-assets.md` is deleted; `grep -R consumer-guide-static-assets` returns 0 dangling references; guide is generic (static-assets is the worked example, not the scope); diagrams are mermaid; `uses:` references use `@v1.4`.
|
||
- `README.md` Credentials 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.yml` and `.github/workflows/deploy.yml` exist, are byte-identical, conform to `schemas/deploy-pipeline.schema.json`, and are reusable (`on: workflow_call` with a `contract` input).
|
||
- `contracts/static-assets.yaml` uses `uses: acdl/pipelines/deploy.yaml@v1.4`.
|
||
- `tests/test_pipeline_contract.py` validates the deploy workflows (exist, byte-identical, schema-conformant); the extended test suite passes; `bash scripts/run_ci.sh` exits 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 stdlib `platform` module, so `core/` was chosen). Restructure `docs/` into a Jekyll-style GitHub Pages site (`_config.yml`, `index.md`, `modules/`, `contracts/`, `pipeline/`, `environments/`, `consumer-guide.md`, consolidated `architecture.md`, `vision.md`). Rewrite `README.md`: remove `.ciagent/` + `.gitea/workflows/` rows; restate consumer repo model (app code + 1+ contracts + CI definitions `uses:`-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. Update `docs/consumer-guide.md`: drop L2 (→ modules), composition → pattern (prose), remove `.gitea/` (GitHub only), forge → platform runners, mermaid updated. Update `modules/` READMEs: L1 → primitives, L2 → modules, composition → pattern (prose only, files kept); bump stale `@v1` → `@v1.4`. Consolidate `docs/architecture.md` + `docs/architecture-v1.0.md` into a single current-architecture `docs/architecture.md`. Add `docs/environments/index.md` (platform-managed AWS account/network/state/runner; consumer provides none). Add a minimal onboarding scaffold: `core/environments/` dir + sample `dev.json` + README, `core/environment_check.py`, wire-in at the top of `scripts/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.md` returns 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 in `docs/`.
|
||
- 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.md` exists; `core/environments/` + `dev.json` + `environment_check.py` + `run_platform.sh` wire-in + `tests/test_environment_check.py` exist and pass.
|
||
- `bash scripts/run_ci.sh` exits 0; `python3 -m pytest tests/ -v` passes (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-assets` everywhere (D-048 — including `.ciagent/` historical narrative, overriding the v1.6 preservation precedent). Author two new primitives: `cloudfront` (distribution + OAC, stack types `aws:cloudfront:distribution` + `aws:cloudfront:originaccesscontrol`) and `waf` (WAFv2 web ACL, stack type `aws:wafv2:webacl`). Augment the `static-assets` module to a production-ready stack referencing s3 + cloudfront + waf (depth 1, D-049). Expand the Terraform adapter `TYPE_MAP`/`INPUT_MAP`/`OUTPUT_MAP` for the new stack types. Bump `uses:`/`ref:` from `@v1.4` to `@v1.6` (D-056/D-057); create the floating `v1.6` + `v1` git tags pointing at `v1.6.0` so 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 to `modules/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 to `static-assets`.
|
||
- `modules/l1/cloudfront/` + `modules/l1/waf/` exist with `interface.json` valid against `schemas/stack.schema.json`; registered in `modules/registry.json`.
|
||
- `modules/l2/static-assets/composition.json` references s3 + cloudfront + waf (depth 1).
|
||
- `adapters/terraform/adapter.py` `TYPE_MAP` covers `aws:cloudfront:distribution`, `aws:cloudfront:originaccesscontrol`, `aws:wafv2:webacl`.
|
||
- `contracts/static-assets.yaml` + `.github/workflows/deploy.yml` + `.gitea/workflows/deploy.yml` use `@v1.6`; git tags `v1.6` + `v1` exist pointing at `v1.6.0`.
|
||
- `bash scripts/run_ci.sh` exits 0; `python3 -m pytest tests/ -v` passes; `bash scripts/run_platform.sh --check-only` exits 0.
|
||
|
||
### Phase 23 — tagging-standards-and-security-adapters
|
||
- **Description:** Define a required-tag set (`acdl:owner`, `acdl:contract`, `acdl:environment`, `acdl:cost-center`) in `schemas/tagging-standard.json` (D-054). Author a Checkov custom YAML rule at `adapters/terraform/policy/custom_rules/acdl_tagging.yaml` that fails when required tags are missing on taggable resources. Remove the `_emit_tag_naming_skipped()` placeholder in `checkov_adapter.py` (D-043 closure) and add `ACDL_TAG_NAMING` to `RULE_MAP` as a real rule. Author a Wiz adapter stub (`adapters/wiz/wiz_adapter.py`) translating Wiz API issues → `PolicyCheckResult` records (`engine: "wiz"`), degrading gracefully when unconfigured (D-052). Author a Kyverno K8s-native adapter (`adapters/kyverno/kyverno_adapter.py`) translating Kyverno `PolicyReport` results → `PolicyCheckResult` records (`engine: "kyverno"`), with sample policies as documentation; inactive for Terraform-only stacks, ready for the GitOps reconciler roadmap item (D-053). Add `wiz` + `kyverno` to the `schemas/policy_check_result.schema.json` engine 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.yaml` exists; Checkov loads it; `checkov_adapter.py` no longer emits a SKIPPED `ACDL_TAG_NAMING` placeholder (D-043 closed).
|
||
- `adapters/wiz/wiz_adapter.py` + `tests/test_wiz_adapter.py` exist; tests pass offline (not-configured graceful degradation).
|
||
- `adapters/kyverno/kyverno_adapter.py` + sample policies + `tests/test_kyverno_adapter.py` exist; tests pass offline.
|
||
- `schemas/policy_check_result.schema.json` engine enum includes `checkov | kyverno | opa | wiz`.
|
||
- `bash scripts/run_ci.sh` exits 0; `python3 -m pytest tests/ -v` passes.
|
||
|
||
### 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 table `acdl-contracts` (PK `consumerRepo`, SK `contractId#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 role `lambda:InvokeFunctionUrl` on the Lambda ARN, scoped via ABAC. The `report_error` action (Phase 25) is prepared but not yet implemented. Update `docs/environments/index.md` to 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.py` exists; handler writes contracts to DynamoDB (tested offline with moto).
|
||
- `terraform/platform/main.tf` defines `acdl-contracts` DynamoDB table, `acdl-contract-ingestor` Lambda, Function URL (IAM auth), KMS CMK, Secrets Manager secret, Lambda execution role.
|
||
- `terraform/platform/consumer_invoke_policy.json` exists (cross-account invoke policy template).
|
||
- `tests/test_contract_ingestor.py` passes offline.
|
||
- `bash scripts/run_ci.sh` exits 0.
|
||
|
||
### Phase 25 — deploy-pipeline-dx-outputs-and-error-reporting
|
||
- **Description:** Add a `publish-outputs` step to `scripts/run_platform.sh` (after apply) that writes deploy outputs to SSM Parameter Store as `SecureString` (KMS-encrypted, namespaced `/acdl/{env}/{contractId}/{output_name}`) for runtime-injectable values, and a `comment-outputs` step that posts a structured GitHub PR comment / job summary with human-readable connection strings (D-050). Implement `core/output_publisher.py` (SSM write + GitHub comment formatting). Implement the Lambda `report_error` action (`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 an `if: failure()` error-report step to `.github/workflows/deploy.yml` that invokes the Lambda via `aws lambda invoke-function-url` (SigV4-signed). Add a PR comment after every successful pipeline stage (D-055 extension) via `scripts/post_stage_comment.sh` (uses `GITHUB_TOKEN` + `gh api`; no-op when not in a PR context). Update `pipelines/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.sh` has a `publish-outputs` step (SSM SecureString, tested offline with moto) + a `comment-outputs` step (GitHub PR comment formatting, tested offline).
|
||
- `core/lambda/contract_ingestor.py` `report_error` action creates a GitHub issue (tested with mocked API); idempotent.
|
||
- `.github/workflows/deploy.yml` + `.gitea/workflows/deploy.yml` (byte-identical) have an `if: failure()` error-report step invoking the Lambda + stage comments after each successful stage (PR context).
|
||
- `pipelines/deploy.yaml` declares the new stages.
|
||
- `bash scripts/run_ci.sh` exits 0; `python3 -m pytest tests/ -v` passes.
|
||
|
||
### 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 — replaces `ci.yml` for 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). Author `scripts/run_primitive_plan.sh` + `scripts/run_pattern_plan.sh` (with `--check-only` mode for CI). Author the release job (`.github/workflows/release.yml`) that runs on merge to `main`, 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 `@v1` or `@v1.7` receive updates.
|
||
- **Status:** complete (v1.7.0)
|
||
- **Depends on:** [25]
|
||
- **Requirements:** REQ-72, REQ-73
|
||
- **Success Criteria:**
|
||
- `.github/workflows/platform-test.yml` exists, runs lint + unit + integration + schema-validation on PR.
|
||
- `.github/workflows/primitives-plan.yml` + `.github/workflows/patterns-plan.yml` exist, run plan-only (matrix) on PR.
|
||
- `.github/workflows/release.yml` exists, computes next semver, creates + updates MAJOR.MINOR.PATCH / MAJOR.MINOR / MAJOR tags on merge.
|
||
- `scripts/run_primitive_plan.sh` + `scripts/run_pattern_plan.sh` exit 0 in `--check-only` mode.
|
||
- `bash scripts/run_ci.sh` exits 0; `python3 -m pytest tests/ -v` passes.
|
||
|
||
### 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 an `engine` input (enum: postgres, mysql, etc.) demonstrating multi-engine variation (D-059). Expand the adapter `TYPE_MAP` for `aws:rds:instance` → `aws_db_instance`. For **each** module (primitives + patterns), add a `modules/<name>/examples/` directory with `simple.yaml` + `complex.yaml` (+ variation files) validated against `schemas/contract.schema.json` in the platform-test pipeline (Phase 26 schema-validation stage) (D-058). Each module's `README.md` `## Examples` section references + excerpts the validated files. Update `docs/modules/index.md` + `docs/consumer-guide.md` + `docs/contracts/index.md` with 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 with `interface.json` (`engine` enum) + `examples/`; registered; adapter emits `aws_db_instance`.
|
||
- Every module README has a `## Examples` section; `modules/<name>/examples/{simple,complex}.yaml` exist and validate against `schemas/contract.schema.json`.
|
||
- `docs/modules/index.md` links to all module READMEs (including cloudfront, waf, rds).
|
||
- `bash scripts/run_ci.sh` exits 0; `python3 -m pytest tests/ -v` passes.
|
||
|
||
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 `rules` input emits nested `rules { ... }` blocks (not `rules = [...]` attribute syntax — P1-4). Honor `default_action` input (allow/block) instead of hardcoding `allow {}` (P1-5). Implement L2 composition `outputs[]` processing in `resolve_l2()` — build `stack.outputs` dict + adapter emits `output` blocks (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, not `rules = [`.
|
||
- WAF with `default_action: block` emits `block {}`; default (absent) emits `allow {}`.
|
||
- L2 resolution of `static-assets` yields `stack.outputs.distribution_domain_name`, `bucket_arn`, `web_acl_arn`.
|
||
- Adapter emits `output "distribution_domain_name" { value = ... }` blocks.
|
||
- `pytest` passes; `run_platform.sh --check-only` exits 0.
|
||
|
||
### Phase 29 — ssm-kms-and-invoke-policy
|
||
- **Description:** SSM publisher fails loud (`RuntimeError`) when `ACDL_KMS_KEY_ID` unset; `ACDL_ALLOW_DEFAULT_KMS=1` escape hatch for local testing (P1-3). Convert `consumer_invoke_policy.json` to a Terraform-rendered template using `data.aws_caller_identity` + `templatestring` — no `000000000000` placeholder (P1-6). Tests for both.
|
||
- **Status:** complete (v1.8.0)
|
||
- **Depends on:** [28]
|
||
- **Requirements:** REQ-78, REQ-79
|
||
- **Success Criteria:**
|
||
- SSM publisher raises `RuntimeError` when `ACDL_KMS_KEY_ID` unset; succeeds with `ACDL_ALLOW_DEFAULT_KMS=1`.
|
||
- Rendered invoke policy contains the caller's live account ID, not `000000000000`.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase 30 — run-platform-isolation-and-api-portability
|
||
- **Description:** `run_platform.sh` emits adapter output to `$WORK/tf` (per-run temp dir), not `terraform/spike/`; remove committed `terraform/spike/*.tf` (P1-8). `contract_ingestor.py` reads `GITHUB_API_BASE` env for forge-agnostic API URLs (GitHub + Gitea); `_forge_type()` branches search URL (P1-9). Deploy workflow `configure-aws-credentials` step restructured as single conditional step: OIDC when no static key, `access-key`/`secret-key` inputs 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-only` writes to a temp dir; no `terraform/spike/*.tf` committed.
|
||
- `contract_ingestor.py` uses `GITHUB_API_BASE`; Gitea base URL produces correct API paths.
|
||
- Deploy workflow static-key override wired to `configure-aws-credentials` inputs.
|
||
- Both deploy workflows byte-identical; `pytest` + `run_ci.sh` green.
|
||
|
||
### Phase 31 — encryption-by-default-and-per-stack-cmk
|
||
- **Description:** Create `kms-key` L1 primitive (type `aws:kms:key`, inputs: description/region/deletion_window_days, outputs: kms_key_arn/kms_key_id, NFRs: enable_rotation default true, deletion_protection default true). Adapter emits `aws_kms_key` + `aws_kms_alias` + `enable_key_rotation = true`. Add `encryption_enabled` NFR (default true) + `kms_key_arn` input to all primitives. L2 modules wire a `kms-key` child + 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_enabled` NFR (default true) + optional `kms_key_arn` input.
|
||
- L2 resolution wires per-stack CMK to all children.
|
||
- Adapter emits encryption blocks (SSE, storage_encrypted, encryption_configuration) referencing the CMK.
|
||
- `enable_key_rotation = true` on the CMK; no shared keys across stacks.
|
||
- `pytest` + `run_ci.sh` green.
|
||
|
||
### Phase 32 — deletion-protection-by-default-and-l2-feature-flag
|
||
- **Description:** Add `deletion_protection` NFR (boolean, default true) to every L1 primitive. Adapter emits `lifecycle { prevent_destroy = true }` when true; omits it when false. L2 modules expose `features.deletion_protection` flag (default true); resolver propagates to each child's NFR. Consumers can set `inputs.deletion_protection: false` in contract. Update contract schema.
|
||
- **Status:** complete (v1.8.0)
|
||
- **Depends on:** [31]
|
||
- **Requirements:** REQ-86, REQ-87
|
||
- **Success Criteria:**
|
||
- Every primitive has `deletion_protection` NFR defaulting to true.
|
||
- Adapter emits `prevent_destroy = true` when true; omits when false.
|
||
- L2 feature flag propagates to all children.
|
||
- `pytest` + `run_ci.sh` green.
|
||
|
||
### Phase 33 — uptime-kuma-primitive
|
||
- **Description:** Create `uptime` L1 primitive (ECS Fargate running `louislam/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. Add `deploy-uptime` pipeline stage (separate state, after publish-outputs) to `pipelines/deploy.yaml` + both deploy workflows. `run_platform.sh` constructs synthetic uptime contract from L2 outputs + runs second terraform apply. Uptime URL published via PR comment. Feature flag from `inputs.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-uptime` stage in deploy contract + byte-identical workflows.
|
||
- `pytest` + `run_ci.sh` green.
|
||
|
||
### Phase 34 — decommission-alias-and-cmdb-validation
|
||
- **Description:** Add `mode: decommission` to deploy pipeline. Stages: validate-change-request (Lambda `validate_change_request` action queries DynamoDB `acdl-change-requests` table, asserts status=approved) → disable-deletion-protection (resolve contract with deletion_protection=false, terraform plan/apply, HITL SRE gate) → zero-counts (resolver `decommission_transform` zeroes all counts, terraform plan/apply, second HITL SRE gate) → confirm-decommission. Add `acdl-change-requests` DynamoDB table to terraform/platform/main.tf. Add `validate_change_request` to contract_ingestor.py. Document in `docs/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_transform` zeroes all counts.
|
||
- Documented in consumer guide.
|
||
- `pytest` + `run_ci.sh` green.
|
||
|
||
### 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. Fix `modules/README.md` catalog index (add rds + uptime + kms-key). Update `modules/README-TEMPLATE.md` with `## NFRs` section. Add `tests/test_module_standards.py` for automated enforcement.
|
||
- **Status:** complete (v1.8.0)
|
||
- **Depends on:** [34]
|
||
- **Requirements:** REQ-95, REQ-96
|
||
- **Success Criteria:**
|
||
- `modules/STANDARDS.md` exists 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.sh` green.
|
||
|
||
### 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). Add `tests/test_docs_coverage.py` to 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.sh` green.
|
||
|
||
### 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.
|
||
- `pytest` passes (~358 tests); `run_ci.sh` exits 0; `run_platform.sh --check-only` exits 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 floating `v1.8` + `v1` tags. Bump `uses:`/`ref:` from `@v1.6` to `@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.0` created; 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`, `Name` tags) into L1 `interface.json` inputs 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.py` passes.
|
||
- Adapter has no hardcoded ECS/ALB/VPC defaults; overrides flow through; `test_p1_1_adapter_parameterization.py` passes.
|
||
- v1.1 S3 regression passes; `pytest` 371 (was 350, +21); `run_ci.sh` exits 0; `run_platform.sh --check-only` exits 0.
|
||
|
||
### 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.py` gains `load()`. 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 raise `ValueError`. `resolve()` accepts `environment_override` (D-088).
|
||
- **Status:** complete (v1.8.2)
|
||
- **Depends on:** [39]
|
||
- **Requirements:** REQ-103, REQ-104
|
||
- **Success Criteria:**
|
||
- `schemas/environment.schema.json` exists; 4 env files validate; `load()` works.
|
||
- `_expand_vars` in 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.py` pass.
|
||
- `pytest` 406 (was 371, +35); `run_ci.sh` exits 0; `run_platform.sh --check-only` exits 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 an `environment` `workflow_call` input (REQ-106); `run_platform.sh --environment <name>` overrides the contract's environment at load time (D-088, before schema validation + interpolation). `resolve()` accepts `environment_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 `environment` input (byte-identical Gitea + GitHub); `run_platform.sh --environment` overrides; resolver supports `environment_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.py` pass.
|
||
- `pytest` 446 (was 406, +40); `run_ci.sh` exits 0; both deploy workflows byte-identical.
|
||
|
||
### Phase 42 — stub-implementation
|
||
- **Description:** `route_halt_artifact` real (SNS publish + outbox fallback, REQ-107) + SNS topic `acdl-sod-halt` in `terraform/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.sh` calls `attest` before 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 when `ACDL_ATTESTATION_SIGNING_KEY_ID` unset (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-version` stub.
|
||
- **Status:** complete (v1.8.4)
|
||
- **Depends on:** [41]
|
||
- **Requirements:** REQ-107, REQ-108, REQ-109, REQ-110, REQ-111
|
||
- **Success Criteria:**
|
||
- `route_halt_artifact` publishes to SNS when ARN set; outbox fallback when unset; SNS topic in Terraform.
|
||
- `hitl_gates.attest` records approver; SoD blocks on identity equality; dev skips; `run_platform.sh` has the HITL step.
|
||
- `attestation_matrix.check` runs 8 concerns; offline concerns pass; operator-supplied missing → block for prod; expired → block; signature skip when key unset.
|
||
- Wiz `WizClient` real client + pagination + graceful degrade; `fetch_and_adapt` translates.
|
||
- Kyverno full mapping (pass/fail/skip/warn + severity + skip-with-reason + resource construction); inactive guard preserved; `--kube-version` parsed.
|
||
- `tests/test_route_halt_artifact.py` + `test_hitl_gates.py` + `test_attestation_matrix.py` + `test_wiz_adapter_real_client.py` + expanded `test_kyverno_adapter.py` pass.
|
||
- `pytest` 493 (was 446, +47); `run_ci.sh` exits 0; `run_platform.sh --check-only` exits 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 floating `v1.9` + `v1` tags. Bump `uses:`/`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-only` green.
|
||
- 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.0` created; floating tags updated; `uses:` bumped to `@v1.9`.
|
||
|
||
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:
|
||
|
||
1. **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.
|
||
2. **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.
|
||
3. **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 `regression` mode; milestone completion requires a clean regression run.
|
||
- A regression run against current code surfaces decay (fails closed).
|
||
- `tests/test_verify_regression_mode.py` passes.
|
||
|
||
### 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.py` passes.
|
||
- `run_platform.sh --local` runs 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.
|
||
|
||
### 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.md` exactly.
|
||
- `ci-doc-verifier` confirms no stale capability claims remain.
|
||
- Decks unfrozen; v1.10.0 tagged; Gitea release published.
|
||
|
||
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.**
|
||
1. **Stateless adapter.** `adapters/terraform/adapter.py` (918 lines, 3
|
||
hardcoded constant tables `TYPE_MAP`/`INPUT_MAP`/`OUTPUT_MAP`, 39
|
||
type-specific branches) is rewritten to a ~80-line stateless assembler.
|
||
Each L1 module ships a real `terraform/` 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 root `main.tf` instantiating each L1 as
|
||
`module "x" { source = "..." ... }` with resolved inputs and wired refs.
|
||
`interface.json` stays engine-agnostic; the terraform dir is the engine
|
||
binding. Defaults move into `locals.tf` (heavy interpolation of vars
|
||
against sensible defaults).
|
||
2. **Terraform owns lifecycle.** `scripts/run_platform.sh` gains `--apply`
|
||
and `--destroy` modes. Python never runs terraform.
|
||
`scripts/verify_deploy_microservice.py` is 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).
|
||
3. **Pipeline-driven testing.** A `modules-lifecycle` pipeline (Gitea +
|
||
GitHub, byte-identical) matrix-runs each L1 module's
|
||
`examples/{simple,complex}.yml` contracts 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.py` from a 918-line monolith (3 constant tables + 39 type-specific branches) to a ~80-line stateless assembler. Author `modules/l1/s3/terraform/` (`versions.tf`/`variables.tf`/`locals.tf`/`main.tf`/`outputs.tf`) as the reference module proving the assembly path end-to-end. Extend `modules/registry.json` with a `terraform_dir` field. Rewrite `modules/STANDARDS.md` §8 from "three tables + specialized branches" to "stateless assembler + per-module terraform dir". Rewrite `tests/test_adapter.py` to assert module-instantiation assembly (root `main.tf` contains `module "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.py` returns nothing.
|
||
- `wc -l adapters/terraform/adapter.py` < 100.
|
||
- `modules/l1/s3/terraform/` passes `terraform init + validate` standalone.
|
||
- Adapter, given the s3 instance, emits a root `main.tf` that `terraform init + validate` accepts.
|
||
|
||
### 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 full `versions.tf`/`variables.tf`/`locals.tf`/`main.tf`/`outputs.tf` split. 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 into `locals.tf` as 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's `interface.json` stays engine-agnostic. Add `terraform_dir` to each registry entry.
|
||
- **Status:** pending
|
||
- **Depends on:** [P56a]
|
||
- **Requirements:** REQ-124
|
||
- **Success Criteria:**
|
||
- All 12 `terraform/` subdirs pass `terraform init + validate` standalone.
|
||
- No defaults remain in the adapter.
|
||
- Each registry entry has a `terraform_dir` field.
|
||
|
||
### Phase P57 — shell-orchestrator-lifecycle-modes (Wave 1)
|
||
- **Description:** `scripts/run_platform.sh` gains `--apply <contract.yml>` and `--destroy <contract.yml>` modes. `--apply` runs resolve → adapter → `terraform init` → `terraform apply -auto-approve` (HITL gate for qa/prod/dr). `--destroy` runs resolve → adapter → `terraform destroy -auto-approve` (gated behind `--decommission` + CR validation, D-070 two-step). `--modify` is implicit (a second `--apply` with a changed contract produces a terraform diff). Delete `scripts/verify_deploy_microservice.py` (the offending script that ran `terraform apply` from Python).
|
||
- **Status:** pending
|
||
- **Depends on:** [P56b]
|
||
- **Requirements:** REQ-125
|
||
- **Success Criteria:**
|
||
- `run_platform.sh --apply` and `--destroy` modes exist and are the ONLY path to terraform apply/destroy.
|
||
- `grep -rn "terraform apply\|terraform destroy" scripts/*.py` returns nothing.
|
||
- `verify_deploy_microservice.py` no longer exists.
|
||
|
||
### Phase P58 — single-platform-vpc-deterministic-state (Wave 1)
|
||
- **Description:** Add a single VPC (`aws_vpc.acdl_shared` 10.0.0.0/16, 2 public subnets, IGW, route table, ECS security group) to `terraform/platform/main.tf`; output `vpc_id`, `public_subnet_ids`, `ecs_security_group_id`. `modules/l2/microservice/composition.json` drops the `vpc` child and references the platform VPC via a `data_sources` block. `core/contract_resolver.py` resolves `data:platform/vpc` references. The adapter emits `data "terraform_remote_state" "platform"` + `data "aws_vpc"`/`data "aws_subnets"` blocks, never an inline `aws_vpc` for the microservice stack. State key fix: `spike/{contract.id}/{contract.environment}/terraform.tfstate` (deterministic, env-aware, stable across lifecycle). Add `state_key` derivation to `schemas/contract.schema.json`.
|
||
- **Status:** pending
|
||
- **Depends on:** [P57]
|
||
- **Requirements:** REQ-126
|
||
- **Success Criteria:**
|
||
- `terraform/platform` apply creates exactly ONE VPC.
|
||
- `contracts/microservice.yml` resolution produces NO `aws:ec2:vpc` resource.
|
||
- 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; standalone `vpc` L1 applies its own. Trigger: `pull_request: [main]` + `workflow_dispatch`. Author `schemas/modules-lifecycle-pipeline.schema.json`. Extend `tests/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.py` passes (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 in `modules/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) and `microservice` × `contracts/microservice.yml` (apply → modify: `desired_count` 1→2 → destroy, references platform VPC). Author `modules/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 in `modules/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.py` registry (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.md` documents 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 --decommission` with 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.md` documents 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 <date>; 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-verifier` confirms 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-verifier` confirms 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 `.png` files. 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 `.md` headers + `README.md` directory 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`):
|
||
|
||
1. **Badge cleanup** — removed all `testing` and `agentic` maturity badges from
|
||
every deck layer (source `.md`, Marp `-marp.md`, rendered `.html`,
|
||
talking-points). Only the `planned` badges are retained where relevant. The
|
||
Marp inline `style:` CSS dropped the `.testing` / `.agentic` rules (kept
|
||
`.planned`). The README maturity-framing section updated to describe only the
|
||
`Planned` badge. Empty table cells (dev environment Maturity row) normalized
|
||
to `—`.
|
||
2. **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 to
|
||
`assets/png/platform-architecture.png` and 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 (complete — NFR Refinement: bug fixes, security, stubs, tests, docs, tag `v1.13.24`)
|
||
|
||
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'd `module` field vanishes without
|
||
diagnostic. Raise `ValueError` (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.0` raises `ValueError` with a
|
||
descriptive message, not a silent drop.
|
||
- Existing registered-module dedup behavior preserved (multi-resource L1s
|
||
still merge into one `module "x" { ... }` block).
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P2 — static-assets-wiring-fix (Wave 1)
|
||
- **Description:** Fix P1-2. `modules/l2/static-assets/composition.json`
|
||
drops `default_ttl`/`max_ttl`/`price_class`/`viewer_protocol_policy`
|
||
(accepted by `cloudfront/interface.json` but never wired) and WAF is
|
||
unconditionally present (no `features`/conditional). Wire the cloudfront
|
||
inputs; make WAF conditional via a `waf_enabled` feature flag so
|
||
`examples/complex.yml` is a real modify (adds CDN + WAF), not a no-op
|
||
re-apply.
|
||
- **Status:** pending
|
||
- **Depends on:** [P1]
|
||
- **Requirements:** REQ-136
|
||
- **Success Criteria:**
|
||
- `complex.yml` resolves to a resource set that differs from `simple.yml`
|
||
(WAF + CDN TTLs present when `waf_enabled: true`, absent when false).
|
||
- The L2 static-assets lifecycle cell's "modify" step exercises a real
|
||
terraform diff, not idempotent re-apply.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P3 — lifecycle-script-arg-cleanup (Wave 1)
|
||
- **Description:** Fix P1-3. `scripts/run_l2_lifecycle_test.sh` and
|
||
`run_l2_lifecycle_destroy.sh` advertise `[ci-vpc-outputs.json]` ($3) in
|
||
their usage strings but never read it (the L2 path uses
|
||
`terraform_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.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P4 — regression-gate-evidence-hardening (Wave 1)
|
||
- **Description:** Fix P1-5. `core/regression_verify.py:432-519`
|
||
CAP-017..022 checks are offline proxies (files exist + contracts
|
||
resolve) — a module with broken HCL would pass as long as files exist.
|
||
Add a `terraform validate` step to
|
||
`_check_lifecycle_module_terraform` so 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_terraform` runs `terraform validate` (or
|
||
documents why it's too slow + falls back to a syntax probe).
|
||
- CAPABILITY_INVENTORY + docstrings reflect the offline-proxy caveat
|
||
honestly.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P5 — adapter-behavior-tests (Wave 1)
|
||
- **Description:** Fix P2-2. Add `test_adapter_dedup_merges_same_module`
|
||
(two resources with the same `module` collapse to one
|
||
`module "<first_id>" { ... }` block with merged inputs) and
|
||
`test_adapter_remote_state_key_override` (`ACDL_REMOTE_STATE_KEY`
|
||
overrides the default `platform/terraform.tfstate` key in the emitted
|
||
`data terraform_remote_state` block).
|
||
- **Status:** pending
|
||
- **Depends on:** [P1]
|
||
- **Requirements:** REQ-139
|
||
- **Success Criteria:**
|
||
- Both unit tests exist in `tests/test_adapter.py` and pass.
|
||
- `pytest` count increases; `run_ci.sh` exits 0.
|
||
|
||
### Phase P6 — alb-name-prefix-fix (Wave 1)
|
||
- **Description:** Fix P2-1. `modules/l1/alb/terraform/main.tf:9` uses
|
||
`name_prefix = "tg-ci-"` (hardcoded literal) which discards `var.name`
|
||
entirely — the target group name is non-configurable and inconsistent
|
||
with the LB name. Change to `name_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_prefix` derives from `var.name`.
|
||
- `terraform validate` passes for the alb module standalone.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### 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 specific
|
||
`ClientError`/`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: pass` remains in the targeted files (grep
|
||
clean for the 6 sites).
|
||
- Specific exception types caught; errors logged with context.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P8 — account-id-externalization (Wave 2)
|
||
- **Description:** Externalize the hardcoded account ID `581513795199`
|
||
from 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 from `ACDL_AWS_ACCOUNT_ID` env (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_ID` env read with a clear default/fallback.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P9 — iam-policy-least-privilege (Wave 2)
|
||
- **Description:** Scope 6 `Resource: "*"` statements in
|
||
`terraform/bootstrap/spike_runner_policy.json` (cloudfront, wafv2, kms,
|
||
iam) to `acdl-*` ARNs. Scope `iam:CreateRole` etc. to
|
||
`arn:aws:iam::...:role/acdl-*`; scope KMS to
|
||
`arn:aws:kms:...:key/acdl-*`; narrow CloudFront/WAF where possible.
|
||
Add a regression test asserting no new `Resource:"*"` 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.py` asserts the
|
||
scoping.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P10 — contract-ingestor-identity-validation (Wave 2)
|
||
- **Description:** Harden `core/lambda/contract_ingestor.py:221-245`
|
||
`_validate_caller_identity` — currently best-effort (validates
|
||
`consumerRepo` format only, doesn't verify the caller owns the repo).
|
||
Add `contractId` format validation, `environment` enum validation,
|
||
`error` length cap. Document the ABAC reliance explicitly. Add a
|
||
spoofing-resistance test.
|
||
- **Status:** pending
|
||
- **Depends on:** —
|
||
- **Requirements:** REQ-144
|
||
- **Success Criteria:**
|
||
- `contractId`, `environment`, `error` validated; malformed input
|
||
rejected with 400.
|
||
- ABAC reliance documented in the function docstring + ARCHITECTURE.md.
|
||
- Spoofing-resistance test in `tests/test_contract_ingestor.py` passes.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P11 — schema-input-validation-hardening (Wave 2)
|
||
- **Description:** Add `additionalProperties: false` to
|
||
`schemas/contract.schema.json` + `schemas/environment.schema.json`
|
||
(currently allows undocumented fields silently). Add `maxItems`/
|
||
`maxProperties` bounds. Validate `state_backend.bucket` S3 naming
|
||
rules, `runner_role_arn` ARN format, `vpc_cidr` CIDR 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.py` pass.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P12 — gitignore-credential-hygiene (Wave 2)
|
||
- **Description:** `.gitignore` covers `.env*`/`*.tfstate*` but lacks a
|
||
credential-pattern catch-all (`*.pem`/`*.key`/`*.p12`/`*.pfx`). Add
|
||
credential patterns. Add `tests/test_no_secrets_tracked.py` asserting no
|
||
credential-looking file is tracked by git.
|
||
- **Status:** pending
|
||
- **Depends on:** —
|
||
- **Requirements:** REQ-146
|
||
- **Success Criteria:**
|
||
- `.gitignore` has credential-pattern catch-all.
|
||
- `test_no_secrets_tracked.py` passes (grep `git ls-files` for
|
||
credential patterns → 0 hits).
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P13 — kyverno-kube-version-resolution (Wave 3)
|
||
- **Description:** Resolve the discarded `--kube-version` flag in
|
||
`adapters/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-version` is either used (version-aware policy selection) or
|
||
removed with a documented deferral rationale.
|
||
- `tests/test_kyverno_adapter.py` updated to match.
|
||
- `pytest` passes; `run_ci.sh` exits 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); stale `pyproject.toml` coverage source
|
||
`acdl_platform` → `core` (renamed in v1.6); `pyproject.toml` version
|
||
`1.3.0` → current; dead JS allowlist entries in `config.json`
|
||
(npm/node/jest/eslint/tsc — no package.json).
|
||
- **Status:** pending
|
||
- **Depends on:** —
|
||
- **Requirements:** REQ-148
|
||
- **Success Criteria:**
|
||
- No orphan `.pyc` for a deleted source file.
|
||
- `pyproject.toml` coverage source = `core`; version = current.
|
||
- `config.json` bash_allowlist has no JS-only entries.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### 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.
|
||
- `pytest` count increases by ≥7; `run_ci.sh` exits 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` (only
|
||
`set -u`, no `-e`/`pipefail`) and `scripts/sync_to_gl.sh` (no `set`
|
||
flags at all) — add `set -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.sh` have `set -euo pipefail`.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P17 — config-and-persona-hygiene (Wave 3)
|
||
- **Description:** Fix `config.json` hygiene: `branching_strategy: "phase"`
|
||
mismatch with flat-workflow practice; empty `ollama-cloud` base_url (no
|
||
`glm` model configured); `frontend-engineer` persona `active: false` in
|
||
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.json` persona block matches PERSONAS.md (frontend-engineer
|
||
inactive).
|
||
- `branching_strategy` reflects actual practice (or documented).
|
||
- `ollama-cloud` backend configured or documented as intentionally
|
||
unset.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P18 — module-standards-consistency (Wave 4)
|
||
- **Description:** 3 L1 modules (`ecr`, `ecs-cluster`, `rds`) lack
|
||
`locals.tf`; `modules/STANDARDS.md` §9.4 requires the full 5-file split
|
||
but §489-492 allows inlining — internally inconsistent. Either add
|
||
`locals.tf` to all 3 or reconcile STANDARDS §9.4 with the inline
|
||
allowance. Remove the stale `TYPE_MAP` reference 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_MAP` reference.
|
||
- `pytest` passes; `run_ci.sh` exits 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.13` across `README.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.md` returns 0 hits (bumped to
|
||
@v1.13).
|
||
- GRILL G-005/G-008 marked resolved with evidence.
|
||
- COST.md window covers v1.11–v1.14.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P20 — platform-vpc-parameterization (Wave 4)
|
||
- **Description:** `terraform/platform/main.tf:255` hardcodes
|
||
`cidr_block = "10.0.0.0/16"` (not `var.vpc_cidr`); `count = 2` subnets
|
||
hardcoded (not data-driven AZs). Parameterize; document the
|
||
`0.0.0.0/0` ingress 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/0` ingress documented.
|
||
- `terraform validate` passes; `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### 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). Merge `milestone/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.24` created; milestone merged to main.
|
||
|
||
After Phase P21: milestone COMPLETE — `v1.13.24` IS the v1.14 release.
|
||
|
||
---
|
||
|
||
## v1.15 (complete — Nova Rebrand, tag `v1.15.4`)
|
||
|
||
A full rebrand from **ACDL** / "Agentic Cloud Delivery Platform" →
|
||
**Nova** / "The New Dawn of DevSecOps — security as a seamless enabler
|
||
of fast deployments." The rebrand applies across docs, decks, code,
|
||
configs, CI, env var prefixes, the consumer contract path, SSM
|
||
parameter paths, AWS tag keys, and AWS resource names — with a staged
|
||
infrastructure migration to avoid breakage. The Nova tagline is added
|
||
alongside (not replacing) the existing "North Star" / "consumers
|
||
declare intent" framing; the S&P Global Energy visual theme
|
||
(`sp-theme.json`) is a client brand and is **not** touched.
|
||
|
||
**Milestone type:** Major (breaking — consumer-facing path, env var
|
||
prefixes, SSM path, AWS tag keys, and AWS resource names all change).
|
||
Per the branch-strategy precedent (breaking/feature milestones tag on
|
||
their OWN minor line), v1.15 tags run on the **v1.15.x minor line**:
|
||
`v1.15.0` (P0) → `v1.15.1..v1.15.4` (P1–P4) → `v1.15.4` (P5 final =
|
||
milestone release). (G-104 binding.)
|
||
|
||
**Brand mapping:**
|
||
- Name: `ACDL` / `Agentic Cloud Delivery Platform` → `Nova`
|
||
- Tagline (added): "The New Dawn of DevSecOps — security as a seamless
|
||
enabler of fast deployments"
|
||
- Env var prefix: `ACDL_*` → `NOVA_*` (dual-read fallback in P2;
|
||
removed in P5)
|
||
- Consumer path: `.acdl/contract.yml` → `.nova/contract.yml`
|
||
- SSM path: `/acdl/{env}/{contractId}/{output}` →
|
||
`/nova/{env}/{contractId}/{output}`
|
||
- AWS tag keys: `acdl:owner|environment|contract|cost-center|ref` →
|
||
`nova:*`
|
||
- AWS resource names: `acdl-*` → `nova-*` (with migration, P4)
|
||
- Illustrative URLs in docs: `github.com/acdl/...` →
|
||
`github.com/nova/...` (prose only; real repo name unchanged)
|
||
- Gitea release titles going forward: `ACDL vX.Y.Z` → `Nova vX.Y.Z`
|
||
- S&P visual theme: unchanged (client branding)
|
||
|
||
**Wave ordering:**
|
||
- Wave 1 (P1): docs/decks/prose — no runtime impact; establishes new
|
||
vocabulary. REQ-155, REQ-156, REQ-157.
|
||
- Wave 2 (P2): code + env vars + consumer path — rename in code with a
|
||
dual-read env fallback so deployments don't break during the
|
||
transition window. REQ-158, REQ-159, REQ-160.
|
||
- Wave 3 (P3): SSM path + tag keys — SSM: copy `/acdl/...` →
|
||
`/nova/...`, update readers, delete old. Tag keys: parallel-tag
|
||
period (`nova:*` added, ABAC policy swapped, `acdl:*` removed).
|
||
REQ-161, REQ-162.
|
||
- Wave 4 (P4): AWS resource names — the big migration (KMS alias, SNS,
|
||
SG, Lambda, DynamoDB data migration, ECR re-push, IAM re-bootstrap,
|
||
state bucket migration, ALB recreate). Maintenance window + rollback
|
||
runbook. REQ-163.
|
||
- Wave 5 (P5): final-review-ship — remove dual-read fallback, consumer
|
||
migration guide finalized, review + audit + milestone ship. REQ-164.
|
||
|
||
### Phase P1 — docs-decks-prose (Wave 1)
|
||
- **Description:** Rebrand all prose, titles, headers, comments,
|
||
deck markdown sources, mermaid `.mmd` sources, `pyproject.toml`
|
||
name/description, and `release.yml` release-title prefix from
|
||
`ACDL`/`Agentic Cloud Delivery Platform` → `Nova`. Add the Nova
|
||
tagline ("The New Dawn of DevSecOps — security as a seamless enabler
|
||
of fast deployments") to the README header, both deck title slides,
|
||
and `docs/vision.md` — alongside the existing "North Star" framing.
|
||
Re-export the mermaid PNG diagrams so committed PNGs match new
|
||
labels. Re-render the deck HTML. Update illustrative URLs in docs
|
||
(`github.com/acdl/...` → `github.com/nova/...`,
|
||
`git.cloudinit.dev/continuous-intelligence/acdl*` → `.../nova*` for
|
||
prose). Ship a consumer migration guide (`docs/NOVA_MIGRATION.md`)
|
||
announcing the `.acdl/`→`.nova/` path, `ACDL_*`→`NOVA_*` env vars,
|
||
`/acdl/`→`/nova/` SSM path, `acdl:*`→`nova:*` tag keys, and
|
||
`acdl-*`→`nova-*` AWS resource names changes coming in P2–P4.
|
||
- **Status:** complete (v1.15.1)
|
||
- **Depends on:** —
|
||
- **Requirements:** REQ-155, REQ-156, REQ-157
|
||
- **Success Criteria:**
|
||
- `grep -rni "ACDL\|Agentic Cloud Delivery" README.md docs/ .ciagent/*.md`
|
||
returns 0 hits (except historical narrative marked as historical).
|
||
- `pyproject.toml` `name` = `nova`; `description` mentions Nova.
|
||
- `release.yml` release title prefix is `Nova `.
|
||
- Both decks' title-slide subtitle is
|
||
`Nova — The New Dawn of DevSecOps`; mermaid `.mmd` sources use
|
||
`Nova`; PNGs re-exported; HTML re-rendered.
|
||
- `docs/vision.md` and README header carry the Nova tagline
|
||
alongside the North Star.
|
||
- `docs/NOVA_MIGRATION.md` exists and lists the 5 breaking changes.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P2 — code-envvars-consumer-path (Wave 2)
|
||
- **Description:** Rename
|
||
`adapters/terraform/policy/custom_rules/acdl_tagging.py` →
|
||
`nova_tagging.py` (+ Checkov custom-rule registration in
|
||
`schemas/tagging-standard.json` + adapter config). Rename all 21
|
||
`ACDL_*` env var prefixes → `NOVA_*` across `scripts/`, `core/`,
|
||
`adapters/`, `tests/`, workflows (`.gitea/`, `.github/`), `.env`,
|
||
`.env.secrets` (key names only — values stay), and consumer docs.
|
||
Implement a **dual-read fallback** (`NOVA_X` preferred, fall back to
|
||
`ACDL_X`) in the env/config loader so deployments don't break during
|
||
the transition window. Rename the consumer on-disk contract path
|
||
`.acdl/contract.yml` → `.nova/contract.yml` (and
|
||
`.acdl/static-assets.*.yml`, `.acdl/contract.yaml`) across the
|
||
contract resolver, deploy workflow checkout path, consumer docs, and
|
||
the contract schema description. Rotate Gitea repo secrets via API
|
||
(rename keys `ACDL_*` → `NOVA_*`, values stay).
|
||
- **Status:** complete (v1.15.2)
|
||
- **Depends on:** [P1]
|
||
- **Requirements:** REQ-158, REQ-159, REQ-160
|
||
- **Success Criteria:**
|
||
- `nova_tagging.py` exists; `acdl_tagging.py` removed; Checkov
|
||
registration updated; rule enforces `nova:*` tag keys (tag-key
|
||
enforcement of `nova:*` lands here; existing resources still carry
|
||
`acdl:*` until P3 parallel-tag — rule warns during P2).
|
||
- No `ACDL_` env var references remain in code/scripts/workflows/tests
|
||
except the dual-read fallback in the loader + `.env.secrets` legacy
|
||
comment.
|
||
- Dual-read fallback implemented and unit-tested.
|
||
- Contract resolver reads `.nova/contract.yml`; deploy workflow
|
||
checks out `.nova/`; docs updated.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P3 — ssm-tagkeys (Wave 3)
|
||
- **Description:** SSM path migration: rename the parameter path prefix
|
||
`/acdl/{env}/{contractId}/{output}` →
|
||
`/nova/{env}/{contractId}/{output}` across `core/output_publisher`,
|
||
the contract resolver, and consumer docs. Add a migration script
|
||
(`scripts/migrate_ssm_paths.py`) that copies existing `/acdl/...`
|
||
parameters → `/nova/...`, then readers are updated, then old
|
||
parameters are deleted. Tag key migration: add `nova:*` tags to all
|
||
AWS resources (parallel-tag period), update the ABAC session policies
|
||
to match `nova:*`, update `nova_tagging.py` to enforce `nova:*`
|
||
(hard, no warn), then remove `acdl:*` tags once consumers are
|
||
verified. Terraform tagging updated to emit `nova:*`.
|
||
- **Status:** complete (v1.15.3)
|
||
- **Depends on:** [P2]
|
||
- **Requirements:** REQ-161, REQ-162
|
||
- **Success Criteria:**
|
||
- SSM readers use `/nova/...`; migration script copies + deletes;
|
||
test asserts new path.
|
||
- `nova_tagging.py` enforces `nova:*` (hard fail on `acdl:*`).
|
||
- ABAC session policies match `nova:*`; terraform emits `nova:*` tags.
|
||
- `acdl:*` tags removed from all resources (verified via `aws` CLI or
|
||
documented deferred if no live AWS access).
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P4 — aws-resource-migration (Wave 4)
|
||
- **Description:** Rename all `acdl-*` AWS resources → `nova-*` via
|
||
terraform with a staged migration: KMS alias `alias/acdl-platform` →
|
||
`alias/nova-platform` (repoint), SNS `acdl-sod-halt` →
|
||
`nova-sod-halt` (recreate), SG `acdl-ecs-sg` → `nova-ecs-sg`
|
||
(recreate), Lambda `acdl-contract-ingestor` →
|
||
`nova-contract-ingestor` (recreate), DynamoDB `acdl-contracts`/
|
||
`acdl-change-requests` → `nova-contracts`/`nova-change-requests`
|
||
(scan+copy data migration, verify row counts, keep old tables until
|
||
verified), ECR `acdl-microservice` → `nova-microservice` (re-push
|
||
images), IAM user/policy `acdl-spike-runner` → `nova-spike-runner`
|
||
(re-bootstrap with new key), state bucket `acdl-tfstate-...` →
|
||
`nova-tfstate-...` (`terraform init -migrate-state` to new backend,
|
||
state JSON backed up first), ALB name prefix `acdl-alb` → `nova-alb`
|
||
(recreate, brief downtime). Publish a maintenance window + rollback
|
||
runbook (`docs/NOVA_AWS_MIGRATION.md`). For the offline/local tier,
|
||
the terraform `name`/`resource` labels change so `terraform validate`
|
||
passes; live apply/modify/destroy is exercised by the
|
||
modules-lifecycle workflow when `ACDL_LIFECYCLE_MODE` (now
|
||
`NOVA_LIFECYCLE_MODE`) is set to full.
|
||
- **Status:** complete (v1.15.4)
|
||
- **Depends on:** [P3]
|
||
- **Requirements:** REQ-163
|
||
- **Success Criteria:**
|
||
- All terraform resource names/labels use `nova-*`; `terraform
|
||
validate` passes for platform/microservice/ci-vpc.
|
||
- State bucket name → `nova-tfstate-...`; `terraform init
|
||
-migrate-state` documented + tested offline.
|
||
- DynamoDB data-migration script exists (scan+copy, row-count
|
||
verify).
|
||
- `docs/NOVA_AWS_MIGRATION.md` runbook exists (maintenance window,
|
||
rollback steps).
|
||
- `grep -rn "acdl-" terraform/` returns 0 hits.
|
||
- `pytest` passes; `run_ci.sh` exits 0.
|
||
|
||
### Phase P5 — final-review-ship (Final Phase)
|
||
- **Description:** Multi-persona code review across all v1.15 phases.
|
||
Audit (reconstruction test, file discipline, branch hygiene, commit
|
||
discipline). Remove the dual-read env var fallback (`ACDL_*`→`NOVA_*`)
|
||
once all consumers are migrated; finalize the consumer migration
|
||
guide; `nova_tagging.py` no longer accepts `acdl:*` tag keys. Complete:
|
||
update REQUIREMENTS.md (REQ-155..164 marked complete), ROADMAP.md
|
||
(v1.15 complete), PROJECT.md. Tag final patch `v1.14.5` (IS the
|
||
milestone release). Merge `milestone/v1.15-nova` → `main`.
|
||
- **Status:** complete (v1.15.4, milestone release)
|
||
- **Depends on:** [P1-P4]
|
||
- **Requirements:** REQ-164
|
||
- **Success Criteria:**
|
||
- Review: 0 new P0; all P1+ flagged or auto-fixed.
|
||
- Audit: clean; reconstruction test passes.
|
||
- Dual-read fallback removed; `nova_tagging.py` hard-fails `acdl:*`.
|
||
- Tag `v1.15.4` created; milestone merged to main.
|
||
|
||
After Phase P5: milestone COMPLETE — `v1.15.4` IS the v1.15 release.
|
||
|
||
---
|
||
|
||
## v1.16 (complete — Nova Simplification, tag `v1.15.26`)
|
||
|
||
A 20-phase NFR sweep (no new features) themed around five user-directed
|
||
axes: **Simplify without regressions**, **Security**, **Maintainability**,
|
||
**User/Developer Experience**, **No Humans Onboarding Flow**. The v1.15
|
||
rebrand left a fresh debt layer (stale brand strings, a state-bucket
|
||
drift, a Kyverno policy contradicting the Nova tagging standard, dead
|
||
code) that this milestone cleared, alongside genuine simplification
|
||
(dedup helpers, a workflow generator, file splits) and the first
|
||
self-service onboarding request path (request-path only; real AWS
|
||
provisioning deferred, D-113).
|
||
|
||
**Milestone type:** NFR (all phases fix/chore/docs/refactor/test). The
|
||
final phase's patch IS the deliverable. Tags on the v1.15.x line:
|
||
`v1.15.5` (P0) → `v1.15.6..v1.15.25` (P1–P20) → `v1.15.26` (P21 final =
|
||
milestone release).
|
||
|
||
**Regression gate (D-118, G-111):** 18 Verified + 4 Skipped (CAP-013..016
|
||
live-AWS caps are the post-v1.11-teardown steady state, D-096; re-
|
||
provisioning is a future feature). 0 Decayed/Broken at P9 + P21.
|
||
|
||
**Grill:** PASS-with-binding (G-111..G-113, E-002 deferred to P21).
|
||
G-111: gate criterion restated 18V+4S + Skipped logic. G-112: P9 source
|
||
model pinned. G-113: P12/P13 import direction documented.
|
||
|
||
**Wave outcomes:**
|
||
- Wave 1 (P1–P4): state-bucket + Kyverno rebrand fix (correctness
|
||
regression), user-facing ACDL→Nova sweep, dead-code cleanup, except
|
||
narrowing.
|
||
- Wave 2 (P5–P9): regression-verify dedup (~70 lines), run-platform
|
||
HITL fn + config, contract-resolver envloader + registry kind, workflow
|
||
generator (sync_workflows.py + workflows-src/), run-platform split
|
||
(decommission + uptime helpers). Gate PASS at P9.
|
||
- Wave 3 (P10–P14): ingestor defense-in-depth (fail closed on missing
|
||
IAM), payload validation (size cap + schema), split contract-resolver
|
||
(decommission + CLI modules), split regression-verify (CLI module),
|
||
schema-driven outputs + schema cache. Mid-milestone checkpoint clean.
|
||
- Wave 4 (P15–P17): run-platform --help + flags doc, workflows README
|
||
catalog (7 workflows), getting-started consolidation (offline-first).
|
||
- Wave 5 (P18–P20): onboarding schema + onboard_consumer Lambda action,
|
||
env-file autogen (core/onboarding.py), cross-account role Terraform
|
||
(offline-proven, D-114).
|
||
|
||
**Outcome:** 20 requirements (REQ-165..184) satisfied; ~630 tests pass;
|
||
regression gate 18V+4S; the onboarding request path is self-service (no
|
||
"contact the platform team" handoff); real AWS provisioning explicitly
|
||
deferred (D-113/D-114).
|
||
|
||
Ship tag at milestone COMPLETE: `v1.15.26` (NFR milestone; final patch IS
|
||
the release). **DONE.**
|