Skip to content

fix: sync fork with upstream calm export visibility and secondmate handoff fixes - #9

Merged
adibirzu merged 4 commits into
mainfrom
fm/fm-sync-fork-upstream
Aug 16, 2026
Merged

adibirzu merged 4 commits into
mainfrom
fm/fm-sync-fork-upstream

Conversation

@adibirzu

Copy link
Copy Markdown
Owner

Intent

Sync fork main with upstream: merge upstream/main's 3 commits (ef35d79 fix(calm): keep Pi's export confirmation visible kunchenguid#2461; 196fb65 docs(skills): remote-secondmate recovery hint kunchenguid#2456; 7a3259e fix: keep the public promise reachable when work is routed to a secondmate kunchenguid#2457) into fork main safely, preserving both sides fully - the fork's ~137 commits of work AND upstream's 3 fixes, with no feature, function, flag, backend arm, or test dropped from either parent. The deliverable is deliberately a single merge commit of upstream/main into a branch off origin/main - a merge, not a rebase or squash, so both histories stay intact. Drop-guard already verified before this run: the merge delta vs origin/main is content-identical to upstream's own delta since the merge-base, and symmetrically vs upstream/main; no files deleted vs either parent; the spawn/backend/relaunch code restored in PR #8 (fm-runtime-handoff.sh, fm-spawn.sh, fm-dispatch-select.mjs, fm-fleet.sh, fm-backend.sh, fm-spawn-acct.sh, fm-account-exec.sh) is byte-unchanged from fork main. The PR targets fork main (adibirzu/firstmate) and must not be merged by the pipeline - the captain merges. Known pre-existing local test flakes not caused by this merge: fm-calm-pi-extension loaded_off case (upstream-origin, predates the merge-base) and fm-inactive-reconcile (environmental); CI is the final gate. Context: the 2026-08-14 upstream-sync merge 2d39b28 silently stripped spawn/backend features and caused a two-week CI blackout repaired by PR #8 - this sync deliberately preserves both sides in full.

What Changed

Risk Assessment

✅ Low: A clean two-parent sync merge whose deltas are verified content-identical to each parent's own delta since the merge-base, with zero deletions, byte-unchanged PR #8 spawn/backend files, orthogonal resolutions in the four dual-touched files, and all dependencies of upstream's new code intact in the merged tree.

Testing

Independently re-verified every drop-guard claim on merge 2244566 (two-parent topology, bidirectional content-identical delta symmetry vs both parents, zero deletions, all 7 PR #8 spawn/backend files blob-identical to fork main), then ran all four test suites upstream touched since the merge-base — including the real-Pi-in-tmux calm E2E that exercises the kunchenguid#2461 export-confirmation fix and the tasks-axi-backed handoff suite exercising the kunchenguid#2457 public-promise fix — all passing with a clean worktree afterward; the known fm-calm loaded_off flake did not manifest in either of two runs. No UI-screenshot artifact applies: the end-user surface here is git history and terminal test behavior, captured as transcripts.

Evidence: Drop-guard verification (merge topology, delta symmetry, no deletions, PR #8 files byte-identical)

Source: Drop-guard verification (merge topology, delta symmetry, no deletions, PR #8 files byte-identical)

=== Upstream-sync merge drop-guard verification ===
Merge commit: 2244566 (fm/fm-sync-fork-upstream)

--- Merge topology (true merge, two parents) ---
tree 31d842923a03523257ade7059cec56ac0db31304
parent 70796575942b3e11609d384937a2e85784695563
parent ef35d799a846d676c2fd30b1d1e3ed47b0fb2c22
author Adrian Birzu <adibirzu@gmail.com> 1786880293 +0300
committer Adrian Birzu <adibirzu@gmail.com> 1786880293 +0300


merge-base(origin/main-side 7079657, upstream/main ef35d79) = f1a4af426d7199c1781bc91ccd143b8e1f732d10

--- Upstream's 3 commits being merged ---
ef35d79 fix(calm): keep Pi's export confirmation visible (#2461)
196fb65 docs(skills): add remote-secondmate recovery hint for false-negative verdicts (#2456)
7a3259e fix: keep the public promise reachable when work is routed to a second mate (#2457)

--- CHECK 1: diff(fork parent 7079657 -> merge) vs diff(merge-base -> upstream ef35d79) ---
PASS: content-identical (only blob hashes / hunk offsets differ) — merge adds exactly upstream's changes, nothing more, nothing less

--- CHECK 2 (symmetric): diff(upstream parent ef35d79 -> merge) vs diff(merge-base -> fork 7079657) ---
PASS: content-identical — merge preserves exactly the fork's ~137 commits of work relative to upstream

--- CHECK 3: no files deleted vs either parent ---
deleted vs fork parent   (7079657): 0
deleted vs upstream parent (ef35d79): 0

--- CHECK 4: PR #8 spawn/backend/relaunch files byte-identical to fork main parent ---
UNCHANGED (blob a3ac7e9b345389ace14761e63998617b75534b3d): bin/fm-runtime-handoff.sh
UNCHANGED (blob 7edffe4fc8d94c5b50dabb44e2cede14f07b25fd): bin/fm-spawn.sh
UNCHANGED (blob 4929700d630e7e2da06f6075ea6d60fd86cc9303): bin/fm-dispatch-select.mjs
UNCHANGED (blob 452d3cf26ee838ad84d5b002626a91bf4266bd8a): bin/fm-fleet.sh
UNCHANGED (blob 1b75ce1e43cfa805aae6cc866072b225f2e8a478): bin/fm-backend.sh
UNCHANGED (blob 299e2b8e07ca750a873c74cf6e6d25d90241cae1): bin/fm-spawn-acct.sh
UNCHANGED (blob 81170da28e2bb7221556de9629a8e58313a8d165): bin/fm-account-exec.sh
Evidence: Calm Pi extension E2E transcript — real Pi in tmux passing the kunchenguid#2461 export-confirmation regression assertions

Source: Calm Pi extension E2E transcript — real Pi in tmux passing the #2461 export-confirmation regression assertions

=== tests/fm-calm-pi-extension.test.sh (covers ef35d79: keep Pi's export confirmation visible) ===
The interactive terminal E2E runs a REAL Pi session inside tmux; the new export-settled
assertions (added by upstream ef35d79) verify Calm's post-export repaint does not overwrite
'Session exported to: <file>' in the live transcript.

skip: installed @earendil-works/pi-coding-agent package not found
ok - Pi calm compatibility evidence never rejects a Pi version for being newer than 0.82.0, and still fails closed on a missing or malformed version
skip: installed @earendil-works/pi-coding-agent package not found
ok - missing Pi presentation class exports reach the independent adapter degradation path
skip: installed @earendil-works/pi-coding-agent package not found
skip: installed @earendil-works/pi-coding-agent package not found
skip: installed @earendil-works/pi-coding-agent package not found
skip: installed @earendil-works/pi-coding-agent package not found
ok - Pi operational follow-up E2E processes exact user-role notifications once while Calm hides current and adjacent rows, Calm off and absent render them, and restart preserves semantics
ok - Pi Calm native /skill:ahoy geometry keeps every collapsed thinking and tool block at zero height while preserving expansion, history, restart, and Calm-off rendering
skip: installed @earendil-works/pi-coding-agent package not found
ok - Pi calm native E2E replaces the stock working row with a moving, resize-clamped working ship that freezes and resumes across two working periods in one Pi session, clears on abort, keeps captain turns visible, hides exact operational user rows without changing persistence, restores stock rendering Calm-off, survives restart, and preserves export plus Ctrl+O behavior
exit=0
Evidence: Targeted test transcripts for upstream fixes (fm-backlog-handoff incl. kunchenguid#2457 public-promise assertions, fm-procevent, fm-x-mode)

Source: Targeted test transcripts for upstream fixes (fm-backlog-handoff incl. #2457 public-promise assertions, fm-procevent, fm-x-mode)

=== Targeted tests for upstream's 3 merged fixes (all tests upstream touched since merge-base) ===

### tests/fm-backlog-handoff.test.sh (covers 7a3259e: keep the public promise reachable when work is routed to a secondmate)
ok - body followed by another item moves intact with no source orphans
ok - body followed by section heading moves intact; section stays
ok - multi-paragraph body with internal blank lines moves whole and is idempotent
ok - body as last lines of the file moves intact
ok - EOF body before a seeded destination section keeps its boundary
ok - untouched EOF line preserves its original terminator
ok - body-carrying handoff is idempotent: re-run changes nothing
ok - noncanonical one-space and tab continuations refuse without changes
ok - indented ## Intent / ## Acceptance are body, not section boundaries
ok - registry home parses when summary has parentheses before (home: ...)
ok - registry entry without (home: ...) fails cleanly with has no home
ok - handoff reports a moved item whose public commitment still binds this home
ok - handoff says nothing about public commitments in a relay-free home
ALL TESTS PASSED
exit=0

### tests/fm-procevent.test.sh
ok - claim replacement cannot produce a torn ownership snapshot
ok - retirement and start share one serialized lifecycle boundary
ok - PID reuse cannot signal an unrelated process
ok - transient identity failure preserves the live source for retry
ok - bounded home sweep preflights then retires every locally owned source
ok - home sweep leaves foreign-home claims and runners untouched
ok - home sweep refuses safely until runner identity is readable
ok - healthy runtime behavior remains registration-only
ok - registration rejects unrepresentable newline arguments
ok - nonzero exit with no output stays armed and silent
ok - oversized output is bounded rather than published whole or dropped
ok - live output stays bounded and retirement reaps the whole source group
ok - invalid output bounds fail closed
ok - the adapter derives physical identity without newline path corruption
ok - source-only homes trigger the general supervision guard
ok - the adapter classifies published poll output safely
ok - the adapter owns which Lavish results end a source, and payload text cannot forge one
ok - the published interfaces state the loss limitation and claim no lossless delivery

all procevent tests passed
exit=0

### tests/fm-x-mode.test.sh (covers 196fb65 area: remote-secondmate skills/x-link)
ok - fm-x-followup tombstones the link when a post-success counter write fails
ok - fm-x-followup treats a relay cap/window rejection as an already-exhausted link, not a retry
ok - fm-x-followup skips silently and clears the link past the 7-day window
ok - fm-x-followup is a no-op for a task with no X link
ok - fm-x-followup dry-run records the follow-up and increments the counter, keeping the link
ok - fm-x-followup dry-run --final clears the link just as a live post would
ok - fm-x-followup rejects malformed invocations
ok - bootstrap activates X mode from an .env token, idempotently
ok - bootstrap ignores CDPATH when writing absolute FM_HOME into the durable X-mode poll shim
ok - bootstrap reports missing X-mode dependencies before arming
ok - bootstrap does not report X mode on when activation artifacts cannot be written
ok - bootstrap rejects linked X artifacts without touching their targets
ok - bootstrap is inert without a non-empty .env token (non-X users unaffected)
ok - bootstrap cleans up X artifacts on opt-out and is silent once off
ok - bootstrap reports failed X artifact cleanup on opt-out
exit=0

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • git cat-file -p 2244566 — confirmed true merge commit with exactly two parents: 7079657 (fork main base) and ef35d79 (upstream/main tip)
  • Drop-guard CHECK 1: normalized git diff 7079657 2244566 vs git diff f1a4af4 ef35d79 — content-identical (only blob hashes/hunk offsets differ), so the merge adds exactly upstream's 3 fixes and nothing else
  • Drop-guard CHECK 2 (symmetric): normalized git diff ef35d79 2244566 vs git diff f1a4af4 7079657 — content-identical, so the merge preserves exactly the fork's work relative to upstream
  • Drop-guard CHECK 3: git diff --diff-filter=D vs both parents — 0 deleted files against either side
  • Drop-guard CHECK 4: blob-hash comparison of bin/fm-runtime-handoff.sh, fm-spawn.sh, fm-dispatch-select.mjs, fm-fleet.sh, fm-backend.sh, fm-spawn-acct.sh, fm-account-exec.sh — all byte-identical to fork main parent 7079657
  • bash tests/fm-backlog-handoff.test.sh — 13/13 ok against the real tasks-axi binary, including the two new #2457 public-commitment assertions
  • bash tests/fm-calm-pi-extension.test.sh (ran twice) — exit 0 both runs; interactive terminal E2E ran a real Pi session in tmux and passed the new #2461 export-settled assertions; known loaded_off flake did not manifest
  • bash tests/fm-procevent.test.sh — all ok, exit 0
  • bash tests/fm-x-mode.test.sh — all ok, exit 0
  • Post-test cleanliness: git status --porcelain empty, no leftover tmux servers or /tmp residue
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

kunchenguid and others added 4 commits August 15, 2026 22:10
…d mate (kunchenguid#2457)

The lightweight Relay follow-up link lives in the answering home's own
state/<task-id>.meta, so it can only bind work that home owns. When a
Relay-linked request is routed to a second mate, the task record lives in the
second mate's home, fm-x-link.sh failed with a bare "no such task ...meta", and
nothing else picked the promise up: only the soft acknowledgement was ever
posted. The typed promised-final path already supports --work-home
secondmate:<id>; the playbook simply never chose it.

- fmx-respond now states the routing rule crisply: a task in this home takes the
  lightweight link, and second-mate-routed work takes a promised-final
  commitment bound to that home, registered up front with the brief command
  carried into the routed worker's instructions.
- fm-x-link.sh refuses a task with no local record by naming the registered
  second mate whose home actually holds it and printing the promised-final
  registration command, with the exact --work-home when the match is
  unambiguous. A home with no registered second mates keeps the plain error.
- fm-backlog-handoff.sh reports, after a successful move, any moved key that
  still owes a public reply bound to main/<key>, since that binding no longer
  names the home owning the work. The move itself is never blocked.

Docs and the secondmate handoff prose follow the same rule. Tests cover the
refusal, its scoping, the unchanged local-link path, and both handoff outcomes
at the script boundary.
…verdicts (kunchenguid#2456)

* fix(skills): hint that remote secondmate liveness verdicts false-negative

fm-crew-state and fm-send routinely misreport a live remote secondmate
as dead; confirm against the pane before relaunching, and relaunch only
through fm-spawn.sh, never raw herdr pane surgery.

* no-mistakes: apply CI fixes
Pi 0.83.0 added a status line to every tool-expansion change, and Pi
updates the previous status line in place when two status messages
arrive back to back. Calm's post-export redraw cycled tool expansion on
the macrotask right after Pi printed "Session exported to: <path>", so
both expansion status lines coalesced over that confirmation and the
captain was left with no record of where their export landed.

Calm now repaints only the tool rows it presents, by invalidating each
row through the render context Pi hands its render slots, and requests
the surrounding redraw through setStatus. Neither appends to the
transcript. The repaint is still needed because Pi can re-render a row
asynchronously - the built-in edit row invalidates itself once its diff
is ready - and that re-render can land inside the window where /export
forces stock rendering.

The real-terminal /export case now asserts the confirmation is still on
screen after the redraw has settled, and that the redraw restored every
Calm-hidden row, instead of only racing the moment the confirmation
first appeared.
@adibirzu
adibirzu merged commit b82ae80 into main Aug 16, 2026
13 checks passed
@adibirzu
adibirzu deleted the fm/fm-sync-fork-upstream branch August 23, 2026 09:53
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.

2 participants