From 167a92f62186d2883699bff4c8ad0b4b8e71e425 Mon Sep 17 00:00:00 2001 From: Jon Chery Date: Tue, 21 Jul 2026 18:50:40 +0000 Subject: [PATCH] =?UTF-8?q?verify(P07):=20VERIFIED=20=E2=80=94=20architect?= =?UTF-8?q?ure=20v1.0=20finalized,=209=20files,=2011=20decisions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ---ci--- project: acdl phase: 7 milestone: v1.1 status: verify verdict: VERIFIED ---/ci--- Phase 07 architecture-v1-finalization verified on main (HEAD 8723206, tag v1.1.2). All four layers PASS: - Structural: 9 deliverable files present; architecture-v1.0.md status is v1.0; all 11 decision IDs + Q1.3 in the snapshot; gitea-runner rename (D-046) applied; §15 table lists the 6 REQ-mapped files; 3 JSON Schemas declare Draft 2020-12 with required fields per PLAN; 3 .py files have expected docstrings + public functions; history preserved (T-7.1 92d4535 is creation point); tags v1.1.0/v1.1.1/v1.1.2 all present. - Behavioral: scripts/verify_phase07.sh exits 0 with expected final line; typecheck gate (bash -n + py_compile) passes; schema cross-checks (qa/prod/dr/agentic negative cases, staging rejected, valid PCR passes) all pass; confidence_signal spot-checks (missing input -> block + INPUT_MISSING; critical fail -> 0.0 block + CRITICAL_OVERRIDE; cold-start dev -> 0.95 pass) all pass; SoD spot-checks (None outbox, None item, equal approvers, distinct, empty approver_qa) all pass; Checkov adapter spot-check (CKV_AWS_24 -> medium fail + ACDL_TAG_NAMING skipped appended) passes. - Security: no secrets in v1.1.1..v1.1.2 file set; no boto3 imports (stdlib only); platform/ shadow of stdlib platform documented + worked around in verify_phase07.sh (cd /tmp for jsonschema); LSP diagnostic on confidence_signal.py:148 confirmed false positive (py_compile + AST parse pass; runtime correct). - Quality: README layout table matches reality (platform/ + schemas/ now populated); all 7 Phase 07 commits carry ---ci--- blocks; ROADMAP Phase 07 = complete (v1.1.2); REQUIREMENTS REQ-16..22 = complete (v1.1.2); architecture-v1.0.md §15 files all exist; §13 resolutions match PROJECT.md decisions table. Requirements covered: REQ-16, REQ-17, REQ-18, REQ-19, REQ-20, REQ-21, REQ-22 (all 7 Phase 07 requirements; no partials). P1 flags (post-hoc, out of Phase 07 scope): - P1-1: platform/ package shadows stdlib platform module; v1.2 rename to acdl_platform/ (or src/ layout) would remove the workaround need. - P1-2: LSP false positive on confidence_signal.py:148 (Dict[str, Any] typing confuses pyright); py_compile + runtime correct; a v1.2 TypedDict tightening would silence it. --- .ciagent/VERIFY.md | 618 +++++++++++++++++++++++++++++++++------------ 1 file changed, 462 insertions(+), 156 deletions(-) diff --git a/.ciagent/VERIFY.md b/.ciagent/VERIFY.md index a410573..7e0b823 100644 --- a/.ciagent/VERIFY.md +++ b/.ciagent/VERIFY.md @@ -1,208 +1,514 @@ -# Phase 06 — archive-demo-and-reorient (v1.1.1) Verification +# Phase 07 — architecture-v1-finalization (v1.1.2) Verification -Verifying Phase 06 on `main` (HEAD `ecb2c78`, tag `v1.1.1`). Phase branch -`phase/06-archive-demo-and-reorient` deleted after merge. +Verifying Phase 07 on `main` (HEAD `8723206`, tag `v1.1.2`). Phase branch +`phase/07-architecture-v1-finalization` deleted after squash merge. + +Phase 07 was a **design-authoring phase**: it locked the ACDL architecture +to v1.0 by authoring 9 deliverable files (6 REQ-mapped schema/design +files + the Checkov adapter + the SoD module + the architecture-v1.0 +snapshot) that resolve all 11 open decisions in `docs/architecture.md` +§13 (W1.A, W1.B, W2.A, W3.D, W3.E, BA.A, BA.B, BA.C, BA.D, BA.E, BA.F + +the OpenTofu timing sub-decision Q1.3), recorded in `PROJECT.md` under +decisions D-034..D-046. + +Verification layers: structural, behavioral, security, quality. All +layers PASS. Final verdict: **Phase 07: VERIFIED**. ## Layer 1 — Structural: PASS -### Must-haves (PLAN.md) vs. file existence +### 1.1 All 9 deliverable files exist -| Must-have | Evidence | Status | -|-----------|----------|--------| -| `demo/` contains full v1.0 demo (`modules/`, `scripts/`, `evidence-ui/`, `contracts/`, `contracts-repo/`, `.gitea/workflows/`, `ACDL_DEMO.md`, `scripts/run_demo.sh`) | `ls demo/` shows all dirs + `demo/ACDL_DEMO.md` (11271 B) + `demo/scripts/run_demo.sh` | PASS | -| New top-level dirs scaffolded with `.gitkeep` (`platform/`, `schemas/`, `adapters/`, `terraform/`, `modules-ir/`) | `ls` confirms each dir exists with a 0-byte `.gitkeep` | PASS | -| Top-level `scripts/verify_phase06.sh` exists (NOT under `demo/scripts/`) | `ls scripts/` shows only `verify_phase06.sh` (2089 B); `demo/scripts/` holds v1.0 verify_phase01..05.sh | PASS | -| README contains "Agentic Cloud Delivery Platform", "demo/", vision/architecture reference | `README.md` line 1 = "ACDL — Agentic Cloud Delivery Platform"; line 10-11 link `docs/vision.md` + `docs/architecture.md`; line 37 references `demo/` | PASS | -| `.gitignore` contains `runner-data/` | `.gitignore` line 10 = `runner-data/` | PASS | -| No stray v1.0 dirs at repo root | `ls` root shows no `modules/`, `evidence-ui/`, `contracts/`, `contracts-repo/`, `ACDL_DEMO.md`, `.gitea/` | PASS | - -### Tags preserved - -`git tag --list 'v1.0*' 'v1.1*'`: ``` -v1.0.1 -v1.0.2 -v1.0.3 -v1.0.4 -v1.0.5 +$ ls -la docs/architecture-v1.0.md schemas/ir.schema.json \ + schemas/policy_check_result.schema.json schemas/contract.schema.json \ + adapters/terraform/policy/checkov_adapter.py platform/confidence_signal.py \ + platform/audit_ledger_design.md platform/hitl_matrix_design.md \ + platform/separation_of_duties.py scripts/verify_phase07.sh +-rw-r--r-- 1 root root 30167 Jul 21 18:48 docs/architecture-v1.0.md +-rw-r--r-- 1 root root 5538 Jul 21 18:48 schemas/ir.schema.json +-rw-r--r-- 1 root root 2484 Jul 21 18:48 schemas/policy_check_result.schema.json +-rw-r--r-- 1 root root 3924 Jul 21 18:48 schemas/contract.schema.json +-rw-r--r-- 1 root root 3578 Jul 21 18:48 adapters/terraform/policy/checkov_adapter.py +-rw-r--r-- 1 root root 5787 Jul 21 18:48 platform/confidence_signal.py +-rw-r--r-- 1 root root 5036 Jul 21 18:48 platform/audit_ledger_design.md +-rw-r--r-- 1 root root 6321 Jul 21 18:48 platform/hitl_matrix_design.md +-rw-r--r-- 1 root root 1835 Jul 21 18:48 platform/separation_of_duties.py +-rwxr-xr-x 1 root root 3831 Jul 21 18:48 scripts/verify_phase07.sh +``` + +All 9 REQ-mapped files + the verify script are present (sizes non-zero). + +### 1.2 `docs/architecture-v1.0.md` status line is v1.0 (not v0.2) + +``` +$ grep -n "Status:" docs/architecture-v1.0.md | head -3 +14: Status: **v1.0** (snapshot taken in ACDL Phase 07, milestone v1.1). All 11 +429: Status: **v1.0**. All 11 open items in §13 are resolved. ... +``` + +Status line at L14 says `v1.0` (Phase 07 bump); the upstream `v0.2` +status does not survive into the snapshot's status line. + +### 1.3 All 11 open-decision IDs + Q1.3 appear in the snapshot + +``` +$ grep -cE "W1\.A|W1\.B|W2\.A|W3\.D|W3\.E|BA\.A|BA\.B|BA\.C|BA\.D|BA\.E|BA\.F|Q1\.3" \ + docs/architecture-v1.0.md +33 +``` + +Every one of the 11 IDs + Q1.3 appears in both the resolution log table +(L26–37) and the §13 "✅ RESOLVED (see PROJECT.md)" markers (L75–425). +Each row carries the resolution text + a pointer to `PROJECT.md`. + +### 1.4 `gitea-runner` rename (D-046) applied; `act_runner` only in "formerly" note + +``` +$ grep -n "act_runner\|gitea-runner" docs/architecture-v1.0.md +9: > `act_runner` → `gitea-runner` rename (D-046, 2026-04 in gitea/runner#850) +10: > is applied; `act_runner` appears only in a "formerly" note. +352: > gitea-runner v2.1.0 (formerly `act_runner`, renamed 2026-04 in +``` + +`gitea-runner` is the body name; `act_runner` only appears in the +header note + the "formerly" parenthetical at L352. D-046 satisfied. + +### 1.5 §15 table lists all 6 REQ-mapped files + +``` +$ sed -n '441,455p' docs/architecture-v1.0.md +## 15. Phase 07 authored artifacts +... +| REQ | File | Owner persona | +|-----|------|--------------| +| REQ-17 | `schemas/ir.schema.json` | platform-engineer | +| REQ-18 | `schemas/policy_check_result.schema.json` + `adapters/terraform/policy/checkov_adapter.py` | security-engineer | +| REQ-19 | `platform/confidence_signal.py` | backend-engineer + security-engineer (co-authored) | +| REQ-20 | `platform/audit_ledger_design.md` | security-engineer | +| REQ-21 | `platform/hitl_matrix_design.md` + `platform/separation_of_duties.py` | security-engineer | +| REQ-22 | `schemas/contract.schema.json` | backend-engineer | +``` + +All 6 REQ rows + the 8 underlying files are listed. All §15 files +exist on disk (cross-checked with `os.path.exists` for every entry). + +### 1.6 The 3 JSON Schemas declare Draft 2020-12 + required fields + +``` +$ grep -n '\$schema\|draft/2020-12' schemas/*.schema.json +schemas/ir.schema.json:2: "$schema": "https://json-schema.org/draft/2020-12/schema", +schemas/policy_check_result.schema.json:2: "$schema": "https://json-schema.org/draft/2020-12/schema", +schemas/contract.schema.json:2: "$schema": "https://json-schema.org/draft/2020-12/schema", +``` + +Per-file required-fields check: + +- `schemas/ir.schema.json`: `required: [version, stack, resources]`; + `stack.depth` max 5; `stack.name` pattern `^l[12]-[a-z][a-z0-9-]*$`; + `stack.kind` enum `[l1, l2]`; `resource.module` pattern + `^l1-[a-z][a-z0-9-]*@\d+\.\d+\.\d+$` (W3.D name@semver); `relationship.kind` + enum `[parent, depends_on, uses_output]`; `shared_keyword` reserved + (present, unused). ✅ +- `schemas/policy_check_result.schema.json`: `required: [contractId, + evaluatedAt, engine, ruleId, severity, result, message, resourceRef]`; + `engine` enum `[checkov, kyverno, opa]`; `severity` enum `[critical, + high, medium, low, info]`; `result` enum `[pass, fail, skipped, error]`; + `evidence` optional with `additionalProperties: true`. ✅ +- `schemas/contract.schema.json`: top `required: [stack, environment]`; + `stack` pattern `^l2-[a-z][a-z0-9-]*$`; `environment` enum `[dev, qa, + prod, dr]` (no `staging`); `profile` enum `[developer, agentic]` + default `developer`; `allOf` conditionals present: qa→`[validation]`, + prod→`[runbook, dashboard, oncall]`, dr→`[drDrillRef]`, + agentic→`[naturalLanguageIntent]`. ✅ + +Substrate-agnostic invariant for IR schema: the only occurrence of +`aws_s3_bucket` is in the `$comment` (L6) and a `description` (L61) +where it is explicitly called out as the *non*-IR / *Terraform* type to +avoid. No Terraform-block keywords (`variable`/`output` as JSON keys, +`tf_block`) appear in the schema body. Invariant satisfied. + +### 1.7 The 3 .py files have expected module docstrings + public functions + +- `platform/confidence_signal.py` (REQ-19, T-7.9): module docstring + (L1–32) enumerates the 6 inputs + weights + severity→penalty + + per-env thresholds. Public surface: `WEIGHTS`, `PENALTY`, + `THRESHOLDS`, `Signal` dataclass, `_per_input_score`, `compute`, + `__main__` CLI. ✅ +- `platform/separation_of_duties.py` (REQ-21, T-7.8): module docstring + (L1–12) explains `qaApprover != prodApprover` + outbox read + spike + dev-only note. Public surface: `check(outbox_client, contract_id, + current_prod_approver)`, `route_halt_artifact(...)`. ✅ +- `adapters/terraform/policy/checkov_adapter.py` (REQ-18, T-7.5): module + docstring (L1–11) "Translate Checkov JSON output to ACDL + PolicyCheckResult records". Public surface: `RULE_MAP`, + `_iso8601_now`, `_to_pcr`, `_emit_tag_naming_skipped`, `adapt`, + `__main__` CLI. ✅ + +### 1.8 History preservation — `docs/architecture-v1.0.md` is a new file + +``` +$ git log --follow --oneline docs/architecture-v1.0.md +92d4535 phase: 7, status: plan-as-execute, persona: lead-developer, task: T-7.1 +``` + +Single creation commit (T-7.1, 92d4535). As expected for a new file — +the upstream `docs/architecture.md` (52665b8 → b84a8a2) history is +preserved on the upstream file itself; the snapshot is intentionally a +new file, not a copy-with-rename. + +### 1.9 Tags v1.1.0, v1.1.1, v1.1.2 all exist + +``` +$ git tag --list 'v1.1*' v1.1.0 v1.1.1 +v1.1.2 ``` -All v1.0 tags (v1.0.1..v1.0.5) preserved + v1.1.0 + v1.1.1 present. - -### History preservation - -`git log --follow --oneline demo/scripts/run_demo.sh`: -``` -e044a2d phase: 6, status: plan-as-execute, persona: lead-developer, task: T-6.1..T-6.4 -0672edf ship: phase-05 evidence-ui-and-demo-dry-run (v1.0.5) -``` -`git mv` preserved history — the trail traces back through the v1.0.5 ship commit. ## Layer 2 — Behavioral: PASS -### Typecheck gate +### 2.1 `scripts/verify_phase07.sh` exits 0 with the expected final line ``` -bash -n demo/scripts/*.sh && echo "demo shell syntax ok" → ok -python3 -m py_compile demo/scripts/*.py && echo "demo python compile ok" → ok -bash -n scripts/verify_phase06.sh && echo "verify_phase06 syntax ok" → ok +$ bash scripts/verify_phase07.sh +ok: all 9 deliverable files exist +ok: 3 JSON Schemas validate as Draft 2020-12 +ok: 3 .py files py_compile +ok: 3 .md design files non-empty +ok: all 11 decision IDs + OpenTofu present in PROJECT.md +ok: docs/architecture-v1.0.md status is v1.0 +ok: D-040..D-044 present in PROJECT.md +ok: spike contract validates against contract schema +ok: minimal IR validates against IR schema +VERIFIED — Phase 07: architecture v1.0 finalized; 6 files authored + 11 decisions resolved + +$ echo $? +0 ``` -### Test gate (`scripts/verify_phase06.sh`) +All 9 assertions in the script pass; final line matches PLAN.md spec. + +### 2.2 Typecheck gate ``` -ok: demo/ contains the full v1.0 demo -ok: demo/scripts/run_demo.sh --no-upload exits 0 -ok: new top-level dirs exist: platform/ schemas/ adapters/ terraform/ modules-ir/ -ok: no stray v1.0 dirs at repo root -ok: README reflects the real platform (name + demo/ ref + vision/arch links) -Phase 06: ALL CHECKS PASS -EXIT=0 +$ bash -n scripts/verify_phase07.sh && \ + python3 -m py_compile platform/confidence_signal.py \ + platform/separation_of_duties.py \ + adapters/terraform/policy/checkov_adapter.py +TYPECHECK_OK ``` -### audit.json regression shape +`bash -n` (syntax) + `py_compile` (byte-compile) all pass. -`demo/scripts/run_demo.sh --no-upload` writes a non-empty, hash-chained -`audit.json` to `/tmp/acdl_demo_run/audit.json` (3180 B). Inspected content: -```json +### 2.3 Schema cross-checks (PLAN.md self-verify test instances) + +Run from `/tmp` to avoid the repo `platform/` package shadowing stdlib +`platform` (see Layer 3 §3.3): + +``` +OK: qa without validation fails +OK: prod without runbook fails +OK: dr without drDrillRef fails +OK: agentic without NLI fails +OK: agentic with NLI passes +OK: staging rejected +OK: valid PCR passes +ALL_SCHEMA_CROSSCHECKS_OK +``` + +`environment` enum confirmed `[dev, qa, prod, dr]` — no `staging` +(Path A locked, ARCHITECTURE.md §5). Per-env mandatory conditionals all +fire correctly. + +### 2.4 Confidence signal behavioral spot-checks (REQ-19) + +Run from `/tmp` with `sys.path.insert(0, '/root/acdl')`: + +- **Missing input → block + INPUT_MISSING:** `compute('cid','dev', inputs)` + with `nfrs` omitted returns `Signal(0.0, "block", {}, ["INPUT_MISSING:nfrs"])`. ✅ +- **Critical fail → 0.0 block + CRITICAL_OVERRIDE:** `compute('cid','dev', inputs)` + with one `severity:"critical", result:"fail"` PolicyCheckResult returns + `Signal(0.0, "block", per_input, ["CRITICAL_OVERRIDE:CKV_AWS_X"])` + regardless of other inputs. ✅ +- **Cold-start dev → pass ≥ 0.50:** `compute('cid','dev', inputs)` with + the ACDL_TAG_NAMING `skipped` PolicyCheckResult + all validation true + + neutral 0.5 for freshness/source/history/nfrs returns + `Signal(0.950, "pass", ...)`. ✅ (0.95 ≥ 0.50 dev threshold). + +Note: the `WEIGHTS` dict keys are `policy / validation / freshness / +source / history / nfrs` (the canonical names), not the docstring's +`policy_results` label — the docstring describes the input's *type* +("list[PolicyCheckResult]"); the `compute()` loop iterates +`WEIGHTS.items()` and reads `inputs.get("policy")` (the key). This is +consistent with the Wave 4 self-verify ("`policy_results`" in the +docstring is the descriptive label, `policy` is the dict key — verified +at runtime). + +### 2.5 Separation-of-duties behavioral spot-checks (REQ-21) + +- `check(None, "cid", "anyone")` → `(True, "no outbox client (dev-only spike)")`. ✅ +- `check(stub_returning_None, "cid", "anyone")` → `(True, "no prior approver (first promotion)")`. ✅ +- `check(stub_with_approver_qa("alice"), "cid", "alice")` → `(False, "SEPARATION_OF_DUTIES_VIOLATION: qaApprover==prodApprover==alice")`. ✅ +- `check(stub_with_approver_qa("alice"), "cid", "bob")` → `(True, "distinct")`. ✅ +- `check(stub_with_empty_approver_qa, "cid", "alice")` → `(True, "no QA approver recorded (dev-only spike)")`. ✅ + +All SoD branches match PLAN.md T-7.8 spec. + +### 2.6 Checkov adapter behavioral spot-check (REQ-18 adapter) + +Synthetic Checkov JSON with one failed `CKV_AWS_24`: + +``` +$ python3 adapters/terraform/policy/checkov_adapter.py fixture.json test-contract-id [ - { "seq": 0, "stage": "genesis", "prev_hash": "GENESIS", - "hash": "dad5926c4f2f1af482613c09dc50ad10177ac7522ae571b2ffc7bdfaa5063a67" }, - { "seq": 1, "stage": "dev", - "prev_hash": "dad5926c4f2f1af482613c09dc50ad10177ac7522ae571b2ffc7bdfaa5063a67", - "hash": "de62f008f205e96cf334e9040853e8869f0146ebeab0cdfddca914c6b5be8e19" }, - ... + { + "contractId": "test-contract-id", + "evaluatedAt": "2026-07-21T18:49:11Z", + "engine": "checkov", + "ruleId": "CKV_AWS_24", + "severity": "medium", ← per RULE_MAP (public-ingress SG 0.0.0.0/0) + "result": "fail", + "message": "SG 0.0.0.0/0 on 22", + "evidence": {"file_path": null, "resource": "aws_security_group.r1", + "resource_address": "aws_security_group.r1", "code_block": null}, + "resourceRef": "aws_security_group.r1" + }, + { + "contractId": "test-contract-id", + "ruleId": "ACDL_TAG_NAMING", ← D-043 appended SKIPPED record + "severity": "info", + "result": "skipped", + "message": "tag/naming check deferred to v1.2 (D-043)", + "evidence": {}, + "resourceRef": "" + } ] ``` -Hash chain intact (each `prev_hash` = prior event's `hash`). Demo regression -satisfied end-to-end from `demo/`. + +Severity correctly defaulted to `medium` for `CKV_AWS_24` from `RULE_MAP`; +`ACDL_TAG_NAMING` SKIPPED record appended (D-043). Both records validate +against `schemas/policy_check_result.schema.json`. ## Layer 3 — Security: PASS -### No credentials/secrets introduced +### 3.1 No credentials/secrets introduced -`git log v1.1.0..v1.1.1 --name-only` (sorted, filtered for secret-like -patterns `.env*|tfstate|*_key|secret|credential|*.pem|id_rsa`) → no matches. -The Phase 06 diff is exclusively: -- moves (`git mv` carries 100% renames: `*.gitkeep`, pipeline.yml, - `index.html`, `manifest.yaml`, `mock_apply.sh`, demo scripts, contracts) -- new scaffold files (`platform/.gitkeep`, `schemas/.gitkeep`, - `adapters/.gitkeep`, `terraform/.gitkeep`, `modules-ir/.gitkeep`) -- `scripts/verify_phase06.sh` (new) -- `README.md` (rewritten), `.gitignore` (+`runner-data/`) -- `demo/ACDL_DEMO.md` (newly tracked, was untracked v1.0 artifact) -- `.ciagent/ROADMAP.md` (status update) +Files touched by Phase 07 (v1.1.1..v1.1.2): -No `.env`, no `*.tfstate`, no `*_key*` files committed. Phase 06 is repo -hygiene only — no AWS/TF code introduced (correctly deferred to Phase 08+). +``` +$ git log v1.1.1..v1.1.2 --diff-filter=A --name-only --pretty=format: | sort -u +.ciagent/PLAN.md +.ciagent/REQUIREMENTS.md +.ciagent/ROADMAP.md +.ciagent/VERIFY.md +adapters/terraform/policy/__init__.py +adapters/terraform/policy/checkov_adapter.py +docs/architecture-v1.0.md +platform/__init__.py +platform/audit_ledger_design.md +platform/confidence_signal.py +platform/hitl_matrix_design.md +platform/separation_of_duties.py +schemas/contract.schema.json +schemas/ir.schema.json +schemas/policy_check_result.schema.json +scripts/verify_phase07.sh +``` -### LSP error in `demo/scripts/finalize_evidence.py:46` is pre-existing +No `.env`, no `*.tfstate`, no `*_key*`, no `credentials*` files. Phase 07 +is design authoring + stdlib-only Python — no AWS/TF runtime calls, no +boto3 imports (the spike passes a duck-typed `outbox_client`). + +### 3.2 LSP diagnostic on `platform/confidence_signal.py:148` is a false positive -`git log -1 --format='%H %s' demo/scripts/finalize_evidence.py`: ``` -e044a2de0d7cedf57949413459992fa1859f350b phase: 6, status: plan-as-execute, persona: lead-developer, task: T-6.1..T-6.4 +$ python3 -m py_compile platform/confidence_signal.py +$ python3 -c "import ast; ast.parse(open('platform/confidence_signal.py').read()); print('AST parse OK')" +AST parse OK ``` -The `e044a2d` commit is the *move* commit (T-6.1..T-6.4) — it only performed -`git mv scripts/finalize_evidence.py demo/scripts/finalize_evidence.py`, -no content edit. `git log -1 --format='%H %s' -L 46,46:demo/scripts/finalize_evidence.py`: + +At L148, `p = PENALTY.get(sev, 0.0)` — `sev` comes from +`pcr.get("severity")` where `pcr` is `Dict[str, Any]`. The LSP +("No overloads for `get` match the provided arguments") is a known +false-positive when `.get()` is called on a `Dict[str, Any]` value +in some pyright configurations. `py_compile` passes; runtime behavior +is verified correct in §2.4 (the critical-override branch returns the +expected `CRITICAL_OVERRIDE:` and the `None` sentinel correctly +short-circuits via `if p is None:` at L149). Not a real bug. + +### 3.3 `platform/` package shadows stdlib `platform` — documented + worked around + +The repo's `platform/` Python package (our code) shadows the stdlib +`platform` module when the repo root is on `sys.path[0]` (which a +`python3 -c` invocation from repo root triggers). `jsonschema` imports +`uuid` → `uuid` imports `platform.system()` → fails with +`AttributeError: module 'platform' has no attribute 'system'`. + +`scripts/verify_phase07.sh` documents this and works around it by +running all `jsonschema`-invoking python from `/tmp` with absolute +paths to the schemas: + ``` -72b359c9a902b035c8a5816437d38aba808b948e ship: phase-04 pipeline-and-approval-gates (v1.0.4) +$ grep -n "platform\|cd /tmp\|sys.path\|shadow" scripts/verify_phase07.sh +24: # Run python from /tmp so the repo's `platform/` package does not shadow the +25: # stdlib `platform` module (jsonschema imports uuid -> platform.system(); +26: # our platform/ shadows it when cwd is repo root and on sys.path[0]). +28: ( cd /tmp && python3 -c "..." ) +70: ( cd /tmp && python3 -c "..." ) +78: ( cd /tmp && python3 -c "..." ) ``` -Line 46 was authored in the v1.0.4 ship commit (Phase 04, demo). Any LSP -finding on that line is **pre-existing v1.0 demo code**, not a Phase 06 -regression. Per the plan, the v1.0 demo is archived as-is (intent reference; -frozen). No action. + +The workaround is correct: `cwd=/tmp` puts `/tmp` at `sys.path[0]`, so +`import platform` resolves to the stdlib, not our package; the schemas +are passed by absolute path. The verify script passes (§2.1), and my +inline behavioral spot-checks (§2.3–2.5) reproduced the workaround by +running from `/tmp` + `sys.path.insert(0, '/root/acdl')` to import our +modules explicitly. + +**P1 — flag for post-hoc cleanup:** a v1.2 rename of `platform/` to +`acdl_platform/` (or moving the package under a `src/` layout) would +avoid the shadowing entirely, removing the need for the `/tmp` dance in +every jsonschema-invoking test. This is out of Phase 07 scope (Phase 07 +must ship the `platform/` layout the README + PLAN.md committed to). +Flagged for v1.2. + +### 3.4 No `import boto3` in the Phase 07 .py files + +``` +$ grep -nE "^import |^from " platform/confidence_signal.py \ + platform/separation_of_duties.py \ + adapters/terraform/policy/checkov_adapter.py +platform/confidence_signal.py:34: from dataclasses import dataclass, asdict +platform/confidence_signal.py:35: from typing import List, Literal, Optional, Dict, Any +platform/confidence_signal.py:36: import json +platform/confidence_signal.py:37: import sys +platform/separation_of_duties.py:14: from typing import Optional, Tuple +adapters/terraform/policy/checkov_adapter.py:13: import datetime +adapters/terraform/policy/checkov_adapter.py:14: import json +adapters/terraform/policy/checkov_adapter.py:15: import sys +``` + +Stdlib only across all 3 modules. The SoD `check()` signature receives +a duck-typed `outbox_client` (has `.get(pk)`); the pipeline step owns the +boto3 client. PLAN.md T-7.8 spec satisfied. ## Layer 4 — Quality: PASS -### README link targets exist +### 4.1 README layout table still matches reality -| README link | Target file | Exists? | -|-------------|-------------|---------| -| `docs/vision.md` | `docs/vision.md` | PASS | -| `docs/architecture.md` | `docs/architecture.md` | PASS | -| `.ciagent/PROJECT.md` | `.ciagent/PROJECT.md` | PASS | -| `.ciagent/ARCHITECTURE.md` | `.ciagent/ARCHITECTURE.md` | PASS (15894 B) | -| `.ciagent/ROADMAP.md` | `.ciagent/ROADMAP.md` | PASS | -| `demo/ACDL_DEMO.md` | `demo/ACDL_DEMO.md` | PASS | - -No broken links. - -### Commit `---ci---` blocks - -Inspected `git log v1.1.0..v1.1.1` (4 commits). Each carries a `---ci---` -block with required fields: - -- `ecb2c78` (ship merge): project, phase, milestone, status: shipped, - release.tag: v1.1.1 ✓ -- `4ab15cb` (post-ship docs): project, phase, milestone, status: shipped, - requirements.complete: [], release.tag: v1.1.1 ✓ -- `e044a2d` (plan-as-execute T-6.1..T-6.4): project, phase, milestone, - status: plan-as-execute, persona: lead-developer, tasks: [T-6.1..T-6.4] ✓ -- `b927f90` (plan): project, phase, milestone, status: plan, plan.waves: 3, - plan.tasks: 6, plan.requirements: [] ✓ - -(Plus pre-phase commits `930c24b` research, `087c89e` clarify, `288607b` -specify — all carry `---ci---` blocks with project/phase/milestone/status.) - -### ROADMAP.md Phase 06 status - -`.ciagent/ROADMAP.md` line 83: ``` -- **Status:** complete (v1.1.1) +$ grep -n "platform/\|schemas/\|adapters/" README.md +31: | `platform/` | Platform code: confidence signal, contract resolver, outbox, HITL/ledger designs | Phase 07+ | +32: | `schemas/` | JSON Schemas: IR, PolicyCheckResult, contract | Phase 07 | +33: | `adapters/` | Substrate adapters (Terraform adapter in v1; the only substrate-specific code per §12) | Phase 09 | ``` -Matches the shipped tag `v1.1.1`. -## Requirement coverage +README's "Phase 07+" and "Phase 07" annotations are now accurate — +`platform/` and `schemas/` are populated with the 9 deliverable files +(no longer just `.gitkeep`'d). `adapters/` is annotated "Phase 09" +which is also accurate: only the `policy/` subdirectory is populated in +Phase 07 (the Checkov adapter, REQ-18), and the rest of the adapter +surface (the IR→Terraform module compiler) is Phase 09. -Phase 06 introduces **no new REQ** (PLAN.md frontmatter `requirements: []`; -ROADMAP §Phase 06 "Requirements: (no new REQ; repo hygiene)"). Nothing to -mark covered/partial this phase. +### 4.2 Phase 07 commit messages all carry `---ci---` blocks -## Auto-generated test coverage +Phase 07 commits on main (v1.1.1..v1.1.2): -`scripts/verify_phase06.sh` IS the auto-generated test. Coverage audit -against PLAN.md must_haves: +``` +8723206 ship: phase-07 architecture-v1-finalization (v1.1.2) +412e1ef phase: 7, status: plan-as-execute, persona: lead-developer, task: T-7.10 +68d90c0 phase: 7, status: plan-as-execute, persona: backend-engineer+security-engineer, task: T-7.9 +6ed93f0 phase: 7, status: plan-as-execute, persona: security-engineer, task: T-7.4..T-7.8 +f8e99ed phase: 7, status: plan-as-execute, persona: platform-engineer+backend-engineer, task: T-7.2+T-7.3 +92d4535 phase: 7, status: plan-as-execute, persona: lead-developer, task: T-7.1 +b40aadd docs(P07): create Phase 07 plan (architecture-v1-finalization) +``` -| PLAN must_have | verify_phase06.sh check | -|----------------|--------------------------| -| demo/ contains full v1.0 demo | Check 1 (dirs + ACDL_DEMO.md + run_demo.sh) | -| run_demo.sh --no-upload exits 0 | Check 2 (regression) | -| New top-level dirs + .gitkeep | Check 3 | -| Top-level scripts/verify_phase06.sh | (the script itself exists) | -| README reflects real platform | Check 5 (name + demo/ ref + vision/arch links) | -| .gitignore runner-data/ | (not asserted by script — see P1 below) | -| No stray v1.0 dirs at root | Check 4 | +Each execute commit + the ship commit carries a `---ci---` block with +`project / phase / milestone / status / persona / task` (execute commits) +or `release.tag` (ship commit). Verified by inspecting commit bodies +(`git log v1.1.1..v1.1.2 --pretty=format:'%H %s%n---%n%b%n---'`): +T-7.1, T-7.2+7.3, T-7.4..7.8, T-7.9, T-7.10, and the merge all include +well-formed `---ci---` blocks. ✅ -**Minor coverage gap (P1, not P0):** the verify script does not assert -`.gitignore` contains `runner-data/`. The must_have is satisfied (file -content verified manually) but not gated. Not auto-fixed — the plan -instructs verifiers to "extend it only if a must_have is uncovered"; -the must_have *is* satisfied (file exists with the entry), so it is -covered structurally, only the assertion is missing. Flagged for -post-hoc review; could be added as a 6th check in a future touch-up. +### 4.3 `ROADMAP.md` Phase 07 status = "complete (v1.1.2)" -## P0/P1 issues +``` +$ grep -n "Phase 07\|complete.*v1.1.2\|status" .ciagent/ROADMAP.md | head -5 +91: ### Phase 07 — architecture-v1-finalization +93: - **Status:** complete (v1.1.2) +``` -- **P0:** none. -- **P1 (post-hoc, non-blocking):** - - `scripts/verify_phase06.sh` does not programmatically assert - `runner-data/` is in `.gitignore`. The must-have is satisfied - structurally; only the assertion is absent. Recommend adding a - `grep -q '^runner-data/$' .gitignore` line in a future touch-up. - - The LSP finding on `demo/scripts/finalize_evidence.py:46` is - pre-existing v1.0 demo code (Phase 04 authorship, Phase 06 only moved - it). No Phase 06 regression. Archived demo is frozen per D-037; no - action required. +### 4.4 `REQUIREMENTS.md` traceability — REQ-16..22 complete (v1.1.2) + +``` +$ grep -n "REQ-1[6-9]\|REQ-2[0-2]" .ciagent/REQUIREMENTS.md | tail -7 +117: | REQ-16 | 07 | complete (v1.1.2) | +118: | REQ-17 | 07 | complete (v1.1.2) | +119: | REQ-18 | 07 | complete (v1.1.2) | +120: | REQ-19 | 07 | complete (v1.1.2) | +121: | REQ-20 | 07 | complete (v1.1.2) | +122: | REQ-21 | 07 | complete (v1.1.2) | +123: | REQ-22 | 07 | complete (v1.1.2) | +``` + +All 7 Phase 07 requirements marked complete at v1.1.2. + +### 4.5 `docs/architecture-v1.0.md` internal consistency + +- The §15 table's 6 files (8 underlying paths) all exist on disk + (verified via `os.path.exists` for every entry). ✅ +- The 11 resolutions in the §13 markers (L75–425) match the + `PROJECT.md` "Open-decision resolutions" table (L178–189) verbatim + (W1.A, W1.B, W2.A, W3.D, W3.E, BA.A, BA.B, BA.C, BA.D, BA.E, BA.F) + + the Q1.3-OpenTofu sub-decision. ✅ +- Decisions D-034..D-046 all present in `PROJECT.md` (the decision + table at L160–172). ✅ + +## Issues found + +### P0 (blocking) — none + +No P0 issues. All must-haves from PLAN.md are satisfied; the phase gate +`scripts/verify_phase07.sh` is green; behavioral spot-checks all pass. + +### P1 (post-hoc cleanup, out of Phase 07 scope) + +- **P1-1: `platform/` package shadows stdlib `platform`.** The repo's + `platform/` directory is a Python package that shadows the stdlib + `platform` module when the repo root is on `sys.path` (any `python3 -c` + from repo root). This breaks `jsonschema` (which imports `uuid` → + `platform.system()`). `scripts/verify_phase07.sh` works around it by + running jsonschema-invoking python from `/tmp`, but the workaround is + brittle — every future test script that imports `jsonschema` (or any + stdlib module that transitively imports `platform`) from repo root + will hit the same shadow. Recommended v1.2 fix: rename `platform/` → + `acdl_platform/` (or adopt a `src/` layout) so the package no longer + collides with the stdlib name. Out of Phase 07 scope (the layout is + locked by Phase 06 + README + PLAN.md). + +- **P1-2: LSP false positive on `platform/confidence_signal.py:148`.** + The "No overloads for `get` match the provided arguments" diagnostic + is a pyright false positive triggered by `Dict[str, Any]` typing on + `pcr`. `py_compile` passes; runtime behavior is correct (verified in + §2.4). No fix needed in Phase 07; if a v1.2 type tightening pass + happens, replacing `Dict[str, Any]` with a `TypedDict` for + `PolicyCheckResult` would silence the LSP and improve type safety. + +## Requirement coverage summary + +| REQ | File(s) | Status | +|-----|---------|--------| +| REQ-16 | `docs/architecture-v1.0.md` | covered (v1.1.2) | +| REQ-17 | `schemas/ir.schema.json` | covered (v1.1.2) | +| REQ-18 | `schemas/policy_check_result.schema.json` + `adapters/terraform/policy/checkov_adapter.py` | covered (v1.1.2) | +| REQ-19 | `platform/confidence_signal.py` | covered (v1.1.2) | +| REQ-20 | `platform/audit_ledger_design.md` | covered (v1.1.2) | +| REQ-21 | `platform/hitl_matrix_design.md` + `platform/separation_of_duties.py` | covered (v1.1.2) | +| REQ-22 | `schemas/contract.schema.json` | covered (v1.1.2) | + +All 7 Phase 07 requirements covered. No partials. ## Final verdict -**Phase 06: VERIFIED** - -All four layers pass. The v1.0 demo is fully archived under `demo/` with -history preserved; the v1.1 top-level layout is scaffolded; the README -reflects the real platform; the regression gate -(`demo/scripts/run_demo.sh --no-upload`) runs end-to-end from `demo/` -with an intact hash chain; no secrets were introduced; commit metadata -is complete; ROADMAP status is correct. \ No newline at end of file +Phase 07: VERIFIED \ No newline at end of file