Files
acdl/.ciagent/PLAN.md
T
Jon Chery cf8aa53c8d docs(P00): grill — v1.26 adversarial review (9 challenges, PROCEED 0.84, 2 revisions)
---ci---
project: acdl
phase: 0
milestone: v1.26
status: grill
verdict: PROCEED
confidence: 0.84
revisions: [G-Q4 REQ-322 to P2 W0, G-Q6 enforcement-deferred note, G-Q9 key-split future item]
---/ci---
2026-08-12 21:20:11 +00:00

20 KiB

PLAN — v1.26 (Live Pilot Estate Activation)

Feature milestone. Tags on the v1.25.x line: v1.25.0 (P0) → v1.25.1 (P1) → v1.25.2 (P2) → v1.25.3 (P3) → v1.25.4 (P4) → v1.25.5 (P5 final = milestone release). 13 requirements (REQ-310..322), 5 phases (P0 pre-execution + 4 execution + 1 final). Multi-project: acdl (platform) + nova-blockchain-exchange (consumer). Tags run on the previous minor's patch line per run.md versioning logic (feature milestone — at least one feat phase; progressive patches per phase; the final phase's patch IS the milestone release; no separate minor tag).


Phase 0 — Pre-Execution (complete, tag v1.25.0)

SPECIFY → CLARIFY → RESEARCH → IDEATE → PLAN → GRILL. All .ciagent/ MD, research, plans. Ships as v1.25.0 on the v1.25.x line.

Pre-run (Workstream A, on main before branch gate):

  • A1: flaky test fix (commit 8c68d68, pushed).
  • A2: ACDL_→NOVA_ bootstrap migration (commit f844fea, pushed).
  • A3: AWS bootstrap — S3 state bucket + DynamoDB outbox created.
  • A4: nova-blockchain-exchange Gitea repo created + cloned.

Phase 0 stages (on phase/00-specify-clarify-research-plan):

  • SPECIFY: v1.26 established in config.json + PROJECT.md + ROADMAP.md + .ciagent/nova-blockchain-exchange/{PROJECT,REQUIREMENTS,ROADMAP}.md.
  • CLARIFY: 10 ambiguities resolved (D-200..D-213).
  • RESEARCH: PoA blockchain, deploy model, DynamoDB gap (REQ-322), metric grounding, persona assessment (5 personas).
  • IDEATE: 7 ideas accepted (I1..I7 → REQ-315..322), 3 deferred.
  • PLAN: this file.
  • GRILL: adversarial review (binding verdicts).

Phase 1 — blockchain-core (tag v1.25.1)

Goal: The consumer repo has a working homegrown PoA blockchain + order-matching engine + settlement service. All unit tests pass in the consumer repo's own CI.

Project: nova-blockchain-exchange (consumer repo). Branch: nova-blockchain-exchange/phase/01-blockchain-core. Persona: blockchain-engineer (primary), lead-developer (coordination).

Wave 1 — chain core (REQ-310)

  • Task 1.1 (blockchain-engineer): chain/block.py — Block dataclass (index, timestamp, prev_hash, transactions, nonce, hash). compute_hash() deterministic (SHA-256). Unit test: test_block.py.
  • Task 1.2 (blockchain-engineer): chain/ledger.py — Ledger class: append_block(), verify_chain(), get_block(index), get_latest_block(). Genesis block on init. Unit test: test_ledger.py.
  • Task 1.3 (blockchain-engineer): chain/validator.py — PoA validator: single validator (config-driven), propose_block(transactions) → Block, commit_block(block). Unit test: test_validator.py.

Wave 2 — order engine + settlement (REQ-311, REQ-312) — parallel with Wave 1 tail

  • Task 2.1 (blockchain-engineer): engine/order.py — Order dataclass (id, side, symbol, price, size, timestamp).
  • Task 2.2 (blockchain-engineer): engine/order_book.py — OrderBook: add_order(order), match_orders() → list of Match (price-time priority, partial fills). Unit test: test_order_book.py.
  • Task 2.3 (blockchain-engineer): settlement/service.py — SettlementService: settle(match) → SettlementTransaction, submit(ledger). Idempotent (re-settling a match is a no-op once final). Finality = block commit. Unit test: test_settlement.py.

Wave 3 — consumer CI (cross-cutting)

  • Task 3.1 (blockchain-engineer): .github/workflows/ci.yml + .gitea/workflows/ci.yml — lint + pytest on chain/engine/settlement.
  • Task 3.2 (lead-developer): nova-blockchain-exchange/README.md — repo overview + dev setup.

Must-haves (verify before ship):

  • pytest tests/ in the consumer repo passes (chain integrity, hash determinism, genesis, append/verify, match priority, partial fills, settlement idempotency, finality check).
  • The chain is deterministic (replay produces the same hash chain).
  • The consumer CI workflow runs on push.

Ship: tag v1.25.1, merge phase/01milestone/v1.26-pilot-activation, Gitea release (best-effort). Delete phase/01.


Phase 2 — consumer-contract-and-deploy (tag v1.25.2)

Goal: The consumer repo declares its infrastructure via contract.yaml (validated against the platform's schema) + invokes the platform's deploy.yml@v1.25 workflow. The contract references the microservice (ECS), dynamodb, + s3 modules.

Project: nova-blockchain-exchange (consumer repo) + acdl (platform repo — for the deploy.yml@v1.25 ref + the v1.25 floating tag). Branch: nova-blockchain-exchange/phase/02-contract-and-deploy. Persona: blockchain-engineer (contract authoring), data-engineer (registry/DynamoDB dependency check), lead-developer (deploy.yml ref).

Wave 1 — contract (REQ-313)

  • Task 1.1 (blockchain-engineer): contract.yaml — id (blkex), name (blockchain-exchange), environment (dev), infrastructure block (microservice + dynamodb + s3).
  • Task 1.2 (blockchain-engineer): contracts/blockchain-exchange.dev.yml, .qa.yml, .prod.yml — per-env variants.
  • Task 1.3 (blockchain-engineer): tests/test_contract_validates.py — schema validation against the platform's schemas/contract.schema.json.

Wave 2 — deploy invocation (REQ-314)

  • Task 2.1 (blockchain-engineer): .github/workflows/deploy.ymluses: acdl/.github/workflows/deploy.yml@v1.25 with with: { contract: contract.yaml, mode: full, environment: dev }.
  • Task 2.2 (blockchain-engineer): .gitea/workflows/deploy.yml — byte-identical mirror.
  • Task 2.3 (blockchain-engineer): tests/test_deploy_workflow_invocation.py — asserts the uses: ref + inputs.

Wave 3 — platform floating tag (cross-cutting)

  • Task 3.1 (lead-developer, on acdl repo): verify the v1.25 floating tag exists (created by release.yml on merge to main). If not, create it pointing at the v1.25.0 tag (Phase 0 ship).

Must-haves (verify before ship):

  • contract.yaml validates against schemas/contract.schema.json.
  • The deploy workflow invocation asserts the correct uses: ref + inputs.
  • The v1.25 floating tag resolves.

Ship: tag v1.25.2, merge phase/02 → milestone, Gitea release. Delete phase/02.


Phase 3 — pilot-metrics-and-policies (tag v1.25.3)

Goal: The platform repo gains the metric-grounding emitters, the kyverno-json pilot policies, the DynamoDB L1 primitive, the env-JSON wiring reconciliation, + the pilot regression CAP. The Post-Pilot metrics are grounded (outcome backfill + escalation reason); the pilot- readiness + settlement-finality policies are in place.

Project: acdl (platform repo). Branch: acdl/phase/03-pilot-metrics-and-policies (platform branch). Personas: backend-engineer (emitters + adapter + regression), data-engineer (DynamoDB primitive + env JSON + collector), policy-engineer (kyverno-json policies).

Wave 1 — DynamoDB primitive (REQ-322) — data-engineer

  • Task 1.1 (data-engineer): modules/l1/dynamodb/interface.json — stack type aws:dynamodb:table, inputs (table_name, region, pk, sk, billing_mode), outputs (table_arn, table_name).
  • Task 1.2 (data-engineer): modules/l1/dynamodb/terraform/main.tfresource "aws_dynamodb_table" "this" (PK + optional SK, PAY_PER_REQUEST default, encryption + PITR enabled per v1.8 NFR).
  • Task 1.3 (data-engineer): modules/l1/dynamodb/README.md + instance.json.
  • Task 1.4 (data-engineer): modules/registry.jsondynamodb entry (kind l1, terraform_dir).
  • Task 1.5 (data-engineer): modules/README.md — catalog index.

Wave 2 — metric grounding (REQ-317, REQ-318) — backend-engineer + data-engineer — parallel

  • Task 2.1 (backend-engineer): core/metrics/outcome_backfill.pybackfill(decision_id, outcome) updates fact_decision.outcome + backfilled_at. Reads run-manifest events.
  • Task 2.2 (backend-engineer): core/metrics/collector.py — invokes backfill after run completion.
  • Task 2.3 (backend-engineer): tests/test_outcome_backfill.py.
  • Task 2.4 (backend-engineer): core/confidence_signal.pyai.decision.made gains escalation_reason: 'confidence' when band == 'block'.
  • Task 2.5 (backend-engineer): core/metrics/collector.py — persists escalation_reason into fact_run.
  • Task 2.6 (backend-engineer): tests/test_confidence_escalation_reason.py.

Wave 3 — env-JSON wiring + adapter (REQ-319) — backend-engineer + data-engineer — parallel

  • Task 3.1 (backend-engineer): adapters/terraform/adapter.py — reads env.state_backend.bucket when present (fallback to computed name for backwards compat).
  • Task 3.2 (data-engineer): core/environments/dev.jsonaccount_id581513795199, state_backend.bucketnova-tfstate-581513795199-us-east-1.
  • Task 3.3 (data-engineer): core/environments/{qa,prod,dr}.jsonstate_backend.bucket updated; account_id stays placeholder (pilot-readiness policy blocks apply on placeholder, D-208).
  • Task 3.4 (backend-engineer): tests/test_adapter_state_backend.py.
  • Task 3.5 (backend-engineer): tests/test_adapter.py — add dynamodb to EXPECTED_L1_KEYS + a resolution + emission test (cross-territory: data-engineer authored the module, backend-engineer owns the test).

Wave 4 — kyverno-json policies (REQ-315, REQ-320) — policy-engineer — parallel

  • Task 4.1 (policy-engineer): adapters/kyverno-json/policies/settlement-finality/all-matches-committed.json — kyverno-json policy over settlement-service status JSON (asserts all_committed: true). Note (G-Q6): the policy is authored + tested in v1.26; enforcement is deferred to the milestone that binds qa/prod/dr (D-208 — the policy gates promotions, not dev applies).
  • Task 4.2 (policy-engineer): adapters/kyverno-json/policies/pilot-readiness/no-placeholder-account.json — kyverno-json policy over env JSON (asserts account_id != "000000000000").
  • Task 4.3 (policy-engineer): tests/test_settlement_finality_policy.py — passing + failing fixtures; skip when kj absent.
  • Task 4.4 (policy-engineer): tests/test_pilot_readiness_policy.py — passing (real account) + failing (placeholder) fixtures; skip when kj absent.

Wave 5 — regression CAP (REQ-316) — backend-engineer

  • Task 5.1 (backend-engineer): core/regression_verify.py — CAP-025 (live-pilot-apply): the round-trip assertion.
  • Task 5.2 (backend-engineer): tests/test_regression_pilot.py.

Must-haves (verify before ship):

  • pytest tests/ in the platform repo passes (170 existing + new tests).
  • The DynamoDB primitive resolves + emits valid Terraform.
  • The outcome backfill updates fact_decision.outcome (not pending).
  • The escalation_reason field is emitted on block band.
  • The adapter reads env.state_backend.bucket from the env JSON.
  • The 2 new kyverno-json policies pass on valid fixtures + fail on invalid fixtures (skip when kj absent).
  • CAP-025 is in the regression gate.
  • No existing tests regress (170 baseline holds).

Ship: tag v1.25.3, merge phase/03 → milestone, Gitea release. Delete phase/03.


Phase 4 — pilot-run-and-docs (tag v1.25.4)

Goal: The pilot estate runs end-to-end against live AWS 581513795199 (contract resolve → adapter compile → terraform plan → policy scan → confidence signal → attestation → outbox record). Docs + adapter README + onboarding guide are complete.

Project: nova-blockchain-exchange (consumer repo — the run) + acdl (platform repo — docs). Branch: acdl/phase/04-pilot-run-and-docs (platform branch for docs); the run happens via the consumer's deploy.yml invocation. Personas: blockchain-engineer (the run), lead-developer (docs), backend-engineer (regression CAP-025 verification).

Wave 1 — the pilot run (REQ-316 verification, live)

  • Task 1.1 (blockchain-engineer): trigger the consumer's deploy.yml with mode: full, environment: dev against 581513795199. The workflow checks out the consumer + platform repos, runs run_platform.sh, applies the contract (ECS + DynamoDB + S3), records the decision + attestation.
  • Task 1.2 (backend-engineer): verify CAP-025 (regression gate) passes against the live run.
  • Task 1.3 (blockchain-engineer): capture the run's ai.decision.made + attestation.recorded events from the Decision Ledger → evidence for the milestone ship.

Wave 2 — docs (REQ-321)

  • Task 2.1 (lead-developer): adapters/README.md — new consumer row + fix the stale TYPE_MAP references (IDEATE I8).
  • Task 2.2 (lead-developer): docs/METRICS.md — Post-Pilot metrics grounded note (the 3 targets now have non-zero denominators post-run).
  • Task 2.3 (lead-developer): .ciagent/ARCHITECTURE.md §12.8 (Pilot Estate).
  • Task 2.4 (lead-developer): .ciagent/nova-blockchain-exchange/README.md — consumer onboarding guide (how to invoke deploy.yml@v1.25, what secrets to set, what the contract shape is).

Must-haves (verify before ship):

  • The pilot run completes end-to-end (apply succeeds, decision recorded, attestation recorded for dev — autonomous, no human approver).
  • CAP-025 passes.
  • The 3 Post-Pilot metrics have non-zero denominators (the run contributed to fact_run + fact_decision).
  • Docs are complete (adapter README, METRICS.md, ARCHITECTURE.md §12.8, consumer onboarding guide).

Ship: tag v1.25.4, merge phase/04 → milestone, Gitea release. Delete phase/04.


Phase 5 — final review + audit + milestone ship (tag v1.25.5)

Goal: Multi-persona code review across P1..P4. Audit (reconstruction test, branch hygiene, commit discipline). Milestone ship: merge to main, tag v1.25.5 (= the v1.26 release), Gitea release with full milestone summary, delete all milestone branches.

Project: both (acdl + nova-blockchain-exchange). Branch: phase/05-final-review-ship. Personas: lead-developer (review + audit + ship), backend-engineer (review), data-engineer (review), policy-engineer (review), blockchain-engineer (review — the chain core is reviewed).

Wave 1 — review

  • Task 1.1 (lead-developer): ciagent-review — multi-persona code review across P1..P4. Auto-fix P0; flag P1+ for post-hoc review.
  • Task 1.2 (all personas): fix P0 issues in this phase.

Wave 2 — audit

  • Task 2.1 (lead-developer): ciagent-audit — reconstruction test (git log ↔ .ciagent/), branch hygiene, commit discipline.
  • Task 2.2 (lead-developer): fix critical audit issues in this phase.

Wave 3 — milestone ship

  • Task 3.1 (lead-developer): merge phase/05milestone/v1.26-pilot-activationmain.
  • Task 3.2 (lead-developer): tag v1.25.5 (= the v1.26 release per prev-minor tagging rule).
  • Task 3.3 (lead-developer): create Gitea release with full milestone summary (all phases, all 13 requirements).
  • Task 3.4 (lead-developer): delete all milestone branches (local + remote). Tags preserve all history.
  • Task 3.5 (lead-developer): update .ciagent/nova-blockchain-exchange/REQUIREMENTS.md (mark REQ-310..322 complete), .ciagent/ROADMAP.md (mark v1.26 complete), .ciagent/NORTH_STAR.md (note Strategic Objectives #1 + #3 — first real consumer estate; Post-Pilot denominators activated).
  • Task 3.6 (lead-developer): write checkpoint stage: complete, phase: 5, phase_role: final + clear checkpoint (milestone complete).

Must-haves (verify before ship):

  • Review: 0 P0 issues unfixed; P1+ flagged for post-hoc.
  • Audit: reconstruction test passes; branch hygiene clean; commit discipline clean.
  • Ship: v1.25.5 tag exists; Gitea release created; milestone branches deleted; main has the milestone merge.

Requirement → Phase Mapping

REQ Phase Wave Persona
REQ-310 (blockchain core) P1 W1 blockchain-engineer
REQ-311 (order engine) P1 W2 blockchain-engineer
REQ-312 (settlement) P1 W2 blockchain-engineer
REQ-313 (contract.yaml) P2 W1 blockchain-engineer
REQ-314 (deploy invocation) P2 W2 blockchain-engineer
REQ-315 (settlement-finality policy) P3 W4 policy-engineer
REQ-316 (pilot regression CAP) P3 W5 + P4 W1 backend-engineer
REQ-317 (outcome backfill) P3 W2 backend-engineer
REQ-318 (escalation reason) P3 W2 backend-engineer
REQ-319 (env-JSON wiring) P3 W3 backend + data-engineer
REQ-320 (pilot-readiness policy) P3 W4 policy-engineer
REQ-321 (docs) P4 W2 lead-developer
REQ-322 (DynamoDB primitive) P3 W1 data-engineer

Wave Ordering Rationale

  • P1 W1 → W2: the chain core (block + ledger + validator) must land before the order engine + settlement (they submit transactions to the ledger). W3 (CI) is cross-cutting + can land any time after W1.
  • P2 W1 → W2: the contract must land before the deploy invocation (the invocation references the contract). W3 (floating tag) is cross- cutting.
  • P3 W1 (DynamoDB) first: the contract (P2) references dynamodb — the primitive must exist before P2's contract can resolve. Risk: P2's contract references a module that doesn't exist until P3. Resolution: P2's contract is authored but the test_contract_validates.py test only checks schema validity (not registry resolution) — the registry resolution test is in P3 (after the primitive lands). The contract's dynamodb block is schema-valid (the schema is open); the registry resolution happens at apply time (P4).
    • Alternative: move REQ-322 to P2 W0 (before the contract). This avoids the P2→P3 dependency. Decision: move REQ-322 to P2 W0. See revised mapping below.

Revised: REQ-322 → P2 W0

REQ-322 (DynamoDB primitive) lands in P2 Wave 0 (before the contract) so the contract's dynamodb block resolves at registry time, not just schema time. This makes P2 self-contained: the primitive + the contract

  • the deploy invocation all land in P2.
REQ Phase Wave Persona
REQ-310 (blockchain core) P1 W1 blockchain-engineer
REQ-311 (order engine) P1 W2 blockchain-engineer
REQ-312 (settlement) P1 W2 blockchain-engineer
REQ-322 (DynamoDB primitive) P2 W0 data-engineer
REQ-313 (contract.yaml) P2 W1 blockchain-engineer
REQ-314 (deploy invocation) P2 W2 blockchain-engineer
REQ-315 (settlement-finality policy) P3 W4 policy-engineer
REQ-316 (pilot regression CAP) P3 W5 + P4 W1 backend-engineer
REQ-317 (outcome backfill) P3 W2 backend-engineer
REQ-318 (escalation reason) P3 W2 backend-engineer
REQ-319 (env-JSON wiring) P3 W3 backend + data-engineer
REQ-320 (pilot-readiness policy) P3 W4 policy-engineer
REQ-321 (docs) P4 W2 lead-developer

This revision is a binding plan decision (G-Q8 in the grill may challenge it).


Future Hardening Items (not in v1.26 scope, documented per grill G-Q9)

  • NOVA_AWS_* key-split: v1.26 uses a single NOVA_AWS_* key with root-equivalent permissions (D-207, confirmed empirically by the bootstrap). A future hardening milestone should split this into a NOVA_BOOTSTRAP_AWS_* root key (bootstrap only) + a least-privilege NOVA_AWS_* runner key (the spike-runner pattern). The pilot scope (single account, no production workloads, OIDC default) bounds the risk.
  • Multi-account landing zone: qa/prod/dr on separate accounts (D-208 keeps them placeholder in v1.26).
  • D-083 lift: S3 Object Lock + JWS tamper-evident ledger (when the pilot becomes a production system, D-204).
  • Multi-validator BFT consensus: D-201.
  • Other security types: bonds (T+2), derivatives, options (D-200).