2026-07-05
Ergonomics release chain completed — all three legs shipped
Finished the release topology for the MCP client ergonomics work (#225):
- Leg 1:
client/v0.15.0auto-released from the #225 merge. - Leg 2 (#226):
clientVersion0.13.2 → 0.15.0 intools/demarkus-plugin/internal/provision/provision.go→ auto-releasedtools/v0.4.1. - Leg 3 (#227):
TOOLS_VERSION0.3.5 → 0.4.1 in all four plugins'bootstrap.sh(lockstep, shared binary) + patch bumps: demarkus-memory 0.12.4, demarkus-knowledge 0.5.4, pi-memory 0.12.5, pi-knowledge 0.5.5, with CHANGELOG entries for the pi pair. Next session start re-provisions demarkus-plugin v0.4.1 → demarkus-mcp v0.15.0; outline mode, #section slicing, session dedup, and mark_explore now reach users.
Also fixed in #227: .claude-plugin/marketplace.json had been desynced
since #217/#221 (still 0.12.2/0.5.2 while the plugin manifests were at
0.12.3/0.5.3) — the manual repins bumped the manifests but missed the
marketplace. Synced to 0.12.4/0.5.4.
Open observations for later (not blocking):
- The
plugin-pin-bumpworkflow's daily runs have reported success since 07-02 without opening a PR, despite pins being behind released versions (client 0.14.0/0.15.0, server 0.19.0, tools 0.4.0/0.4.1 all newer than the pins at the time). Eitherchanged=falseis mis-computed in.github/scripts/bump-plugin-pins.shor something in the PR step is short-circuiting — worth a debugging pass. serverVersionpin still 0.18.0 (server/v0.19.0 released 07-02) andfallbackToolsVersionstill 0.3.3 — both deliberately left out of the repin PRs to keep them narrow; decide whether to sweep them.
plugin-pin-bump silent failure: root-caused and fixed
The "workflow succeeds but no PR" mystery from this morning's loose ends:
gh pr view "$branch" in the workflow's upsert step resolves closed PRs,
so after #210 was closed unmerged it edited that dead PR daily instead of
creating a new one. Proof: #210 (closed 06-24) carries a title naming
server 0.19.0 (released 07-02) and updatedAt 07-03. Fix on branch
fix/plugin-pin-bump-closed-pr: look up an OPEN PR via
gh pr list --head … --state open and edit by number, else create.
Verified both paths read-only against the live repo. Gotcha generalized in
/debugging.md.
Once merged, dispatching the workflow will sweep the remaining stale pins (serverVersion 0.18.0 → 0.19.0, fallbackToolsVersion 0.3.3 → 0.4.1) via a proper auto PR — closing this morning's second loose end through the automation instead of another manual repin.
Automation restored — first proper bump PR since 06-24
#228 (the closed-PR upsert fix) merged; dispatched plugin-pin-bump and it opened #229 — the first real auto bump PR since #210 was closed. It sweeps serverVersion 0.18.0 → 0.19.0 and fallbackToolsVersion 0.3.3 → 0.4.1 plus lineage patch bumps; bootstraps stay at 0.4.1 (already current). Both of this morning's loose ends closed.
Merge note for #229: it updates source pins only. Plugin users still provision server 0.18.0 until a new tools release ships the updated provision.go and the bootstraps repin to it — the standing three-leg topology; the now-working daily automation opens that follow-up bump PR when the tools release appears. Script gap (cosmetic): auto bumps don't add pi CHANGELOG entries.
Wrap: #229 merged, loop fully closed
#229 merged (d0d4b2d) and — correcting the earlier merge note — the
chore(plugins) commit DID auto-release tools/v0.4.2 (release tooling
keys on module changes, not commit type). So server 0.19.0 +
fallbackToolsVersion 0.4.1 are now baked into a shipped demarkus-plugin,
and the next scheduled plugin-pin-bump run (daily 07:23 UTC) will see
tools 0.4.2 ≠ bootstrap pin 0.4.1 and open the bootstrap repin PR on its
own. From here the pin pipeline is fully self-driving again: release →
auto bump PR → merge → repeat. Day's arc: ergonomics phase shipped to
users (#225/#226/#227), pin automation un-wedged (#228), stale pins swept
(#229).
Broker gateway ergonomics parity built (feature/broker-ergonomics-parity)
Ported the client ergonomics to the broker MCP gateway so knowledge-system agents get the same surface; awaiting Fritz's commit.
- Shared code (D4 payoff): the tools module already imports client, so
the new
client/mdoutline/render.go(OutlineBody, LinkLines, CappedList) is consumed by BOTH client cmd and broker — client's local copies were refactored out, no duplication. - W1: broker
handleMarkFetchmoved tomcp_tools_fetchmode.gowith outline mode,#anchorslicing,force. Fragments are cut BEFOREparseToolURL(which rejects them for the other verbs by design — for fetch the fragment now has defined meaning). - W3 with the multi-tenant twist: dedup keyed by MCP session ID
(
ClientSessionFromContext), nested map sessionID → world+path → (version,etag). No session → no dedup, never a cross-user "unchanged". Eviction viaHooks.AddOnUnregisterSession; caps (4096 sessions × 1024 docs) bound memory if a transport never unregisters — beyond cap it degrades to no-dedup, not eviction of someone else's state. - W2:
mark_explore(16th tool; mcpToolNames + handler map + count test 15→16). Backlinks from the broker's ephemeral per-pod graph store with an honest reset note; siblings via dispatcher LIST, degrades on failure. - W4: description pass mirrored (fetch/lookup/list/backlinks + explore).
- Proof of session scoping end-to-end: a new HTTP-level test drives
initialize → Mcp-Session-Id → two tools/call fetches (second returns
status: unchanged) → second initialize gets a fresh session and the full body. Not just a hand-attached session in ctx.
The gateway's fidelity contract is untouched — formatToolResult unchanged;
the new modes compose via a mirrored formatToolResultWith (cloned
metadata, never mutates the response map).
Broker ergonomics parity merged — #230, five review rounds
PR #230 (2d4dab7) landed: the knowledge system's broker MCP gateway now
carries the full W1–W4 ergonomics (outline fetch, #section, force,
session-scoped dedup, mark_explore as the 16th tool, description pass).
The two MCP surfaces are at parity.
The CodeRabbit rounds progressively hardened the dedup identity handling and are worth remembering as a sequence:
- Cap-hit observability + the mcp-go session-leak reality (OnUnregisterSession only fires on explicit DELETE, mcp-go#723) → LRU eviction at the session cap instead of refusing new sessions, Warn logs on both cap paths.
changedNoteetag-only wording ("still v" with no version).- Asymmetric identity flips (versioned ↔ etag-only) rendered a bare "v" — spelled out as "was etag-only, now vN" / "was vN, now etag-only".
- The two-place fixes in rounds 2–3 proved the mirror was the problem →
hoisted identity + notice text into the new shared
client/fetchdeduppackage (Doc, Identified, UnchangedNotice, ChangedNote), one test copy; both surfaces now render through it. - Note branch lacked the
cur.Identified()guard — a response that loses BOTH identity fields after an identified fetch claimed "now etag-only" with no etag. Guarded at both call sites.
Lesson (pattern for /debugging.md if it recurs): duplicated "mirror" code whose drift is caught by review instead of by the compiler will absorb every fix twice and still leak differences — hoist at the second two-place fix, not the fifth. The formatResult mirror survives only because a byte-for-byte fidelity TEST enforces it; the changedNote mirror had no such test and broke twice in one PR.
Shared-package census after this PR: client/mdoutline (outline/slice +
render helpers), client/fetchdedup (dedup identity + notices) — both
consumed by client cmd and broker per D4.
Deploy note: this ships with the next broker release/deploy (server-side
lane); no plugin repin involved. Remaining deferred follow-ups on the
ergonomics plan: MCP resources/prompts, library librarian open
adoption of mdoutline.
Broker 0.5.0 deployed — ergonomics live on the knowledge system
Deploy repo PR merged (18d9097, chart+image 0.2.0 → 0.5.0); ArgoCD
synced; verified live: #section fetch works (old broker rejected
fragments), second fetch of an unchanged doc returns status: unchanged
(201 chars). The whole ergonomics arc is now in production on BOTH
surfaces — plugin users (demarkus-mcp v0.15.0 via tools 0.4.1) and
knowledge-system users (broker 0.5.0). Details in
/demarkus-knowledge-system-deploy/journal/2026-07-05.md.
Record correction: versions sharding shipped in April, not "unstarted"
Fritz caught the soul asserting versions sharding was "fully specced; no
code yet, unstarted" — it shipped in PR #90 (d7cb68a, 2026-04-08),
the same day the plan was written, and the store was later hoisted to
protocol/store (#120). The 2026-05-31 index verification pass missed it,
likely because the plan doc carried no completion stamp and the commit
subject says feat(filestore) while the plan says "sharding". Fixed: plan
doc stamped COMPLETE, index entry moved to Completed Plans (and the MCP
ergonomics plan added there too — it was never indexed).
Hygiene lesson: stamp the plan doc at ship time, in the same session — grep-based verification passes can't recover intent from mismatched vocabulary. The index is only as good as the completion discipline.