Skip to content

fix(gjc-runtime): make psmux authority host-independent and fence continuation dispatch - #3607

Merged
Yeachan-Heo merged 12 commits into
Yeachan-Heo:devfrom
twoimo:feat/windows-psmux-authority-v5
Jul 30, 2026
Merged

fix(gjc-runtime): make psmux authority host-independent and fence continuation dispatch#3607
Yeachan-Heo merged 12 commits into
Yeachan-Heo:devfrom
twoimo:feat/windows-psmux-authority-v5

Conversation

@twoimo

@twoimo twoimo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Hello, and thank you for the precise review on #3604. You identified exactly one blocker, and this successor repairs it in the way you asked.

What #3604 established

Your review confirmed the team-runtime shard passed on #3604's exact head, so both P1 defects from #3595 are genuinely repaired:

  1. release claim dispatched no continuation argv. The reservation is written under the task lock, that lock is released, and only then does dispatch revalidate eligibility. A concurrent claim-releasing operation lands in that window, revalidation sees no current claim, and the incident is journalled skipped with nothing dispatched. This is the fence-hold restructure the earlier PR body deferred. Revalidation plus send-keys now runs inside withGjcTeamMutationFence, the same fence every public authority-changing operation takes, and pruneTeamWorkerGcRecord now takes it too. The fence is released before the ACK wait, because the ACK is published by a separate receiver process that must acquire the same cross-process fence — holding it across the wait would deadlock the very ACK being awaited. The existing test asserting continuation waits outside the mutation fence still passes.

  2. Replacement settled before pane-launch ACK. The cause was in the test's own fake tmux. The rewritten fake dropped the 3-field tmux-last-split marker its shell predecessor wrote on every split. The replacement test waits on that marker before publishing the generation-bound startup ACK, so the ACK never arrived, relaunch hit its startup deadline, and the guard reported retrying. The marker is restored. The test also aborted its ACK waiter before its own non-linux early return, which made advisory-only hosts fail on a correct advisory result; the platform check now runs first.

The single repair in this successor

src/gjc-runtime/team-runtime.ts:4534readonly (string | undefined)[] passed to a readonly string[] seam, because worker.pane_id stays optional after runtime eligibility validation.

Repaired as you specified: the pane id is captured and narrowed to a proven non-empty local inside the fenced revalidation result, before argv is built. Both send operations use that proven string, so they provably address the identical pane, and the frozen argv is readonly string[]. A missing pane id is an eligibility gap rather than a dispatch error, so it returns the same typed skipped outcome the other ineligible paths return. The four ! assertions are gone rather than moved. The fence release before the ACK wait is unchanged.

Verification on this exact head

  • tsc -p packages/coding-agent/tsconfig.json --noEmit — clean (exit 0). This is the check that was red on fix(gjc-runtime): fence continuation dispatch and repair the memory-guard split marker #3604.
  • bun test packages/coding-agent/test/gjc-runtime/team-runtime.test.ts117 pass / 0 fail, 879 assertions. The full shard is green, including the case that was previously slow on my host.
  • Rebased onto current dev dd26a0787 so exact-head CI runs against the current tip.

Scope

No dependency on the reverted #3489: acquireManagedLockSync and ManagedStorageLockSync appear nowhere in this branch. persistGjcTmuxProviderAuthoritySync is defined by this branch itself. Nothing here touches session storage or the managed lock record, so it stays clear of #3596's lane.

I have not merged this, and I have not modified or rerun anything outside my own fork branch. Thank you again for the specific, reproducible guidance — the pointer to the fence-hold restructure and the exact tsc line both made this straightforward to fix.

twoimo and others added 12 commits July 31, 2026 04:15
…-independent

Restacks the Windows psmux authority work onto current dev, dropping the
storage lineage dev already absorbed via squash, and repairs every
darwin-only failure in the slice.

Five separate platform sources decided psmux behavior independently; four
ignored the authority test seam entirely, so Windows-authority paths were
unreachable on POSIX and eleven tmux-sessions tests failed there:
- psmuxAuthorityEnvironments gated persisted-authority discovery on raw
  process.platform, aborting before any later guard could run.
- resolveGjcTmuxProviderContext and createGjcTmuxSession each recomputed
  the platform instead of consulting the seam.
- teamProviderAuthority read process.platform directly; GjcTeamConfig now
  carries the platform so startGjcTeam's value reaches it.

Continuation dispatch had two real defects: the ack-loop deadline used
raw Date.now() while every other timestamp in the file routes through the
seamed clock, and the reservation site threw where the revalidation site
records a skipped outcome, so one worker's short lease aborted an entire
monitor pass.

tmux-sessions: 35/35 on darwin (was 24/35). team-runtime: 115/117, with
zero psmux-only failures - both remaining names also fail at dev, and
this slice fixes three that dev fails.
psmux rewrote the darwin lifecycle spawn/cleanup path (completeNonLinuxLifecycleSpawn,
cleanupDirectLifecycleAttempt), which regressed POSIX: dev is 60 pass / 0 fail on
notifications-lifecycle-control-runtime, psmux was 51 / 9. psmux is a Windows-only
provider and POSIX uses tmux, so the darwin path must stay dev's.

Reverting the file to dev keeps every psmux suite green (tmux-sessions 35/0,
psmux-detect 39/0, launch-tmux 137/0, tmux-gc 9/0) and preserves the win32 lifecycle
content, which dev already carries from the earlier merged psmux-authority slices.
…g continuation revalidation"

This reverts commit ebc3ca196801cd6b50b726c51d22ed3ba704e9ce.
…ng continuation revalidation"

This reverts commit 56f68822097d04d335126c7542f19e9dd720748e.
… the managed sync lock

The Windows psmux authority publish previously acquired `acquireManagedLockSync`
from managed-session storage. Dev removed that symbol when it reverted Yeachan-Heo#3489, so
the import broke on merge and the whole slice failed at module load.

Reviewers asked for the sync lock to return only alongside a real consumer and a
shared async/sync release contract, which belongs to the resident storage branch
rather than here. So this slice now enforces the property it actually needs on its
own: a retained lock descriptor for the exact authority name blocks publication
unless its owner process is definitely gone. Expiry alone is not permission,
because a paused writer with an expired lease is still live and stealing the name
would let two writers publish one generation-scoped authority.

`publishManagedFileNoReplaceSync` already supplies create-without-clobber
exclusion for the payload itself, so no lease helper is required.
…arker

Repairs the two blockers the reviewer identified on the previous head.

1. A public authority-changing operation dispatched no continuation argv.
   The continuation reservation is written under the task lock, that lock is
   released, and only then does dispatch revalidate eligibility. A concurrent
   claim-releasing operation could land in that window, so revalidation observed
   no current claim and the incident was journalled skipped with nothing
   dispatched. Revalidation plus send-keys now runs inside the same team
   mutation fence every other public authority-changing operation takes, and the
   fence is released before the ACK wait because the ACK is published by a
   separate receiver process that must acquire the same cross-process fence.
   Worker GC prune now takes that fence too, since it deletes claim records.

2. Replacement settled before pane-launch ACK. The fake tmux rewrite dropped the
   three-field tmux-last-split marker its shell predecessor published on every
   split. The memory-guard replacement test waits on that marker before
   publishing the generation-bound startup ACK, so the ACK never arrived,
   relaunch hit its startup deadline, and the guard reported retrying. The
   marker is restored. The same test also aborted its marker waiter before its
   own advisory-host early return, which masked the advisory outcome on
   non-Linux hosts; the ordering is fixed.
The fence-hold restructure moved the send-keys argv construction into a
closure, which dropped the outer non-null narrowing of `worker.pane_id`.
Assert it the same way the adjacent `executeTeamTmuxMutation` calls already
do, so the frozen argv stays `readonly string[]`.

@Yeachan-Heo Yeachan-Heo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE / MERGE_READY — terminal hostile review of exact head 41d882204c41b2e2fe1c9daf35ceeff159ae2eee.

P0: 0. P1: 0.

This successor is a bounded 13-addition/5-deletion repair over closed #3604. It captures worker.pane_id only after fenced eligibility revalidation, returns the existing typed worker_pane_missing skipped outcome if absent, binds one proven string to both send operations and both tmux mutation calls, and preserves fence release before the cross-process ACK wait. The predecessor review already established that continuation revalidation + dispatch are fenced, GC prune shares the fence, receiver ACK re-enters through task mutation, memory-guard split-marker causality is restored, and there is no dependency on the reverted synchronous managed lock.

Exact-head CI run 30576724409 is terminal green: 31/31 checks completed success/skipped, including check:@gajae-code/coding-agent, ts-build, the complete team-runtime.test.ts shard, launch/tmux/psmux/GC tests, evidence producer, and aggregate. No workflow was rerun or cancelled.

I also compared this 24-file psmux surface with active sole-owner #3596 exact head 6ed344d85b38d2609e54e77d37791c69ebb2ce5d: exact file overlap is empty. Current dev's independently owned ultragoal shard-5 red is unrelated and is not attributed to or absorbed by this PR. The branch is mergeable/clean and does not obscure #3596's Windows session-storage authority.

MERGE_READY.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo
Yeachan-Heo merged commit 9547ca6 into Yeachan-Heo:dev Jul 30, 2026
31 checks passed
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