---ci--- project: acdl phase: 18 milestone: v1.3 status: complete requirements: covered: [REQ-39, REQ-40, REQ-41, REQ-42] partial: [] ---/ci---
ACDL — Agentic Cloud Delivery Platform
Consumers declare intent; the platform delivers safe production deployment through an agentic stack — automatically, safely, and with a complete audit trail. A merged change progresses through lower environments end-to-end without a platform engineer joining a thread; a non-technical consumer ships a production deployment by declaring intent, without authoring a workflow, a configuration file, or a Terraform module.
- Vision (the why):
docs/vision.md - Architecture (the how):
docs/architecture.md+.ciagent/ARCHITECTURE.md - Decisions:
.ciagent/PROJECT.md - Phase plan:
.ciagent/ROADMAP.md
Status
- v1.2 (active): platform hardening + first real consumer deployment.
Harden the v1.1 spike's NFRs, simplify the setup, rewrite the docs, and
prove the platform delivers real value by deploying a basic microservice
to AWS ECS Fargate end-to-end (
terraform apply, dev autonomous). Ship tagv1.3.0. - v1.1 (complete, tag
v1.2.0): architecture finalization + v1 spike. Finalized the architecture to v1.0 (resolved all 11 open design decisions) and proved the IR commitments hold with one end-to-end spike (l1-s3+l2-static-asset+ Terraform adapter → realterraform planagainst AWS). Gitea release id 202. - v1.0 demo (complete, archived under
demo/, tagv1.1.0): the 30-minute stub-driven executive demo. Preserved as the intent reference; it is not the platform.
How the platform works
The platform is four layers + six cross-cutting concerns, bound by the vision's "Two Consumer Surfaces, One Platform" tenet: technical developers (L3A) and non-technical consumers (L3B) converge on the same contract schema, the same policy envelope, and the same evidence stream.
The v1.1 spike flow (end-to-end)
contracts/spike.yaml
│ (contract schema validation)
▼
acdl_platform/contract_resolver.py ──▶ Target Stack IR (JSON)
│ (IR schema validation)
▼
adapters/terraform/adapter.py ──▶ terraform/spike/{main,terraform,providers}.tf
│ (the only substrate-specific code)
▼
terraform plan (real AWS, via the rotated spike key — D-039/D-047)
│
▼
adapters/terraform/policy/checkov_adapter.py ──▶ PolicyCheckResult (JSON list)
│ (normalized, engine-agnostic)
▼
acdl_platform/confidence_signal.py ──▶ { score, band, perInput, reasonCodes }
│ (6 inputs: policy, validation, freshness, source, history, nfrs)
▼
acdl_platform/outbox_writer.py ──▶ DynamoDB outbox (acdl-outbox)
│ (hash-chained evidence event)
▼
acdl-evidence timeline (acdl-evidence repo, raw-file served)
The spike validates the architecture's claim that the IR-shaped
commitments do not require a polyglot mess: the adapter is the only
substrate-specific code. modules-ir/, schemas/, contracts/,
acdl_platform/confidence_signal.py, acdl_platform/contract_resolver.py,
and acdl_platform/outbox_writer.py are all substrate-agnostic (no
aws_s3_bucket / aws_ Terraform terms).
What's different in v1.2
v1.2 extends the spike to a real, simpler, better-documented platform that deploys a microservice to ECS Fargate:
- Six new IR-typed L1s:
l1-vpc,l1-ecs-cluster,l1-ecs-service,l1-iam-role,l1-alb,l1-ecr. - One new L2 thin-composition:
l2-microservice(references the six L1s). terraform apply(dev, autonomous per §10, confidence ≥ 0.50) — real provisioning, not justplan.- A new consumer repo
acdl-consumer-microservicewith a basic HTTP container + Dockerfile + ECR push + contract submission. - One
scripts/run_platform.sh(consolidated from the v1.1 spike scripts). - NFR hardening: least-privilege IAM (expanded for ECS), idempotent bootstrap, proper error handling, P1-1 redaction.
How to run
Prerequisites
- AWS account + the rotated spike key in
.env.secrets(seescripts/rotate_spike_key.sh; the bootstrap root key was deactivated per D-034 closure). terraform(pin1.9.*),checkov(pin>=3.2,<4),python3+boto3jsonschema.
Run the platform pipeline end-to-end
# 1. Bootstrap the AWS state backend + spike IAM user (one-time, idempotent)
# (requires the bootstrap root key in env — now deactivated; skip if
# the state bucket + acdl-spike-runner already exist)
ACDL_BOOTSTRAP_AWS_ACCESS_KEY_ID=... ACDL_BOOTSTRAP_AWS_SECRET_ACCESS_KEY=... \
python3 terraform/bootstrap/create_state_backend.py
ACDL_BOOTSTRAP_AWS_ACCESS_KEY_ID=... ACDL_BOOTSTRAP_AWS_SECRET_ACCESS_KEY=... \
python3 terraform/bootstrap/create_iam_user.py # prints the initial key
# 2. Rotate the spike key (writes .env.secrets, gitignored)
ACDL_BOOTSTRAP_AWS_ACCESS_KEY_ID=... ACDL_BOOTSTRAP_AWS_SECRET_ACCESS_KEY=... \
bash scripts/rotate_spike_key.sh
# 3. Run the full platform pipeline (IR -> adapter -> plan -> Checkov ->
# confidence -> outbox)
bash scripts/run_platform.sh
# Expected: "=== PLATFORM E2E OK ==="
# Or plan-only (IR -> adapter -> terraform plan; no Checkov/outbox):
bash scripts/run_platform.sh --plan-only
Test the platform (offline, no AWS required)
# Install test dependencies
pip install -r requirements-test.txt
# Run the test suite (90 tests, all offline — uses moto for DynamoDB mocking)
python3 -m pytest tests/ -v
# Run the platform in check-only mode (offline — no AWS, no Checkov, no outbox)
bash scripts/run_platform.sh --check-only
# Expected: "=== PLATFORM CHECK OK ==="
CI/CD pipelines
Identical pipelines run on both Gitea Actions (dev) and GitHub Actions (production):
.gitea/workflows/ci.yml— Gitea Actions (dev environment).github/workflows/ci.yml— GitHub Actions (production)
Both run three stages: lint (py_compile), test (pytest), and
check-only (run_platform.sh --check-only). Both trigger on push to
main and on pull requests.
Re-run the archived v1.0 demo (stubs only, no AWS)
bash demo/scripts/run_demo.sh --no-upload
The demo deck is at demo/ACDL_DEMO.md. It runs
entirely on local stubs — no AWS, no AI — and shows intent and safety
behavior rather than provisioning real cloud resources.
Repository layout
| Path | Purpose | Status |
|---|---|---|
acdl_platform/ |
Platform code: confidence signal, contract resolver, outbox writer, HITL/ledger/SoD designs (renamed from platform/ in Phase 08 to avoid shadowing the stdlib platform module) |
v1.1 complete; v1.2 extends |
schemas/ |
JSON Schemas: IR, PolicyCheckResult, contract (draft 2020-12) | v1.1 complete; v1.2 extends contract schema |
adapters/ |
Substrate adapters — Terraform adapter (the only substrate-specific code per §12) + Checkov policy adapter | v1.1 complete; v1.2 expands TYPE_MAP |
terraform/ |
State backend (S3 + DynamoDB) + spike TF (terraform/spike/) + bootstrap scripts (terraform/bootstrap/) |
v1.1 complete; v1.2 adds ECS apply |
modules-ir/ |
IR-typed L1/L2 modules + registry.json. v1.1: l1-s3, l2-static-asset. v1.2: + 6 ECS L1s, l2-microservice |
v1.1 complete; v1.2 expands |
contracts/ |
Sample contracts (spike.yaml for l2-static-asset) |
v1.1 complete; v1.2 adds microservice.yaml |
scripts/ |
Verify scripts (verify_phaseNN.sh), platform run script (run_platform.sh; --plan-only for plan subset), key rotation |
v1.1 complete; v1.2 consolidates |
demo/ |
Archived v1.0 executive demo (tag v1.1.0); runs locally via demo/scripts/run_demo.sh --no-upload |
complete (archived) |
.ciagent/ |
CIAgent metadata (config, project, architecture, requirements, roadmap, personas, plans, research, verify, review, audit) | active |
docs/ |
Upstream vision + architecture sources (vision.md, architecture.md) |
active |
Environments
| Environment | Autonomy | Gate | Status |
|---|---|---|---|
| dev | Full autonomy (no HITL) | Confidence ≥ 0.50 | v1.1 spike (plan); v1.2 (apply) |
| qa | Held for attestation | QA HITL + confidence ≥ 0.75 | v1.3+ |
| prod | Held for attestation | SRE HITL + confidence ≥ 0.90 | v1.3+ |
| dr | Held for attestation | SRE HITL + confidence ≥ 0.95 + dr-drill | v1.3+ |
Staging does not exist (Path A locked).
Credentials
Long-lived AWS credentials are forbidden (§12.5). The v1.1 spike uses a
temporary long-lived key once to bootstrap (waiver D-034, now closed —
the root key was deactivated by the user), then rotates the spike key
per-run via scripts/rotate_spike_key.sh (waiver D-039, extended for v1.2
as D-047). Real OIDC federation is deferred to v1.3+, blocked on
go-gitea/gitea#36988 (still
open as of 2026-07-21).