Files
acdl/.ciagent/REQUIREMENTS.md
T
Jon Chery 8c09580c43
acdl-ci / Lint (pull_request) Successful in 15s
acdl-ci / Platform check-only (offline) (pull_request) Successful in 33s
acdl-modules-lifecycle / CI VPC apply (pull_request) Successful in 58s
acdl-ci / Test (pull_request) Successful in 4m52s
acdl-modules-lifecycle / L1 lifecycle (alb) (pull_request) Failing after 2m7s
acdl-modules-lifecycle / L1 lifecycle (cloudfront) (pull_request) Failing after 1m30s
acdl-modules-lifecycle / L1 lifecycle (ecr) (pull_request) Successful in 3m2s
acdl-modules-lifecycle / L1 lifecycle (ecs-cluster) (pull_request) Successful in 3m38s
acdl-modules-lifecycle / L1 lifecycle (ecs-service) (pull_request) Failing after 5m15s
acdl-modules-lifecycle / L1 lifecycle (iam-role) (pull_request) Successful in 2m57s
acdl-modules-lifecycle / L1 lifecycle (kms-key) (pull_request) Failing after 1m18s
acdl-modules-lifecycle / L1 lifecycle (rds) (pull_request) Failing after 1m18s
acdl-modules-lifecycle / L1 lifecycle (s3) (pull_request) Successful in 2m56s
acdl-modules-lifecycle / L1 lifecycle (uptime) (pull_request) Failing after 5m19s
acdl-modules-lifecycle / L1 lifecycle (vpc) (pull_request) Successful in 2m56s
acdl-modules-lifecycle / L2 lifecycle (microservice) (pull_request) Failing after 59s
acdl-modules-lifecycle / L2 lifecycle (static-assets) (pull_request) Failing after 1m27s
acdl-modules-lifecycle / L1 lifecycle (waf) (pull_request) Successful in 3m24s
acdl-modules-lifecycle / CI VPC destroy (pull_request) Failing after 20m42s
docs(milestone): update v1.11 status — all phases complete
Update REQUIREMENTS.md traceability table: all 12 v1.11 requirements
(REQ-116, REQ-118..REQ-128) marked complete.

Update ROADMAP.md: v1.11 marked "complete" (was "active").

---ci---
project: acdl
phase: 0
milestone: v1.11
status: complete
requirements:
  covered: [REQ-116, REQ-118, REQ-119, REQ-120, REQ-121, REQ-122, REQ-123, REQ-124, REQ-125, REQ-126, REQ-127, REQ-128]
  partial: []
---/ci---
2026-07-29 12:24:23 +00:00

56 KiB
Raw Blame History

ACDL — Requirements

v1

Category: Repos & Org

  • REQ-01: All demo code lives under the continuous-intelligence Gitea org at https://git.cloudinit.dev.
  • REQ-09: Three repos exist: acdl (platform + stubs + reusable workflows), acdl-contracts (developer surface), acdl-evidence (Pages audit timeline).

Category: L1 Modules

  • REQ-02: 8 L1 module folders exist under acdl/modules/l1/: l1-eks-fargate, l1-iam-role, l1-lambda, l1-api-gateway, l1-eventbridge, l1-sqs, l1-s3, l1-cloudwatch.
  • REQ-03: Each L1 module has a manifest.yaml (declaring inputs) and a mock_apply.sh that echoes success, sleeps 1s, and exits 0.

Category: L2 Modules

  • REQ-04: 4 L2 modules exist under acdl/modules/l2/: l2-invoice-service, l2-commodity-price-feed, l2-energy-analytics-api, l2-regulatory-reporting, each composing the specified L1s.
  • REQ-05: L2 modules compose L1 primitives into deployable shapes with a maximum depth of 5.

Category: Core Scripts

  • REQ-06: mock_executor.sh reads an L2 composition, invokes each L1 mock_apply.sh, and writes state.json.
  • REQ-07: policy_checker.py reads contract.yaml and fails with POLICY_VIOLATION:PUBLIC_INGRESS on public-ingress: true; otherwise passes.
  • REQ-08: confidence_signal.py returns a base score of 0.90 and drops to 0.40 (with reason code) when policy fails; gate threshold is ≥ 0.50.

Category: Evidence Stream

  • REQ-11: evidence_writer.py appends events to audit.json and links each event to the previous via a SHA-256 hash chain (prev_hash + own hash).
  • REQ-13: acdl-evidence is Pages-enabled and serves audit.json plus index.html.

Category: Pipeline

  • REQ-10: The reusable pipeline runs Dev (autonomous), pauses at QA (manual approval), pauses at Prod (manual approval), then finalizes by committing audit.json to acdl-evidence.
  • REQ-12: Opening an Issue in acdl-contracts runs l3b_agent_stub.py, commits a generated contract.yaml to a new branch, closes the Issue, and triggers the main pipeline.

Category: Demo Acts

  • REQ-14: index.html uses vanilla JS to fetch audit.json from the Pages URL and render events as a timeline.
  • REQ-15: All four demo acts (Friction, Developer Self-Service, Citizen Developer, Safety Net) reproduce deterministically in a dry run.

v2

(None — v1 covers the complete demo.)

v1.1 (Prior milestone — architecture finalization + v1 spike, complete)

Category: Architecture Finalization

  • REQ-16: Architecture reaches v1.0 — all 11 open decisions in docs/architecture.md §13 are resolved and recorded in PROJECT.md (W1.A, W1.B, W2.A, W3.D, W3.E, BA.AF, OpenTofu timing).
  • REQ-17: Target Stack IR is defined as a JSON Schema under schemas/ir.schema.json; engine-agnostic (resources, relationships, composition max-depth-5, policy hooks).
  • REQ-18: PolicyCheckResult normalized schema is defined under schemas/policy_check_result.schema.json; a Checkov adapter translates Checkov JSON to this schema.
  • REQ-19: Six-input confidence signal is specified under platform/confidence_signal.py with per-env thresholds (dev 0.50 / qa 0.75 / prod 0.90 / dr 0.95) and severity→penalty mapping (critical=hard override, high=-0.2, medium=-0.05, low=-0.01, info=0.0).
  • REQ-20: Tiered audit ledger design is authored: S3 Object Lock (compliance mode, 7-yr) + DynamoDB outbox (RPO=0, JWS detached signatures, prev_event_hash chain, daily checkpoints).
  • REQ-21: Full 8-concern HITL matrix + separation-of-duties design is authored (CODEOWNERS routing + DynamoDB identity-distinctness check; pre-execution gate model; 1d warn / 2d freeze timeout).
  • REQ-22: Contract schema (JSON Schema draft 2020-12) is defined under schemas/contract.schema.json with per-env mandatory/optional inputs (W3.E) and profile: agentic marker for L3B fields.

Category: AWS OIDC Bootstrap

  • REQ-23: AWS auth bootstrap + state backend for the spike: an S3 state bucket + DynamoDB lock/outbox table + an IAM user with a minimal scoped policy (S3 + DynamoDB + plan-only). The temporary long-lived key is used once (waiver D-034) then rotated via scripts/rotate_spike_key.sh after each spike run (D-039). Real OIDC federation is deferred to v1.2 — Gitea Actions does not support id-token: write (RESEARCH TARGET 1, conf 0.95), blocked on go-gitea/gitea#36988.

Category: v1 Spike — IR, L1, Adapter

  • REQ-24: One real L1 module l1-s3 exists under modules-ir/l1/l1-s3/ with an IR-typed interface (typed inputs/outputs/NFRs) registered in the L1 registry.
  • REQ-25: One real L2 thin-composition l2-static-assets exists under modules-ir/l2/l2-static-assets/ referencing l1-s3 only (depth 1, within max-depth-5).
  • REQ-26: The Terraform adapter (adapters/terraform/) compiles the IR-typed L1 interface to Terraform variable/output blocks and the L2 thin-composition tree to a Terraform root module; it emits a real terraform plan against AWS via OIDC; state is stored in S3 + DynamoDB.

Category: v1 Spike — End-to-End

  • REQ-27: One end-to-end contract submission (contracts/spike.yaml for l2-static-assets) flows through: contract schema validation → contract→IR resolution → terraform plan (real AWS) → Checkov PolicyCheckResult → confidence signal → evidence event written to the DynamoDB outbox.
  • REQ-28: Spike verification (scripts/verify_phase10.sh) proves the IR-shaped commitments hold: the adapter is the only engine-specific code; no polyglot mess; the L1 content, contract YML, and thin-composition tree are engine-agnostic.

Out of Scope (v1.1)

Feature Reason
Full HITL matrix wiring (qa/prod/dr) Spike is dev-only (terraform plan); HITL wiring is v1.2.
Kyverno + OPA policy engines Spike uses Checkov only; Kyverno/OPA are v1.2.
MCP skill catalog + real L3B agent L3B spike = a single stub contract submission; the 5-skill catalog is v1.2.
GitOps reconciler (ArgoCD/Flux) v1.2.
Multi-region state / outbox Single-region in v1 (§9, §12.3).
Prod/dr environments v1.2.
Terraform apply (real provisioning) Spike runs plan only; apply is gated by HITL in v1.2.

v1.2 (Prior milestone — platform hardening + first real consumer deployment, complete, tag v1.3.0)

Category: Documentation & Simplification

  • REQ-29: README.md is fully rewritten to reflect the v1.1-complete platform: the actual spike flow (contract → IR → terraform plan → Checkov → confidence signal → outbox), how to run it (scripts/run_platform.sh), the real repo layout (acdl_platform/, schemas/, adapters/, terraform/, modules-ir/, contracts/, demo/), and the v1.2 objective. No stale "v1.1 (active)" framing.
  • REQ-30: NFR hardening of the v1.1 spike: (a) terraform/bootstrap/spike_runner_policy.json audited to least-privilege (S3 + DynamoDB + ECS + ECR + ELB + IAM plan-only, no wildcards beyond the documented exceptions); (b) create_state_backend.py and create_iam_user.py are idempotent (re-running exits 0 without duplicating resources); (c) run_spike_plan.sh + run_spike_e2e.sh consolidated into a single scripts/run_platform.sh with proper exit codes and error handling; (d) P1-1 carried forward from the v1.1 audit — the two AWS access key IDs in .ciagent/VERIFY.md Phase 09 narrative are redacted to placeholders; (e) any remaining stale platform/ paths in .ciagent/ are corrected to acdl_platform/.

Category: L1 Catalog Expansion (ECS Fargate)

  • REQ-31: Six new IR-typed L1 modules exist under modules-ir/l1/ and are registered in modules-ir/registry.json: 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 (application load balancer + listener + target group), l1-ecr (ECR repository). Each has an interface.json valid against schemas/ir.schema.json and produces a valid terraform plan fragment via the Terraform adapter. The adapter TYPE_MAP is expanded to cover all six IR resource types.

Category: L2 Composition & Contract Schema

  • REQ-32: l2-microservice thin-composition exists under modules-ir/l2/l2-microservice/ referencing the six ECS L1s (depth ≤ 5, within max-depth-5). schemas/contract.schema.json is extended with microservice inputs (image: string, port: integer, env: map, healthcheck: object) and validates a contracts/microservice.yaml submission. Contract→IR resolution (acdl_platform/contract_resolver.py) yields a complete target stack for l2-microservice.

Category: Real Provisioning

  • REQ-33: The platform runs terraform apply (not just plan) for the dev environment, autonomous per §10 (confidence ≥ 0.50, no HITL). The apply creates real AWS resources (VPC, ECS cluster, ECR repo, ALB, ECS service) and the result is captured in the evidence stream. apply for qa/prod/dr remains HITL-gated and out of scope for v1.2.

Category: Consumer Repo

  • REQ-34: A new Gitea repo acdl-consumer-microservice exists under the continuous-intelligence org, containing: a basic HTTP microservice (e.g., a tiny Python/Go server returning 200), a Dockerfile, an ECR push step, and a contracts/microservice.yaml submission for l2-microservice (dev environment).

Category: End-to-End Verification

  • REQ-35: One end-to-end flow: consumer commit to acdl-consumer-microservice → pipeline triggered → contract→IR resolution → terraform planterraform 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. scripts/verify_phase16.sh proves the full flow green.

v1.3 (Prior — module documentation + thin-composition removal, complete)

Category: Thin-Composition Removal

  • REQ-36: The L2 thin-composition layer is removed completely: composition.json files, acdl_platform/contract_resolver.py, schemas/contract.schema.json, contracts/spike.yaml, contracts/microservice.yaml, and L2 entries in modules-ir/registry.json are deleted. The L2 directories are kept as placeholders with READMEs. The downstream pipeline (adapter → checkov → confidence → outbox) is patched to load a pre-existing IR instance instead of resolving a contract.
  • REQ-37: A modules-ir/README-TEMPLATE.md exists that works for both L1 and L2 modules, written in plain language (no jargon), with sections for Overview, Resources, Inputs, Outputs, Usage, Compliance extension points, and Versioning.
  • REQ-38: Every module has a README.md: the 7 L1 modules have full READMEs with Resources/Inputs/Outputs/Usage/Compliance-extension-points/Versioning sections derived from their interface.json; the 2 L2 modules have placeholder READMEs noting the composition is under redesign. A modules-ir/README.md catalog index lists all modules with one-line descriptions and links.

Category: Testing

  • REQ-39: A pytest test suite exists under tests/ covering the platform components offline (no AWS, no Checkov, no DynamoDB): the Terraform adapter (adapters/terraform/adapter.py), the confidence signal (acdl_platform/confidence_signal.py), the Checkov adapter (adapters/terraform/policy/checkov_adapter.py), and the outbox writer (acdl_platform/outbox_writer.py). The suite validates the IR schema, registry, spike_instance, and adapter output structure. pyproject.toml + requirements-test.txt pin test dependencies (pytest, jsonschema, pyyaml, boto3-stubs or moto for outbox mocking).

Category: Shell Reproducibility

  • REQ-40: scripts/run_platform.sh has a --check-only mode that runs offline: loads the pre-existing IR instance, runs the adapter to emit Terraform, validates the JSON structure — without AWS credentials, Checkov, or DynamoDB. The existing --plan-only and full modes continue to require AWS. The --check-only mode is what CI pipelines run.

Category: CI/CD Pipelines

  • REQ-41: Identical CI/CD pipelines exist for both Gitea Actions (.gitea/workflows/ci.yml, dev environment) and GitHub Actions (.github/workflows/ci.yml, production). Both run the same three stages: (1) lint — py_compile all Python files, (2) test — pytest, (3) check-only — bash scripts/run_platform.sh --check-only. Both trigger on push to main + pull request. Both use ubuntu-latest. Identical outcomes — the only difference is the runner environment.

  • REQ-42: pyproject.toml exists at the repo root with pytest configuration (testpaths, markers) and the project metadata. requirements-test.txt pins test-only dependencies separate from runtime dependencies.

v1.4 (Active — central pipeline contract + shell reproducibility + streaming)

Category: Central Pipeline Contract

  • REQ-43: A central pipeline contract exists as schemas/pipeline.schema.json (JSON Schema draft 2020-12) + pipelines/ci.yaml (YAML instance). The contract declares the pipeline name, triggers (push/PR branches), runner, Python version, and stages (name + command + required + install + description). Both .gitea/workflows/ci.yml (Gitea Actions, dev) and .github/workflows/ci.yml (GitHub Actions, production) implement the same stages, commands, triggers, and runner as declared in the contract. A test (tests/test_pipeline_contract.py) validates the contract against the schema and asserts both workflows conform (same jobs, same commands, same triggers, same runner, byte-identical).

Category: Shell Reproducibility

  • REQ-44: scripts/run_ci.sh reproduces the CI pipeline locally — runs the same 3 stages (lint, test, check-only) in sequence with proper exit codes, failing on first error. The script exits 0 with "CI PIPELINE OK" on success. A --quiet flag suppresses per-stage banners. The script mirrors the central pipeline contract (pipelines/ci.yaml) so the shell and CI environments produce identical outcomes.

Category: Pipeline Streaming

  • REQ-45: scripts/run_platform.sh streams output by default: terraform init/validate/plan output is piped to stdout via tee (visible to the user and logged), Checkov results are printed in human-readable form, and PolicyCheckResult records are displayed with severity, rule ID, and pass/fail status per record. The --check-only mode streams the emitted Terraform file content. A --quiet flag suppresses streaming (output to log files only) for backwards compatibility. Both gitea and github workflows are byte-identical (identical outcomes — the only difference is the forge runtime).

v1.5 (Prior — consumer happy path + zero-trust docs + reusable deploy workflow, complete)

Category: Consumer Happy Path Documentation

  • REQ-46: README.md is rewritten so the consumer model is unambiguous: this repo is the platform source; a consumer never clones it. A consumer repo contains only app code + contract.yaml referencing the central pipeline + contract. The platform-flow diagram is a mermaid flowchart TD (replacing the ASCII art). "L3A"/"L3B" nomenclature is removed from README (single-surface model). "spike" nomenclature is removed from prose (code paths in bash blocks are kept verbatim).
  • REQ-47: docs/CONSUMER_GUIDE.md (all-caps) replaces docs/consumer-guide-static-assets.md. It is generic across all L2 modules (static-assets as the worked example), uses mermaid diagrams (model + pipeline flow), documents versioned uses: references (floating MAJOR+MINOR tags — bare/@main discouraged), scopes prerequisites to consumer-repo bootstrap only (no Terraform/Checkov/boto3/runner-key — those are platform-repo concerns), and documents that the pipeline fetches the ACDL repo at run time via a reusable workflow (consumers never invoke scripts/run_platform.sh locally for the happy path).
  • REQ-48: README.md Credentials section is rewritten to express the zero-trust target model: consumer repos use OIDC federation (no long-lived keys) with attribute-based authorization (ABAC) — IAM roles + session policies scoped by repository identity and resource-creation tags so a consumer can only view/update resources it created (blast-radius containment). A documented override allows a static key in GitHub Secrets (consumer repo) or .env.secrets (local testing), rotated by a platform-managed scheduled pipeline on a daily cadence; when .env.secrets is used locally, rotating out of band is the consumer's responsibility.

Category: Reusable Deploy Workflow

  • REQ-49: A reusable deploy workflow exists as byte-identical .gitea/workflows/deploy.yml (Gitea, dev) and .github/workflows/deploy.yml (GitHub, production), implementing the central deployment pipeline contract (pipelines/deploy.yaml validated against schemas/deploy-pipeline.schema.json). It is invoked by consumer repos via uses: acdl/.gitea/workflows/deploy.yml@vMAJOR.MINOR (versioned tag). The workflow checks out the consumer repo, checks out the ACDL platform repo into the runner workspace, installs runtime deps (Python, Terraform, Checkov), and invokes scripts/run_platform.sh against the consumer's contract path (passed as a workflow input). OIDC is the default auth (permissions: id-token: write); a static-key override reads from repository secrets.
  • REQ-50: contracts/static-assets.yaml uses a versioned uses: reference (@v1.4, MAJOR+MINOR) — not bare @v1 or @main — as the canonical example the consumer guide points at.
  • REQ-51: tests/test_pipeline_contract.py is extended to validate the new deploy workflows: both files exist, are byte-identical, and conform to schemas/deploy-pipeline.schema.json (stages present, names match pipelines/deploy.yaml stage names). The existing CI-workflow conformance tests continue to pass unchanged.

v1.6 (Active — consumer-facing docs restructure + terminology normalization + environments concept)

Category: Internal-surface scrub

  • REQ-52: No consumer-facing documentation (README.md, docs/, modules//README.md, contracts/**) references .ciagent/ — it is local CIAgent metadata, never visible to platform engineers or consumers. The README repository-layout table has no .ciagent/ row. No .gitea/ references appear in consumer-facing docs (consumers use GitHub only); the README repository-layout table has no .gitea/workflows/ row.
  • REQ-53: acdl_platform/ is renamed to core/ across the directory, all imports in tests/scripts/pipelines/workflows, and all doc references. (platform/ was the original target but shadows Python's stdlib platform module — core/ was chosen to stay importable.) grep -R "acdl_platform" . (excluding .ciagent/, demo/, .git/) returns 0 hits. The test suite passes after the rename.

Category: Docs site restructure

  • REQ-54: docs/ is restructured into a Jekyll-style GitHub Pages site: docs/_config.yml, docs/index.md (landing), docs/modules/ (catalog + per-module Pages-friendly copies), docs/contracts/index.md, docs/pipeline/index.md + docs/pipeline/versioning.md, docs/environments/index.md, docs/consumer-guide.md, docs/architecture.md (consolidated from architecture.md + architecture-v1.0.md, current-architecture only), docs/vision.md. No .ciagent/ links anywhere in docs/. Consumer-facing content (modules, contracts, pipeline, versioning) lives in Pages.

Category: Terminology normalization

  • REQ-55: Consumer-facing docs drop the "L2" nomenclature — L2 modules are referred to as "modules". "L1" label is dropped in consumer-facing docs — L1 primitives are referred to as "primitives". The "composition" terminology is changed to "pattern" for modules in prose (the on-disk composition.json files and code references are unchanged this phase). A roadmap entry records that "composition" will later describe the thin orchestration where consumers dynamically create a module directly from the contract file (future implementation, not implemented now).
  • REQ-56: The term "forge" is replaced in consumer-facing docs with "platform runners" / "platform-managed" as appropriate. The term "forge" remains only in internal architecture docs.

Category: README rewrite

  • REQ-57: README.md repository-roles section is restated to match reality: a consumer repo contains (a) its application code, (b) one or more contracts (.acdl/contract.yaml), and (c) one or more CI definitions (a thin .github/workflows/deploy.yml that uses: the central reusable workflow, pointing at the appropriate environment + contract). The platform repo (this one) owns modules/adapters/schemas/pipelines/scripts/workflows. A consumer never clones the platform repo.
  • REQ-58: README.md Status section is replaced with a Features list (referenceable by consumers and platform engineers) and a Roadmap subsection listing only planned future features (no internal CIAgent status, no version-by-version changelog).
  • REQ-59: README.md "How the platform works" mermaid diagram is revised so all node text is visible (no overflow): labels are split with <br/>, boxes widened as needed. A security-checks stage is added before the policy-checks stage. Specific tools (Checkov, Terraform) are not named — they are "security checks (adapter)", "policy checks (adapter)", "infrastructure plan". An "infrastructure apply" stage is added at the appropriate level (dev only, after confidence).
  • REQ-60: README.md Credentials & zero-trust section removes the "go-gitea/gitea#36988 blocked" mention and the "waivers D-039/D-047" language (not consumer/platform-engineer facing). It states: default OIDC + ABAC; alternative is a static AWS key (GitHub Secrets for platform-runner runs, or .env.secrets locally) with the expectation of daily rotation (platform-managed for runner runs) or out-of-band rotation (consumer-managed for local .env.secrets).

Category: Environments concept + onboarding

  • REQ-61: The concept of platform-managed environments is introduced: consumers are not required to provide an AWS account, VPC, subnet, S3 state bucket, or runner key. docs/environments/index.md documents that a named environment is a platform-owned AWS account + network + state backend + IAM role surfaced to the consumer via ABAC, selected by name in the contract. The old README environments table (dev/qa/prod/dr) is removed completely. A minimal onboarding scaffold exists: platform/environments/ with a sample dev.json + README, platform/environment_check.py, a wire-in at the top of scripts/run_platform.sh, a friendly first-run onboarding message when no environment is defined for the repo, and tests/test_environment_check.py covering the missing-env and present-env cases.

v1.7 (Active — production platform + contract ingestion + pipeline maturation)

Category: Rename + production-ready stack

  • REQ-62: static-assets is renamed to static-assets everywhere (D-048 — including .ciagent/ historical narrative: verbatim phase descriptions, REQ-25/27/50 text, D-036, RESEARCH.md). grep -R "static-assets[^s]" . (excluding .git/) returns 0 hits. The module dir modules/l2/static-assets/modules/l2/static-assets/; contracts/static-assets.yamlcontracts/static-assets.yaml; the registry key is renamed; all scripts, tests, docs, and .ciagent/ files use static-assets. The reconstruction test is updated to expect static-assets throughout.
  • REQ-63: Two new primitives exist: cloudfront (distribution + OAC, stack types aws:cloudfront:distribution + aws:cloudfront:originaccesscontrol) and waf (WAFv2 web ACL, stack type aws:wafv2:webacl), each with an interface.json valid against schemas/stack.schema.json and a full README (Resources/Inputs/Outputs/Usage/Compliance/Versioning). Both are registered in modules/registry.json. The Terraform adapter TYPE_MAP/INPUT_MAP/OUTPUT_MAP covers the new stack types.
  • REQ-64: The static-assets module is augmented to a production-ready stack referencing s3 + cloudfront + waf (depth 1, D-049). composition.json wires the s3 bucket regional domain name to the CloudFront origin, and the WAF web ACL ARN to the CloudFront distribution. schemas/contract.schema.json is extended for the new module inputs (price_class, viewer_protocol_policy, waf_enabled, default_ttl, max_ttl). The uses:/ref: tag advances from @v1.4 to @v1.6 (D-056/D-057); floating git tags v1.6 + v1 are created pointing at v1.6.0.

Category: Tagging standards + security adapters

  • REQ-65: A required-tag set is defined in schemas/tagging-standard.json (acdl:owner, acdl:contract, acdl:environment, acdl:cost-center). A Checkov custom YAML rule at adapters/terraform/policy/custom_rules/acdl_tagging.yaml fails (severity medium) when required tags are missing on taggable resources. checkov_adapter.py removes the _emit_tag_naming_skipped() placeholder (D-043 closure) and maps ACDL_TAG_NAMING as a real rule. scripts/run_platform.sh Step 5 passes --external-checks-dir to load the custom rule.
  • REQ-66: A Wiz adapter stub exists at adapters/wiz/wiz_adapter.py translating Wiz API issues → PolicyCheckResult records (engine: "wiz", D-052). It degrades gracefully when unconfigured (emits a single SKIPPED WIZ_NOT_CONFIGURED record). tests/test_wiz_adapter.py passes offline with a fixture response. The pipeline invokes it optionally (Step 5b) when WIZ_API_TOKEN is set.
  • REQ-67: A Kyverno K8s-native adapter exists at adapters/kyverno/kyverno_adapter.py translating Kyverno PolicyReport results → PolicyCheckResult records (engine: "kyverno", D-053). Sample policies exist at adapters/kyverno/policies/ (disallow-privileged, require-labels, require-image-digests). tests/test_kyverno_adapter.py passes offline. The adapter is inactive for Terraform-only stacks (the platform emits Terraform, not K8s manifests); it is ready for the GitOps reconciler roadmap item. schemas/policy_check_result.schema.json engine enum includes checkov | kyverno | opa | wiz.

Category: Platform Lambda + contract ingestion

  • REQ-68: A platform Lambda (core/lambda/contract_ingestor.py) is invoked via a Function URL (IAM auth) and accepts { consumerRepo, contractId, contract, environment, action }. It writes contracts to a DynamoDB table acdl-contracts (PK consumerRepo, SK contractId#submittedAt, SSE via a customer-managed CMK, point-in-time recovery) (D-051). terraform/platform/main.tf defines the table, Lambda, Function URL, KMS key, Secrets Manager secret (acdl/github-token), and Lambda execution role. terraform/platform/consumer_invoke_policy.json grants the consumer's deploy role lambda:InvokeFunctionUrl on the Lambda ARN, scoped via ABAC (cross-account). Onboarding grants the Lambda-invoke permission; docs/environments/index.md documents this. tests/test_contract_ingestor.py passes offline (moto-mocked DynamoDB).

Category: Deploy outputs + error reporting + stage comments

  • REQ-69: scripts/run_platform.sh has a publish-outputs step (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). core/output_publisher.py implements the SSM write + GitHub comment formatting. tests/test_output_publisher.py passes offline (moto + mocked GitHub API). pipelines/deploy.yaml + both deploy workflow YAMLs declare the new stages (byte-identical).
  • REQ-70: The Lambda report_error action (core/lambda/contract_ingestor.py) creates a GitHub issue on the platform repo (acdl/acdl) via the GitHub API using a token from Secrets Manager (D-055). Idempotent (comments on an existing open issue rather than duplicating). .github/workflows/deploy.yml + .gitea/workflows/deploy.yml (byte-identical) have an if: failure() error-report step invoking the Lambda via aws lambda invoke-function-url (SigV4-signed). Gitea is excluded (only the CIAgent uses it; platform engineers and consumers use GitHub).
  • REQ-71: .github/workflows/deploy.yml + .gitea/workflows/deploy.yml (byte-identical) post a PR comment after every successful pipeline stage (validate-contract, resolve-stack, plan, checkov, confidence, apply, publish-outputs) via scripts/post_stage_comment.sh (uses GITHUB_TOKEN + gh api; no-op when not in a PR context). The comment includes the stage name, status (pass), and key metrics (plan counts, confidence score, outputs published).

Category: Platform pipelines + release automation

  • REQ-72: Three platform pipelines exist: (1) .github/workflows/platform-test.yml (PR, stages: lint, unit-test, integration-test — runs run_platform.sh --check-only for every sample contract, schema-validation — validates all schemas/*.json + modules/**/interface.json + modules/**/composition.json + modules/<name>/examples/*.yaml against their schemas); (2) .github/workflows/primitives-plan.yml (PR, plan-only for all L1 primitives via matrix, scripts/run_primitive_plan.sh); (3) .github/workflows/patterns-plan.yml (PR, plan-only for all L2 modules via matrix, scripts/run_pattern_plan.sh).
  • REQ-73: .github/workflows/release.yml 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, and creates a GitHub release with an auto-generated body (D-057). tests/test_release_logic.py passes (unit test the semver computation + tag-update logic with a mocked git describe).

Category: Remove legacy consumer-repos + module examples + RDS primitive

  • REQ-74: The legacy consumer-repos directory is deleted entirely (a v1.2 artifact removed in v1.7; references in .ciagent/ historical narrative are rewritten per D-048). A recursive grep for the legacy directory name (excluding .git/) returns 0 hits.
  • REQ-75: A new RDS primitive (modules/l1/rds/) with an engine input (enum: postgres, mysql, etc.) demonstrates multi-engine variation (D-059). Every module (primitives + patterns) has a modules/<name>/examples/ directory with simple.yaml + complex.yaml (+ variation files) validated against schemas/contract.schema.json in the platform-test pipeline schema-validation stage (D-058). Each module's README.md ## Examples section references + excerpts the validated files. docs/modules/index.md + docs/consumer-guide.md + docs/contracts/index.md are updated with the new module names + examples.

v1.8 (Complete — P1 remediation + uptime + engineering standards + encryption/deletion-protection by default + decommission + docs)

Category: P1 Fixes

  • REQ-76: WAF adapter emits custom rules as nested HCL blocks (not attribute syntax) and honors default_action input (allow/block) — P1-4, P1-5 closed.
  • REQ-77: L2 composition outputs[] array is resolved by contract_resolver.py into stack.outputs; the adapter emits corresponding output blocks — P1-7 closed.
  • REQ-78: SSM publisher fails loud when ACDL_KMS_KEY_ID is unset (no silent AWS-managed-key fallback); ACDL_ALLOW_DEFAULT_KMS=1 escape hatch for local testing — P1-3 closed.
  • REQ-79: consumer_invoke_policy is rendered via Terraform with the caller's live account ID (no 000000000000 placeholder) — P1-6 closed.
  • REQ-80: run_platform.sh emits adapter output to a per-run temp dir, not committed terraform/spike/*.tf; the committed files are removed — P1-8 closed.
  • REQ-81: contract_ingestor.py reads GITHUB_API_BASE env for forge-agnostic API URLs (GitHub + Gitea) — P1-9 closed.
  • REQ-82: Deploy workflow static-key override is wired to configure-aws-credentials inputs (access-key/secret-key), not inert env vars — S1 closed.

Category: Encryption by Default

  • REQ-83: A per-stack CMK primitive (kms-key) exists with 90-day rotation enabled at creation; one key per L2 deployment; no shared keys across stacks.
  • REQ-84: All primitives have encryption by default (encryption_enabled NFR, default true) + optional kms_key_arn input. CMK is prioritized; managed KMS is the fallback when no CMK is provided.
  • REQ-85: L2 modules wire a per-stack CMK child + connect its kms_key_arn output to each child's kms_key_arn input.

Category: Deletion Protection by Default

  • REQ-86: deletion_protection NFR (boolean, default true) on every L1 primitive; the adapter emits prevent_destroy lifecycle meta-arg when true.
  • REQ-87: L2 modules expose a features.deletion_protection flag (default true); consumers can disable via contract inputs.deletion_protection: false.

Category: Uptime Monitoring

  • REQ-88: An uptime-kuma L1 primitive exists (ECS Fargate) with: feature_flag_enabled (boolean, default true), monitored_endpoints (array of HTTP/DNS/TCP checks), static_checks (pre-defined health checks), alert_channels (Teams webhook, email, SMS, GitHub issues).
  • REQ-89: Uptime is deployed by default after any L2 module deploy (separate terraform state, separate terraform run); L2 module outputs (endpoints) are passed to the uptime deployment as monitored_endpoints. The uptime URL is published to the consumer via PR comment.
  • REQ-90: The feature_flag_enabled input (set from consumer contract inputs.uptime_enabled, default true) disables the uptime deployment entirely (no resources emitted).
  • REQ-91: A deploy-uptime pipeline stage is declared in pipelines/deploy.yaml + both deploy workflow YAMLs (byte-identical).

Category: Decommission + CMDB

  • REQ-92: A decommission mode on the deploy pipeline (mode: decommission) implements a 2-step pipeline: (1) plan/apply to disable deletion protection with an HITL SRE gate, (2) plan/apply with all counts set to 0 with a second HITL SRE gate. Uses the existing deploy pipeline with different behavior.
  • REQ-93: A DynamoDB acdl-change-requests table serves as the CMDB. The decommission alias accepts a changeRequestId input validated via a validate_change_request Lambda action (CR status must be approved).
  • REQ-94: The decommission flow is documented in docs/CONSUMER_GUIDE.md (how to request a CR, trigger decommission, HITL gates, what happens).

Category: Engineering Standards

  • REQ-95: modules/STANDARDS.md exists with comprehensive L1 + L2 authoring + code review standards (scanned from current modules): required files, interface schema, input/output/NFR conventions, encryption + deletion protection as mandatory NFRs, naming, adapter extension pattern, code review checklist.
  • REQ-96: modules/README.md catalog index includes all primitives (rds + uptime + kms-key added); modules/README-TEMPLATE.md updated with ## NFRs section.

Category: Path Documentation

  • REQ-97: schemas/README.md documents how to write a schema, wire it into the platform, test it in CI, where to write tests, dependencies, and the existing schema catalog.
  • REQ-98: pipelines/README.md documents how to write a pipeline contract, wire it into workflows, test it, dependencies, and the existing pipeline catalog.
  • REQ-99: adapters/README.md documents how to write an adapter, wire it into the platform, test it, dependencies, and the existing adapter catalog.

Out of Scope (v1.2)

REQ Original criterion Clarified criterion (effective) Decision
REQ-09 Three repos exist Three repos exist (acdl, acdl-contracts, acdl-evidence) under continuous-intelligence; new repos use default_branch: "main", auto_init: true D-015
REQ-10 "Pages returns 200 with placeholder index.html" on acdl-evidence Gitea has no Pages; substitute: an HTTP GET against the raw file URL https://git.cloudinit.dev/continuous-intelligence/acdl-evidence/raw/branch/main/index.html returns 200 with the placeholder HTML body D-012, D-016
REQ-10 "qa and prod environments exist on acdl-contracts" Gitea has no environments API and ignores environment: blocks; substitute: the reusable workflow defines qa-gate and prod-gate jobs gated by workflow_dispatch approval inputs (D-004 fallback); a qa and prod branch may be created on acdl-contracts as a visible stand-in for environments D-013

Out of Scope (v1.0 demo — retained for history)

Feature Reason
Real cloud provisioning (AWS/GCP/Azure) Demo explicitly stubs all infrastructure; no cloud access available.
Real LLM inference / external AI APIs Spec forbids external AI; L3B is a keyword parser.
Production-grade infrastructure Demo target is a 30-minute executive show, not a production system.
Adversarial tamper-proofing of evidence Hash chain is demonstrative; not cryptographically secure against a determined attacker.
Multi-tenant isolation Out of demo scope.

v1.9 (complete — design doc refresh + contract interpolation + per-env CI jobs + stub implementation + P1-1 remediation, tag v1.9.0)

Category: Design Doc Refresh

  • REQ-100: core/hitl_matrix_design.md is up to date: the "dev-only spike" framing is replaced with the v1.9 wired-gates reality (qa/prod/dr workflow_dispatch approval gates + CODEOWNERS routing + outbox-based SoD); the 8-concern attestation matrix is marked implemented (offline-testable subset) with operator-supplied concerns noted; the spike-scope note is updated. No stale "v1.2 wires the gates" language remains.
  • REQ-101: core/audit_ledger_design.md is up to date: the hash-chain + DynamoDB-outbox path is marked shipped + production (since v1.8); the S3 Object Lock + JWS + async worker + DLQ + daily checkpoints build-out is clearly labeled "Deferred to a future milestone" (D-083); the RPO/RTO table reflects the v1.9 state.

Category: P1-1 Remediation

  • REQ-102: The adapter (adapters/terraform/adapter.py) contains no resource-type-specific hardcoded defaults for ECS/ALB/VPC resources — desired_count, launch_type, target_type, load_balancer_type, family, and Name tag values are read from L1 interface.json inputs (with defaults declared in the interface). The adapter is a thin translator. An L1 with an overridden desired_count: 3 emits desired_count = 3; the default emits desired_count = 1 via the interface default, not an adapter hardcode (P1-1 closed).

Category: Contract Interpolation

  • REQ-103: The contract resolver (core/contract_resolver.py) expands ${env.<field>} and ${contract.<field>} tokens in contract string values (including dotted paths like ${env.state_backend.bucket}) after schema validation and before IR resolution. The env context is the loaded core/environments/<contract.environment>.json; the contract context is the contract dict. Unresolved tokens raise ValueError (fail loud). Sample contracts use naming patterns that include region, account id, and environment (e.g. acdl-${env.environment}-${contract.module}-${env.account_id}-${env.region}).
  • REQ-104: An environment JSON schema schemas/environment.schema.json (draft 2020-12) defines the environment file shape (name, account_id, region, state_backend, network, runner_role_arn, autonomy, confidence_threshold). core/environments/dev.json validates against it. qa.json, prod.json, dr.json placeholder bindings exist (autonomy attested, thresholds 0.75/0.90/0.95).

Category: Per-Environment CI Jobs

  • REQ-105: Per-environment contract files exist for each sample module (contracts/static-assets.{dev,qa,prod,dr}.yaml and contracts/microservice.{dev,qa,prod,dr}.yaml), each setting environment: to its own name and using interpolation for env-specific values. The existing contracts/static-assets.yaml + contracts/microservice.yaml remain as the dev default for backwards compatibility.
  • REQ-106: The reusable deploy workflow (.github/workflows/deploy.yml + .gitea/workflows/deploy.yml, byte-identical) declares an environment workflow_call input (enum dev/qa/prod/dr, default empty). When non-empty, scripts/run_platform.sh --environment <name> overrides the contract's environment field at load time (before interpolation). A consumer repo's caller workflow has one job per environment, each pointing at its respective contract (or the same contract + the env input). Promotion = running the matching job; no environment: field editing. docs/CONSUMER_GUIDE.md documents the per-env caller workflow pattern.

Category: Stub Implementation

  • REQ-107: core/separation_of_duties.py route_halt_artifact is a real implementation: publishes to an SNS topic acdl-sod-halt (ARN from ACDL_SOD_HALT_TOPIC_ARN); when unset, falls back to a structured stderr emission + a SEPARATION_OF_DUTIES_VIOLATION event write to the DynamoDB outbox via outbox_writer.write_event. No silent print-only stub. The SNS topic is defined in terraform/platform/main.tf.
  • REQ-108: HITL qa/prod/dr pre-execution attestation gates are wired via core/hitl_gates.py (attest(contract_id, env, approver, evidence)). The gate records the approver (gitea.actor / github.actor) to the outbox (approver_qa / approver_prod / approver_dr attributes per audit_ledger_design.md), runs the separation-of-duties check on prod, and returns (ok, reason). scripts/run_platform.sh calls hitl_gates.attest before apply for qa/prod/dr (dev skips). The workflow's workflow_dispatch approval input is the trigger.
  • REQ-109: The full 8-concern attestation matrix from hitl_matrix_design.md §10.4 is implemented in core/attestation_matrix.py. Offline-testable concerns (contract NFRs, schema validity, policy pass) run for real; operator-supplied concerns (k6 load test, DR drill, FinOps forecast) accept an uploaded signed evidence artifact validated for freshness + schema, failing loud if missing/expired for prod/dr. hitl_gates.attest invokes the matrix for the target env and blocks on any failing concern.
  • REQ-110: The Wiz adapter (adapters/wiz/wiz_adapter.py) is a real API client: a WizClient queries the Wiz GraphQL API (WIZ_API_TOKEN + WIZ_API_URL) and translates issues → PolicyCheckResult records. It degrades gracefully (existing WIZ_NOT_CONFIGURED SKIPPED record) when env unset. Offline tests use a recorded GraphQL fixture.
  • REQ-111: The Kyverno adapter (adapters/kyverno/kyverno_adapter.py) translator is fleshed out: full PolicyReportPolicyCheckResult mapping with severity + skip handling. It remains inactive for Terraform-only stacks (guard preserved); a --kube-version stub is added for future GitOps. Sample policies already exist.

v1.10 (active — pipeline regression fix + capability re-verification + verified-reality rewrite, tag v1.10.0)

Category: Pipeline Regression Fix

  • REQ-112: The CIAgent VERIFY stage supports a regression mode that re-runs capability checks (not just diff checks), triggered at minimum on milestone completion. The regression run executes the local-emulator tier (REQ-113) for every capability marked Verified in prior milestones; any capability that fails the regression run blocks milestone completion. Regression results are recorded in ---ci--- blocks as regression: { capability: <id>, status: Verified|Decayed|Broken }. Existing diff-scoped VERIFY behavior is preserved for non-regression invocations. A regression run against the current codebase surfaces at least one Decayed/Broken capability (proving the gate catches decay, not just passes). tests/test_verify_regression_mode.py passes.

Category: Local Emulating Adapters

  • REQ-113: Local emulating adapters exist so the platform is fully locally testable without cloud credentials: (a) a flat-file DynamoDB outbox adapter that writes evidence events to flat files in a temp folder with a valid hash chain, same write/read interface as the live DynamoDB outbox adapter; (b) a local ECS Fargate emulator that records the service definition and returns a synthetic HTTP 200 from a local shell process, same interface as the live ECS adapter; (c) a local S3 state backend (flat-file tfstate in a temp folder); (d) a local Lambda stub that invokes the handler in-process with no AWS Lambda call. The headline E2E (contract submission → service live → evidence event) runs end-to-end against the local tier with no cloud credentials. tests/test_local_emulating_adapters.py passes. run_platform.sh --local (or equivalent) runs the full pipeline locally.

Category: Capability Re-Verification Sweep

  • REQ-114: Every capability advertised in v1.1→v1.8 PROJECT/ROADMAP is enumerated in .ciagent/CAPABILITY_INVENTORY.md with a unique ID per capability (v1.0 demo excluded as archived/superseded). Each capability is re-verified: the headline E2E (contract → ECS Fargate → evidence event) runs both live-AWS and local-emulator tiers, both must pass; all other capabilities run the local tier via emulating adapters (REQ-113). Each capability is tagged Verified / Decayed / Broken in CAPABILITY_INVENTORY.md. Every Decayed/Broken capability is fixed in-sweep (D-090: no cap) until Verified, with per-capability commits verify(P54): <id> — <status> and fix(P54): <id> — <summary>. All v1.1→v1.8 advertised capabilities end Verified. The regression run (REQ-112) is clean against the re-verified state.

Category: Verified-Reality Rewrite

  • REQ-115: PROJECT.md, ROADMAP.md, and both leadership decks are rewritten to match CAPABILITY_INVENTORY.md exactly. PROJECT.md gains a "Capability Status (Re-Verified 2026-07-27)" section listing every v1.1→v1.8 capability with its Verified tag and the tier(s) tested, plus a decay disclosure: capabilities marked complete in v1.1v1.8 ran at the time of tagging; as of 2026-07-27 they were not reproducible and were re-verified in v1.10. ROADMAP.md v1.9.x entries note deck-freeze and superseded-by-reverification status. Both leadership decks reflect the re-verified status; any claim that cannot be demonstrated live is removed. HTML is re-rendered; PPTX is uploaded to the v1.10.0 release. Decks are unfrozen only after this lands. ci-doc-verifier confirms no stale capability claims remain. v1.10.0 is tagged; the Gitea release is published.

Out of Scope (v1.9)

Feature Reason
S3 Object Lock + JWS + async worker + DLQ + daily checkpoints (audit ledger build-out) Requires non-offline-testable AWS infra (Object Lock bucket, KMS signing key, SQS DLQ, Lambda worker). Deferred to a future milestone (D-083). The hash-chain + DynamoDB-outbox path remains the v1.9 production audit record.
Live k6/Gatling load test execution, live DR drill, live FinOps forecast Operator-supplied evidence artifacts (signed blobs) are accepted + validated; the platform does not run these inline.
Self-service environment provisioning Adding an environment remains a platform-team action (per core/environments/README.md). v1.9 adds the env files + schema, not self-service provisioning.

Traceability

v1.0 (prior — demo)

Requirement Phase Status
REQ-01 1 complete (v1.0.1)
REQ-02 2 complete (v1.0.2)
REQ-03 2 complete (v1.0.2)
REQ-04 3 complete (v1.0.3)
REQ-05 3 complete (v1.0.3)
REQ-06 3 complete (v1.0.3)
REQ-07 3 complete (v1.0.3)
REQ-08 3 complete (v1.0.3)
REQ-09 1 complete (v1.0.1)
REQ-10 4 complete (v1.0.4)
REQ-11 3 complete (v1.0.3)
REQ-12 4 complete (v1.0.4)
REQ-13 5 complete (v1.0.5)
REQ-14 5 complete (v1.0.5)
REQ-15 5 complete (v1.0.5)

v1.1 (prior — architecture finalization + v1 spike, complete)

Requirement Phase Status
REQ-16 07 complete (v1.1.2)
REQ-17 07 complete (v1.1.2)
REQ-18 07 complete (v1.1.2)
REQ-19 07 complete (v1.1.2)
REQ-20 07 complete (v1.1.2)
REQ-21 07 complete (v1.1.2)
REQ-22 07 complete (v1.1.2)
REQ-23 08 complete (v1.1.3)
REQ-24 09 complete (v1.1.4)
REQ-25 10 complete (v1.1.5)
REQ-26 09 complete (v1.1.4)
REQ-27 10 complete (v1.1.5)
REQ-28 10 complete (v1.1.5)

v1.2 (prior — platform hardening + first real consumer deployment, complete)

Requirement Phase Status
REQ-29 11 complete (v1.2.1)
REQ-30 12 complete (v1.2.2)
REQ-31 13 complete (v1.2.3)
REQ-32 14 complete (v1.2.4)
REQ-33 15 partial (v1.2.5, IAM-blocked)
REQ-34 15 complete (v1.2.5)
REQ-35 16 partial (v1.2.6, IAM-blocked)

v1.3 (prior — module documentation + thin-composition removal, complete)

Requirement Phase Status
REQ-36 17 complete (v1.3.1)
REQ-37 17 complete (v1.3.1)
REQ-38 17 complete (v1.3.1)
REQ-39 18 complete (v1.3.2)
REQ-40 18 complete (v1.3.2)
REQ-41 18 complete (v1.3.2)
REQ-42 18 complete (v1.3.2)

v1.4 (prior — central pipeline contract + shell reproducibility + streaming)

Requirement Phase Status
REQ-43 19 complete (v1.4.1)
REQ-44 19 complete (v1.4.1)
REQ-45 19 complete (v1.4.1)

v1.5 (prior — consumer happy path + zero-trust docs + reusable deploy workflow, complete)

Requirement Phase Status
REQ-46 20 complete (v1.5.0)
REQ-47 20 complete (v1.5.0)
REQ-48 20 complete (v1.5.0)
REQ-49 20 complete (v1.5.0)
REQ-50 20 complete (v1.5.0)
REQ-51 20 complete (v1.5.0)

v1.6 (complete — consumer-facing docs restructure + terminology normalization + environments concept, tag v1.6.0)

Requirement Phase Status
REQ-52 21 complete (v1.6.0)
REQ-53 21 complete (v1.6.0)
REQ-54 21 complete (v1.6.0)
REQ-55 21 complete (v1.6.0)
REQ-56 21 complete (v1.6.0)
REQ-57 21 complete (v1.6.0)
REQ-58 21 complete (v1.6.0)
REQ-59 21 complete (v1.6.0)
REQ-60 21 complete (v1.6.0)
REQ-61 21 complete (v1.6.0)

v1.7 (complete — production platform + contract ingestion + pipeline maturation, tag v1.7.0)

Requirement Phase Status
REQ-62 22 complete (v1.7.0)
REQ-63 22 complete (v1.7.0)
REQ-64 22 complete (v1.7.0)
REQ-65 23 complete (v1.7.0)
REQ-66 23 complete (v1.7.0)
REQ-67 23 complete (v1.7.0)
REQ-68 24 complete (v1.7.0)
REQ-69 25 complete (v1.7.0)
REQ-70 25 complete (v1.7.0)
REQ-71 25 complete (v1.7.0)
REQ-72 26 complete (v1.7.0)
REQ-73 26 complete (v1.7.0)
REQ-74 27 complete (v1.7.0)
REQ-75 27 complete (v1.7.0)

v1.8 (complete — P1 remediation + uptime + standards + encryption/deletion-protection by default + decommission + docs, tag v1.8.0)

Requirement Phase Status
REQ-76 28 complete (v1.8.0)
REQ-77 28 complete (v1.8.0)
REQ-78 29 complete (v1.8.0)
REQ-79 29 complete (v1.8.0)
REQ-80 30 complete (v1.8.0)
REQ-81 30 complete (v1.8.0)
REQ-82 30 complete (v1.8.0)
REQ-83 31 complete (v1.8.0)
REQ-84 31 complete (v1.8.0)
REQ-85 31 complete (v1.8.0)
REQ-86 32 complete (v1.8.0)
REQ-87 32 complete (v1.8.0)
REQ-88 33 complete (v1.8.0)
REQ-89 33 complete (v1.8.0)
REQ-90 33 complete (v1.8.0)
REQ-91 33 complete (v1.8.0)
REQ-92 34 complete (v1.8.0)
REQ-93 34 complete (v1.8.0)
REQ-94 34 complete (v1.8.0)
REQ-95 35 complete (v1.8.0)
REQ-96 35 complete (v1.8.0)
REQ-97 36 complete (v1.8.0)
REQ-98 36 complete (v1.8.0)
REQ-99 36 complete (v1.8.0)

v1.9 (complete — design doc refresh + contract interpolation + per-env CI jobs + stub implementation + P1-1 remediation, tag v1.9.0)

Requirement Phase Status
REQ-100 39 complete (v1.9.0)
REQ-101 39 complete (v1.9.0)
REQ-102 39 complete (v1.9.0)
REQ-103 40 complete (v1.9.0)
REQ-104 40 complete (v1.9.0)
REQ-105 41 complete (v1.9.0)
REQ-106 41 complete (v1.9.0)
REQ-107 42 complete (v1.9.0)
REQ-108 42 complete (v1.9.0)
REQ-109 42 complete (v1.9.0)
REQ-110 42 complete (v1.9.0)
REQ-111 42 complete (v1.9.0)

v1.10 (active — pipeline regression fix + capability re-verification + verified-reality rewrite, tag v1.10.0)

Requirement Phase Status
REQ-112 52 complete (v1.9.9)
REQ-113 53 complete (v1.9.10)
REQ-114 54 complete (v1.9.11)
REQ-115 55 complete (v1.9.12)

v1.11 (active — RESTART: stateless adapter + pipeline-driven module lifecycle testing, tag v1.11.0)

The v1.11 milestone closes G-005 (CAP-017..022 deploy-unverified) and G-008 (no cost docs) via a corrected architecture. The first v1.11 attempt is abandoned (branches phase/56-iam-re-bootstrap + phase/57-live-deploy-microservice); the restart branches off v1.10.2.

Category: Stateless Adapter

  • REQ-123 — The terraform adapter (adapters/terraform/adapter.py) is rewritten from a 918-line monolith (3 constant tables TYPE_MAP/INPUT_MAP/OUTPUT_MAP + 39 type-specific branches) to a ~80-line stateless assembler. Each L1 module ships a real terraform/ module dir owning its resource shape, nested blocks, and defaults. The adapter reads the registry and emits module "x" { source = ... } blocks. No type-specific logic in the adapter. (Phase P56a)

Category: Per-Module Terraform

  • REQ-124 — All 12 L1 modules have a terraform/ subdir (versions.tf/variables.tf/locals.tf/main.tf/outputs.tf) with defaults centralized in locals.tf (heavy interpolation of vars against sensible defaults). interface.json stays engine-agnostic. The registry has a terraform_dir field per entry. (Phase P56b)

Category: Shell Lifecycle Modes

  • REQ-125scripts/run_platform.sh gains --apply and --destroy modes; the shell owns all terraform lifecycle. Python never runs terraform. scripts/verify_deploy_microservice.py is deleted. (Phase P57)

Category: Single Platform VPC + Deterministic State

  • REQ-126terraform/platform/main.tf owns ONE VPC; the microservice composition references it via data source (no inline VPC). State keys are deterministic and env-aware (spike/{id}/{env}/terraform.tfstate), stable across apply/modify/destroy. (Phase P58)

Category: L1 Lifecycle Pipeline

  • REQ-127 — 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. The "test" = the pipeline cell going green. (Phases P59P60)

Category: L2 Lifecycle Pipeline

  • REQ-128 — The lifecycle pipeline extends to L2 modules (static-assets, microservice). L2 = composition only (no L2 terraform files); the composition is deterministic (same contract → same stack → same state key). (Phases P61P62)

Category: Operating Model + G-005/G-008 Closure

  • REQ-116 — CAP-017..022 marked Verified in CAPABILITY_INVENTORY + PROJECT + decks with "Verified live-aws via lifecycle pipeline; torn down to zero-cost" note. (Phase P65)
  • REQ-118 — Both leadership decks rewritten to reflect verified-then-torn-down status; no stale "deploy-unverified" claims. (Phase P65)
  • REQ-119.ciagent/COST.md documents the v1.0→v1.10 AWS spend window (Cost Explorer query). (Phase P63)
  • REQ-120.ciagent/PRE_MORTEM.md documents the v1.10 decay root cause + forward pre-mortem. (Phase P64)
  • REQ-121 — CAP-017..022 added to the regression registry (evidence = lifecycle pipeline green). (Phase P63)
  • REQ-122 — All deployed stacks torn down via --decommission (D-070 two-step, CR CHG0680001); zero live ACDL resources remain. (Phase P64)

v1.11 Traceability

Requirement Phase Status
REQ-123 P56a complete
REQ-124 P56b complete
REQ-125 P57 complete
REQ-126 P58 complete
REQ-127 P59, P60 complete
REQ-128 P61, P62 complete
REQ-116 P65 complete
REQ-118 P65 complete
REQ-119 P63 complete
REQ-120 P64 complete
REQ-121 P63 complete
REQ-122 P64 complete

Out of Scope (v1.11)

  • OIDC act_runner adoption (pending go-gitea/gitea#36988).
  • Per-phase regression (G-007: milestone-level regression gate is correct).
  • Audit ledger build-out (D-083).
  • Operator-supplied evidence.
  • Pilot onboarding (G-001).
  • Boto3 post-deploy verification probes (CAP-017..022 live-verify via boto3) — deferred to a future QA milestone. The lifecycle pipeline apply→destroy IS the verification for v1.11.