Files
acdl/.ciagent/PROJECT.md
T
Jon Chery e050e65158
acdl-ci / Lint (push) Successful in 8s
acdl-ci / Test (push) Successful in 14s
acdl-ci / Platform check-only (offline) (push) Successful in 9s
feat(P19): central pipeline contract + shell reproducibility + output streaming (v1.4.1)
---ci---
project: acdl
phase: 19
milestone: v1.4
status: execute
---

Add declarative pipeline contract (schemas/pipeline.schema.json +
pipelines/ci.yaml) as single source of truth for both Gitea Actions (dev)
and GitHub Actions (production) workflows. Both workflow files are
byte-identical and validated against the contract by 32 new tests.

Add scripts/run_ci.sh for shell reproducibility — mirrors the CI pipeline
locally (lint → test → check-only), exits 0 with 'CI PIPELINE OK'.

Update scripts/run_platform.sh to stream output by default: terraform
init/validate/plan via tee, Checkov compliance results with per-record
severity/rule/pass-fail, and emitted Terraform in --check-only. New
--quiet flag for log-only mode.

Requirements: REQ-43 (central pipeline contract), REQ-44 (shell
reproducibility), REQ-45 (output streaming). 122 tests pass (90 + 32).
2026-07-22 15:10:54 +00:00

349 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ACDL — Agentic Cloud Delivery Platform
## Vision / Core Value
Consumers declare intent; the platform delivers safe production
deployment through an agentic stack. The platform absorbs two frictions:
the cognitive load of getting the infrastructure right, and the
operational work of getting the change to production safely.
Source of truth for **why**: `docs/vision.md`.
Source of truth for **how**: `docs/architecture.md` + `.ciagent/ARCHITECTURE.md`.
Where the two conflict, the vision wins.
## North Star
A merged change progresses through lower environments end-to-end without a
platform engineer joining a thread, approving a ticket, or manually
triggering a stage gate. A non-technical consumer ships a production
deployment by declaring intent — without authoring a workflow, a
configuration file, or a Terraform module. Every production change is
traceable to a human attestation and an immutable evidence stream.
## Core Tenets (from `docs/vision.md`)
1. **Operations are Declared, Not Executed.** Consumers define what they
need; the platform reconciles, provisions, and progresses.
2. **The Delivery Lifecycle is a Sovereign Boundary.** The platform
governs infra and delivery; it does not penetrate upstream product/SDLC.
Integration is only through validated, published contracts.
3. **Lower Environments are Autonomous; Higher Environments are Attested.**
Dev = zero-touch agentic. QA/prod/dr = deliberate human attestation, not
rubber stamps.
4. **Safety is Computed, Not Assumed.** Every action produces a measurable,
explainable confidence signal. The signal is the platform's certified
answer to "is this safe to proceed?"
5. **Infrastructure is Consumed, Not Maintained.** Compute is abstract,
containerized, or serverless. No node/OS/bare-metal lifecycle.
6. **Two Consumer Surfaces, One Platform.** Technical developers (L3A) and
non-technical consumers (L3B) converge on the same contract schema, the
same policy envelope, and the same evidence stream.
## Domain Boundaries
- **In scope:** environment progression; cloud resource lifecycle; operational
security and observability NFRs; policy enforcement; immutable audit
lineage; confidence frameworks; two consumer surfaces (developer + agentic).
- **Out of scope:** application business logic; IDE workflows; product
backlog / sprint planning; compute requiring node-level or OS-level management.
- **Interface:** upstream systems integrate through a strict contract
boundary. The platform validates, enriches with operational standards,
and reconciles the target state.
## Objective for Milestone v1.1 (prior — complete, tag `v1.2.0`)
Finalize the architecture to v1.0 (resolve all 11 open design decisions in
`docs/architecture.md` §13) and prove the locked commitments with one
end-to-end v1 implementation spike:
- **One L1 module** (`l1-s3`) — substrate-agnostic, IR-typed interface.
- **One L2 thin-composition** (`l2-static-asset`) — references the L1.
- **Terraform adapter** — compiles the IR to a real `terraform plan`
against AWS via OIDC (no long-lived credentials, per §12.5).
- **One contract submission** → contract→IR resolution →
`terraform plan` → PolicyCheckResult (Checkov) → confidence signal →
evidence event to the DynamoDB outbox.
The spike validates the architecture's claim that the IR-shaped commitments
do not require a polyglot mess (`docs/architecture.md` §14, step 2).
**Status: COMPLETE — all 5 phases shipped (v1.1.1..v1.1.5) + verified; review
READY TO SHIP (0 P0); audit CLEAN; milestone tag `v1.2.0`; Gitea release
id 202 published. D-034 closed (root key deactivated by user).**
## Milestone v1.1 Phases (prior — complete)
| Phase | Name | Goal |
|-------|------|------|
| 06 | archive-demo-and-reorient | Move the v1.0 demo (`modules/`, `scripts/`, `evidence-ui/`, `contracts/`, demo workflows) to `demo/`; establish the new repo layout (`platform/`, `schemas/`, `adapters/`, `terraform/`, `modules-ir/`); rewrite README. |
| 07 | architecture-v1-finalization | Resolve the 11 open decisions → architecture v1.0. Author IR JSON Schema, PolicyCheckResult schema, contract schema, confidence-signal spec, HITL matrix, outbox/ledger design under `schemas/` + `platform/`. |
| 08 | aws-oidc-bootstrap | One-shot use of a temporary long-lived key (waiver D-034) to create an IAM role + OIDC trust policy for the act_runner, an S3 state bucket, and a DynamoDB lock table. Rotate the key. Verify the runner assumes the role via OIDC with no long-lived secret. |
| 09 | v1-spike-ir-and-l1-and-adapter | Target Stack IR; one real L1 (`l1-s3`) with IR-typed interface; L1 registry; Terraform adapter (IR → Terraform var/output + `terraform plan`) running against AWS via OIDC. |
| 10 | v1-spike-l2-and-contract-e2e | One L2 thin-composition (`l2-static-asset`) referencing `l1-s3`; contract schema + contract→IR resolution; one end-to-end contract submission → `terraform plan` → Checkov → confidence signal → evidence event to outbox. Verify the IR commitments hold. |
Milestone COMPLETE gate: review → ship `v1.2.0` (feature milestone, next
minor per ship.md) → audit. **DONE.**
## Objective for Milestone v1.2 (prior — complete)
Platform hardening + first real consumer deployment. The v1.1 spike proved
the IR commitments hold on a single dev-only `terraform plan` for one S3
bucket. v1.2 takes the spike to a real, simpler, better-documented platform
that actually delivers a microservice to AWS ECS Fargate end-to-end.
Five scope axes (user-directed, 2026-07-21):
1. **Re-evaluate the current state.** Confirm go-gitea/gitea#36988 (OIDC for
Gitea Actions) is still unmerged (re-checked 2026-07-21: **open**, last
updated 2026-05-27). Extend the D-039 per-run-rotated-key waiver for
v1.2; real OIDC is deferred to v1.3+ (D-047).
2. **NFR improvements on the existing spike.** Least-privilege IAM audit,
idempotent bootstrap, proper exit codes / error handling, rotation
hygiene, P1-1 / P1-B redaction carried forward from the v1.1 audit.
3. **Streamline / simplify the current setup.** Consolidate the
`run_spike_*.sh` scripts into one `scripts/run_platform.sh`; remove
dead code and stale paths; one command runs the whole pipeline.
4. **README.md fully up to date on how the platform works.** The current
README still says "v1.1 (active)" — it must reflect v1.1 complete, the
actual spike flow, how to run it, the real repo layout, and the v1.2
objective.
5. **Bootstrap a consumer repo with a basic microservice deployed to ECS
end-to-end.** New Gitea repo `acdl-consumer-microservice` (org
`continuous-intelligence`) holding a tiny HTTP container + Dockerfile;
new IR-typed L1s (`l1-vpc`, `l1-ecs-cluster`, `l1-ecs-service`,
`l1-iam-role`, `l1-alb`, `l1-ecr`); new `l2-microservice`
thin-composition; one contract submission → `terraform apply` (dev,
autonomous) → a live ECS Fargate service serving HTTP 200 → evidence
event to the DynamoDB outbox → acdl-evidence timeline.
The milestone proves the platform delivers real value (a running
microservice), not just a plan.
## Milestone v1.2 Phases
| Phase | Name | Goal |
|-------|------|------|
| 11 | v1.2-research-and-readme | Re-eval #36988 (confirm open → extend D-039 as D-047). Audit the v1.1 spike for NFR gaps (least-privilege, idempotency, error handling, rotation hygiene) + simplification opportunities. **Rewrite README.md** to reflect v1.1 complete + how the platform actually works (spike flow, how to run, repo layout, v1.2 objective). Output: RESEARCH.md v1.2 addendum; updated README. |
| 12 | nfr-harden-and-simplify | Apply Phase 11 findings: tighten `spike_runner_policy.json` (least-privilege audit); make `terraform/bootstrap/create_*.py` idempotent; consolidate `run_spike_*.sh` → one `scripts/run_platform.sh`; proper exit codes / error handling; redact P1-1 AWS key IDs in `VERIFY.md`; fix any remaining stale `platform/` paths. Spike still runs e2e after the refactor. |
| 13 | l1-catalog-for-ecs | Author IR-typed L1s for an ECS Fargate microservice: `l1-vpc`, `l1-ecs-cluster`, `l1-ecs-service`, `l1-iam-role` (task + exec role), `l1-alb`, `l1-ecr`. Register all in `modules-ir/registry.json`. Expand the Terraform adapter `TYPE_MAP`. Each L1 produces a valid `terraform plan` fragment. |
| 14 | l2-microservice-and-contract-schema | Author `l2-microservice` thin-composition (references the ECS L1s, depth ≤ 5). Extend `schemas/contract.schema.json` for microservice inputs (image, port, env, healthcheck). Verify contract→IR resolution yields a complete target stack. |
| 15 | consumer-repo-and-terraform-apply | Create consumer repo `acdl-consumer-microservice` (Gitea org) with a basic microservice (tiny HTTP container + Dockerfile + ECR push). Lift the platform from `plan`**`apply`** (dev, autonomous per §10). Submit `contracts/microservice.yaml` → pipeline → IR → plan → apply → a real ECS Fargate service running. |
| 16 | v1.2-capstone-e2e | End-to-end verification: consumer commit → pipeline → ECS service live serving HTTP 200 → evidence event to the DynamoDB outbox → acdl-evidence timeline renders it. Verify NFR improvements hold, the setup is simpler (one `run_platform.sh`), and the README is accurate. |
Milestone COMPLETE gate: review → ship `v1.3.0` (feature milestone, next
minor per ship.md — v1.1 shipped `v1.2.0`) → audit.
## Objective for Milestone v1.4 (active)
Central pipeline contract + shell reproducibility + output streaming. The
v1.3 milestone (Phases 1718) created identical CI/CD pipelines for Gitea
and GitHub but they were duplicated copies with no single source of truth.
v1.4 makes the pipeline a declarative contract, enables full shell
reproducibility, and streams terraform/checkov output so users can see
what the platform is doing.
Three scope axes:
1. **Central pipeline contract.** A JSON Schema
(`schemas/pipeline.schema.json`) + YAML instance (`pipelines/ci.yaml`)
declares the pipeline stages, commands, triggers, and runner. Both
`.gitea/workflows/ci.yml` (Gitea Actions, dev) and
`.github/workflows/ci.yml` (GitHub Actions, production) implement the
contract. A test validates conformance.
2. **Shell reproducibility.** `scripts/run_ci.sh` mirrors the CI pipeline
locally — runs the same 3 stages (lint, test, check-only) in sequence.
The pipeline is fully reproducible from the shell, not just in CI.
3. **Output streaming.** `scripts/run_platform.sh` streams terraform
init/validate/plan output, Checkov compliance results, and
PolicyCheckResult records to stdout by default, so the user sees what
is happening. A `--quiet` flag suppresses streaming for log-only mode.
## Milestone v1.4 Phases
| Phase | Name | Goal |
|-------|------|------|
| 19 | central-pipeline-contract-and-shell-reproducibility | Create the central pipeline contract (JSON Schema + YAML instance). Create `scripts/run_ci.sh` for shell reproducibility. Update `run_platform.sh` to stream terraform/checkov output. Update both workflow YAMLs with contract references (staying byte-identical). Add tests for contract validation, workflow conformance, and streaming. |
Milestone COMPLETE gate: review → ship `v1.4.1` (feature milestone, next
minor per ship.md — v1.3 shipped `v1.3.2`) → audit.
## Requirements
### v1.0 (Prior milestone — the demo)
Status: complete. Tag `v1.1.0`. All REQ-01..15 satisfied by the stub-driven
executive demo. See `REQUIREMENTS.md` §v1 and the prior decisions table
appendix below. The demo is **archived** to `demo/` in Phase 06.
### v1.1 (Prior milestone — architecture finalization + v1 spike, complete)
New requirements REQ-16..REQ-28 — see `REQUIREMENTS.md` §v1.1. Summary:
- **REQ-16:** Architecture finalized to v1.0 (11 open decisions resolved).
- **REQ-17:** Target Stack IR defined as JSON Schema; substrate-agnostic.
- **REQ-18:** PolicyCheckResult normalized schema defined; Checkov adapter.
- **REQ-19:** Six-input confidence signal specified with per-env thresholds
(dev 0.50 / qa 0.75 / prod 0.90 / dr 0.95) and severity→penalty mapping.
- **REQ-20:** Tiered audit ledger design (S3 Object Lock 7-yr + DynamoDB
outbox, RPO=0, JWS detached signatures, `prev_event_hash` chain).
- **REQ-21:** Full 8-concern HITL matrix + separation-of-duties design
(CODEOWNERS + DynamoDB identity-distinctness).
- **REQ-22:** Contract schema (JSON Schema draft 2020-12) with per-env
mandatory/optional inputs and `profile: agentic` marker for L3B.
- **REQ-23:** AWS OIDC bootstrap (IAM role + trust policy for act_runner);
the long-lived key is used once then rotated (waiver D-034).
- **REQ-24:** One real L1 module (`l1-s3`) with an IR-typed interface.
- **REQ-25:** One real L2 thin-composition (`l2-static-asset`) referencing
`l1-s3`.
- **REQ-26:** Terraform adapter compiles the IR to a real `terraform plan`
against AWS via OIDC; state in S3 + DynamoDB.
- **REQ-27:** One end-to-end contract submission → contract→IR resolution →
`terraform plan` → Checkov → confidence signal → evidence event to outbox.
- **REQ-28:** Spike verification proves the IR-shaped commitments hold (no
polyglot mess; the adapter is the only substrate-specific code).
### v1.2 (Prior milestone — platform hardening + first real consumer deployment, complete)
New requirements REQ-29..REQ-35 — see `REQUIREMENTS.md` §v1.2. Summary:
- **REQ-29:** README.md fully documents the v1.1-complete platform: spike
flow, how to run, repo layout, v1.2 objective.
- **REQ-30:** NFR hardening — least-privilege IAM audit, idempotent
bootstrap, consolidated `run_platform.sh`, error handling, P1-1/P1-B
redaction.
- **REQ-31:** L1 catalog expanded for ECS — 6 new IR-typed L1s
(`l1-vpc`, `l1-ecs-cluster`, `l1-ecs-service`, `l1-iam-role`, `l1-alb`,
`l1-ecr`) registered and adapter-compiled.
- **REQ-32:** `l2-microservice` thin-composition + contract schema extended
for microservice inputs (image, port, env, healthcheck).
- **REQ-33:** `terraform apply` (dev, autonomous) — real provisioning, not
just `plan`.
- **REQ-34:** Consumer repo `acdl-consumer-microservice` with a basic
microservice (ECR image, Dockerfile, contract).
- **REQ-35:** End-to-end verification — consumer commit → live ECS service
(HTTP 200) → evidence event → timeline.
### v1.4 (Active milestone — central pipeline contract + shell reproducibility + streaming)
New requirements REQ-43..REQ-45 — see `REQUIREMENTS.md` §v1.4. Summary:
- **REQ-43:** Central pipeline contract — `schemas/pipeline.schema.json` +
`pipelines/ci.yaml`. Both Gitea and GitHub workflows implement the
contract; a test validates conformance.
- **REQ-44:** `scripts/run_ci.sh` mirrors the CI pipeline locally (lint →
test → check-only), exiting 0 with "CI PIPELINE OK".
- **REQ-45:** `scripts/run_platform.sh` streams terraform/checkov output by
default (with `--quiet` for log-only mode). Both workflows byte-identical.
## Constraints
- **Forge:** Gitea at `https://git.cloudinit.dev`, org `continuous-intelligence`.
- **CI runtime:** act_runner / Gitea Actions (reuses GitHub Actions workflow YAML).
- **Cloud:** AWS via OIDC federation. **Long-lived credentials are forbidden**
(§12.5). The v1.1 spike uses a temporary long-lived key **once** to bootstrap
OIDC (waiver D-034), then rotates it.
- **Substrate:** Terraform adapter in v1 (the only adapter). L1/L2 are
substrate-agnostic in shape; the adapter is the only substrate-specific code.
- **State:** S3 (state files) + DynamoDB (locking), single-region in v1.
- **Environments:** dev (autonomous) → qa (QA HITL) → prod (SRE HITL) → dr
(SRE HITL). **Staging does not exist** (Path A locked).
- **Compute:** abstract / containerized / serverless. No VMs, bare metal, OS
lifecycle.
- **Autonomy:** Full. Escalation hooks: deploy, delete_data, merge_to_main.
## Anti-Goals (from `docs/vision.md` §7)
- Not an upstream development platform (no product backlogs, IDE, code authorship).
- Not a general-purpose AI (autonomy is narrow, bounded by policy envelopes).
- Not a legacy infrastructure bridge (no VMs/bare metal/OS).
- Not a permissive delivery highway (no escape hatches past confidence or HITL).
- Not a mutable audit log (VCS history ≠ regulatory evidence).
## Context
- The `acdl` repo exists at the org root. `acdl-contracts` and
`acdl-evidence` exist from the v1.0 demo and continue as the developer
surface and the audit-timeline host respectively.
- `docs/vision.md` and `docs/architecture.md` (v0.2) are the upstream
vision/architecture sources, pulled from `origin/main` at the start of v1.1.
- The v1.0 demo (tag `v1.1.0`) is the reference of intent — it proved the
shape (L1/L2/contract/confidence/evidence/HITL) on stubs. v1.1 replaces the
stubs with the real platform substrate.
## Key Decisions (v1.1)
Carries forward the still-valid v1.0 decisions (see appendix). New v1.1
decisions:
| ID | Decision | Rationale | Outcome |
|----|----------|-----------|---------|
| D-034 | Temporary long-lived AWS key (waiver) used once in Phase 08 to bootstrap the state backend + IAM user; rotated/deactivated immediately after | §12.5 forbids long-lived creds; the bootstrap needed one `aws iam` call before the spike user + rotated key could take over | Spike achieves real `terraform plan` against AWS without violating the locked target after bootstrap. **CLOSED 2026-07-21: root key `AKIA…ROOT-DEACTIVATED` deactivated by the user in the AWS IAM console (verified — `InvalidClientTokenId`); the spike uses the rotated `acdl-spike-runner` key per D-039. Key ID redacted in v1.2 Phase 12 (P1-1).** |
| D-035 | Milestone version = `v1.1` (feature), ship tag `v1.2.0` | Real platform is a breaking reframing of the demo, but treated as the next incremental milestone per user choice; ship.md: feature milestone → next minor | Tag `v1.2.0` on milestone COMPLETE |
| D-036 | Spike picks `l1-s3` + `l2-static-asset` | Simplest real AWS resource (no IAM/network deps); smallest real `terraform plan`; proves the IR + adapter end-to-end | Spike scope fixed |
| D-037 | Demo archived to `demo/` (not deleted) | Preserves the working v1.0 demo as intent reference; new platform layout under `platform/`, `schemas/`, `adapters/`, `terraform/`, `modules-ir/` | No churn on demo code; clean separation |
| D-038 | Open decisions resolved in "accept recommendations + decide rest" mode | User-locked mode: accept architecture's stated recommendations (W1.A, W1.B, W2.A, BA.A); lead-developer decides the remaining 8 (W3.D, W3.E, BA.B, BA.C, BA.D, BA.E, BA.F, OpenTofu timing) with rationale | Architecture reaches v1.0 in Phase 07 |
| D-039 | Spike-only waiver: per-run-rotated long-lived AWS key. OIDC federation deferred to v1.2, blocked on go-gitea/gitea#36988. | **RESEARCH TARGET 1 verdict (conf 0.95):** Gitea Actions does NOT support `id-token: write` / OIDC token issuance as of Gitea 1.27.x / gitea-runner v2.1.0. GitHub's OIDC pattern is not portable. The waiver satisfies §12.5's *intent* (no persistent long-lived key) for the spike: the key is rotated after each run by `scripts/rotate_spike_key.sh`. v1.2 implements real OIDC when the Gitea PR merges. | Spike achieves real `terraform plan` against AWS without a *persistently* long-lived key; real OIDC is a v1.2 deliverable |
| D-040 | The 6 confidence-signal inputs are: policy (0.30), validation (0.25), freshness (0.10), source (0.15), history (0.10), nfrs (0.10). Weights frozen for v1, tuned in v1.2 alongside thresholds (BA.B). | Architecture §8 locks "six canonical inputs" but does not enumerate them; RESEARCH TARGET 6 chose the platform-computable subset present in every environment (incl. dev). | Confidence signal (Phase 10) has a concrete input enumeration |
| D-041 | Spike audit ledger = v1.0 hash chain + DynamoDB outbox + `acdl-evidence` mirror. S3 Object Lock (compliance mode, 7-yr) + JWS (platform KMS key, quarterly rotation) + daily checkpoints are v1.2 build-out, authored as design in Phase 07. | REQ-20 is "design authored," not "implemented." The spike proves the outbox write path; the regulatory ledger is v1.2. | Spike scope stays bounded; REQ-20 satisfied by the Phase 07 design doc |
| D-042 | HITL approver identity in Gitea = `gitea.actor` of the `workflow_dispatch` run that sets `approve_qa=true`/`approve_prod=true`/`approve_dr=true`. Separation-of-duties reads `approver_qa` from the DynamoDB outbox and compares to the prod-dispatch `gitea.actor`. | Gitea has no Environments API (re-confirmed in RESEARCH); `gitea.actor` is the only approval-identity signal. | SoD design (Phase 07) is concrete for the Gitea forge |
| D-043 | Tag/naming compliance deferred for the spike: the Checkov adapter emits a single `SKIPPED` PolicyCheckResult (`ruleId: ACDL_TAG_NAMING`, `severity: info`) so the confidence policy input is non-empty. Custom Checkov YAML rule lands in v1.2. | Checkov has no built-in tag-presence check; a custom rule in the spike is scope creep. | Spike's policy input is non-empty without a custom-rule dependency |
| D-044 | DynamoDB outbox = `PAY_PER_REQUEST`; PK `contractId`, SK `eventType#eventTs`, TTL `expire_at` = now + 365d. No separate async worker/DLQ in the spike (RTO = workflow re-run); v1.2 outbox worker + DLQ is a Phase 07 design artifact. | On-demand is zero-cost-at-idle for the spike's single dev submission. | Spike outbox is minimal; v1.2 worker design authored in Phase 07 |
| D-045 | Runner tooling: `runs-on: ubuntu-latest`; install `terraform` via HashiCorp apt repo (pin `1.9.*`), `checkov` via pip (pin `>=3.2,<4`, `--break-system-packages`). Neither is pre-installed on the default runner image. | RESEARCH TARGET 2; pinning avoids mid-spike version drift. | Phase 09/10 workflows have a concrete setup step |
| D-046 | `act_runner``gitea-runner` rename: Phase 07 updates docs to use the current name `gitea-runner` (renamed 2026-04 in gitea/runner#850). | RESEARCH TARGET 1 + R-4: naming drift between v1.0 docs and the current runner. | Docs reflect the current binary name |
| D-047 | v1.2 carries forward the D-039 per-run-rotated-key waiver. Real OIDC federation remains deferred to v1.3+, blocked on go-gitea/gitea#36988 (re-checked 2026-07-21: still **open**, last updated 2026-05-27, not merged). | §12.5 forbids long-lived creds; the Gitea Actions OIDC provider is still not merged. The waiver continues to satisfy §12.5's *intent* (no *persistently* long-lived key) for v1.2: `scripts/rotate_spike_key.sh` rotates the key, and Phase 12 tightens the IAM scoping + rotation hygiene. | v1.2 achieves `terraform apply` against AWS without a persistently long-lived key; real OIDC is a v1.3+ deliverable. |
### Open-decision resolutions (Phase 07 deliverable — recorded here for traceability)
| ID | Question | Resolution |
|---|---|---|
| W1.A | AI-refinement trigger | **Accept recommendation.** Joint condition: N ≥ 50 consecutive changes with zero rollbacks AND no L1/L2 incident in last 6 months AND Infra & Ops unilateral override. |
| W1.B | Multi-stack edge case rule | **Accept recommendation.** Permitted only for (a) DR-region mirror, (b) time-boxed experimental stack with TTL ≤ 30d, (c) explicit Infra & Ops approval with `multiStack.justification`. |
| W2.A | Tag mutability for prod | **Accept recommendation (Path B).** Tag for dev/qa, SHA for prod. Platform CLI resolves tag→SHA for prod-bound workflows. Justified by the "Audit truth lives outside the repository" bet. |
| BA.A | Initial L3B skill catalog | **Accept recommendation.** 5 skills: web API, worker, scheduled job, static asset, basic observability bootstrap. Addition criteria: (a) reviewable for sensitive data, (b) expressible as a single contract submission, (c) documented use case. |
| W3.D | L1/L2 standard versioning | **Decided.** Semver: interface → MAJOR, behavior → MINOR, lifecycle → PATCH (same as the v1.0 demo D-rule, lifted to the real platform). Pin model: L2 contracts pin L1 by `name@semver`; the resolver picks the highest compatible. Evolution: MAJOR bumps require a new registry entry (immutable publication); old entry enters a 12-month deprecation window. |
| W3.E | Schema mandatory vs optional inputs | **Decided.** Per-env mandatory table: dev requires `stack` + `environment`; qa adds `validation.e2eSuite` + `validation.loadTest`; prod adds `runbook` + `dashboard` + `oncall`; dr adds `drDrillRef`. `inputs` map is always optional. `profile: agentic` fields (`naturalLanguageIntent`, `confidenceAtSubmission`, `agentTrace`) optional everywhere. |
| BA.B | Confidence threshold tuning | **Decided.** Starting thresholds frozen for v1. Tuning begins in v1.2: track FP/FN per environment quarterly; override authority = Infra & Ops + SRE joint sign-off; any override is itself a confidence-event in the audit stream. |
| BA.C | On-call / operational ownership | **Decided.** Platform on-call = Infra & Ops rotation. Escalation: L3A/L3B halt → platform on-call pager (Sev2); consumer-visible outage → consumer on-call (Sev1) with platform on-call support. Consumer on-call relationship is contractual, defined at onboarding (BA.E). |
| BA.D | Cost / capacity governance | **Decided.** Cloud cost owner = Infra & Ops FinOps. Per-contract consumption reported monthly. Runaway spend: hard halt at 120% of contract-declared budget envelope via the confidence signal (cost is one of the 6 inputs); override = FinOps + SRE joint sign-off. |
| BA.E | Consumer onboarding | **Decided.** Two paths: developer (L3A) — `getting-started` walks through contract schema + central pipeline template; citizen developer (L3B) — onboarding grants a scoped agent + skill catalog, no workflow authoring. Both end in a sandbox dev submission that must pass the confidence gate before the consumer is promoted. |
| BA.F | Cross-platform evolution | **Decided.** The contract schema, IR, PolicyCheckResult, confidence signal, and audit stream are portable (substrate- and forge-agnostic). Forge-specific code: workflow YAML, OIDC trust, CODEOWNERS, Environments. A second forge (e.g., GitLab) requires a forge adapter + a workflow-template translator; no change to L1/L2/IR/confidence/audit. |
| Q1.3 | OpenTofu timing | **Decided (deferred).** Not in v1 or v1.1. The substrate abstraction (§12) makes OpenTofu a future adapter, not an architecture change. Revisit when an OpenTofu adapter is requested; no version committed. |
## Appendix — Prior milestone (v1.0 demo) decisions
The v1.0 demo (tag `v1.1.0`) carried decisions D-001..D-033. They governed
the stub-driven executive demo and remain valid **for the archived demo
under `demo/`**. They are **superseded** by the v1.1 decisions above for the
real platform. Full text preserved in git history at tag `v1.1.0`.
## Operational parameters (CLARIFY auto-resolution, full autonomy)
Resolved at the CLARIFY stage to unblock planning. None require user
sign-off (autonomy = full; all within locked constraints).
| Parameter | Value | Rationale |
|---|---|---|
| AWS region | `us-east-1` | Default; matches v1.0 demo references; single-region in v1 (§12.3) |
| Terraform state bucket | `acdl-tfstate-<account-id>-us-east-1` | Namespaced by account id to avoid collision; region-suffixed |
| Terraform lock table | `acdl-tflock` | DynamoDB; single-region v1 |
| OIDC IAM role | `acdl-act-runner-role` | Assumed by the act_runner via web-identity |
| OIDC trust subject | `repo:continuous-intelligence/acdl:ref:refs/heads/main` (+ phase branches) | Least-privilege; refined in Phase 08 |
| Spike L1 (`l1-s3`) inputs | `bucket_name: string`, `region: string` | Minimal S3 interface per §2 |
| Spike L2 (`l2-static-asset`) | thin-composition referencing `l1-s3` only; depth 1 | Smallest real plan per D-036 |
| Spike contract | `contracts/spike.yaml`: `stack: l2-static-asset`, `environment: dev`, `inputs: { bucket_name: acdl-spike-bucket, region: us-east-1 }` | One end-to-end submission (REQ-27) |
| Spike `terraform` command | `plan` only | `apply` is out of scope (Out of Scope table); HITL-gated in v1.2 |
| Checkov ruleset (spike) | the 4 L2 checks (secrets-in-plaintext, public ingress, IAM wildcard, KMS key reference) + tag/naming | §3 + §12.4; Kyverno/OPA deferred |
| v1.0 tags preserved | `v1.0.1`..`v1.0.5`, `v1.1.0` retained | Immutability; demo archive does not rewrite history |
| Next ship tag | `v1.3.0` | Feature milestone → next minor per ship.md (v1.1 shipped `v1.2.0`; v1.2 ships `v1.3.0`) |
### Items deferred to RESEARCH (not clarifications)
- **Gitea/act_runner OIDC support** — does act_runner emit an OIDC
`id-token`? Determines whether real-AWS plan is achievable in this
environment or whether a spike-only waiver is needed. Highest-priority
research target.
- **Terraform + Checkov availability on the runner image** — install in the
workflow if missing.
- **`actions/configure-aws-credentials` action on act_runner** — if
unavailable, fall back to `aws sts assume-role-with-web-identity` from a
step.