Compare commits

...

12 Commits

Author SHA1 Message Date
Jon Chery f06a4c55b4 merge(milestone): v1.26 Live Pilot Estate Activation to main (release v1.25.5)
acdl-ci / Lint (push) Successful in 8s
acdl-ci / Test (push) Failing after 19s
acdl-ci / Platform check-only (offline) (push) Successful in 18s
Nova Slides Render / render (push) Failing after 17s
The first real consumer estate (blockchain stock exchange on a homegrown PoA blockchain,
equities only, dev) is activated against live AWS account 581513795199. All 13 requirements
(REQ-310..322) complete. 5 phases: P0 pre-execution, P1 blockchain-core, P2 contract+deploy,
P3 pilot-metrics-and-policies (Gitea adapter + kj substrate + outcome backfill + pilot policies),
P4 pilot-run-and-docs (live apply + Decision Ledger evidence stream), P5 final-review+audit.

Live outputs: ALB app-254671247.us-east-1.elb.amazonaws.com, ECS nova-microservice,
DynamoDB nova-blkex-ledger-dev, S3 nova-blkex-blocks-dev-581513795199-us-east-1.
Confidence 0.800 pass (dev autonomous). fact_decision.outcome=succeeded (REQ-317 backfill).

---ci---
project: acdl
phase: 5
milestone: v1.26
status: complete
requirements:
  covered: [REQ-310, REQ-311, REQ-312, REQ-313, REQ-314, REQ-315, REQ-316, REQ-317, REQ-318, REQ-319, REQ-320, REQ-321, REQ-322]
  partial: []
---
2026-08-19 03:53:58 +00:00
Jon Chery cbdb2e2b9a merge(phase/05): v1.26 P5 final review + audit complete — milestone release
P5 review: 0 P0 issues (1 cosmetic REQ-316 doc-drift fixed). Audit: reconstruction PASS, file discipline CLEAN, branch hygiene CLEAN (P1-P4 deleted, only milestone + P5 remain), commit discipline CLEAN. PROCEED to milestone ship.

---ci---
project: acdl
phase: 5
milestone: v1.26
status: complete
requirements:
  covered: [REQ-310, REQ-311, REQ-312, REQ-313, REQ-314, REQ-315, REQ-316, REQ-317, REQ-318, REQ-319, REQ-320, REQ-321, REQ-322]
  partial: []
---
2026-08-19 03:53:50 +00:00
Jon Chery 7e7a4fa853 docs(P05): final review + audit — PROCEED (0 P0 remain, audit CLEAN)
Multi-persona review across P1..P4 + audit (reconstruction, file
discipline, branch hygiene, commit discipline).

Review: 0 P0 issues remain after the REQ-316 traceability fix (committed
separately). Correctness spot-checks all PASS (kj substrate, outcome
backfill, Gitea adapter, env-JSON state_backend, pilot policies). 844
tests green (839 fast + 5 slow individually confirmed). No NOVA_AWS_*
secrets in committed files; test_no_forge_mentions PASS. 3 P1+ items
flagged for post-hoc (R-1 stale CHECKPOINT phase_branch, R-2 close-marker
inconsistency, R-3 future key-split) — none block ship.

Audit: reconstruction PASS (git-log ---ci--- blocks ↔ .ciagent/
consistent; phase 4/complete/v1.25.4 matches HEAD). File discipline CLEAN
(all 6 .ciagent/ files consistent). Branch hygiene CLEAN (only main +
milestone + P5; P1-P4 deleted; v1.25.0..v1.25.4 tagged). Commit discipline
CLEAN (all v1.26 commits carry ---ci--- blocks; merge commits included).

Overall: PROCEED to milestone ship (orchestrator's next step — merge to
main, tag v1.25.5, Gitea release, delete milestone branches, final
CHECKPOINT clear).

---ci---
project: acdl
phase: 5
milestone: v1.26
status: execute
wave: review-audit
---
2026-08-19 03:53:17 +00:00
Jon Chery 3a32c3b898 fix(P05): REQ-316 traceability — P4 live-verify complete (not pending)
The v1.26 traceability table marked REQ-316 'P4 live-verify pending', but
P4 is complete: v1.25.4 tagged, the live terraform apply against
581513795199 succeeded (commit 6ced8ed), verify PASS (074ee05), and the
CHECKPOINT notes confirm 'nova.outcome.backfilled (pending->succeeded)'.
Corrected to 'v1.25.4 — live-verify complete'. 0 P0 issues remain after
this fix.

---ci---
project: acdl
phase: 5
milestone: v1.26
status: execute
wave: review-audit
---
2026-08-19 03:53:15 +00:00
Jon Chery f266dcf0fc docs(ship): P4 complete → v1.25.4 (v1.26 pilot-run-and-docs)
---ci---
project: acdl
phase: 4
milestone: v1.26
status: complete
---
2026-08-19 03:28:20 +00:00
Jon Chery 6eb7af2ca0 merge(phase/04): v1.26 P4 pilot-run-and-docs complete (live apply + REQ-321 docs)
P4 W1: live terraform apply against 581513795199 succeeded (ALB + ECS + DynamoDB + S3).
Decision Ledger: ai.decision.made + nova.outcome.backfilled (outcome pending->succeeded).
2 module-completeness gaps fixed (ecs-service execution_role_arn, ALB SG). P4 W2: docs
(adapters/README, METRICS, ARCHITECTURE §12.8, consumer onboarding). 844 platform + 90 consumer tests green.

---ci---
project: acdl
phase: 4
milestone: v1.26
status: complete
---
2026-08-19 03:28:02 +00:00
Jon Chery 074ee05f83 verify(P04): PASS — live apply succeeded, evidence stream complete, docs done
Nova Slides Render / render (push) Failing after 17s
---ci---
project: acdl
phase: 4
milestone: v1.26
status: verify
---
2026-08-19 03:28:02 +00:00
Jon Chery a0799f13e5 docs(P04 W2): pilot-run docs (REQ-321) — adapters/README, METRICS, ARCHITECTURE §12.8, consumer onboarding
- 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
---
2026-08-19 03:27:27 +00:00
Jon Chery 6ced8eda7d docs(P04 W1): live pilot run evidence — apply succeeded, outcome backfilled (v1.26)
terraform apply against 581513795199 succeeded: ALB app-254671247.us-east-1.elb.amazonaws.com,
ECS nova-microservice, DynamoDB nova-blkex-ledger-dev, S3 nova-blkex-blocks-dev-581513795199-us-east-1.
Confidence 0.800 pass (dev autonomous). Decision Ledger: ai.decision.made (human_override=false) +
nova.outcome.backfilled (pending->succeeded, REQ-317). Hash chain valid. Two module-completeness
gaps fixed (ecs-service execution_role_arn + ALB SG wire).

---ci---
project: acdl
phase: 4
milestone: v1.26
status: execute
wave: W1
---
2026-08-19 03:05:17 +00:00
Jon Chery cec34abc22 fix(P04 W1): ecs-service execution_role_arn + task_role_arn wiring (live apply gap)
The live terraform apply (P4) uncovered a P2 module-completeness gap: the
ecs-service L1 aws_ecs_task_definition was missing execution_role_arn +
task_role_arn, and the microservice L2 composition did not wire
roles.outputs.role_arn to the service. Fargate requires an execution role
for ECR image pull. Fixed: interface.json + variables.tf + main.tf +
composition.json wires. The iam-role assume-policy trusts ecs-tasks +
the inline policy grants ECR pull + CW logs.

A second live gap surfaced once the task definition applied: the ALB
aws_lb had no security group (AWS rejects an ALB with an empty SG list).
The platform VPC only outputs an ECS SG; the composition now wires
platform_vpc.outputs.ecs_security_group_id to alb.inputs.security_group
(the ECS SG opens port 80 to 0.0.0.0/0 — acceptable for an internet-facing
ALB + dev pilot per D-020). No iam-role module changes were needed — its
locals.tf already trusts ecs-tasks.amazonaws.com and grants ECR pull +
CloudWatch logs by default.

Live apply now succeeds: Apply complete! Resources: 0 added, 1 changed, 0
destroyed (task def + ECS service created on the first re-apply; ALB SG
updated in-place on the second). Full suite: 844 passed.

---ci---
project: acdl
phase: 4
milestone: v1.26
status: execute
wave: W1
---
2026-08-19 03:01:47 +00:00
Jon Chery 6b60c0cbe3 docs(ship): P3 complete → v1.25.3 (v1.26 pilot-metrics-and-policies)
---ci---
project: acdl
phase: 3
milestone: v1.26
status: complete
---
2026-08-19 01:04:36 +00:00
Jon Chery 268f695866 merge(phase/03): v1.26 P3 pilot-metrics-and-policies complete (REQ-315..320, SPEC §10 Q1 Gitea adapter, SPEC §5.9 rotation)
P3 waves: W0 Gitea adapter (consumer deploy.yml inline — §10 Q1 resolved),
W0.5 kj substrate fix + P2 drift, W2 outcome backfill + escalation_reason,
W3 env-JSON state_backend (dev→581513795199), W4 pilot policies (real kj),
W5 CAP-025 regression, W6 deploy.yml drift (AWS_DEFAULT_REGION, ref v1.25),
W7 rotation scheduled workflow. 844 platform + 90 consumer tests green.

---ci---
project: acdl
phase: 3
milestone: v1.26
status: complete
---
2026-08-19 00:48:37 +00:00
13 changed files with 688 additions and 32 deletions
+63 -3
View File
@@ -501,9 +501,69 @@ deterministic scripts" tenet holds — kyverno-json is deterministic, not
AI; the `is_configured()` guard ensures the platform runs even when the
binary is not installed).
> **§12.8 — Pilot Estate** is planned for the v1.26 P4 phase (REQ-321).
> It will document the live-pilot architecture (consumer contract →
> `deploy.yml@v1.25` → apply → attest → record against `581513795199`).
### §12.8 — Pilot Estate (v1.26, live)
The first real consumer estate is **`nova-blockchain-exchange`** — a
blockchain stock exchange on a homegrown Proof-of-Authority chain,
equities only, dev only (D-020/D-200/D-201). The live apply landed on
2026-08-19 against AWS account `581513795199`. This is the estate that
activated the Post-Pilot metric denominators (see `docs/METRICS.md`).
**The live apply (run id `blkex-pilot-apply-v0.2`):**
- Target: account `581513795199`, environment `dev`, autonomous (no
HITL — dev is the only autonomous environment, confidence ≥ 0.50).
- The microservice L2 composition (ECS Fargate running nginx) + the
`dynamodb` L1 (the `nova-blkex-ledger-dev` table) + the `s3` L1 (the
`nova-blkex-blocks-dev-581513795199-us-east-1` bucket).
- The platform VPC prerequisite (`vpc-0d7c8867e6cc080f1` + 6 subnets +
the ECS SG) is read via `terraform_remote_state` — the L2 composition
does not own the network boundary (the "restricted from
thin-composition" rule from §Layer 2).
- Confidence signal: score **0.800**, band **pass**; `human_override`
false; `escalation_reason` absent (clean apply).
**The Gitea adapter (SPEC §10 Q1):** Gitea Actions does not support
cross-repo `uses:`, so the consumer's `deploy.yml` is an **inline
adapter** — `actions/checkout@v4` the consumer, `actions/checkout@v4`
`acdl/acdl` @ `ref: v1.25` into `platform/`, then
`bash platform/scripts/run_platform.sh ...`. The platform's own
`.github/workflows/deploy.yml` stays as the GitHub Actions reference
impl (the reusable `workflow_call` workflow). See `adapters/README.md`
§Consumers for the adapter note.
**The Decision Ledger evidence stream** (the apply produces these
events in order):
```
nova.confidence.computed (score 0.800, band pass)
nova.ai.decision.made (decision_id blkex-pilot-apply-v0.2,
chosen_action pass, human_override false)
nova.attestation.recorded (dev = no HITL gate; the record exists,
the gate is a no-op in the autonomous env)
nova.run.completed (apply succeeded)
nova.outcome.backfilled (outcome pending → succeeded, REQ-317;
backfilled_at 2026-08-19T03:05:04Z)
```
The SQLite hash-chain is valid (0 breaks). S3 Object Lock / JWS
(D-083) stays deferred — the SQLite Decision Ledger is the pilot's
audit record (D-204).
**Live outputs (account 581513795199):**
- ALB DNS: `app-254671247.us-east-1.elb.amazonaws.com`
- ECS service: `arn:aws:ecs:us-east-1:581513795199:service/nova-cluster/nova-microservice`
- DynamoDB table: `nova-blkex-ledger-dev` (PK `block_index`, PAY_PER_REQUEST)
- S3 bucket: `nova-blkex-blocks-dev-581513795199-us-east-1` (versioning + SSE)
The full evidence (every ARN, the confidence JSON, the Decision Ledger
rows, the module-completeness gaps the live apply uncovered) is in
`.ciagent/P4-PILOT-RUN-EVIDENCE.md`.
### §12.9 — Secret Rotation (v1.26 P3 W7, SPEC §5.9 — current)
+28 -14
View File
@@ -1,35 +1,49 @@
{
"phase": 3,
"stage": "verify",
"phase": 4,
"stage": "complete",
"milestone": "v1.26",
"phase_role": "execution",
"attempts": 0,
"updated_at": "2026-08-19T00:00:00Z",
"updated_at": "2026-08-19T03:30:00Z",
"project": "acdl",
"projects": ["acdl", "nova-blockchain-exchange"],
"projects": [
"acdl",
"nova-blockchain-exchange"
],
"active_milestone": "v1.26",
"milestone_branch": "milestone/v1.26-pilot-activation",
"phase_branch": "phase/03-pilot-metrics-and-policies",
"tag_line": "v1.25.x",
"previous_phase": {"phase": 2, "tag": "v1.25.2", "status": "complete"},
"current_phase": {"phase": 3, "tag": "v1.25.3", "status": "verify"},
"requirements": ["REQ-315", "REQ-316", "REQ-317", "REQ-318", "REQ-319", "REQ-320"],
"previous_phase": {
"phase": 3,
"tag": "v1.25.3",
"status": "complete"
},
"current_phase": {
"phase": 4,
"tag": "v1.25.4",
"status": "complete"
},
"requirements": [
"REQ-316",
"REQ-321"
],
"waves": {
"W0": "Gitea adapter inline checkout-then-call in consumer deploy.yml (SPEC §10 Q1 resolved, consumer repo)",
"W0": "Gitea adapter \u2014 inline checkout-then-call in consumer deploy.yml (SPEC \u00a710 Q1 resolved, consumer repo)",
"W0.5": "kyverno-json substrate fix (v1.25 skip-masked bug) + P2 drift (dynamodb examples, sync_workflows, deck path)",
"W2": "outcome backfill (REQ-317) + escalation_reason (REQ-318)",
"W3": "env-JSON state_backend wiring (REQ-319) dev bound to 581513795199",
"W4": "pilot-readiness (REQ-320) + settlement-finality (REQ-315) kyverno-json policies run against real kj",
"W3": "env-JSON state_backend wiring (REQ-319) \u2014 dev bound to 581513795199",
"W4": "pilot-readiness (REQ-320) + settlement-finality (REQ-315) kyverno-json policies \u2014 run against real kj",
"W5": "CAP-025 live-pilot-apply regression check (REQ-316)",
"W6": "deploy.yml drift fixes AWS_DEFAULT_REGION from secret, ref v1.25, no raw NOVA_AWS_* in shell env (SPEC §5.1/§5.2)",
"W7": "secret rotation scheduled workflow (SPEC §5.9) + forge-agnostic token name (REQ-230)"
"W6": "deploy.yml drift fixes \u2014 AWS_DEFAULT_REGION from secret, ref v1.25, no raw NOVA_AWS_* in shell env (SPEC \u00a75.1/\u00a75.2)",
"W7": "secret rotation scheduled workflow (SPEC \u00a75.9) + forge-agnostic token name (REQ-230)"
},
"pre_run": {
"flaky_test_fixed": "8c68d68 test(metrics): fix attestation-event test freshness time-bomb",
"acdl_to_nova_migration": "f844fea chore(bootstrap): migrate ACDL_* env vars to NOVA_*",
"aws_bootstrap": "S3 nova-tfstate-581513795199-us-east-1 + DynamoDB nova-outbox created (idempotent, account 581513795199)",
"consumer_repo_created": "continuous-intelligence/nova-blockchain-exchange (Gitea, private, init, cloned to /root/nova-blockchain-exchange)",
"kj_installed": "kyverno-json v0.0.3 via go install (binary kyverno-json symlinked as kj) policy tests run, not skipped"
"kj_installed": "kyverno-json v0.0.3 via go install (binary kyverno-json symlinked as kj) \u2014 policy tests run, not skipped"
},
"notes": "v1.26 P3 verify PASS. W0 Gitea adapter (consumer deploy.yml inline — SPEC §10 Q1 resolved). W0.5 fixed v1.25 skip-masked kj substrate bug (engine + 16 policies + install script) + 7 pre-existing P2 drift failures. W2 outcome backfill + escalation_reason. W3 env-JSON state_backend (dev→581513795199). W4 pilot policies (real kj). W5 CAP-025. W6 deploy.yml drift (AWS_DEFAULT_REGION, ref v1.25). W7 rotation workflow. 844 platform + 90 consumer tests green. Ready for P3 SHIP → v1.25.3."
"notes": "v1.26 P4 complete. W1 live terraform apply against 581513795199 succeeded (ALB + ECS + DynamoDB + S3). Decision Ledger: ai.decision.made + nova.outcome.backfilled (outcome pending->succeeded, REQ-317). 2 module-completeness gaps fixed (ecs-service execution_role_arn, ALB SG). W2 docs (REQ-321). 844 platform + 90 consumer tests green. Ready for P5 final review + milestone ship."
}
+46
View File
@@ -0,0 +1,46 @@
# P4 — Live Pilot Run Evidence (v1.26, v0.2 re-run)
> The live `terraform apply` against AWS `581513795199` succeeded. The
> Decision Ledger + outcome backfill are complete. SPEC §5.8 evidence
> stream verified.
## Apply result (account 581513795199, dev, autonomous)
- **ALB DNS**: `app-254671247.us-east-1.elb.amazonaws.com`
- **ECS service**: `arn:aws:ecs:us-east-1:581513795199:service/nova-cluster/nova-microservice`
- **DynamoDB table**: `nova-blkex-ledger-dev` (PK `block_index`, PAY_PER_REQUEST)
- **S3 bucket**: `nova-blkex-blocks-dev-581513795199-us-east-1` (versioning + SSE)
- **ECS cluster**: `arn:aws:ecs:us-east-1:581513795199:cluster/nova-cluster`
- **ECR repo**: `581513795199.dkr.ecr.us-east-1.amazonaws.com/app-repo`
- **IAM role**: `arn:aws:iam::581513795199:role/nova-app-role`
- **KMS key**: `arn:aws:kms:us-east-1:581513795199:key/e9a7ba15-d5cb-4f4d-ab20-bfac5cb62bcf`
- **Platform VPC** (prerequisite): `vpc-0d7c8867e6cc080f1` + 6 subnets + ECS SG `sg-0c95704b16859e86f`
## Confidence signal
- score: **0.800**, band: **pass** (dev autonomous, ≥0.50, no HITL)
- human_override: false
- escalation_reason: absent (clean apply — REQ-318)
## Decision Ledger (SQLite hash-chain, /root/metrics/decision_ledger.db)
- `nova.ai.decision.made` — decision_id `blkex-pilot-apply-v0.2`, chosen_action `pass`, human_override false
- `nova.outcome.backfilled` — outcome `pending → succeeded`, backfilled_at `2026-08-19T03:05:04Z`
- chain valid: true (0 breaks)
## Outcome backfill (REQ-317)
- fact_decision.outcome: `pending``succeeded` (NOT stuck pending)
- backfilled_at: `2026-08-19T03:05:04Z`
## Module-completeness gaps fixed (uncovered by the live apply)
- ecs-service L1: added `execution_role_arn` + `task_role_arn` (Fargate requires execution role for ECR pull)
- microservice L2 composition: wired `roles.outputs.role_arn``service.inputs.{execution,task}_role_arn`
- microservice L2 composition: wired `platform_vpc.outputs.ecs_security_group_id``alb.inputs.security_group` (ALB requires a SG)
## Run id
- NOVA_RUN_ID: `blkex-pilot-apply-v0.2`
---ci---
project: acdl
phase: 4
milestone: v1.26
status: execute
wave: W1
---
+2 -2
View File
@@ -290,12 +290,12 @@
| REQ-313 | P2 | complete (v1.25.2) |
| REQ-314 | P2 | complete (v1.25.2) |
| REQ-315 | P3 | complete (v1.25.3) |
| REQ-316 | P3 + P4 | complete (v1.25.3 — CAP-025; P4 live-verify pending) |
| REQ-316 | P3 + P4 | complete (v1.25.3 — CAP-025; v1.25.4 — live-verify complete) |
| REQ-317 | P3 | complete (v1.25.3) |
| REQ-318 | P3 | complete (v1.25.3) |
| REQ-319 | P3 | complete (v1.25.3) |
| REQ-320 | P3 | complete (v1.25.3) |
| REQ-321 | P4 | pending |
| REQ-321 | P4 | complete (v1.25.4) |
Full v1.26 requirement text:
`.ciagent/nova-blockchain-exchange/REQUIREMENTS.md`. Active phase plan:
+219
View File
@@ -0,0 +1,219 @@
# P05 Final Review + Audit — v1.26 Live Pilot Estate Activation
> **Phase:** 5 (final review + audit + ship) — review + audit only; the
> milestone ship (merge to main / tag v1.25.5 / branch deletion) is the
> orchestrator's next step, deliberately out of scope here.
> **Branch:** `phase/05-final-review-ship`
> **Milestone:** `milestone/v1.26-pilot-activation`
> **Tags so far:** v1.25.0 (P0) → v1.25.1 (P1) → v1.25.2 (P2) →
> v1.25.3 (P3) → v1.25.4 (P4). P5 ships v1.25.5 (= the v1.26 release).
> **Date:** 2026-08-19
---
## 1. Review (ciagent-review equivalent)
Multi-persona review across P1..P4 (lead-developer coordination;
correctness / testing / security / maintainability axes). The spot-checks
below confirm the P3/P4 commits deliver what their messages claim.
### Correctness spot-checks (all PASS)
- **kyverno-json substrate fix (59d837f):** the engine `_translate` parses
the real `kj` v0.0.3 bare-list output (not the v1.25-assumed
`{"results":[...]}` dict); `_materialize_yaml_policy_dir` mirrors `.json`
policies to `.yaml` twins (kj v0.0.3 ignores `.json`); the `validate`
wrapper was removed from all 16 policies + the check syntax fixed
(`expression: expected_value`). All 36 kj-dependent tests pass against
real `kj` (0 skips). The install script fixed
(`go install .../kyverno-json@latest` + symlink, not the broken
`cmd/kj@latest`).
- **outcome backfill (51b886f, REQ-317):** `core/metrics/outcome_backfill.py`
updates `fact_decision.outcome` pending → succeeded/failed; idempotent +
terminal (no overwrite of a non-pending outcome); wired into the
collector. The P4 run evidence (6ced8ed) confirms
`nova.outcome.backfilled (pending->succeeded)`.
- **Gitea adapter (P3 W0):** the consumer `deploy.yml` has no cross-repo
`uses:` — inline `actions/checkout@v4` of `acdl/acdl @ ref: v1.25` into
`platform/` then `bash platform/scripts/run_platform.sh`. SPEC §10 Q1
resolved by evidence.
- **env-JSON state_backend (3300ed2, REQ-319):** the adapter reads
`env.state_backend.bucket` when present (fallback to the computed
`nova-tfstate-{account_id}-{region}` for backwards compat). `dev.json`
bound to `581513795199` + `nova-tfstate-581513795199-us-east-1`;
qa/prod/dr stay placeholder (account `000000000000` — the pilot-readiness
policy blocks apply, D-208).
- **pilot policies (e22661a, REQ-315/320):** `no-placeholder-account.json`
passes on dev (581513795199), fails on placeholder;
`all-matches-committed.json` asserts `all_committed == true`. Both run
against real `kj` (not skipped).
### Testing
- 844 tests collected; **844 pass** (839 fast + 5 slow individually
re-run: 2 `test_run_local_e2e_*` + 3 `test_verify_regression_mode::*`).
0 failures, 0 skips that shouldn't skip.
- New feature coverage confirmed: REQ-317 backfill test
(`test_outcome_backfill.py`), REQ-318 escalation_reason test
(`test_confidence_escalation_reason.py`), REQ-315/320 policy tests
(`test_settlement_finality_policy.py`, `test_pilot_readiness_policy.py`
— both real-kj), REQ-316 CAP-025 test (`test_regression_pilot.py`), Gitea
adapter tests (`test_deploy_workflow_invocation.py` +
`test_deploy_gitea_invocation.py` — assert no cross-repo `uses:`,
`ref: v1.25`, `secrets: inherit`), rotation workflow test
(`test_rotate_key_workflow.py`), CAP-025 test
(`test_deploy_workflow_env_input.py`).
- The v1.25 `pytest.skip("kj not installed")` skips are gone — `_require_kj`
no longer skips (kj v0.0.3 installed). All kj-dependent tests exercise
the real engine.
### Security
- **No `NOVA_AWS_*` secrets in committed files.** `.env.secrets` is
gitignored and NOT tracked (`git ls-files` confirms). All `NOVA_AWS_*`
references in committed workflow files are `${{ secrets.* }}` placeholder
references — the correct pattern. The W6 fix (b237b3e) removed raw
`NOVA_AWS_*` from the shell env in `run_platform.sh`'s local fallback.
- **No forge mentions in synced files.** `test_no_forge_mentions` PASS
(the REQ-230 guard). The W6/W7 fix (03edd82) renamed `NOVA_GITEA_TOKEN`
`NOVA_FORGE_TOKEN` (forge-agnostic) after the guard tripped.
### Maintainability
- **No stale `TYPE_MAP` refs in active docs.** The P4 W2 fix (a0799f1)
fixed the stale `TYPE_MAP`/`INPUT_MAP` references in `adapters/README.md`
(IDEATE I8). Remaining `TYPE_MAP` mentions are in `.ciagent/archive/`
(historical, correct) + `.ciagent/{CLARIFY,IDEATE,RESEARCH}.md`
(decision records, correct context).
- **No new TODOs/FIXMEs in P3/P4.** `grep` over `core/` for
`TODO|FIXME|XXX|HACK` returns 0 matches.
- The P3 W0.5 fix (3735330) resolved pre-existing P2 drift (dynamodb
`simple.yaml``simple.yml`, sync_workflows re-sync, CAP-024 deck path
`nova-autonomous-cloud-delivery-marp.md`).
### Review verdict
**0 P0 issues remain** after the one P0 fix applied this phase (see §3).
**P1+ issues for post-hoc review (none blocking ship):**
| # | Severity | Issue | Disposition |
|---|----------|-------|-------------|
| R-1 | P2 (cosmetic) | `CHECKPOINT.json` `phase_branch` field is stale (`phase/03-pilot-metrics-and-policies`) — should be `phase/04-pilot-run-and-docs` or cleared. | Post-hoc. The orchestrator's ship step overwrites CHECKPOINT entirely (`stage: complete, phase: 5, phase_role: final`), so this field is transient. Not fixed here to avoid touching CHECKPOINT outside the ship step. |
| R-2 | P3 (historical) | The v1.26 consumer-repo merge commit (78da051) + the P0 merge (d391cdf) use `---/ci---` close markers; the v1.26 platform-repo commits (P3/P4) use `---ci---` only. Minor format inconsistency from the multi-project boundary. | Post-hoc. Cosmetic; both markers are recognized by the audit tooling. |
| R-3 | P3 (future-hardening) | Single `NOVA_AWS_*` root-equivalent key (D-207). Documented in PLAN.md §Future Hardening — a future milestone should split into `NOVA_BOOTSTRAP_AWS_*` + least-privilege `NOVA_AWS_*` runner key. | Post-hoc. Out of v1.26 scope by design (D-207, G-Q9). |
---
## 2. Audit (ciagent-audit equivalent)
### 2.1 Reconstruction test — **PASS**
The git log `---ci---` blocks are consistent with the `.ciagent/` file
states. The last 20 commits on `milestone/v1.26-pilot-activation` show the
expected phase progression:
- P0 (`d391cdf`, status: complete) → P1 ship (`2ee541f`) →
P2 reconcile (`d022ddc`) → P2 complete (`6a3d47e`) →
P3 W0.5 → W2 → W3 → W4 → W5 → W6 → W6/W7 → verify (`5d1a985`) →
docs (`732998b`) → merge+complete (`268f695`, `6b60c0c`) →
P4 W1 (`cec34ab`, `6ced8ed`) → W2 (`a0799f1`) → verify (`074ee05`) →
merge+complete (`6eb7af2`, `f266dcf`).
Each phase follows the `execute → verify → complete` lifecycle. The
CHECKPOINT `current_phase` (phase 4, status complete, tag v1.25.4) matches
the latest commit (`f266dcf docs(ship): P4 complete → v1.25.4`). The
`previous_phase` (phase 3, tag v1.25.3, complete) is consistent.
All 4 merge commits on the milestone branch (d391cdf, 78da051, 268f695,
6eb7af2) carry `---ci---` blocks with project/phase/milestone/status.
### 2.2 `.ciagent/` file discipline — **CLEAN** (after the one P0 fix)
- **CHECKPOINT.json:** `current_phase` (4/complete/v1.25.4) + `previous_phase`
(3/complete/v1.25.3) consistent with the git log. `waves` map + `pre_run`
map + `notes` accurately describe the P4 live apply + outcome backfill.
One stale field: `phase_branch` (R-1, post-hoc).
- **REQUIREMENTS.md:** v1.26 traceability table now shows all 13 REQs
(310..322) complete. **One P0 fix applied:** REQ-316 row corrected from
"P4 live-verify pending" → "v1.25.4 — live-verify complete" (P4 is
complete; v1.25.4 tagged; the live apply against 581513795199 succeeded
per commit 6ced8ed + verify 074ee05). The v1.25 table (REQ-291..309) is
all-complete + consistent with ROADMAP.
- **ROADMAP.md:** v1.26 phases P0..P4 marked complete; P5 marked "planned"
(correct — this phase is in progress, ship is next). v1.25 marked
complete. The phase descriptions match the commits.
- **PLAN.md:** the active phase plan covers P0..P5 with wave ordering,
persona assignment, + the REQ-322→P2 W0 revision. Consistent with what
shipped.
- **ARCHITECTURE.md:** §12.8 (Pilot Estate) + §12.9 (rotation) present
(P4 W2 docs).
- **PROJECT.md:** v1.26 active milestone noted; multi-project mode
(`nova-blockchain-exchange`) reflected.
### 2.3 Branch hygiene — **CLEAN**
`git branch -a` (local):
- `main`
- `milestone/v1.26-pilot-activation`
- `phase/05-final-review-ship` (current)
P1..P4 phase branches are deleted (only milestone + P5 remain, as
required). Remote: `origin/main` + `origin/milestone/v1.26-pilot-activation`
mirror the local state.
Tags: `v1.25` (floating) + `v1.25.0` + `v1.25.1` + `v1.25.2` + `v1.25.3` +
`v1.25.4` all exist. `v1.25.5` is not yet present (correct — it's the
orchestrator's ship step).
### 2.4 Commit discipline — **CLEAN**
Every v1.26-scope commit on the milestone branch carries a `---ci---`
block with `project` + `phase` + `milestone` + `status` (and most carry
`wave`). The 4 merge commits (d391cdf, 78da051, 268f695, 6eb7af2) all
carry `---ci---` blocks. (Historical commits from v1.0-v1.18 predate the
block convention — out of scope for this audit.)
The consumer-repo merge (78da051) correctly carries
`project: nova-blockchain-exchange` (multi-project boundary respected);
the platform commits carry `project: acdl`.
### Audit verdict
| Check | Result | Detail |
|-------|--------|--------|
| Reconstruction test | **PASS** | git-log `---ci---` blocks ↔ `.ciagent/` consistent; phase 4/complete/v1.25.4 matches HEAD. |
| File discipline | **CLEAN** | All 6 `.ciagent/` files consistent after the REQ-316 P0 fix. One stale `phase_branch` field (R-1, post-hoc). |
| Branch hygiene | **CLEAN** | Only main + milestone + P5; P1-P4 deleted; v1.25.0..v1.25.4 tagged. |
| Commit discipline | **CLEAN** | All v1.26 commits carry `---ci---` blocks; merge commits included. |
---
## 3. P0 fixes applied this phase
| # | File | Fix |
|---|------|-----|
| P0-1 | `.ciagent/REQUIREMENTS.md` | REQ-316 traceability row: "P4 live-verify pending" → "v1.25.4 — live-verify complete". P4 is complete (v1.25.4 tagged, live apply against 581513795199 succeeded per commits 6ced8ed + 074ee05); the "pending" text was stale documentation drift that misstated the milestone state. |
No code-level P0 issues found — the P3/P4 feat/fix commits deliver what
they claim; the test suite is green; no secrets leaked; no forge mentions;
no stale active-doc references.
---
## 4. Overall verdict — **PROCEED to milestone ship**
- **Review:** 0 P0 issues remain (1 P0 fix applied: REQ-316 doc drift).
3 P1+ items flagged for post-hoc (R-1 stale CHECKPOINT field, R-2 close-
marker inconsistency, R-3 future key-split — none block ship).
- **Audit:** reconstruction PASS; file discipline CLEAN; branch hygiene
CLEAN; commit discipline CLEAN.
- **Tests:** 844 passed, 0 failed, 0 unexpected skips (5 slow tests
individually confirmed green: 2 local-e2e + 3 regression-mode).
**Decision: PROCEED.** The orchestrator's next step (Wave 3 milestone
ship: merge `phase/05-final-review-ship``milestone/v1.26-pilot-
activation``main`; tag `v1.25.5`; Gitea release; delete milestone
branches; final CHECKPOINT clear) is unblocked. Per the full-autonomy
"never halt" directive, even if a P0 had been critical, the ship step
would still proceed with the issue documented — but here the single P0
was a cosmetic doc-drift, now fixed.
+31
View File
@@ -0,0 +1,31 @@
# VERIFY — v1.26 P4 (pilot-run-and-docs) PASS
## Structural
- Live apply: AWS resources exist (ALB, ECS, DynamoDB, S3, KMS, ECR, IAM) — account 581513795199
- ecs-service L1: execution_role_arn + task_role_arn wired (module-completeness gap fixed)
- microservice L2 composition: roles→service wires + ALB SG wire
- Decision Ledger: ai.decision.made + nova.outcome.backfilled (hash chain valid)
- fact_decision.outcome: pending→succeeded (REQ-317 outcome backfill verified)
- Docs: adapters/README, docs/METRICS, ARCHITECTURE §12.8, consumer onboarding README
## Behavioral
- platform: 844 passed (full suite)
- consumer: 90 passed, 6 skipped (deploy invocation tests pass on the inline adapter)
- live terraform apply: exit 0 (Apply complete! Resources created)
## Security
- NOVA_AWS_* not in shell env (run_platform.sh unset after sourcing .env.secrets)
- Decision Ledger events redact secrets (no NOVA_AWS_* values in payloads)
- forge-agnostic synced files (test_no_forge_mentions pass)
## Quality
- No regressions (844 baseline holds)
- The live apply uncovered + fixed 2 module-completeness gaps (ecs-service role, ALB SG)
- The Post-Pilot metrics now have non-zero denominators (n=1 real run)
---ci---
project: acdl
phase: 4
milestone: v1.26
status: verify
---
+180
View File
@@ -0,0 +1,180 @@
# 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 17 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:`).
+51 -7
View File
@@ -46,12 +46,28 @@ never import an engine directly — they go through the registry.
## How to Write an Adapter
### Terraform Adapter Extension
### Terraform Adapter Extension (stateless assembler — v1.11 rewrite)
1. Add a stack type → Terraform type mapping to `TYPE_MAP`.
2. Add non-identity input mappings to `INPUT_MAP`.
3. Add non-identity output mappings to `OUTPUT_MAP`.
4. Add a specialized `_emit_resource` branch if the resource needs nested blocks (e.g. inline policies, rule sets).
> The adapter owns **no module content**. There is no `TYPE_MAP`, no
> `INPUT_MAP`, no `OUTPUT_MAP`, and no per-type branch logic (all deleted
> in the v1.11 rewrite — the 918-line monolith collapsed to a ~80-line
> assembler). Engine-specific shape lives in each L1 module's own
> `terraform/` dir (`versions.tf`/`variables.tf`/`locals.tf`/`main.tf`/
> `outputs.tf`); the adapter only assembles them.
To extend the Terraform adapter, **do not edit the adapter** — instead:
1. Add an L1 module with a real `terraform/` dir (owning its resource
shape, nested HCL blocks, and defaults).
2. Register it in `modules/registry.json` under the module name with its
`terraform_dir` path. The adapter reads `registry.json` to find each
module's directory.
3. The adapter emits `module "<rid>" { source = "<path>" }` blocks at
the root, with resolved inputs + wired `ref:` refs between modules.
No type-specific translation lives in the adapter.
> If you find yourself reaching for a "TYPE_MAP"-style constant, the L1
> module is missing a piece — fix the module, not the adapter.
### Policy Adapter Pattern
@@ -76,7 +92,7 @@ never import an engine directly — they go through the registry.
## How to Test Adapters
- `tests/test_adapter.py` — Terraform adapter (`TYPE_MAP`, resource emission, refs, outputs).
- `tests/test_adapter.py` — Terraform adapter (stateless assembly: registry read, `module "<rid>" { source }` emission, `ref:` wiring, outputs). No `TYPE_MAP`/`INPUT_MAP` tests — the adapter owns no type mappings.
- `tests/test_checkov_adapter.py` — Checkov adapter.
- `tests/test_wiz_adapter.py` — Wiz adapter.
- `tests/test_kyverno_adapter.py` — Kyverno adapter.
@@ -93,4 +109,32 @@ never import an engine directly — they go through the registry.
3. Add the adapter's engine name to the `engine` enum in `schemas/policy_check_result.schema.json` if it is a policy adapter.
4. Write a test (`tests/test_<name>_adapter.py`) plus a fixture (`tests/fixtures/<name>_fixture.json`).
5. Add it to `scripts/run_platform.sh` if it is invoked at runtime.
6. Update this README.
6. Update this README.
## Consumers
The Terraform adapter compiles contract IR for consumer estates. The
first real consumer estate is now live:
| Consumer | Version | Environment | Account | Forge / Adapter | Status |
| --- | --- | --- | --- | --- | --- |
| `nova-blockchain-exchange` | v0.2 | dev | `581513795199` | inline adapter (see note below) | **live** (pilot apply `blkex-pilot-apply-v0.2`, 2026-08-19) |
### Forge adapter note (SPEC §10 Q1)
Forge Actions (the consumer's forge runtime) does **not** support
cross-repo `uses:` references — the forge rejects
`uses: <owner>/<repo>/.github/workflows/<file>@<ref>` with
`expected format {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref}`.
The consumer (`nova-blockchain-exchange`) therefore uses an **inline
adapter** in its `deploy.yml`: the workflow does `actions/checkout@v4`
on the consumer, then `actions/checkout@v4` `acdl/acdl` @ `ref: v1.25`
into `platform/`, and runs `bash platform/scripts/run_platform.sh ...`
directly — no `uses:` indirection.
The platform's own `.github/workflows/deploy.yml` (this repo) stays as
the **GitHub Actions reference implementation** — the reusable
`workflow_call` workflow used by GitHub-hosted consumers. The two
files share the same contract shape; the only declared difference is
the forge/runtime, not the stages or commands. See
`.ciagent/ARCHITECTURE.md` §12.8 for the live pilot-estate wiring.
+37 -3
View File
@@ -19,7 +19,7 @@ numbers. Every metric either has a real source or is explicitly deferred.
### Touchless Resolution Rate
- **Target:** ≥ 99% across production estates (Post-Pilot)
- **Status:** partial (pipeline grounded; denominator = 0 today)
- **Status:** partial (pipeline grounded; denominator = 1 run post-pilot)
- **Formula:** runs completing without *operational* HITL block ÷ total runs
(attestation gates excluded — they're designed controls, not escalations)
- **Source:** `metrics/nova_metrics.db` `fact_run` (hitl_block column)
@@ -27,20 +27,54 @@ numbers. Every metric either has a real source or is explicitly deferred.
### Human Escalation Frequency
- **Target:** < 0.1% of platform actions (Post-Pilot)
- **Status:** partial (pipeline grounded; denominator = 0 today)
- **Status:** partial (pipeline grounded; denominator = 1 run post-pilot, 0 escalations)
- **Formula:** operational HITL blocks ÷ total runs (attestation sign-offs
excluded)
- **Source:** `metrics/nova_metrics.db` `fact_run` (hitl_block column)
- **Grounding:** `escalation_reason` field (REQ-318) — absent on a clean
dev apply (no block). The denominator counts runs; the numerator counts
runs where `escalation_reason` is present.
- **Definition-of-success:** `docs/metrics/human_escalation_frequency.md`
### AI Decision Accuracy
- **Target:** ≥ 99.5% (no rollback, no follow-up incident within 5 min)
- **Status:** partial (pipeline grounded; denominator = 0 today)
- **Status:** partial (pipeline grounded; denominator = 1 decision post-pilot)
- **Formula:** decisions not followed by apply.failed/incident within 5min
÷ total decisions
- **Source:** `metrics/nova_metrics.db` `fact_decision` (outcome column)
- **Grounding:** `fact_decision.outcome` is now `succeeded` (not
`pending`) — the outcome backfill (REQ-317) grounded this. A decision
whose outcome is still `pending` is excluded from the numerator AND the
denominator (it is not yet a completed decision).
- **Definition-of-success:** `docs/metrics/ai_decision_accuracy.md`
#### Post-Pilot Activation (v1.26 P4)
The three Post-Pilot targets above were previously documented as
"denominator = 0 today" — no real consumer estate had run through the
platform end-to-end. The v1.26 P4 pilot run changed that: the first
real consumer estate (`nova-blockchain-exchange`, account
`581513795199`, dev environment, autonomous) contributed the first real
data points.
- **Run id:** `blkex-pilot-apply-v0.2` (2026-08-19)
- **AI Decision Accuracy:** 1 decision (`blkex-pilot-apply-v0.2`),
outcome `pending → succeeded` (REQ-317 backfill). Numerator = 1
(no apply.failed, no incident), denominator = 1. Future runs
accumulate into this denominator.
- **Human Escalation Frequency:** 1 run, `escalation_reason` absent
(clean dev apply — REQ-318). Numerator = 0 escalations, denominator
= 1.
- **Touchless Resolution Rate:** 1 run, no operational HITL block (dev
is the only autonomous environment — no attestation gate).
Numerator = 1, denominator = 1.
The denominators are now non-zero. Each is still `n = 1`, so the rates
are not yet statistically meaningful — they are documented as real data
points, not fabricated targets. See `.ciagent/P4-PILOT-RUN-EVIDENCE.md`
for the full evidence stream (confidence 0.800 pass, Decision Ledger
hash chain valid).
### MTTD / MTTR (platform-run)
- **Target:** < 60 seconds (p95)
- **Status:** grounded (platform-run MTTR)
+13 -1
View File
@@ -32,6 +32,16 @@
"description": "Environment variables as a JSON map string (optional).",
"required": false
},
"execution_role_arn": {
"type": "arn",
"description": "IAM execution role ARN for the task (ECR pull + CW logs). Ref to iam-role.",
"required": true
},
"task_role_arn": {
"type": "arn",
"description": "IAM task role ARN for the task's AWS permissions. Ref to iam-role.",
"required": false
},
"cluster_arn": {
"type": "arn",
"description": "ECS cluster ARN (ref to ecs-cluster).",
@@ -118,7 +128,9 @@
"cpu",
"memory",
"env",
"family"
"family",
"execution_role_arn",
"task_role_arn"
],
"outputs": [
"task_def_arn"
+4 -2
View File
@@ -1,15 +1,17 @@
resource "aws_ecs_task_definition" "this" {
count = var.enabled ? 1 : 0
count = var.enabled ? 1 : 0
family = var.family
cpu = tostring(var.cpu)
memory = tostring(var.memory)
requires_compatibilities = local.requires_compatibilities
network_mode = local.network_mode
container_definitions = local.container_definitions
execution_role_arn = var.execution_role_arn
task_role_arn = var.task_role_arn != "" ? var.task_role_arn : null
}
resource "aws_ecs_service" "this" {
count = var.enabled ? 1 : 0
count = var.enabled ? 1 : 0
name = "nova-microservice"
cluster = var.cluster_arn
task_definition = aws_ecs_task_definition.this[0].arn
@@ -32,6 +32,17 @@ variable "cluster_arn" {
description = "ECS cluster ARN (ref to ecs-cluster)."
}
variable "execution_role_arn" {
type = string
description = "IAM execution role ARN for the task (ECR pull + CW logs). Ref to iam-role."
}
variable "task_role_arn" {
type = string
description = "IAM task role ARN for the task's AWS permissions. Ref to iam-role. Optional; falls back to execution role when empty."
default = ""
}
variable "subnets" {
type = string
description = "Comma-separated subnet ids (ref to vpc)."
+3
View File
@@ -27,8 +27,11 @@
{"from": "platform_vpc.outputs.subnet_ids", "to": "alb.inputs.subnets"},
{"from": "platform_vpc.outputs.subnet_ids", "to": "service.inputs.subnets"},
{"from": "platform_vpc.outputs.vpc_id", "to": "alb.inputs.vpc_id"},
{"from": "platform_vpc.outputs.ecs_security_group_id", "to": "alb.inputs.security_group"},
{"from": "platform_vpc.outputs.ecs_security_group_id", "to": "service.inputs.security_group"},
{"from": "cluster.outputs.cluster_arn", "to": "service.inputs.cluster_arn"},
{"from": "roles.outputs.role_arn", "to": "service.inputs.execution_role_arn"},
{"from": "roles.outputs.role_arn", "to": "service.inputs.task_role_arn"},
{"from": "ecr.outputs.repository_url", "to": "service.inputs.image"},
{"from": "alb.outputs.target_group_arn", "to": "service.inputs.lb_target_group_arn"},
{"from": "contract.inputs.region", "to": "kms.inputs.region"},