Local delivery pilot (private)
Local delivery sends review comments to a linked local chat instead of the
normal thread queue. It is a private pilot. It is off by default, and we turn
it on one project at a time. If list_projects shows workflow: threads,
nothing on this page applies to you.
Recorded local compatibility
| Client | Bridge |
|---|---|
| Claude Code 2.1.195 | 0.1.1 |
| Codex CLI 0.150.1 | 0.1.2 |
Desktop and cloud chats are not supported. The local bridge from 0.1.4 puts
the recoveryGeneration in the delivery message.
Link a chat
- A workspace owner enables project access and connects the GitHub repository.
- In your existing chat, run the
grouchlinkskill. It links the chat to the project that matches the repository, and asks if several match. The public plugin alone does not install the private bridge. - Call
get_chat_connectionbefore working feedback. A visible tool list does not prove access. - Keep the original chat and the saved state path from the setup receipt. Resume the same chat after closing it. Do not copy chat IDs or delete state to work around a mismatch.
To pick up work, ask the linked chat to check Gutternote, or leave a
wait_for_batches call running. Automatic arrival needs extra bridge and
Channel setup.
Project enablement
BRIDGE_PROJECT_DISABLED from a tool, or HTTP 503 project_not_enabled, means
delivery is not on for this project. A workspace owner can ask us with
Contact us in the dashboard. Keep the original chat and request IDs. Do not
fall back to another comment reader.
While delivery is off, existing claims, results, status, owner recovery and exact request replays still work. New pickup waits. Held comments stay private: no other tool can read them or their screenshots, even after the pilot is off.
Delivery settings
Agents → Local delivery appears only on pilot projects with a linked chat.
- Owners choose Collect, then send selected comments or Immediately when tagged, and can pause automatic delivery.
- Pausing keeps Immediate comments queued until you resume. Switching to Collect cancels automatic sending for comments not yet sent.
- Owners can pause or switch to Collect even when the chat lost access or the project is not enabled. Resume and Immediate wait for both to be restored.
- Members can inspect and send held comments.
Before release, the server checks each comment’s author again. A permission change can block a saved comment. Restoring access does not release it, but a permitted member can still send it. Slack comments and bot replies are never delivered.
Send from the widget
Only workspace members see delivery controls. Comment-only reviewers can still comment and reply.
The saved-comments counter opens a list of your held notes on this preview. Select comments and send them to a linked chat. Select all for this chat selects ready comments up to the batch limit. Replies must go to their original chat in a separate batch.
A send the server could not confirm stays in the tab until you retry or discard it. Retry with the same request: a queued batch replays and is not queued twice. Signing out clears it.
| Status | Code | Meaning |
|---|---|---|
400 | invalid | The batch was empty, too large or repeated a comment. Nothing queued. |
403 | agents_disabled | Sending to agents is off on this deployment. Nothing queued. |
403 | delivery_unavailable | This session cannot send these comments. |
409 | comment_changed | A comment changed or was already sent. Refresh and select again. |
409 | conversation_destination | Send replies to their original chat in a separate batch. |
503 | project_not_enabled | Delivery is not on for this project. Nothing queued. |
409 release_failed, 503 pilot_disabled, other server errors and a lost
response may have queued the batch. Retry with the same request ID and body.
Work a batch
On a batches project, the agent works only batches released to its chat:
list_batchesorwait_for_batches(each wait is at most 20 seconds).get_batch, thenacknowledge_batchwith a new UUID asrequestId. Edit only after a successful new claim.- Post progress and results with
reply_to_batch_thread(at most 32,000 bytes). Reply at least every 20 minutes on long work. After 30 minutes with no reply, the batch shows Stalled.
| Code | What to do |
|---|---|
BATCH_ALREADY_CLAIMED | Another pickup holds the claim. Do not edit. If this task made the claim and lost the response, retry with the same requestId. |
REQUEST_ID_INVALID | Retry with a new UUID as requestId. |
BATCH_REOFFERED | An owner recovered or released the batch. Do not edit. If asked to pick it up again, call list_batches and acknowledge with a new requestId and the current recoveryGeneration. |
BATCH_CONTEXT_CHANGED | A comment changed. After pickup, stop editing and call finish_superseded_batch with the claimId. Tell the user which threads were not done. |
BATCH_RELEASED | An owner released the batch from this pickup. Stop and tell the user. Changes already made stay in the checkout. |
BATCH_CONTEXT_CURRENT | Nothing changed, so the batch cannot be finished as superseded. Reply to each thread. |
When the repository is busy
The pilot runs one batch at a time per GitHub repository in a workspace, even across projects.
acknowledge_batchreturnsREPOSITORY_BUSY. Retry the same batch in the same chat every one to two minutes, before editing. Resending or opening another task does not help.- Batches start oldest first. A batch whose agent stops asking for 5 minutes loses its place until it asks again. The dashboard shows waiting batches as Queued.
- A batch keeps the repository through sleep, disconnection and pauses. It frees the repository when every thread has a final result, or when an owner releases it. Nothing times out.
REPOSITORY_REQUIRED: ask the owner to set the project’s repository, then retry.REPOSITORY_RECONCILIATION_REQUIRED: an older run must finish, or an owner must stop and reconcile it.
Recover a delivery
Only a workspace owner can recover an uncertain delivery, from Agents → Local delivery, after checking the original chat. An agent cannot approve its own retry. Members see the next step without recovery controls.
A recovery keeps its request ID. If the response is lost, Check recovery
returns the saved receipt. The saved confirmation belongs to the account that
made it and is cleared on sign-out. A 200 confirms the queue changed, not that
the agent picked it up. Claimed or accepted batches cannot be reset.
Release a stalled repo
When a batch shows Stalled, an owner can stop it and release the repository. The outcome is one of:
- Requeue: the batch waits again for the same chat.
- Finish: a released comment changed, so the batch finishes as superseded. Unanswered comments go back to their reviewers.
Either way the repository is free. The earlier pickup’s replies are refused from then on.
Local delivery recovery
Errors from Recover and Release:
| Status | Code | What to do |
|---|---|---|
400 | invalid | Check the request. |
403 | not_owner | Ask a workspace owner. |
409 | reconciliation_required | Confirm the action and what happened in the original chat. |
409 | delivery_changed | Refresh. The destination or generation changed. |
409 | request_id_reused | Reuse the original body to check its receipt, or start a new action. |
409 | batch_already_claimed | Continue in the chat that owns the claim. |
409 | batch_context_changed | Reconcile the work, then send the current comment revision. |
409 | recovery_unsupported | The chat accepted the batch. Ask it to pick it up. Do not resend. |
409 | recovery_failed | Refresh and check the chat and its access. Nothing was recovered. |
409 | repository_not_stalled | The agent was active in the last 30 minutes. Refresh. |
409 | repository_already_released | The batch finished or was released since the page loaded. Refresh. |
409 | delivery_unavailable | The batch is not in this project. Nothing was released. |
503 | pilot_disabled | Delivery is not on for this deployment. |
Bridge errors
| Code | What to do |
|---|---|
BRIDGE_UPGRADE_REQUIRED | The bridge and server versions do not match. Ask the pilot operator to align them, then retry with the saved state. Do not delete pairing files. |
CODEX_CALL_CONTEXT_REQUIRED | The Codex call had no valid chat identity. Use a supported local Codex surface. Do not copy an ID into an argument. |
TOOL_CACHE_REQUIRED | The saved tool list is missing. Run grouchlink again from the original chat with its saved state path. |
If setup says the harness gave no chat identity, run grouchlink from the
original local chat. Do not copy or invent an ID.