Origin
Established during the initial audit-log architecture work on 2026-03-20 and amended on 2026-04-17 after the reorder procedure incident surfaced a violation of the transaction-boundary rule (AL-7). The function’s signature and semantics have been stable since the amendment.
Rule Text
writeAuditLog is an async function exported from packages/api/lib/audit.ts. It accepts a single params object ({ userId, organizationId, action, entityType, entityId, product, metadata?, ipAddress? }) and returns Promise<void>. It does NOT return the inserted row. It uses its own top-level db import — not the caller’s ctx.db or transaction tx — so audit writes are never part of the caller’s transaction and cannot be rolled back by a failed caller transaction.
Testable Assertion
expect(await writeAuditLog(params)).toBeUndefined();
// It swallows internal errors — never throws:
expect(writeAuditLog({ ...brokenParams })).resolves.toBeUndefined();
Enforcement
- Runtime — The function body catches every internal error and logs via
writeSystemErrorLograther than throwing. Callers that wrapwriteAuditLogin try/catch are flagged in review as dead code (the catch can never fire).
Violation Closed
Audit writes being rolled back with failed caller transactions — which would produce the failure mode where a defective mutation succeeds but its audit entry disappears, destroying forensic integrity. Also closes the dead-code try/catch pattern that accumulated across caller files before the contract was clarified.