a0799f13e5
- 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 ---
180 lines
7.7 KiB
Markdown
180 lines
7.7 KiB
Markdown
# 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 "<rid>" { 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:`). |