Statewave v0.9.1 — v0.9 governance release correction
v0.9.0 was cut too early and does not contain the full v0.9 governance stack. v0.9.1 is the canonical v0.9 governance release.
What v0.9 delivers
Receipts, auto-labeling, replay, and residency — the v0.8 governance foundation extended into an end-to-end audit story:
- Scheduled retention-purge worker (#162, closes #156) — hourly worker reads
tenant_configs.config.receipt_retention_daysand tombstones expired receipts. Soft-delete only; partial index keeps it cheap. Migration 0020. - HMAC-signed receipts (#163, closes #157) —
hmac-sha256-canonical-v1over the canonical receipt body. Operator-provided keys viaSTATEWAVE_RECEIPT_SIGNING_KEYS(never persisted to DB).GET /v1/receipts/{id}/verifyreturns{valid: true | false | null, key_id, algorithm, reason}with constant-time compare. Pre-v0.9 receipts verify cleanly asno_signature. Migration 0021. - Heuristic auto-labeling pipeline (#164, closes #158) — opt-in
STATEWAVE_AUTO_LABELING_ENABLEDstamps advisorysuggested_labels(strictly separate from authoritativesensitivity_labels). v0.9 first wave:pii.email,pii.phone,financial.card(Luhn),secret.token. Migration 0022 (GIN-indexed). - Receipt replay (#165, closes #159) — every v0.9+ receipt embeds the active policy bundle's YAML in
policy_snapshot.POST /v1/receipts/{id}/replayre-runs the original retrieval against current memories with the original policy, returning a structural diff envelope. Mode"as_of_replay", child receipts link to the parent. Semantic: current code + original policy. Migration 0023. - Admin review/promote/replay UI (#166 + statewave-admin#89, closes #160) —
POST /admin/memories/{id}/promote-labelsis review-only with audit-trail entries onmemory.metadata.label_promotions. Admin app gains a/suggested-labelspage and a Replay button on receipt detail that renders the diff envelope inline. - Per-tenant residency (#167, closes #161) —
STATEWAVE_REGION+tenant_configs.config.region. Hard application-layer enforcement on/v1/AND/admin/(total isolation). HTTP 403residency.mismatchon conflict. Receipts stampregionfor end-to-end audit. Code + config + tests + ops runbook shipped. - Handoff replay symmetry (#168) —
/v1/handoffreceipts now stamp the samepolicy_snapshotas retrieval receipts; both paths are replayable through the same endpoint. Pre-fix handoff receipts remain backwards-compatible and returnunreplayable.missing_policy_snapshot. - Release-hardening docs sweep — #168 (server README + receipt/replay docs) + statewave-docs#45 (changelog, roadmap, receipts, sensitivity-labels, api/v1-contract, ADR-001 Postgres positioning) + statewave-admin#90 (admin app README + sidebar v0.9 footer).
API surface added (no breaking changes)
| Endpoint | Purpose |
|---|---|
GET /v1/receipts/{id}/verify |
HMAC signature verification |
POST /v1/receipts/{id}/replay |
As-of replay against current memories + original policy |
POST /admin/receipts/{id}/replay |
Admin-proxy shim mirroring the public endpoint |
GET /admin/memories/with-suggested-labels |
Review queue for auto-labeling suggestions |
POST /admin/memories/{id}/promote-labels |
Explicit operator commit of suggestions into sensitivity_labels |
Migrations (additive, reversible)
0020_receipts_retention · 0021_receipts_signature_keyid · 0022_memories_suggested_labels · 0023_receipts_policy_snapshot
DB head moves from 0019_per_tenant_bundles (v0.8) to 0023_receipts_policy_snapshot (v0.9.1). No data backfill required; pre-v0.9 rows carry NULL on the new columns and remain fully functional.
Backwards compatibility
- Pre-v0.9 receipts verify as
no_signatureand refuse replay withunreplayable.missing_policy_snapshot— same contract as a fresh tenant that hasn't opted into signing. - Pre-fix handoff receipts (emitted between v0.9 ship and #168) carry NULL
policy_snapshotand remain backwards-compatible:/v1/receipts/{id}/replayreturnsunreplayable.missing_policy_snapshotfor them. - No breaking API changes beyond the new endpoints listed above.
Deferred to v0.10
Visual policy editor · Admin identity (so promoted_by populates) · Bulk label promotion · Federated cross-region audit · Memory snapshots for byte-for-byte replay. Listed explicitly in CHANGELOG.md, roadmap.md, and the server README's Current limitations.
Why v0.9.1 instead of moving v0.9.0
The published v0.9.0 tag (at e51a553) and its GitHub release predate the v0.9 governance work. Moving a published tag breaks anyone who already consumed it; cutting an additive v0.9.1 preserves immutability of published tags while making the canonical v0.9 release point at the actual v0.9 commit (4036f4f).