v0.1.40
[0.1.40] — 2026-07-15
0.1.39 was never published — the version was bumped and a changelog section cut,
but no tag, GitHub release, or PyPI artifact ever carried it. This release
supersedes it and contains everything that section described. If you have a
0.1.39 wheel from a local build, it predates this release and is not a
released version.
Upgrade notes
mms doctornow exits nonzero on a dense-to-BM25 LTM degradation that
previously only warned. Automation that gates onmms doctor's exit status
will start failing against a core whose configured dense retrieval has
degraded — the diagnosis is the point, but the exit status is new. An
intentional BM25-only configuration still exits zero with a warning. (#709)- A
context_composeresponse missing its negotiated top-level keys is now a
fault rather than an empty result. A core that conforms to the negotiated
schema is unaffected; against one that renamed or retyped a key, surfacing now
reportsltm_call_failedand warns, where it previously reported
empty_resultsand stayed silent. The warning fires once per surfacing engine
and does not re-arm, so a later independent compose regression is counted but
not re-warned. (#710)
Added
- Added portable Toolgraph policy-bundle enforcement for the STM MCP gateway,
including strict/review/explore profiles, list/call gates, contract-drift
validation, andmms gateway status,explain, andmodeoperator commands
(#701). Added a review-first gateway guide and a producer-owned cross-repo
smoke contract (#703). - Added
mms selection replayfor issue #468 (#698): read-only schema/join/cohort
diagnostics over selection JSONL plus deterministic evaluation of the current
eligibility filter and BM25 ranker on a packaged, sanitized 30-case corpus.
The report evaluates 35 existing risk-weight combinations with safety-first
train/validation/test gates and emits a config preview without applying it. - Added
mms doctor --measure-ltmwarm-daemon search sampling and runtime-profile
checks for missing ONNX/Korean extras and configured-versus-effective retrieval
mode, with measured timeout recommendations (#709). - Added a native Windows first-success path: cross-process state locking,
PowerShell diagnostics, safe daemon-stop behavior, platform-aware Claude
Desktop discovery, and absolute-Python MCP registrations. (#700) - Added
mms init --demo --client auto|claude|codex|json|skip,--resume,
cache freshness presets, Codex registration,CODEX_HOMEdiscovery, trusted
project Codex configs, and stdio upstreamcwdsupport. (#700) - A catalog-wide policy-bundle bind failure now warns once per episode, naming
the likely cause — atool_contract_digestalgorithm or stale-catalog drift
versus atoolgraph.server_name_mapmismatch — instead of silently withholding
every tool understrict.stm_proxy_healthreports the same diagnosis, with
the unmapped/drifted split when the cause is mixed. Only STM-computed
rejections count toward the diagnosis: aDRIFTED/UNMAPPEDreason the
producer declared in the bundle maps to the same reject code, so counting
final codes would false-alarm on a catalog of deliberate denials. (#706) - The gateway now warns once at adoption when the policy bundle looks substitutable,
naming what an unprotected bundle exposes. The bundle is the gateway's only
enforcement authority and is unsigned, so anyone able to write it — or rename any
directory above it — decides what the proxy exposes. Scope: POSIX owner and mode
bits only. It is a no-op on Windows, and extended ACLs are not evaluated, so a
0644file carryingeveryone allow writereads as clean — silence is not an
assurance of protection. Advisory only: findings are logged and the bundle is
still adopted. (#708) - Added a Korean vibe-coding quickstart guide. (#699)
Changed
- Behavior change:
mms doctornow exits nonzero when a connected LTM has
degraded from configured dense retrieval to BM25-only, while an intentional
BM25-only configuration remains a warning and older cores without a runtime
profile remain warning-only (#709). - The packaged
policy-bundle.schema.jsonis re-vendored byte-identical to the
producer's copy, which now carries the contract as normative prose:tool_key
uniqueness acrosstools(withuniqueItems: truebackstopping exact
duplicates only), consumer MAY-ignore notes forcreated_at,risk_score,
reasonon an eligible row, andpaths,graph_statedocumented
closed-by-design, and the producer's int-literal obligation forgeneration.
Enforcement is unchanged — the runtime parser never read the schema. (#712)
Fixed
- Behavior change: a
context_composeresponse whose negotiated top-level
pinned/retrievedkeys are missing or not arrays is now a fault naming the
schema version, on both the direct and shared-daemon routes. Previously each
route defaulted to an empty list, so a core that renamed a key silently
produced an empty bundle that surfacing classified asempty_results— a
degradation indistinguishable from an empty namespace, past every fault
counter. It is now classifiedltm_call_failedand warned once per surfacing
engine (the latch is per-instance and does not re-arm after a healthy
compose). (#710) mms register --client codex --replace-registrationno longer removes the
existing registration before knowing it can be rebuilt. It captures
codex mcp get --jsonfirst and refuses to remove a registration
codex mcp addcannot reproduce exactly; when the replacement add fails it
attempts to restore the previous one and reports whether that restore
succeeded. Codex has no.mcp.jsonfallback, so the previous remove-then-add
could leave no registration at all. Rollback is an attempt, not a guarantee:
a restore can itself fail, and the command says so rather than implying the
old registration survived. (#705)- New MCP and native-hook registrations now pin a shared-daemon runtime policy
with ordered surfacing/hook deadlines instead of depending on host environment
inheritance. Existing registrations remain keep-by-default; explicit refreshes
preserve unrelated environment and host fields, and legacy inline-envhook
commands migrate to portable runtime flags (#709). - Score-scale recovery persistence now writes once per healthy transition instead
of committing on every healthy search, while retaining restart recovery and
re-arming after a below-threshold observation (#709). - Short-lived MCP sessions now keep task groups owned by the serving task and
close reconnect owners before shutdown, eliminating Python 3.13 AnyIO
cancel-scope warnings without changing long-lived daemon behavior (#709). - Failed Codex MCP registration now exits nonzero and reports
ok: falsein
JSON setup output, preventing automation from treating an unusable setup as
successful (#702). - Corrected public configuration, surfacing, MCP-tool, and notebook guidance to
match the v0.1.38 runtime contracts and keep copy/paste examples executable.
(#697)