Skip to main content

Agent Communication Protocol

Last amended: 2026-05-07 (NQU-757 thread — field-discipline + PR-signaling + advance-or-escalate)

Defines how the two AI agents in this workspace communicate, hand off work, and escalate to human input.

Roles

  • CC (Claude Code). Code, tests, migrations, git operations, PR mechanics, runtime debugging, infrastructure/Terraform, observability.
  • CD (Cowork / Claude Desktop). Strategic scoping, doc writing, spec drafting, content review, cross-cutting analysis, planning, requirements detailing.
  • Joe. Strategic decisions, business judgment, customer-facing and contractual decisions, final merge approval.

The role split is summarized in MEMORY.md under "CD vs CC role split." Don't take work in the other agent's lane — reassign instead.

Channels

All durable agent-to-agent communication happens in Linear. Issues, comments, labels, the delegate field, and the assignee field are the source of truth. Other channels (file-system handoffs, journal entries) are supplementary.

Identities and attribution

  • CC posts comments via its registered Linear identity. Any Linear MCP comment tool that posts as CC is acceptable.
  • CD posts comments via linear-agent-cd:comment. Never use the standard save_comment — that attributes the post to Joe.
  • Both agents have distinct delegate identities (delegate=CC and delegate=CD).
  • Setting delegate=CC or delegate=CD is the canonical way to route work between lanes.

Routing primitives

ActionHow
Hand off work to CCSet delegate=CC on the issue. Comment summarizing what CC needs.
Hand off work to CDSet delegate=CD on the issue. Comment summarizing what CD needs.
Ask the other agent a questionComment on the relevant issue, address the other agent explicitly.
Escalate to JoeApply Review-Joe label. Comment with the question, options, and recommendation.

Field, not comment. Routing decisions live in the delegate field, not in comment text. Stating "Marking delegate=CD" or "Reassigning to CC" in a comment without also updating the field is a discipline failure — the inbox-check skills, Joe's morning queue, and the state-drift audit all filter on the field, not on comment scrape. Update the field in the same step you announce the reassignment. If your only available tool for the field edit is Joe-attributed (CD's case for delegate changes today), surface that explicitly in the comment so attribution stays honest.

Signaling Joe for PR-merge gates

Per post-NQU-700 PR protocol, Joe's "go" gate moved from GitHub UI to chat. Two signaling rules:

  1. One PR per ask. Don't bundle multiple PRs into a multi-PR table inside a longer status — those are easy to skim past. When a PR is ready, post a single chat message: PR #N ready — [one-line summary]. Risk: [low/med/high]. Go?
  2. Linear-side mirror. If you also post in Linear (e.g., on the originating issue), lead the comment with ✅ READY FOR JOE GO — PR #N: [one-liner] so it stands out in Joe's inbox-check feed.

Either chat-only or chat-plus-Linear-header is acceptable; bundling-into-tables is not.

Wake-up: Scheduled Inbox Checks

Both agents are session-based — neither runs continuously between sessions. To enable agent-to-agent communication without Joe acting as a relay, both agents run scheduled tasks that poll Linear for unhandled work directed at them.

CD schedule

Cron: 0 9,10,13,17 * * * (Eastern US local time). Four runs daily: 9 AM, 10 AM, 1 PM, 5 PM.

CD's scheduled task:

  1. Reads memory for current project context
  2. Queries Linear for unhandled CD-directed items (delegate=CD, new comments, mentions)
  3. Responds, reassigns, or escalates each item
  4. Awaiting-Joe surface. Queries label:Review-Joe AND state.type NOT IN (completed, canceled, triage_waiting_for) and lists the result in the run log under a 🟠 section.
  5. State-drift audit. Lists issues with comments or updates in the last 24 h that are still in Backlog or Todo. Includes who last touched them. Does not auto-promote; surfaces for next interactive pickup.
  6. Logs a run summary to Nquiry/docs/working/cd-inbox-runs.md

CC schedule

Cron: TBD on the CC side. Recommended 0 9,10,13,17 * * * (Eastern US) to match CD's cadence.

CC's scheduled task mirrors CD's: query for delegate=CC and CC-directed items, respond/reassign/escalate, run the same Awaiting-Joe surface and state-drift audit (steps 4 and 5 above), log a run summary.

Latency expectation

The shared cadence means routine items resolve within ~4 hours during business hours. Items posted overnight resolve at the 9 AM run. Plan against this latency — don't post time-sensitive work agent-to-agent and expect a 5-minute response. Real-time items go through Joe.

Escalation: Review-Joe

When either agent encounters an item that requires Joe's judgment, the protocol is:

  1. Apply the Review-Joe label to the issue.
  2. Post a comment containing:
    • The decision needed (one sentence)
    • The options under consideration
    • The agent's recommendation and reasoning
    • What's blocked until Joe decides
  3. Set delegate=Joe to make ownership explicit.

Joe's filter for "what needs my attention" is label:Review-Joe. Anything not labeled Review-Joe is presumed agent-handleable.

Filter spec (precise): label:Review-Joe AND state.type NOT IN (completed, canceled, triage_waiting_for). The Waiting For state is excluded because it represents a different stall semantic — see below.

Review-Joe vs. Waiting For — semantic distinction. Both pause an issue, but they represent different blockers:

  • Review-Joe (in Backlog/Todo/In Progress): blocked specifically on Joe's judgment. Goes onto Joe's review queue.
  • Waiting For: blocked on something other than Joe — third-party response, scheduled date, another open ticket, external dependency. Stays out of Joe's queue but tracked elsewhere.

Don't conflate them. If an item is awaiting Joe's ratification, sign-off, or direction, the correct combination is state=In Progress (or whatever the work state was) + Review-Joe label, not state=Waiting For. Use Waiting For only when Joe's action would not unblock the issue.

Removing Review-Joe. Strip the label the moment Joe acts (or when state moves to Done/Canceled). A Done issue with Review-Joe still attached is a discipline failure — clean it up. Any agent that reads such an issue in passing should fix it.

When to escalate

Escalate to Joe when any of the following apply:

  • Decision affects pricing, billing, retention values, contracts, or other customer-facing policy
  • Decision crosses a scope boundary an agent shouldn't unilaterally redraw
  • Cross-functional dependency (legal, finance, outside counsel)
  • Disagreement between CC and CD that the agents can't resolve in 2-3 rounds of comments
  • Cost or risk threshold exceeded (define explicit thresholds in repo CLAUDE.md — e.g., changes touching billing flow, anything affecting external API contracts, anything destructive in production)
  • Issue mentions "urgent," "blocker," "production," or refers to legal/financial/customer risk
  • Comment thread has gone >3 rounds without resolution

When in doubt, escalate. Better to ask Joe and find out it was unnecessary than to make a call Joe wouldn't have made.

State Discipline

Issue state must reflect actual progress. Both agents must transition state when starting substantive work — not on issue creation, but at the moment of first real action.

Required transitions:

  • BacklogTodo when CD or CC commits the issue to active work (next session, this week, etc.)
  • TodoIn Progress when an agent posts substantive content (a draft, a spec, a PR, a code change, etc.)
  • In ProgressDone or Canceled at completion
  • In ProgressWaiting For only when a non-Joe external blocker appears
  • For Joe-action items: In Progress + Review-Joe label (never Waiting For)

Why this matters: the CD inbox-check, Linear filters, and Joe's morning review all rely on state to identify what's actively moving. Items grinding away in Backlog or Todo lie about WIP. The state-drift audit step in the CD inbox-check (see "Wake-up" above) catches items with recent activity in non-started states; that audit only works if discipline is consistent across humans and agents.

On the human side: Joe is bound by the same rule. When picking up an issue, bump it to In Progress so the system sees it.

On the agent side: when CD or CC opens an issue and does substantive work, the work itself counts as "starting." Don't leave a freshly-commented Todo issue in Todo. Use linear-agent-cd:state for CD-attributed transitions; CC uses its own state tool.

Use linear-agent-cd:state for CD-attributed transitions, never save_issue for state changes (the latter attributes the change to Joe).

In Progress: advance or escalate, never status-sweep

When an item has been In Progress across multiple sessions without commits, comments, or PRs, the default response is not "no progress this session." Items must advance per session or get explicit Review-Joe escalation with a specific question.

Two failure modes to avoid:

  1. Status-sweep on stalled items. Reading the issue body, noting "no movement," and parking is the wrong default. It costs queue legibility — Joe can't tell whether the item is stuck on him, on the other agent, or on you. Either commit a focused multi-session sprint and say so explicitly in a comment, or escalate the specific decision blocking progress via Review-Joe.
  2. Read the body once more before flagging "needs Joe scoping." Many In Progress items already contain proceed-defaults ("defaulting to X unless told otherwise"), pre-decided scope numbers, or stated tooling choices that resolve apparent open questions. Reread the issue body and any linked specs before flagging an item as scope-blocked. The 2026-05-07 review found a 4-of-6 false-positive rate on "needs Joe scoping" flags that traced to body-skimming during status sweep.

CC has the Agent SDK and can spawn subagents internally. Before posting Plans or PR descriptions for external review by CD or Joe, CC is encouraged to run an internal code-reviewer subagent for a self-review pass. This catches mechanical issues before external review and reduces iteration count.

CD doesn't have the equivalent surface today; this is a CC-side recommendation.

Examples

Example 1: CC has a technical question for CD

CC working on a refactor encounters a design decision (e.g., "should this helper assert the user exists in the DB on every call?"). Rather than waiting for Joe:

  1. CC posts the question as a comment on the Linear issue, addresses CD.
  2. CC's session ends.
  3. CD's next scheduled run (within 4 h during business hours) picks up the comment.
  4. CD posts a response with reasoning.
  5. CC's next scheduled run sees the response and proceeds.
  6. Joe sees the resolved thread on his next Linear scan but didn't have to mediate.

Example 2: CC encounters a billing-affecting change

CC working on a billing handler realizes they need to change how a quota is calculated, which will affect what customers see in invoices.

  1. CC applies Review-Joe label and delegate=Joe.
  2. CC posts comment: "This change shifts the quota math — current customers will see different numbers next billing cycle. Options: (a) grandfather existing, (b) apply to all on next cycle, (c) wait for end of contract term. Recommend (a). Blocked until your call."
  3. Joe sees the Review-Joe filter, makes the call, removes the label, sets delegate=CC.
  4. CC's next run picks up the resolution and proceeds.

Example 3: CD identifies missing test coverage during spec review

CD reviewing a CC plan notices test coverage gaps but can't write tests itself.

  1. CD comments on the plan with the gap analysis.
  2. CD reassigns: delegate=CC.
  3. CC's next run reads the gap analysis and either accepts or pushes back via comment.
  4. Iteration continues agent-to-agent until resolution or escalation.

Anti-patterns

  • Don't use save_comment for CD posts (attributes to Joe). Always linear-agent-cd:comment.
  • Don't take work in the other agent's lane. Reassign instead.
  • Don't make policy or business decisions on Joe's behalf. Escalate via Review-Joe.
  • Don't leave items in limbo. Every reviewed item should advance to a clear next state (responded, reassigned, escalated, closed).
  • Don't announce a delegate reassignment in a comment without updating the delegate field in the same step.
  • Don't bundle multiple PRs into a single status table when asking Joe for merge "go" — one PR per chat ask.
  • Don't status-sweep stalled In Progress items. Advance them or escalate the specific blocker via Review-Joe.
  • Don't spawn new tickets without Joe's go-ahead. Recommend creation via Review-Joe instead.

Sibling docs

  • git-workflow.md — GitHub Flow + branch protection rules
  • MEMORY.md (auto-memory) — agent identities, role split, project context