Repository navigation
chore: restore upstream content for three captain-environment-only hunks - #82
Merged
Merged
Conversation
…the captain environment (R3)
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.
Intent
Second step of shrinking this fork's divergence from kunchenguid/firstmate (fork sync rethink report 2026-09-30, decision R3): three hunks that only existed because of the captain's own machine environment go home to that environment, and the fork reverts to upstream content for them.
Auto-compact: the captain's user-scope ~/.claude/settings.json now sets autoCompactEnabled true with autoCompactWindow 500000 (dotfiles d06c249), so bin/fm-spawn.sh no longer needs to write those two keys into each crew worktree's .claude/settings.local.json. The spawned file carries only the lifecycle hooks again, exactly as upstream writes it. The harness-adapters Claude reference and the stuck-crewmate-recovery skill lose the fork-only prose that explained the override; the stuck-crewmate line returns to upstream's "modern harnesses auto-compact and keep going". tests/fm-spawn-claude-attribution.test.sh drops the two auto-compact assertions and keeps pinning the hooks and the absence of the attribution object.
Calm widget key: the standalone Pi Calm in the captain's dotfiles now uses the firstmate-calm-working-ship widget slot (dotfiles d06c249), so .pi/extensions/lib/fm-calm-working-ship.ts returns to upstream's key and comment; dual-install sessions still render one boat. Upstream PR fix: share Pi Calm's working-ship widget slot kunchenguid/firstmate#1854 becomes unnecessary.
.sessions/: the captain retired the session export that wrote .sessions/ into repos (skills-sprint 017793b), so the fork's .gitignore line for it is dead and is removed.
Deliberate non-goals: no behavior replacement is added in the fork for any of the three; per-project auto-compact pins, if ever wanted, are a project-scope settings matter outside this repo. Local evidence: bin/fm-lint.sh --fast clean on bin/fm-spawn.sh and the attribution test; tests/fm-spawn-claude-attribution.test.sh passes.
What Changed
bin/fm-spawn.shno longer writesautoCompactEnabled/autoCompactWindowinto each crew worktree's.claude/settings.local.json; the spawned file now carries only the lifecycle hooks, andtests/fm-spawn-claude-attribution.test.shdrops the two auto-compact assertions while still pinning the hooks and the absence of the attribution object. The harness-adapters Claude reference and thestuck-crewmate-recoveryskill lose the fork-only prose explaining that override, with the stuck-crewmate line returning to upstream's "modern harnesses auto-compact and keep going"..pi/extensions/lib/fm-calm-working-ship.tsrevertsCALM_WORKING_SHIP_WIDGET_KEY(and its comment) to upstream'sfirstmate-calm-working-shipslot, andtests/fm-calm-pi-extension.test.shdrops the assertion pinning the sharedcalm-working-shipkey..gitignoredrops the now-dead.sessions/entry.Risk Assessment
✅ Low: Clean, well-bounded revert-to-upstream of three environment-specific hunks that removes code and assertions with no dangling references, valid generated JSON, and source files matching upstream 349e189 exactly as the intent requires.
Testing
Phase 1 ran the two changed test scripts serially (jobs 1, 300s/script). fm-spawn-claude-attribution passed: it drives fm-spawn.sh's claude branch and asserts the real generated .claude/settings.local.json via jq — hooks present for all four lifecycle events, no attribution object, and (per intent) no autoCompactEnabled/autoCompactWindow keys. fm-calm-pi-extension failed, but on an unrelated pre-existing assertion (Pi package createToolHtmlRenderer tool-HTML export under Pi 1.0.3 + node v25.8.1), which crashed the node eval before the working-ship test and is causally independent of the one-line widget-key edit. To prove scenario 2 I drove the working-ship geometry/lifecycle test in isolation against the real Pi package: the boat registers and renders under CALM_WORKING_SHIP_WIDGET_KEY (now firstmate-calm-working-ship) as exactly one boat, passing. No reviewer-visible screenshot was captured because the Calm boat surface is a terminal-TUI widget exercised headlessly through the Pi package's render API, not a browser/Electron surface; the render assertions in the passing working-ship test are the product-level evidence. The .gitignore line removal and the claude.md / stuck-crewmate-recovery prose removals have no live-exercisable runtime surface. Both driveable scenarios pass; the transient scoped test copy was removed and the worktree is clean.
tests/fm-spawn-claude-attribution.test.shdrives fm-spawn.sh and asserts the real generated JSON via jq (has hooks, has("attribution")|not, and the two autoCompact assertions removed per intent)Evidence: Phase 1 + scenario-2 isolation record
Source: Phase 1 + scenario-2 isolation record
Evidence: fm-spawn settings: hooks present, no attribution, no autoCompact
Evidence: Scenario 2: isolated working-ship boat renders under firstmate-calm-working-ship key
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed ✅
.pi/extensions/lib/fm-calm-working-ship.ts:47- Changing CALM_WORKING_SHIP_WIDGET_KEY to "firstmate-calm-working-ship" breaks an existing behavioral test that was not updated. tests/fm-calm-pi-extension.test.sh:3017 imports the real module and assertsCALM_WORKING_SHIP_WIDGET_KEY === "calm-working-ship", throwing a hard failure otherwise; the diff does not touch that test, so it will now fail. (The stale slot-sharing comment/message at tests/fm-calm-pi-extension.test.sh:2952-2960 and :3018 describe the old contract but only line 3017 is the failing assertion.) The remedy — aligning the expected key to "firstmate-calm-working-ship", matching the Claude mod's CALM_SHIP_RASTER_KEY and the intent — is a mechanical correction that completes the authoritative key change, not a behavior change.🔧 Fix applied.
✅ Re-checked - no issues remain.
tests/fm-calm-pi-extension.test.sh:1685- tests/fm-calm-pi-extension.test.sh fails on an unrelated pre-existing assertion: test_rendering_and_session_lifecycle's assertStockHtmlRendering reports "grep disappeared from /export calm.html HTML while calm mode was on" because the Pi package's createToolHtmlRenderer().renderCall returns falsy under the installed Pi 1.0.3 + node v25.8.1. This is the tool-HTML-export code path and is causally independent of this change's one-line widget-key edit ("calm-working-ship" -> "firstmate-calm-working-ship"). The crash aborts the suite before the working-ship test, so I drove that test in isolation (passed). Not introduced by this change; broad regression is owned by CI.tests/fm-spawn-claude-attribution.test.shdrives fm-spawn.sh and asserts the real generated JSON via jq (has hooks, has("attribution")|not, and the two autoCompact assertions removed per intent)bin/fm-test-run.sh --jobs 1 --per-script-timeout-secs 300 tests/fm-spawn-claude-attribution.test.sh(PASS)bin/fm-test-run.sh --jobs 1 --per-script-timeout-secs 300 tests/fm-calm-pi-extension.test.sh(FAILED on unrelated renderer assertion; crashed before working-ship test)Drovetest_working_ship_geometry_and_lifecyclein isolation via a scoped copy of the suite against the real Pi 1.0.3 package (PASS); copy removed, worktree cleandocs/adr/0001-fork-divergence-budget.md:11- ADR 0001 cites PR fix: share Pi Calm's working-ship widget slot kunchenguid/firstmate#1854 (the Calm widget) as live evidence of fork-PR drift, explicitly timestamped "all checked 2026-09-28." This change retires fix: share Pi Calm's working-ship widget slot kunchenguid/firstmate#1854 (user intent: it "becomes unnecessary"), so the example is now historically bounded. I deliberately did not edit it: an ADR is a point-in-time decision record, the citation is correctly dated/caveated, and the corollary it supports is unchanged, so the fact is not rendered false. Flagging as a judgment call rather than editing an immutable record.✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.