---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---
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 perrun.mdversioning 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-exchangeGitea 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/01 → milestone/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'sschemas/contract.schema.json.
Wave 2 — deploy invocation (REQ-314)
- Task 2.1 (blockchain-engineer):
.github/workflows/deploy.yml—uses: acdl/.github/workflows/deploy.yml@v1.25withwith: { 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 theuses:ref + inputs.
Wave 3 — platform floating tag (cross-cutting)
- Task 3.1 (lead-developer, on
acdlrepo): verify thev1.25floating tag exists (created byrelease.ymlon merge to main). If not, create it pointing at thev1.25.0tag (Phase 0 ship).
Must-haves (verify before ship):
contract.yamlvalidates againstschemas/contract.schema.json.- The deploy workflow invocation asserts the correct
uses:ref + inputs. - The
v1.25floating 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 typeaws: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.tf—resource "aws_dynamodb_table" "this"(PK + optional SK,PAY_PER_REQUESTdefault, 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.json—dynamodbentry (kindl1,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.py—backfill(decision_id, outcome)updatesfact_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.py—ai.decision.madegainsescalation_reason: 'confidence'whenband == 'block'. - Task 2.5 (backend-engineer):
core/metrics/collector.py— persistsescalation_reasonintofact_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— readsenv.state_backend.bucketwhen present (fallback to computed name for backwards compat). - Task 3.2 (data-engineer):
core/environments/dev.json—account_id→581513795199,state_backend.bucket→nova-tfstate-581513795199-us-east-1. - Task 3.3 (data-engineer):
core/environments/{qa,prod,dr}.json—state_backend.bucketupdated;account_idstays 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— adddynamodbtoEXPECTED_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 (assertsall_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 (assertsaccount_id != "000000000000"). - Task 4.3 (policy-engineer):
tests/test_settlement_finality_policy.py— passing + failing fixtures; skip whenkjabsent. - Task 4.4 (policy-engineer):
tests/test_pilot_readiness_policy.py— passing (real account) + failing (placeholder) fixtures; skip whenkjabsent.
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(notpending). - The
escalation_reasonfield is emitted onblockband. - The adapter reads
env.state_backend.bucketfrom the env JSON. - The 2 new kyverno-json policies pass on valid fixtures + fail on
invalid fixtures (skip when
kjabsent). - 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.ymlwithmode: full, environment: devagainst581513795199. The workflow checks out the consumer + platform repos, runsrun_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.recordedevents 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 staleTYPE_MAPreferences (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 invokedeploy.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/05→milestone/v1.26-pilot-activation→main. - 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.5tag 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 thetest_contract_validates.pytest only checks schema validity (not registry resolution) — the registry resolution test is in P3 (after the primitive lands). The contract'sdynamodbblock 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 singleNOVA_AWS_*key with root-equivalent permissions (D-207, confirmed empirically by the bootstrap). A future hardening milestone should split this into aNOVA_BOOTSTRAP_AWS_*root key (bootstrap only) + a least-privilegeNOVA_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).