# Intake records ## AUDIT-IN-0003 — Register informed-decision as a load-bearing sender; commitment-only payload doctrine ```yaml id: AUDIT-IN-0003 kind: intake title: 'Register informed-decision as a load-bearing sender, and answer GH-DEC-2026-014 limit 3' status: closed origin: cross-repo origin_ref: INFD-WP-0001-T08 / GH-DEC-2026-012 / GH-DEC-2026-014 priority: high owner: audit-core requested_by: informed-decision description: > informed-decision is the browser-facing approver surface approval-engine deliberately does not contain, ruled PEP-shaped by GH-DEC-2026-012. Limit 3 of that ruling requires its evidence copy to reach audit-core independently of the emitter, because the actor being audited and the evidence source are the same component. Requested: (1) sender registration — source informed-decision exact, tenants [tenant:platform], write true, read false, evidence_kind load-bearing, secret_policy redact; (2) whether reconciliation per class as primary plus heartbeat for the low-volume classes is the right cadence form for a mixed-volume source; (3) whether commitment-only content is one event class or two, and whether it belongs in the same class as other evidence. GH-DEC-2026-014 attached a condition addressed to audit-core: non-production of committed content must be detectable as a FINDING rather than present as an absence, so the record must carry an assertion that committed content exists and where custody sits. Gate House asked audit-core to say plainly whether the record shape can express that, rather than have a rule written that the storage cannot meet. created: '2026-09-09' updated: '2026-09-10' outcome: registered-with-a-stated-bound closed: '2026-09-10' resolution: 'Registration accepted on every proposed field; the proposal was correct and the substance is in the bounds. Prepared and inert pending token, protected-registry entry and operator apply — docs/informed-decision-source-registration.md, deploy/senders-scope.{json,yaml}, audit-core-informed-decision-ingress. (1) GH-DEC-2026-014 limit 3: the fabric 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, and the stored declaration is what makes non-production attributable rather than a blank. Residual: a custodian that never held the content can emit a false content_exists; audit-core validates the declaration shape, never its truth — same class as omission at source, not closed by chain, attestation or T04/T06. (2) Cadence: reconciliation plus heartbeat is right, 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, so neither control covers the limit-3 residual. Depends on T04/T06; declare now, do not describe as operating. (3) One source, distinct type values per class, following approval-engine four-class shape; a second sender would split one residual into two smaller-looking ones. (4) Tenant provenance is recorded in the registration document, not the envelope: audit-core does not resolve the tenant claim, it checks a value the credential is permitted to write, and restating an unobserved route in an event is the same error as claiming an event occurred. (5) Stated for all documents: commitment-only satisfies non-alteration and never reconstructability, and no audit-core document or conformance claim may describe it otherwise.' recorded_in: docs/informed-decision-source-registration.md work: AUDIT-WP-0009-T11 state_hub_intake_id: "01a08b76-05b9-7a53-8359-9cda50755f28" ``` ## AUDIT-IN-0002 — Register tenant-engine as an attributive audit-core sender ```yaml id: AUDIT-IN-0002 kind: intake title: 'Register tenant-engine as an attributive audit-core sender' status: open origin: cross-repo origin_ref: TEN-WP-0011-T04 priority: high owner: audit-core requested_by: tenant-engine description: > tenant-engine now emits mutation evidence through a local outbox (audit-core.event.v1alpha1, source=tenant-engine, POST /v1/events). The class is attributive and drain is non-blocking (tenant-engine/docs/evidence-emission.md). Production cannot land events until audit-core admits this sender: sender identity with source tenant-engine, a projected token (no secret in Git; warden route for custody), and NetworkPolicy if the current allow-list is still user-engine only. Envelope: schema_version audit-core.event.v1alpha1; tenant is the affected tenant_id; action is the domain event type; resource tenant:. Duplicate event ids should 200. Credentials must not travel via State Hub messages. Requested: sender registration + token lane, or a correction if the envelope needs a field this engine is not sending. created: '2026-08-29' updated: '2026-09-10' outcome: registered-with-a-blocking-correction resolution: 'Registered attributive with the declared completeness_trade recorded receiver-side, tenants ["*"] justified per sender, source pinned exact, ingress added — all inert pending the token (docs/tenant-engine-source-registration.md, AUDIT-WP-0010 T01/T03/T04). Taking the correction the intake invited: the envelope does not match. 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 and every event would 400 and dead-letter. Because the drain treats 400 as terminal, the outbox row is marked handled while audit-core holds only a dead letter — lost on both sides, silently, presenting as a working integration. normalize() is not being relaxed to accept the alternate spellings: guessing which sender key means which stored field would make the mapping audit-core''s rather than the sender''s, and correlation_id cannot be synthesized at all. Root cause is audit-core''s — the wire envelope was documented nowhere a sender could read it, and schema_version audit-core.event.v1alpha1 selects nothing here. Contract now published at docs/event-envelope.md. Stays OPEN until tenant-engine corrects the emitter and T05 records live evidence.' state_hub_intake_id: "01a04d8f-b1c1-746a-8007-15221ebf0a48" ``` ## AUDIT-IN-0001 — Proposed: audit-core takes the approval evidence half (security layer model v0.3 §9.4) ```yaml id: AUDIT-IN-0001 kind: intake title: 'Proposed: audit-core takes the approval evidence half (security layer model v0.3 §9.4)' status: closed origin: cross-repo origin_ref: net-kingdom security-layer-model_v0.3 §9.4 priority: medium owner: audit-core requested_by: gate-house description: 'gate-house proposes that audit-core own the tamper-evident record of approvals: issuance, use, supersession, and revocation emitted as audit events. Rationale: principle 6 (signed or hash-chained manifests to prove a record set was not changed, omitted, or truncated) is exactly what authenticated approval entries need forensically, and audit-core independence is the property Canon core rule 13 wants — audit evidence protected from the actor being audited. What is NOT proposed: the operative approval state. approval-engine owns the durable object, atomic supersession, single consumption, and revocation, because those need mutable in-path current-state semantics and audit-core operational custody is append-only Postgres by design; coupling decision-time approval reads to the audit fabric would also make an audit outage an authorization outage. Note audit-core INTENT lists policy decision making as out of scope — this proposal respects that: approval evidence is a record of what happened, never the authoritative answer to whether an approval is still valid. Requested: assent, revision, or rejection. If audit-core would rather not carry approval events as a distinct source, say so and gate-house will record the evidence half as unowned rather than assume it.' created: '2026-08-28T20:35:09.148892Z' updated: '2026-08-28T21:10:00Z' outcome: assent-with-conditions closed: '2026-08-28T21:10:00Z' resolution: 'Assent. The split is right: approval-engine owns the operative state, audit-core owns the tamper-evident record of issuance, use, supersession, and revocation as a distinct source. Two corrections to the rationale and one condition. (1) INTENT principle 6 overstates the delivered guarantee; docs/integrity.md is authoritative — an in-database chain does not withstand a database owner without the external chain-head attestation, and even then it is not WORM. Approval events get exactly the guarantee every other source gets, no more; anything stronger is an engine gap to declare under §5.3. (2) The chain proves alteration and truncation, not omission at source. A suppressed revocation leaves the chain intact and verify reports intact; completeness at the boundary is the emitter''s property, not the archive''s. CONDITION: approval-engine must guarantee emission atomicity (transactional outbox or equivalent) so an approval cannot change state without the event being durably queued in the same transaction — a requirement on approval-engine, not a task audit-core can discharge for it. Boundary stated: no approval-validity query will ever be exposed; a verdict surface would be deciding early under §6.1. Also raised: audit-core declared no layer, contrary to §11 — now declared Engine layer, explicitly not a decision point.' recorded_in: history/2026-08-28-approval-evidence-assent.md state_hub_intake_id: "01a04d8f-be67-75ed-a221-d50f99dbb78e" ```