Repository navigation
v1.96.0 - Trust and Responsiveness Hardening
Open Second Brain v1.96.0 - Trust and Responsiveness Hardening
Open Second Brain v1.96.0 makes the vault's seams state what they accept, and its stdio reads stop queueing behind each other. Third-party text could carry wikilinks, @osb markers and osb fence lines into capture pages and ingest summaries as live vault structure - the link graph, the marker scanners and the section parsers read it as the vault's own; now an optional neutralization gate escapes that markdown at the write seam, off by default as a deliberate operator choice, with a shadow mode that measures without writing and a read-only doctor audit naming the pages that already carry planted rows. The install answers for its own state: a fresh o2b brain init seeds a managed .gitignore block so derived state stays out of git, a doctor error names every path git already tracks, and the readiness probe fails a write-back contract installed into a file the operative host never reads. And read-classified MCP calls run up to four in flight while writes stay exclusive and arrival-ordered behind a dispatch-level gate.
What ships
- Write-time markdown neutralization at the third-party seams, gated off, shadow or enforce. With
markdown_neutralize_mode(envOPEN_SECOND_BRAIN_MARKDOWN_NEUTRALIZE_MODE, defaultoff), the two seams where third-party text lands - capture writes and untrusted-source ingest summaries - run the gate on caller text:enforcebackslash-escapes the structure-bearing markdown (wikilinks,@osbinline markers,osbfence lines, ATX headings) before it is written, so no scanner treats it as the vault's own, and stamps aneutralized_markersfrontmatter key naming the escaped families;shadowleaves every write byte-identical and lets the would-be families surface through the doctor audit;off, the default and a deliberate operator choice, runs no gate. The env twin wins over the config key, an invalid value is refused by name at the seam, and because capture identity hashes the persisted bytes, flipping the mode between captures of the same text yields an honest duplicate rather than a silent mutation. - A read-only doctor audit names the pages that already carry planted rows. The
o2b brain doctorpass gains the fail-softplanted-structure-rowsfinding: it counts the live structure rows third-party text planted in capture pages, untrusted-stamped pages, quarantined entity pages and source summaries, names up to five paths and counts the rest, and stays silent on a vault with none. Undershadow, the finding appends a preview of whatenforcewould escape on the next capture or untrusted ingest of the same text. The audit is read-only by contract - the rows leave only by re-capturing the text with the gate inenforceor by a later repair pass - so the finding carries noo2bcommand. o2b brain initseeds a managed .gitignore guard, and a doctor error names derived state git already tracks. A fresh init in a git repository writes a managed guard block over/.open-second-brain/- the derived runtime state, bench runs included - beside the identity stamp, so a fresh vault no longer leavesbrain.sqlitevisible togit status. The seeder merges with existing content, never clobbers a conforming block, keeps CRLF endings, reports malformed markers as a named conflict, and--forcenever rewrites the guard. For existing vaults, thegit-tracked-derived-statedoctor check measures what git actually tracks withgit ls-files- never inferred from status - and answers with an error naming the untrack command and the missing ignore line; the check never edits anything.o2b doctor --readinessfails a shadowed instruction contract. A workspace where the file the operative host reads carries no managed write-back block while another candidate file carries it had the contract installed where it never runs. The readiness probe now grades that placement as a fail: per the host-to-file precedence, claude-code readsCLAUDE.md, codex, cursor, opencode and aider readAGENTS.md, and gemini-cli readsGEMINI.md; the finding names the host, the file the host reads, the file carrying the contract and the read-only recovery clause. Symlinked candidates keep their refused unknown treatment, and a workspace with no instruction file at all stays skipped - nothing installed is not a contract violation.- Parallel reads with exclusive writes on the stdio MCP transport. Every tool is classified
readorwritein the registry at registration - write-mode-dominant, decided per operation family, never from arguments at dispatch - and the classification is metadata only: it never reaches thetools/listwire payload, and a definition that arrives without one is treated aswrite, so it can only ever lose concurrency, never safety. Read-classified calls run concurrently, up to four in flight - a constant, backpressured at the cap - while write-classified calls run one at a time behind a dispatch-level FIFO gate and never beside a read: the loop reads no further line until a dispatched write has settled. Cross-request frame order is surrendered in one direction - responses may arrive out of arrival order, which is legal JSON-RPC; correlate by responseidand progress byprogressToken- while each request's own progress notifications all precede its response. - Digest and brief delivery surfaces honor the enforced owner scope. The digest's maintenance actions, the brief period rows and the digest's dream-parsed shift and contradiction rows were filtered by transport reach alone, so under
integrity.owner_scope_delivery: faila scoped caller could receive rows naming preferences the sections beside them had already withheld. Those rows are now kept through the same enforced ownership rule at every reach, a caller the enforced scope narrows takes no report snapshot and is shown no delta, and without the gate - or underwarn- every output is byte-identical.
Guarded seams, an install that answers for its own state, and reads that no longer queue behind each other - every claim above traces to the 1.96.0 CHANGELOG entry and the merged PR #281.
