Skip to content

fix(claude): a teammate that approved its shutdown is no longer counted as running - #744

Closed
Haeminway1 wants to merge 1 commit into
devswha:mainfrom
Haeminway1:fix/claude-teammate-shutdown-count
Closed

Haeminway1 wants to merge 1 commit into
devswha:mainfrom
Haeminway1:fix/claude-teammate-shutdown-count

Conversation

@Haeminway1

Copy link
Copy Markdown
Contributor

Change

A Claude pane whose session used an agent team kept every teammate counted as running after it shut down. A live pane showed background_tasks: 12 with no subagent alive. The twelfth was a real background shell, which Claude Code's own footer also showed (1 shell still running).

A teammate ends by answering its lead's shutdown_request. It calls SendMessage({type: "shutdown_response", approve: true, request_id: "shutdown-…"}), and Claude Code's tool result says Shutdown approved. … is now exiting. Nothing is written after that. turnAfter counted only an end_turn answer as the end of a turn. The shutdown request that arrives after the teammate's last end_turn reset that, so every teammate that shut down read as running forever. All 11 teammates in the reported session ended this way.

The answer approving a shutdown now ends the agent's turn. It is matched as a toolUseResult with success: true, a request_id starting with shutdown-, and a message starting with Shutdown approved. A rejected request still counts as running. A later message to the agent still resumes it.

Validation

  • server/claude-subagents.test.ts covers an approved shutdown after end_turn (completed, ended at the answer), a rejected request (running), and a message after the approval (running again). Result: 73 pass.
  • claudeSubagents on the reported session's real files: 12 running before the fix (11 teammates and the shell), 1 running after (the shell).
  • typecheck and server/claude-session.contract.test.ts pass. test:unit passes except voice transcribe > streams deltas…, which fails the same way on main.

🤖 Generated with Claude Code

…ed as running

An agent-team teammate ends by answering its lead's shutdown_request with
SendMessage(shutdown_response, approve: true); Claude Code's tool result
says "Shutdown approved … is now exiting" and nothing follows. turnAfter
took only an end_turn answer as the end, and the shutdown request after
it reset that, so every shut-down teammate read as running forever: a
live pane showed 12 background tasks with 1 background shell and no
subagent alive. That approved answer now ends the agent's turn; any later
message still resumes it.

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

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: devswha/herdr-web-ui/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 050dae9e-4aad-41d7-980e-39e3beafa319

📥 Commits

Reviewing files that changed from the base of the PR and between 21d1b92 and 0a08dec.


📒 Files selected for processing (3)
  • CHANGELOG.md
  • server/claude-subagents.test.ts
  • server/claude-subagents.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.



📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Claude pane running counts and the agent list now mark teammates as completed after they approve a shutdown request, rather than continuing to count them as running.
    • Teammates remain running if they reject the shutdown request or send a later message.

Walkthrough

Claude teammate lifecycle detection now recognizes successful shutdown approvals as turn endings. Later user messages clear that turn-end state. Tests cover approved and rejected shutdowns and subsequent messages.

Changes

Claude teammate shutdown lifecycle

Layer / File(s) Summary
Detect approved teammate shutdowns
server/claude-subagents.ts, server/claude-subagents.test.ts, CHANGELOG.md
A successful shutdown tool result marks the teammate completed at the result timestamp. Rejected shutdowns leave it running, and a later user message returns it to running status. The changelog describes the updated count and agent list behavior.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: devswha, kilhyeonjun


Merge Risk | ⚪ Minimal · up to 0a08d

Merge Risk: ⚪ Minimal · up to 0a08d

Approved shutdowns are intended to mark teammates completed until a later user message resumes them. No actionable merge-blocking issue was established in the reviewed scope.

Security Architecture Review

Security architecture risk: ⚪ Minimal · up to 0a08d

The fix changes reported completion and notification timing, not process execution or permissions. Rejected shutdowns remain running, and later messages resume the teammate. No material security risk was identified in the changed behavior.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — A misleading matching transcript result could influence the affected session’s displayed completion, running counts and alert timing. The traced consumers do not turn that result into additional execution authority or resource cleanup.

Trust Boundaries and Controls

  • observed — The classifier consumes a top-level toolUseResult object in a user transcript record, not merely shutdown-like text in message content. The pane endpoint continues resolving the existing pane session before requesting its task list.

Resilience and Maintainability Implications

  • observed — The existing reader uses complete-line parsing and file-signature checks for unsettled reads and cache certification. Inspected tests cover torn records and replay behavior; no dedicated simultaneous-writer test establishes stronger concurrency guarantees.

Pre-merge checks | Passed 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: teammates that approve shutdown requests are no longer counted as running.
Description check Passed The description includes the required Change and Validation sections. It explains the problem, resulting behavior, test coverage, real-session validation, and known unrelated test failure.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. (1 skipped: 1 …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@devswha

devswha commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Thank you for this fix, @Haeminway1! It has been carried into #764 (#764) together with other Claude parsing fixes in the same area, because it conflicted with main after the 0.4.6 release. Your commit is cherry-picked with you as its author, and the changelog entry links this PR and credits you. I'm leaving this PR open so the maintainer can close it when #764 lands.

devswha added a commit that referenced this pull request Oct 11, 2026
…swer Hermes, end shut-down teammates (#764)

## Change

Fixes four things reported against 0.4.6, all in the prompt reader and
the Claude background-task reader.

- **Claude multiple choice with ticked rows (#752).** Claude Code
2.1.296 draws a ticked row as `[✔]`; the reader only took `[✓]`, so once
a row was ticked the card became a single choice, its labels kept the
box, and a pick sent Enter on a multi-select row, which unticks it.
`[✔]` is now a tick. With the cursor on the unnumbered **Submit** row
the card no longer disappears: the moves count Submit as a row between
"Type something" and "Chat about this", so ↑/↓ + Enter + → still land
where they should.
- **`/model` guard (#542).** `claudeModelListWaits()` read the hint over
six lines joined with spaces, so a hint cut inside a word (`ses` /
`sion`) or wrapped over seven lines was missed and pending delivery
could type Enter into the list. The hint is now read with spaces taken
out over up to sixteen lines, and the run of lines that holds it must
begin with it, so the same words quoted in Claude's output (`⏺ Example:
Enter to set as default …`) no longer hold pending sends.
`parseClaudeModel` and `promptTailIsActive` read the hint the same way,
so the card and the guard agree.
- **Agent-team teammates that shut down (carried from #744 by
@Haeminway1).** A teammate that approved its lead's shutdown request is
read as completed at that answer, so the pane's running count stops
counting it. Cherry-picked with its author kept.
- **Hermes clarify questions (carried from #750 by @DarkoKuzmanovic).**
Hermes's clarify dialog gets an answer card: arrows + Enter for a
choice, Space ticks + Enter for a multiple choice, typed text for
"Other" and open questions. No digits are sent, per server/AGENTS.md.
Cherry-picked with its author kept, plus one review fix (53ae368): text
already on the dialog's `>` line (typed in the terminal, or a typed
answer Tab brought back) used to join the chat's answer, so the line is
emptied first with ctrl+k / ctrl+u, which Hermes's TextInput takes on
every platform (`ui-tui/src/lib/platform.ts`). An unused `currentPrompt`
export is dropped.

Fixes #752
Fixes #542
Carries #744 and #750

Not changed: #542's gap 4 (a line under the hint that is not Claude's
footer). The issue says no real layout is known to draw one, so it is
left for a maintainer decision.

## Verification

- Before the fix (53ae368), the six new tests failed as the issues
describe: the three `Claude's multiple choice ticked in the terminal`
tests (no card, single choice, Submit move missing) and the three
`Claude Code's model list under a hint wrapped anywhere` tests (split
word, seven lines, quoted hint). They pass after 999099b.
- `HERDR_TEST_MODE=unit bun test ./server/prompt.test.ts
./server/hermes-prompt.test.ts ./server/claude-subagents.test.ts`: 311
pass, 0 fail.
- `bun run typecheck`: passes.
- `CHECK_MAX_RUNS=8 bun run check full` on ba61fd4 (after merging
origin/main 5792d71): workflow syntax, generated types, typecheck,
build, unit tests and the integration and browser lanes all `ok` (252
browser PASS, 0 FAIL).

Origin/main was merged in, not rebased (5792d71, #755); the only
conflict was CHANGELOG.md.

---------

Co-authored-by: Haeminway1 <130830910+Haeminway1@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Darko Kuzmanovic <darko.kuzmanovic@gmail.com>
@devswha

devswha commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Thank you, @Haeminway1! Your change landed on main through #764, with you kept as the commit author and credited in the changelog. Closing this one as superseded by #764.

@devswha devswha closed this Oct 11, 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.

2 participants