90 offline tests covering adapter, confidence_signal, checkov_adapter, outbox_writer, and pipeline integration. Identical CI/CD workflows for Gitea Actions (dev) and GitHub Actions (production). New --check-only mode for run_platform.sh (offline, no AWS). ---ci--- project: acdl phase: 18 milestone: v1.3 status: verify ---/ci---
19 KiB
ACDL — Roadmap
Overview
- v1.0 (demo): complete — tag
v1.1.0, 2026-07-21. All 5 phases shipped + audited PASS. - v1.1 (complete): architecture finalization + v1 spike. 5 phases (06–10). Tag
v1.2.0, 2026-07-21. All 5 phases shipped + verified; review READY TO SHIP (0 P0); audit CLEAN. Gitea release id 202. - v1.2 (complete): platform hardening + first real consumer deployment. 6 phases (11–16). Tag
v1.3.0, 2026-07-21. All 6 phases shipped + verified; review READY TO SHIP (1 P0 operator action, 1 P1 deferred); audit CLEAN. - v1.3 (active): module documentation + thin-composition removal. The L2 composition layer is removed; module READMEs are built out.
- v1.0 demo URL: https://git.cloudinit.dev/continuous-intelligence/acdl-evidence/raw/branch/main/index.html
v1.0 (Prior — the demo, complete)
Five-phase breakdown that took ACDL from empty repo to a reproducible 4-act
executive demo. Milestone v1.0-initial covered the full demo build. Each
phase produced a runnable increment and ended with a phase-completion commit
- tag. All phases complete; demo archived to
demo/in v1.1 Phase 06.
Phases
Phase 01 — repo-scaffolding
- Description: Create the three repos under
continuous-intelligence(acdl-contracts,acdl-evidence;acdlalready exists), seed directory layouts, configure Pages onacdl-evidence, add environment protection forqaandprodonacdl-contracts. - Status: complete (v1.0.1)
- Depends on: —
- Requirements: REQ-01, REQ-09, REQ-10
- Success Criteria:
acdl-contractsandacdl-evidenceexist and are pushable.acdl-evidencePages returns 200 with placeholderindex.html.qaandprodenvironments exist onacdl-contracts.
Phase 02 — l1-modules
- Description: Create all 8 L1 module folders under
acdl/modules/l1/, each withmanifest.yaml(declared inputs) andmock_apply.sh(uniform echo + 1s sleep + exit 0). - Status: complete (v1.0.2)
- Depends on: [1]
- Requirements: REQ-02, REQ-03
- Success Criteria:
- All 8 L1s present;
mock_apply.shruns and exits 0 for each. manifest.yamlvalidates against the L1 schema.
- All 8 L1s present;
Phase 03 — l2-modules-and-core-scripts
- Description: Create the 4 L2 compositions under
acdl/modules/l2/referencing L1s, plus the 5 core scripts inacdl/scripts/(mock_executor.sh,policy_checker.py,confidence_signal.py,evidence_writer.py,l3b_agent_stub.py). - Status: complete (v1.0.3)
- Depends on: [2]
- Requirements: REQ-04, REQ-05, REQ-06, REQ-07
- Success Criteria:
mock_executor.shapplies each L1 in an L2 and writesstate.json.policy_checker.pyfails onpublic-ingress: truewithPOLICY_VIOLATION:PUBLIC_INGRESS.confidence_signal.pyreturns 0.90 (pass) / 0.40 (fail).evidence_writer.pyappends an event with a valid hash chain.l3b_agent_stub.pymaps the Act 3 example issue tol2-commodity-price-feed.
Phase 04 — pipeline-and-approval-gates
- Description: Build the reusable pipeline workflow in
acdl/.gitea/workflows/(Dev → QA → Prod → Finalize) plus the issue-triggered L3B workflow inacdl-contracts/.gitea/workflows/. Wire environment protection for QA and Prod. - Status: complete (v1.0.4)
- Depends on: [3]
- Requirements: REQ-08, REQ-09, REQ-10, REQ-12
- Success Criteria:
- Pushing a valid
contract.yamlruns Dev automatically and pauses at QA. - Approving QA moves to Prod; approving Prod finalizes.
- Opening an Issue with the Act 3 text generates a
contract.yamlcommit and triggers the pipeline.
- Pushing a valid
Phase 05 — evidence-ui-and-demo-dry-run
- Description: Build
index.html(vanilla JS, fetchesaudit.json, renders timeline) and run all four acts end-to-end as a dry run. - Status: complete (v1.0.5)
- Depends on: [4]
- Requirements: REQ-11, REQ-13, REQ-14, REQ-15
- Success Criteria:
- Pages timeline renders events from
audit.json. - Act 2: valid contract passes through all gates; timeline shows the full flow.
- Act 3: Issue text produces the expected
l2-commodity-price-feedcontract and triggers the pipeline. - Act 4: malicious
public-ingress: truecontract halts in Dev with confidence < 0.50 and a visible rejection reason on the timeline.
- Pages timeline renders events from
v1.1 (Complete — architecture finalization + v1 spike, 2026-07-21, tag v1.2.0)
Five-phase breakdown to finalize the architecture to v1.0 and prove the
locked commitments with one end-to-end implementation spike. Milestone
v1.1-spike covered the real platform's first materialization. Ship tag
at milestone COMPLETE: v1.2.0 (feature milestone, next minor per
ship.md). Status: COMPLETE — all 5 phases shipped (v1.1.1..v1.1.5) +
verified; review READY TO SHIP (0 P0); audit CLEAN; Gitea release id 202.
D-034 closed (root key deactivated by user).
Phase 06 — archive-demo-and-reorient
- Description: Move the v1.0 demo (
modules/,scripts/,evidence-ui/,contracts/, demo.gitea/workflows/) todemo/. Establish the new repo layout (platform/,schemas/,adapters/,terraform/,modules-ir/). Rewrite README to reflect the real platform. Verify the demo still runs fromdemo/(regression check). - Status: complete (v1.1.1)
- Depends on: —
- Requirements: (no new REQ; repo hygiene)
- Success Criteria:
demo/contains the full v1.0 demo;demo/scripts/run_demo.sh --no-uploadstill exits 0.- New top-level dirs exist and are empty-but-scaffolded:
platform/,schemas/,adapters/,terraform/,modules-ir/. - README reflects the real platform (vision + architecture links, new layout).
Phase 07 — architecture-v1-finalization
- Description: Resolve the 11 open decisions in
docs/architecture.md§13 (already recorded inPROJECT.md). Author the locked schemas + designs:schemas/ir.schema.json(REQ-17),schemas/policy_check_result.schema.json(REQ-18),schemas/contract.schema.json(REQ-22),platform/confidence_signal.pyspec (REQ-19),platform/audit_ledger_design.md(REQ-20),platform/hitl_matrix_design.md(REQ-21). Mark architecture v1.0. - Status: complete (v1.1.2)
- Depends on: [06]
- Requirements: REQ-16, REQ-17, REQ-18, REQ-19, REQ-20, REQ-21, REQ-22
- Success Criteria:
- All 11 open decisions resolved and recorded in
PROJECT.md. - All 6 schema/design files exist and validate (
ajv/python -m jsonschema). docs/architecture.mdstatus note updated to v1.0 (or adocs/architecture-v1.0.mdsnapshot).
- All 11 open decisions resolved and recorded in
Phase 08 — aws-oidc-bootstrap
- Description: Re-scoped per RESEARCH TARGET 1 + D-039. Gitea Actions does not support
id-token: write(conf 0.95), so real OIDC is deferred to v1.2. This phase instead: uses the temporary long-lived key (waiver D-034) once to create an S3 state bucket, a DynamoDB lock/outbox table, and an IAM user with a minimal scoped policy (S3 + DynamoDB + plan-only); stores the key as a Gitea Actions secret; implementsscripts/rotate_spike_key.shto rotate the key after each spike run. Real OIDC federation is tracked via go-gitea/gitea#36988 for v1.2. - Status: complete (v1.1.3)
- Depends on: [07]
- Requirements: REQ-23 (re-interpreted: AWS auth bootstrap + state backend; OIDC deferred to v1.2 per D-039)
- Success Criteria:
- S3 state bucket + DynamoDB lock/outbox table exist.
- An IAM user with a minimal scoped policy exists; its access key is stored as a Gitea Actions secret.
scripts/rotate_spike_key.shrotates the key (deactivates old, creates new, updates the secret) and is idempotent.- A workflow step authenticates to AWS with the rotated secret and runs
aws sts get-caller-identitysuccessfully. - D-034 is closed: the bootstrap long-lived key is rotated/deactivated (logged in
PROJECT.md).
Phase 09 — v1-spike-ir-and-l1-and-adapter
- Description: Implement the Target Stack IR, one real L1
l1-s3(IR-typed interface, registered), and the Terraform adapter that compiles the IR → Terraformvariable/output+ root module and emits a realterraform planagainst AWS (via the rotated-key secret per D-039; OIDC is v1.2). State in S3 + DynamoDB. - Status: complete (v1.1.4)
- Depends on: [08]
- Requirements: REQ-24, REQ-26
- Success Criteria:
schemas/ir.schema.jsonis satisfied bymodules-ir/l1/l1-s3/interface.- The Terraform adapter translates
l1-s3to a validterraform plan(real AWS). terraform validate+terraform plansucceed; no long-lived credential in the workflow.
Phase 10 — v1-spike-l2-and-contract-e2e
- Description: Implement
l2-static-asset(thin-composition referencingl1-s3), the contract schema + contract→IR resolution, and one end-to-end contract submission (contracts/spike.yamlforl2-static-asset) flowing through schema validation → IR resolution →terraform plan→ CheckovPolicyCheckResult→ confidence signal → evidence event to the DynamoDB outbox. Verify the IR commitments hold (no polyglot mess). - Status: complete (v1.1.5)
- Depends on: [09]
- Requirements: REQ-25, REQ-27, REQ-28
- Success Criteria:
l2-static-assetreferencesl1-s3only (depth 1).- One contract submission completes the full pipeline end-to-end.
scripts/verify_phase10.shproves the adapter is the only substrate-specific code.- Evidence event is written to the DynamoDB outbox.
After Phase 10: COMPLETE gate — review → ship v1.2.0 → audit. DONE.
v1.2 (Complete — platform hardening + first real consumer deployment, 2026-07-21, tag v1.3.0)
Six-phase breakdown to harden the v1.1 spike, simplify the setup, update
the docs, and prove the platform delivers real value by deploying a basic
microservice to AWS ECS Fargate end-to-end. Ship tag at milestone COMPLETE:
v1.3.0 (feature milestone, next minor per ship.md — v1.1 shipped
v1.2.0). Phase patches v1.2.1..v1.2.6. Status: COMPLETE — all 6
phases shipped (v1.2.1..v1.2.6) + verified; review READY TO SHIP (1 P0
operator action, 1 P1 deferred to v1.3); audit CLEAN. The terraform apply
is blocked by the live IAM policy (P0-IAM, operator action); the platform
flow is verified end-to-end up to terraform plan (13 to add).
Phase 11 — v1.2-research-and-readme
- Description: Re-evaluate go-gitea/gitea#36988 (OIDC for Gitea Actions) — confirm still open (re-checked 2026-07-21: open, last updated 2026-05-27, not merged) and record the decision to extend D-039 as D-047. Audit the v1.1 spike for NFR gaps (least-privilege IAM, idempotency, error handling, rotation hygiene) and simplification opportunities (script consolidation, dead code, stale paths). Rewrite
README.mdto reflect v1.1 complete + the actual spike flow + how to run + the real repo layout + the v1.2 objective. - Status: complete (v1.2.1)
- Depends on: —
- Requirements: REQ-29
- Success Criteria:
RESEARCH.mdhas a v1.2 addendum with the #36988 re-check + NFR audit + simplification findings.README.mdreflects v1.1 complete; documents the spike flow,scripts/run_platform.sh, the repo layout, and the v1.2 objective; no stale "v1.1 (active)" framing.- D-047 is recorded in
PROJECT.md.
Phase 12 — nfr-harden-and-simplify
- Description: Apply Phase 11's findings. Tighten
terraform/bootstrap/spike_runner_policy.jsonto least-privilege (add ECS + ECR + ELB + IAM plan-only permissions for v1.2; audit for wildcards). Makecreate_state_backend.pyandcreate_iam_user.pyidempotent. Consolidaterun_spike_plan.sh+run_spike_e2e.shinto a singlescripts/run_platform.shwith proper exit codes and error handling. Redact P1-1 (the two AWS access key IDs in.ciagent/VERIFY.mdPhase 09 narrative). Fix any remaining staleplatform/paths in.ciagent/. The v1.1 spike still runs e2e after the refactor. - Status: complete (v1.2.2)
- Depends on: [11]
- Requirements: REQ-30
- Success Criteria:
scripts/run_platform.shruns the full v1.1 spike e2e and exits 0.create_state_backend.py/create_iam_user.pyre-runs are idempotent (no duplicate resources; exit 0).spike_runner_policy.jsonpasses a least-privilege audit (no*actions beyond documented exceptions)..ciagent/VERIFY.mdPhase 09 narrative has no live AWS access key IDs.- No stale
platform/paths remain in.ciagent/.
Phase 13 — l1-catalog-for-ecs
- Description: Author six IR-typed L1 modules for an ECS Fargate microservice:
l1-vpc(VPC + subnets + route tables),l1-ecs-cluster(ECS Fargate cluster),l1-ecs-service(ECS service + task definition),l1-iam-role(task execution + task role),l1-alb(ALB + listener + target group),l1-ecr(ECR repository). Each has aninterface.jsonvalid againstschemas/ir.schema.json. Register all six inmodules-ir/registry.json. Expand the Terraform adapterTYPE_MAPto cover the new IR resource types. Each L1 produces a validterraform planfragment. - Status: complete (v1.2.3)
- Depends on: [12]
- Requirements: REQ-31
- Success Criteria:
- All six L1s exist under
modules-ir/l1/withinterface.jsonvalid againstschemas/ir.schema.json. modules-ir/registry.jsonlists all six.- The adapter
TYPE_MAPcovers all six IR resource types. - Each L1 produces a valid
terraform planfragment.
- All six L1s exist under
Phase 14 — l2-microservice-and-contract-schema
- Description: Author
l2-microservicethin-composition undermodules-ir/l2/l2-microservice/referencing the six ECS L1s (depth ≤ 5). Extendschemas/contract.schema.jsonwith microservice inputs (image: string,port: integer,env: map,healthcheck: object). Verify contract→IR resolution yields a complete target stack. - Status: complete (v1.2.4)
- Depends on: [13]
- Requirements: REQ-32
- Success Criteria:
l2-microservicereferences the six ECS L1s only (depth ≤ 5).schemas/contract.schema.jsonvalidates acontracts/microservice.yamlwith the new inputs.- Contract→IR resolution yields a complete target stack (all six L1 instances + relationships).
Phase 15 — consumer-repo-and-terraform-apply
- Description: Create a new Gitea repo
acdl-consumer-microserviceunder thecontinuous-intelligenceorg containing a basic HTTP microservice (tiny Python/Go server returning 200), aDockerfile, an ECR push step, and acontracts/microservice.yamlsubmission forl2-microservice(dev environment). Lift the platform fromplantoapplyfor thedevenvironment (autonomous per §10, confidence ≥ 0.50, no HITL). Submit the contract → pipeline → IR → plan → apply → a real ECS Fargate service running. - Status: complete (v1.2.5, PARTIAL — terraform apply blocked by IAM P0)
- Depends on: [14]
- Requirements: REQ-33 (partial), REQ-34
- Success Criteria:
acdl-consumer-microservicerepo exists undercontinuous-intelligence.- The microservice builds into a Docker image and is pushed to ECR.
terraform apply(dev) creates real AWS resources (VPC, ECS cluster, ECR repo, ALB, ECS service).- The apply result is captured in the evidence stream.
Phase 16 — v1.2-capstone-e2e
- Description: End-to-end verification: consumer commit to
acdl-consumer-microservicetriggers the pipeline → contract→IR resolution →terraform plan→terraform apply(dev) → a live ECS Fargate service serving HTTP 200 on its ALB → evidence event written to the DynamoDB outbox → the event renders on theacdl-evidencetimeline. Verify the NFR improvements from Phase 12 hold, the setup is simpler (onescripts/run_platform.sh), and the README is accurate.scripts/verify_phase16.shproves the full flow green. - Status: complete (v1.2.6, capstone — terraform apply blocked by IAM P0, verified up to plan)
- Depends on: [15]
- Requirements: REQ-35 (partial — IAM-blocked)
- Success Criteria:
- One consumer commit produces a live ECS service serving HTTP 200.
- An evidence event for the apply is in the DynamoDB outbox and renders on the timeline.
scripts/verify_phase16.shexits 0.- README accurately documents the v1.2 platform flow.
After Phase 16: COMPLETE gate — review → ship v1.3.0 → audit.
v1.3 (Active — module documentation + thin-composition removal)
The v1.3 milestone starts with simplification: removing the unsatisfactory thin-composition layer and building out proper module documentation. The L2 composition mechanism will be redesigned in a later phase.
Phase 17 — remove-thin-composition-and-module-readmes
- Description: Remove the L2 thin-composition layer completely (composition.json files, contract_resolver.py, contract schema, sample contracts) and build out proper module READMEs. Create a README template for both L1 and L2 modules, rewrite all 7 L1 module READMEs in plain language (no jargon, with Resources/Inputs/Outputs/Usage/Compliance-extension-points/Versioning sections), write 2 L2 placeholder READMEs noting the composition is under redesign, create a catalog index, and patch run_platform.sh to load a pre-existing IR instance instead of resolving a contract. Prune L2 entries from the registry.
- Status: complete (v1.3.1)
- Depends on: —
- Requirements: REQ-36, REQ-37, REQ-38
- Success Criteria:
- The thin-composition layer is fully removed (composition.json, contract_resolver.py, contract schema, contracts/).
- run_platform.sh loads a pre-existing IR instance; the downstream adapter/checkov/confidence/outbox pipeline still works.
- A README-TEMPLATE.md exists for both L1 and L2 modules.
- Every L1 module has a README.md with Resources/Inputs/Outputs/Usage/Compliance-extension-points/Versioning.
- Every L2 module has a placeholder README.md noting the composition is under redesign.
- A modules-ir/README.md catalog index exists.
Phase 18 — testing-and-cicd-pipelines
- Description: Create a pytest test suite that reproduces the platform pipeline offline (adapter, confidence_signal, checkov_adapter, outbox_writer). Add an offline
--check-onlymode torun_platform.shthat runs the pipeline up to adapter emission without AWS/Checkov/outbox. Create identical CI/CD pipelines for both Gitea Actions (.gitea/workflows/ci.yml, dev environment) and GitHub Actions (.github/workflows/ci.yml, production) that run: lint, pytest,run_platform.sh --check-only. Addpyproject.toml+requirements-test.txtfor dependency pinning. - Status: complete (v1.3.2)
- Depends on: [17]
- Requirements: REQ-39, REQ-40, REQ-41, REQ-42
- Success Criteria:
pytestruns and passes offline (no AWS, no Checkov, no DynamoDB).run_platform.sh --check-onlyruns offline and exits 0..gitea/workflows/ci.ymland.github/workflows/ci.ymlexist with identical job stages (lint, test, check-only).pyproject.toml+requirements-test.txtpin test dependencies.