#362: make the plugin visible, and fix the drift that made it unusable #363
Reference in New Issue
Block a user
Delete Branch "362-plugin-visibility-and-drift"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes the first two scope items of #362. Item 3 (seeding
.claude/skills/into provisioned worktrees) is a separate branch.Why
CB-527 shipped a Claude Code plugin and a marketplace in this repo. In September 2026 a session planned the same feature from scratch, because nothing in
CLAUDE.mdordocs/named it.The
wiki/11-Features.mdentry did exist and was correct. It did not help:wiki/is a submodule whose pointer is never advanced, so no session reads it by default. That is the real defect — a documentation-channel problem, not a missing-documentation problem.Visibility
CLAUDE.mdaddendum now namesplugin/and both structural limits. This is the change that stops the rebuild recurring — it is the only file every session loads.wiki/11-Features.mdrecords the rename and, explicitly, that the entry alone was not enough.Drift fixed — each measured against the code
fleetd→fleetPeerLauncher.java:34MCP_MOUNT_NAME. The old name gave a lead with both a project.mcp.jsonand the plugin two mounts of one daemon and a duplicatedfleet_*tool set${FLEETD_MCP_URL}claude-bridge→fleet, marketplace →fleetd, v0.2.0fleet/fleetdsince CB-623, notltms/claude-bridgesetup§5primary.terminal:→fleet.leaders.*.tabBreaking for a 0.1.0 install. A project that pre-allowed
mcp__fleetd__fleet_whoamiin.claude/settings.jsonmust be updated tomcp__fleet__*. Only this fleet has it installed, so the cost is small now and grows.I used the plain
${VAR}form, not${VAR:-default}.kb-almsproves the plain form works in a real installed plugin on this machine; the default-value form is untested, and I was not willing to put an unverified expansion in the one file every session's mount depends on. Thesetupskill now checks the variable in preflight.Scope: the plugin is lead-side only, and cannot be otherwise
Two structural reasons, both verified in the code, not assumed:
ClaudeCodeLauncher.java:371callsagentDefinitionFile(spec.cwd(), spec.role(), ".claude", "agents");HerdrPeerLauncher.java:359-365returns a path only when<cwd>/.claude/agents/<role>.mdis a regular file;:391-393adds--agentonly when that is non-null. Agent files must live in the member's worktree.ClaudeCodeLauncher.java:285exportsCLAUDE_CONFIG_DIRfrom the profile'sconfigDir. All four Claude profiles on the live Mac fleet set it, and the fourccsinstances hold four separate copies of the plugin store — same md5 (51c6e1c853e32e656b817e123fbbfcc5), different inodes. A member never reads the operator's plugin store.So member-facing assets travel in the worktree. That is #362 item 3.
Verification
claude plugin validate ./plugin→ passes clean.mvn -o test -Dtest=McpContractDocTest→ Tests run: 3, Failures: 0, Errors: 0.CLAUDE.mdblock is still byte-identical with the wiki template (the repo's own python check printsin sync: True). My edit was in the project addendum, not the block.A warning worth keeping:
claude plugin validatedoes not read.mcp.json. I replaced the file with{ this is not json at alland validation still passed with exit 0. It validates the manifest only. Do not use it as evidence a mount is correct — I nearly did.Not done here
plugin/still ships only thesetupskill. The bridge-charter skill, which would end the hand-copiedCLAUDE.mdblock, is a later stage.CB-527 shipped a Claude Code plugin and a marketplace in this repo. Nothing in CLAUDE.md or docs/ ever named it, so a later session planned the same feature from scratch. The wiki Features entry existed and was correct, but wiki/ is a submodule whose pointer is never advanced, so no session reads it. Visibility: - CLAUDE.md addendum now names plugin/ and both structural limits, so every session sees it. This is the change that stops the rebuild happening again. - wiki/11-Features.md records the rename and why the entry alone was not enough. Drift (each measured against the code, not assumed): - mount name fleetd -> fleet, matching PeerLauncher.MCP_MOUNT_NAME. The old name gave a lead with both a project .mcp.json and the plugin two mounts of one daemon and a duplicated fleet_* tool set. - url is now ${FLEETD_MCP_URL} instead of a hardcoded address, so one plugin can serve hosts running the daemon on different ports. Plain ${VAR}, the form kb-alms proves works here; ${VAR:-default} is untested and not used. - plugin claude-bridge -> fleet, marketplace claude-bridge -> fleetd, version 0.2.0. Breaking for a 0.1.0 install: mcp__fleetd__* becomes mcp__fleet__*. - README install path ltms/claude-bridge -> the fleet/fleetd remote. - the setup skill's §5 told operators to pin primary.terminal:. CB-579 replaced that with fleet.leaders.*.tab. Replaced, with the duplicate-tab warning (#359). Scope: the plugin is lead-side only, and cannot be otherwise. The launcher adds --agent only when <worktree>/.claude/agents/<role>.md exists in the member's own tree (ClaudeCodeLauncher.java:371,391), and a member's CLAUDE_CONFIG_DIR points at its profile's config dir (ClaudeCodeLauncher.java:285), so a member never reads the operator's plugin store. On this Mac all four Claude profiles set configDir, and the four ccs instances hold four separate copies of the plugin store -- same md5, different inodes. Seeding member skills through the worktree is #362 scope item 3, implemented separately. Note for anyone verifying a plugin: `claude plugin validate` does NOT read .mcp.json. Replacing it with `{ this is not json at all` still passes, exit 0. Refs #362, #359Correction to the "Breaking for a 0.1.0 install" paragraph. I wrote "Only this fleet has it installed". I had not measured that. I have now:
Nobody has it installed, including this fleet, and this repo's marketplace is not even registered. So the rename breaks nothing that exists today — the "breaking change" is theoretical, not a live migration. That makes the rename cheaper than the PR body claims, not more expensive.
It also sharpens the original finding. The plugin was not merely undocumented in the files sessions read: it was never installed anywhere either. It shipped, and then nothing consumed it.