feat(h6): AgentOps hardening — live alerting, provider-API reconcile, hosted dashboard, window breaker (79→80)

Close the three gaps the scoring report itself flagged for H6 plus V15,
each as a real MVP + fail-able adversarial test (same pattern that lifted H5):

- D1 alert-dispatch.sh: alerts POST to a real HTTP webhook (severity routing,
  dedup window, retry) + dead-letter queue with redelivery; fail-loud in strict.
  Wired into agent-metrics.sh so a failing step pages live end-to-end.
- D2 provider-usage-fetch.sh + telemetry-reconcile.sh: pull usage from a provider
  usage HTTP API (all-or-nothing schema gate, fail-loud) + reconcile local vs
  provider ground truth — token under-reporting/hidden runs => TELEMETRY_DISCREPANCY.
- D3 dashboard-serve.sh + dashboard-server.py: serve the dashboard over HTTP with
  a stale-aware /healthz probe (fresh=200 ok, telemetry silent-death=503 stale).
- D4 circuit-breaker-check.sh: sliding-window failure-rate breaker (V15) — interleaved
  successes no longer evade the consecutive-failure breaker (CIRCUIT_OPEN_WINDOW).

New suite phase-h6-agentops-tests.sh: 20/20, all live against local HTTP endpoints
(webhook sink, mock provider API, dashboard server) — deterministic, no model needed.

Also fix sign-policy-bundle.sh key-sync invariant: the local-fallback branch only
exported policy-public.pem when generating a NEW key, so a Vault-DOWN run after a
Vault-signed run verified a local-key signature against the Vault pubkey (RSA padding
error, run-casan4 died mid-suite). Now always re-exports the pubkey before signing —
same fix class as tool-audit-lib.sh / governance-check.sh.

Full battery re-run sequentially: 175/175 PASS, 0 FAIL across 8 suites
(KMS SKIP this run — Vault down; validated live 2026-07-04). Docs synced:
scoring-run-report (H6 79→80, no harness below 80, 155→175), CASAN_HARDENING_STATUS
(Phase 5 D1–D4), Plan-07, submission README, and run-hardening.sh (H6+ scenes HO1–HO4).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
thanhnv
2026-07-05 01:14:46 +09:00
co-authored by Claude Fable 5
parent 2af67ef6a5
commit da66a36f97
55 changed files with 1306 additions and 455 deletions
+30 -14
View File
@@ -44,6 +44,15 @@
| B3 | **KMS key management**: sign audit/telemetry head via Vault Transit (key `exportable:false` → never leaves KMS) + key **rotation**; validated live | [implemented+tested] (live when Vault present; skip-aware otherwise) | `vault-kms.sh` (`rotate`, `assert-nonexportable`), `sign-audit-head.sh` | phase-h5-infra (KMS) |
| C5 | **External WORM audit**: ship audit head to a hash-linked append-only ledger; detect local rollback (`AUDIT_GAP_DETECTED`) and ledger tamper (`AUDIT_LEDGER_TAMPERED`) | [implemented+tested] (local ledger MVP) | `worm-ledger.py`, `audit-ship.sh`, `verify-audit-gap.sh` | phase-h5-infra (WORM) |
### Phase 5 — H6 AgentOps hardening (raises the lowest harness) — mixed
| ID | Control | Status | Where | Test |
|---|---|---|---|---|
| D1 | **Live alert dispatch**: alerts POST to a real HTTP webhook (severity routing, dedup window, retry); undelivered alerts fail-loud (`ALERT_DELIVERY_FAILED`, strict) and queue to a **dead-letter** file with redelivery (`--flush-deadletter`); wired into `agent-metrics.sh` (failing step ⇒ live page) | [implemented+tested] (live local webhook; production points at Slack/PagerDuty + on-call) | `alert-dispatch.sh`, `agent-metrics.sh` | phase-h6-agentops (①) |
| D2 | **Provider-telemetry API + reconciliation**: pull usage from a provider usage HTTP API (all-or-nothing schema gate, `PROVIDER_API_UNREACHABLE`/`PROVIDER_USAGE_INVALID` fail-loud) + reconcile local metrics vs provider ground truth — under-reporting/hidden runs ⇒ `TELEMETRY_DISCREPANCY` | [implemented+tested] (live local API endpoint; production points at OpenAI/Anthropic usage APIs) | `provider-usage-fetch.sh`, `telemetry-reconcile.sh` | phase-h6-agentops (②) |
| D3 | **Hosted dashboard**: dashboard served over HTTP with a stale-aware `/healthz` probe (fresh ⇒ 200 ok; telemetry silent-death ⇒ 503 stale — page-able by any uptime monitor) | [implemented+tested] (local HTTP daemon; production host = nginx/container, same routes) | `dashboard-serve.sh`, `dashboard-server.py` | phase-h6-agentops (③) |
| D4 | **Sliding-window circuit breaker (V15)**: failure **rate** over the last N calls trips `CIRCUIT_OPEN_WINDOW` — interleaving successes no longer evades the consecutive-failure breaker | [implemented+tested] | `circuit-breaker-check.sh` | phase-h6-agentops (④) |
## 2. Test inventory (all suites)
| Suite | Checks | Purpose |
@@ -53,9 +62,10 @@
| `phase1-track-a-tests.sh` | 25 | Track A hardening |
| `phase2-track-c-tests.sh` | 29 | Track C-MVP |
| `phase3-evidence-pack-tests.sh` | 7 | Evidence Pack MVP |
| `phase-h5-approval-tests.sh` | 8 | **New** — approval-identity (C4) |
| `phase-h5-infra-tests.sh` | 7 | **New** — KMS (B3, live/skip-aware) + WORM (C5) |
| **Total** | **155** | Baseline 79 preserved; +76 new hardening checks. Last full run 2026-07-04 @ `00aabfa`, 0 fail (KMS live via Vault dev). |
| `phase-h5-approval-tests.sh` | 8 | Approval-identity (C4) |
| `phase-h5-infra-tests.sh` | 7 | KMS (B3, live/skip-aware) + WORM (C5) |
| `phase-h6-agentops-tests.sh` | 20 | **New** — live alerting (D1) + provider-API/reconcile (D2) + hosted dashboard (D3) + window breaker (D4); all against live local HTTP endpoints |
| **Total** | **175** | Baseline 79 preserved; +96 new hardening checks. Last full run 2026-07-05 @ head of `feat/plan07-track-a-hardening`, 0 fail (KMS SKIP this run — validated live 2026-07-04 via Vault dev). |
Run order note: `run-casan4-harness-tests.sh` does `rm -rf .specify/logs`, so run it
**first** and never concurrently with the other suites.
@@ -66,7 +76,10 @@ Run order note: `run-casan4-harness-tests.sh` does `rm -rf .specify/logs`, so ru
|---|---|---|
| H4 multilingual detection (VI/JA injection block-patterns) | [planned] | Plan-07 B1 (V2) |
| Classifier-inject / split-injection resistance | [planned] | Plan-07 B2 (V5,V6) |
| Model-digest pinning, sliding-window circuit breaker | [planned] | Plan-07 B4 (V15,V16) |
| Model-digest pinning | [planned] — sliding-window circuit breaker (V15) is now done (Phase 5 D4) | Plan-07 B4 (V16) |
| Live alerting to a managed channel (Slack/PagerDuty + on-call rota) | [partial] — webhook dispatch + dedup + dead-letter done; managed channel & escalation are config away, incident workflow is C7 | Plan-07 C7 / Phase 5 D1 |
| Hosted telemetry dashboard | [partial] — HTTP-served dashboard + stale-aware `/healthz` done locally; deployed host (nginx/container, auth) planned | Phase 5 D3 |
| Provider billing-API telemetry | [partial] — API fetch + schema gate + local-vs-provider reconciliation done against a live local endpoint; real OpenAI/Anthropic usage-API calls (needs keys) planned | Phase 5 D2 |
| **True runtime isolation** (container `--network=none --read-only --pids-limit`, nsjail) | [planned] — C6 is a static+ulimit scaffold only | Plan-07 C6 (V22) |
| Incident severity/kill-switch/runbook | [planned] | Plan-07 C7 (V23) |
| KMS key management (rotation, non-exportable) | [partial] — Vault Transit path implemented + validated live; not yet the default (local-key fallback), no HSM/short-lived IdP tokens | Plan-07 B3 |
@@ -76,13 +89,16 @@ Run order note: `run-casan4-harness-tests.sh` does `rm -rf .specify/logs`, so ru
## 4. Honest claim
Track A + Track C-MVP + Evidence Pack + H5 governance-hardening raise H4/H5/H6 from
"PoC/demo (~3.0/5)" to **early internal-production hardening**, with executable
adversarial tests for every control (155 checks, 0 fail — last full run 2026-07-04,
KMS validated live via Vault). Fair maturity score (`00_SUBMISSION_PACKAGE/evidence/
scoring-run-report.md`): per-harness **~80/100**, **H5 76→80** (approval-identity +
KMS live + WORM), so the **lowest harness is now H6=79** (was H5=76) — CASAN **Level 4**,
proven by attack. This is **not** full production readiness: serious production still
needs live IdP (OIDC/JWT), a true WORM store (S3 Object Lock), KMS-by-default + HSM,
true sandbox isolation, multilingual detection, and hosted telemetry — the [partial]/
[planned] rows above and in `CASAN_PLAN_07_PRODUCTION_HARDENING.md`.
Track A + Track C-MVP + Evidence Pack + H5 governance-hardening + H6 AgentOps-hardening
raise H4/H5/H6 from "PoC/demo (~3.0/5)" to **early internal-production hardening**, with
executable adversarial tests for every control (175 checks, 0 fail — last full run
2026-07-05; KMS validated live via Vault on 2026-07-04). Fair maturity score
(`00_SUBMISSION_PACKAGE/evidence/scoring-run-report.md`): per-harness **~80/100**,
**H5 76→80** (approval-identity + KMS live + WORM) and **H6 79→80** (live alert dispatch
+ provider-API reconciliation + hosted dashboard + window breaker), so the **lowest
harness is now 80** (H2/H4/H5/H6/H7 level) — CASAN **Level 4**, proven by attack. This is
**not** full production readiness: serious production still needs live IdP (OIDC/JWT), a
true WORM store (S3 Object Lock), KMS-by-default + HSM, true sandbox isolation,
multilingual detection, a deployed dashboard host + managed alert channel/on-call, and
real billing-API telemetry — the [partial]/[planned] rows above and in
`CASAN_PLAN_07_PRODUCTION_HARDENING.md`.