Sanctuary v1.3.2: audit chain pilot-ready under concurrent load

Sanctuary v1.3.2 is a focused patch release that closes the two P0 operator-trust cliffs surfaced by the v1.3.1 Mini1 drill, plus eight P1/P2/P3 carry-forward findings. The headline change: the audit chain now holds under concurrent dashboard + CLI write load, and a fortress whose audit chain has accumulated integrity findings can still be introspected and recovered through the MCP read-tool surface.

v1.3.1 was not pilot-ready. v1.3.2 is.

What changed

Audit chain: the core fix

F-1.3.1-N-001 (P0): cross-process seq-duplication race. v1.3.0 GA on Mini1 produced a clean MMMMM audit-export-and-verify cycle. v1.3.1 against the same machine produced sequence_gap and checkpoint_root_mismatch under any concurrent write load. Dashboard idle alone was sufficient to trigger the race. Once any integrity finding accumulated, exit export, state_write, AND read-class MCP tools all refused to run.

Root cause: each Sanctuary process held its own AuditLog instance with an independent in-memory nextSequence counter. The in-process appendQueue serialized writes within one process, but cross-process writers had no coordination. Two processes both read seq N from disk, both wrote at seq N+1 with different sub-indices, both succeeded at the filesystem layer, and the verifier correctly caught the duplicate as a sequence break.

Fix shape: process-level serialize via lockfile + freshen-from-disk under the lock. Before allocating a sequence number, the writer acquires an exclusive flock against _audit/.audit-write.lock, re-reads the highest persisted seq from disk, and then writes its entry with that fresh value. The lock holds for the duration of one entry write (~ms). Concurrent writers serialize without losing audit data.

The spawn-prompt-considered alternative, making the verifier sub-index-aware, was rejected after design analysis. Two writers at the same seq with divergent prev_hash produce genuinely distinct audit entries with different payloads. Collapsing them would lose audit data. The sub-index in the on-disk filename was anticipatory but does not solve the divergent-prev_hash problem.

F-1.3.1-N-004 (P0): MCP read tools refused to run after audit chain integrity findings. Once a fortress’s audit chain had any integrity finding, all MCP tool calls returned JSON-RPC -32603 with "N audit integrity findings detected". This included read-class tools (identity_list, federation_status, sovereignty_audit). Operator could not introspect their broken fortress to diagnose or recover.

Fix: the MCP router now distinguishes read tools from write tools. Read tools bypass the audit-integrity gate unconditionally: operator can always introspect. Write tools keep the gate but accept accept_broken_chain: true as an operator-explicit override for recovery scenarios. The override path writes its own audit entry for traceability. A registration-time check ensures every tool declares its class.

Operator-experience improvements

Polish

Carry-forward to v1.3.3

How to install

npm install -g @sanctuary-framework/mcp-server

Operators on v1.3.0 or v1.3.1 should upgrade. The audit-chain race is silent until a downstream operation tries to use the chain, at which point operations refuse.

Acceptance drill

v1.3.2 is tested against the v1.3.1 Mini1 acceptance drill plus the regression scenarios that surfaced F-1.3.1-N-001 and N-004:

Drill results doc: Wiki/sessions/sanctuary-v1.3.2-execution-results-mini1-2026-05-22.md.

Acknowledgments

v1.3.2 was assembled by an autonomous patch coordinator running on Mini1 from the v1.3.1 Mini1 drill results, dispatching nine parallel Codex workers for the carry-forward findings and two more for the P0 fixes, then cascade-merging eleven PRs.

What’s next

v1.3.3 picks up F-1.3.1-N-003 (--import-state wiring), the ZZZZZ continuation (CLI write-ops audit-logging completeness), and continued v1.x principle-closing work.