--- id: AUDIT-WP-0003 type: workplan title: "Provide durable user-engine event ingestion" domain: infotech repo: audit-core status: finished owner: codex topic_slug: netkingdom created: "2026-08-08" updated: "2026-08-10" depends_on: - NK-WP-0024 state_hub_workstream_id: "8c2cfd72-126d-517e-8032-1f5c5cdaa20f" --- # AUDIT-WP-0003 - user-engine event ingestion service Provide the authenticated, durable cluster event receiver for user-engine's transactional outbox. Reuse audit-core's intended POST /v1/events boundary; do not turn user-engine into an audit-retention service. ## T01 - Finalize the ingestion contract ```task id: AUDIT-WP-0003-T01 status: done priority: high state_hub_task_id: "c9b402ae-3cc4-58c9-be37-c817db4d8145" ``` Map the user-engine envelope fields (id, type, source, subject, tenant, correlation_id, occurred_at, data) into the normalized audit-core event schema. Define validation, redaction, size limits, tenant isolation, Idempotency-Key behavior, and stable HTTP error semantics. Done when valid events preserve correlation and duplicate event IDs are accepted idempotently without duplicate custody records. Done 2026-08-09: the normalized contract preserves event, tenant, correlation, occurrence, source, subject, type, and redacted data; request size, timestamp, source, secret-shaped fields, and Idempotency-Key are validated. ## T02 - Implement authenticated durable ingestion ```task id: AUDIT-WP-0003-T02 status: done priority: high state_hub_task_id: "85df35ce-f6dd-5688-b38e-6b6678ada6e0" ``` Implement POST /v1/events with scoped workload authentication, schema validation, idempotency storage, bounded request handling, and durable backend write acknowledgment. Reject missing/invalid credentials, cross-tenant claims, secret-shaped fields, oversized payloads, and malformed timestamps. Done when a successful response means the event is durably accepted and retryable failures do not lose or duplicate evidence. Done 2026-08-09: `POST /v1/events` requires a constant-time bearer check and stores normalized records plus payload hashes in SQLite. Exact duplicates return 200 without a second record; conflicting IDs and malformed events fail. All 15 repository tests pass. ## T03 - Deploy the single-cluster receiver ```task id: AUDIT-WP-0003-T03 status: cancel priority: high state_hub_task_id: "2c5a0a9f-53e1-5040-a86d-7fb724c5f9ec" ``` Publish an immutable image and deploy audit-core API plus durable backend on railiance01. Provide Service discovery, health probes, resource/security controls, default-deny NetworkPolicy, backup/restore, retention, and rollback. Deliver the user-engine sender credential through the approved OpenBao lane. Done when only the user-engine workload can use its sender identity and the receiver survives pod restart without losing idempotency state. Cancelled 2026-08-10, superseded by AUDIT-WP-0005. A pre-deploy review found that the receiver is not deployable as built: the ingestion path bypasses the `AuditBackend` contract entirely and writes to SQLite directly, so a 202 does not mean the event reached audit custody. Deployment also presumed SQLite on a volume as the production store; it will instead use the Railiance PostgreSQL platform (RAPP-POSTGRES-WP-0002). The deploy work moves to AUDIT-WP-0005 and the receiver correctness work it depends on moves to AUDIT-WP-0004. ## T04 - Prove delivery, retry, and replay ```task id: AUDIT-WP-0003-T04 status: cancel priority: high state_hub_task_id: "7b1634a6-8b85-5e77-8f87-27f33074afc2" ``` Exercise successful delivery, receiver timeout/unavailability, bounded user-engine retry, dead-letter visibility, operator replay, duplicate replay, redaction, and correlation lookup through the deployed path. Hand non-secret evidence back to NK-WP-0024. Done when one source outbox event produces exactly one durable normalized event across retries and replay. Cancelled 2026-08-10, superseded by AUDIT-WP-0005-T05. The matrix cannot run against the current build: there is no read surface, no replay tool, and no correlation lookup, so the evidence NK-WP-0024 needs cannot be produced. Those are build work and move to AUDIT-WP-0004-T05; the live run moves to AUDIT-WP-0005-T05. ## Scope note (2026-08-10) This workplan is complete as the *contract and reference implementation* strand: T01 fixed the ingestion contract and T02 built a working, tested receiver against it. Production hardening and deployment were rescoped out into AUDIT-WP-0004 and AUDIT-WP-0005 after review. WP-0003 closes as `finished` on that narrowed scope rather than staying open across work that now belongs to two successor plans.