From 9dff75e59e51a0da092aea5add06a96782a3f84c Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 29 Aug 2026 14:54:18 +0200 Subject: [PATCH] =?UTF-8?q?Raise=20AUDIT-WP-0010=20=E2=80=94=20admit=20ten?= =?UTF-8?q?ant-engine=20as=20an=20attributive=20sender?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the path for AUDIT-IN-0002. tenant-engine emits through a local outbox and cannot land production events until audit-core admits the sender, so this is another repo's production blocked on ours — a workplan of its own rather than a task inside AUDIT-WP-0009. The request arrives with its bound already declared: attributive class, non-blocking drain, trade documented at tenant-engine/docs/evidence- emission.md. Under §9.6 that is legitimate. Nothing needs renegotiating; it needs admitting. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01WpeL68AWHqtqPQZEXY5kFe Assistant: claude-code Assistant-Model: opus Assistant-Process: 4040362@bnt-lap001 Assistant-Session: 4fd0fd24-2ee8-4413-bd67-43bd79ca73f1 --- ...-WP-0010-tenant-engine-sender-admission.md | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 workplans/AUDIT-WP-0010-tenant-engine-sender-admission.md diff --git a/workplans/AUDIT-WP-0010-tenant-engine-sender-admission.md b/workplans/AUDIT-WP-0010-tenant-engine-sender-admission.md new file mode 100644 index 0000000..e8e07ff --- /dev/null +++ b/workplans/AUDIT-WP-0010-tenant-engine-sender-admission.md @@ -0,0 +1,122 @@ +--- +id: AUDIT-WP-0010 +type: workplan +title: "Admit tenant-engine as an attributive sender" +domain: infotech +repo: audit-core +status: ready +owner: claude +topic_slug: railiance +created: "2026-08-29" +updated: "2026-08-29" +depends_on: + - AUDIT-WP-0005 +--- + +# AUDIT-WP-0010 — Admit tenant-engine as an attributive sender + +## Goal + +Close `AUDIT-IN-0002`. `tenant-engine` emits mutation evidence through a local +outbox and **cannot land events in production until audit-core admits the +sender**. This is another repository's production blocked on ours, which is why +it is a workplan of its own rather than a task inside `AUDIT-WP-0009`. + +The request is well-formed and arrives with its own bound already declared: +class **attributive**, drain non-blocking, documented at +`tenant-engine/docs/evidence-emission.md`. Under §9.6 that is a legitimate +trade — attributive evidence may deliberately trade away atomicity provided the +trade is declared and completeness is never claimed. `tenant-engine` declared +it. Nothing here needs renegotiating; it needs admitting. + +Intake: `AUDIT-IN-0002` (`01a04d8f-b1c1-746a-8007-15221ebf0a48`), origin +`TEN-WP-0011-T04`. Onboarding follows INTENT principle 4 — a source is onboarded +when ownership, retention, access, export, and evidence policy are declared and +validated, not when events start arriving. + +## Non-goals + +- Reclassifying `tenant-engine` as load-bearing. It declared attributive and the + declaration is the emitter's to make; §9.6 obligations follow the class. +- Carrying any credential value in this repository, in a work record, in State + Hub, or in chat. The intake says so and it is right. +- Blocking on `AUDIT-WP-0009-T03`. The `evidence_kind` field lands there; + admission does not wait for it, and T04 below records the class in the + meantime. + +## Tasks + +```task +id: AUDIT-WP-0010-T01 +status: todo +priority: high +``` +Register the sender identity: name `tenant-engine`, `sources: [tenant-engine]`, +`may_write: true`, `may_read: false`, `secret_policy: redact`, tenants scoped as +the envelope requires. Follow the existing `user-engine` shape in +`deploy/externalsecret-senders.yaml` and `deploy/senders-scope.yaml`. No token +value in Git — projected only, per the established lane. + +```task +id: AUDIT-WP-0010-T02 +status: todo +priority: high +``` +Provide the token lane. Coordinate the projected credential with the owning +credential operator through the `ops-warden` route, matching the custody pattern +already used for `user-engine`. Verify field presence without disclosure. Do not +transport a value through State Hub messages. + +```task +id: AUDIT-WP-0010-T03 +status: todo +priority: high +``` +Extend the NetworkPolicy. `deploy/networkpolicies.yaml` currently admits +`user-engine`; add `tenant-engine`. `tests/test_networkpolicies.py` exists — +extend it so the second sender is asserted rather than assumed, and so a future +third sender fails the test rather than silently failing in production. + +```task +id: AUDIT-WP-0010-T04 +status: todo +priority: medium +``` +Validate the envelope against what `tenant-engine` actually sends: +`schema_version: audit-core.event.v1alpha1`, `tenant` = affected `tenant_id`, +`action` = domain event type, `resource` = `tenant:`, duplicate event ids +returning 200. Confirm the duplicate path reconciles rather than minting a +second link (`test_replay_reconciles_rather_than_duplicating`). If the envelope +needs a field this engine does not send, reply with the correction the intake +invited rather than accepting a lossy record. + +Record the declared class (**attributive**, non-blocking drain, trade declared +at `tenant-engine/docs/evidence-emission.md`) alongside the sender registration, +so the §9.6 trade is documented here and not only in the emitter. + +```task +id: AUDIT-WP-0010-T05 +status: todo +priority: medium +``` +Prove it end to end against the production receiver: a real event from +`tenant-engine` accepted, attributed to the right tenant, redacted per policy, +and linked into the chain. Record the evidence under `docs/evidence/`. Then +close `AUDIT-IN-0002` with outcome `promoted` citing this workplan, and reply to +`tenant-engine`. + +## Acceptance + +- `tenant-engine` events land in production, correctly attributed and redacted. +- The token never appears in Git, a work record, State Hub, or chat. +- The NetworkPolicy admits exactly the intended senders, asserted by test. +- The attributive trade is recorded on audit-core's side, and completeness is + nowhere claimed for this stream. +- `AUDIT-IN-0002` closed and the requester answered. + +## Notes + +`tenant-engine` did this the right way round: it built the outbox, declared the +class honestly, documented the trade, and asked before assuming it could emit. +The correct response is to move quickly, not to make it wait behind +`AUDIT-WP-0009`.