Audit schema evolution: scope chain, category, seq, partition-ready PK [Story-1160]

Story 1160Epic None11 files · +1449/−36

PR #294 · pramaan-io/pramaan-functions · merged 2026-06-10

Why this matters

The audit log is the firm's witness — and the window to reshape it is now.

Partition-ready PK, cursor-aligned seq, scope chain, and a ledger no one can erase.

Lock-it-later is the lie. The cheap window is while the table is near-empty.

The fix — Number every entry, scope every event, lock the ledger before the questions arrive.

How it flows

sequenceDiagram
  autonumber
  participant schema as Alembic migration
  participant data as Existing rows
  participant db as Postgres guarantees
  schema->>data: Add new columns (nullable / defaulted)
  schema->>data: Backfill seq in (created_at, id) order
  schema->>data: Attach seq identity, continue from max+1
  schema->>db: Add scope-chain + agent CHECKs
  schema->>db: REVOKE UPDATE, DELETE + BEFORE trigger
  schema-->>db: Add seq-aligned firm-leading indexes

5c8e2f9a1b47_0089_audit_schema_evolution.py · +340 — new methods

Methodin → outwhat it does
upgrade() → None
downgrade() → None

What changed, file by file

Alembic migration evolving the audit log — adds partition-ready PK, seq identity with deterministic backfill, scope CHECKs, append-only enforcement, and firm-leading indexes.

new methodsignature
upgrade() → None
downgrade() → None
New fields: revision : strdown_revision : str | Sequence[str] | Nonebranch_labels : str | Sequence[str] | Nonedepends_on : str | Sequence[str] | None

Audit log ORM entity — adds actor_label, category, scope chain, agent_run_id, and seq fields so the model mirrors the evolved schema with legacy rows still valid.

New fields: actor_label : str | Nonecategory : str | Nonesubject_label : str | Nonearea : str | Nonematter_id : UUID | Noneproceeding_id : UUID | Nonefiling_id : UUID | Nonedocument_id : UUID | Noneagent_run_id : UUID | Noneon_behalf_of_user_id : UUID | Nonetrigger : str | Noneseq : int | None

Files changed (11)

File±
alembic/versions/5c8e2f9a1b47_0089_audit_schema_evolution.py ★+340
docs/walkthroughs/story-1160-walkthrough.html+183
src/domains/audit_log/entity.py ★+189 −10
tests/contract/seed.py+2 −5
tests/db.py+27 −1
tests/factories.py+2 −5
tests/integration/test_app_adversary_reads.py+2 −5
tests/integration/test_audit_log_migration_roundtrip.py+222
tests/integration/test_audit_log_schema.py+478
tests/integration/test_extraction_claim_promotion.py+2 −2
tests/integration/test_rls_isolation.py+2 −8