Files
acdl/.ciagent/nova-blockchain-exchange/REQUIREMENTS.md
T
CIAgent Orchestrator 932923ee99
Nova Slides Render / render (push) Failing after 22s
merge(milestone): v1.29 Reposplit + Identity Layer Bring-Live to main (release v1.28.6)
---ci---
project: acdl
phase: 6
milestone: v1.29
status: complete
---/ci---
2026-08-20 05:29:46 +00:00

11 KiB

Requirements — nova-blockchain-exchange (v1.26 pilot)

Project: nova-blockchain-exchange — blockchain stock exchange (pilot) Milestone: v1.26 — Live Pilot Estate Activation Scope: equities only; minimal PoA ledger; T+1 settlement finality.


v1.26 — Live Pilot Estate Activation

REQ-310 — Homegrown PoA blockchain core

The consumer repo implements a minimal Proof-of-Authority blockchain: append-only blocks, single validator (pilot), SHA-256 block hash chain, deterministic block production (same ordered transactions → same block). The chain records every order, match, and settlement as transactions. Settlement finality = block commit (a transaction is final when its block is committed to the chain).

Must-haves:

  • chain/block.py — Block dataclass (index, timestamp, prev_hash, transactions, nonce, hash). compute_hash() deterministic.
  • chain/ledger.py — Ledger class: append_block(), verify_chain(), get_block(index), get_latest_block(). Genesis block on init.
  • chain/validator.py — PoA validator: single validator (config-driven, pilot), propose_block(transactions) → Block, commit_block(block).
  • tests/test_block.py, tests/test_ledger.py, tests/test_validator.py — chain integrity, hash determinism, genesis, append/verify.

REQ-311 — Order-matching engine

A limit-order-book matching engine: buy/sell orders with price + size, matched at the best price (price-time priority). Produces match transactions recorded on the chain.

Must-haves:

  • engine/order_book.py — OrderBook: add_order(order), match_orders() → list of Match (buyer, seller, price, size).
  • engine/order.py — Order dataclass (id, side, symbol, price, size, timestamp).
  • tests/test_order_book.py — match priority, partial fills, no-match.

REQ-312 — Settlement service

T+1 settlement: matches commit to the chain; a settlement is final when its block is committed. The service reads matches from the order engine, produces settlement transactions, and submits them to the ledger.

Must-haves:

  • settlement/service.py — SettlementService: settle(match) → SettlementTransaction, submit(ledger). Idempotent (re-settling a match is a no-op once final).
  • tests/test_settlement.py — happy path, idempotency, finality check.

REQ-313 — Consumer contract.yaml ✓ complete (P2, v1.25.2)

The consumer repo declares its infrastructure via a contract.yaml at the repo root, validated against schemas/contract.schema.json. The contract references the Nova platform's deploy workflow (uses: acdl/.github/workflows/deploy.yml@v1.25) and declares the blockchain exchange stack (the AWS resources the app needs: ECS for the matching engine, DynamoDB for the ledger, S3 for block storage). The DynamoDB L1 primitive (REQ-322) must land before this contract can declare dynamodb — ECS + S3 already exist.

Must-haves:

  • contract.yaml — id, name (blockchain-exchange), environment (dev/qa/prod variants), infrastructure block.
  • contracts/blockchain-exchange.dev.yml, .qa.yml, .prod.yml — per-environment variants (per-env promotion model, REQ-105).
  • tests/test_contract_validates.py — schema validation against the platform's schemas/contract.schema.json.

REQ-CONSUMER-BUMP — Consumer deploy.yml @v1.25@v1.29 (v1.29 P5)

The consumer repo's deploy workflow invocation (REQ-314, originally @v1.25) is bumped to @v1.29 to track the v1.29 platform release (Reposplit + Identity Layer Bring-Live). The v1.29 platform publishes Lambda zip + layer wheel + Python wheel + ECR container image to GitHub Releases (REQ-354); the consumer's smoke test runs against these artifacts.

Must-haves:

  • .github/workflows/deploy.ymluses: acdl/.github/workflows/deploy.yml@v1.29 with with: { contract: contract.yaml, mode: full, environment: dev }.
  • .gitea/workflows/deploy.yml — updated to @v1.29 (the consumer's .gitea/ is out of scope for the acdl REQ-367 Gitea scrub — that scrub is acdl/acdl only; the consumer may keep its Gitea mirror or follow suit — this is a consumer-repo decision).
  • tests/test_v1.29_smoke.py — sign-up → sign-in → token-vend → apply → audit chain against the v1.29 publish artifacts (the consumer's contract → deploy.yml@v1.29 mode=full → apply → attest → record against 581513795199). Uses the existing CAP-025 round-trip assertion (v1.26).

Status: The consumer repo is not checked out in this environment. The deploy.yml bump + smoke test are documented here; the actual bump requires a consumer repo checkout. The smoke test runs against the v1.29.0 intermediate tag artifacts (produced by P1, grill CF-3/G-3).

REQ-315 — Settlement-finality kyverno-json policy (IDEATE I6)

A kyverno-json policy asserting that every promotion (qa→prod) requires settlement finality: all matches in the promotion window have committed blocks. This is the securities-specific extension of v1.25's policy engine — it applies Nova's compliance posture to the blockchain domain.

Must-haves:

  • policies/settlement-finality.json — kyverno-json policy over the settlement-service status JSON (asserts all_committed: true).
  • tests/test_settlement_finality_policy.py — passing + failing fixtures; skip when kj absent.

REQ-316 — Pilot-estate regression capability (CAP-025)

A new capability in the regression gate: "pilot estate apply→attest→record round-trip." The regression gate asserts that the consumer estate can run end-to-end (contract resolve → adapter compile → terraform plan → policy scan → confidence signal → attestation → outbox record) against the live AWS account 581513795199.

Must-haves:

  • core/regression_verify.py gains CAP-025 (live-pilot-apply).
  • tests/test_regression_pilot.py — the round-trip assertion.

REQ-317 — Outcome-backfill emitter (IDEATE I1)

Wire apply.completed / apply.failed events back into fact_decision in the cold store so the AI Decision Accuracy metric has a non-pending outcome. Today fact_decision.outcome is stuck at pending (D-096 blocker). The backfill emitter reads run_manifest.completed/failed events and updates the corresponding decision's outcome.

Must-haves:

  • core/metrics/outcome_backfill.pybackfill(decision_id, outcome) updates fact_decision.outcome + fact_decision.backfilled_at.
  • core/metrics/collector.py — invokes backfill after run completion.
  • tests/test_outcome_backfill.py.

REQ-318 — reason='confidence' escalation tag (IDEATE I2)

Emit a distinct reason='confidence' field on the block band's ai.decision.made event so the Human Escalation Frequency metric has a discriminated numerator. Today hitl_block is a boolean from the manifest; the reason discriminator is not stored.

Must-haves:

  • core/confidence_signal.pyai.decision.made gains escalation_reason: 'confidence' when band == 'block'.
  • core/metrics/collector.py — persists escalation_reason into fact_run.
  • tests/test_confidence_escalation_reason.py.

REQ-319 — Env-JSON state_backend wiring reconciliation (IDEATE I3)

The env JSON's state_backend.bucket field is currently unused by the adapter (the adapter computes nova-tfstate-<AWS_ACCOUNT_ID> directly). Reconcile: the adapter reads state_backend.bucket from the env JSON (falling back to the computed name for backwards compat). This closes the wiring gap so the pilot's env JSON is the single source of truth.

Must-haves:

  • adapters/terraform/adapter.py — reads env.state_backend.bucket when present.
  • tests/test_adapter_state_backend.py.
  • core/environments/*.jsonstate_backend.bucket updated to the real bucket name nova-tfstate-581513795199-us-east-1.

REQ-320 — Declarative pilot-readiness kyverno-json policy (IDEATE I5)

A kyverno-json policy asserting the env JSON has a non-placeholder account_id (not 000000000000) before any terraform apply. This is the declarative gate that prevents a pilot run against a placeholder account.

Must-haves:

  • adapters/kyverno-json/policies/pilot-readiness/no-placeholder-account.json
  • tests/test_pilot_readiness_policy.py.

REQ-321 — Docs + adapter README for the consumer estate

Update adapters/README.md (new consumer row), docs/METRICS.md (the 3 Post-Pilot metrics now grounded post-pilot), .ciagent/ARCHITECTURE.md (§12.8 — Pilot Estate), and .ciagent/nova-blockchain-exchange/README.md (consumer onboarding guide).

Must-haves:

  • adapters/README.md — consumer-repo row.
  • docs/METRICS.md — Post-Pilot metrics grounded note.
  • .ciagent/ARCHITECTURE.md — §12.8 Pilot Estate.
  • .ciagent/nova-blockchain-exchange/README.md — onboarding guide.

REQ-322 — DynamoDB L1 primitive (platform-side) ✓ complete (P2, v1.25.2)

The blockchain exchange's ledger table needs a DynamoDB L1 primitive. Research (RESEARCH §3) confirmed the adapter is stateless/registry- driven (no TYPE_MAP — deleted in v1.11); a new stack type requires a new L1 module, not an adapter change. The dynamodb primitive mirrors the existing s3 / rds primitives: interface.json (stack type aws:dynamodb:table, inputs table_name/region/pk/sk/billing_mode, outputs table_arn/table_name), terraform/main.tf (resource "aws_dynamodb_table" "this"), README.md, instance.json,

  • a registry.json entry. The pilot contract's infrastructure.dynamodb block references this primitive. This is the single platform-side module build-out for the milestone (ECS + S3 already exist).

Must-haves:

  • modules/l1/dynamodb/interface.json — stack type aws:dynamodb:table, inputs, outputs.
  • modules/l1/dynamodb/terraform/main.tfresource "aws_dynamodb_table" "this" (PK + optional SK, billing_mode = PAY_PER_REQUEST default, encryption + point-in-time- recovery enabled per v1.8 NFR defaults).
  • modules/l1/dynamodb/README.md — module doc.
  • modules/l1/dynamodb/instance.json — sample instance.
  • modules/registry.jsondynamodb entry (kind l1, terraform_dir: modules/l1/dynamodb/terraform).
  • tests/test_adapter.py — add dynamodb to EXPECTED_L1_KEYS + a resolution + emission test.
  • modules/README.md — catalog index updated.

Summary

13 requirements (REQ-310..322). Equities-only pilot; minimal PoA ledger; T+1 settlement; consumer deploy via deploy.yml@v1.25; 3 Post-Pilot metrics grounded (outcome backfill + escalation reason + pilot runs); 3 kyverno-json policies extending v1.25 (settlement-finality, pilot-readiness, + the existing meta-policies apply); env-JSON wiring reconciled; DynamoDB L1 primitive authored (the single platform-side module build-out — the adapter is stateless/registry-driven, so the primitive is a new modules/l1/dynamodb/ module + registry entry, not an adapter change).