Commit graph

175 commits

Author SHA1 Message Date
a1f625a644 Prove tenant-engine live accept and close AUDIT-WP-0010
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
A labeled Job in tenant-engine posted 202 then duplicate 200.
Chain intact (60 events). AUDIT-IN-0002 promoted. Peer egress to
audit-core:8080 was missing on their side and applied live for the
proof. No token values recorded.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 22:21:22 +02:00
d68823ff06 chore(consistency): refresh work-record index after T02
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s
Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 22:07:08 +02:00
custodian-sync
01a9e3a6b3 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
Updated by fix-consistency on 2026-09-15:
  - update .custodian-brief.md for audit-core

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 22:06:50 +02:00
535876a2e9 Record attended tenant-engine sender mint (AUDIT-WP-0010-T02)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Registry version 9 includes tenant-engine with a token. ExternalSecret
synced and the receiver is Ready. Evidence is metadata only; no secret
values. Producer file projection remains tenant-engine's for live 202.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 22:06:06 +02:00
ede59ba8fb Pin attended sender mint to the operator OpenBao tunnel
Public bao.coulomb.social was retracted today and now presents
Traefik's default certificate. Login must use http://127.0.0.1:18200
via openbao-attended-exec.py, matching the sitting-requester path.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 21:59:28 +02:00
7c0f270b44 Export BAO_ADDR in the parent before attended sender mint
warden access runs OIDC from the caller environment. Putting BAO_ADDR
only on the child env argv leaves bao login talking to the wrong
address, which fails before command handoff.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 21:42:01 +02:00
46d55ba8e0 Add silent attended mint for the tenant-engine sender
AUDIT-WP-0010-T02. Contained platform-admin login writes tenant-engine
into the OpenBao senders registry with CAS, force-syncs the
ExternalSecret, and recreates the receiver so it re-reads identities.
No token value is printed; metadata evidence only.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 21:35:28 +02:00
custodian-sync
9fd30e66a1 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-09-15:
  - update .custodian-brief.md for audit-core

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 21:19:38 +02:00
2fbc1df3b5 chore(consistency): refresh work-record index after T12
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 21:19:01 +02:00
custodian-sync
bc0560a3b0 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Updated by fix-consistency on 2026-09-15:
  - update .custodian-brief.md for audit-core

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 21:18:53 +02:00
4c940d49ae Operate scheduled chain-head attestation (AUDIT-WP-0009-T12)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Apply the separate attestor identity, named-ConfigMap RBAC, attest
egress and daily CronJob. Bootstrap an empty chain-head ConfigMap
only because it was absent; drop the placeholder from the apply path
so a later apply cannot overwrite a live head. One-shot job published
a 59-event attestation; mounted readback and receiver write-denial
passed. Offsite copy stays the operator path.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 21:18:17 +02:00
805bacbc14 Record runtime lease remint and receiver Ready after ESO token refresh
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 3s
Attended orphan-token remint succeeded. ClusterSecretStore needed a
force-sync to drop the cached 403. ExternalSecrets synced, the mounted
lease rotated, and /readyz returned 200 in 6ms. No secret values.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 00:09:39 +02:00
aad5a75ca6 Silence the runtime-lease remint for contained warden --exec
Warden fails closed on any child stdout or stderr, even on success.
The previous helper echoed status and prompted for BAO_TOKEN after
the login envelope had already unset it. Use the contained
.vault-token helper, write Kubernetes Secret from a file, and persist
only metadata evidence.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-15 00:02:35 +02:00
custodian-sync
802356efae chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-09-14:
  - update .custodian-brief.md for audit-core

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-14 23:55:20 +02:00
ca6a608b16 Add attended runtime-lease remint helper for the expired ESO token
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 5s
The 768h orphan token in external-secrets/openbao-audit-core-eso-token
expired at 2026-09-14T10:23Z and ClusterSecretStore lookup-self is 403,
so ESO cannot mint database/creds/audit-core-runtime. Recreate the
Kubernetes Secret without last-applied-configuration so the token is
not stored in annotation metadata.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-14 23:54:35 +02:00
cf8c740b1b Switch receiver rollout to Recreate and pin bounded-readyz image
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
RollingUpdate maxSurge cannot schedule a second 50m pod on a node
packed to 99% CPU requests. Recreate replaces in place; the Service
already has no ready endpoints.

Image sha256:ec15f63d… is commit bc3d80f. Local release check passed
against disposable Postgres. No schema migration. Live Ready still
depends on a fresh runtime lease from ESO/OpenBao.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-14 23:01:23 +02:00
bc3d80fbd9 chore(consistency): record ADHOC-2026-09-14 hub identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-14 22:15:16 +02:00
b0e6792cf0 Bound /readyz so kubelet probes cannot hang the Service
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
/readyz walked the hash chain and opened pooled connections with no
libpq connect_timeout, so a 2s kubelet probe never saw a response and
the pod stayed unready. Informed Decision accept is blocked on that.

Probe health() only, under a 1.5s budget, publish last-known
tamper_evidence, and fail TCP handshake in 1s. Integrity stays on
/v1/integrity.

Assistant: grok
Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
2026-09-14 22:13:55 +02:00
e7e054d8d6 Classify open workplans with flavor (CUST-WP-0072).
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s
Set flavor on open workplans from origin/prose/status. Copy existing
depends_on aliases only. Do not promote residuals.

Assistant: grok
Assistant-Session: 01a09dc1-b21e-77e1-919e-fcad2f82b267
2026-09-14 15:50:41 +02:00
custodian-sync
b8cf8f91c0 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-09-11:
  - update .custodian-brief.md for audit-core

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 16:37:33 +02:00
3a13a05073 Accept independent readback of both native factory sender probes
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 16:35:14 +02:00
custodian-sync
a400b9d3da chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-09-11:
  - update .custodian-brief.md for audit-core

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 14:23:32 +02:00
0b30bfb08c Record native sender acceptance and retained audit readback gate
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 14:23:07 +02:00
custodian-sync
9cc500219c chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-09-11:
  - update .custodian-brief.md for audit-core

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 10:32:47 +02:00
a2173c6cc4 docs: record native audit sender delivery and reload
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 10:32:20 +02:00
a8058ee342 chore: refresh audit work record index after custody return
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 10:10:50 +02:00
custodian-sync
7f8c445709 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-09-11:
  - update .custodian-brief.md for audit-core

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 10:09:40 +02:00
7471d3835f docs: consume factory sender custody and retain delivery gate
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 10:09:10 +02:00
repo-manager
b154f4d497 repo.work.assign_missing_identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
source: repo-manager
reason: deterministic projection registration

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 07:26:17 +02:00
8b3bceea7f Record native receiver rollout and live attestation follow-up
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 07:26:16 +02:00
custodian-sync
0e421fd52f chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Updated by fix-consistency on 2026-09-11:
  - update .custodian-brief.md for audit-core

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 06:49:49 +02:00
041a50aa78 Pin factory-compatible audit receiver release
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 06:48:47 +02:00
cb23dc82fd Prepare compatible audit receiver with verified container lifecycle
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 06:46:15 +02:00
f1b0577095 Record factory sender dependency on compatible receiver release
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 02:02:53 +02:00
custodian-sync
362329ebab chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Updated by fix-consistency on 2026-09-11:
  - update .custodian-brief.md for audit-core

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 02:02:32 +02:00
5c0ad522fb chore(records): refresh the work-records index [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nb7Q6ZmXppNDkTWytfYqfv

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2069992@bnt-lap001
Assistant-Session: 167dd7f8-2a25-4be1-aa46-3b6f1a5f94c6
2026-09-10 16:44:24 +02:00
custodian-sync
a0f0ceafbf chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-09-10:
  - update .custodian-brief.md for audit-core

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2069992@bnt-lap001
Assistant-Session: 167dd7f8-2a25-4be1-aa46-3b6f1a5f94c6
2026-09-10 16:44:14 +02:00
8a2a09deae AUDIT-WP-0009 — record T04/T06/T07 as done
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nb7Q6ZmXppNDkTWytfYqfv

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2069992@bnt-lap001
Assistant-Session: 167dd7f8-2a25-4be1-aa46-3b6f1a5f94c6
2026-09-10 16:43:44 +02:00
b098fb12ca AUDIT-WP-0009 T04/T06/T07 — heartbeats, reconciliation, and a home for findings
The detection half audit-core argued up to a MUST and then could not support.
Two registered sources were waiting on it.

T04, heartbeats. A heartbeat is an ordinary event — same envelope, same
append-only custody, same chain, no special table. Deliberate: a heartbeat
stored outside the chain would be the one record here that could be back-dated.
Declared per class rather than per source, because a per-source heartbeat from
a mixed-volume emitter is satisfied by its chattiest class and says nothing
about the quiet, security-relevant one, which is the only reason heartbeats
exist. Not the §17 cadence schema T05 waits on: cadence describes expected
rate, this says how often a source promises to say "nothing to report" for a
class that may legitimately be silent.

no_heartbeat_since_registration is its own finding kind rather than a skip —
it is the case most likely to be a broken integration and the one a naive
"compare against last seen" implementation silently drops. Grace widens the
window so one late run does not flap; it never removes a finding.

T06, reconciliation. Counts, never payloads. The awkward part is that every
registered sender holds may_read: false, which taken literally makes the §9.6
reconciliation obligation undischargeable by every source actually registered.
Resolved by observing that a source asking how many of its own events we hold
is not reading the archive — it learns nothing it did not itself emit. So the
surface is scoped to the caller's own sources and tenants and returns no
payloads; anything wider stays behind may_read and full tenant scope. Another
source's counts return 403 rather than an empty count, because a zero would
read as "we hold none of yours" — a false answer to a question about
completeness. No default window, since a count whose bounds the caller did not
choose is not comparable to anything the caller computed.

T07, the findings surface. /v1/stream-findings, following the dead-letter and
secret-finding conventions: may_read plus full tenant scope, since findings
span every sender and carry no tenant key to filter on.

The bound is on every response rather than in a document nobody opens beside
it. A missing heartbeat is not proof of suppression, and agreement on counts
proves neither completeness nor that any event occurred. Both controls cover
loss, outage, drain failure and accident; neither covers a source lying about
itself, and where the emitter is compromised both agree with it. Closing that
needs an observer independent of the emitter, which §16 put outside our scope.

The scope overlay may shorten a heartbeat interval or add a class, never
lengthen or remove one — same asymmetry as evidence_kind, and for the same
reason: a ConfigMap refresh must not widen the window in which a suppressed
class goes unnoticed without anyone deciding to.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nb7Q6ZmXppNDkTWytfYqfv

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2069992@bnt-lap001
Assistant-Session: 167dd7f8-2a25-4be1-aa46-3b6f1a5f94c6
2026-09-10 16:43:26 +02:00
de9e3abe5f AUDIT-WP-0009 T02/T10 — schedule attestation, and make the §5 check total
T02. deploy/attest-cronjob.yaml: daily at 03:17 UTC against the 168h window,
its own ServiceAccount, and a Role reaching exactly one named ConfigMap —
get/update/patch, no create, no list. audit_core/attest_publish.py does the
publish in stdlib; the image carries no kubectl, and adding one to an audit
receiver's image to write a single file is the worse trade.

Three refusals, all deliberate:

  The producer is not the receiver. A receiver that could rewrite its own
  attestation could forge it. audit-core-egress is now scoped to
  component: receiver and a separate audit-core-attest-egress carries the 6443
  rule, so the receiver never gains API-server reach. Asserted by test.

  It refuses to publish over a broken chain. A fresh head written over a break
  replaces an honest chain_break with a fresh-looking attestation. Stale
  degrades the claim visibly; false does not.

  Mounted as a directory, not subPath. Found while writing the manifest: a
  subPath ConfigMap mount is resolved once at pod start and never updates, so
  the daily attestation would land in the ConfigMap and never reach the running
  receiver — tamper_evidence would age out to false while the job reported
  success every night, silent in both directions.

The offsite copy stays an operator step. audit-core holds no Nextcloud
credential and should not acquire one to publish a hash, so docs/integrity.md
states the bound plainly: until that copy exists the delivered control defends
against a database owner, not a cluster owner, and no stronger claim may be
made from it.

T10. layer.yaml lists four infrastructure contacts — platform-pg, state-hub,
kube-apiserver, the container registry — each with its role and whether another
layer reads it. tooling_contacts stays [], which is true under §5 as written;
the companion's totality request is met by the uncatalogued list rather than by
inventing a Tooling row. tests/test_layer_conformance.py derives the egress
destinations from the manifests and the registry from the pinned digests, so a
new contact appearing in deploy/ without a row fails the test rather than
waiting for a reviewer to notice.

Applying the manifests remains an operator action; nothing here was applied.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nb7Q6ZmXppNDkTWytfYqfv

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2069992@bnt-lap001
Assistant-Session: 167dd7f8-2a25-4be1-aa46-3b6f1a5f94c6
2026-09-10 16:39:20 +02:00
3c2cdcdf79 AUDIT-WP-0010 T01/T03/T04 — admit tenant-engine, and the envelope does not match
Registration: attributive, with the declared completeness_trade recorded on the
receiver side rather than only in the emitter, per §9.6's requirement that the
trade travel with the trail. tenants ["*"] is justified rather than inherited —
tenant-engine's events carry the affected tenant, the set is every tenant
including ones created later, and an explicit list would fail closed at exactly
the moment a tenant is provisioned, dead-lettering the creation evidence of the
tenant whose creation it is. source stays pinned exactly. Ingress ANDs namespace
and pod label; a weaker evidence class is not a reason for a wider network rule.
All inert until the token exists.

Then the finding T04 existed to find: tenant-engine cannot deliver a single
event today. envelope_for sends five required fields under other names —
event_id, action, resource, observed_at, details — and omits correlation_id
entirely, so normalize() raises invalid_event. Verified by running the real
envelope through the real function, not by reading.

Worse than an ordinary integration bug. The drain treats 400 as terminal, so the
outbox row is marked handled while audit-core holds only a dead letter, which is
not chained and is not custody. Lost on both sides, and since the drain is
non-blocking and attributive, nothing fails loudly — a silent total loss of the
stream presenting as a working integration.

Taking the correction the intake invited rather than accepting a lossy record.
normalize() is NOT relaxed to accept the alternate spellings: a receiver that
guesses which sender key means which stored field has made the mapping its own,
and the record stops being the sender's assertion. correlation_id cannot be
synthesized at all — an invented one ties an event to an operation audit-core
never observed.

Root cause is ours. The accepted envelope was published nowhere a sender could
read it; audit-backend-contract.md describes the stored record, and a sender
reading it would reasonably infer exactly the names tenant-engine used.
schema_version audit-core.event.v1alpha1 selects nothing here and gave a false
impression of a negotiated contract. Published docs/event-envelope.md as the
wire contract, including the point that a 400 means the event is not in the
archive and must be treated as a defect to fix rather than a delivery outcome.

T05 moved to wait: nothing to prove end to end until an event can be accepted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nb7Q6ZmXppNDkTWytfYqfv

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2069992@bnt-lap001
Assistant-Session: 167dd7f8-2a25-4be1-aa46-3b6f1a5f94c6
2026-09-10 16:34:45 +02:00
e0505af3b5 chore(consistency): write back hub ids for AUDIT-IN-0003 and T11 [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nb7Q6ZmXppNDkTWytfYqfv

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2069992@bnt-lap001
Assistant-Session: 167dd7f8-2a25-4be1-aa46-3b6f1a5f94c6
2026-09-10 15:16:23 +02:00
custodian-sync
a4516c5c16 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-09-10:
  - update .custodian-brief.md for audit-core

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2069992@bnt-lap001
Assistant-Session: 167dd7f8-2a25-4be1-aa46-3b6f1a5f94c6
2026-09-10 15:16:13 +02:00
c4016a70d5 AUDIT-WP-0009-T11 — register informed-decision, and answer GH-DEC-2026-014
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
informed-decision is the browser-facing approver surface; GH-DEC-2026-012
limit 3 makes its evidence copy the one that must reach audit-core
independently of the emitter, because there the actor being audited and the
evidence source are the same component.

Registration accepted on every proposed field — exact source,
["tenant:platform"], write true, read false, load-bearing, secret_policy
redact. Prepared and inert: the scope overlay applies only to a sender the
Secret already carries, asserted by test rather than by reading. Ingress ANDs
namespace and pod label in one peer, following approval-engine rather than
user-engine's older breadth.

Gate House asked whether the record shape can carry a source-held-content
declaration with a retrieval expectation, and asked for a straight answer
rather than a rule the storage cannot meet. Both halves, which must travel
together:

  It CAN carry the declaration. data is stored verbatim into details.data and
  hash-chained, so content_exists and custody need no schema change and become
  as tamper-evident as the commitment they accompany.

  It CANNOT detect non-production. audit-core performs no retrieval and its
  egress permits Postgres and DNS only. Detection happens at retrieval, by the
  reviewer; the stored declaration is what turns a blank into a failure
  attributable to the named custodian.

Residual stated rather than left to be found: a custodian that never held the
content can emit a false content_exists. audit-core validates the declaration's
shape, never its truth — the same class as omission at source, and not closed
by the chain, by attestation, or by T04/T06. A test asserts no egress to the
emitter exists, because that claim silently stops being true if one appears.

Cadence: reconciliation plus heartbeat is right for a mixed-volume source, with
both scoped per class rather than per source — a per-source heartbeat is
satisfied by the high-volume presentation stream and says nothing about a quiet
month of dispositions. Bound: a compromised emitter suppresses the event and
its own count together.

Also recorded: commitment-only satisfies non-alteration and never
reconstructability, in this repo's documents as in theirs; and tenant
provenance under GH-DEC-2026-013 lands in the registration record, not the
envelope, since audit-core checks a value the credential may write rather than
resolving an identity claim.

No secret was created and no production manifest applied.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nb7Q6ZmXppNDkTWytfYqfv

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2069992@bnt-lap001
Assistant-Session: 167dd7f8-2a25-4be1-aa46-3b6f1a5f94c6
2026-09-10 15:15:35 +02:00
custodian-sync
565e7e38d4 chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 3s
Updated by fix-consistency on 2026-09-08:
  - update .custodian-brief.md for audit-core

Assistant: codex
Assistant-Model: gpt-5.6-luna
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-08 20:34:53 +02:00
bbe8c15494 fix(admission): restrict approval audit sender to the platform tenant
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Assistant: codex
Assistant-Model: gpt-5.6-luna
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-08 17:01:41 +02:00
633f68b81b chore(records): refresh the work-records index for T03/T09
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185wifnLzCxjEY2MT1XbK7L

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713962@bnt-lap001
Assistant-Session: 2718d99d-d3ff-478f-83a2-3a30f01a02fc
2026-09-06 22:32:55 +02:00
custodian-sync
da976ec81a chore(consistency): sync task status from DB [auto]
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Updated by fix-consistency on 2026-09-06:
  - update .custodian-brief.md for audit-core

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713962@bnt-lap001
Assistant-Session: 2718d99d-d3ff-478f-83a2-3a30f01a02fc
2026-09-06 22:32:45 +02:00
15e54369be AUDIT-WP-0009-T03/T09 — evidence_kind, and approval-engine's registration inputs
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
T03. §9.6 gives load-bearing and attributive sources different obligations, so
the archive must record which one a source declared rather than infer it from
traffic. evidence_kind and completeness_trade now sit on SenderIdentity, the
AUDIT_CORE_SENDERS schema, and the non-secret scope overlay.

Two asymmetries are deliberate. The default is attributive, because the other
default would have audit-core imply a completeness obligation no source ever
accepted. And the overlay may raise the kind but never lower it — the same
principle that stops an ExternalSecret refresh shrinking user-engine's
tenants: a ConfigMap refresh must not drop a source's atomicity and detection
obligations without anyone deciding to. A load-bearing source may not carry a
completeness trade at all, since §9.6 requires atomicity of it, and
evidence_declaration() reports completeness_claimed: false for both kinds.

T09 (in progress). approval-engine's registration inputs are prepared and
recorded in docs/approval-engine-source-registration.md: scope entry declared
load-bearing, and audit-core-approval-engine-ingress with namespace and pod
label ANDed in one `from` peer — narrower than user-engine's namespace-only
rule, which is left unchanged. The scope entry lands ahead of the credential
because the overlay only applies to senders the Secret already carries, so it
admits nothing until the token exists; a test asserts that rather than
trusting the reading.

Two inputs remain approval-engine's: a confirmed tenant scope, since senders.py
requires a missing tenant restriction be justified per sender and audit-core
cannot justify it on another repo's behalf, and an explicit secret_policy
choice. Applying the manifests is an operator action.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185wifnLzCxjEY2MT1XbK7L

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713962@bnt-lap001
Assistant-Session: 2718d99d-d3ff-478f-83a2-3a30f01a02fc
2026-09-06 22:31:37 +02:00
a07c52e34a chore(records): refresh the work-records index
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Picks up AUDIT-WP-0010 and this session's T01/T08 closures. AUDIT-WP-0009 is
active, not ready — the index was regenerated mid-run, before fix-consistency
renormalized the lifecycle state.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185wifnLzCxjEY2MT1XbK7L

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713962@bnt-lap001
Assistant-Session: 2718d99d-d3ff-478f-83a2-3a30f01a02fc
2026-09-06 20:37:37 +02:00