v2.11.7
[2.11.7] — 2026-09-18
Added
- The org bus now carries a
tool_resultevent when a tool call completes, so "did that command work?" is a field rather than an inference from the agent's own narration — aBashrunning a test suite previously looked identical on the bus whether it passed, failed, or the binary was missing. Correlated to its invocation by the SDK's per-call id (so two concurrentBashcalls from one role stay distinct), carryingok, duration and output capped at 4,000 characters withredactSecretsapplied before the cut and truncation signalled structurally. Typed asToolResultEventDataintypes.tsrather than an ad-hoc literal; runners that cannot observe tool completion simply never emit it (#289: a4bcf86). - Decision traces carry a structured
kind(fence-block,gate-pending,policy-deny,approval-pending,approval-resolved,cross-org-handoff, …). A prompt-injection fence block and a routine wait for human approval previously emitted identical structured fields, distinguishable only by matching English prose. The field is required inrecordDecision's signature, so the compiler guarantees every emitter populates it — which covered four emitters, not the two originally reported (#290: 071a646).
Fixed
- Org run memory was silently dropped when the memory backend could not load:
bridgeStoreEntryreturnsnull,storeRunMemoryignored it, and its caller'scatchnever fired because nothing threw. Runs completed normally,runtime.jsonand history were written, the bus looked perfect — and everyorg_recallcame back empty, with the only trace printed underMONOMIND_DEBUG=1. A failed store now surfaces three ways that outlive the terminal: anorg-memory-store-failedaudit event, an unconditional warning, and amemoryErrorfield inruntime.jsonthatorg statusprints (human and--format json). It deliberately does not throw — by then the run has succeeded and its history is on disk, so throwing would fail a run that worked and blame history for it. The same swallowed-nullpattern was fixed in four more callers, two of which actively misreported:hooks post-commandreturnedrecorded: truefor a write that never happened and skipped its JSON fallback (losing the record twice), and a consolidation worker counted patterns it never wrote (#293: bc75ea5). policy.gitdenials now name the boundary and the allowed alternative, not just the rejected attempt. "path escapes org workdir" never said what the workdir was, so a role could only guess another path — in one rehearsal a reviewer's singleReadwas denied, it never learned the root it ran under, and it reviewed from submission messages without reading a line of code. Five denial messages fixed: workdir escape, write-scope, path-lessGrep/Glob, tool allowlist and research-domain allowlist (#291: 3911a5e).monomind org branch <org> <run> <label>read as though<label>named the new run; the id is generated, and the label was not merely a note — it was discarded entirely, never reaching.branch-source. The label is now recorded,--format jsonprints the generated id ({"v":1,"org":…,"run":…,"from":…,"label":…}) so a script can replay without parsing prose, and the help no longer shows a label in the id position. The label is deliberately NOT used as the run id: run ids are joined into filesystem paths and the codebase already guards that shape against traversal (#292: f4c08a3).biomelinted nothing inside.claude/worktrees, which is where this repo's own workflow puts worktrees:npx biome checkreported "Checked 0 files" and naming a file said the path was ignored. A "lint is clean" reading was really "biome refused to look" — CI was unaffected, but anyone working the recommended way was misled. The ignore pattern now excludes the.claudeassets without excluding a worktree checkout's own source, with a repo test asserting both directions (#294: 71b3e17).
Changed
scripts/sync-claude-trees.mjs(pnpm run sync:claude-trees, with--checkinverifyand CI) keeps the five.claudeasset trees canonical afterinitmarks files in this repo. It normalises rather than mirrors: the shippedpackages/@monomind/cli/.claudeis init's asset source, so copying the marked root copy into it would ship per-project markers to every npm user and make the nextinitnest a second block inside the first. It never creates and never deletes, which is how the shipped superset is protected structurally. The deadsync-claude-assets.sh(a hardexit 1since July, still referenced by three checklists) is deleted, and the parity test, skill lint anddoc/publishing.mdnow name the real command (42cb52e).@monoes/hooks1.0.6 → 1.0.7 (the consolidation-worker fix above).
npm: monomind@2.11.7 · @monoes/monomindcli@2.11.7 · @monoes/hooks@1.0.7