fix(broker): fail fast when a persona worker exits before harness-ready; repair installed persona skill paths#223
Conversation
…team spawn → implement Adds the complete software factory pipeline so issues marked `ready-for-agent` flow automatically through scoping, team spawning, and implementation: - writeRemoteFile IPC: renderer/agents can now create/update Linear issues - ready-for-agent 4th band in Attention Inbox (expanded by default) - spawnTeamForIssue: spawns codex-impl + claude-review pairs with task prompts - issue-scoping module: detectRepo, suggestTeamSize, labelIssueWithRepo - board-steward persona: proactive agent that watches and drives the pipeline Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…line # Conflicts: # src/renderer/src/components/issues/AttentionInbox.tsx
Install @agentworkforce/persona-linear-dispatcher and @agentworkforce/persona-repo-router, and append both to the personas:refresh npm script so all personas stay current via one command. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
board-steward overlaps with the linear-dispatcher + repo-router pair — both poll ready-for-agent Linear issues and spawn impl/review teams, so running them together double-dispatches. Keep linear-dispatcher (board watcher) + repo-router (per-issue routing) as the single dispatch path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…dy; repair installed persona skill paths A workforce CLI that dies during setup (e.g. a failed skill install calls process.exit) previously burned the entire 120s PERSONA_HARNESS_READY_TIMEOUT_MS before surfacing an error. The harness-ready wait now rejects as soon as the worker is gone: it watches agent_exit/agent_exited/agent_released events and runs a 2s listAgents liveness poll as a catch-all for exits that slip past the event stream (e.g. between spawn and subscription). Also repairs the installed linear-dispatcher and repo-router personas, which carried raw `./skills/*.md` sources from an installer version without skill-asset support. The cp for those paths resolved against the project root, failed, aborted every spawn, and kept the workforce skill cache marker from being written — forcing a full prpm re-download on each attempt. Skill files now live under __assets/<id>/skills/ with sources rewritten to the convention the fixed installer emits (AgentWorkforce/workforce#226). Do not re-run personas:refresh until a CLI with that fix is published and the agentworkforce dep is bumped — npx prefers the local 3.0.52 binary, which would regenerate the broken JSONs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 59 minutes and 22 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (23)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces the linear-dispatcher and repo-router personas, adds support for writing remote files through Relayfile, and implements a "Ready for Agent" band in the Attention Inbox UI to allow manual spawning of agent teams. It also adds a liveness poll to the broker to fail fast if a persona process exits during setup. Feedback on these changes suggests replacing the setInterval liveness poll with a recursive setTimeout pattern to avoid overlapping executions, expanding the repository keyword map to include core repos like cloud and agents, and improving error reporting in the UI when spawning an agent team fails.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| livenessTimer = setInterval(() => { | ||
| void session.client | ||
| .listAgents() | ||
| .then((agents) => { | ||
| if (settled) return | ||
| if (!agents.some((agent) => agent.name === name)) { | ||
| finish(exitedError()) | ||
| } | ||
| }) | ||
| .catch(() => { | ||
| // Transient broker errors are fine — the readiness timeout still | ||
| // bounds the wait. | ||
| }) | ||
| }, PERSONA_LIVENESS_POLL_MS) |
There was a problem hiding this comment.
Using setInterval with asynchronous operations can lead to overlapping executions if a call takes longer than the interval duration. It is highly recommended to use a recursive setTimeout pattern instead to ensure that a new poll is only scheduled after the previous one has completed. Additionally, please update the type of livenessTimer to ReturnType<typeof setTimeout> and clear it using clearTimeout.
const pollLiveness = (): void => {
if (settled) return
void session.client
.listAgents()
.then((agents) => {
if (settled) return
if (!agents.some((agent) => agent.name === name)) {
finish(exitedError())
} else {
livenessTimer = setTimeout(pollLiveness, PERSONA_LIVENESS_POLL_MS)
}
})
.catch(() => {
if (!settled) {
livenessTimer = setTimeout(pollLiveness, PERSONA_LIVENESS_POLL_MS)
}
})
}
livenessTimer = setTimeout(pollLiveness, PERSONA_LIVENESS_POLL_MS)| const REPO_KEYWORDS: Record<string, string[]> = { | ||
| relay: ['relay', 'agent-relay', 'broker', 'mcp', 'workspace', 'webhook', 'mount', 'relayfile'], | ||
| pear: ['pear', 'electron', 'renderer', 'terminal', 'ui', 'inbox', 'sidebar', 'dialog', 'ipc'], | ||
| workforce: ['workforce', 'persona', 'autonomous', 'proactive', 'agent-workforce', 'skill'], | ||
| } |
There was a problem hiding this comment.
The REPO_KEYWORDS map is missing several core repositories of the organization, such as cloud and agents. Adding keywords for these core repos will significantly improve the accuracy of the repository detection logic.
| const REPO_KEYWORDS: Record<string, string[]> = { | |
| relay: ['relay', 'agent-relay', 'broker', 'mcp', 'workspace', 'webhook', 'mount', 'relayfile'], | |
| pear: ['pear', 'electron', 'renderer', 'terminal', 'ui', 'inbox', 'sidebar', 'dialog', 'ipc'], | |
| workforce: ['workforce', 'persona', 'autonomous', 'proactive', 'agent-workforce', 'skill'], | |
| } | |
| const REPO_KEYWORDS: Record<string, string[]> = { | |
| relay: ['relay', 'agent-relay', 'broker', 'mcp', 'workspace', 'webhook', 'mount', 'relayfile'], | |
| pear: ['pear', 'electron', 'renderer', 'terminal', 'ui', 'inbox', 'sidebar', 'dialog', 'ipc'], | |
| workforce: ['workforce', 'persona', 'autonomous', 'proactive', 'agent-workforce', 'skill'], | |
| cloud: ['cloud', 'worker', 'api', 'nango', 'd1', 'kv', 'durable'], | |
| agents: ['agents', 'reviewer', 'harness', 'bot'] | |
| } |
| } catch { | ||
| setNavNotice('Failed to spawn team') | ||
| } |
There was a problem hiding this comment.
Displaying a generic error message like 'Failed to spawn team' makes debugging difficult when spawning fails due to specific issues (e.g., missing project root, broker startup failure). Catching the error and displaying its actual message provides much better feedback to the user.
| } catch { | |
| setNavNotice('Failed to spawn team') | |
| } | |
| } catch (error) { | |
| setNavNotice(error instanceof Error ? error.message : 'Failed to spawn team') | |
| } |
|
ℹ️ pr-reviewer: review only — no file changes were applied to the PR (nothing to commit after review). The notes below are advisory and were not pushed. Reviewed PR #223 against Addressed comments
VerificationPassed:
Note: one earlier parallel run caused lint to be killed and Vitest to time out under load; both passed when rerun normally. |
|
Implemented two fixes:
Addressed comments
Advisory NotesNone. Local verification passed:
I installed the missing Playwright Chromium browser locally before rerunning the Playwright gates. |
|
Reviewed PR #223 and made one small verified fix: cleaned up the new persona liveness timer in src/main/broker.ts so it satisfies lint without changing behavior, and added regression coverage for Addressed comments
Advisory Notes
Validation run:
I’m not printing |
|
Implemented one review fix: the persona harness liveness timer in src/main/broker.ts now uses a cleanup-safe timer holder, removing the new lint warning without risking cleanup before assignment. Addressed comments
Advisory Notes
Local validation run:
|
|
Implemented scoped fixes from review and one validated self-review issue:
Addressed comments
Advisory Notes
Local verification passed:
|
Problem
Spawning
linear-dispatcher(andrepo-router) failed with:Two independent bugs compounded:
linear-dispatcher.json/repo-router.jsoncarry raw./skills/*.mdskill sources from anagentworkforceinstaller version without skill-asset support (the local 3.0.52 —npxprefers it over the registry, so today'spersonas:refreshused it). The workforce CLI resolves those against the project root, thecpfails, the&&-chained skill install aborts the spawn, and the workforce skill-cache marker is never written — so every retry re-downloads all prpm skills from scratch.PERSONA_HARNESS_READY_TIMEOUT_MSexpired, turning an instant failure into a 2-minute mystery timeout.Fix
Broker (
src/main/broker.ts):waitForPersonaHarnessReadyOutputnow rejects as soon as the persona's worker is gone:agent_exit/agent_exited/agent_releasedevents for the agent, andlistAgentsliveness poll as a catch-all for exits that slip past the event stream (e.g. between spawn and subscription).The error includes the captured output tail, so failures like the
cpabove surface in ~2 seconds with the actual cause.Installed personas: copied the skill files into
__assets/<id>/skills/and rewrote the JSON sources to the convention the fixed installer emits (same shapeterminal-renderer.jsonalready uses). The 3.0.52 runtime resolves these viarepoRoot; verified the exact generated install command now succeeds end-to-end.personas:refreshuntil a workforce CLI with the installer fix (AgentWorkforce/workforce#226 is the runtime half; the installer skill-asset support is already in workforce main, unpublished) is released and theagentworkforcedep here is bumped —npxwill keep preferring the local 3.0.52, which regenerates the broken JSONs with--overwrite.Testing
npm run typecheck:nodeclean.npm test: 120/120 pass.agentworkforce show linear-dispatcher --jsonresolves the rewritten sources and the generated skill-installcpsucceeds against the repaired paths.🤖 Generated with Claude Code