Skip to content

feat(specialist): add immediate specialist handoff - #607

Merged
ewen-poch merged 1 commit into
aipoch:mainfrom
wen2zhou:feat/specialist-handoff
Aug 2, 2026
Merged

feat(specialist): add immediate specialist handoff#607
ewen-poch merged 1 commit into
aipoch:mainfrom
wen2zhou:feat/specialist-handoff

Conversation

@wen2zhou

@wen2zhou wen2zhou commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Problem

  • Switching specialists mid-turn only hands off the current turn at the next turn boundary, so the new specialist loses the in-flight context.
  • Specialist switch/delete approval cards show raw redacted JSON, which is hard for users to read and reason about.
  • Specialist updates (including renames) travel a privileged approval path, and a renamed specialist keeps its old display name in the Settings list.

Proposed change

  • Immediate handoff: switching specialists hands the in-flight turn to the switched specialist right away. The switch approval is bound to the exact outer repl_execute completion via a per-control invocation identity, so an approved continuation can re-enter the control queue safely without deadlock.
  • Approval cards: switch cards now show the resolved specialist identity, capability scope, and current → target direction instead of redacted JSON (with a stale-warning fallback when the target was renamed/removed/disabled mid-request); delete cards get a friendly detail block with a destructive primary action and a fail-closed binding warning. A new deeplink opens the specialist's Settings editor from the card.
  • Approval rework: specialist updates (including renames) are now ordinary chat-reviewed mutations; only delete and switch keep approval cards. The revision guard and atomic single-profile commit are preserved, and renames sync displayName into the Settings specialist list.
  • Scope: handoff skills are scoped to the switched specialist; empty handoff snapshots are stabilized.
  • Build: exclude .codex agent worktrees from vitest discovery and ESLint scanning (same duplicate-source rationale as .claude/.worktree).

Scope and non-goals

  • Provider-specific cancel/reconfigure/continuation behavior is out of scope: this change owns the provider-neutral completion boundary (NotebookControlCompletionInterceptor), while concrete framework adapters (Codex, OpenCode) build on it.
  • No database schema changes.

Acceptance criteria and validation

Behavior Project-owned check Result
Immediate handoff lifecycle (pending intent → completion capture → continuation) src/main/agents/handoff-lifecycle*.test.ts, src/main/agents/completion-handoff*.test.ts, src/main/agents/handoff-lifecycle.integration.test.ts passed
Control completion binding & re-entry src/main/acp/codex-completion-handoff.integration.test.ts, src/main/agents/completion-gate.execute-control.integration.test.ts passed
Switch approval card details & stale fallback src/renderer/src/pages/workspace/PermissionApprovalControls.specialist-switch.render.test.tsx passed
Delete card & fail-closed warning src/renderer/src/pages/workspace/PermissionApprovalControls.specialist-delete.render.test.tsx passed
Rename sync & update-as-ordinary-mutation src/renderer/src/stores/settings-store.test.ts, src/main/agents/agents-mutations.test.ts passed
Empty handoff snapshot stabilization src/renderer/src/pages/workspace/WorkspaceMessageScroller.render.test.tsx passed
Session-aggregate merge (runtime-service + NotebookSession* types) src/main/notebook/runtime-service.export.test.ts, session lifecycle tests passed

All listed checks ran after the last material edit (conflict resolution + prettier formatting + eslint ignore config).

  • npm run typecheck — passed
  • npm run lint — passed (0 errors; 22 pre-existing prettier warnings in untouched files)
  • npm test (full suite) — 667 files / 9707 tests passed, 0 failed

Review focus

  • Conflict resolution with the upstream session-aggregate refactor (refactor(notebook): extract session aggregate landed on main after this branch was cut): controlInvocationId and beginControlInvocation were migrated onto the NotebookSessionExecutionRequest / NotebookSessionMcpRpcConnection types in session-aggregate.ts, and executeControl now uses session.enqueueControl while keeping the interceptor semantics. Verify the two merge points in src/main/notebook/runtime-service.ts (executeControl and the session.execute call in executeControlExclusive).
  • The interceptor may start an approved continuation that re-enters executeControl; the control-queue tail must settle before the handoff completes.

@github-actions github-actions Bot added the enhancement New feature or request label Aug 2, 2026
@wen2zhou
wen2zhou marked this pull request as draft August 2, 2026 06:06
When the user switches specialists mid-turn, hand the current turn to the
switched specialist right away instead of waiting for the next turn. The
switch approval is bound to the exact outer repl_execute completion via a
per-control invocation identity, so an approved continuation can re-enter
the control queue safely.

- handoff: immediate switch hands off the in-flight turn; handoff skills are
  scoped to the switched specialist; empty handoff snapshots are stabilized.
- permissions: specialist switch approval cards show resolved identity,
  capability scope, and current -> target direction (with a stale-warning
  fallback) instead of raw redacted JSON; deletes get a friendly detail
  block with a destructive primary action and fail-closed binding warning.
- agents: specialist updates (including renames) are ordinary chat-reviewed
  mutations; only delete and switch keep approval cards. The revision guard
  and atomic single-profile commit are preserved, and renames now sync
  displayName into the Settings specialist list.
- workspace: durable host.agents.switch pending intent is broadcast to the
  renderer so the handoff lifecycle projection stays in sync.
- build: exclude .codex agent worktrees from vitest discovery.
@wen2zhou
wen2zhou force-pushed the feat/specialist-handoff branch from 1ce5328 to 859ecab Compare August 2, 2026 06:12
@wen2zhou
wen2zhou marked this pull request as ready for review August 2, 2026 06:21
@ewen-poch
ewen-poch merged commit 3f4094a into aipoch:main Aug 2, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants