Close AUDIT-WP-0007 after live chain attestation.
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Migration 0006 applied on railiance01. Verify-against the dated
chain-head evidence is intact for 30 events.
This commit is contained in:
tegwick 2026-08-16 01:23:54 +02:00
parent 5fd04e2095
commit 61214bc24a
7 changed files with 46 additions and 15 deletions

View file

@ -31,12 +31,13 @@ audit-core exists to provide the capability described in INTENT.md.
- Status: production
- Production receiver on railiance01 (`namespace audit-core`), Postgres
operational custody on `platform-pg`, sender `user-engine`.
- Recovery is the platform `data.backup` window (30 days, RESOURCE-WP-0002
live). Live `/readyz` reports `custody_class=operational` and
`recoverable_days=30` (image `sha256:05fe1c06…`, 2026-08-16 cutover).
- ITC-CAP case: `data/capability/audit-core-operational.json`.
`data.archive` is an unmet requirement. `tamper_evidence` is still false.
- Open workplan: `workplans/AUDIT-WP-0007-integrity-verification.md`.
- Recovery is the platform `data.backup` window (30 days). Live `/readyz`
reports `custody_class=operational`, `tamper_evidence=true`,
`recoverable_days=30` (image `sha256:7febc28e…`).
- Hash chain verified on 30 live events
(`docs/evidence/chain-head-20260816.json`).
- ITC-CAP case: `data/capability/audit-core-operational.json` at D4.
`data.archive` is an unmet requirement.
## Getting Oriented

View file

@ -8,7 +8,7 @@ the server port or export a copy before applying.
Apply order is documented in `docs/operator-runbook.md`. Do not apply the
Deployment until:
1. The image digest is pinned (currently `sha256:05fe1c06…` from commit `40dcadd`).
1. The image digest is pinned (currently `sha256:7febc28e…` from commit `5fd04e2`).
2. Secrets `audit-core-database`, `audit-core-database-migrate`, and
`audit-core-senders` exist. ConfigMap `audit-core-senders-scope` is
applied (`deploy/senders-scope.yaml`) before the Deployment mounts it.

View file

@ -48,7 +48,7 @@ metadata:
audit-core.railiance.io/rollback-note: >-
Migrations 0001-0006 are additive. 0006 adds chain_hash/chain_prev and
then NOT NULL. An image that does not write those columns cannot accept
events after 0006. Do not roll back past sha256:05fe1c06… to a pre-0007
events after 0006. Do not roll back past sha256:7febc28e… to a pre-0007
writer. A future migration that drops or narrows a column must state
its own rollback position before it is released.
spec:
@ -80,7 +80,7 @@ spec:
- name: audit-core
# REPLACE at release time with the built digest. A mutable tag is not
# an immutable image, and `:latest` must never be the only reference.
image: forgejo.coulomb.social/coulomb/audit-core@sha256:05fe1c06f809be29309695c397025da755bfe82afed81a7f9b8771e0b9200c17
image: forgejo.coulomb.social/coulomb/audit-core@sha256:7febc28e8a828dbc245144a38e5728e0fbf496b594dd7591170b450a1265fb10
imagePullPolicy: IfNotPresent
ports:
- name: http

View file

@ -33,7 +33,7 @@ spec:
type: RuntimeDefault
containers:
- name: migrate
image: forgejo.coulomb.social/coulomb/audit-core@sha256:05fe1c06f809be29309695c397025da755bfe82afed81a7f9b8771e0b9200c17
image: forgejo.coulomb.social/coulomb/audit-core@sha256:7febc28e8a828dbc245144a38e5728e0fbf496b594dd7591170b450a1265fb10
imagePullPolicy: IfNotPresent
command: ["python", "-m", "audit_core", "migrate"]
env:

View file

@ -0,0 +1,9 @@
{
"accepted_at": "2026-08-13T15:38:37+00:00",
"chain_hash": "03fd1773c1954e2c39548b0ba297359b9edd739a94ff9b2dcc9529dcd5cf1fcc",
"event_count": 30,
"event_id": "evt_69aad81d75bb49c9b988be7650a5360d",
"genesis": "0000000000000000000000000000000000000000000000000000000000000000",
"observed_at": "2026-08-15T23:23:34+00:00",
"schema": "audit-core.chain-head.v1"
}

View file

@ -24,6 +24,8 @@ def test_capability_record_exists_and_joins_operations_audit():
unknown = [row for row in audit["consumes"] if row["basis"] == "unknown"]
assert unknown
assert all(row["quantity"]["value"] is None and row.get("gap") for row in unknown)
hooks = {item["hook"]: item["basis"] for item in audit["evidence"]}
assert hooks["integrity_verification"] == "measured"
def test_capability_review_against_live_catalog():

View file

@ -4,7 +4,7 @@ type: workplan
title: "Integrity verification for operational custody"
domain: infotech
repo: audit-core
status: active
status: finished
owner: grok
topic_slug: railiance
created: "2026-08-16"
@ -89,11 +89,14 @@ Write a short contract in `docs/audit-backend-contract.md` (or a sibling
Done when the contract is written and the tests to be added are named.
Done 2026-08-16: `docs/integrity.md` names the chain, genesis, proof bound,
and the six tests.
## T02 — Persist the chain on accept
```task
id: AUDIT-WP-0007-T02
status: todo
status: done
priority: high
state_hub_task_id: "5830bb1a-27b7-4eed-b09f-75ba8cc9f7f1"
```
@ -112,11 +115,14 @@ suite. Mock file backend stays `tamper_evidence=False`.
Done when conformance tests show: first accept sets genesis; second
links; duplicate does not fork; verify is clean on a fresh store.
Done 2026-08-16: migration 0006 plus backfill; SQLite and Postgres accept
write the next link under a lock. Conformance + `tests/test_integrity.py`.
## T03 — Verify surface
```task
id: AUDIT-WP-0007-T03
status: todo
status: done
priority: high
state_hub_task_id: "fee1f93c-dcac-4fc3-9e41-17bb4436e8d6"
```
@ -133,11 +139,14 @@ alone never gave us.
Done when CLI and HTTP agree, and the broken-row test is red-then-green
as a detector, not as a repair.
Done 2026-08-16: `verify-chain` CLI, `GET /v1/integrity`, SQLite rewrite
test and Postgres superuser rewrite test both fail verify.
## T04 — Attest the chain head outside platform-pg
```task
id: AUDIT-WP-0007-T04
status: todo
status: done
priority: medium
state_hub_task_id: "b6d03d6a-0605-4982-a9a3-e18c89319ba9"
```
@ -158,11 +167,17 @@ and report mismatch as a break.
Done when one production walk produces an attestation file in
`docs/evidence/` and verify-against-attestation is tested.
Done 2026-08-16: live walk 30 events, intact, head
`03fd1773…`. Evidence
`docs/evidence/chain-head-20260816.json`. Verify-against matched.
Do not copy this file into the Barman prefix; a second copy may follow
RESOURCE-WP-0002-T06 logical-offsite.
## T05 — Declare tamper_evidence only as far as the proof
```task
id: AUDIT-WP-0007-T05
status: todo
status: done
priority: medium
state_hub_task_id: "9fd70d3c-5a64-4b26-967f-4ef45394d81c"
```
@ -182,6 +197,10 @@ After T03 and T04:
Done when capability-review still `ok` and the hook is no longer
`unknown`.
Done 2026-08-16: Postgres `tamper_evidence=True`; live `/readyz` reports
it; capability-review `ok`; `integrity_verification` is `measured`.
Maturity stays D4. `data.archive` stays unmet.
## Acceptance
- A rewritten stored payload makes `verify` fail.