Story: Audit trail and system account

Table of Contents

This page documents a story in Sprint 12. It captures the goal, current status, acceptance criteria, and the tasks that compose it.

Goal

Get the audit trail honest. Standardise terminology. Add a non-login system account for initial population. Make protocol messages stop trusting client-supplied modified_by. Decompose the generation context so generators can read audit fields from environment.

Status

Field Value
State DONE
Parent sprint Sprint 12
Now Completed 2026-02-17.
Waiting on None.
Next None.
Last touched 2026-02-17

Acceptance

  • modified_by + performed_by have soft FK to accounts.
  • performed_by visible in UI.
  • System account exists; used for initial population only.
  • Protocol rejects client-supplied modified_by.
  • generation_engine + generation_environment + generation_context in place; ~36 generators migrated.

Tasks

Task State Start End Description
Fix audit trail metadata for recorded_by and modified_by DONE 2026-05-19 2026-02-16 modified_by + performed_by soft FK to accounts; super-admin no longer 'modified by bootstrap'; tenant admin no longer 'recorded by onboarding'; performed_by visible in UI; terminology standardised.
Investigate how performed by is being set DONE 2026-05-19 2026-02-16 Audit the source of performed_by; should be the database account.
Add system account DONE 2026-05-19 2026-02-16 Non-login system account used for all initial population; publication uses the new admin account, not the system account.
Add-entity messages should not set modified_by DONE 2026-05-19 2026-02-16 modified_by must come from the session (logged-in user); reject any client-supplied modified_by in protocol messages.
Add generation context with KVP for audit trail fields DONE 2026-05-19 2026-02-17 generation_context decomposed into generation_engine + generation_environment + composing context; ~36 generators migrated to accept generation_context&; modified_by lookup via environment; strict ores_iam_validate_account_username_fn re-enabled; make_generation_context() factory in ores.testing.

Decisions

modified_by = DB user, performed_by = app actor
split is real; was previously inconsistent.
System account for bootstrap, admin account for publication
separates initial-state-only writes from operational ones.
Environment + parent-chain lookup
clean way to plumb tenant_id + modified_by into generators without explicit parameters.

Out of scope

  • Audit-trail UI surface (separate story).
  • Field-level audit (we audit at the row level only).

See also

Emacs 29.1 (Org mode 9.6.6)