Commit Graph

22 Commits

Author SHA1 Message Date
17ae157365 refactor: strip Phase/Plan/R-number references from source comments 2026-05-13 09:51:45 +02:00
83f135b5e1 fix(conformance): withCapture propagates inner brands + chain test + docstring fixes 2026-05-12 23:00:50 +02:00
1d8b30045a feat(core-audit): withAudit wraps and attaches runtime __audited marker 2026-05-12 22:42:16 +02:00
925f4e4e5b docs(core-audit): TODO breadcrumb for future audit recording automation 2026-05-12 22:35:23 +02:00
bf3abea776 fix(core-audit): rename unused withAudit test param to _input 2026-05-12 21:52:06 +02:00
103e06d20a feat(core-audit): withAudit wrapper + Audited<F> brand 2026-05-12 21:41:40 +02:00
c06f47b81e feat(core-audit): createAuditAfterReadHook factory for opt-in VIEW capture
Adds the afterRead hook factory for per-collection opt-in automatic VIEW
audit entry emission. Fire-and-forget design ensures failing sinks never
propagate to the user-facing read. Includes sentinel IP/UA fallbacks,
truncateIp /24 integration, shouldSkip predicate, and system actor
resolution. All 6 TDD test cases pass; both barrels updated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:33:59 +02:00
55993a2c93 feat(core-audit): wrap bound auditLog with TraceIdEnrichingAuditLog
bindAudit now wraps the inner sink/fan-out with TraceIdEnrichingAuditLog so
all sinks receive AuditEntry.correlationId auto-populated from the active
OTel span. bind-audit.test.ts assertions updated to check instanceof
TraceIdEnrichingAuditLog first, then .inner for the concrete sink type.
TraceIdEnrichingAuditLog exported from the package barrel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:31:19 +02:00
07548c4620 feat(core-audit): TraceIdEnrichingAuditLog decorator for OTel correlation
Decorator implementing IAuditLog that auto-populates AuditEntry.correlationId
from the active OTel span via currentTraceId(). Caller-supplied correlationId
always wins (explicit > implicit). eraseSubject passes through unmodified.
Adds @opentelemetry/{api,sdk-trace-base,context-async-hooks} as devDeps for
test infrastructure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:29:15 +02:00
131efd5d2f feat(core-audit): admin tRPC procedure for eraseSubject
Adds auditProcedure (adminOnly middleware + defineErrorMiddleware([])) in
core-audit/src/integrations/api/procedures.ts. Adds createAuditRouter that
captures an IAuditLog and exposes a single eraseSubject mutation with zod
input validation. Non-admins receive FORBIDDEN. Barrel re-exports
pseudonymize, createAuditErasureHook, createAuditRouter, auditRouter,
AuditRouter, auditProcedure, AdminTrpcUser. Adds AUDIT_PSEUDONYM_SALT to
turbo.json globalEnv to clear lint warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:25:09 +02:00
270897c550 feat(core-audit): createAuditErasureHook Payload afterDelete factory
Adds createAuditErasureHook in core-audit/src/hooks/. The factory returns
a CollectionAfterDeleteHook that calls auditLog.eraseSubject() when a
document is deleted. Defaults to "pseudonymize" mode; coerces numeric ids
to string; skips undefined/null/object ids. Barrel at hooks/index.ts.
6 unit tests cover all guard branches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:23:08 +02:00
18fddcc45f feat(core-audit): PayloadAuditLog.eraseSubject (pseudonymize + delete via overrideAccess)
Replaces the Phase-2 stub with a real impl. Mode "delete" issues a bulk
payload.delete with overrideAccess:true to bypass the append-only rule.
Mode "pseudonymize" fetches up to 10_000 matching docs and patches each
actorId to the token produced by pseudonymize(). Adds 3 eraseSubject unit
tests to the existing payload-audit-log test file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:22:35 +02:00
846b4c2511 feat(core-audit): pseudonymize helper (sha256 + AUDIT_PSEUDONYM_SALT)
Adds `pseudonymize(actorId)` in core-audit — SHA-256 of salt+":"+actorId
truncated to 16 hex chars, prefixed "erased-". Salt from
AUDIT_PSEUDONYM_SALT env (fallback dev label). 6 unit tests: deterministic,
salt-change-differs, fallback-no-throw.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:22:30 +02:00
cbde74b7ee feat(core-audit): package barrel exports
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:16:44 +02:00
683dab691f feat(core-audit): bindAudit binder with sink selection + prod salt validation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:14:47 +02:00
7f75f3d56a feat(core-audit): MultiSinkAuditLog fan-out with settle-all + stderr fallback
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:13:48 +02:00
fc4e4a1392 feat(core-audit): PayloadAuditLog.record impl (eraseSubject lands in Phase 3)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:13:18 +02:00
04c99346c6 feat(core-audit): append-only auditLogs Payload collection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:12:48 +02:00
03e3ef39cd feat(core-audit): StdoutJsonAuditLog impl with audit + audit-erasure markers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:12:18 +02:00
17996e9347 feat(core-audit): NoopAuditLog impl
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:11:52 +02:00
12a8391944 feat(core-audit): IAuditLog interface + AUDIT_SYMBOLS
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:11:30 +02:00
0c5ad08dcd feat(core-audit): scaffold optional package (no impls yet)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:10:58 +02:00