Skip to content

cmux NEXT: keep ambiguous child starts in shell rows - #26627

Merged
teamleaderleo merged 25 commits into
feat-cmux-nextfrom
nx-shell-card-identity-1028
Oct 30, 2026
Merged

teamleaderleo merged 25 commits into
feat-cmux-nextfrom
nx-shell-card-identity-1028

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Bash commands that invoke Codex or Claude keep their command and output rows. A child-session record may create an agent card only when its shell start is unambiguous; concurrent starts cannot borrow another child's identity, model or reply.

Repair for #26368's independent review BLOCK at b54463253a1a48eb707dd691b7c9206653115cfe. This branch starts from feat-cmux-next at 83c919d5176a669a6a1ab84cab7414727eb623a3 and ports only the original PR's three own commits, then adds the regression and repair. The original branch and its merge history remain preserved.

Leo, 2026-10-27: "we don't want to have that sort of thing going on"

Takes back #25043: command syntax and stdout must not establish harness or session identity. Explicit child-session metadata still supplies the harness, model, effort, session id and reply for an unambiguous tracked start.

The daemon lowercases and splits requested names before claiming base, base-2, base-3; the fold mirrors that normalization before comparing rename families. The current child records carry no reliable originating call id. Overlapping parent shell starts therefore stay plain when their names or prompts overlap, even if a competing call later ends; distinct explicit names remain deterministic. An active start_session disqualifies only overlapping shell candidates. Once that MCP call completes, its identity tombstone still rejects a same-name or same-prompt queued child that arrives late, while a genuinely distinct parent remains cardable. An explicit -n fix can no longer consume a fix-2 record through prompt fallback. Discarded calls cannot become candidates again through repeated updates.

Validation: cd webviews && bun test src/agent-session/acpmux/subagents/agentRunFold.test.ts test/shell-agent-identity.test.ts reproduced 3 normalization failures against prior head 58e6064ee8bc7caa87f895ab2dc06f67283d6a6d and passes 33 tests at the final head 89e21311eb06a3d5b182a8647c9428bf6b151dd1. The broader focused fold, parser, MCP and transcript replay suite passes 68 tests. scripts/web-lint.sh and python3 scripts/cmux-next/prepush-gate.py pass.

Observed / Not run

Observed concurrent same-name shell/MCP starts in both start orders and all three MCP input shapes, two background parent runs in both child orders, two background runs plus start_session, a queued MCP first prompt, a native subagent's competing MCP start, and repeated updates after competing calls fail. Existing tests retain exact recorded metadata and ordinary shell command/output rows.

python3 scripts/verify-local.py previously passed all selected checks except localization parity, which reports 45,327 errors in catalogs and localization inputs unchanged from base 83c919d5176a669a6a1ab84cab7414727eb623a3. No native build, app dogfood, live review-router call or new browser capture ran for this attribution repair.

Preserved visual evidence from #26368: hosted Chromium capture 40590006683 covered running/completed light/dark gallery states at original regression c65b829f88eddf7f98df737258404a58b102de36 and original fixed head 4d7bb4943641e44792ba5f0460369c6de1144345. Those captures document the original shell-row change; the concurrency repair is verified by the new protocol regressions above.

Reference: cmux-design-references/apps/claude/live/transcript-tool-rows-and-task-list.png and apps/codex/live/transcript-expanded-command-activity.png for shell rows; apps/claude/live/transcript-linked-session-card.png for a tracked session card.

Gallery: agent-pane.shell-agent-identity/running, agent-pane.shell-agent-identity/completed

Size: This repair PR carries the original shell-row implementation and preserved gallery captures so the exact-head repair can be reviewed from current feat-cmux-next in one self-contained change.

Changelog

Fixed: Bash commands keep their normal rows, and ambiguous concurrent starts cannot inherit another child session's identity.

State Before After
Running · dark Before After
Completed · dark Before After
Running · light Before After
Completed · light Before After

Agent session: agent session

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 341a2d7: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr26627 -f ref=nx-shell-card-identity-1028 -f platform=macos -f backend_mode=local

Passes: CI passes on 341a2d757c.

CI passes on 341a2d757c (run 41013628873 attempt 1).

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

red: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on 760ac10 to compare; do not merge until green; see lane-rules

Gallery before/after for 341a2d7: the capture produced no images (run).

@teamleaderleo

teamleaderleo commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 28, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Found 2 test failures on Blacksmith runners:

Failures

Test View Logs
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)/
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)
View Logs
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)/
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-569c1h created for this PR by the cmux coordinator.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Follow-up repair pushed at exact head a64b3fc54c02351480ff5cbbbf02b2e013df514d.

Fresh Astra review findings addressed:

  • Active start_session overlap is tracked by call identity instead of a process-lifetime latch. A completed MCP start no longer poisons a later genuinely distinct parent; a same-name or same-prompt queued child remains fail-closed via a bounded tombstone.
  • Concurrent parent starts are ambiguous only when their recorded name/prompt identities overlap. Distinct explicit names (alpha and beta) remain deterministic even with the same prompt.
  • Failed/timed-out pending parent calls leave identity tombstones. A late subsession.started record cannot prompt-match a later same-prompt parent.

Fresh regression discriminator was red against prior head 39a5b896b6d1a6d8365e516a61c5959b8a4423e1 (4 failures) and is green at this head. The focused fold, parser, MCP and transcript suite passes 62 tests; web lint and the prepush gate pass. No merge performed; root owns fresh exact-head review and landing.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Final follow-up head is 4257ad1235fd68403b1764f8b729ad5b4c66bc47 (remote branch nx-shell-card-identity-1028). The stale-child terminal guard now covers failed, stopped and timed-out parent updates explicitly; the regression uses background_task_update.state = "timed_out".

Exact-head verification after this final push: the focused fold/parser/MCP/transcript suite is 62 pass, 0 fail; scripts/web-lint.sh passes; python3 scripts/cmux-next/prepush-gate.py passes. Root owns the fresh independent review and merge; no merge was performed.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Final exact head is now c0b21ab3e109ae00d37960172c70ea3926b057db. The stale identity tombstones are deduplicated and retained for the fold lifetime rather than evicted, so a late child cannot regain a prompt match after many subsequent failed starts. Focused 62-test suite, web lint, prepush gate and clean-tree checks pass at this head. Root owns fresh independent review and merge; no merge performed.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Final exact head is d6f566faf231c7cc9f8a7926a48940457a263d95. Terminal MCP starts now also leave identity tombstones on failure/timeout, preserving fail-closed late-child handling for every terminal start path. Focused 62-test suite, web lint, prepush gate and clean-tree checks pass; root owns fresh review and merge, with no merge performed.

teamleaderleo and others added 2 commits October 29, 2026 17:14
…quested name

startChild compared the child's claimed short name with the call's raw -n text, so a lone
`acpmux run --parent chat-1 -n Alpha` never matched `alpha` and lost its card (review P2 at
89e2131). Match on the call's normalized identity instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Kept this branch's rule that command text never makes a session card (the codex exec tests stay
removed) and took base's child-record fields (startedBy, effort, lastMessage, turn-end refresh)
and their tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 30, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

teamleaderleo and others added 2 commits October 29, 2026 18:56
…the parent's child

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…for the parent's child

An update acpmux tags with a native subagent returns before reduceRun, so a subagent running the
same `acpmux run --parent chat-1 -n fix` was never a competing start: if its child claimed `fix`
first, the parent's shell call took that child's session, model and reply (review P2 at
6b3d2c3). The subagent's call now registers its identity as a competing start while it runs and
leaves a tombstone when it ends, as a nested start_session already does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, review-router, for drain-transcript): BLOCK at 6b3d2c3

  1. P2 — webviews/src/agent-session/acpmux/subagents/subagentFold.ts:352: Native subagent shell starts bypass the ambiguity guard. Owner-tagged shell updates return at line 272 before reaching reduceRun(). If the parent and a native subagent both execute acpmux run --parent chat-1 -n fix ..., the native subagent’s start never becomes a competing candidate. If its child claims fix first, startChild() associates that child with the parent’s shell call, displaying the wrong session, model and reply—the attribution bug this PR claims to prevent. Register nested shell starts as competitors before the owner return, as the change already does for nested MCP starts.

Static review only.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol high, review-router, for drain-transcript): BLOCK at 428f1b0

  1. tree/webviews/src/agent-session/acpmux/subagents/subagentFold.ts:463 — P2: Every child whose normalized name ends in -<digits> is rejected as “daemon renamed,” even when that suffix was explicitly requested and there is no competing session. A valid acpmux run --parent ... -n fix-2 therefore never gets an agent card, contradicting the claimed deterministic handling of distinct explicit names.

  2. tree/webviews/src/agent-session/acpmux/subagentFold.ts:465,1062-1065 — P2: An unnamed/unprompted parent (for example, a --prompt-file run) retires an empty identity. identitiesOverlap treats an identity with no name or prompt as overlapping every future identity, and the tombstone is retained indefinitely. After one such run, all later tracked child starts in that fold are rejected and remain ordinary shell rows.

Static review only.

teamleaderleo and others added 5 commits October 29, 2026 21:00
Regression for review finding 1 on #26627.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-a4efd6c1314eb5a4fc3e
Regression for review finding 2 on #26627.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-a4efd6c1314eb5a4fc3e
… base competes

Review finding 1 on #26627: every child named `base-N` was refused, so a lone
`acpmux run --parent ... -n fix-2` never got its card. The suffix is now treated
as a daemon rename only when a pending, running or retired start requested the
base name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-a4efd6c1314eb5a4fc3e
Review finding 2 on #26627: a `--prompt-file` run retired an empty identity,
which identitiesOverlap treats as overlapping everything, so every later
tracked child start in the fold stayed a plain shell row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-a4efd6c1314eb5a4fc3e
teamleaderleo and others added 2 commits October 29, 2026 23:21
A known background run ended only on completed, failed or stopped, so a
timed_out or cancelled background_task_update left its card running forever.
It now ends on every isTerminal state: timed out as failed, cancelled or
stopped as cancelled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-a4efd6c1314eb5a4fc3e
@teamleaderleo
teamleaderleo merged commit 567dcaf into feat-cmux-next Oct 30, 2026
158 of 161 checks passed
@teamleaderleo
teamleaderleo deleted the nx-shell-card-identity-1028 branch October 30, 2026 07:06
@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

@lawrencecchen

Copy link
Copy Markdown
Contributor

Base red after this PR: its What's New highlight had no tryIt action or docs link, so scripts/whats-new/test_digest.py (release-notary) failed. Fix: #28441.

austinywang added a commit that referenced this pull request Oct 30, 2026
…28458)

test_digest.py requires every highlight to have a tryIt action or docs link.
chief-name-in-agent-chats.md (#27935) and shell-agent-identity.md (#26627)
landed without one, turning workflow-guard-tests / release-notary red on
feat-cmux-next and on every PR that runs it.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
lawrencecchen added a commit that referenced this pull request Oct 31, 2026
…e red) (#28114)

chief-name-in-agent-chats.md (#27935) and shell-agent-identity.md (#26627) had no action,
deeplink or docs link, so scripts/whats-new/test_digest.py
(test_the_repository_highlights_validate) failed in nightly-guards / release-notary on every
feat-cmux-next PR. Both are agent-chat changes, so the action opens a new agent chat, the
same action the other agent-chat highlights use.

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 341a2d75 Deployed Oct 30, 2026 by teamleaderleo via cmux-tui tree preflight #81099
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants