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
198 lines
11 KiB
Markdown
198 lines
11 KiB
Markdown
# informed-decision source registration
|
|
|
|
`AUDIT-WP-0009-T11` · intake `AUDIT-IN-0003` · statute §9.6 · rulings
|
|
`GH-DEC-2026-012` (limit 3), `GH-DEC-2026-014`, `GH-DEC-2026-013`
|
|
|
|
The registration inputs for `informed-decision` as a distinct audit source: the
|
|
browser-facing approver surface that `approval-engine` deliberately does not
|
|
contain. Onboarded under `INTENT.md` principle 4 — declared ownership,
|
|
retention, access, export and evidence policy, not merely events arriving.
|
|
|
|
This file is the owner-side record. Everything in it is non-secret. No sender
|
|
token appears here, in Git, in State Hub, or in a workplan.
|
|
|
|
## Declaration
|
|
|
|
| Field | Value |
|
|
| --- | --- |
|
|
| Sender name | `informed-decision` |
|
|
| Permitted `source` | `informed-decision` (exact; no wildcard) |
|
|
| `evidence_kind` | **`load-bearing`** (§9.6 — GH-DEC-2026-012 limit 3 makes the presentation record the independent evidence of a binding act) |
|
|
| `completeness_trade` | none, and none is permitted — §9.6 requires emission atomicity of a load-bearing source |
|
|
| `may_write` | true |
|
|
| `may_read` | false — a source does not gain a read surface by emitting. See the reconciliation note below, which is where the temptation to grant one will come from |
|
|
| `secret_policy` | `redact` — accepted as proposed |
|
|
| `tenants` | `["tenant:platform"]` — accepted as proposed, with the provenance obligation below |
|
|
| Retention | no expiry set; recoverable history is the platform `data.backup` window, 30 days, `measured` |
|
|
| Custody class | `operational` — never `archive`, never WORM |
|
|
|
|
Accepted as proposed on every field. The proposal was correct; the substance of
|
|
this record is in what follows it.
|
|
|
|
## Event classes — one source, not two
|
|
|
|
Asked directly: is commitment-only content one event class or two, and does it
|
|
belong in the same class as other evidence at all.
|
|
|
|
**One source, distinct `type` values per class.** This is the same shape
|
|
`approval-engine` carries for its four §9.4 classes: audit-core stores classes
|
|
as actions on one source and derives nothing from them.
|
|
|
|
| Class | Volume | Why it matters |
|
|
| --- | --- | --- |
|
|
| presentation | high — one per render | Carries the commitment. The only class carrying a custody declaration |
|
|
| disposition | low | **security-relevant** — the binding verb |
|
|
| stance application | low | **security-relevant** — what was applied to the act |
|
|
|
|
A separate sender for the commitment-bearing class was considered and refused.
|
|
Two senders would mean two credentials, two tenant scopes and two ingress rules
|
|
for one component whose defining property is that the actor and the evidence
|
|
source are the same — splitting them makes that single residual look like two
|
|
smaller ones. The distinction that matters is per class, and `type` carries it.
|
|
|
|
Commitment-only content does belong in the same store as other evidence,
|
|
because the custody guarantee it receives is the same one and no stronger. What
|
|
differs is what may be claimed of it, and that is stated below rather than
|
|
encoded in a separate class.
|
|
|
|
## GH-DEC-2026-014 limit 3: can this fabric carry it?
|
|
|
|
Gate House asked whether a source-held-content declaration with a retrieval
|
|
expectation is a thing the record shape can carry today, and asked for a
|
|
straight answer rather than a rule nobody can meet.
|
|
|
|
**It can carry the declaration. It cannot itself detect non-production.** Both
|
|
halves are load-bearing; neither should be read without the other.
|
|
|
|
**What is carried.** `data` is an arbitrary structured object stored verbatim,
|
|
normalized into the envelope's `details.data`, appended under the trigger and
|
|
linked into the hash chain like every other field. `content_exists` and
|
|
`custody` therefore need no schema change, no new column and no new surface.
|
|
Once stored, the chain detects any later alteration or truncation of them
|
|
exactly as it does for the commitment digest itself. So the declaration is as
|
|
tamper-evident as the thing it accompanies, which is the property the condition
|
|
needs — a custodian cannot quietly retract the assertion that content existed.
|
|
|
|
**What is not delivered, and must not be inferred.** audit-core performs no
|
|
retrieval. It holds no client for `informed-decision`, and its egress policy
|
|
permits Postgres and DNS and nothing else (`deploy/networkpolicies.yaml`) — the
|
|
new ingress rule adds no egress. So audit-core never learns whether a custodian
|
|
would in fact produce the content, and raises no finding when it would not.
|
|
Non-production becomes detectable **at retrieval, by the reviewer**, and the
|
|
stored declaration is what makes it a finding rather than a blank: the reviewer
|
|
holds a chained, timestamped statement that content existed and where custody
|
|
sat, so failure to produce is attributable to the named custodian. That is the
|
|
condition met in the form audit-core can honestly meet it.
|
|
|
|
**The 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. This is the same class of defect as
|
|
omission at source — the archive cannot retrofit a property the boundary did
|
|
not have — and it is not closed by the chain, by attestation, or by T04/T06. It
|
|
narrows to this: the declaration converts an unattributable absence into an
|
|
attributable false statement, which is strictly better and is not the same as
|
|
proof.
|
|
|
|
**One design consequence for the emitter.** `secret_policy: redact` scans
|
|
`data`. If the `custody` locator is ever secret-shaped — a token in a URL, a
|
|
path that trips the scanner — it will be redacted out and the declaration will
|
|
reach the store without its pointer. The redaction is recorded in
|
|
`details.redaction.paths`, so this fails visibly rather than silently, but the
|
|
locator should be a stable non-secret identifier resolved by the custodian, not
|
|
a credentialed URL. Under commitment-only the exposure is small by
|
|
construction, as informed-decision observed; the custody field is the one place
|
|
that stops being true.
|
|
|
|
## Cadence: the shape for a mixed-volume source
|
|
|
|
Asked whether reconciliation per class as primary, plus heartbeat for the
|
|
low-volume classes, is right. **Yes, with one refinement and one bound.**
|
|
|
|
**Refinement — both are per class, not per source.** A per-source heartbeat
|
|
from a component emitting one presentation per render is nearly worthless: it
|
|
is satisfied by the high-volume class and says nothing about a quiet month of
|
|
dispositions. Heartbeat must be scoped to the low-volume classes individually,
|
|
carrying a *nothing to report* assertion for that class. Likewise reconciliation
|
|
counts must be keyed `(source, class, window)`, which is the shape
|
|
`AUDIT-WP-0009-T06` is being built to.
|
|
|
|
The high-volume class needs reconciliation too, and rate alone is not a
|
|
substitute for it. Rate monitoring detects a stream stopping; it does not detect
|
|
a stream missing the particular renders that mattered.
|
|
|
|
**The bound, which matters more here than for approval-engine.** Reconciliation
|
|
compares audit-core's counts against counts the source computes from its own
|
|
state. Where the threat is a compromised emitter — and GH-DEC-2026-012 limit 3
|
|
exists precisely because here the actor and the evidence source are one
|
|
component — a compromised `informed-decision` suppresses the event and its own
|
|
count together, and reconciliation agrees. Heartbeat inherits the same weakness:
|
|
a compromised source emits a truthful-looking *nothing to report*.
|
|
|
|
So reconciliation and heartbeat cover loss, accident, outage and drain failure,
|
|
which is most of what actually goes wrong. They do not cover the residual
|
|
informed-decision already declares and should not be described as covering it.
|
|
Nothing audit-core can build closes that; it needs an observer independent of
|
|
the emitter, which is out of scope here (§16).
|
|
|
|
**Sequencing.** T04 and T06 are open. informed-decision may declare this cadence
|
|
now and must not describe it as operating until they land — which is exactly
|
|
what the intake proposed, and is the right handling.
|
|
|
|
## Tenant provenance
|
|
|
|
`tenant:platform` is accepted. informed-decision notes that under
|
|
`GH-DEC-2026-013` the value arrives by the declared-gap route
|
|
(registration-bound rather than directory-sourced) and asks whether the
|
|
registration or envelope inherits the obligation to record which route it came
|
|
by.
|
|
|
|
**Not in this envelope, and here is why.** audit-core's `tenant` is not an
|
|
asserted identity claim it resolves; it is a value the credential is *permitted
|
|
to write*, checked by exact string equality against this registration. The
|
|
provenance question — how a principal came to hold `tenant:platform` — is a
|
|
property of the token issuer's claim, and recording a route in the audit event
|
|
would be audit-core restating something it did not observe. That is the same
|
|
error as claiming an event occurred.
|
|
|
|
Where it does land is here, in the registration record, which is the document
|
|
that says why this sender may write this tenant. Recorded: the scope is exact,
|
|
single-valued, and its authority is `GH-DEC-2026-013`'s bounded gap rather than
|
|
a populated directory record. If the gap closes and the terminal
|
|
directory-sourced shape lands, this entry should be revisited rather than
|
|
assumed still correct.
|
|
|
|
## Applied in this repository
|
|
|
|
| Input | Where |
|
|
| --- | --- |
|
|
| Non-secret scope | `deploy/senders-scope.json` + `deploy/senders-scope.yaml` (lockstep) |
|
|
| Receiver ingress | `deploy/networkpolicies.yaml`, `audit-core-informed-decision-ingress` |
|
|
| Evidence kind in the model | `audit_core/senders.py`, `SenderIdentity.evidence_kind` |
|
|
|
|
The scope overlay only applies to a sender the Secret already carries, so this
|
|
entry is **inert until the token exists** — asserted by test, not by reading.
|
|
The ingress rule ANDs namespace and pod label in one `from` peer.
|
|
`user-engine`'s and `approval-engine`'s policies are unchanged.
|
|
|
|
## Still owed by others
|
|
|
|
| Input | Owner | Note |
|
|
| --- | --- | --- |
|
|
| Sender token, custody path via `warden route` | OpenBao (`railiance-platform`) | audit-core never holds or transports it |
|
|
| Protected registry entry with explicit `secret_policy: redact` | `railiance-platform` | The overlay deliberately does not override `secret_policy`; provisioning must set it |
|
|
| Applying the manifests to `railiance01` | operator | audit-core does not apply cluster changes unprompted |
|
|
| The `content_exists` / `custody` fields on the emitted payload | `informed-decision` | audit-core carries them; it does not require, validate or dereference them |
|
|
|
|
## What Audit Core will and will not claim about this stream
|
|
|
|
**Will:** every event it accepted is stored append-only, and the hash chain
|
|
detects alteration or truncation of what it received — including of the
|
|
`content_exists` and `custody` declarations.
|
|
|
|
**Will not:** that the archive proves a presentation occurred, or that the
|
|
absence of one proves it did not. And specifically, per GH-DEC-2026-014:
|
|
audit-core will not describe a commitment-only record as satisfying
|
|
**reconstructability**. It satisfies non-alteration of the commitment. About
|
|
what was committed to it establishes nothing, except conditionally — if a
|
|
document is later produced, whether it is the one. No conformance claim, ITC-CAP
|
|
case, or `docs/integrity.md` statement may say otherwise.
|