diff --git a/.ciagent/AUDIT.md b/.ciagent/AUDIT.md index 273d232..a191ac2 100644 --- a/.ciagent/AUDIT.md +++ b/.ciagent/AUDIT.md @@ -1,70 +1,48 @@ -# ACDL v1.8 — Audit Report +# ACDL v1.9 — Audit Report -> Audit date: 2026-07-22. Auditor: ci-audit. Milestone: v1.8. Result: PASS. +> Audit date: 2026-07-23. Auditor: ci-debugger. Milestone: v1.9. Result: PASS. ## Step 1: Reconstruction Test -**Result: PASS** +- 12 v1.9 commits with `---ci---` blocks (specify → clarify → research → + plan → execute ×4 phases → merge ×4 → verify/review/audit/complete). +- State matches config.json (milestone v1.9, status complete). +- PROJECT.md v1.9 objective + decisions D-080..D-086 + auto-resolved + parameters present. REQUIREMENTS.md REQ-100..111 + traceability table + present. ROADMAP.md v1.9 section + phases 39–43 present. +**PASS.** -Reconstructed state from 17 `---ci---` blocks in git log (v1.7.0..HEAD): +## Step 2: File Discipline -| Field | Reconstructed | .ciagent/config.json | Match | -|-------|---------------|----------------------|-------| -| Milestone | v1.8 | v1.8 | ✅ | -| Status | complete | complete | ✅ | -| Project | acdl | acdl | ✅ | -| Phases | 28–38 | 28–38 in ROADMAP | ✅ | -| Requirements | REQ-76..99 (24) | REQ-76..99 (24) in REQUIREMENTS.md | ✅ | -| Partial | [] | [] | ✅ | - -All 17 commits have `---ci---` blocks with `project: acdl`, `milestone: v1.8`. - -## Step 2: .ciagent/ File Discipline - -**Result: PASS (0 issues)** - -| File | Check | Result | -|------|-------|--------| -| config.json | Valid JSON, required fields | PASS | -| PROJECT.md | Has v1.8 objective, requirements, key decisions (D-061..D-072), phases | PASS | -| ROADMAP.md | v1.8 marked complete, all phases complete, no pending | PASS | -| REQUIREMENTS.md | 24 requirements complete (v1.8.0), no pending, traceability matrix | PASS | -| ARCHITECTURE.md | v1.8 addendum added (kms-key, uptime, encryption, decommission, adapter expansion) | PASS (fixed during audit) | -| PLAN.md | Covers phases 28–38 | PASS | -| PERSONAS.md | Updated for v1.8 (lambda-engineer reactivated, 11 phase overrides) | PASS | -| RESEARCH.md | Has v1.8 addendum (6 targets, D-073..D-077) | PASS | -| VERIFY.md | Has VERIFY PASS (4 layers, 350 tests) | PASS | +- All 10 `.ciagent/` files valid (config.json, PROJECT.md, REQUIREMENTS.md, + ROADMAP.md, PLAN.md, RESEARCH.md, PERSONAS.md, REVIEW.md, VERIFY.md, + AUDIT.md). +- PERSONAS.md updated for v1.9 (milestone field, lambda-engineer + reactivated, phase-specific overrides for 39–43). +- REVIEW.md reconstructed with v1.9 content (D-086); note records v1.3–v1.8 + reviews were not persisted (no git-history rewrite). +**PASS.** ## Step 3: Branch Hygiene -**Result: PASS (after cleanup)** - -| Branch | Status | Action | -|--------|--------|--------| -| main | Active, clean | — | -| origin/main | Tracks main | — | -| ~~phase/21-docs-restructure~~ | Stale (v1.6) | Deleted | -| ~~milestone/v1.0-initial~~ | Stale (v1.0) | Deleted + pruned | - -Only `main` + `origin/main` remain. No orphan branches. +- 5 v1.9 phase branches (phase/39..43) merged to main. They can be pruned + after the milestone tag. No milestone branch was used (single-project + mode, main is the integration branch per the v1.8 precedent). +- Only main + origin/main + the 5 phase branches remain. +**PASS.** ## Step 4: Commit Discipline -**Result: PASS** +- 12/12 v1.9 commits have `---ci---` blocks with project, phase, milestone, + status fields. +- No stale decisions; D-080..D-086 recorded in PROJECT.md; D-087..D-089 + recorded in RESEARCH.md. +- No secrets in commits (SNS topic ARN is a Terraform output, not a + literal; Wiz/KMS/SNS env-var-based). +**PASS.** -| Check | Count | Result | -|-------|-------|--------| -| Total v1.8 commits | 17 | — | -| Commits with `---ci---` blocks | 17 | PASS | -| Commits without `---ci---` blocks | 0 | PASS | -| Stale decisions | 0 | PASS (D-061..D-077 all reflected in code) | -| Unresolved escalations | 0 | PASS (none) | +## Issues fixed during audit -## Issues Found + Fixed During Audit +None — the milestone is clean as shipped. -1. **ARCHITECTURE.md missing v1.8 content** (P1) — Fixed: added v1.8 addendum covering new primitives, encryption-by-default, deletion-protection, decommission, adapter expansion, pipeline stages, forge-agnostic APIs. -2. **Stale branches** (P2) — Fixed: deleted `phase/21-docs-restructure` + `milestone/v1.0-initial`, pruned remote refs. - -## Verdict - -**AUDIT PASS** — Project state is fully reconstructable from git log. All `.ciagent/` files match codebase. Branch hygiene clean. Commit discipline perfect (17/17 with `---ci---` blocks). No stale decisions or unresolved escalations. \ No newline at end of file +## Audit result: PASS \ No newline at end of file diff --git a/.ciagent/PROJECT.md b/.ciagent/PROJECT.md index c269c1e..80b4a13 100644 --- a/.ciagent/PROJECT.md +++ b/.ciagent/PROJECT.md @@ -296,7 +296,7 @@ and test each. Milestone COMPLETE gate: review → ship `v1.8.0` (feature milestone, next minor per run.md — v1.7 shipped `v1.7.0`) → audit. -## Objective for Milestone v1.9 (active) +## Objective for Milestone v1.9 (complete, tag `v1.9.0`) Production-grade progression: contract interpolation, per-environment promotion without field editing, stub implementation, and P1-1 diff --git a/.ciagent/REQUIREMENTS.md b/.ciagent/REQUIREMENTS.md index 74f793d..33c9e71 100644 --- a/.ciagent/REQUIREMENTS.md +++ b/.ciagent/REQUIREMENTS.md @@ -240,7 +240,7 @@ | 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 (Active — design doc refresh + contract interpolation + per-env CI jobs + stub implementation + P1-1 remediation) +## 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. @@ -416,4 +416,20 @@ | 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) | \ No newline at end of file +| 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) | diff --git a/.ciagent/REVIEW.md b/.ciagent/REVIEW.md index 5b02909..53faba8 100644 --- a/.ciagent/REVIEW.md +++ b/.ciagent/REVIEW.md @@ -1,106 +1,114 @@ -# ACDL v1.2 Milestone — Multi-Persona Code Review +# ACDL v1.9 Milestone — Multi-Persona Code Review **Reviewer:** ci-code-reviewer (model: glm-5.2) -**Scope:** v1.2 milestone — Phases 11–16 (tags v1.2.1..v1.2.6), diff `v1.2.0..HEAD` -**Date:** 2026-07-21 -**Verdict:** **READY TO SHIP** — 1 P0 (operator action, non-code), 1 P1 (adapter hardening for v1.3) +**Scope:** v1.9 milestone — Phases 39–42 (tags v1.8.1..v1.8.4), diff `v1.8.0..HEAD` +**Date:** 2026-07-23 +**Verdict:** **READY TO SHIP** — 0 P0, 0 P1 + +> **Note (D-086):** This REVIEW.md was reconstructed at v1.9 complete. +> The previous content was the v1.2 milestone review (v1.3–v1.8 reviews +> were not persisted to this file). No git history was rewritten; the +> v1.2 review is preserved in git history at the v1.2 review commit. --- ## Summary -v1.2 hardens the v1.1 spike, simplifies the setup, rewrites the docs, and -takes the platform to a real ECS Fargate microservice deployment. 6 phases -shipped (v1.2.1–v1.2.6): research + README, NFR hardening + simplification, -6 ECS L1s + adapter generalization, l2-microservice + contract schema + -resolver wiring, consumer repo + terraform apply (blocked by IAM), -capstone e2e. +v1.9 closes four gaps left by v1.8 (user-directed, 2026-07-23): stale +design docs, no contract interpolation, promotion requires editing the +`environment` field, and unimplemented stubs. It also closes P1-1 +(adapter hardcoded defaults, deferred from v1.2). 4 phases shipped +(39–42): design-doc refresh + P1-1 parameterization, contract +interpolation + env schema, per-environment CI jobs, stub implementation. ## P0 issues -### P0-IAM (operator action, NOT a code fix) -**The `terraform apply` (Phase 15) is blocked by the live IAM policy.** The -Phase 12 `spike_runner_policy.json` expansion (ECS/ECR/ELB/IAM/EC2) was -committed to the repo but never pushed to the live AWS account — the root -key was deactivated per D-034, and the `acdl-spike-runner` user cannot -self-elevate via `iam:PutUserPolicy`. - -**Unblock step (operator):** -```bash -ACDL_BOOTSTRAP_AWS_ACCESS_KEY_ID= \ -ACDL_BOOTSTRAP_AWS_SECRET_ACCESS_KEY= \ -python3 terraform/bootstrap/create_iam_user.py -``` -This re-PUTs the expanded policy (idempotent). Then `terraform apply` -(plan is valid, 13 to add) → live ECS Fargate service → HTTP 200. - -**Why this is not a code fix:** the code + plan are correct + verified -(`terraform validate` + `terraform plan` succeed). The blocker is purely -the live IAM policy state, which requires a privileged credential that -was deliberately deactivated (D-034 closure). +None. ## P1 issues -### P1-1 (adapter hardening, deferred to v1.3) -The adapter's ECS/ALB/VPC emission includes several resource-type-specific -defaults (`desired_count = 1`, `launch_type = "FARGATE"`, `target_type = "ip"`, -`load_balancer_type = "application"`, `tags = { Name = ... }`, `family = "app"`). -These are pragmatic for the v1.2 spike but should be parameterized via the -L1 interfaces in v1.3 (the adapter should remain a thin translator; these -defaults belong in the L1 contract, not the adapter). +None. ## Per-lens review ### Correctness -- The contract→IR→adapter pipeline produces valid HCL (`terraform validate` - passes; `terraform plan` succeeds with 13 to add). -- The v1.1 S3 regression passes (byte-identical `main.tf`) across all - adapter changes (ref emission, JSON-string detection, ECS service - network_configuration/load_balancer, listener default_action, target - group defaults, VPC tags, IGW emission, managed_policy_arns). -- The `intra_refs` mechanism (L1-declared refs between sub-resources of - the same L1) correctly resolves subnet→vpc.vpc_id + routetable→vpc.vpc_id. -- The resolver's array-form wires + child→child `ref:` emission are - backward-compatible (v1.1 single-object wires still work). +- The contract interpolation (`_expand_vars`) is recursive over + dicts/lists/strings; unknown tokens raise `ValueError` (fail loud). + Expansion is post-schema-validation, pre-IR-resolution — the schema + sees raw tokens (valid strings), the resolver sees concrete values. +- The `environment_override` (D-088) is applied BEFORE schema validation + so the interpolation context is consistent. +- P1-1: the adapter reads `desired_count`, `launch_type`, `family`, + `target_type`, `load_balancer_type` from inputs (with interface + defaults). The resolver's `child_input_map` routes wires to the + sub-resource that declares the input (desired_count → aws:ecs:service, + family → aws:ecs:task_definition). The v1.1 S3 regression is preserved + (byte-identical `main.tf` for S3-only stacks). +- The HITL attestation gate records the approver to the outbox, runs SoD + on prod (blocks on `approver_qa == approver_prod`), invokes the + attestation matrix. Dev skips (autonomous). +- The attestation matrix's freshness validation uses the §10.4 windows; + signature verification skips when the signing key is unset (D-089) and + is required when set. +- The Wiz real client uses the GraphQL API with pagination; graceful + degrade when unconfigured. +- The Kyverno translator handles pass/fail/skip/warn + severity + skip- + with-reason + resource construction; the inactive-for-TF guard is + preserved. ### Testing -- 6 per-phase verify scripts (`verify_phase11.sh`..`verify_phase16.sh`), - all green. -- The capstone verify (`verify_phase16.sh`) exercises every v1.2 - deliverable + the v1.1 regression + NFR + docs + L1 catalog + outbox. -- The `terraform apply` + HTTP 200 check are the operator's post-unblock - step (documented in Phase 15/16 VERIFY). +- 493 offline tests (was 350 at v1.8 → 493 at v1.9, +143 new). Each new + feature has dedicated tests: + - P1-1: `test_p1_1_adapter_parameterization.py` (override + default + regression). + - Design docs: `test_design_docs_current.py` (no stale framing). + - Interpolation: `test_interpolation.py` + `test_sample_contracts_interpolate.py` + + `test_environment_schema.py`. + - Per-env jobs: `test_per_env_contracts.py` + `test_deploy_workflow_env_input.py` + + `test_consumer_guide_per_env_section.py`. + - Stubs: `test_route_halt_artifact.py` + `test_hitl_gates.py` + + `test_attestation_matrix.py` + `test_wiz_adapter_real_client.py` + + expanded `test_kyverno_adapter.py`. +- `run_ci.sh` exits 0; `run_platform.sh --check-only` exits 0. ### Security -- No credentials introduced. The `P1-1` AWS key ID redaction (carried from - v1.1) is closed — no live key IDs in `.ciagent/`. -- The IAM blocker is a security positive: least-privilege enforced; the - policy push requires a deliberate privileged action. -- The `assume_role_policy` in the contract is the standard ECS task - execution trust policy (not a secret). +- No credentials introduced. The SNS topic is KMS-encrypted. +- SoD blocks on identity equality; the halt artifact is in the audit chain. +- The attestation matrix fails loud on missing/expired evidence for prod/dr. +- Signature verification is required when the signing key is set. +- The adapter has no hardcoded resource defaults (P1-1 closed) — defaults + live in the L1 interface, not the adapter. ### Performance -- N/A (this milestone is about correctness + simplification, not perf). +- N/A (this milestone is about correctness + design-doc accuracy + stub + implementation, not perf). ### Maintainability -- `run_platform.sh` consolidates two scripts (D-048) — one entry point. -- The adapter's `TYPE_MAP` + `INPUT_MAP` + `OUTPUT_MAP` tables make adding - future L1s a table-extension, not new emit logic. -- The `intra_refs` mechanism is a clean L1-declared extension. +- The interpolation is a single recursive walker; the env context is + loaded via a self-contained `_load_env` (works as script + package import). +- The `child_input_map` makes multi-resource L1 wire routing deterministic + (the sub-resource that declares the input receives the value). +- The attestation matrix's concern lists + freshness table are data-driven + (adding a concern is a table extension, not new logic). +- The Wiz `WizClient` is a clean class with a single `_post` seam (testable + with `mock.patch.object`). ### Adversarial -- The `terraform apply` failure was investigated thoroughly: the subagent - attempted one fix (adapter HCL correctness), then correctly identified - the IAM root cause + documented the unblock step. No half-applied AWS - state (all 5 creates failed at the API; state is empty). -- The `TERRAFORM_APPLY_BLOCKED` + `MILESTONE_CAPSTONE_VERIFIED` evidence - events truthfully record the state (not faking success). +- The interpolation fail-loud (`ValueError` on unknown tokens) prevents + silent mis-resolution — a typo in a token name surfaces immediately, + not as a stale literal in the emitted Terraform. +- The `environment_override` is applied before schema validation, so a + contract with `environment: dev` cannot silently interpolate against + the dev env when the workflow passes `environment: prod` — the override + is authoritative. +- The SoD check reads `approver_qa` from the outbox (the platform is the + only writer); a consumer cannot forge the approver identity. +- The attestation matrix's signature skip is explicit + logged (not silent). ## Conclusion -v1.2 is READY TO SHIP. The 1 P0 is an operator action (not a code fix), and -the 1 P1 is deferred to v1.3. The milestone's code is complete + verified: -the platform flow works end-to-end up to `terraform plan` (13 to add), and -the one remaining step (`terraform apply` → live ECS service) is the -operator's IAM policy push. Ship tag: `v1.3.0` (feature milestone, next -minor per ship.md — v1.1 shipped `v1.2.0`). \ No newline at end of file +v1.9 is READY TO SHIP. 0 P0, 0 P1. The milestone's code is complete + +verified: design docs are current, contract interpolation works, per-env +promotion requires no field editing, all stubs are implemented (audit +ledger Object Lock/JWS build-out deferred per D-083), and P1-1 is closed. +Ship tag: `v1.9.0` (feature milestone, next minor per run.md — v1.8 +shipped `v1.8.0`). \ No newline at end of file diff --git a/.ciagent/ROADMAP.md b/.ciagent/ROADMAP.md index e1b3666..7b7cd26 100644 --- a/.ciagent/ROADMAP.md +++ b/.ciagent/ROADMAP.md @@ -567,7 +567,7 @@ After Phase 38: COMPLETE gate — review → ship `v1.8.0` → audit. --- -## v1.9 (Active — design doc refresh + contract interpolation + per-env CI jobs + stub implementation + P1-1 remediation) +## v1.9 (complete — design doc refresh + contract interpolation + per-env CI jobs + stub implementation + P1-1 remediation, tag `v1.9.0`) The v1.9 milestone closes four gaps left by v1.8 (user-directed, 2026-07-23): stale design docs, no contract interpolation, promotion @@ -620,3 +620,16 @@ also closes P1-1 (adapter hardcoded defaults, deferred from v1.2). - Kyverno full mapping (pass/fail/skip/warn + severity + skip-with-reason + resource construction); inactive guard preserved; `--kube-version` parsed. - `tests/test_route_halt_artifact.py` + `test_hitl_gates.py` + `test_attestation_matrix.py` + `test_wiz_adapter_real_client.py` + expanded `test_kyverno_adapter.py` pass. - `pytest` 493 (was 446, +47); `run_ci.sh` exits 0; `run_platform.sh --check-only` exits 0. + +### Phase 43 — verify-review-audit-complete +- **Description:** 4-layer verify (structural, behavioral, security, quality) of all v1.9 phases. Multi-persona review (0 P0, 0 P1). Audit (reconstruction, file discipline, branch hygiene, commit discipline — all clean). REVIEW.md reconstructed (D-086). Complete: update REQUIREMENTS.md (REQ-100..111), ROADMAP.md, PROJECT.md. Tag `v1.9.0`; update floating `v1.9` + `v1` tags. Bump `uses:`/`ref:` from `@v1.6` → `@v1.9`. +- **Status:** complete (v1.9.0) +- **Depends on:** [42] +- **Requirements:** — +- **Success Criteria:** + - 4-layer verify PASS; 493 tests; `run_ci.sh` + `run_platform.sh --check-only` green. + - Review: 0 P0, 0 P1; REVIEW.md reconstructed with v1.9 content (D-086). + - Audit: clean; all 12 v1.9 commits have `---ci---` blocks. + - Tag `v1.9.0` created; floating tags updated; `uses:` bumped to `@v1.9`. + +After Phase 43: COMPLETE gate — review → ship `v1.9.0` → audit. **DONE.** diff --git a/.ciagent/VERIFY.md b/.ciagent/VERIFY.md index 8e7dc02..5818d0e 100644 --- a/.ciagent/VERIFY.md +++ b/.ciagent/VERIFY.md @@ -1,46 +1,40 @@ -# Phase 28-36 — Verify (v1.8) +# Phase 39-43 — Verify (v1.9) ## Structural -All 14 new files present (kms-key primitive, uptime primitive, STANDARDS.md, -3 READMEs, seed script, 4 test files). terraform/spike removed. Registry -has 14 entries. **PASS.** +All 26 new files present (environment.schema.json, 4 env files, 8 per-env +contracts, hitl_gates.py, attestation_matrix.py, 10 new test files, +refreshed design docs). SNS topic in terraform/platform/main.tf. **PASS.** ## Behavioral -- `pytest`: 350 tests, all passing (was 275 at v1.7 → 350 at v1.8, +75 new). +- `pytest`: 493 tests, all passing (was 350 at v1.8 → 493 at v1.9, +143 new). - `run_ci.sh`: exits 0 with "CI PIPELINE OK". -- `run_platform.sh --check-only`: exits 0 with "PLATFORM CHECK OK" (5 resources - for static-assets with the per-stack CMK). +- `run_platform.sh --check-only`: exits 0 with "PLATFORM CHECK OK". +- `run_platform.sh --check-only --environment qa`: exits 0; bucket name reflects qa env. **PASS.** ## Security -- No placeholder account ID in consumer_invoke_policy.json. -- No hardcoded GitHub API URLs in contract_ingestor.py (uses GITHUB_API_BASE). -- Deploy workflows byte-identical. -- SSM fails loud without ACDL_KMS_KEY_ID (RuntimeError). -- Deletion protection on by default for all primitives. -- Encryption enabled by default for all primitives. +- No hardcoded adapter ECS/ALB/VPC defaults (P1-1 closed; defaults in interface.json). +- HITL gates block on SoD violation (approver_qa == approver_prod). +- Attestation matrix fails loud on missing/expired evidence for prod/dr. +- Signature verification required when ACDL_ATTESTATION_SIGNING_KEY_ID set; skipped + logged when unset (D-089). +- Wiz degrades gracefully when unconfigured (WIZ_NOT_CONFIGURED SKIPPED record). +- SNS topic KMS-encrypted; outbox fallback for the halt artifact. +- Deploy workflows byte-identical (Gitea + GitHub). **PASS.** ## Quality -Each P1 fix has a dedicated test: -- P1-3: test_kms_unset_raises, test_kms_unset_allow_default_kms_escape_hatch -- P1-4: test_waf_custom_rules_emit_nested_blocks -- P1-5: test_waf_default_action_block_honored, test_waf_default_action_allow_when_absent -- P1-6: test_policy_has_no_hardcoded_account_id, test_main_tf_has_caller_identity_data_source -- P1-7: test_static_assets_has_stack_outputs, test_static_assets_adapter_emits_stack_output_blocks -- P1-8: run_platform.sh writes to $WORK/tf (verified by check-only) -- P1-9: test_gitea_search_url_uses_repos_endpoint, test_github_search_url_uses_search_endpoint -- S1: test_deploy_workflow_static_key_override_wired - Each new feature has dedicated tests: -- Encryption: test_kms_key_adapter_emits_rotation, test_all_l1_primitives_have_encryption_nfr, test_s3_with_kms_key_arn_emits_sse_configuration, test_static_assets_l2_wires_kms_key_to_s3 -- Deletion protection: test_all_l1_primitives_have_deletion_protection_nfr, test_adapter_emits_prevent_destroy_when_nfr_true, test_l2_feature_flag_propagates_deletion_protection_false -- Uptime: test_uptime_adapter_emits_ecs_service_when_enabled, test_uptime_adapter_emits_nothing_when_disabled, test_deploy_pipeline_has_deploy_uptime_stage -- Decommission: test_decommission_transform_zeros_desired_count, test_validates_approved_cr, test_consumer_guide_has_decommission_section -- Standards: test_standards_md_has_required_sections, test_all_l1_have_deletion_protection_nfr, test_all_l1_have_encryption_enabled_nfr -- Docs: test_schemas_readme_has_required_sections, test_pipelines_readme_has_required_sections, test_adapters_readme_has_required_sections +- Design docs: test_design_docs_current.py (no stale framing; deferred D-083 labeled). +- P1-1: test_p1_1_adapter_parameterization.py (override + default + v1.1 S3 regression). +- Interpolation: test_interpolation.py + test_sample_contracts_interpolate.py + test_environment_schema.py. +- Per-env jobs: test_per_env_contracts.py + test_deploy_workflow_env_input.py + test_consumer_guide_per_env_section.py. +- SoD: test_route_halt_artifact.py (SNS + outbox fallback + SNS failure fallback). +- HITL gates: test_hitl_gates.py (dev skips; qa/prod/dr record approver; SoD blocks; matrix invoked). +- Attestation matrix: test_attestation_matrix.py (offline concerns; operator-supplied; freshness; signature skip). +- Wiz: test_wiz_adapter_real_client.py (real client + pagination + graceful degrade). +- Kyverno: expanded test_kyverno_adapter.py (pass/fail/skip/warn + severity + inactive guard + kube-version). **PASS.** ## Verdict -**VERIFY PASS** — all four layers pass. 350 offline tests, no AWS required for CI. \ No newline at end of file +**VERIFY PASS** — all four layers pass. 493 offline tests, no AWS required for CI. \ No newline at end of file diff --git a/.ciagent/config.json b/.ciagent/config.json index 5c4cc97..e2a3539 100644 --- a/.ciagent/config.json +++ b/.ciagent/config.json @@ -5,7 +5,7 @@ "slug": "acdl", "name": "Agentic Cloud Delivery Platform", "milestone": "v1.9", - "status": "active" + "status": "complete" } ], "active_project": "acdl", diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 1273565..06ccc4c 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -8,8 +8,8 @@ # declared difference is the forge/runtime, not the stages or commands. # # Consumer repos invoke this workflow via a versioned tag (floating MAJOR + MINOR): -# uses: acdl/.gitea/workflows/deploy.yml@v1.6 (Gitea) -# uses: acdl/.github/workflows/deploy.yml@v1.6 (GitHub) +# uses: acdl/.gitea/workflows/deploy.yml@v1.9 (Gitea) +# uses: acdl/.github/workflows/deploy.yml@v1.9 (GitHub) # # Unversioned references (@main, bare) are discouraged — the consumer's setup # must be immutable + resilient. The versioned tag is the only immutability @@ -82,7 +82,7 @@ jobs: with: repository: acdl/acdl path: platform - ref: v1.6 + ref: v1.9 - uses: actions/setup-python@v5 with: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1273565..06ccc4c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -8,8 +8,8 @@ # declared difference is the forge/runtime, not the stages or commands. # # Consumer repos invoke this workflow via a versioned tag (floating MAJOR + MINOR): -# uses: acdl/.gitea/workflows/deploy.yml@v1.6 (Gitea) -# uses: acdl/.github/workflows/deploy.yml@v1.6 (GitHub) +# uses: acdl/.gitea/workflows/deploy.yml@v1.9 (Gitea) +# uses: acdl/.github/workflows/deploy.yml@v1.9 (GitHub) # # Unversioned references (@main, bare) are discouraged — the consumer's setup # must be immutable + resilient. The versioned tag is the only immutability @@ -82,7 +82,7 @@ jobs: with: repository: acdl/acdl path: platform - ref: v1.6 + ref: v1.9 - uses: actions/setup-python@v5 with: diff --git a/contracts/microservice.dev.yaml b/contracts/microservice.dev.yaml index f38cac5..9c64104 100644 --- a/contracts/microservice.dev.yaml +++ b/contracts/microservice.dev.yaml @@ -1,7 +1,7 @@ # ACDL sample consumer contract — microservice module (dev) # Per-environment contract (REQ-105). Promotion = running the dev job; # no environment field editing. Interpolation resolves against dev.json. -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: microservice environment: dev inputs: diff --git a/contracts/microservice.dr.yaml b/contracts/microservice.dr.yaml index 73d8f74..d665d85 100644 --- a/contracts/microservice.dr.yaml +++ b/contracts/microservice.dr.yaml @@ -1,7 +1,7 @@ # ACDL sample consumer contract — microservice module (dr) # Per-environment contract (REQ-105). Promotion = running the dr job; # no environment field editing. Interpolation resolves against dr.json. -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: microservice environment: dr inputs: diff --git a/contracts/microservice.prod.yaml b/contracts/microservice.prod.yaml index 1a60129..401a297 100644 --- a/contracts/microservice.prod.yaml +++ b/contracts/microservice.prod.yaml @@ -1,7 +1,7 @@ # ACDL sample consumer contract — microservice module (prod) # Per-environment contract (REQ-105). Promotion = running the prod job; # no environment field editing. Interpolation resolves against prod.json. -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: microservice environment: prod inputs: diff --git a/contracts/microservice.qa.yaml b/contracts/microservice.qa.yaml index 40a4225..0f9a145 100644 --- a/contracts/microservice.qa.yaml +++ b/contracts/microservice.qa.yaml @@ -1,7 +1,7 @@ # ACDL sample consumer contract — microservice module (qa) # Per-environment contract (REQ-105). Promotion = running the qa job; # no environment field editing. Interpolation resolves against qa.json. -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: microservice environment: qa inputs: diff --git a/contracts/microservice.yaml b/contracts/microservice.yaml index 1a8cfbb..6e1b0b2 100644 --- a/contracts/microservice.yaml +++ b/contracts/microservice.yaml @@ -4,7 +4,7 @@ # Interpolation (D-081): bucket_name uses the naming pattern that includes # region, aws account id, and environment: # acdl-${env.environment}-${contract.module}-${env.account_id}-${env.region} -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: microservice environment: dev inputs: diff --git a/contracts/static-assets.dev.yaml b/contracts/static-assets.dev.yaml index 42e70e2..8886021 100644 --- a/contracts/static-assets.dev.yaml +++ b/contracts/static-assets.dev.yaml @@ -2,7 +2,7 @@ # Per-environment contract (REQ-105). The dev default # (contracts/static-assets.yaml) remains for backwards compat; this file # is the explicit per-env dev contract. Interpolation resolves against dev.json. -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: static-assets environment: dev inputs: diff --git a/contracts/static-assets.dr.yaml b/contracts/static-assets.dr.yaml index 87e45f6..d7d9860 100644 --- a/contracts/static-assets.dr.yaml +++ b/contracts/static-assets.dr.yaml @@ -1,7 +1,7 @@ # ACDL sample consumer contract — static-assets module (dr) # Per-environment contract (REQ-105). Promotion = running the dr job; # no environment field editing. Interpolation resolves against dr.json. -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: static-assets environment: dr inputs: diff --git a/contracts/static-assets.prod.yaml b/contracts/static-assets.prod.yaml index 8160a55..162807d 100644 --- a/contracts/static-assets.prod.yaml +++ b/contracts/static-assets.prod.yaml @@ -1,7 +1,7 @@ # ACDL sample consumer contract — static-assets module (prod) # Per-environment contract (REQ-105). Promotion = running the prod job; # no environment field editing. Interpolation resolves against prod.json. -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: static-assets environment: prod inputs: diff --git a/contracts/static-assets.qa.yaml b/contracts/static-assets.qa.yaml index 9a44288..9541ed9 100644 --- a/contracts/static-assets.qa.yaml +++ b/contracts/static-assets.qa.yaml @@ -1,7 +1,7 @@ # ACDL sample consumer contract — static-assets module (qa) # Per-environment contract (REQ-105). Promotion = running the qa job; # no environment field editing. Interpolation resolves against qa.json. -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: static-assets environment: qa inputs: diff --git a/contracts/static-assets.yaml b/contracts/static-assets.yaml index 61649d8..6288906 100644 --- a/contracts/static-assets.yaml +++ b/contracts/static-assets.yaml @@ -15,7 +15,7 @@ # aws account id, and environment: # acdl-${env.environment}-${contract.module}-${env.account_id}-${env.region} -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: static-assets environment: dev inputs: diff --git a/docs/consumer-guide.md b/docs/consumer-guide.md index 1eec3cd..1967a66 100644 --- a/docs/consumer-guide.md +++ b/docs/consumer-guide.md @@ -19,7 +19,7 @@ definitions. ```mermaid flowchart LR - A["your repo
(app code + contracts + CI definitions)"] -->|uses: acdl/.github/workflows/deploy.yml@v1.6| B + A["your repo
(app code + contracts + CI definitions)"] -->|uses: acdl/.github/workflows/deploy.yml@v1.9| B B["platform runners
(modules + pipelines + adapters + schemas)"] -->|contract -> resolver -> stack -> adapter
-> security checks -> infrastructure plan -> policy checks
-> confidence -> apply -> evidence event| C C["your resources in AWS"] ``` @@ -27,7 +27,7 @@ flowchart LR ## Versioning the `uses:` reference The central deployment pipeline is **always versioned with floating MAJOR -and MINOR tags** (e.g. `acdl/pipelines/deploy.yaml@v1.6`). Version +and MINOR tags** (e.g. `acdl/pipelines/deploy.yaml@v1.9`). Version constraints cannot be expressed inside the contract, so the tag in `uses:` is the only immutability lever a consumer has. See [Versioning](pipeline/versioning) for the full rationale. @@ -47,7 +47,7 @@ platform-managed. See [Environments](environments/). environment is bound, your first pipeline run emits a friendly onboarding prompt. See [Environments](environments/). - **Authorization to reference the central pipeline.** Onboarding grants - your repo the right to `uses: acdl/.github/workflows/deploy.yml@v1.6`. + your repo the right to `uses: acdl/.github/workflows/deploy.yml@v1.9`. Contact the platform team if you have not been onboarded. ## Step 1 — Create a consumer repo @@ -92,7 +92,7 @@ In your contract YAML, declare `uses:` pointing at the central ACDL deployment pipeline with a **versioned tag** (floating MAJOR + MINOR): ```yaml -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 ``` This tells the platform to run the standard deployment pipeline: @@ -104,7 +104,7 @@ policy checks → confidence → evidence event → apply. Write `.acdl/contract.yaml`. The `static-assets` example: ```yaml -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: static-assets environment: dev inputs: @@ -115,7 +115,7 @@ inputs: A `microservice` example: ```yaml -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 module: microservice environment: dev inputs: @@ -129,7 +129,7 @@ inputs: | Field | Type | Required | Description | |-------|------|----------|-------------| -| `uses` | string | yes | Reference to the central deployment pipeline, **versioned** with a floating MAJOR+MINOR tag (e.g. `acdl/pipelines/deploy.yaml@v1.6`). Bare or `@main` references are discouraged. See [Versioning](pipeline/versioning). | +| `uses` | string | yes | Reference to the central deployment pipeline, **versioned** with a floating MAJOR+MINOR tag (e.g. `acdl/pipelines/deploy.yaml@v1.9`). Bare or `@main` references are discouraged. See [Versioning](pipeline/versioning). | | `module` | string | yes | Module name from the registry — any primitive or module (e.g. `static-assets`, `microservice`, `s3`). See the [module catalog](modules/). | | `environment` | string | yes | The platform-managed environment to deploy to (e.g. `dev`). See [Environments](environments/). | | `inputs` | object | yes | Module-specific inputs (see the module's README). | @@ -166,14 +166,14 @@ on: branches: [main] jobs: deploy: - uses: acdl/.github/workflows/deploy.yml@v1.6 + uses: acdl/.github/workflows/deploy.yml@v1.9 with: contract: .acdl/contract.yaml ``` That is the entire consumer-side workflow. When you push to `main`: -1. The platform runner resolves `uses: acdl/.github/workflows/deploy.yml@v1.6` +1. The platform runner resolves `uses: acdl/.github/workflows/deploy.yml@v1.9` to the reusable workflow **at the pinned tag**. 2. A **platform-provided runner** checks out **your** repo. 3. The runner checks out the **ACDL platform repo** into the workspace — @@ -281,7 +281,7 @@ push your container image to the ECR repo the platform created. Change `environment` in your contract (keeping the same versioned `uses:`): ```yaml -uses: acdl/pipelines/deploy.yaml@v1.6 +uses: acdl/pipelines/deploy.yaml@v1.9 environment: qa # QA attestation + confidence >= 0.75 ``` @@ -310,8 +310,8 @@ per-module extension points. Common examples: | Contract schema | `schemas/contract.schema.json` | JSON Schema for consumer contracts. | | Stack schema | `schemas/stack.schema.json` | JSON Schema for the resolved stack instance. | | Module catalog | [modules/](modules/) | All primitives and modules. | -| Sample contract | `contracts/static-assets.yaml` | The reference example contract (uses `@v1.6`). | -| Sample contract | `contracts/microservice.yaml` | The microservice example contract (uses `@v1.6`). | +| Sample contract | `contracts/static-assets.yaml` | The reference example contract (uses `@v1.9`). | +| Sample contract | `contracts/microservice.yaml` | The microservice example contract (uses `@v1.9`). | | Module examples | `modules//examples/` | Validated per-module example contracts (`simple.yaml` + `complex.yaml`). | | Contract resolver | `core/contract_resolver.py` | Resolves contracts to stack instances. | | Substrate adapter | `adapters/terraform/adapter.py` | Compiles stack instances to infrastructure. | diff --git a/tests/test_pipeline_contract.py b/tests/test_pipeline_contract.py index dccc065..fa709c3 100644 --- a/tests/test_pipeline_contract.py +++ b/tests/test_pipeline_contract.py @@ -376,7 +376,7 @@ class TestSampleContractVersioning: uses = contract["uses"] assert "@v" in uses, "sample contract must use a versioned @vX.Y tag" assert "@main" not in uses, "sample contract must not use @main" - assert uses == "acdl/pipelines/deploy.yaml@v1.6" + assert uses == "acdl/pipelines/deploy.yaml@v1.9" class TestPlatformWorkflows: