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
- F-GA-3 (P1): per-subcommand
--helpnow renders correctly for the eight remaining subcommands (audit-chain verify,anomaly subscribe,exit export,did-web issue,identity show,agents list,policy compile,intelligence diagnose). v1.3.1 had only fixed two; v1.3.2 finishes the set. - F-GA-4 (P1): dashboard
/api/snapshotnow reads the same source-of-truth assanctuary identity show. Previously snapshot returnedidentity_count: 0while CLI confirmed a real identity. The dashboard now sees the liveIdentityManagerandAuditLogafter wrap-auto’s fortress bootstrap. - F-GA-6 (P1):
sanctuary inbox approvals listandsanctuary task createnow name the failure class (network connection failure, endpoint 404, auth 401/403, server 5xx) instead of the uninformativefetch failed. - F-GA-8 (P1):
sanctuary castle-wall <unknown>returns explicitUnknown subcommandwith exit code 2, restoring v1.3.0 behavior. v1.3.1 silently spawned an MCP stdio server, misleading operators. - F-GA-9 (P1):
sanctuary wrapnow registers tenant storage paths in a host-level registry (~/.sanctuary/tenants.json).sanctuary agents listreads the registry alongside existing sources. Two concurrent wrapped tenants are now both visible. - F-1.3.1-N-005 (P1):
sovereignty_auditno longer reports 100/100 on a fortress with bricked operations. Severe deductions for audit-chain integrity findings, exit-export blocked state, and MCP-tools-bricked state.
Polish
- F-1.3.1-N-006 (P2):
sanctuary wrap --dashboard-port <port>flag added with integer validation. Was previously env-var-only. - F-GA-10/11/12 (P2): vocabulary drift cleanup:
anomaly statusregistered as alias forlist-subscribed,intelligence diagnose --jsonemits structured JSON,exit helproutes to standard exit help. - F-1.3.1-N-002 (P3):
sanctuary exit exportaborted-state now returns exit code 78 (matchesFORTRESS_NOT_FOUNDconvention). Was returning 0, hiding aborted exports from script callers.
Carry-forward to v1.3.3
- F-1.3.1-N-003 (P1):
--import-stateflag accepted by parser but does not trigger state import. v1.3.2 deferred; v1.3.3 will wire the code path.
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:
- 30 parallel writes from 5 separate Node processes against a shared on-disk fortress produce a clean monotonic audit chain.
- A fortress with injected
sequence_gapfindings allows read-class MCP tools to succeed; write-class tools reject without override and accept withaccept_broken_chain: true.
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.