[Spike-1152] Audit log design — human + agent logs, taxonomy, schema, capture point, mockups

Story 1152Epic None3 files · +1817/−0

PR #146 · pramaan-io/pramaan-docs · merged 2026-06-10

Why this matters

If an agent acts, where's the proof?

In legal-tech, every human click and every agent tool call must leave a trace — otherwise regulators, courts, and even your own debugging fly blind.

Free-text logs can't answer 'who, what, when, with what approval' — and that's exactly what regulators ask.

The fix — One structured emit, one typed snapshot, one immutable log — so every human click and every agent tool call leaves a trail you can actually read.

How it flows

sequenceDiagram
  autonumber
  participant actor as Actor (human or agent)
  participant emit as emit()
  participant log as ops.audit_log
  participant reader as Reader (auditor / regulator)
  actor->>emit: structured call
  emit->>emit: validate against registry
  emit->>log: typed ChangeSnapshot → JSONB
  log-->>reader: query by actor / action / scope

docs/designs/audit-log/README.md

Methodin → outwhat it does
emitasync def emit( session: AsyncSession, *, action: str, # registry key "<subject_kind>.<verb>" subject: Subject, # kind, id, label — label REQUIRED scope: Scope | None = None, # matter/proceeding/filing/document ids snapshot: ChangeSnapshot the single chokepoint that writes one structured audit event per call, enforcing action registry key, required subject label, scope ids, and a typed change snapshot

What changed, file by file

The design doc that answers Q1–Q6 for the audit log: prior-art comparison (GitHub Enterprise, Stripe, Slack, Salesforce, CloudTrail, Notion + OCSF + NIST SP 800-92/SOC 2 CC7.x), seed actor·action·subject vocabulary registry, ops.audit_log evolution DDL with typed change-snapshot JSONB, one-vs-two-tables decision, capture-point analysis including the founder hook hypothesis, and the follow-up Story list (per what_how_claims).

new methodsignature
emitasync def emit( session: AsyncSession, *, action: str, # registry key "<subject_kind>.<verb>" subject: Subject, # kind, id, label — label REQUIRED scope: Scope | None = None, # matter/proceeding/filing/document ids snapshot: ChangeSnapshot

Files changed (3)

File±
docs/designs/audit-log/README.md ★+1234
docs/designs/audit-log/mockups/agent-audit-log.html+297
docs/designs/audit-log/mockups/human-audit-log.html+286