Repository navigation
feat(bridge): package the Claude Code mod and session-bound command - #74
Conversation
Add the Captain's Bridge mod skeleton to the Claude plugin: hooks module, hooks.json modules entry, PluginState/BridgeState type contract, userConfig, /captains-bridge (immediate) bound to the exact session id, changed-conversation state, 2.1.293 minimum-version gate, and a non-drawing text fallback. CI installs an exact checksum-verified Claude Code 2.1.296, runs claude plugin validate and claude plugin test without credentials, and fails closed on calls outside the read-only allowlist. Refs #68, #55
timeleft--
left a comment
There was a problem hiding this comment.
Reviewed a55ebc1 against #68 and #55. One material binding defect is described inline.
Verification: 62 focused Python packaging, toolchain, supply-chain and public-boundary tests pass. The 25 shipped mod tests and real validation pass on official checksum-verified Claude Code 2.1.293 and 2.1.296 in credential-free temporary homes; the 2.1.296 pins match the official release manifest. The Linux CI receipt also shows 25 pass, 0 fail and the seven calls within #55's allowlist. The additional clear-then-reload regression fails on both terminal and desktop.
Version synchronization is a separate merge blocker. The current Version policy check fails because the feature bump is absent; the Captain's explicit no-touch instruction for .codex-plugin/plugin.json remains in force. Preserve that boundary and the existing checks during this repair; do not change the Codex manifest or version policy to resolve the conflict.
timeleft--
left a comment
There was a problem hiding this comment.
Captain re-review of exact head 62d5078.
The requested reload repair is fixed. Clear, resume, fork and session.end now keep the binding invalidated through session.start until an explicit /captains-bridge command. The added public-seam regressions cover the lifecycle and both drawn surfaces. Independent real-Claude-Code 2.1.296 validation passed, and the combined shipped tests plus the independent terminal/Desktop reload probes passed (33 tests, 0 failures). All five required source checks pass on this head. No further code repair is requested.
Merge remains blocked by the repository Version policy check: it expects 0.6.0 in pyproject.toml, the Python package version, and both plugin manifests; all remain at 0.5.0. The accepted #55 track explicitly forbids changing .codex-plugin/plugin.json. The worker correctly preserved that constraint. Resolving this requires reconciling the version-policy and track-scope constraints; do not modify the excluded manifest, weaken the check, or make an unrelated change in response to this review.
This is a blocked review checkpoint, not a merge approval.
timeleft--
left a comment
There was a problem hiding this comment.
Captain review of exact head 62d5078 under the updated #55/#68 scope.
The Captain has resolved the manifest-scope conflict. The accepted child now permits the repository updater to synchronize all configured version mirrors, including .codex-plugin/plugin.json. The previous blocked review is superseded by this actionable repair request.
Run scripts/mw-version.py update/check against the latest origin/main using this PR's actual Conventional Commit title and body. Synchronize pyproject.toml, the Python package version, and both plugin manifests; preserve version-policy configuration and checks. Re-run the updater after incorporating any newer main from the parallel Codex track. Remove obsolete no-touch/version-held statements from the PR and affected changelog/guide so they describe the final implementation accurately.
The reload-binding repair remains accepted: invalidated binding survives session.start until explicit opening; 33 real-Claude mod tests including independent terminal/Desktop probes passed on this head. Reuse that evidence for unchanged behavior and retain the real CLI CI path. Do not change Codex feature work or #53/#56–#61. Return the repair on this same worker PR.
timeleft--
left a comment
There was a problem hiding this comment.
The version-synchronization repair is accepted in substance, and the earlier reload-binding fix and real Claude Code validation/test receipts remain valid. One required base update remains: main advanced to dc99e4c (0.6.0) when PR #64 merged. This exact head does not contain it; GitHub reports a merge conflict and scripts/mw-version.py check --base dc99e4cc96837eec1b0c8bb24760a9f276ea75bc --event-file <actual PR title/body> fails with branch is behind current base; update the branch and rerun the updater.
Merge current origin/main into this same worker branch, resolve the shared changelog/verify/docs files preserving main's Codex MCP and observation behavior, then run the updater and check again with this actual feature PR title/body. The feature bump against main 0.6.0 should synchronize 0.7.0 across all four mirrors, including .codex-plugin/plugin.json. Update the PR's stale version paragraph accordingly. Do not force-push, create another PR, weaken checks, or alter #53/#56–#61. No additional product changes are requested.
…fter merging main
timeleft--
left a comment
There was a problem hiding this comment.
The requested dc99e4c integration is correct; the product code remains unchanged and earlier validation/test receipts remain valid. The reader PR #75 merged while this repair was being published, so this exact head still misses the actual current main f384c9c (0.7.0). GitHub reports dirty, and the version-policy check against f384c9c fails with branch is behind current base; update the branch and rerun the updater.
Merge that actual current origin/main into the same branch, retain the full-ref Claude reader and all existing Codex behavior, resolve shared changelog/version conflicts, and rerun update/check using this PR's actual feature title/body. Against main 0.7.0, synchronize all four mirrors to 0.8.0. Update the version paragraph accordingly. No further product changes or broader tests are requested beyond changed-path checks and required CI.
Merge order is being coordinated with the #53 first officer: #74 is next before #66, so this base can settle. Keep the same PR/root; no force push or duplicate task.
timeleft--
left a comment
There was a problem hiding this comment.
Captain review of this exact head is clean against #68 and #55's mod skeleton/packaging acceptance. It includes current main f384c9c and retains the full-ref reader plus the Codex MCP/observation changes. The updater check passes against main 0.7.0 with all four mirrors at 0.8.0. The Codex manifest diff is version-only.
Current-head verification: 107 focused reader, plugin-packaging, public-boundary, Claude toolchain and CI-supply-chain tests pass. Mod hooks, types and toolchain source are byte-for-byte unchanged from the already-reviewed reload-binding repair, so its real Claude Code 2.1.296 validate receipt and 31 shipped tests plus two independent terminal/Desktop reload probes (33 passing) remain applicable. Minimum-version 2.1.293 checks were previously exercised with the real pinned CLI. The ended binding remains ended on reload until the Captain explicitly opens a fresh Bridge.
The integrated verify workflow installs an exact integrity-checked CLI and preserves existing Codex checks. Current-head required CI must finish green before merge; its Linux/macOS real mod tests are the release source authority. Installed Terminal/Desktop acceptance remains human-only #73 and is not claimed here.
Summary
Closes #68 (child of #55). Adds the Captain's Bridge mod skeleton to the existing Claude plugin, plus authoritative exact-version Claude Code CI.
hooks/hooks.json(modules:./register.tsx),hooks/register.tsxexportingregister, andtypes/index.d.ts(PluginState/BridgeState, matching feat: ship Captain’s Bridge as a Claude Code mod #55) named bytypesin.claude-plugin/plugin.json. Manifest description now mentions the Bridge;userConfighas the feat: ship Captain’s Bridge as a Claude Code mod #55 defaults./captains-bridgeis registered onsession.startwithimmediate: true.command.runcalls$.ui.open({ id: "captains-bridge", title: "Captain's Bridge" })and returns text. It starts no turn, sends no message, and arms no timer. It never auto-opens.$.session.id()is retained atsession.start, and the session id andtranscript_pathatclassic.SessionStart.clear,resume,forkandsession.endend the binding and set the exact "This conversation changed..." message. Nothing rebinds silently, and a reload for a different session id drops the binding.$.session.version(), named in the command text and the pane.CI / supply chain
src/hermes_helmet/claude_mod_toolchain.pymirrorsjj_toolchain: installs Claude Code 2.1.296 fromdownloads.claude.aiwith per-platform SHA-256 pins (equal to the signed release manifest and the npm platform binaries), atomic install, exact version check, and a credential-free temporaryHOME.verify.ymlinstalls and version-checks the CLI beforescripts/verify.sh.verify.shruns the realclaude plugin validate --jsonandclaude plugin test, and fails closed on unparseable output or anycalls:entry outside feat: ship Captain’s Bridge as a Claude Code mod #55's 14-call allowlist. In CI a missing CLI is a hard failure.modulespath confinement, one marketplace plugin at./, intact Codex packaging, docs, and the public boundary scan (hooks/,types/added to the scan roots).Verification
Local, with the real Claude Code 2.1.296 binary (digest-matched):
claude plugin validate: passed. Calls:$.command.register, $.session.id, $.session.version, $.state.get, $.state.set, $.ui.open, $.ui.resolve.claude plugin test: 25 pass, 0 fail (SessionStart, command, terminal and desktop drawn trees, non-drawing fallback, binding, clear/resume/fork, reload, too-old version).unittest discover: 610 tests; the only failures are environmental in this worker (4test_fava_trailsand 2 venv/pip bootstraps in the container). The new and extended tests,test_public_boundaryandtest_ci_supply_chainpass, as do the four Bridge.cjschecks.Version synchronization
Per the Captain's updated #55/#68 scope,
scripts/mw-version.py update(against current origin/main 0.7.0, with this PR title and body) moved 0.7.0 -> 0.8.0 inpyproject.toml,src/hermes_helmet/__init__.py,.claude-plugin/plugin.jsonand.codex-plugin/plugin.json(version field only). Version policy check passes. CHANGELOG records 0.8.0.Not touched: #53, #56-#61, Codex feature work, MCP packaging, the existing skills, version-policy configuration.