git:20260816.a0c2a2d to git:20260817.3e8a3c6

75 added, 38 removed. Audit A to A.

---
name: cvg-multi-session
description: Orchestrate real specialist sessions as one monitored multi-agent workflow. Use when the user asks to coordinate or supervise multiple agent sessions, planning or implementation loops, or worker/reviewer handoffs, on Codex threads or Claude Code background agents.
argument-hint: "[goal, plan path, worktree, or workflow description]"
---
# Multi-Session Workflow
Use this skill when the current session should act as an **orchestrator** over other real specialist sessions.
The workflow is repo-independent. Specialist prompts should carry only the
coordination data the specialist cannot infer from the selected role skill and
source artifact. Do not paste broad repo rules, likely-file lists, old phase
state, or role-skill procedures unless they are task-specific authority.
## Non-Negotiable Protocol Gates
Apply these gates before any planner, worker, reviewer, QA runner, or quality reviewer is launched.
### Gate 0: Transport Binding
Bind the specialist operations to the current platform before applying any other gate:
| Operation | Codex | Claude Code |
|---|---|---|
| Spawn specialist | skill-local App Server transport `start` | `Agent` tool with `run_in_background: true` |
- | Continue specialist | skill-local App Server transport `resume` | `SendMessage` to the agent id |
- | Verify identity | `read_thread` on the returned thread id | agent id in the `Agent` tool result |
- | Inspect output | `read_thread` | `TaskOutput` or the completion notification |
- | Wait | heartbeat automation | end the turn; the harness re-invokes the orchestrator on `<task-notification>` |
+ | Continue specialist | Desktop `send_message_to_thread` on the same thread id | `SendMessage` to the agent id |
+ | Verify identity | `read_thread` after bootstrap handoff | agent id in the `Agent` tool result |
+ | Inspect output | `wait_threads` and `read_thread` | `TaskOutput` or the completion notification |
+ | Wait | attached bootstrap session, then `wait_threads` | end the turn; the harness re-invokes the orchestrator on `<task-notification>` |
The authoritative specialist identity is always the id returned by the
platform transport — never an id the specialist writes in prose. Do not accept
placeholder specialist identity in callback templates.
On Codex, locate `scripts/codex-app-server-transport.mjs` beside the active
- skill. Loop skills ship an identical generated copy. Before each spawn or
- continue, write the exact specialist prompt to a file inside the current loop's
- scratch directory, including this line:
+ skill. Loop skills ship an identical generated copy. Before each spawn, write
+ the exact specialist prompt to a file inside the current loop's scratch
+ directory, including this line:
`Your verified thread id is <specialist-thread-id>.` The transport replaces that
placeholder with the id returned by App Server before starting the turn.
- Run the transport with `exec_command` from the specialist worktree and a short
- yield so the command returns its live execution session after the
+ Run the transport once with `exec_command` from the specialist worktree and a
+ short yield so the command returns its live execution session after the
`thread_started` event:
```text
node <transport-script> start --cwd <worktree> --prompt-file <prompt-file> --require-callback
- node <transport-script> resume --thread-id <specialist-thread-id> --cwd <worktree> --prompt-file <prompt-file> --require-callback
```
Add `--model <id>` or `--effort <level>` only when the user explicitly selected
an override. Never use `--ephemeral` for a real specialist.
The transport checks managed requirements, explicitly requests
- `approvalPolicy=never` plus `sandbox=danger-full-access` on thread start or
- resume, then repeats the effective policy as
+ `approvalPolicy=never` plus `sandbox=danger-full-access` on thread start, then
+ repeats the effective policy as
`sandboxPolicy.type=dangerFullAccess` on turn start. It verifies the effective
thread response before sending the prompt. If any check fails, stop with a
transport blocker. Do not fall back to `create_thread`: its current tool
contract cannot bind permissions and may silently downgrade a cross-project
- specialist. It also exposes `convergo_callback` as a dynamic tool and prints
- its payload as a `specialist_callback` event on the attached execution session.
+ specialist. On macOS it prefers the Codex binary bundled with ChatGPT Desktop
+ over a possibly stale `codex` on `PATH`; `CONVERGO_CODEX_BIN` remains the
+ explicit override.
+ The bootstrap transport exposes `convergo_callback`, prints its payload as a
+ `specialist_callback` event, calls `thread/unsubscribe`, closes its App Server,
+ and emits `thread_handoff_ready` only after the child process exits. Do not
+ continue the thread before that final event. Every later worker repair or
+ same-reviewer focused check must use Desktop `send_message_to_thread` on the
+ same thread id. Never launch a second App Server process or call this
+ transport with `resume`: a second writer can collide with Desktop ownership of
+ the persisted thread.
+
If the transport tools are not available after searching for them, report a
tool-layer blocker. Do not fall back to inline simulation of a specialist.
### Gate 1: Real Specialist Session
Specialists must run as real, individually addressable platform sessions:
Codex threads or Claude Code background agents.
- Spawn a new specialist with the spawn operation unless the user explicitly named an existing specialist session.
- Continue an existing specialist with the continue operation.
- - Verify every specialist id immediately after creation or selection with the Gate 0 verify operation.
+ - Verify every specialist id before its first continuation with the Gate 0 verify operation.
- Do not use local shell jobs, detached processes, or inline role-play in the orchestrator turn as substitutes for a real specialist session.
- Do not treat a process id, shell job id, or model-generated id as a specialist id.
- If the id returned by the spawn operation cannot be verified, stop the workflow and retry with the platform specialist tools or report a tool-layer blocker.
- If the platform specialist tools are not loaded, search for them first. If they still cannot be loaded, report a tool-layer blocker.
- (Codex) Search for `exec_command`, `write_stdin`, `read_thread`, and the
- heartbeat automation tool. The `thread_started` transport event contains the
- authoritative thread id. Verify it immediately with `read_thread`; the prompt
- already contains the same id because the transport replaces
- `<specialist-thread-id>` before turn start. The attached transport process is
- only a client for the real App Server thread; its process or execution-session
- id is never the specialist identity.
+ (Codex) Search for `exec_command`, `write_stdin`, `send_message_to_thread`,
+ `wait_threads`, `read_thread`, and the heartbeat automation tool. The `thread_started` transport event contains the authoritative thread id returned
+ by App Server; the prompt contains the same id because the transport replaces
+ `<specialist-thread-id>` before turn start. During the attached bootstrap turn,
+ a Desktop read can transiently report `notLoaded` or `interrupted`; do not use
+ that snapshot as the turn verdict. The transport's `turn_completed` result is
+ authoritative until `thread_handoff_ready`. After handoff, verify the task with
+ `read_thread` before the first Desktop continuation. The transport process and
+ execution-session id are never the specialist identity.
### Gate 2: Orchestrator Callback Transport
Every specialist prompt must include:
- the callback destination,
- exact callback template,
- instruction to include `Audit artifact: <absolute path>` when the specialist
creates or receives an audit artifact.
- - (Codex) fallback instruction if callback transport is unavailable.
- On Codex, the callback destination is the attached App Server transport. The
- specialist must call `convergo_callback` exactly once with the complete callback
- text. The transport prints a `specialist_callback` event to its execution
- session; a final answer left only in the specialist thread is not sufficient.
+ On Codex, callback transport depends on the operation:
+ - A newly spawned specialist calls `convergo_callback` exactly once. The
+ attached bootstrap transport prints a `specialist_callback` event.
+ - A continued specialist returns the exact callback text as its final answer.
+ Desktop `wait_threads` delivers it to the orchestrator. It must not call
+ `convergo_callback`; that dynamic tool belonged to the closed bootstrap App
+ Server and no longer has an attached handler.
+
If the specialist creates or receives an audit artifact, the callback must include `Audit artifact: <absolute path>`.
The specialist must use the verified id supplied by the orchestrator in its
callback body.
- (Codex) If `convergo_callback` is unavailable inside the specialist thread, the specialist must say `callback transport failed` in its final answer and include the exact callback text for manual relay. The required-callback transport exits nonzero so the orchestrator treats this as a blocker.
+ (Codex) During bootstrap, if `convergo_callback` is unavailable, the specialist must say `callback transport failed` in its final answer and include the exact callback text for manual relay. The required-callback transport exits nonzero so the orchestrator treats this as a blocker.
The orchestrator treats the phase as pending until the callback is visible.
### Gate 3: Waiting Handoff
Waiting is handled by the platform, not by manual polling.
Handoff sequence:
1. Send the specialist work with the spawn or continue operation.
2. Verify the specialist id per Gate 1.
3. Tell the user the specialist id.
4. End the active turn and let the platform deliver the callback.
- (Codex) Between steps 2 and 3, confirm the transport-injected id matches the
- `read_thread` result, then create or update a heartbeat automation for the
- current orchestrator thread; include the heartbeat id when telling the user.
- Retain the live `exec_command` session id as the callback destination. On a
- heartbeat turn, read that session once with `write_stdin` and confirm the
- `specialist_callback` event against `read_thread`; do not poll either source.
+ (Codex) For a bootstrap turn, retain the live `exec_command` session id and
+ create or update a heartbeat automation for the current orchestrator thread;
+ include the heartbeat id when telling the user. On a heartbeat turn, read that
+ session once with `write_stdin`. Accept the bootstrap only after both
+ `specialist_callback` and `thread_handoff_ready` are present, then verify the
+ task with `read_thread`.
+ For a continuation, call `send_message_to_thread` once with the existing
+ specialist id and the continuation prompt, then use one bounded `wait_threads`
+ call with the returned cursor as `afterCursor` when available. The task's final
+ text is the callback. If the bounded wait times out while the task is still
+ active, report one short status and end the turn; a later turn can wait again.
+ Do not create a heartbeat for native continuations and do not invoke App Server
+ `thread/resume`.
+
Do not emulate waiting with `sleep`, repeated reads, shell loops, timers, or repeated status checks in the same assistant turn — on either platform.
This gate forbids in-turn waiting, not background watchers: a background
watcher command that exits when its condition holds (the hybrid loops'
codex-completion watcher) is the platform's single-completion shape and
ends the turn properly — arming one is not a violation of this gate.
(Codex) If heartbeat automation tools are not loaded, search for `automation_update` first. If no heartbeat tool is available, tell the user the fallback is unavailable and end the turn after one verified handoff; do not replace the missing heartbeat with manual polling.
A wake-up turn (heartbeat on Codex, task notification on Claude Code) may do one status check. If the specialist is still active, report one short status and stop. Do not sleep and check again.
Continue immediately only when an explicit callback is already present or the specialist is already shown as completed.
### Gate 4: Role-Specific Review Feedback
Reviewer feedback returns to the same planner or worker session that produced the reviewed artifact, via the continue operation.
The orchestrator must not classify findings, choose the repair route, filter reviewer output, or turn the review into a patch list.
Plan-review blockers return to the planner with the `cvg-plan-review-feedback` skill. The prompt must contain the exact reviewer blocker findings under a `Plan Review Feedback Input` section.
Code-review blockers return to the worker with the `cvg-code-review-feedback` skill. The prompt must contain the exact reviewer blocker findings under a `Code Review Feedback Input` section.
Role boundaries still apply: workers may repair implementation-owned findings only. Workers must stop and callback for plan gaps, contract gaps, systemic design gaps, reviewer clarification, or escalation. Only planners may produce plan or contract revisions.
The orchestrator continues only after the actor callback reports a role-valid result: implementation repair from a worker, plan or contract revision from a planner, or a blocker that needs planner, reviewer, user, or escalation handling.
### Gate 5: Fresh Reviewer Exit
Same-reviewer pass is never the final exit condition.
The exit sequence is:
1. Fresh reviewer performs a complete first review.
2. If blockers exist, return feedback to the same planner or worker and require the role-specific feedback skill.
3. Same reviewer performs a focused re-review after the actor produces a reviewable update.
4. If same reviewer passes, start a new fresh reviewer for another complete first review.
5. Exit only when the new fresh reviewer reports no blocking findings.
A fresh reviewer is a newly spawned specialist with no prior review context.
Same-reviewer re-review continues the original reviewer session so it retains
its first-pass context.
For code-review final exits, the final fresh reviewer prompt must include
`Review mode: final-fresh-exit`. Its audit artifact must show every selected
auxiliary reviewer dispatched with a non-null `agent_id`;
inline auxiliary coverage cannot satisfy the final fresh-reviewer exit condition.
A "ready with fixes" verdict (plan criteria met, only non-blocking P2 findings
remain) satisfies the exit condition; carry the remaining P2 list into the
completion summary instead of looping on it.
**Round cap.** One round is one full cycle of steps 1-4. The cap is 3 rounds
unless the user set a different cap in the invocation. When the cap is reached
without a clean fresh review, stop the loop and escalate to the user with all
open findings, their adjudications, and the one-line instruction to authorize
more rounds; an authorization raises the cap explicitly and is recorded in the
ledger. Do not keep looping past the cap.
**Loop ledger.** In-context round counting drifts over long loops, so the cap
and the ratchet are enforced from a file, not from memory. When the loop
starts, create `/tmp/convergo/<loop-slug>/ledger.md` — the slug is
`<UTC-timestamp>-<base-short-sha>` (timestamp alone when there is no repo),
so every loop gets a fresh directory. Never append to or read another loop's
ledger: a stale ledger's non-blocking adjudications would suppress a new
loop's legitimate blockers. Append one line per
event: `round <N> opened | reviewer <id> | <K> blockers` when feedback is
sent, `round <N> closed | <verdict>` when the focused re-review returns,
`cap raised to <N> | user` on authorization, and
`adjudication | <finding key> | <verdict> | by <role>` for every validity or
severity adjudication. The cap check and the adjudication ratchet read the
ledger; the completion summary quotes it.
**Adjudication ratchet.** A finding adjudicated invalid or out of scope by the
role-specific feedback skill in an earlier round (same file, line, and issue)
cannot re-block a later round unless new evidence appears. The orchestrator
relays the prior adjudication back to the reviewer; the reviewer decides
whether new evidence overrides it.
The ratchet also covers reviewer classifications: a finding an earlier review
classified as non-blocking in a verdict that passed cannot be re-raised as
blocking by a later reviewer without new evidence. The orchestrator relays the
prior classification from the ledger alongside the new finding — a ledger
lookup, not orchestrator classification.
A reviewer whose task carries `Review mode: final-fresh-exit` is exempt from
this classification arm: an exit gate blocks on its own judgment. When it
re-raises a finding a prior review classified non-blocking, it must cite the
prior classification from the ledger in its verdict, and the orchestrator
surfaces the unresolved conflict to the user at loop end or escalation. In
single-engine loops every Phase 5 fresh reviewer carries final-fresh-exit, so
there the classification arm binds only first reviews and focused re-reviews.
That narrowing is intended, not an oversight: thrash protection belongs to
the early rounds, exit gates keep full judgment, and the round cap bounds the
cost of a re-raise. The adjudication arm above is never exempted: overturning
an evidence-based adjudication requires new evidence — and showing the
original evidence wrong is itself new evidence.
Audit artifact identity fields are self-reported by the reviewer. Treat them as
an audit trail, not proof of dispatch. If the artifact is missing, identity
fields are null, or the callback contradicts the artifact, treat the exit gate
as unmet.
## Specialist Prompt Checklist
Every specialist prompt must include:
- role and scope,
- callback destination per Gate 2,
- worktree or repo path,
- base/head refs when relevant,
- dirty-state warning and unrelated files when present,
- one source artifact or exact user input: plan path, requirements path, review
callback, or implementation goal,
- required role skill,
- task-specific external side-effect boundary, especially whether push, deploy,
remote smoke checks, secrets, or external environment/data changes are allowed,
- audit artifact callback line when the specialist creates or receives one,
- - exact callback transport block,
+ - the operation-appropriate callback transport block,
- exact callback template.
Do not include:
- execution rules already owned by the required role skill,
- duplicated authority lists when the plan or source artifact links them,
- likely files or exhaustive surface checklists copied from the orchestrator,
- old heartbeat payloads or previous phase instructions,
- reviewer concerns unless this is a role-specific feedback prompt.
- Callback transport block (Codex):
+ Bootstrap callback transport block (Codex `start` only):
```text
Callback destination: the attached Convergo App Server transport.
When complete or blocked, call convergo_callback exactly once with this input:
{"callback":"<the exact callback text required below>"}
If you create or receive an audit artifact, include this line in the callback:
Audit artifact: <absolute path>
If convergo_callback is unavailable, write "callback transport failed" and include the exact callback text in your final answer.
```
- ## Heartbeat Prompt Checklist (Codex only)
+ Native continuation callback transport block (Codex
+ `send_message_to_thread` only):
+ ```text
+ Callback destination: your final answer in this same Codex task. Desktop wait_threads delivers it to the orchestrator.
+
+ When complete or blocked, make your final answer the exact callback text required below.
+ Do not call convergo_callback during this continuation.
+ If you create or receive an audit artifact, include this line in the callback:
+ Audit artifact: <absolute path>
+ ```
+
+ ## Bootstrap Heartbeat Prompt Checklist (Codex only)
+
Heartbeat prompts should say:
- which specialist thread to check,
- - which attached execution-session id carries `specialist_callback`,
+ - which attached execution-session id carries `specialist_callback` and
+ `thread_handoff_ready`,
- what callback shape to detect,
- whether the actor completed the role-specific feedback intake,
- if still active, report one short status and continue waiting,
- do not busy-wait,
- delete or update the heartbeat when the phase is complete or stale.
+
+ Do not use a heartbeat for Desktop-native continuations; use `wait_threads`.
When updating a heartbeat for a new phase, replace the old instructions. Do not
wrap or nest previous heartbeat payloads inside the new heartbeat prompt.
## Completion Summary
When the workflow completes, summarize:
- base and final refs or final plan path,
- specialist ids verified per Gate 1,
- callback transport status,
- audit artifact paths received from specialists,
- review loop results,
- role-specific feedback results,
- verification gates,
- remaining known gaps,
- heartbeat cleanup (Codex),
- whether the fresh-reviewer exit condition was met.