- adapters/README.md: fixed stale TYPE_MAP/INPUT_MAP refs (the adapter is a stateless assembler); added the blockchain-exchange consumer row + the Gitea adapter note (SPEC §10 Q1 — no cross-repo uses:) - docs/METRICS.md: Post-Pilot denominators activated (AI Decision Accuracy + Human Escalation Frequency + the third metric now have non-zero data from the blkex-pilot-apply-v0.2 run) - .ciagent/ARCHITECTURE.md §12.8: Pilot Estate (v1.26 live) — the first real consumer estate, the live apply, the Gitea adapter, the evidence stream - .ciagent/nova-blockchain-exchange/README.md: consumer onboarding guide (deploy invocation, secrets, contract shape, verification) ---ci--- project: acdl phase: 4 milestone: v1.26 status: execute wave: W2 ---
7.7 KiB
nova-blockchain-exchange — Consumer Onboarding Guide
Milestone: v1.26 — the first real Nova consumer estate. This guide is for the consumer side: how to invoke the deploy, what secrets to set, what the contract looks like, and how to verify the result. The platform side is documented in
.ciagent/ARCHITECTURE.md§12.8; the live-pilot evidence is in.ciagent/P4-PILOT-RUN-EVIDENCE.md.
This is a consumer of the Nova platform, not a fork. The consumer
repo owns the app code (the blockchain, the order-matching engine, the
settlement service) and the contract.yaml that declares the
infrastructure. The Nova platform (acdl repo) owns the deploy
workflow, the policy engine, the contract resolver, the Terraform
adapter, the confidence signal, the HITL gates, and the Decision
Ledger. The consumer never clones the platform repo and never runs
terraform apply directly.
1. Invoke the deploy
The consumer's .github/workflows/deploy.yml (and its byte-identical
.gitea/workflows/deploy.yml mirror) is a workflow_dispatch workflow.
It does not use cross-repo uses: (SPEC §10 Q1 — the Gitea forge
rejects it). Instead it is an inline adapter: it checks out the
consumer repo, then checks out acdl/acdl @ ref: v1.25 into
platform/, then runs bash platform/scripts/run_platform.sh.
To run a deploy:
- In the consumer repo's Actions UI, pick the Deploy workflow.
- Click Run workflow.
- Inputs:
mode=full(the default — applies the Terraform). Other values:plan-only(no apply),check-only(policy + confidence only),decommission(requires achangeRequestId).environment=dev(the pilot scope — equities only, dev only, D-020/D-200). Leave empty to use the contract'senvironmentfield.
- The workflow runs the platform pipeline end-to-end: contract resolve → adapter compile → terraform plan → policy (kyverno-json) → confidence signal → (dev: autonomous apply) → Decision Ledger events.
For the pilot, the documented invocation is mode=full, environment=dev. The first live run was blkex-pilot-apply-v0.2
(2026-08-19).
2. Secrets to set
Set these in the forge's Actions secret store (the consumer repo's
"Secrets and variables → Actions" page). The platform-managed
scheduled workflow rotate-aws-key.yml rotates the NOVA_AWS_* key
daily (SPEC §5.9 — the v0.2 deploy uses the currently-active key).
| Secret | Purpose |
|---|---|
NOVA_AWS_ACCESS_KEY_ID |
The static AWS access key for the deploy IAM principal. Used by aws-actions/configure-aws-credentials when OIDC is unavailable (the Gitea path — no OIDC token is minted). |
NOVA_AWS_SECRET_ACCESS_KEY |
The matching secret key. Rotated by workflows-src/rotate-aws-key.yml. |
AWS_DEFAULT_REGION |
The target region (us-east-1 for the pilot). |
The platform's .github/workflows/deploy.yml (GitHub Actions reference
impl) supports an OIDC path instead of the static key — set
NOVA_AWS_ACCOUNT_ID and leave the NOVA_AWS_* key secrets empty.
The Gitea inline adapter uses the static-key path.
3. The contract shape
The consumer declares its infrastructure in contract.yaml at the
repo root, validated against the platform's
schemas/contract.schema.json. The pilot contract has the shape:
id: blkex
name: blockchain-exchange
environment: dev
infrastructure:
microservice: # the L2 composition (ECS Fargate + ALB + roles)
...
dynamodb: # the L1 DynamoDB table (the ledger)
...
s3: # the L1 S3 bucket (block storage)
...
Three infrastructure.* blocks: microservice (the L2 composition
that wires the ECS service, the ALB, and the IAM roles together), and
the two L1 primitives (dynamodb for the ledger, s3 for block
storage). Per-environment variants live in
contracts/blockchain-exchange.{dev,qa,prod}.yml (the per-env
promotion model, REQ-105). The pilot runs the dev variant.
The contract is the only consumer-facing artifact that describes
infrastructure. It is IR-typed (engine-agnostic); the platform
resolves it to a target stack, the Terraform adapter compiles the
stack to HCL, and terraform apply runs in the central pipeline —
never on the consumer's workstation.
4. What the platform does
When run_platform.sh runs against contract.yaml:
- Resolve the contract to a target stack (a list of L1 instances +
inputs + relationships), reading
modules/registry.jsonfor each L1'sterraform_dir. - Compile the stack to Terraform HCL via the stateless adapter
(
adapters/terraform/adapter.py) — emitsmodule "<rid>" { source }blocks + wiredref:refs. NoTYPE_MAP— each L1 owns its shape. - Plan —
terraform planagainst the live AWS account. Infracost runs on the plan JSON and emitsnova.cost.estimated. - Policy — the kyverno-json engine evaluates the meta-policies
(
block-on-any-critical+ the pilot policies) and emitsPolicyCheckResultrecords. - Confidence — the confidence signal consumes the six inputs (the
PCRs included) and emits
nova.confidence.computedwith{ score, band, perInput, reasonCodes }. Dev threshold = 0.50. - Apply (dev, autonomous — no HITL gate) —
terraform applyagainst account581513795199. On success,nova.ai.decision.madenova.run.completedland in the Decision Ledger.
- Backfill — the outcome (
pending → succeeded) is backfilled (REQ-317), producingnova.outcome.backfilled. The SQLite hash-chain is extended, not torn up.
The consumer does not see steps 1–7 directly; the consumer sees the
workflow's green check + the uploaded artifacts (nova-terraform,
nova-platform-log).
5. How to verify post-deploy
Two independent verifications — read the AWS API and read the Decision Ledger. Neither trusts the other.
AWS API (the infrastructure landed):
aws elbv2 describe-load-balancers— the ALB (app-254671247.us-east-1.elb.amazonaws.comfor the pilot).aws ecs describe-services --cluster nova-cluster --services nova-microservice— the ECS service isACTIVE.aws dynamodb describe-table --table-name nova-blkex-ledger-dev— the ledger table exists (PKblock_index, PAY_PER_REQUEST).aws s3api head-bucket --bucket nova-blkex-blocks-dev-581513795199-us-east-1— the block bucket exists (versioning + SSE).
Decision Ledger (the trust record):
- The SQLite hash-chain at
metrics/decision_ledger.dbhas thenova.ai.decision.maderow forblkex-pilot-apply-v0.2(chosen actionpass,human_overridefalse) + thenova.outcome.backfilledrow (outcomepending → succeeded). - The chain is valid (
prev_event_hashlinks, 0 breaks). The Trust Snapshot (metrics/TRUST_SNAPSHOT.md) records the verdict.
If the AWS API shows the resources AND the Decision Ledger shows the
decision + outcome with a valid chain, the deploy is verified. See
.ciagent/P4-PILOT-RUN-EVIDENCE.md for the full pilot-evidence
checklist (every ARN, the confidence JSON, the backfill timestamp).
References
.ciagent/ARCHITECTURE.md§12.8 — the pilot-estate architecture (this guide is the consumer-facing companion to that section)..ciagent/P4-PILOT-RUN-EVIDENCE.md— the live-pilot evidence (runblkex-pilot-apply-v0.2)..ciagent/nova-blockchain-exchange/PROJECT.md— the consumer project charter (vision, scope, decisions D-200..D-205)..ciagent/nova-blockchain-exchange/REQUIREMENTS.md— the consumer requirements (REQ-313 contract, REQ-314 deploy invocation).adapters/README.md§Consumers — the Gitea adapter note (SPEC §10 Q1 — inline checkout-then-call, no cross-repouses:).