fix(orchestrator): path hashing + system_status version emit - #7
Open
evannadeau wants to merge 2 commits into
Open
fix(orchestrator): path hashing + system_status version emit#7evannadeau wants to merge 2 commits into
evannadeau wants to merge 2 commits into
Conversation
…ewatcher projectHash mirrors how Claude Code names per-project dirs under ~/.claude/projects/. CC keeps the leading dash that comes from POSIX absolute paths (/home/foo -> -home-foo). The previous .replace(/^-+/, "") stripped that dash, producing 'home-foo' instead of '-home-foo' and silently pointing the agent-channel JSONL filewatcher at a directory that doesn't exist. The MCP server stayed up and tools answered, but no cross-session channel events were observed (and downstream features that depend on the watcher quietly broke). Reference: anti_pattern 6dfc7ae1. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…d literal)
The system_status output line hardcoded "0.30.28" instead of using the
${PLUGIN_VERSION} constant that's already read from package.json at module
load. The 0.30.31 cleanup (see lines 32-37 of mcp/server.ts) consolidated
the version source specifically so it wouldn't be "hardcoded in multiple
spots and forgotten on every other version bump" — but this single line at
mcp/server.ts:655 was missed during that consolidation, and every bump
since (0.30.32 → 0.30.38) shipped with the line still saying 0.30.28.
Concrete symptom: running an up-to-date plugin and calling system_status
returns "**Version**: orchestrator MCP server **0.30.28**" regardless of
the actual package.json version. The startup banner (which uses
PLUGIN_VERSION directly) reports correctly — only this line was wrong.
Tested: bun run typecheck clean, bun test 516 pass / 0 fail, dist/server.js
rebuilt via bun run build.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SpawnBox-dev
pushed a commit
that referenced
this pull request
Jul 28, 2026
…and the triage branches on need instead of enforcing an order Firing #7 (0-for-7) refired on PA at 13:32Z, 22 minutes after PA had answered a direct address and closed #6. Two independent reports, two distinct fixes. MEASURED AT THE MOMENT IT FIRED, before concluding anything: PA's transcript had been written 2 SECONDS earlier, and six of seven sessions had produced output within 20s. So the subject was demonstrably alive and the fleet demonstrably awake - which also confirms 0.31.6's dormant suppressor is correctly SCOPED rather than over-broad: it did not catch this, and should not have. 1. REFRACTORY FLOOR (SA-c5b207e0). The episode dedup clears the moment a verdict goes healthy, so the alert re-arms and re-asks immediately, forever, and every ask costs a peer a turn. The subject's own recent OUTPUT is far stronger proof of liveness than an unprocessed delivery is proof of the opposite. Emission is now floored at 30 minutes per session, OUTSIDE the episode dedup - the alert remembers it just asked. Their honest note is why this is a defect rather than an annoyance: they skipped the triage this time and said plainly that "I judged it safe to skip" is not something the triage should have to rely on. That is the alert training the behaviour it must not train. 2. TRIAGE BRANCHES ON NEED (SA-b14fafa3). The 0.30.77 text numbered the checks 1-2-3 and said "do NOT skip" - but the costs are not comparable. ADDRESSING SPENDS A PEER'S TURN; TRANSCRIPT MTIME COSTS NOBODY ANYTHING and is conclusive for liveness. So a fixed order is wrong for the common case. Now: need only liveness -> mtime first, free and instant. Need something from them anyway -> address, since liveness rides along free. Answered recently -> do nothing. The sharp part: PA had ALREADY been reasoning this way, praising one session for choosing mtime and another for addressing. But that judgement lived in PA's head, not in the alert text, and non-PA readers only have the text. Same lesson as putting the base rate in the alert - encode the reasoning where the reader is. TEST NOTE, recorded because it looked like a product bug and was not: the recovery/re-arm integration test began failing, and the cause was MY OWN 0.31.6 dormant gate. That test advances a SIMULATED clock 30 minutes while file mtimes stay at real time, so every peer transcript looked 30 minutes stale and suppressed as "fleet asleep". An artifact of simulating time with real files - in production both clocks are real. Fixed by ageing the fixture with utimesSync rather than by weakening either check, and the test's original property (episode state CLEARS on recovery, not merely suppressed) is preserved and still asserted. Two of tonight's checks now interact, which is worth knowing: refractory (30m) exceeds the dormant threshold (15m), so a post-refractory re-emit requires the fleet to be active at that later time. Correct in production; only the harness had to be taught about it. Tests: +6 refractory (first firing allowed; suppresses the exact 22-minute refire; allows a genuinely new episode past the window; exact boundary; window exceeds the delivery threshold; independence from the dormant gate). Suite 841 pass / 0 fail. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MLELREep1GfMbuPSpmJRcu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two independent latent bugs in
plugins/orchestrator/mcp/server.ts. Bundled because both are one-line fixes to the same file with the samebun run buildcost.1. Path hashing — leading-dash strip broke the JSONL filewatcher on POSIX (
cab2a57)projectHashmirrors how Claude Code names per-project directories under~/.claude/projects/. CC keeps the leading dash that comes from POSIX absolute paths (/home/foo→-home-foo). The previous.replace(/^-+/, "")stripped that dash, producinghome-fooinstead of-home-fooand silently pointing the agent-channel JSONL filewatcher at a directory that doesn't exist.The MCP server stayed up and tools answered normally, but no cross-session channel events were observed (and downstream features that depend on the watcher quietly broke). Diagnostic: absence of
offsets-<id8>.jsonfiles in<project>/.orchestrator-state/agent-channel/despite live JSONLs in~/.claude/projects/-<...>.Fix: drop the strip. The Windows case (
C:\foo→C--foo) just produces a cosmetic double-dash and remains harmless — that was the original reason for the strip, but the cost on POSIX (silent feature death) outweighs the cosmetic cleanup on Windows.2. system_status emitted hardcoded version string (
93c5da6)system_statusreported a literal0.30.28instead of${PLUGIN_VERSION}. The 0.30.31 cleanup (see the comment atmcp/server.ts:32-37) consolidated the version source to read frompackage.jsonat module load specifically so it wouldn't be "hardcoded in multiple spots and forgotten on every other version bump" — but the system_status line atmcp/server.ts:655was missed during that consolidation. Every bump since (0.30.32 → 0.30.38) shipped with the line still saying 0.30.28.Concrete symptom: running an up-to-date install and calling
system_statusreturns**Version**: orchestrator MCP server **0.30.28**regardless of the actual package version. The startup banner usesPLUGIN_VERSIONdirectly and reports correctly — only this one line was wrong.Fix: use the existing
PLUGIN_VERSIONconstant.Files changed
plugins/orchestrator/mcp/server.ts— 2 single-line edits (line 2183 path-hashing, line 655 version emit)plugins/orchestrator/dist/server.js— rebuilt viabun run buildTested
bun run typecheck— cleanbun test— 516 pass / 0 fail / 38 files / 1207 assertionsdist/server.jsno longer contains the0.30.28literal in the system_status output line; build output is byte-stable across repeatedbun run buildruns against the same source.Test plan
~/.claude/projects/-<...>is scanned —offsets-*.jsonfiles appear in<project>/.orchestrator-state/agent-channel/and@SA-<id8>channel addresses deliver to peer sessions.C:\fooinputs (cosmetic double-dashC--fooexpected).system_statusreports thepackage.jsonversion, not the hardcoded0.30.28.🤖 Generated with Claude Code