# 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: 1. In the consumer repo's Actions UI, pick the **Deploy** workflow. 2. Click **Run workflow**. 3. Inputs: - `mode` = `full` (the default — applies the Terraform). Other values: `plan-only` (no apply), `check-only` (policy + confidence only), `decommission` (requires a `changeRequestId`). - `environment` = `dev` (the pilot scope — equities only, dev only, D-020/D-200). Leave empty to use the contract's `environment` field. 4. 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: ```yaml 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`: 1. **Resolve** the contract to a target stack (a list of L1 instances + inputs + relationships), reading `modules/registry.json` for each L1's `terraform_dir`. 2. **Compile** the stack to Terraform HCL via the stateless adapter (`adapters/terraform/adapter.py`) — emits `module "" { source } ` blocks + wired `ref:` refs. No `TYPE_MAP` — each L1 owns its shape. 3. **Plan** — `terraform plan` against the live AWS account. Infracost runs on the plan JSON and emits `nova.cost.estimated`. 4. **Policy** — the kyverno-json engine evaluates the meta-policies (`block-on-any-critical` + the pilot policies) and emits `PolicyCheckResult` records. 5. **Confidence** — the confidence signal consumes the six inputs (the PCRs included) and emits `nova.confidence.computed` with `{ score, band, perInput, reasonCodes }`. Dev threshold = 0.50. 6. **Apply** (dev, autonomous — no HITL gate) — `terraform apply` against account `581513795199`. On success, `nova.ai.decision.made` + `nova.run.completed` land in the Decision Ledger. 7. **Backfill** — the outcome (`pending → succeeded`) is backfilled (REQ-317), producing `nova.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.com` for the pilot). - `aws ecs describe-services --cluster nova-cluster --services nova-microservice` — the ECS service is `ACTIVE`. - `aws dynamodb describe-table --table-name nova-blkex-ledger-dev` — the ledger table exists (PK `block_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.db` has the `nova.ai.decision.made` row for `blkex-pilot-apply-v0.2` (chosen action `pass`, `human_override` false) + the `nova.outcome.backfilled` row (outcome `pending → succeeded`). - The chain is valid (`prev_event_hash` links, 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 (run `blkex-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-repo `uses:`).