Cline: who decides what
How to read this page
A seat is a judgment the agent makes over and over: which run path a command takes, what the model sees, is the work done. Each card gives the question, how the judgment is answered, and where in the code it is held. Seat ids (A1, B3 …) are links.
The chip on each card has two words. The first is about the question: a RULE has one right answer given its inputs, so a run that answers differently is a bug; a RULING is one that competent people could answer differently. Enforcing a limit someone set is a RULE; choosing what to keep, what to trust or when the work is done is a RULING, even when code holds it.
The second word is who holds it: llm = a language-model call; model = another learned model; code = code in their repository; human = a person; external = code outside the repository that the agent hands the decision to.
Paths are relative to the repository root. A bare :120-140 means lines in the file named just before it.
Counts
83 seats on this edition: A 12, B 17, C 11, E 16, F 13, G 8, H 5, I 1.
| Kind of question · holder | Seats |
|---|---|
| RULE · code | 43 |
| RULING · code | 21 |
| RULING · llm | 11 |
| RULING · human | 6 |
| RULING · external | 2 |
What this edition leaves out
31 decisions are left out of this edition.
Each card shows its question, how it is answered and where it is held. It does not show what checks each decision, its contract, what happens on error, or its failure history, because those parts were not each re-checked against the code. There is no list of gaps and no coverage figure: the readers' candidate gaps have not each been ruled against the code, and we have not counted, by stated searches, the model calls and approval points the seats leave out.
A. Intake and routing
A1 Which run path does a CLI invocation take (interactive TUI, one-shot, piped stdin, background hub "zen", ACP, kanban)? RULE · code
- Answered how
Code routes on flags in a fixed order: after the
--updateand--kanbanbranches (each returns first) and argument checks,--acpenters the ACP stdio transport and returns before the remaining paths; then, when stdin is not a TTY, carries non-empty piped input and--tuiis absent, the input is appended to the prompt and run one-shot (or handed to the background hub with--zen); otherwise--tuior a missing prompt opens the interactive TUI (--zenthere is an error); otherwise the prompt runs one-shot, or goes to the hub with--zen.- Held by
apps/cli/src/main.ts:785-831(argument conflicts: json needs a prompt or piped stdinapps/cli/src/main.ts:794-800; ACP exclusive, returnsapps/cli/src/main.ts:802-820;--worktreewith no prompt, no resume and no piped stdin needs a full TTYapps/cli/src/main.ts:822-831);apps/cli/src/main.ts:975-986(theisHeadless/isInteractiveflags, which gate OAuth and catalog loading);apps/cli/src/main.ts:1142-1170(piped stdin, one-shot or zen);apps/cli/src/main.ts:1174-1219(interactive);apps/cli/src/main.ts:1221-1244(one-shot / zen).
A2 Should the agent be planning or acting right now? (the person's Plan/Act toggle) RULING · human
- Answered how
The person flips the Plan/Act toggle. In VS Code the webview request is decoded to "plan"/"act" and handed to
controller.togglePlanActMode; in the CLI TUI the choice is persisted at once and, if a turn is running, recorded as a pending change with source "ui" and the turn aborted, otherwise applied immediately, which swaps the mode, the plan-onlyswitch_to_act_modetool and the system prompt.- Held by
the person, through the VS Code Plan/Act toggle (
apps/vscode/src/core/controller/state/togglePlanActModeProto.ts:13-35) or the CLI TUI mode toggle (apps/cli/src/runtime/run-interactive.ts:780-792, pending source"ui"). Applying a mode in the CLI rewrites mode, extra tools and system prompt (apps/cli/src/runtime/interactive/mode.ts:118-131); a plan-mode session also gets the command guard (sdk/packages/core/src/runtime/orchestration/runtime-builder.ts:553-558).
A3 Has the person approved the plan, so execution may start? (CLI switch_to_act_mode) RULING · llm
- Answered how
In a CLI plan-mode session the main model decides by calling
switch_to_act_mode; the tool'sexecuterecords a pending switch to act with source "tool" without looking at the transcript, the run ends on the tool result, and if that turn finished "completed" the CLI rebuilds in act mode and sends the canned continuation prompt so execution starts with no further word from the person. Whether the tool call itself is put to the person first is a separate approval seat; CLI auto-approve defaults on.- Held by
the session's main model, via the tool built at
apps/cli/src/runtime/interactive/mode.ts:31-68(createInteractiveModeSwitchTool, tool nameswitch_to_act_mode), registered only in plan mode (apps/cli/src/runtime/interactive/mode.ts:124-125). Model = the session's provider/model (A5).
A4 Which provider and model serve this VS Code session (per mode)? RULE · code
- Answered how
Code in
buildSessionConfigtakes the runtime's model selection if one is passed, else the provider stored for the current mode (plan or act) in StateManager and that provider's model for the mode; only when no provider resolved at all does it use the last-used providers.json entry that has an API key, thenDEFAULT_PROVIDER_ID. A missing model id becomes the catalog default, except for local-model providers, which read providers.json and otherwise get an empty id (an explicit "select a model" state).- Held by
apps/vscode/src/sdk/cline-session-factory.ts:952-1050(insidebuildSessionConfig, which starts atapps/vscode/src/sdk/cline-session-factory.ts:919): runtime selection, else the mode's provider from StateManager (apps/vscode/src/sdk/cline-session-factory.ts:952-955); model fromresolveModelId(providerId, mode, ...)(apps/vscode/src/sdk/cline-session-factory.ts:962); if no provider at all, the last-used providers.json entry with an API key (apps/vscode/src/sdk/cline-session-factory.ts:1010-1031); thenDEFAULT_PROVIDER_IDand the catalog default (apps/vscode/src/sdk/cline-session-factory.ts:1035-1050), except local-model providers, which take the providers.json model or an empty id, never a catalog default (apps/vscode/src/sdk/cline-session-factory.ts:1036-1047).
A5 Which provider and model serve this CLI session? RULE · code
- Answered how
Code picks the provider from
-P/--provider, else the last-used provider, else "cline"; the model is--model, else that provider's saved model, else (Cline provider only) its curated default, else the first chat model in the resolved catalog, elseCLINE_DEFAULT_MODEL_ID. The chosen provider and model are then saved back as the provider's settings.- Held by
apps/cli/src/main.ts:1056-1063(--model> saved provider model > the Cline provider's curated default > first catalog chat model >CLINE_DEFAULT_MODEL_ID); provider fromapps/cli/src/main.ts:944-946(-P> last-used provider >"cline"; flag definedapps/cli/src/commands/program.ts:49); the choice is persisted back to provider settings (apps/cli/src/main.ts:1115-1137).
A6 Does a typed slash command in VS Code expand into instructions, and which one? RULE · code
- Answered how
Code scans every slash token in the message, anywhere in it, and resolves each by exact name, then case-insensitively, then by workflow file basename; the first token that resolves to an enabled workflow or a builtin (such as
/deep-planning) is replaced by that command's instructions and the rest are left as typed. Configured skills are never expanded here (theskillstool is expected to serve them); a disabled workflow is skipped; any error returns the raw text.- Held by
apps/vscode/src/sdk/SdkController.ts:1135-1163(resolveSlashCommands) callingexpandSlashCommands(apps/vscode/src/sdk/slash-command-expansion.ts:168-206): matches anywhere in the message, expands only the first token that resolves, honours workflow toggles (apps/vscode/src/sdk/slash-command-expansion.ts:185-190), never expands configured skills (apps/vscode/src/sdk/slash-command-expansion.ts:198-200), expands builtins such as/deep-planning(apps/vscode/src/sdk/builtin-slash-commands.ts:98-103).
A7 Does a typed slash command in the CLI / core expand into instructions? RULE · code
- Answered how
In the interactive TUI, a whitespace-delimited
/namethat names a workflow or skill can be expanded first, anywhere in the message, skills only under the same skills-tool check (apps/cli/src/tui/commands/slash-command-registry.ts:259-299). The core resolver then looks only at a leading/nametoken, normalizes it and matches it exactly against the available commands, where a skill owns any name it shares with a workflow; a matched workflow is always replaced by its instructions (the rest of the message kept), while a matched skill expands only when the CLI judges theskillstool unavailable for the mode and the user's disabled-tools setting (or that check throws).- Held by
sdk/packages/core/src/extensions/config/runtime-commands.ts:133-162(resolveRuntimeSlashCommandFromWatcher: leading/nameonly, skills own a name over workflowssdk/packages/core/src/extensions/config/runtime-commands.ts:100-119); CLI callerapps/cli/src/runtime/prompt.ts:104-119withshouldExpandSkillSlashCommands(apps/cli/src/runtime/prompt.ts:93-102: expand skills only when the skills tool is unavailable).
A8 Which skill does this request call for, and should it be loaded now? RULING · llm
- Answered how
When the
skillstool is registered, the main model decides by calling it with a skill name, steered by a description that lists the enabled skills by name (or namespaced id) only; code then resolves the name by exact id, else a unique enabled suffix match, and returns the skill's instructions as the tool result, or an error string the model reads. When the tool is not registered, no model judgment is made here (CLI slash expansion, A7, is the only path).- Held by
the session's main model, via the tool built at
sdk/packages/core/src/extensions/tools/definitions.ts:774-824(createSkillsTool, tool nameskills), registered when tools are on, the skills extension is on, configured skills exist, and the tool survives presets/policies (sdk/packages/core/src/runtime/orchestration/runtime-builder.ts:521-534).
A9 May a VS Code session start when the organization's policy cannot be verified? RULE · code
- Answered how
Before each session start, code waits for the initial remote-config load and tries a refresh. A successful refresh starts the session. If it failed: with no active organization, the session is blocked when the install carries a
lastManagedOrganizationIdmarker and allowed otherwise; with an active organization, the session starts on the cached policy bundle when that bundle belongs to the same organization, and is blocked otherwise.- Held by
apps/vscode/src/sdk/SdkController.ts:911-973(ensureRemoteConfigForSessionStart, wired asbeforeStartSessionatapps/vscode/src/sdk/SdkController.ts:978): refreshed → start; no org and a persistedlastManagedOrganizationId→ block (apps/vscode/src/sdk/SdkController.ts:934-945); no org ever → start (apps/vscode/src/sdk/SdkController.ts:947-954); active org with a same-org cached bundle → start on last known-good (apps/vscode/src/sdk/SdkController.ts:957-965), else block (apps/vscode/src/sdk/SdkController.ts:967-972). Marker kept through offline cold starts (apps/vscode/src/core/storage/remote-config/sdk-control-plane.ts:238-251).
A11 Does this incoming automation event start a scheduled run? RULE · code
- Answered how
Code logs the event and, if an event with that id was already logged, does nothing more; otherwise, for each event spec registered for the event type, it checks the spec's filters (every key must match by attribute, payload or dotted path; an array means any-of; an empty filter matches). A matching spec queues a run unless it is debounced onto an already-queued run for the same dedupe key, or suppressed by its dedupe window or cooldown; all three are off when the spec leaves them at 0.
- Held by
sdk/packages/core/src/cron/events/cron-event-ingress.ts:163-171(automationEventMatchesFilters) andsdk/packages/core/src/cron/events/cron-event-ingress.ts:213-360(duplicate-event check, per-spec filter, debounce merge, dedupe-window and cooldown suppression; dedupe key defaulteventType:source:subject, oreventType:source:eventIdwhen there is no subject, used only when the event carries nodedupeKey,sdk/packages/core/src/cron/events/cron-event-ingress.ts:87-89).
A13 When the person sends a message during a run, does it interrupt the current run or wait? RULE · code
- Answered how
The person picks the delivery for each message:
queueorsteer. Code puts a steer entry at the front of the queue and, unless the session is aborting, notifies the running agent that a user message is pending; a queued entry waits at the back and is drained one at a time once the agent can start a run. A new prompt whose text equals one already queued replaces it (keeping steer if either was steer, otherwise moving to the back).- Held by
sdk/packages/core/src/runtime/turn-queue/pending-prompt-service.ts:137-190(enqueue: identical prompt text merges; asteerentry jumps the queue;consumeSteertakes the first steer) andsdk/packages/core/src/runtime/turn-queue/pending-prompt-service.ts:256-290(controller: steer notifies the running agent); drain runs one entry at a time and stops on a failing turn (sdk/packages/core/src/runtime/turn-queue/pending-prompt-service.ts:313-369).
A14 Which provider, model, workspace and working directory does a new Cline Hub dashboard session use? RULE · code
- Answered how
Provider and model come from the browser's choice if sent. Otherwise they come from the most recently updated hub session of any client, then the last-used provider settings, then
CLINE_PROVIDER/CLINE_MODEL. With neither, the send fails: "No provider/model available". The workspace is the caller'sworkspaceRootif one is passed (whether the dashboard ever passes one was not read), else that same most-recent session'sworkspaceRoot/cwd, else the dashboard's configured workspace root. So a new dashboard session can open in whatever folder another client last touched.- Held by
apps/cline-hub/src/server/sessions.ts:43-76(resolveLaunchContext); "most recent" set atapps/cline-hub/src/server/hub.ts:87-91and on every hubsession created/updatedeventapps/cline-hub/src/server/hub.ts:183-184,:201-202; fallback rootapps/cline-hub/src/options.ts:89.
B. Context: what the model sees
B1 Which base system prompt does this session get (act, yolo, a caller override, or a host fallback)? RULE · code
- Answered how
Code in
buildClineSystemPromptreturns a non-empty caller override as is (adding workspace metadata for the Cline provider when given); otherwise it takes the yolo base prompt in yolo mode and the act base prompt in act and plan, then fills platform, cwd, date, IDE, Cline-only metadata and the rules slot (mode-tag and plan-mode sections plus caller rules). Each host decides what to pass: the CLI passes--system-promptas the override, core bootstrap usesconfig.systemPromptoutright when set, and VS Code never sends yolo and falls back to a one-line prompt if assembly throws.- Held by
sdk/packages/shared/src/prompt/cline.ts:152-213(buildClineSystemPrompt): a non-empty override wins (sdk/packages/shared/src/prompt/cline.ts:169-179); elseDEFAULT_CLINE_SYSTEM_PROMPTS.YOLOfor yolo,.ACTotherwise (sdk/packages/shared/src/prompt/cline.ts:181-184); placeholders filled (sdk/packages/shared/src/prompt/cline.ts:200-212). Callers, consolidated into this seat: CLIapps/cli/src/runtime/prompt.ts:14-38; VS Codeapps/vscode/src/sdk/cline-session-factory.ts:1077-1110; core bootstrapsdk/packages/core/src/services/local-runtime-bootstrap.ts:167-186(aconfig.systemPromptwins); sub-agentssdk/packages/core/src/extensions/tools/team/subagent-prompts.ts:13,33. Registered rules are appended per run (sdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts:754-771, B3).
B2 Which workspace facts (path, git remotes, branch, latest commit) go into the system prompt? RULE · code
- Answered how
Code includes workspace metadata only when the provider id is
clineorcline-pass: the workspace root path as the key, its name hint, every git remote URL with anyuser:pass@part removed, and the latest commit hash and branch. For other providers the metadata slot is left empty, even where the CLI and cron compute it; with a caller override prompt the metadata is still appended for the Cline provider unless the override already carries the marker.- Held by
sdk/packages/shared/src/prompt/cline.ts:79-120(processWorkspaceInfo,buildWorkspaceMetadata) andsdk/packages/shared/src/prompt/cline.ts:205-210(only when the provider is Cline,isClineProvider=clineorcline-pass,sdk/packages/shared/src/providers/utils.ts:1-3; override pathsdk/packages/shared/src/prompt/cline.ts:169-177); credential userinfo stripped from remote URLs (sdk/packages/shared/src/prompt/cline.ts:55-77). VS Code builds the metadata only for the Cline provider (apps/vscode/src/sdk/cline-session-factory.ts:1066-1075).
B3 Which rule files reach the system prompt? RULE · code
- Answered how
Code scans a fixed list of places: the workspace
AGENTS.md,<workspace>/.clinerulesand<workspace>/.cline/rules, the global~/.agents/AGENTS.md, the global Cline rules directories, andrules.mdunder managed plugin roots in<workspace>/.cline. A rule markeddisabled: true, orenabled: falsewith nodisabledvalue, is dropped, the rest are sorted by name and appended under# Ruleson each run, provided rules are enabled for the session.- Held by
search paths
sdk/packages/shared/src/storage/paths.ts:586-601(workspaceAGENTS.md,.clinerules,.cline/rulesviasdk/packages/shared/src/storage/paths.ts:536-543, global~/.agents/AGENTS.md, global rules dirs); discoverysdk/packages/core/src/extensions/config/user-instruction-config-loader.ts:509-591(markdown files plus a rootAGENTS.md; managed.clinepluginrules.md:512-520), definitionsdk/packages/core/src/extensions/config/user-instruction-config-loader.ts:673-698(id = normalized rule name); selectionsdk/packages/core/src/runtime/safety/rules.ts:40-70(enabled = notdisabled, sorted by name); registeredsdk/packages/core/src/extensions/config/user-instruction-plugin.ts:255-261(only withincludeRules); appended per runsdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts:754-771. VS Code reaches the same service (apps/vscode/src/sdk/vscode-session-host.ts:168-174,apps/vscode/src/sdk/SdkController.ts:1112-1124).
B4 Which skills does the model learn exist? RULE · code
- Answered how
Only when the
skillstool is registered (tools on, skills extension on, configured skills exist, tool not removed by preset or policy) does the model learn of skills: the tool description lists every configured skill that passes the session's allowed-skill filter (matched by id, name or bare suffix) and is not disabled, by name, or by id when the id is namespaced. Descriptions are not listed.- Held by
sdk/packages/core/src/runtime/orchestration/runtime-builder.ts:521-545(skills tool only when tools on, skills extension on, skills configured and the tool survives presets/policies);sdk/packages/core/src/extensions/config/user-instruction-plugin.ts:101-130(allowed-skill filter by id, name or bare suffix; disabled skills dropped from the list); listed names reach the model through theskillstool description (sdk/packages/core/src/extensions/tools/definitions.ts:809-818).
B5 What does a configured workflow or skill command expand to when it is typed? RULE · code
- Answered how
Code substitutes the command's instruction body, with an agent-plugin skill's root prepended as a
<skill-root>tag; the shape of the result depends on the path. The CLI/core leading-slash path returns the body followed directly by the rest of the typed text; a command registered through the user-instruction plugin returns the body, a blank line, and the trimmed remainder; VS Code replaces the token in place, keeping text on both sides. The core resolver expands a skill unless the host passesexpandSkillCommands: false, which the CLI does when the skills tool is available (A7); VS Code expands only workflows and builtins (A6).- Held by
workflow and skill expansion text:
sdk/packages/core/src/extensions/config/runtime-commands.ts:63-79(resolveCommandInstructions; an agent-plugin skill gets its root prepended), used by the leading-slash resolver (sdk/packages/core/src/extensions/config/runtime-commands.ts:161, body + raw remainder) and by registered commands (sdk/packages/core/src/extensions/config/user-instruction-plugin.ts:275-292, body + blank line + trimmed remainder). VS Code in-place replacement incl. builtins:apps/vscode/src/sdk/slash-command-expansion.ts:201-203. Skill expansion when the skills tool is absent:apps/cli/src/runtime/prompt.ts:93-102.
B6 Which tools does the model get this turn? RULING · code
- Answered how
At session build, code starts from the mode's preset (act, plan or yolo), then applies the model-routing rules (the defaults unless the caller supplies its own list; an empty list applies none): with the defaults, in act mode only, an
openai-nativeprovider or a model id containing "codex" or "gpt" getsapply_patchin place ofeditor. Tool policies (enabled: false) and global disables remove tools; provider-nativeweb_search(not in yolo, when supported and globally enabled),image_generation, MCP tools and team/agent tools are added; and a final policy filter runs. Each turn, extension tools are merged in (config tools win on a name clash), and every tool is withheld when the model's capability list is populated withouttoolsor the model uses a dedicated image-generation operation.- Held by
sdk/packages/core/src/runtime/orchestration/runtime-builder.ts:141-182(createBuiltinToolsList: mode presetsdk/packages/core/src/extensions/tools/presets.ts:20-128, model routingsdk/packages/core/src/extensions/tools/model-tool-routing.ts:60-134, policies and global disablessdk/packages/core/src/runtime/orchestration/runtime-builder.ts:71-99); provider-nativeweb_search(not in yolo) andimage_generation(sdk/packages/core/src/runtime/orchestration/runtime-builder.ts:419-439); MCP tools from settings and agent plugins (sdk/packages/core/src/runtime/orchestration/runtime-builder.ts:583-598, loader:207-312); configured agents and team tools (:655-815); final filter:817; per turn, extension tools merged and all tools dropped when the model's capability list lackstoolsor it uses dedicated image generation (sdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts:963-989; capability check fails open when the list is empty,sdk/packages/shared/src/llms/model-info.ts:231-241). VS Code swaps in its own terminal tool and MCP hub tools (apps/vscode/src/sdk/vscode-session-host.ts:120-160, not re-read).
B7 What does an @-mention pull into a VS Code message? RULE · code
- Answered how
After slash-command expansion, code replaces each recognised mention with a short label and appends its content: a URL is opened in a browser and converted to markdown; a file is inlined as text (binary files get a placeholder); a folder lists its entries and inlines its immediate non-binary files, without recursing;
@problemsadds workspace diagnostics,@terminalthe latest terminal output,@git-changesthe working-tree state, and a 7-40 character hex token that commit's info. A bare/is skipped; with several workspace roots an unprefixed path is looked up in all of them and every hit is included.- Held by
apps/vscode/src/core/mentions/index.ts:58-332(parseMentions: URLs fetched to markdown via a browser, files and folders inlined (one level, binaries skippedapps/vscode/src/core/mentions/index.ts:334-388),@problemsdiagnostics,@terminallatest output,@git-changes, commit hashes; bare/skippedapps/vscode/src/core/mentions/index.ts:117-123; multi-root search across all rootsapps/vscode/src/core/mentions/index.ts:153-209). Called fromapps/vscode/src/sdk/SdkController.ts:1194-1215, after slash-command expansion (:1195).
B8 What does a CLI @file mention attach (inline image, file attachment, or nothing)? RULE · code
- Answered how
After slash-command resolution, code finds
@mentions that start with/,~/,./or../(optionally quoted) and resolves each against the home directory for~/and against the process's working directory otherwise (so@/xis the filesystem path/x). An existing image file becomes a data-URL image and is replaced by[image: name]; any other existing file is replaced by[file: name]and attached by path, its text loaded later by the runtime's file loader; a missing path or a directory prints a warning and stays as typed.- Held by
apps/cli/src/runtime/prompt.ts:40-205(buildUserInputMessage:@/,@~/,@./,@../paths resolved byapps/cli/src/runtime/prompt.ts:77-82; images become data URLs, other files become attachments loaded later bybuildUserFileContentBlock,sdk/packages/core/src/runtime/orchestration/user-input-builder.ts:118-159).
B9 How does the model learn which mode each message was sent in? RULE · code
- Answered how
Code wraps each user message as
<user_input mode="...">with the mode it was sent in (default act), and, after a UI toggle, prepends a<mode_notice>to the next message saying which mode the person switched from and to; a toggle that returns to the starting mode before anything is sent cancels the notice. Outside yolo, the system prompt's mode-tag section tells the model how to read both tags and that the newest message's mode governs.- Held by
sdk/packages/shared/src/prompt/format.ts:5-10(formatUserInputBlock),sdk/packages/shared/src/prompt/format.ts:41-80(formatModeSwitchNotice,createModeSwitchNoticeTracker: a plan→act→plan round trip cancels; UI toggles only), explained to the model byMODE_TAG_INSTRUCTIONS(sdk/packages/shared/src/prompt/cline.ts:15-17, omitted in yolosdk/packages/shared/src/prompt/cline.ts:188-198).
B10 Which earlier file reads does the model see as "outdated" instead of their content? RULE · code
- Answered how
When building the provider request, code marks a successful
read/read_filesresult as outdated for a path or line range when a different read orfileblock is the last recorded full-content owner of that path, or a different read is the last one of that exact range; error results are never marked. Marked reads are only rewritten to "[outdated - see the latest file content]" once the newly stale content adds up to at least 64 KB (envCLINE_MESSAGE_BUILDER_MIN_OUTDATED_REWRITE_BYTES, 0 = eager), and a rollback that makes a read current again un-marks it.- Held by
sdk/packages/core/src/session/services/message-builder.ts:371-454(commitOutdatedRewrites: a read is outdated when a different read orfileblock is the last recorded full-content owner of its path, or a different read is the last one of that exact rangesdk/packages/core/src/session/services/message-builder.ts:933-946; rewrites are batched until 64 KB is reclaimablesdk/packages/core/src/session/services/message-builder.ts:38-40,:440-442); replacementsdk/packages/core/src/session/services/message-builder.ts:948-1005.
B11 Is a tool call that never got a result repaired before the transcript is sent? RULE · code
- Answered how
Yes, always, by code. When the request is built, every assistant
tool_usewith no matchingtool_resultanywhere in the history gets a synthesized error result "Tool execution was interrupted before a result was produced. Tool: <name>.", placed in the next tool-result message or in a new user message before the next non-tool turn. History migrated from the legacy VS Code extension gets a plain (not flagged as error) result reading "[migration] Tool result missing in legacy conversation history."- Held by
sdk/packages/core/src/session/services/message-builder.ts:538-747(addMissingToolResults: synthesizes anis_errortool result "Tool execution was interrupted..."sdk/packages/core/src/session/services/message-builder.ts:51-52,:726-747); VS Code legacy migration inserts a result with "[migration]" text and no error flag (apps/vscode/src/sdk/initial-message-sanitizer.ts:48-57).
B12 What prior transcript does the model see when a task is resumed? RULE · code
- Answered how
In VS Code, code reads the task's persisted SDK messages; for a task flagged as legacy it passes those to the legacy converter, which produces the seed, and otherwise seeds with the persisted messages as they are. The resumed session takes the task's original cwd but the current global Plan/Act mode. On every run the orchestrator then seeds the model with the whole stored conversation, which the message builder still rewrites per request (B10, B11).
- Held by
apps/vscode/src/sdk/sdk-task-resume.ts:42-71(persisted SDK messages; for a legacy task,getLegacyResumeInitialMessageswith those messages passed in,apps/vscode/src/sdk/sdk-task-resume.ts:54-64); per run the orchestrator seeds the whole stored transcript (sdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts:993-1001).
B13 After a checkpoint restore, which part of the conversation does the model keep? RULE · code
- Answered how
Code keeps every message up to and including the person's message that started the chosen run, dropping that run's replies and everything after, unless the caller sets
restoreMessages: false; the checkpoint used is the latest one recorded at or before that run. A run folded inside a compacted summary message cannot be targeted and the restore throws, except the last run the summary represents; a fork 'before' a run keeps only the messages before its user message.- Held by
sdk/packages/core/src/session/checkpoint-restore.ts:245-264(trimMessagesToCheckpoint,trimMessagesBeforeUserRun; run lookupsdk/packages/core/src/session/checkpoint-restore.ts:217-243) andsdk/packages/core/src/session/checkpoint-restore.ts:266-303(createCheckpointRestorePlan; checkpoint = latest at or before the run,:202-215).
B14 Which organization-managed rules, workflows and skills reach the session? RULE · code
- Answered how
When remote config is discovered for the organization and the org has not been opted out locally, code takes the org's rules, workflows and skills from it and drops each one the person has toggled off in their remote rule, workflow or skill toggles unless it is marked
alwaysEnabled(viaisInstructionEnabled); skills are carried as managed instructions rather than as part of the SDK remote config. With no org, no remote config, or an opt-out, none reach the session.- Held by
apps/vscode/src/core/storage/remote-config/sdk-control-plane.ts:202-222(org rules and workflows filtered by the person's remote toggles viaisInstructionEnabled; skills adapted to managed instructions and filtered by the remote skill toggles); returns nothing for no org, no config or opt-out (apps/vscode/src/core/storage/remote-config/sdk-control-plane.ts:179-191).
B15 What extra context do the person's hook scripts add to this turn? RULING · external
- Answered how
In VS Code, when
hooksEnabledis on and hook files exist, the person's scripts decide: before a run the TaskStart and UserPromptSubmit hooks run in turn, and any non-cancellingcontextModificationthey return is joined and appended to the turn as context; PreToolUse and PostToolUse hooks can likewise append context around each tool call. A hook that setscancelstops instead, and its text becomes the stop reason, never context. The CLI path goes through the core file-hook extension, not traced here.- Held by
the person's hook scripts (TaskStart, UserPromptSubmit, PreToolUse, PostToolUse), mapped at
apps/vscode/src/sdk/hooks-adapter.ts:58-75(mapStopOrContextResult: non-cancellingcontextModificationbecomesappendContext; scripts run byHookFactory); TaskStart + UserPromptSubmit context joined (apps/vscode/src/sdk/hooks-adapter.ts:131-145); tool hooksapps/vscode/src/sdk/hooks-adapter.ts:147-252. CLI uses the core file-hook extension (sdk/packages/core/src/services/local-runtime-bootstrap.ts:433-446; not read in detail).
B17 What does the model see of a user-attached file? RULE · code
- Answered how
Code builds the first user content as the message text, then one image block per attached image (a
data:URL keeps its media type; any other non-empty string is taken as raw base64 PNG), then one file block per attached path holding the text the runtime's loader returns, or "Error fetching content: ..." if loading fails. With no images and no files the message is sent as plain text.- Held by
sdk/packages/core/src/runtime/orchestration/user-input-builder.ts:10-37(buildInitialUserContent: text, then images, then file blocks); non-data-URL image strings are assumed PNG (sdk/packages/core/src/runtime/orchestration/user-input-builder.ts:110-115).
B18 Should the conversation (and workspace) roll back to this checkpoint? RULING · human
- Answered how
The person decides by choosing a checkpoint's restore action in VS Code, picking the restore type the webview offers; code forwards the checkpoint's run number and that type to the controller's SDK
restoreCheckpoint, and B13 carries it out. Nothing in the code initiates a rollback on its own.- Held by
the person, via the restore action (
apps/vscode/src/core/controller/checkpoints/checkpointRestore.ts:6-23, forwardingcheckpointRunCountandrestoreType; CLI equivalent not traced), carried out by B13.
C. Choosing the next action
C1 What should the agent do next: which tools, with which arguments, or answer and stop? RULING · llm
- Answered how
The session's main model answers it on every loop iteration: the runtime sends the system prompt, transcript and tool list, then processes the tool calls that come back and runs the eligible ones; a reply with no tool call ends the run as completed, unless a completion policy (set when
submit_and_exitis among the tools, or for agent teams) injects a reminder and loops again. When the model's info says it cannot call tools (or it is a dedicated image-generation model), the session sends no tools and drops the completion policy, so no completion reminder can keep the run going; the interruption, error and output-limit paths still apply.- Held by
the session's main model, called on each loop iteration in
sdk/packages/agents/src/agent-runtime.ts:836-1023(AgentRuntime.execute; request built byprepareModelRequest,sdk/packages/agents/src/agent-runtime.ts:1656-1736); runtime and tool list built per user turn atsdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts:948-1028. Sub-agents run the same loop.
C2 Is a streamed tool call well formed enough to become a call: does it have a name, and do its arguments parse? RULE · code
- Answered how
Code assembles streamed tool-call pieces per call id (or index) and, when the stream ends, drops any call with no tool name, recording it only in message metadata. A structured input from the adapter wins over text; empty argument text becomes
{}with no error and goes on through the normal checks; text thatJSON.parserejects becomes a call with input{}and a parse error, which the runtime turns into an error result before any hook or approval. In an interrupted turn every tool call is dropped (C10).- Held by
sdk/packages/agents/src/agent-runtime.ts:1877-1937(assembly per tool-call id or index), finalizesdk/packages/agents/src/agent-runtime.ts:2015-2057,parseToolInputandparseToolArguments(sdk/packages/agents/src/agent-runtime.ts:2814-2889); the AI SDK adapter emits whole calls (sdk/packages/llms/src/providers/ai-sdk.ts:1688-1709).
C3 When a provider streams a tool call's arguments in pieces, is each piece a continuation or a fresh copy of the whole? RULE · code
- Answered how
Code guesses from the piece's shape: if text has already arrived and the new piece (after leading whitespace) begins with
{or[, it replaces everything so far; otherwise it is appended. The first piece is always taken as is.- Held by
mergeToolInputText(sdk/packages/agents/src/agent-runtime.ts:2891-2900), called atsdk/packages/agents/src/agent-runtime.ts:1930-1935.
C4 Should a malformed tool payload be repaired, and into what? RULING · code
- Answered how
On the AI SDK route, when the SDK rejects a call's argument text, code tries a repair: straight
JSON.parse, thenjsonrepair(skipped when a string is left unterminated, the truncation guard), then a one-key bare-value repair; valid JSON that failed the schema, unknown tool names and empty text are not repaired. Separately, after the stream, the runtime parses JSON-looking strings where the tool's schema expects an array or object, andread_filesandrun_commandsaccept several input shapes and re-join split pieces.- Held by
sdk/packages/llms/src/providers/ai-sdk.ts:919-946(repairMalformedToolCall, wired asexperimental_repairToolCallatsdk/packages/llms/src/providers/ai-sdk.ts:2447), usingparseJsonStream(sdk/packages/shared/src/parse/json.ts:70-102; guardhasUnterminatedString:15-36; bare-object repair:38-68). Per-tool leniency on the same question:normalizeJsonLikeStringsForSchema(sdk/packages/shared/src/parse/json.ts:203-246, applied atsdk/packages/agents/src/agent-runtime.ts:2437);read_filesshapes (sdk/packages/core/src/extensions/tools/definitions.ts:286-319,sdk/packages/core/src/extensions/tools/helpers.ts:117-135);run_commandsshapes and heredoc re-join (sdk/packages/core/src/extensions/tools/helpers.ts:137-165,sdk/packages/core/src/extensions/tools/definitions.ts:116-178). No schema validation in the provider layer (commentai-sdk.ts:872-876).
C5 Should a failed model request be re-sent inside the provider layer (request start, mid-stream, empty reply)? RULING · code
- Answered how
Code re-sends inside the AI SDK call with fixed budgets: up to 5 retries of a failed request start, up to 3 retries of error parts after streaming began, and, outermost, up to 3 attempts when an attempt produced nothing at all and finished
stop,otherorunknownor its stream died on a network error before any output (each AI SDK vendor gets it unless its factory setsretryEmptyResponses: false; none in the checkout does). None of the numbers is a setting.- Held by
sdk/packages/llms/src/providers/ai-sdk.ts:2436-2476(streamTextoptions:maxRetries: MODEL_REQUEST_MAX_RETRIES, 5, andstreamRetries: MODEL_STREAM_MAX_RETRIES, 3, constants atsdk/packages/llms/src/providers/ai-sdk.ts:1096-1097), and the outermostwithEmptyResponseRetry(sdk/packages/llms/src/providers/ai-sdk.ts:2151-2166; middlewaresdk/packages/llms/src/providers/middleware/retry-empty-response.ts, default 3 attempts at:97).
C6 Should the agent loop retry a turn that failed with a provider error, and how long should it wait? RULING · code
- Answered how
Code retries the whole turn up to 3 times, waiting 1 s, 2 s, 4 s (cap 15 s), only when the turn finished with an error, produced no content and no provider tool activity, was not classed auth or context overflow, and was judged retryable: by the model boundary's own flag if it sent one, else by the classifier (the AI SDK's typed
isRetryable, else a transient HTTP status, else the one message "provider returned error").- Held by
sdk/packages/agents/src/agent-runtime.ts:1242-1314(withProviderErrorRetry,isRetryableProviderErrorTurn; constantssdk/packages/agents/src/agent-runtime.ts:87-91); retryability from the boundary'serrorRetryable, elseisRetryableProviderError(sdk/packages/llms/src/providers/error-classification.ts:425-437; statuses:319-321; message pattern:330,:409-412).
C7 A turn that ended with no recognized finish reason: continue it once, or fail? RULING · code
- Answered how
Code continues once: when a turn ends with finish reason
unknown, was not interrupted, and carried no tool calls and no provider tool activity, it records the partial reply, adds the fixed user-role line "Previous turn ended unexpectedly. Continue from where you left off." and re-issues the request. If that second attempt also endsunknownwith no tool call the run fails; anunknownturn that did carry tool calls runs them and fails only if none of them succeeded. The once is per loop iteration, not per run.- Held by
sdk/packages/agents/src/agent-runtime.ts:1202-1233(generateAssistantMessageWithProviderRetry; continuation literalsdk/packages/agents/src/agent-runtime.ts:1227-1230); failure checkssdk/packages/agents/src/agent-runtime.ts:920-923and:984-996.
C8 A turn cut off at the model's output-token limit with no tool call: nudge the model to be shorter and try again, or fail? RULING · code
- Answered how
Code first tries one forced compaction and retry per run (only when the runtime has a
prepareTurn, the turn has no tool calls and no provider tool activity); if the turn still ends at the output limit with no tool call, it appends a fixed "be concise" user message and loops, up to 3 consecutive times, the count resetting whenever a turn yields a tool call. After that the run fails.- Held by
sdk/packages/agents/src/agent-runtime.ts:1163-1183(recoverFromIncompleteMaxTokensTurn; limitMAX_TOKENS_RECOVERY_LIMITatsdk/packages/agents/src/agent-runtime.ts:72; counter reset:943-946; called at:925-938). The forced-compaction retry that runs first (sdk/packages/agents/src/agent-runtime.ts:1369-1371,:1427-1447) belongs to compaction, a separate seat.
C9 A turn that came back empty or content-filtered: what does the run say, and does it end? RULE · code
- Answered how
Code ends the run when a finished, uninterrupted turn has no content: finish
errorraises the recorded provider error (or "Model stream failed"), finishcontent-filterraises the content-filter message, anything else raises "Model returned empty response". Turns carrying only provider tool activity, or endingmax-tokensorunknown, are kept for C7/C8; an interrupted empty turn just loops.- Held by
sdk/packages/agents/src/agent-runtime.ts:866-899(empty-turn checks;CONTENT_FILTER_EMPTY_TURN_MESSAGEatsdk/packages/agents/src/agent-runtime.ts:98-99).
C10 When the person's new message interrupts a model reply mid-stream, what of the partial reply is kept? RULE · code
- Answered how
When a new message arrives mid-reply, code aborts only the model request. The partial reply keeps its visible text and media and loses all tool calls (even fully streamed ones) and reasoning; an empty partial is not recorded. The loop then starts the next request, which picks up the queued message at the request boundary; tools already running finish normally.
- Held by
sdk/packages/agents/src/agent-runtime.ts:632-635(notifyPendingUserMessage); partial-reply filtersdk/packages/agents/src/agent-runtime.ts:2012-2022; loopsdk/packages/agents/src/agent-runtime.ts:854-862,:906-916; queued message read atsdk/packages/agents/src/agent-runtime.ts:1687-1695,:2302-2321(queue policy is A13).
C11 Should a tool call the provider already executed (or marks provider-side) run again locally? RULE · code
- Answered how
Code never runs a provider-executed call locally: a streamed call that arrives with an
executionmarker is recorded as model tool activity, not queued; a queued call whose metadata saystoolSource.executionMode === "provider"gets an error result instead of running; and the provider-error retry, the unknown-finish continuation and the max-tokens compaction retry all refuse to replay a turn that had provider tool activity.- Held by
sdk/packages/agents/src/agent-runtime.ts:1878-1900(provider-executed calls kept asmodelToolActivities; emitted bysdk/packages/llms/src/providers/ai-sdk.ts:1672-1686); local refusalsdk/packages/agents/src/agent-runtime.ts:2422-2434; replay refusals:1214-1220,:1303-1306,:1444-1446.
E. Execution and observation
E1 Do the tool calls of one turn run one after another, or at the same time? RULE · code
- Answered how
Code prepares every call of the turn first, in order (hooks and approvals), then runs them one after another unless the tool or the runtime says
parallel, in which case adjacent parallel calls run together with no cap. The runtime isparallelonly whenmaxParallelToolCallsis set to 2 or more; no non-test code in the checkout sets it (and the schema carrying a default of 8 is used by no non-test code), so built-in tools run in sequence and only the sub-agent tools overlap.- Held by
sdk/packages/agents/src/agent-runtime.ts:2343-2381(executeToolCalls); runtime defaultsequentialatsdk/packages/agents/src/agent-runtime.ts:614-617; mode fromresolveToolExecution(sdk/packages/core/src/runtime/config/agent-runtime-config-builder.ts:187-198); sub-agent tools declareexecutionMode: "parallel"(sdk/packages/core/src/extensions/tools/team/spawn-agent-tool.ts:122,sdk/packages/core/src/extensions/tools/team/configured-agent-tool.ts:152).
E2 Are the commands inside one run_commands call run in order, or all at once? RULE · code
- Answered how
Code runs every command in one
run_commandscall at the same time (Promise.all), each from the same cwd, after re-joining a heredoc that the model split across array elements. Nothing orders them; whether they are independent is left to the model, which the description asks to batch only independent commands.- Held by
sdk/packages/core/src/extensions/tools/definitions.ts:180-257(executeShellCommands,Promise.all); heredoc re-joinsdk/packages/core/src/extensions/tools/definitions.ts:116-178.
E3 When is a running shell command stopped (CLI, hub and SDK hosts)? RULING · code
- Answered how
Code stops it on a 30 s timer or on abort, killing the whole process tree (taskkill /T /F on Windows, SIGKILL to the process group elsewhere). Neither the CLI nor the core runtime sets the timeout, so both the executor default and the tool wrapper's race stay at 30 s; a person can instead release a running command through a hub client's
proceedWhileRunning, which the CLI TUI does not offer.- Held by
sdk/packages/core/src/extensions/tools/executors/bash.ts:717-1118(spawnAndCollect: kill tree:773-817, timer:837-843, abort:820,:845-848); 30 s from the executor default (sdk/packages/core/src/extensions/tools/executors/bash.ts:1138) and the wrapper race (sdk/packages/core/src/extensions/tools/definitions.ts:515,:216-220); the core runtime passes only the execution controller (sdk/packages/core/src/runtime/orchestration/runtime-builder.ts:165-167).
E4 Did the shell command succeed, and has it finished? RULE · code
- Answered how
Code decides from the exit code alone: 0 resolves with the output, any other code (or a signal) rejects with the output attached. If the shell has exited but a background child still holds the pipes, it settles 1 s later with a trailing note; a spawn failure rejects; a command released to the background resolves at once with a log-path notice.
- Held by
sdk/packages/core/src/extensions/tools/executors/bash.ts:968-1027(completeCommand); exit-gracesdk/packages/core/src/extensions/tools/executors/bash.ts:1066-1096(EXIT_STREAM_GRACE_MS:52; comment cites #12417); spawn failure:1098-1108; detached early resolve:850-897.
E5 Which part of a long command output does the model see? RULING · code
- Answered how
Code keeps, per stream, the first half of a 48 000-character budget verbatim and rolls the rest so the newest output survives; at completion stdout and stderr are joined (stderr after a
[stderr]marker) and, if anything was dropped or the join is over budget, middle-truncated to about the first and last 24 000 characters with a notice. The early notice for a command released to the background joins both streams without that final cut.- Held by
sdk/packages/core/src/extensions/tools/executors/bash.ts:457-506(createRollingCollector), thentruncateCommandOutput(sdk/packages/core/src/extensions/tools/executors/output-limits.ts:20-38,MAX_COMMAND_OUTPUT_CHARS:18; called atsdk/packages/core/src/extensions/tools/executors/bash.ts:992-997,:1014-1022); streams combined at:985-991,:1010-1012.
E6 In VS Code, did a command run in the visible terminal succeed? RULE · code
- Answered how
In the default
vscodeTerminalmode, code reads the terminal's completion details: a terminal closed mid-command, or a completion it could not observe, is a failure (exit code 1, with a message telling the model not to assume success); a non-zero exit code from shell integration is a failure; an observed completion with no exit code returns the output as success. A command detached by the person or the 300 s timer returns partial output instead (E7, E8). InbackgroundExecmode the core executor decides (E4).- Held by
apps/vscode/src/sdk/vscode-run-commands-tool.ts:222-492(executeForeground: closedapps/vscode/src/sdk/vscode-run-commands-tool.ts:446-452, unobserved:454-465, non-zero exit:474-481, no exit code:467-473,:483); background modeapps/vscode/src/sdk/vscode-run-commands-tool.ts:562-591(E3/E4).
E7 Should the agent move on while a command is still running? (the person's "Proceed While Running") RULING · human
- Answered how
In VS Code foreground mode the person answers by clicking "Proceed While Running", which detaches every in-flight foreground command; if nobody clicks, code answers after 300 s (E8). The tool call then returns partial output and a log path while the command keeps running. Through the hub, a client's
proceedWhileRunningdetaches the core executor's commands for a session (or one tool call), and only those whose process identity probe succeeded are detachable; the CLI TUI has no such control.- Held by
the person, through the VS Code button (
apps/vscode/src/sdk/SdkController.ts:1605-1610→apps/vscode/src/sdk/sdk-foreground-command-coordinator.ts:63-73, handle registered per command atapps/vscode/src/sdk/vscode-run-commands-tool.ts:266-268), or a hub client callingproceedWhileRunning(sdk/packages/core/src/hub/server/handlers/run-handlers.ts:385-399→sdk/packages/core/src/extensions/tools/executors/run-command-execution-controller.ts:25-42; used by the desktop example, excluded).
E8 In VS Code, when does the agent stop waiting for a foreground command on its own? RULING · code
- Answered how
In VS Code foreground mode, code detaches the command after 300 s if the person has not, returning partial output and a log path while the command keeps running in the terminal; the wrapper's own race is raised to 60 minutes for that mode, so the 300 s timer normally answers first. A cancelled task sends Ctrl+C to the terminal instead.
- Held by
apps/vscode/src/sdk/vscode-run-commands-tool.ts:52(FOREGROUND_COMMAND_AUTO_PROCEED_MS, timer atapps/vscode/src/sdk/vscode-run-commands-tool.ts:269); wrapper race 60 min (VSCODE_FOREGROUND_RUN_COMMANDS_TIMEOUT_MS,apps/vscode/src/sdk/vscode-run-commands-tool.ts:49; set atapps/vscode/src/sdk/vscode-runtime-builder.ts:105). A VS Code terminal cannot be killed, so the command keeps running (comment:48).
E9 Is a tool call that runs past its time limit stopped, or only reported as failed? RULE · code
- Answered how
Only reported, for most tools: each built-in tool except
ask_question(no timer at all) wraps its executor inwithTimeout, aPromise.racewhose timer rejects but never cancels the work, so the model gets a timed-out failure while the operation may still finish. Only the shell executor kills on its own timer (E3); web fetch aborts on its own timer only until response headers arrive, after which the body read has no executor timer; the editor and apply_patch executors have no timer and never check the abort signal, so a timed-out write can still land.- Held by
sdk/packages/core/src/extensions/tools/helpers.ts:48-59(withTimeout), used byread_files(sdk/packages/core/src/extensions/tools/definitions.ts:333-337),search_codebase(:395-399),run_commands(:216-220),fetch_web_content(:593-597),apply_patch(:682-686),editor(:745-749),skills(:797-805) andsubmit_and_exit(:877-881). Own timers: shell (E3); web fetchsdk/packages/core/src/extensions/tools/executors/web-fetch.ts:130-132, cleared at:155. No timer or signal check:sdk/packages/core/src/extensions/tools/executors/editor.ts:230-267,sdk/packages/core/src/extensions/tools/executors/apply-patch.ts:404-425.
E10 How is an editor edit applied to the file? RULE · code
- Answered how
Code: with
insert_line, the new text is inserted at that one-based line boundary; otherwise a missing file is created withnew_text(whateverold_textsays), an existing file with noold_textis refused, andold_textmust occur exactly once after line-ending normalization or nothing is written. Texts over the size limit are refused before the executor runs. A relative path is checked by path arithmetic to stay inside the cwd; absolute paths are accepted anywhere. In VS Code a read-only diff preview is shown around the same SDK write.- Held by
sdk/packages/core/src/extensions/tools/executors/editor.ts:221-268(createEditorExecutor: insertsdk/packages/core/src/extensions/tools/executors/editor.ts:194-216, create:246-248, no-old_textrefusal:249-258, exact-once replace:162-192); size guardsdk/packages/core/src/extensions/tools/helpers.ts:20-33. VS Code previewapps/vscode/src/sdk/sdk-diff-edit-coordinator.ts:59-144(write is always the SDK executor,:65-67,:131).
E11 Where does an apply_patch hunk land when its context does not match the file exactly? RULING · code
- Answered how
Code searches from the parser's current position (after the previous hunk), not from the file top: a canonicalized match, then trailing-space-trimmed (fuzz 1), then fully trimmed (fuzz 100), then the FIRST position whose Levenshtein similarity reaches 0.66 (fuzz 1000), not the best one; an end-of-file hunk first tries the file's tail and adds 10000 if it must fall back. At that position the hunk's old lines are replaced by count, without comparing them. A hunk that matches nowhere fails the whole patch; a fuzzy match reports success with a fuzz number.
- Held by
sdk/packages/core/src/extensions/tools/executors/apply-patch-parser.ts:347-431(findContext; thresholdsdk/packages/core/src/extensions/tools/executors/apply-patch-parser.ts:404-412, end-of-file branch:421-428);applyChunksreplacesdelLines.lengthlines unchecked (sdk/packages/core/src/extensions/tools/executors/apply-patch.ts:162-193); unmatched hunk fails the patch (sdk/packages/core/src/extensions/tools/executors/apply-patch.ts:389-391).
E12 What does the model see when it reads a file? RULE · code
- Answered how
Code: a
.gif/.png/.jpg/.jpeg/.webpfile becomes an image part when the model accepts images (else an error; images over 10 MB refuse); any other file over 100 MB refuses; everything else streams as UTF-8 text in a window of at most 2 000 lines and 48 000 characters, long lines cut at 2 000 characters, with a "Showing lines a-b of n" footer when more remains.cline://paths read the oversized-result cache. There is no binary detection.- Held by
sdk/packages/core/src/extensions/tools/executors/file-read.ts:208-285(createFileReadExecutor: imagessdk/packages/core/src/extensions/tools/executors/file-read.ts:248-269, 100 MB refusal:271-276,cline://cache:218-230); text windowreadTextWindow(sdk/packages/core/src/extensions/tools/executors/file-read.ts:82-193). The tool description says binaries are not supported (sdk/packages/core/src/extensions/tools/definitions.ts:280).
E15 Who answers the agent's clarifying question (ask_question)? RULING · human
- Answered how
The person answers, through the host's prompt: in VS Code
handleAskQuestion; in the interactive CLI the TUI's prompt handler; in one-shot CLI a terminal readline that takes an option number or free text. Code answers instead in two CLI cases, with the first option and no notice to the model: when stdin or stdout is not a TTY, and when the interactive TUI has no prompt handler mounted; an empty reply at the terminal prompt also yields the first option. The tool is absent whensubmit_and_exitis enabled (yolo).- Held by
the person: VS Code
apps/vscode/src/sdk/SdkController.ts:425(handleAskQuestion); CLI interactive TUIapps/cli/src/runtime/interactive/session-runtime.ts:171-176; CLI one-shot terminal promptapps/cli/src/utils/approval.ts:120-164(wired atapps/cli/src/runtime/run-agent.ts:167). Tool defined atsdk/packages/core/src/extensions/tools/definitions.ts:831-850; removed wheneversubmit_and_exitis on (sdk/packages/core/src/extensions/tools/definitions.ts:981-986).
E16 What does the model see when a tool throws, does not exist, was refused, or was blocked? RULE · code
- Answered how
Code turns every non-run into an error result the model sees: a skip reason (invalid JSON arguments, provider-side tool, a hook's skip, a policy-disabled tool, or a refused approval, which carries the suffix "NOT a tool or system failure. Clarify with user before proceeding.") becomes
{ error }; an unknown name becomes "Unknown tool: <name>"; a thrown error becomes its message. A tool that needs approval with no approval callback configured, or whose callback throws, counts as refused. An afterTool hook may still replace the result (E17).- Held by
sdk/packages/agents/src/agent-runtime.ts:2543-2647(executePreparedTool: skipsdk/packages/agents/src/agent-runtime.ts:2555-2559, unknown name:2560-2564, thrown error:2588-2595); skip reasons set inprepareToolExecution(sdk/packages/agents/src/agent-runtime.ts:2405-2501;TOOL_REJECTION_SUFFIXatsdk/packages/shared/src/llms/tools.ts:104-105); no-callback and throwing-callback refusalssdk/packages/agents/src/agent-runtime.ts:2509-2514,:2533-2540(the gate itself is a separate seat).
E17 Can a hook or plugin rewrite or add to what the model sees from a tool? (PostToolUse / afterTool) RULING · external
- Answered how
Partly, and it depends on who wrote the hook. The person's PostToolUse hook files (VS Code adapter, core hook-file hooks) can only add a context block or stop the run; their mappers return
stop,reasonorappendContextand neverresult. An in-process SDK plugin or extensionafterToolhook can do that and also REPLACE the tool result. All run after every call to a known tool (not after an unknown tool name), and only when such hooks exist (in VS Code, also when hooks are enabled).- Held by
afterTool hooks, called after every tool in
sdk/packages/agents/src/agent-runtime.ts:2601-2625(appendContextqueued:2613-2620; a returnedresultreplaces the tool result:2622-2624); merged from config and extension hooks atsdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts:1152-1178and:266-281. The person's hook files map to stop/context only: VS Codeapps/vscode/src/sdk/hooks-adapter.ts:199-252; coresdk/packages/core/src/hooks/hook-file-hooks.ts:1043-1047viastopOrContextResultFromControl(sdk/packages/core/src/hooks/hook-file-hooks.ts:610-627).
E18 When does an MCP tool call give up, and what comes back? RULE · code
- Answered how
Code gives up when the MCP client's request timeout passes: the server's configured
timeoutin seconds (clamped to 1-3600), else 60 s; the error is rewritten to name the server and becomes an error result. The built-in toolwithTimeoutrace does not wrap MCP tools. Arguments that are not a plain object are dropped, and the server receives{}.- Held by
sdk/packages/core/src/extensions/mcp/client.ts:874-895(callToolwithtimeout: this.requestTimeoutMs, set atsdk/packages/core/src/extensions/mcp/client.ts:235-237fromresolveMcpRequestTimeoutMs,sdk/packages/core/src/extensions/mcp/timeout.ts:7-9; default 60 s atsdk/packages/shared/src/mcp.ts:10,:33-38; per-servertimeoutfieldsdk/packages/core/src/extensions/mcp/config-loader.ts:93,:101); non-object arguments sent asundefined(sdk/packages/core/src/extensions/mcp/tools.ts:41-44), then{}(client.ts:884). VS Code routes MCP through its own hub (vscode-session-host.ts:150, not read).
F. Limits and memory
F1 How many consecutive failing turns does a run tolerate before the limit fires? RULING · code
- Answered how
At the end of each turn code counts the turn as a mistake only when at least one tool call failed and none succeeded; any turn with a successful tool resets the count, and a text-only turn neither counts nor resets. When the count reaches
execution.maxConsecutiveMistakes(core default 6; CLI default 3 or--retries), the limit fires; a limit of 0 means it never fires (if (!max || next < max)).- Held by
sdk/packages/core/src/runtime/safety/mistake-tracker.ts:88-150(MistakeTracker.record), fed bysdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts:1362-1383(a turn counts as a mistake only when at least one tool failed AND none succeeded; any successful tool resets the count,:1378-1382). Limitconfig.execution.maxConsecutiveMistakes ?? 6(session-runtime-orchestrator.ts:471); CLI default 3 (apps/cli/src/runtime/defaults.ts:15, appliedapps/cli/src/main.ts:1073-1074, flag--retriesapps/cli/src/commands/program.ts:64-65). VS Code sets no value, so 6 (grep ofapps/vscode/srcformaxConsecutiveMistakes: 0 non-test hits).
F2 When the mistake limit is reached, does the run stop or continue? (VS Code, yolo CLI, non-TTY CLI, sub-agents, scheduled runs) RULING · code
- Answered how
Code decides by host. VS Code's handler always returns
stopafter posting an error row. The CLI one-shot and the TUI both returnstopwhenever the*tool policy is notautoApprove: false, which is the CLI default (apps/cli/src/main.ts:885-895; overridden only by--auto-approve falseor a persistedtoolAutoApprove); the one-shot also stops without a TTY. With no callback at all (sub-agents, teammates, hub runs whose client contributed none) the tracker stops.- Held by
VS Code always stops and asks the person to send a message (
apps/vscode/src/sdk/sdk-interaction-coordinator.ts:96-116, wiredapps/vscode/src/sdk/SdkController.ts:391); CLI one-shot stops in yolo (apps/cli/src/runtime/format.ts:30-36) or without a TTY (format.ts:41-46); CLI interactive stops in yolo (apps/cli/src/runtime/interactive/mistakes.ts:16-21); no callback configured → stop (mistake-tracker.ts:206-211), which is the path for sub-agents (delegated-agent.ts:129-146passes no callback) and hub/cron runs unless a client contributes one (sdk/packages/core/src/hub/runtime-host/hub-runtime-host.ts:357-358).
F3 When the mistake limit is reached, does the run stop or continue? (interactive CLI with a person present) RULING · human
- Answered how
Absent by default: the person is asked only when the CLI's
*tool policy has auto-approve off (--auto-approve falseor a persisted setting); otherwise code stops first (F2). When asked, "Stop this run" / "2" / "stop" / "n" / "no" stops, "Try a different approach" / "1" / an empty answer continues with a fixed guidance line, and any other text continues with that text appended as a user message; if the TUI ask is not wired the first option is chosen and the run continues.- Held by
the person answers "Try a different approach" / "Stop this run" or types guidance (
apps/cli/src/runtime/interactive/mistakes.ts:22-58, TUI askapps/cli/src/runtime/run-interactive.ts:270-273; one-shot TTYapps/cli/src/runtime/format.ts:47-78). Typed text becomes a user message (mistake-tracker.ts:129-135).
F4 Is the model repeating the same tool call, and when does repetition stop the run? RULING · code
- Answered how
On every
tool-startedevent (except calls carrying anexecutionfield), code compares the tool name and key-sorted JSON input with the previous call; the 3rd identical call in a row appends a user-role "try a different approach" notice, and the 5th or later forces the mistake count to the limit, which then goes to the F2/F3 decision. On unlessexecution.loopDetectionis exactlyfalse; an unset value uses the 3/5 defaults.- Held by
sdk/packages/core/src/runtime/safety/loop-detection.ts:66-87(checkRepeatedToolCall: identical name and key-sorted JSON input, consecutive), thresholds soft 3 / hard 5 (:113-116; CLI the same,apps/cli/src/runtime/defaults.ts:6-9); applied atsession-runtime-orchestrator.ts:1465-1495(soft → a user-role notice; hard → a forced mistake at the limit,forceAtLimit, which then goes through F2/F3).
F5 Is there an iteration or wall-clock cap on a run? RULING · code
- Answered how
Code loops while
config.maxIterationsis undefined or not yet reached and raises "exceeded maxIterations" when it is; VS Code passesundefinedand the CLI one-shot and TUI set none, so those runs have no iteration cap. A wall-clock cap exists only where a caller sets one: CLI--timeout(a positivetimeoutSecondsarms an abort) and a schedule's optionaltimeoutSeconds; a schedule'smaxIterationsis passed through only when set.- Held by
sdk/packages/agents/src/agent-runtime.ts:836-839(loop whilemaxIterationsundefined or not reached; exceeded → raises:1025-1027). VS Code passesmaxIterations: undefined(apps/vscode/src/sdk/cline-session-factory.ts:1206); the CLI one-shot and interactive paths set none (grep ofapps/cli/srcformaxIterations: schedule wizard only); CLI--timeoutaborts a one-shot (apps/cli/src/runtime/run-agent.ts:320-331); cronspec.maxIterationsandspec.timeoutSeconds(sdk/packages/core/src/cron/runner/cron-runner.ts:373-390,:743), both optional.
F6 Should the conversation be compacted before this request, and to what size? RULING · code
- Answered how
Only when
compaction.enabled === true(VS Code: per-task, else globaluseAutoCondense, default true; CLI: on unless the compaction mode isoff), code estimates the request's tokens before each model call and compacts when they reach 0.9 of the model's input limit (128 000 when the model reports none), shrinking the limit by the provider's last real count when the char estimate under-counts (at most 4x). The auto target is 0.7 of the trigger, or 0.5 of the input limit once there are 5+ user/assistant pairs and the model reports an output cap below that limit; overflow recovery and manual compaction use their own targets.- Held by
sdk/packages/core/src/extensions/context/compaction.ts:303-409(trigger at 0.9 of the effective input limit:355-362,compaction-shared.ts:19; default limit 128 000 when the model reports nonecompaction.ts:324-328,compaction-shared.ts:15; the char estimate scaled by the provider's last real count, capped at 4x:342-354; target 0.7 of trigger or 0.5 of the window for long conversations:210-228). Present only whencompaction.enabled === true(:291-293): VS Code fromuseAutoCondense(default true,apps/vscode/src/shared/storage/state-keys.ts:281, readcline-session-factory.ts:1115-1118,:1193-1200); CLI on by default (apps/cli/src/utils/compaction-mode.ts:33-43),offavailable.
F7 What does the compacted history keep? (agentic strategy: the LLM summary) RULING · llm
- Answered how
When F6 fires with the agentic strategy (the default), code cuts the history so the most recent ~20 000 estimated tokens stay verbatim, and so does the latest typed prompt unless it is the first message, then one LLM call (the session's model, or
compaction.summarizer's, with thinking off) writes a summary, folded onto any previous summary. Whatever non-empty text comes back replaces the cut-away messages as a user-role "Context summary", with a## Filessection appended if the text has none; an empty reply skips compaction.- Held by
sdk/packages/core/src/extensions/context/agentic-compaction.ts:116-318(runAgenticCompaction); the callgenerateSummarysdk/packages/core/src/extensions/context/agentic-compaction.ts:70-106; model = the session's model unlesscompaction.summarizernames another (sdk/packages/core/src/extensions/context/compaction-shared.ts:737-775), thinking off; output cap = an explicitmaxOutputTokensas-is, else the lower of 8 192 and the model's reportedmaxTokens, and none foropenai-codex(sdk/packages/core/src/extensions/context/compaction-shared.ts:34,:721-755). Cut pointfindCutIndexkeeps ~20 000 recent tokens and never cuts away the latest typed prompt unless it is the first message (sdk/packages/core/src/extensions/context/compaction-shared.ts:352-385).
F8 What does the compacted history keep? (basic strategy: truncation) RULING · code
- Answered how
When the basic strategy is chosen, or forced during overflow recovery, or used as the agentic fallback, code selects every typed user prompt (attachments only on the latest), keeps earlier compaction output untouched, then fills the token target with the newest messages after the latest prompt (snapped forward to an assistant message so no tool pair splits), then each older turn's final non-tool assistant answer, newest first, if it fits; everything else is dropped and summarised mechanically. A final budget pass can still trim what was selected.
- Held by
sdk/packages/core/src/extensions/context/basic-compaction.ts:452onward (runBasicCompaction): every typed user prompt kept (:472-498), the newest messages after the latest prompt that fit (:513-548), each older turn's final assistant answer when it fits (:550-), earlier compaction output frozen (:500-511); the last 3 assistant texts survive inside dropped-work summaries (:59-61).
F9 When a request overflows the context window or the reply hits the output-token limit, is it retried, and how? RULING · code
- Answered how
Code, once per run each: a provider error classed
context_window_exceededon a turn with no tool calls forces a compaction and one retry (with noprepareTurnconfigured it raises at once, and a second overflow raises); a text-only turn cut at the output-token limit gets one forced-compaction retry whenprepareTurnexists. After that, a text-only cut-off turn gets up to 3 consecutive "be concise" nudges, the count resetting on any turn with a tool call, and then the run raises with the partial answer kept.- Held by
sdk/packages/agents/src/agent-runtime.ts:1363-1408(overflow: one forced compaction and retry per run; failure raisesContextWindowOverflowError),:1427-1447and:1481-1595(text-only truncated turn: one compaction retry),:1163-1183(then up to 3 "be concise" nudges,MAX_TOKENS_RECOVERY_LIMIT:72),:925-938(exhausted → raises with the partial answer kept).
F10 Is a failed model request retried? RULING · code
- Answered how
Code retries a turn up to 3 times (4 requests), waiting 1 s, 2 s, 4 s (cap 15 s), only when the attempt finished
errorwith no content and no provider-side tool activity, the error is not classed auth or context overflow, and the error is flagged retryable (the model boundary's typed flag, else a message classifier). An uninterrupted turn with an unknown finish reason and no tool activity gets one "continue from where you left off" continuation; every other turn goes back to the loop unchanged, which raises on a turn stillerrorafter retries or still unknown with no tool call (agent-runtime.ts:920-923,:939-942) and otherwise handles it normally.- Held by
sdk/packages/agents/src/agent-runtime.ts:1242-1314(withProviderErrorRetry,isRetryableProviderErrorTurn): up to 3 retries (:87), backoff 1 s doubling to 15 s (:89-91), only when the failed attempt produced nothing and ran no provider-side tool, never for auth or overflow errors; retryability from the provider's typed flag, elseisRetryableProviderErroron the message (:2000-2004). An unknown finish with no tool activity gets one continuation prompt (:1212-1232).
F11 How much of a tool result, attachment or long assistant text is sent back to the model? RULING · code
- Answered how
Code, every time a request is built: each text entry or string inside a tool result over 8 000 chars, user file attachment over 50 000, or assistant text over 200 000 is cut in the middle (head and tail kept, a marker in between), and if the messages' counted text (text, thinking, file content, tool arguments and tool-result strings; images not counted) still exceeds 6 MB a budget pass truncates further. For tools marked
cache-oversized(MCP and Composio tools) an oversized result is still middle-truncated, plus, only when a cache URI exists (the cache refuses a result over 16 MB) and the notice fits under half the total budget, a notice naming that URI, which the model can read withread_files. Three of the limits can be overridden byCLINE_MESSAGE_BUILDER_*environment variables.- Held by
sdk/packages/core/src/session/services/message-builder.ts:29-43(tool result 8 000 chars, attachment 50 000, assistant text 200 000, repeated tool-call markup 12 000 after 8 repeats, total 6 MB), middle truncation:1100-1197, total-budget pass:1199-; cacheable tools can get a cache URI notice (:260-280,session-runtime-orchestrator.ts:441-444). Env overridesMESSAGE_BUILDER_LIMIT_ENV(message-builder.ts:44-48).
F12 Should a restorable snapshot of the workspace be taken before this user turn? RULE · code
- Answered how
Only when
checkpoint.enabled === true(CLI and VS Code on by default, core off): before the first model call of each root-agent run, code takes a snapshot when the run brings a new user turn or that turn number has no checkpoint in the session's history yet. A host-suppliedcreateCheckpointreplaces the built-in one; otherwise, in a git repo, a stash-style commit of the worktree is stored underrefs/cline/checkpoints/<session>/<run>, a clean tree records HEAD, and a non-repo gets none.- Held by
sdk/packages/core/src/hooks/checkpoint-hooks.ts:658-708(beforeModel, root agent, first iteration, only when the run introduces a user turn or that turn has no checkpoint yet), snapshot:535-649(stash commit underrefs/cline/checkpoints/<session>/<run>; a clean tree records HEAD; not a git repo → none). Present whencheckpoint.enabled === true(sdk/packages/core/src/services/local-runtime-bootstrap.ts:578-583): CLI on (apps/cli/src/runtime/defaults.ts:22-24), VS CodeenableCheckpointsSettingdefault true (cline-session-factory.ts:1117,:1188-1190), core off by default (defaults.ts:19-20comment).
F13 Which earlier tool results stay cached for later reads after truncation? RULING · code
- Answered how
Code caches a tool's full result only when the tool declares
resultPolicy: "cache-oversized"(MCP and Composio tools) and its text preview exceeds the tool-result cap (8 000 chars by default). The cache is per session, 16 MiB in all with oldest-first eviction, drops an entry after 5 iterations without an explicit read, and is cleared at a conversation boundary.- Held by
sdk/packages/core/src/session/services/tool-result-cache.ts:17-98(ToolResultCache: 16 MiB cap:5, idle eviction after 5 iterations:6,:75-84); filled by theafterToolwrappersdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts:1161-1178; which tools:resultPolicy === "cache-oversized"(sdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts:1002-1006; set bysdk/packages/core/src/extensions/mcp/tools.ts:31andsdk/packages/core/src/extensions/composio/composio-tools-extension.ts:176); URI lookupsdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts:441-444.
G. Judging the result
G1 Is the task done? (act and plan mode) RULING · llm
- Answered how
The main model decides by replying without a tool call. Code then finishes the run
completedwith that reply as the answer, unless the completion policy yields reminder messages (a required completion tool, G2, or the team guard, G3), in which case the reminders are appended and the loop continues. A cut-off or unknown-finish reply goes to the error or recovery paths instead (F9, F10); a content-filtered reply that has text and no tool call completes like any other; nothing checks whether the work is done.- Held by
the session's main model, by replying without a tool call; code accepts that turn as
completed(sdk/packages/agents/src/agent-runtime.ts:949-971) unless a completion policy adds reminders (:956-963).
G2 Is the task done and verified? (yolo, headless and scheduled runs: submit_and_exit) RULING · llm
- Answered how
Where the tool list includes
submit_and_exit(yolo preset, and only when the host supplies asubmitexecutor), the main model decides by calling it with a summary (10+ chars) and averifiedboolean. Code ends the runcompletedas soon as that call's result is not an error, even if other tool calls in the same turn failed; both executors read (CLI and hub schedules) return a non-error result whateververifiedsays. Every no-tool turn that reaches completion handling (not interrupted, empty, failed, cut off or of unknown finish) instead gets the "not complete until you call" reminder and the loop continues, with no counter.- Held by
the main model calling
submit_and_exit(sdk/packages/core/src/extensions/tools/definitions.ts:852-884,lifecycle.completesRun), registered by the yolo preset only (presets.ts:98-110); when present the runtime requires a completion tool (runtime-builder.ts:817-822,:855-864) and re-prompts after every no-tool turn (agent-runtime.ts:754-762,:956-963). Run ends when the tool's result is not an error (agent-runtime.ts:1005-1022,:2383-2403).
G3 Has the team finished its work? (team completion guard) RULING · code
- Answered how
Only when agent teams are enabled (CLI act/plan by default,
enableAgentTeams: !isYoloModeatapps/cli/src/main.ts:1092; off in VS Code and ACP): after every lead turn with no tool call, code lists the team's tasks and runs, and if any task ispending/in_progressor any run isqueued/runningit appends a "[SYSTEM] You still have team obligations ... Do NOT stop" reminder and the lead continues; otherwise the turn may complete. The guard reads task and run statuses only; whoever marked the task decided it is done.- Held by
sdk/packages/core/src/runtime/orchestration/runtime-builder.ts:823-854(teamCompletionGuard: any taskpending/in_progressor any runqueued/running→ a reminder and the lead continues), consumed atagent-runtime.ts:764-769,:956-963.
G4 Did a CLI one-shot run succeed? (exit code) RULE · code
- Answered how
Code maps the run's finish reason to the process exit code:
completed→ 0; any other non-aborted reason → 1 with the error text;aborted(or a local abort request) → 1 only when the--timeoutfired, otherwise the code stays 0 and the CLI prints "aborted" for a local abort or "aborted by another client" for anything else, which is what a mistake-limit or loop-detector stop produces. A thrown error → 1.- Held by
apps/cli/src/runtime/run-agent.ts:382-423:aborted→ exit code set to 1 only on timeout (:383-385), otherwise the code stays 0 from:147and the text "aborted by another client" is printed (format.ts:4-15);!== completed→ 1 (:401-412);completed→ 0 (:423).
G5 Did a scheduled run succeed? RULE · code
- Answered how
Code: when the hub's turn resolves, a finish reason of
errorbecomes a thrown error and the run is recordedfailed; any other finish reason (completed,aborted) recordsstatus: "done", telemetry outcomesuccess, and publishesschedule.execution.completed. A thrown error or the schedule's own timeout (the cron runner's abort signal) recordsfailed(telemetry outcomefailedortimeout), a cancellation recordscancelled, and both publishschedule.execution.failed; that report file carries the error and its context instead of the final text.- Held by
sdk/packages/core/src/cron/runner/cron-runner.ts:440-491(finishReason === "error"→ failed:445-447; everything else →status: "done", outcomesuccess,schedule.execution.completedpublished); catch path:492-553.
G6 Is a sub-agent's result good enough to use? RULING · llm
- Answered how
Where
spawn_agentexists (CLI act/plan by default; not in VS Code, which setsenableSpawnAgent: false, nor in CLI yolo mode), the parent model judges the result: the tool returns{ text, iterations, finishReason, usage }as a normal, non-error tool result for every finish, so a sub-agent that failed on a provider error comes back withfinishReason: "error"and the error message astext, and one stopped by its mistake limit comes backaborted. Only a thrown exception becomes a tool error.- Held by
the parent model reading the
spawn_agentoutput{ text, iterations, finishReason, usage }(sdk/packages/core/src/extensions/tools/team/spawn-agent-tool.ts:159-183). A sub-agent stopped by the mistake limit returns normally withfinishReason: "aborted"; only a thrown error becomes a tool error (:184-199).
G7 Is a teammate's outcome fragment acceptable? (team review) RULING · llm
- Answered how
Only in agent teams (G3's condition): any team member holding the management tools, the lead or any teammate, calls
team_review_outcome_fragmentwith a fragment id andapproved; code sets the fragment toreviewedorrejectedand records the caller as reviewer, with no criteria, no check that the reviewer is not the fragment's author, and no guard against re-reviewing a fragment already reviewed.- Held by
whichever team agent calls
team_review_outcome_fragmentwithapproved(sdk/packages/core/src/extensions/tools/team/team-tools.ts:801-825); stored byreviewOutcomeFragment(multi-agent.ts:1713-1728).
G8 May a team outcome be finalized? RULE · code
- Answered how
Code: when a team agent asks to finalize an outcome, every one of the outcome's required sections must have at least one fragment whose status is
reviewed; otherwise it raises naming the first missing section, and on success the outcome is markedfinalized. Rejected or draft fragments beside a reviewed one do not block it.- Held by
sdk/packages/core/src/extensions/tools/team/multi-agent.ts:1736-1760(finalizeOutcome: every required section needs at least onereviewedfragment).
H. Delegation
H1 Should this work go to a sub-agent, and with what instructions? RULING · llm
- Answered how
Where
spawn_agentis registered (enableSpawnAgent: CLI act/plan by default, off in VS Code and in CLI yolo mode), the main model decides when to delegate and writes both the sub-agent's system prompt and its task as free strings; code accepts any strings. For the Cline provider the written prompt becomes theoverridePromptof the Cline system prompt; for any other provider it is the sub-agent's base system prompt.- Held by
the main model calling
spawn_agent(sdk/packages/core/src/extensions/tools/team/spawn-agent-tool.ts:117-204), built for sessions bycreateSessionSpawnTool(sdk/packages/core/src/runtime/host/local/spawn-tool.ts:121-188) and registered atruntime-builder.ts:802-811.
H2 Which configured sub-agent should take this task? RULING · llm
- Answered how
Only when spawning is enabled and the person has configured at least one agent: the main model picks one of the
subagent_<name>tools, each described asUse the "<name>" subagent: <description>, and sends a non-empty prompt. Code then runs that agent's ownsystemPromptwith its configured provider, model and iteration cap (falling back to the parent's), with built-in tools filtered for that agent.- Held by
the main model choosing among
subagent_<name>tools (sdk/packages/core/src/extensions/tools/team/configured-agent-tool.ts:145-247), one per configured agent, registered atsdk/packages/core/src/runtime/orchestration/runtime-builder.ts:655-693.
H3 What tools and approval posture does a sub-agent get? RULE · code
- Answered how
Code: a
spawn_agentsub-agent gets the built-in tools of the parent's mode preset (plus its ownspawn_agentwhen spawning is on, minus disabled tools, no MCP tools); a configured agent gets built-in tools filtered for it. Neither receives tool policies or an approval callback, and the runtime asks only when a policy saysautoApprove === false, so every tool the sub-agent calls runs without asking the person, unless an inheritedbeforeToolhook (such as the plan-mode command guard) blocks it.- Held by
sdk/packages/core/src/runtime/host/local/spawn-tool.ts:132-147(built-in tools of the parent's mode preset, plus anotherspawn_agentwhen spawning is on, minus globally disabled tools; no MCP tools),sdk/packages/core/src/runtime/host/local/spawn-tool.ts:149-187(notoolPolicies, norequestToolApprovalpassed); configured agents:sdk/packages/core/src/extensions/tools/team/configured-agent-tool.ts:160-175with the comment "child tools run autonomously ... Do not inherit approval policy" (:163-164); the runtime asks for approval only when a policy saysautoApprove === false(sdk/packages/agents/src/agent-runtime.ts:2476-2492,resolveToolPolicy:216-224), so with no policy every tool runs. Extensions and hooks are inherited (sdk/packages/core/src/runtime/orchestration/runtime-builder.ts:632-654), including the plan-mode command guard (:553-566).
H4 What does a sub-agent know of the parent's conversation? RULE · code
- Answered how
Code gives the sub-agent a fresh session with no copy of the parent's conversation: its only input is the
taskstring the parent model wrote (for a configured agent, thepromptstring), under the system prompt from H1/H2. Project rules reach it through the inherited user-instruction extension, not through the parent's history.- Held by
sdk/packages/core/src/extensions/tools/team/spawn-agent-tool.ts:159(subAgent.run(input.task): only the task text; a freshSessionRuntime,sdk/packages/core/src/extensions/tools/team/delegated-agent.ts:149-158); rules arrive through the inherited user-instruction extension (sdk/packages/core/src/runtime/orchestration/runtime-builder.ts:559-566).
H5 How should the team's work be split, assigned and marked done? (agent teams) RULING · llm
- Answered how
Only in agent teams (CLI act/plan by default; off in VS Code, ACP and CLI yolo mode): the lead model alone decides who joins the team (spawn, shutdown and cleanup check for the lead role), while the lead and every teammate model can create, claim, complete or block tasks and route work to a teammate, since those tools carry no role check. Code marks a task
completedfor whoever calls complete with a non-empty summary, assignee or not, and ablockedtask no longer counts as unfinished for G3.- Held by
the lead model through
team_spawn_teammate(lead only,sdk/packages/core/src/extensions/tools/team/team-tools.ts:304-345), and the lead or any teammate model throughteam_taskcreate/claim/complete/block (sdk/packages/core/src/extensions/tools/team/team-tools.ts:394-488) andteam_run_tasksync or async (sdk/packages/core/src/extensions/tools/team/team-tools.ts:495-), none of which checks the caller's role; teammates are themselves delegated agents (sdk/packages/core/src/extensions/tools/team/delegated-agent.ts:124-127,buildTeammateSystemPromptsdk/packages/core/src/extensions/tools/team/subagent-prompts.ts:4-21).
I. Learning and feedback
I1 What should the agent learn from the person's rejection of a tool call? RULING · human
- Answered how
Only in VS Code and only when the person is actually asked (the tool's policy is not auto-approve and the host's auto-approver did not approve first): if the person clicks Reject and types text, code appends that text inside
<feedback>tags to a fixed denial line (for edit tools, one saying the file was NOT modified) and the model receives it in the skipped tool call's result. Typing a chat message instead of clicking leaves the approval pending and routes the message as a follow-up.- Held by
the person's optional feedback text on a rejection, wrapped as
<feedback>in the denial reason (apps/vscode/src/sdk/tool-approval-denial.ts:18-25, built atapps/vscode/src/sdk/sdk-interaction-coordinator.ts:256-278) and returned to the model as the skipped tool's result (agent-runtime.ts:2488-2491).
How this map was made
Four readers each took a part of the agent and wrote seat cards from the source. Fresh readers then re-read those seats against the cited lines, filled in how each is answered, and corrected what the source did not support; each correction is recorded with the lines opened. Another reader searched the Cline Hub app, which no card covered yet, and drafted 6 cards; the map's author opened each card's holding lines before adding it, and checked a sample of 8 re-read claims against the source. Models from another family (read-only, at the same commit) reviewed the seat data once, checked an earlier, fuller edition's wording twice, then checked this edition's wording; each finding was checked at source before anything changed, and a sentence or card that could not be settled was narrowed or cut. A checker confirms that each seat's holder line exists at the pinned commit and carries its anchor text. Nothing on this page was produced by running their code.