Recovery
Agents recover by contract, not by guessing.
Every recoverable failure returns the same fields: reason, userMessage,
fixActionForAgent, recoveryTool, retryable, and stopRule.
That lets caller agents continue the launch loop safely instead of parsing prose or retrying blind.
Canonical shape
{
"ok": false,
"reason": "requires_approval",
"summaryForUser": "This action hasn't been approved yet.",
"userMessage": "Approve inline in chat, or open the signed review link if you are away from the IDE.",
"fixActionForAgent": "STOP. Render inline approval commands; surface reviewUrl only as fallback.",
"recoveryTool": null,
"retryable": false,
"stopRule": "Do not retry publish/send until approved.",
"reviewUrl": "https://chieflab.io/runs/..."
} Recovery table
| reason | agent move | hard stop |
|---|---|---|
missing_api_key | Call chieflab_signup_workspace, surface deliveryUrl, wait for key, then retry the original tool. | Do not keep retrying the launch without a Bearer key. |
requires_approval | Render the inline drafts and approval commands. Surface reviewUrl only when the user needs the away-from-IDE fallback. After approval, call the executor tool with the approved actionId. | Never call publish/send again until the user approves in chat or on the reviewUrl fallback. |
missing_connector | Call chieflab_connect_provider or chieflab_use_manual_fallback for manual-only channels. | Do not claim the channel was published. |
missing_repo_context | Gather whatChanged, recentCommits, changedFiles, routes, README, targetCustomer, launchGoal; retry chieflab_launch_product. | Warn the user the first output may be generic. |
wrong_workspace | Use the workspace bound to the Bearer key, or mint a fresh workspace key. | Do not leak whether another workspace's action exists. |
rate_limited | Wait retryAfterSeconds, then retry once. | Do not spin in a loop. |
provider_not_live | Use manual fallback or pick a live connector-backed channel. | Do not pretend a mock connector executed. |
measurement_unavailable | Normally the cron auto-fires post_launch_review at +24h and surfaces the lesson on the next boot. If the readback came back empty (provider lag, missing OAuth scope), wait 12-24 hours and force a manual chieflab_post_launch_review for replay — but only as recovery, not as the default flow. | Do not fabricate metrics. Do not call post_launch_review on a normal launch — the cron handles that. |
Safe launch preparation
A successful chieflab_launch_product call returns sideEffectsPreparedButNotFired,
externalActionsExecuted: 0, approvalStateMachine, reviewUrl, and
agentUsefulness. Agents should render the inline approval path first, surface reviewUrl only when useful, then stop.