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 - Status: production
- Production receiver on railiance01 (`namespace audit-core`), Postgres - Production receiver on railiance01 (`namespace audit-core`), Postgres
operational custody on `platform-pg`, sender `user-engine`. operational custody on `platform-pg`, sender `user-engine`.
- Recovery is the platform `data.backup` window (30 days, RESOURCE-WP-0002 - Recovery is the platform `data.backup` window (30 days). Live `/readyz`
live). Live `/readyz` reports `custody_class=operational` and reports `custody_class=operational`, `tamper_evidence=true`,
`recoverable_days=30` (image `sha256:05fe1c06…`, 2026-08-16 cutover). `recoverable_days=30` (image `sha256:7febc28e…`).
- ITC-CAP case: `data/capability/audit-core-operational.json`. - Hash chain verified on 30 live events
`data.archive` is an unmet requirement. `tamper_evidence` is still false. (`docs/evidence/chain-head-20260816.json`).
- Open workplan: `workplans/AUDIT-WP-0007-integrity-verification.md`. - ITC-CAP case: `data/capability/audit-core-operational.json` at D4.
`data.archive` is an unmet requirement.
## Getting Oriented ## 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 Apply order is documented in `docs/operator-runbook.md`. Do not apply the
Deployment until: 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 2. Secrets `audit-core-database`, `audit-core-database-migrate`, and
`audit-core-senders` exist. ConfigMap `audit-core-senders-scope` is `audit-core-senders` exist. ConfigMap `audit-core-senders-scope` is
applied (`deploy/senders-scope.yaml`) before the Deployment mounts it. applied (`deploy/senders-scope.yaml`) before the Deployment mounts it.

View file

@ -48,7 +48,7 @@ metadata:
audit-core.railiance.io/rollback-note: >- audit-core.railiance.io/rollback-note: >-
Migrations 0001-0006 are additive. 0006 adds chain_hash/chain_prev and 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 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 writer. A future migration that drops or narrows a column must state
its own rollback position before it is released. its own rollback position before it is released.
spec: spec:
@ -80,7 +80,7 @@ spec:
- name: audit-core - name: audit-core
# REPLACE at release time with the built digest. A mutable tag is not # REPLACE at release time with the built digest. A mutable tag is not
# an immutable image, and `:latest` must never be the only reference. # 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 imagePullPolicy: IfNotPresent
ports: ports:
- name: http - name: http

View file

@ -33,7 +33,7 @@ spec:
type: RuntimeDefault type: RuntimeDefault
containers: containers:
- name: migrate - name: migrate
image: forgejo.coulomb.social/coulomb/audit-core@sha256:05fe1c06f809be29309695c397025da755bfe82afed81a7f9b8771e0b9200c17 image: forgejo.coulomb.social/coulomb/audit-core@sha256:7febc28e8a828dbc245144a38e5728e0fbf496b594dd7591170b450a1265fb10
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
command: ["python", "-m", "audit_core", "migrate"] command: ["python", "-m", "audit_core", "migrate"]
env: 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"] unknown = [row for row in audit["consumes"] if row["basis"] == "unknown"]
assert unknown assert unknown
assert all(row["quantity"]["value"] is None and row.get("gap") for row in 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(): def test_capability_review_against_live_catalog():

View file

@ -4,7 +4,7 @@ type: workplan
title: "Integrity verification for operational custody" title: "Integrity verification for operational custody"
domain: infotech domain: infotech
repo: audit-core repo: audit-core
status: active status: finished
owner: grok owner: grok
topic_slug: railiance topic_slug: railiance
created: "2026-08-16" 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 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 ## T02 — Persist the chain on accept
```task ```task
id: AUDIT-WP-0007-T02 id: AUDIT-WP-0007-T02
status: todo status: done
priority: high priority: high
state_hub_task_id: "5830bb1a-27b7-4eed-b09f-75ba8cc9f7f1" 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 Done when conformance tests show: first accept sets genesis; second
links; duplicate does not fork; verify is clean on a fresh store. 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 ## T03 — Verify surface
```task ```task
id: AUDIT-WP-0007-T03 id: AUDIT-WP-0007-T03
status: todo status: done
priority: high priority: high
state_hub_task_id: "fee1f93c-dcac-4fc3-9e41-17bb4436e8d6" 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 Done when CLI and HTTP agree, and the broken-row test is red-then-green
as a detector, not as a repair. 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 ## T04 — Attest the chain head outside platform-pg
```task ```task
id: AUDIT-WP-0007-T04 id: AUDIT-WP-0007-T04
status: todo status: done
priority: medium priority: medium
state_hub_task_id: "b6d03d6a-0605-4982-a9a3-e18c89319ba9" 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 Done when one production walk produces an attestation file in
`docs/evidence/` and verify-against-attestation is tested. `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 ## T05 — Declare tamper_evidence only as far as the proof
```task ```task
id: AUDIT-WP-0007-T05 id: AUDIT-WP-0007-T05
status: todo status: done
priority: medium priority: medium
state_hub_task_id: "9fd70d3c-5a64-4b26-967f-4ef45394d81c" 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 Done when capability-review still `ok` and the hook is no longer
`unknown`. `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 ## Acceptance
- A rewritten stored payload makes `verify` fail. - A rewritten stored payload makes `verify` fail.