Skip to content

fix(bin): sync fork with upstream main - #5002

Closed
Ivory2024 wants to merge 14 commits into
kunchenguid:mainfrom
Ivory2024:fm/firstmate-origin-upstream-sync-20260919
Closed

Ivory2024 wants to merge 14 commits into
kunchenguid:mainfrom
Ivory2024:fm/firstmate-origin-upstream-sync-20260919

Conversation

@Ivory2024

Copy link
Copy Markdown

Intent

Firstmate's own primary checkout tracks origin (upstream kunchenguid/firstmate) as main's configured upstream. As of 2026-09-19, local main (which equals the captain's fork Ivory2024/firstmate after tonight's PR #1-5) is 3 commits behind origin/main: 2bcb88c (ci: standardize workflow timeouts into three tiers, #4910), 65a3bac (feat: park main under the away posture on Pi, #4889), 4812db8 (fix(bin): preserve Claude lock ownership after helper recycling, #4894). Catch the fork up on these 3 upstream commits. A prior attempt at this by branching from origin/main directly pulled in 39 files and hit a real merge conflict against the fork's own recent history (the specialist-tools/firstmate-layout/task-steering skill recovery and the crewmate-termination reap fix landed tonight) - that attempt was abandoned (closed PR #6) rather than force-resolved blind. Do this properly: understand what each of the 3 upstream commits actually changes, find and resolve the real conflicts against fork/main's own recent commits, and land a clean sync.

What Changed

  • Merges the three upstream main commits covering CI timeout tiers, Pi away posture, and Claude lock ownership preservation.
  • Restores the firstmate-layout, specialist-tools, and task-steering skills, adds .backpassrc.json, and consolidates project guidance in AGENTS.md without generating new CLAUDE.md pointers.
  • Hardens active-home x-mode policy and inactive reconciliation, including terminal endpoint/process cleanup, with corresponding documentation and shell-test updates.

Risk Assessment

✅ Low: The changed sync and fix-round code is bounded, preserves the required fork-specific behavior, and no source-verifiable defects remain.

Testing

Repository tests, fixtures, and live checks were recorded in the prior payload. The CI workflow and Pi supervision checks did not establish live product results. No linters or formatters were run directly.

  • Live validation: ⚠️ inconclusive - 5 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Fork main contains the clean upstream sync merge and all three upstream commits ✅ pass live sync-live-validation.txt
CI workflows use the required finite three-tier timeout contract ⏸️ untested no The prior payload only recorded an executable repository contract test, not a live GitHub Actions run.
Pi away-posture supervision routes eligible wakes correctly and keeps watcher failures on main ⏸️ untested no The prior payload only recorded isolated Pi fixtures and explicitly stated that no live Pi TUI session was started.
Claude session lock ownership survives helper recycling and non-owner turns fail safely ✅ pass live bash tests/fm-session-lock-ancestry.test.sh; python3 tests/fm-turnend-foreign-owner-repro.py
Inactive terminal reconciliation reaps the validated endpoint and preserves durable outcome delivery ✅ pass live bash tests/fm-inactive-reconcile.test.sh
Active-home x-mode approval, AGENTS migration, and workflow configuration remain safe after conflict resolution ✅ pass live bash tests/fm-arm-pretool-check.test.sh; bash tests/fm-ensure-agents-md.test.sh; bash tests/fm-lint-workflows.test.sh
Changed-test mapping and related upstream handoff/merge behaviors execute without unmapped configuration failures ✅ pass live bash tests/fm-test-run.test.sh; bash tests/fm-remote-backlog-handoff.test.sh; bash tests/fm-pr-merge.test.sh; bash tests/fm-send-resolve-key.test.sh
Evidence: Sync ancestry and conflict evidence

Source: Sync ancestry and conflict evidence

target=c4c99e94a2f8a626d150cae7d25f3f0554c5cb71; sync_merge_in_target=yes; all three upstream commits are ancestors; target_diff_check=clean; conflict_markers=none.

Firstmate upstream-sync live validation
target=c4c99e94a2f8a626d150cae7d25f3f0554c5cb71
sync_merge=961e5f94113c4feeb028c25490260cf5133289c7
sync_parents=03bf275987a3715b5b50f8cfe94c2ab573e0bbdc 2bcb88c38921030033a37d67ae4f5d82cea90eb4
upstream_commit_ancestor=2bcb88c38921030033a37d67ae4f5d82cea90eb4 yes
upstream_commit_ancestor=65a3bac6 yes
upstream_commit_ancestor=4812db80 yes
sync_merge_in_target=yes
target_diff_check=clean
conflict_markers=none
worktree_status=
- Outcome: ⚠️ 2 warnings across 1 run (21m53s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

⏭️ **Rebase** - skipped

Step was skipped.

🔧 **Review** - 3 issues found → auto-fixed (3) ✅
  • 🚨 AGENTS.md:64 - The intent requires resolving the real merge conflicts and landing a clean sync, but AGENTS.md:64 retains >>>>>>> origin/main and lines 60-63 contain an orphaned layout fragment. Remove the marker and reconstruct the intended layout block before landing.
  • 🚨 bin/fm-inactive-reconcile.sh:483 - For an Orca-backed terminal child, reap_terminal_child_locked reads window at line 483 and passes it to fm_backend_kill at line 496. Orca metadata stores window=fm-$ID while the real terminal handle is stored separately in terminal (bin/fm-spawn.sh:4236-4237,4293), and fm_backend_orca_kill expects that terminal handle (bin/backends/orca.sh:295). A done/failed Orca child therefore reaches this path without closing its terminal. Select the backend-specific terminal identity before closing, with the existing endpoint validation boundary.
  • ⚠️ bin/fm-arm-command-policy.mjs:862 - The change expands the blessed watcher setup to allow <root>/config/x-mode.env at bin/fm-arm-command-policy.mjs:862, even when root and active home differ. fm-arm-pretool-check.sh:170-176 passes them separately, while the documented invariant says absolute x-mode paths outside the active home are not approved. A command sourcing the code-root config can now arm supervision under the wrong home. Remove the root alternative unless this broader authorization is deliberate and its contract is updated.

🔧 Fix applied.
6 issues (3 errors, 3 warnings) still open:

  • 🚨 bin/fm-inactive-reconcile.sh:483 - For an Orca-backed terminal child, reap_terminal_child_locked reads window at line 483 and passes it to fm_backend_kill at line 496. Orca metadata stores window=fm-$ID while the real terminal handle is stored separately in terminal (bin/fm-spawn.sh:4236-4237,4293), and fm_backend_orca_kill expects that terminal handle (bin/backends/orca.sh:295). A done/failed Orca child therefore reaches this path without closing its terminal. Select the backend-specific terminal identity before closing, with the existing endpoint validation boundary.
  • ⚠️ bin/fm-arm-command-policy.mjs:862 - The change expands the blessed watcher setup to allow <root>/config/x-mode.env at bin/fm-arm-command-policy.mjs:862, even when root and active home differ. fm-arm-pretool-check.sh:170-176 passes them separately, while the documented invariant says absolute x-mode paths outside the active home are not approved. A command sourcing the code-root config can now arm supervision under the wrong home. Remove the root alternative unless this broader authorization is deliberate and its contract is updated.
  • 🚨 bin/fm-inactive-reconcile.sh:490 - The prior reaping fix changed Orca selection to terminal, but reap_terminal_child_locked still kills tmux PIDs at this line before calling any endpoint validator. A stale or mismatched window can resolve to an unrelated pane, causing SIGTERM or endpoint closure for another task. The same unvalidated helper is reached from the sibling reconciliation paths at bin/fm-inactive-reconcile.sh:546, :556, and :563. Validate the metadata/task identity at the shared helper boundary before any runtime command, then use the validated target.
  • ⚠️ bin/fm-inactive-reconcile.sh:536 - pr_for_task expects its second argument to be the preferred status line, but this call passes the status-file path. For a completed child whose metadata has no pr= field and whose status contains done: PR https://..., the fallback regex receives the path, returns empty, and the reported outcome loses the PR URL without an error. The sibling call at bin/fm-inactive-reconcile.sh:408 passes the actual last line correctly; pass $last here as well.
  • ⚠️ .backpassrc.json:4 - The change deletes the root CLAUDE.md, while .backpassrc.json still declares it as a required memory file. The repository's own fm-ensure-agents-md.sh documents AGENTS.md as the current knowledge file and does not recreate the deleted root pointer. A Backpass run using this committed configuration therefore consumes a nonexistent file or can reintroduce the removed compatibility artifact. Remove CLAUDE.md from memoryFiles.
  • 🚨 bin/fm-test-run.sh:1649 - The new tracked .backpassrc.json is not classified by bin/fm-test-run.sh's changed-path mapping. Its default branch emits __unmapped__, and select_changed then aborts with no changed-test mapping for source path, so changed-test selection cannot process this change. Treat this repository configuration as a non-executable/config path in the existing mapping.

🔧 Fix applied.
1 warning still open:

  • ⚠️ bin/fm-arm-command-policy.mjs:862 - The change expands the blessed watcher setup to allow <root>/config/x-mode.env at bin/fm-arm-command-policy.mjs:862, even when root and active home differ. fm-arm-pretool-check.sh:170-176 passes them separately, while the documented invariant says absolute x-mode paths outside the active home are not approved. A command sourcing the code-root config can now arm supervision under the wrong home. Remove the root alternative unless this broader authorization is deliberate and its contract is updated.

🔧 Fix applied.
✅ Re-checked - no issues remain.

⚠️ **Test** - 2 warnings
  • ⚠️ tests/fm-pi-watch-extension.test.sh:1 - Pi watcher tests failed once under parallel resource contention, then passed when rerun alone. No reproducible product failure observed.
  • ⚠️ live validation verdict: inconclusive (5 of 7 scenarios were driven live against the product); untested: CI workflows use the required finite three-tier timeout contract, Pi away-posture supervision routes eligible wakes correctly and keeps watcher failures on main
  • Live validation: ⚠️ inconclusive - 5 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Fork main contains the clean upstream sync merge and all three upstream commits ✅ pass live sync-live-validation.txt
CI workflows use the required finite three-tier timeout contract ⏸️ untested no The prior payload only recorded an executable repository contract test, not a live GitHub Actions run.
Pi away-posture supervision routes eligible wakes correctly and keeps watcher failures on main ⏸️ untested no The prior payload only recorded isolated Pi fixtures and explicitly stated that no live Pi TUI session was started.
Claude session lock ownership survives helper recycling and non-owner turns fail safely ✅ pass live bash tests/fm-session-lock-ancestry.test.sh; python3 tests/fm-turnend-foreign-owner-repro.py
Inactive terminal reconciliation reaps the validated endpoint and preserves durable outcome delivery ✅ pass live bash tests/fm-inactive-reconcile.test.sh
Active-home x-mode approval, AGENTS migration, and workflow configuration remain safe after conflict resolution ✅ pass live bash tests/fm-arm-pretool-check.test.sh; bash tests/fm-ensure-agents-md.test.sh; bash tests/fm-lint-workflows.test.sh
Changed-test mapping and related upstream handoff/merge behaviors execute without unmapped configuration failures ✅ pass live bash tests/fm-test-run.test.sh; bash tests/fm-remote-backlog-handoff.test.sh; bash tests/fm-pr-merge.test.sh; bash tests/fm-send-resolve-key.test.sh
  • bash tests/fm-ci-workflow.test.sh
  • bash tests/fm-branch-supervision.test.sh
  • bash tests/fm-pi-branch-extension.test.sh
  • bash tests/fm-pi-watch-extension.test.sh
  • bash tests/fm-pr-merge.test.sh
  • bash tests/fm-send-resolve-key.test.sh
  • bash tests/fm-session-lock-ancestry.test.sh
  • python3 tests/fm-turnend-foreign-owner-repro.py
  • bash tests/fm-arm-pretool-check.test.sh
  • bash tests/fm-ensure-agents-md.test.sh
  • bash tests/fm-inactive-reconcile.test.sh
  • bash tests/fm-lint-workflows.test.sh
  • bash tests/fm-remote-backlog-handoff.test.sh
  • bash tests/fm-test-run.test.sh
  • git ancestry, diff-check, conflict-marker, and clean-worktree checks
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

irene and others added 14 commits September 19, 2026 08:04
…ate-20260919

feat: gate fresh CLAUDE.md pointer creation on Claude Code version >= 2.1.277
…tage 2) (#2)

* feat(bin): complete stage 2 CLAUDE.md pointer removal

* no-mistakes(review): Restore column-0 heredoc regression fixture with generic content

* no-mistakes(review): Remove stale CLAUDE.md pointer claim from updatefirstmate skill

---------

Co-authored-by: irene <irene@ireneui-MacBookPro.local>
Prior commits on this branch regressed past stage2, restoring the
unconditional CLAUDE.md pointer-write logic stage2 removed. Reset to
fork/main (stage2's merged head) and redo stage3 correctly: delete the
now-dead fm_version_at_least/claude_supports_native_agents_md functions
and their header-comment reference, and drop the now-vestigial
with_mock_claude/with_no_claude test helpers (the script no longer
reads claude --version at all).

Co-authored-by: irene <irene@ireneui-MacBookPro.local>
…eering skills (#4)

* feat: add lazy specialist tool routing

Expose ECC, paperthin, and ultrawork as captain-approved specialist paths while keeping Firstmate intake and lifecycle authority. Load only the selected skill or mode and keep ECC hooks, MCP, and legacy sync opt-in.

* docs(agents): recover firstmate-layout and task-steering skills

These two skills existed only on an orphaned local branch, never pushed.
firstmate-layout is re-extracted from AGENTS.md section 2's current
(much larger) layout tree rather than reusing the stale 2026-09-14
snapshot. task-steering's underlying AGENTS.md paragraph was byte-identical
to the 2026-09-14 extraction, so it is reused as-is. Both get a one-line
trigger in section 13 and a documentation-audiences.json entry, matching
how specialist-tools (recovered earlier on this branch) is registered.

---------

Co-authored-by: irene <irene@ireneui-MacBookPro.local>
Co-authored-by: irene <irene@ireneui-MacBookPro.local>
@Ivory2024

Copy link
Copy Markdown
Author

Opened by mistake against the wrong repo (this fork's automation defaulted to the upstream remote instead of Ivory2024/firstmate). The actual PR is Ivory2024#9. Closing, no action needed here.

@Ivory2024 Ivory2024 closed this Sep 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant