---ci--- project: acdl phase: 0 milestone: v1.1 status: review verdict: READY TO SHIP p0: 0 p1: 1 ---/ci---
11 KiB
ACDL v1.1 Milestone — Multi-Persona Code Review
Reviewer: ci-code-reviewer (model: glm-5.2)
Scope: v1.1 milestone — Phases 06–10 (tags v1.1.1..v1.1.5), diff v1.1.0..HEAD
Date: 2026-07-21
Verdict: READY TO SHIP — 0 P0, 1 P1 (carried-forward), 0 P2 new
Lens 1 — Correctness
The schemas + Python modules + Terraform implement what the decisions +
ARCHITECTURE.md committed. Spot-checks all pass.
Findings
schemas/ir.schema.json(REQ-17): resources / relationships / composition (max-depth-5) / policy hooks (via PolicyCheckResult consumer) all present per §12.1. Substrate-agnostic:aws_s3_bucketappears ONLY in$commentanddescriptionstrings (which explain the IR→Terraform mapping); it does NOT appear in any constraining keyword (enum/const/pattern/required). The schema body uses IR types (aws:s3:bucket). Correct.schemas/contract.schema.json(REQ-22, W3.E): per-env mandatory viaallOfif/then — qa requiresvalidation.e2eSuite+validation.loadTest; prod requiresrunbook+dashboard+oncall; dr requiresdrDrillRef. Theprofile:agenticconditional isif: {required:[profile], profile:{const:agentic}}→then: {required:[naturalLanguageIntent]}— this is the fixed form (requiresprofileto be present before checkingconst), not the Phase 07 initial bug. Verified: prod-missing-runbook rejected; agentic-without-NLI rejected; qa-without-validation rejected; dr-without-drDrillRef rejected; dev + agentic-with-NLI accepted. Correct.acdl_platform/confidence_signal.py(REQ-19, D-040):WEIGHTSsum to 1.0 (verified: 0.30+0.25+0.10+0.15+0.10+0.10 = 1.0).PENALTY["critical"] = None(hard-override sentinel). The critical-override short-circuit (if p is None: return Signal(0.0, "block", ...)) returns BEFORE thescore = max(0.0, min(1.0, base - penalty))clamp. Dev-warn→block flip present (if environment == "dev" and band == "warn": band = "block"). Thepolicyinput key is read asinputs.get("policy")(notpolicy_results) — matches the Phase 10 e2erun_spike_e2e.shwhich passesinputs = {"policy": pcr, ...}. Adversarial test: a critical-fail PCR →score=0.0 band=block reasons=['CRITICAL_OVERRIDE:...']. Correct.acdl_platform/contract_resolver.py(REQ-27):resolve()loads YAML → validates againstcontract.schema.json→ looks up L2 in registry → loadscomposition.json→ maps wires → emits IR → validates againstir.schema.json. Wire mapping verified:contract.inputs.bucket_name→child.inputs.bucket_nameviawires.bucket_name.{target:s3, input:bucket_name}. Resolved spike IR hasresources[0].inputs = {bucket_name: acdl-spike-bucket, region: us-east-1}. Prod-missing-runbook raisesjsonschema.ValidationError(not a generic ValueError). Correct.acdl_platform/outbox_writer.py(D-044, D-P10-3): SHA-256 over canonical JSON (sort_keys=True, separators=(",", ":")).prev_event_hashdefaults to"GENESIS". DynamoDB item shape: PKcontractId(S), SKeventType#eventTs(S), TTLexpire_at(N, now+365d). Append-only (put_itemonly; 0delete_item/update_item). Correct.adapters/terraform/adapter.py(REQ-26, D-P10-1):TYPE_MAP = {aws:s3:bucket -> aws_s3_bucket}. Backend key derived from stack name:spike/l2-static-asset/terraform.tfstate(verified). Unknown IR type raisesValueError. Resources array handling is shape-driven (iteratesir_instance["resources"]; works for both l1 and l2 IR). Correct.adapters/terraform/policy/checkov_adapter.py(REQ-18, D-043):RULE_MAPhas exactly 11 Checkov rule IDs (CKV_AWS_41/45/46/20/57/24/25/1/40/7/33). TheACDL_TAG_NAMINGSKIPPED record is appended (severity: info, result: skipped). Tolerates both Checkov JSON shapes — nested{framework: {results: {...}}}and legacy{framework: {passed_checks:...}}(theresults = body.get("results", body)fallback). Correct.
Verdict: PASS — no issues.
Lens 2 — Testing
The verify scripts are real gates that fail on regression, not presence checks.
Findings
scripts/verify_phase07.sh: Check 2 usesjsonschema.Draft202012Validator.check_schema(...) || fail— actually validates the 3 schemas as Draft 2020-12 (fails if a schema is broken). Check 8 cross-checks the spike contract againstcontract.schema.jsonviajsonschema.validate(...) || fail. Check 9 cross-checks a minimal IR againstir.schema.json. Every check has|| fail. Real gate.scripts/verify_phase10.sh: 8 checks, each with|| fail. Check (h) is the REQ-28 substrate-agnostic scan. Synthetic leak test performed: appendedLEAK = "aws_s3_bucket"toacdl_platform/separation_of_duties.pyand ran the Check (h) grep — it caught the leak (acdl_platform/separation_of_duties.py:44: LEAK = "aws_s3_bucket"), then reverted. The check also scansmodules-ir/JSON foraws_*resource-type VALUES (excludingdescription/$commentstrings). Real gate.scripts/run_spike_e2e.sh+scripts/run_spike_plan.sh: touch real AWS —terraform init/validate/plan -lock=false+checkov+ DynamoDBput_item/query. NOT stubbed (the spike key is loaded from gitignored.env.secrets). The e2e runner uses|| failon every step, so a DynamoDB outage or terraform failure exits 1 (verified: outbox write failure propagates via|| fail "outbox write failed"). Real e2e.
Verdict: PASS — no issues.
Lens 3 — Security
AWS key handling (D-034/D-039), IAM least-privilege, gitignore discipline, no secrets in commits. All clean.
Findings
- No leaked key IDs in executable code:
git log v1.1.0..HEAD -p | grep -iE "AKIA[A-Z0-9]{16}" | grep -v "^#"returns matches ONLY inside.ciagent/VERIFY.md(the Phase 09 narrative — the carried-forward P1-1). No.py,.tf,.json,.yaml, or.shfile contains anAKIA…key ID. Clean. - No leaked secret keys:
git log v1.1.0..HEAD -p | grep -iE "aws_secret_access_key.*=.*[A-Za-z0-9/+=]{40}" | grep -v "^#"returns nothing. Clean. terraform/bootstrap/spike_runner_policy.json(REQ-23): least-privilege. Allow actions:s3:{PutObject,GetObject,DeleteObject,ListBucket,GetBucketLocation,GetBucketVersioning}dynamodb:{GetItem,PutItem,DeleteItem,UpdateItem,Query,Scan,DescribeTable}sts:GetCallerIdentity. Noiam:*, noec2:*, nos3:CreateBucket, nos3:DeleteBucket, noterraform apply(apply is out of spike scope).DenyEverythingElseNotResourcelists exactly 3 ARNs (state bucket + bucket objects + outbox table); everything else is denied. Correct.
- Gitignore discipline:
.env.secrets,terraform/bootstrap/.bootstrap_state.json,terraform/spike/.terraform/,terraform/spike/.terraform.lock.hcl,terraform/spike/tfplan,terraform/spike/*.tfstate*all gitignored (git check-ignoreconfirms each). Correct. - Outbox write is append-only:
grep -c "delete_item|update_item" outbox_writer.py= 0 (onlyput_item). Correct. - E2E runner is plan-only:
grep -c "terraform apply" run_spike_e2e.sh= 0 (onlyinit + validate + plan). Correct.
P1 (carried-forward, NOT auto-fixed)
- P1-1: The
.ciagent/VERIFY.mdPhase 09 narrative contains two AWS access key IDs —AKIAYOZHMKZ7RK26N66W(the rotated spike key id) andAKIAYOZHMKZ772SINHFX(the deactivated root key id). Confirmed still present (grep -creturns 2). These are public identifiers, not secret pairs; they live in the.ciagent/audit narrative, not in any executable code path. Recommended for a future hygiene redaction pass (replace withAKIA…SPIKE/AKIA…ROOT-DEACTIVATEDplaceholders). Non-blocking for v1.2 ship; flagged for post-hoc review.
Verdict: PASS — 1 carried-forward P1 (non-blocking).
Lens 4 — Performance
Not a concern for the spike (plan-only, single resource, no load). Skipped.
Lens 5 — Maintainability
The acdl_platform/ rename, substrate-agnostic boundary, and decision trail
are all consistent.
Findings
acdl_platform/rename (Phase 08 prep, fixing the stdlibplatformshadow): consistently applied acrossscripts/verify_phase06.sh,scripts/verify_phase07.sh,README.md, and the Python imports (import acdl_platform.confidence_signal as cinrun_spike_e2e.sh).grep -l acdl_platformconfirms all three files reference the renamed dir. Consistent.- Decision trail: every schema/module cites its source. Sampled 3 files:
acdl_platform/confidence_signal.pycitesREQ-19,D-040,ARCHITECTURE.md §8.acdl_platform/contract_resolver.pycitesARCHITECTURE.md §12.8.schemas/ir.schema.jsoncitesARCHITECTURE.md §12.1,§3,W3.D. Citations present.
- Spike-vs-v1.2 boundary documented in each design doc:
acdl_platform/audit_ledger_design.md,acdl_platform/hitl_matrix_design.md, and.ciagent/PLAN.mdall referencev1.2. Boundary documented. - Substrate-agnostic boundary (REQ-28): the adapter is the only
substrate-specific code.
acdl_platform/Python is clean (verified by the Check (h) grep + the synthetic leak test).modules-ir/JSON data files contain only IR types (aws:s3:bucket);aws_s3_bucketappears only indescription/$commentstrings that explain the mapping. Boundary holds.
Verdict: PASS — no issues.
Lens 6 — Adversarial
Tried to break the spike. All failure modes handled correctly.
Findings
contracts/spike.yamlwithenvironment: prod(missing runbook): the contract schema rejects it via theallOfif/then (runbookis a required property whenenvironment == "prod").contract_resolver.pyraisesjsonschema.ValidationError(not a generic ValueError). Handled.- IR instance with a resource type not in
TYPE_MAP(e.g.aws:ec2:instance): the adapter raisesValueError("unknown IR type 'aws:ec2:instance' (adapter spike handles aws:s3:bucket only)"). Handled. - Confidence signal gets a critical-fail
PolicyCheckResult: hard-overrides toscore=0.0,band=block,reasonCodes=['CRITICAL_OVERRIDE:...']. The short-circuit returns BEFORE the score clamp. Handled. - Outbox write fails (DynamoDB unreachable):
outbox_writer.pyraises (boto3put_itempropagates the exception);run_spike_e2e.shline 93 uses|| fail "outbox write failed"→ exit 1. Handled (no silent success). - Missing confidence input (e.g.
nfrsabsent):compute()returnsSignal(0.0, "block", {}, ["INPUT_MISSING:nfrs"]). Handled.
Verdict: PASS — no issues.
P0 / P1 / P2 Summary
| Severity | Count | Action |
|---|---|---|
| P0 | 0 | none (no auto-fix needed) |
| P1 | 1 | P1-1 (carried-forward): two AWS access key IDs in .ciagent/VERIFY.md Phase 09 narrative — flagged for post-hoc hygiene redaction; non-blocking |
| P2 | 0 | none |
Milestone verdict
v1.1 milestone: READY TO SHIP
- 0 P0 issues (no blocking fixes).
- 1 P1 carried-forward (non-blocking; flagged for post-hoc review).
- All 5 lenses pass. REQ-16..28 satisfied. The IR commitments hold (REQ-28).
- Ready for the COMPLETE gate → ship
v1.2.0→ audit.