DeerFlow: who decides what
How to read this page
A seat is a judgment the agent makes over and over: which model runs a turn, what the model sees, may this tool call run, is the work done. Each card records the question, how it is answered, and who or what holds it, with the code that implements or exposes that decision. Seat ids (A1, D12 …) are links.
Each answer describes what DeerFlow does by default at the commit named above. Exceptions named are the main ones, not a complete list.
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; code = code in their repository; human = a person; external = something outside the repository that the agent hands the decision to (a hosted service, a sandbox provider, a configured command).
Paths are relative to the repository root. A file name written without its folder is in the folder of the full path written before it on the same card. A bare :120-140 means lines in the file named just before it.
Counts
133 seats across 9 stages: A 12, B 26, C 6, D 31, E 17, F 19, G 7, H 10, I 5.
| Kind of question · holder | Seats |
|---|---|
| RULE · code | 65 |
| RULING · code | 28 |
| RULING · llm | 23 |
| RULING · external | 10 |
| RULING · human | 4 |
| RULE · external | 3 |
What this edition does not have
There is no list of gaps. No coverage figure: this edition does not say how many of DeerFlow's model calls and decision points the seats leave out. Each card shows the question, the answer and its holder; for most seats we also recorded what checks the judgment and how it has failed, but those notes are not shown here.
What is left out of this edition
17 of the 133 cards are left out of this edition. The counts above include them.
A. Intake and routing
A1 Which configured model is chosen for this conversation turn, before model-use authorization? RULE · code
- Answered how
Code takes the request's
model_name/model, else the custom agent'smodel, elseconfig.models[0]. An unknown name falls back to the first configured model with a log warning, unless the run marks it as an explicit model selection; then the run is refused.- Held by
backend/packages/harness/deerflow/agents/lead_agent/agent.py:228(called atbackend/packages/harness/deerflow/agents/lead_agent/agent.py:1077; explicit selectionbackend/packages/harness/deerflow/agents/lead_agent/agent.py:1081-1089)
A2 Is extended thinking on, and at what reasoning effort, for this run? RULE · code
- Answered how
Code applies precedence request > custom-agent default > runtime default (
backend/packages/harness/deerflow/agents/lead_agent/agent.py:167-180,_resolve_runtime_option), then normalizes against the model's reasoning contract: unsupported thinking is turned off, required thinking is forced on (or rejected), and an out-of-vocabulary effort is aliased or replaced by the contract default.- Held by
backend/packages/harness/deerflow/models/reasoning.py:142(called atbackend/packages/harness/deerflow/agents/lead_agent/agent.py:1103and again inside the factory atbackend/packages/harness/deerflow/models/factory.py:615)
A3 Which provider class, endpoint and request payload does the chosen model get? RULE · code
- Answered how
Code resolves the model class by reflection, layers per-agent sampling overrides, merges thinking templates, and applies provider defaults such as routing the gpt-6 family to the OpenAI Responses API unless a custom endpoint is set.
- Held by
backend/packages/harness/deerflow/models/factory.py:536
A4 Which build path does this request take: bootstrap agent creator, a named custom agent, or the default lead agent? RULE · code
- Answered how
Code reads
is_bootstrapandagent_namefrom the run config; bootstrap gets a narrow skill set plussetup_agent, a named agent loads its own config, SOUL and tool groups, otherwise the default lead agent is built.- Held by
backend/packages/harness/deerflow/agents/lead_agent/agent.py:1169
A5 Does the user's message explicitly ask for a skill (/skill-name task), and which one? RULE · code
- Answered how
Code matches a strict leading
/nametoken (lowercase letters, digits, hyphens, followed by whitespace or end), skips nine reserved control names always and/context compactonly in that exact form, and then resolves the name against the installed, enabled skills this agent may use.- Held by
backend/packages/harness/deerflow/agents/middlewares/skill_activation_middleware.py:317(grammar atbackend/packages/harness/deerflow/skills/slash.py:18)
A6 Which DeerFlow thread does an inbound IM message continue? RULE · code
- Answered how
Code looks up the conversation/topic in the connection repository when the message carries a bound connection, else in the global channel store; no mapping means a new thread is created.
- Held by
backend/app/channels/connection_identity.py:47
A7 Which agent handles an IM message? RULE · code
- Answered how
Code applies a fixed precedence: per-message override (GitHub fan-out), thread pin from
/agent use, user session layer, channel layer, default session, manager default; a custom agent name is routed throughlead_agentplusagent_namecontext.- Held by
backend/app/channels/manager.py:1743
A8 Which model does an IM conversation use after a user pins one with /model? RULE · code
- Answered how
Code applies the thread's
/modelpin over every session-config layer; the agent factory then prefers this requested name over the custom agent's own model.- Held by
backend/app/channels/manager.py:2191
A9 Is an inbound IM text a channel command or a chat turn? RULE · code
- Answered how
Code checks whether text that starts with
/begins with one of the known slash commands (/new,/status,/models,/model,/memory,/goal,/agent,/bootstrap,/help…), case-insensitively.- Held by
backend/app/channels/commands.py:87-91(leading mentions are stripped separately, for adapters that leave them in the text, at:46-65)
A10 Does this GitHub event wake this agent binding? RULE · code
- Answered how
Code applies the binding's configured gates in order: action allowlist,
allow_authorsbypass, then a boundary-aware@mentionrequirement.- Held by
backend/app/gateway/github/triggers.py:150
A11 How should the user's rough draft be rewritten before it is sent? RULING · llm
- Answered how
On request from the composer, a one-shot model call rewrites the draft into a clearer instruction; the user sees the result and decides whether to send it.
- Held by
model setting
input_polish.model_name, read atbackend/app/gateway/routers/input_polish.py:86(falls back to the default model insiderun_oneshot_llm); call atbackend/app/gateway/routers/input_polish.py:88
A12 Which follow-up questions should the user be offered next? RULING · llm
- Answered how
A one-shot model call reads the recent conversation (supplied by the client) and proposes N short follow-up questions.
- Held by
model setting from request
model_name, else the default model, atbackend/app/gateway/routers/suggestions.py:145; call atbackend/app/gateway/routers/suggestions.py:140
B. Context: what the model sees
B3 Which skill, if any, should the model load for this task? RULING · llm
- Answered how
The lead model decides from the advertised skill metadata whether a skill matches and loads its SKILL.md with
read_file(or first callsdescribe_skillin deferred mode).- Held by
the run's lead model, resolved at
backend/packages/harness/deerflow/agents/lead_agent/agent.py:1077
B4 Which skills match the model's describe_skill query? RULING · code
- Answered how
Code ranks the catalog by literal intent-term coverage (name hits preferred), returns at most 5;
select:returns exact names uncapped.- Held by
backend/packages/harness/deerflow/skills/catalog.py:145
B10 Which tools are bound to the lead model for this run? RULE · code
- Answered how
Code assembles candidate tools from configured tools, built-ins, platform and personal MCP tools, ACP and plugin tools, filtered by the agent's settings and the run context, drops later duplicates by name, and then applies further additions and filters before the final tool set is bound.
- Held by
backend/packages/harness/deerflow/tools/tools.py:103
B11 Is this channel trusted enough to offer the agent its self-modification tool (update_agent)? RULING · code
- Answered how
Code offers
update_agentto every named custom agent unless the run came from a channel in a fixed set, which today contains onlygithub.- Held by
backend/packages/harness/deerflow/agents/lead_agent/agent.py:1329(set atbackend/packages/harness/deerflow/agents/lead_agent/agent.py:92)
B12 Which deferred MCP tool schemas can the model see on this call? RULE · code
- Answered how
Code hides every deferred (MCP) tool schema whose name is not in the thread's promoted set for the current catalog hash and current genuine user turn, and blocks calls to hidden ones with an error telling the model to call
tool_search.- Held by
backend/packages/harness/deerflow/agents/middlewares/deferred_tool_filter_middleware.py:93
B13 Which deferred tools match the model's tool_search query? RULING · code
- Answered how
Code matches the query against deferred tool names and descriptions:
select:exact names (uncapped),keywords:literal term coverage,+namerequired-substring plus regex, or plain regex with name hits ranked first; at most 5 results under a 100 ms regex budget.- Held by
backend/packages/harness/deerflow/tools/builtins/tool_search.py:128
B14 Which deferred MCP tools are auto-promoted from what the user just said? RULING · code
- Answered how
Code checks whether any MCP server's configured routing keyword occurs as a case-insensitive substring of the latest genuine user message, and promotes the top-k matches by configured priority, before the model call.
- Held by
backend/packages/harness/deerflow/agents/middlewares/mcp_routing_middleware.py:92
B17 Which personal data in the user's messages is replaced before the model sees it? RULING · code
- Answered how
When enabled (default off), code runs deterministic regex detectors over genuine user messages and the compaction summary and swaps matches for irreversible value-derived placeholders.
- Held by
backend/packages/harness/deerflow/agents/middlewares/pii_redaction_middleware.py:418
B18 Which of this turn's uploaded files are described to the model, and how? RULE · code
- Answered how
Code lists files attached to the latest user message (capped by count, in upload order), with size, path and either a heading outline or a short preview, all tag-neutralized, prepended to that message; historical uploads are left to the
list_uploaded_filestool.- Held by
backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py:239
B19 Of the images viewed in the thread, which are re-sent as pixels on this model call, and which are replaced by an "omitted" note? RULING · code
- Answered how
On each model call, code removes the earlier image-context messages that carry its reserved id prefix and server-owned marker (an unmarked one from an older checkpoint stays, and can stop the rebuild,
backend/packages/harness/deerflow/agents/middlewares/view_image_middleware.py:80-82,:450-461) and, when a rebuild is due and authorized, builds a new one from the thread's viewed-image records. It examines the records newest first: an image gets a read attempt only while the attempt count is under the smaller of 4 and the configured image cap and its estimated size still fits the 28 MiB base64 budget and the configured character cap; otherwise it gets "(omitted: image injection budget reached; call view_image again to re-view this image)" and the scan goes on, so a smaller, older image can still fit after a large one is omitted. Each attempted image is read fresh, with its recorded size and digest passed to the reader; one that is unavailable or changed gets a note instead.- Held by
backend/packages/harness/deerflow/agents/middlewares/view_image_middleware.py:386
B20 What compacted history, delegation ledger, active skills, artifacts, goal and task notes does the model see? RULE · code
- Answered how
Code renders, per model call, one hidden
<durable_context_data>block: the active goal, the bounded conversation summary, the delegation ledger, active skill references, artifact registry and task notes, each escaped and length-bounded.- Held by
backend/packages/harness/deerflow/agents/middlewares/durable_context_middleware.py:101(injected at:400)
B22 What one-line description does a project document get on the shelf the model reads? RULING · llm
- Answered how
A background model call reads up to 16,384 characters of the document and writes a single descriptive sentence, stored once per document.
- Held by
model setting
projects.summary_model_name, read atbackend/packages/harness/deerflow/projects/summaries.py:160; call atbackend/packages/harness/deerflow/projects/summaries.py:335
B23 Which knowledge scope applies to this turn, and is knowledge search offered at all? RULE · code
- Answered how
Code takes the Gateway-admitted scope from runtime context, or the single
knowledge_scopecarried on a current-run user message, canonicalizes it, strips scope data from model-visible messages, and removes and blocksknowledge_searchwhen the scope isdisabled.- Held by
backend/packages/harness/deerflow/agents/middlewares/knowledge_scope_middleware.py:44
B25 How are the separate system messages merged before the provider sees the request? RULE · code
- Answered how
Code merges the static system prompt and every in-history SystemMessage into one leading system message per request, keeping only the newest date reminder.
- Held by
backend/packages/harness/deerflow/agents/middlewares/system_message_coalescing_middleware.py:64
B26 Which message content blocks must be downgraded to text placeholders for the selected model? RULE · code
- Answered how
Code rewrites URL-sourced file blocks and non-fetchable-scheme image blocks into neutralized text placeholders on the request view only, keeping http(s) URLs where the selected model's serializer accepts them.
- Held by
backend/packages/harness/deerflow/agents/middlewares/model_content_compatibility_middleware.py:231
B27 What does the model receive when the user explicitly activates a skill? RULE · code
- Answered how
Code inserts, before the user's message and for that turn only, an escaped copy of the full SKILL.md plus the remaining task text, recording the activation so retries in the same run replay the same text.
- Held by
backend/packages/harness/deerflow/agents/middlewares/skill_activation_middleware.py:541
C. Choosing the next action
C2 Before the model is called again, how is a broken tool-call transcript repaired: which calls get an "interrupted" or "invalid arguments" placeholder, which results are dropped as orphans, and how are empty names and ids relabelled? RULE · code
- Answered how
Code rewrites the model-bound message list (request only, state untouched): synthetic ids for missing call ids,
unknown_toolfor empty names,{}for non-JSON arguments, an error ToolMessage after each unanswered call, and silent removal of ToolMessages whose call is gone.- Held by
backend/packages/harness/deerflow/agents/middlewares/dangling_tool_call_middleware.py:429
C3 When a model call fails (HTTP error, timeout, in-stream error, empty completion), is it transient (retry, with what delay and budget) or final (quota, auth, generic), and what does the person see? RULING · code
- Answered how
Code classifies the exception by class name, status code, in-band status text and substring patterns (
_QUOTA_PATTERNS,_AUTH_PATTERNS,_BURST_PATTERNS,_BUSY_PATTERNS), retries up to a per-class / per-reason budget with Retry-After or decorrelated jitter, and on exhaustion replaces the model output with an AIMessage markeddeerflow_error_fallback.- Held by
backend/packages/harness/deerflow/agents/middlewares/llm_error_handling_middleware.py:623
C4 When the model stops normally but says nothing and calls nothing, is that an answer, a provider glitch to retry once, or (after tools ran) a failed run? RULING · code
- Answered how
Code, at two points. At the model boundary
_raise_for_empty_responseturns a stop/end_turn/None finish with no visible content and no tool-call intent into a retriableEmptyModelResponseError, one retry per run (context key). After the model,TerminalResponseMiddlewarereplaces a still-empty response that follows a tool result in the current turn with a visible fallback markeddeerflow_error_fallback, which the worker turns into run statuserror(E14).- Held by
backend/packages/harness/deerflow/agents/middlewares/llm_error_handling_middleware.py:59(boundary);backend/packages/harness/deerflow/agents/middlewares/terminal_response_middleware.py:42(terminal)
C5 Did the provider stop because the output budget ran out, and if so must the possibly truncated tool calls be suppressed and the person told? RULE · code
- Answered how
Code: four detectors (OpenAI-compatible
finish_reason=length, Anthropicstop_reason=max_tokens, GeminiMAX_TOKENS, Responsesstatus=incomplete+max_output_tokens) recognise the cap; on a hit all tool calls (structured, invalid, raw) are removed,stop_reason=model_length_cappedis stamped in run context (and kept per run id for the subagent executor'sconsume_stop_reason), and a notice is appended when tool calls were removed or no visible text remains.- Held by
backend/packages/harness/deerflow/agents/middlewares/model_length_finish_reason_middleware.py:121(detectorsbackend/packages/harness/deerflow/agents/middlewares/model_length_termination_detectors.py:130)
C6 When a provider's safety system terminated the response (content_filter, refusal, SAFETY), should its tool calls be blocked and an empty message back-filled? RULE · code
- Answered how
Code: configurable detectors (
OpenAICompatibleContentFilterDetector,AnthropicRefusalDetector,GeminiSafetyDetector) readfinish_reason/stop_reason; on a hit with tool calls or blank content it clears tool calls, stampsstop_reason=safety_capped, records an audit event and appends a notice.- Held by
backend/packages/harness/deerflow/agents/middlewares/safety_finish_reason_middleware.py:359
D. Gatekeeping: may this action run?
D1 When authorization is on, is this user's role allowed to execute this specific tool call? RULE (enforcing an operator-supplied role policy) · code
- Answered how
Code.
GuardrailMiddlewarewraps aGuardrailAuthorizationAdapter, which builds a Principal from server-set run context and asks the configuredAuthorizationProvider(built-in: RBAC role→tools allow/deny lists, deny wins); a deny returns an error ToolMessage instead of running the tool.- Held by
backend/packages/harness/deerflow/authz/adapter.py:137
D2 Is this tool (and, for a custom provider, these arguments) permitted by the configured guardrail policy? RULE (name membership against a supplied list); a custom provider may hold a RULING (e.g. blocked-pattern matching) — not knowable from this repo. · code
- Answered how
Code by default —
AllowlistProviderchecks the tool name against configured allowed/denied lists; a custom provider (any class onguardrails.provider.use, e.g. an OAP passport evaluator) is external code the system hands the decision to.- Held by
backend/packages/harness/deerflow/guardrails/builtin.py:28
D3 Is this specific call risky enough to refuse before it runs? RULING · external
- Answered how
A hosted TypeSafe "Jev" service scores one question (
risky_tool_call) on the tool name + full canonical argument JSON; code denies when the returned probability >=threshold(default 0.5). Local preflight first: tools outsideallowed_toolsare refused, tools outsidetoolsare allowed un-probed, unserialisable or over-max_state_chars(4000) arguments are refused.- Held by
backend/packages/harness/deerflow/guardrails/typesafe.py:352
D4 Before a bash call runs, should it be blocked as high-risk, run with a warning, or run silently? RULING (which commands are "high-risk" is a judgment; their own guide calls it "defense-in-depth and audit, not a security boundary") · code
- Answered how
Code.
SandboxAuditMiddlewarerejects empty / >10,000-char / NUL-containing commands, then classifies with regex + shlex splitting (_HIGH_RISK_PATTERNS, command-position substitution patterns,_MEDIUM_RISK_PATTERNS); "block" returns an error ToolMessage without running, "warn" runs and appends a warning to the result.- Held by
backend/packages/harness/deerflow/agents/middlewares/sandbox_audit_middleware.py:570
D5 When the sandbox is the local host provider, may the agent execute shell commands at all? RULE (reads an operator setting) · code
- Answered how
Code.
is_host_bash_allowedreturns True for any non-local sandbox provider, and for the local provider only whensandbox.allow_host_bash: true; the bash tool returns an error string otherwise, and tool assembly hides bash.- Held by
backend/packages/harness/deerflow/sandbox/security.py:45
D6 With host bash opted in, does this command reference host paths it should not? RULING (a regex/token heuristic over shell text deciding "is this a host-path reference"; their docstring: "best-effort guard … not a secure sandbox boundary") · code
- Answered how
Code.
validate_local_bash_command_pathsrejectsfile://URLs, absolute paths outside/mnt/user-data, skills, ACP, custom mounts and a small system-path allowlist, shell-variable path prefixes other than$PWD(outside the single-quoted inline program of an awk command, which is exempt), and named-tilde paths; raises PermissionError, returned to the model as an error string.- Held by
backend/packages/harness/deerflow/sandbox/tools.py:1793
D7 Is this virtual path inside the families a structured file tool may touch, and is a write allowed there? RULE · code
- Answered how
Code.
validate_local_tool_pathrejects..segments, allows/mnt/user-data/*read+write and the bare/mnt/user-dataroot for reads only, skills and ACP workspace read-only, custom mounts per theirread_onlyflag, and refuses everything else.- Held by
backend/packages/harness/deerflow/sandbox/tools.py:1020
D8 Is this user's role permitted to execute anything in a sandbox? RULE · code
- Answered how
Code. Before any sandbox reuse or acquire,
authorize_sandbox_executionasks the authorization providerauthorize(principal, "sandbox", "execute", target="*"); deny raisesSandboxAuthorizationError, surfaced as an error ToolMessage.- Held by
backend/packages/harness/deerflow/authz/sandbox_authz.py:149
D9 When the AIO sandbox is in restricted network mode, may an outbound connection to host:port proceed? RULE · code
- Answered how
Code in a per-sandbox proxy sidecar: in
allowlistmode it allows hosts matching operator domain rules (DEERFLOW_ALLOW_DOMAINS_JSON, exact or leading*.) or an unexpired grant;isolated(default) allows nothing. IP-literal destinations are refused, and a name is refused unless every address it resolves to is public (Docker Desktop's synthetic198.18.0.0/15range counts as public only whenDEERFLOW_ALLOW_SYNTHETIC_DNS=1,backend/packages/harness/deerflow/community/aio_sandbox/network_proxy.py:99-102,:218-220); a policy denial is recorded as a pending event for D10/D11 only whenDEERFLOW_RECORD_DENIALS=1, and the IP-literal and resolution refusals record none.- Held by
backend/packages/harness/deerflow/community/aio_sandbox/network_proxy.py:130
D10 The sandbox tried to reach a host outside the allowlist; does the person allow it temporarily, for the sandbox's life, or deny it? RULING · human
- Answered how
A person, via a Human Input card raised after the tool call; the chosen option (
deny/allow_temporary/allow_sandbox) is applied at the start of the next turn as a grant in the sidecar. The blocked call is NOT replayed.- Held by
the user of an interactive run (response applied at backend/packages/harness/deerflow/sandbox/middleware.py:350)
D11 In scheduled/webhook/autonomous runs and in subagents, what happens to a blocked connection that would otherwise go to a person? RULE · code
- Answered how
Code. If the resolved run interaction policy does not allow clarification, or the call is from a subagent, every unsurfaced denial is atomically marked
denyand no card is raised.- Held by
backend/packages/harness/deerflow/sandbox/middleware.py:640
D12 Is this run interactive (a person may be asked) or unattended (scheduled, webhook, autonomous)? RULE · code
- Answered how
Code.
resolve_run_interaction_policytakes an explicitinteraction_mode, else maps legacy flags in order (non_interactive→ scheduled,channel_name == "github"→ webhook,disable_clarification→ autonomous), else interactive. The result removesask_clarification, switches the prompt guidance, makes ClarificationMiddleware answer "proceed without asking", and auto-denies network approvals (D11).- Held by
backend/packages/harness/deerflow/agents/interaction_policy.py:150
D15 Given the agent's question (missing info, approach choice, risk confirmation, suggestion), what does the person choose or say? RULING · human
- Answered how
A person, through a Human Input card (web) or IM text; the run ends at the interrupt and the answer arrives as the next user turn (a hidden
HumanMessagewithhuman_input_responsemetadata).- Held by
the run's user; interrupt issued at backend/packages/harness/deerflow/agents/middlewares/clarification_middleware.py:553
D16 If a model turn contains ask_clarification plus other tool calls, do the others wait for the answer? RULE · code
- Answered how
Code. In interactive runs ClarificationMiddleware rewrites the AIMessage to keep only the clarification call(s), so siblings never execute; in unattended runs it leaves them.
- Held by
backend/packages/harness/deerflow/agents/middlewares/clarification_middleware.py:479
D17 May this write_file / str_replace on an existing file run, given what the model last read? RULE · code
- Answered how
Code. ReadBeforeWriteMiddleware reads the file's current content and compares its hash with the newest
read_filemark carried on ToolMessages; a mismatch or missing mark returns an error ToolMessage telling the model to read first.- Held by
backend/packages/harness/deerflow/agents/middlewares/read_before_write_middleware.py:367
D19 Is this user's role allowed to activate (load and follow) this specific skill? RULE · code
- Answered how
Code.
skill_activation_allowedasks the authorization providerauthorize(principal, "skill", "activate", skill_name); used by slash activation,describe_skilland skill-file loads.- Held by
backend/packages/harness/deerflow/authz/skill_filter.py:62
D20 Is this role allowed to use the selected model; if denied and the run did not explicitly select it, which authorized model replaces it? RULE · code
- Answered how
Code, only when
authorization.enabledis true. A model the run explicitly selected is refused on denial and never replaced. Otherwise_authorize_model_namechecksauthorize("model","use"); on a denial it walks the provider's visible model list and takes the first other model that also passesuse. With none left it raises whenfail_closedis true, which is the default; withfail_closed: falseit logs a warning and keeps the denied model, as the function's docstring says.- Held by
backend/packages/harness/deerflow/agents/lead_agent/agent.py:285; explicit selectionbackend/packages/harness/deerflow/models/selection.py:93-121(called atbackend/packages/harness/deerflow/agents/lead_agent/agent.py:1089)
D21 Is this skill text or script the agent wants to create/edit safe to write (no prompt-injection, privilege escalation, exfiltration, unsafe code)? RULING · llm
- Answered how
Two holders in sequence. First code: SkillScan's deterministic analyzers block any CRITICAL finding (D22). Then a moderation model (
skill_evolution.moderation_model_nameor the default model) classifies the content allow/warn/block;blockrefuses the write, and executable content must getallow.- Held by
backend/packages/harness/deerflow/skills/security_scanner.py:158
D22 Does a deterministic scan of the skill (secrets, shell pipes to interpreters, exfiltration hosts, executable binaries, …) find a CRITICAL issue? RULING (pattern-based severity of code/prose; their rule specs choose what is CRITICAL) · code
- Answered how
Code.
enforce_static_scanruns SkillScan over the candidate directory and raisesStaticScanBlockedErroron any CRITICAL finding; lower findings are logged and passed to D21 as context.- Held by
backend/packages/harness/deerflow/skills/skillscan/orchestrator.py:232
D23 Is the scheduler tool usable in this run — feature on, not a subagent, the host bound a capability of the right mode (interactive for management, scheduled for self-stop)? RULE · code
- Answered how
Code.
_capabilityreturns the host-bound capability only whenscheduler.tool_enabled, the run is not a subagent, the capability mode matches, and the resolved interaction policy mode equals that mode; the Gateway capability then re-checks interactive mode, live owner authentication, route permissions and the originating thread (backend/app/gateway/scheduled_task_access.py:338-350, 384-388).- Held by
backend/packages/harness/deerflow/tools/scheduled_tasks.py:31
D24 Should the agent create (or update/resume/delete) a recurring task that will run later with no person present? RULING · llm
- Answered how
The lead model, guided by the
schedule_tasktool description ("Use create only after the user asked for scheduled or recurring work … Use delete only when the user explicitly asks"). The host checks permissions, field validity and safety caps, but NOT that the current user turn asked — unliketrial(D25) andnote(D26), which it does check.- Held by
the lead agent's chat model calling
schedule_task(backend/packages/harness/deerflow/tools/scheduled_tasks.py:35)
D25 Before dispatching a trial run, is the person's latest message a direct "run it now" request (not a bare "yes", a mention, a quote or a conditional)? RULING (deciding consent from free text; implemented as an exact phrase list) · code
- Answered how
Code.
_has_explicit_trial_requestnormalises the turn, strips up to two leading acknowledgements and one trailing particle, and requires the whole remainder to be one of a fixed set of English/Chinese direct-run phrases (or one naming the opaque task id).- Held by
backend/app/gateway/scheduled_task_access.py:155
D26 May the agent save this standing instruction for all future runs of the task? RULE · code
- Answered how
Code.
_noteaccepts the note only if it is a non-empty substring (≤500 chars) of the current user message.- Held by
backend/app/gateway/scheduled_task_access.py:539
D27 Before discovering or calling tools on a user's personal MCP server, is it a privileged (non-public-network) definition, and is the owner a current admin? RULE · code
- Answered how
Code. A personal server not marked
personal_public_network: truerequires a fresh admin lookup via a host-installed checker; no checker, a failed lookup or a non-admin → the server is omitted from discovery and every call raises.- Held by
backend/packages/harness/deerflow/mcp/personal_access.py:38
D28 For an HTTP/SSE MCP server configured with per-user (user_auth) or per-request (headers_from_context) credentials, may a call run when the credential is missing or unusable? RULE · code
- Answered how
Code. The interceptor resolves the credential for the authenticated user / request secrets; missing or empty →
ToolExceptionunless the operator seton_missing: "passthrough"; a value that cannot be a header is always denied without echoing it.- Held by
backend/packages/harness/deerflow/mcp/user_scoped_auth.py:107(user_auth); request-scoped context headers by a separate interceptor atbackend/packages/harness/deerflow/mcp/context_headers.py:138-205
D29 Is this URL an http(s) address that resolves only to public IPs, and is a self-hosted fetch backend's egress confirmed isolated? RULE · code
- Answered how
Code.
validate_public_http_urlrefuses non-http(s) schemes and any host resolving to a private, loopback, link-local, reserved, multicast, CGNAT or metadata address;validate_delegated_backend_urlrefuses a self-hosted Browserless/crawl4ai/fastcrw/firecrawl backend unlessnetwork_isolation_confirmed.- Held by
backend/packages/harness/deerflow/community/url_safety.py:140
D30 Does this inherited environment variable look like a credential that must be withheld from sandbox processes? RULING (a name-shape heuristic for "is this a secret") · code
- Answered how
Code.
is_blocked_env_nameblocks exact names (connection strings,MYSQL_PWD, …) and wildcard patterns (*KEY*,*SECRET*,*TOKEN*,*PASS*,*CREDENTIAL*,*DSN*);build_sandbox_envdrops them, then adds explicitly configured and request-scoped values.- Held by
backend/packages/harness/deerflow/sandbox/env_policy.py:105
D31 Does an uploaded file's name and target path stay inside the thread's upload directory without traversal, links, reserved names or non-portable forms? RULE · code
- Answered how
Code.
normalize_filenamefirst keeps only the base name (Path(filename).name,backend/packages/harness/deerflow/uploads/manager.py:75, so../../etc/passwdbecomespasswd), then rejects an empty or unsafe base name, NUL, remaining backslashes, over-255-byte, staging-pattern and non-Windows-portable names;validate_upload_destination/validate_path_traversalrefuse non-regular or escaping destinations, and refuse an existing multi-link destination only on the default (non-exclusive) path (not on the exclusive first-claim path) and only off Windows, where the link count is treated as unreliable (manager.py:170-179, 194-195). At this pin the default path no longer overwrites: a same-name collision is written under the next free_Nname.- Held by
backend/packages/harness/deerflow/uploads/manager.py:59
D32 In a scheduled run, does the work now meet the stop rule written into the task, so the recurring schedule should pause after this run? RULING · llm
- Answered how
The run's model decides, guided by the
stop_scheduled_tasktool description ("Call this when the stop rule in your task instructions is met … Meeting this run's goal does not by itself mean the stop rule is met"). The host checks only that this is a scheduled run with its own task and occurrence and that the owner may write, then records the stop request; it does not judge whether the stop rule holds.- Held by
the scheduled run's chat model calling
stop_scheduled_task(backend/packages/harness/deerflow/tools/scheduled_tasks.py:166)
E. Execution and observation
E1 If a tool call throws, does the run stop, or does the model receive an error result it can recover from, and how much of the error text does it see? RULE · code
- Answered how
Code catches every non-control-flow exception around the tool handler and returns an error ToolMessage
Error: Tool '<name>' failed with <Class>: <detail≤500 chars>. Continue with available context, or choose an alternative tool.;taskfailures also get the subagent failure contract.- Held by
backend/packages/harness/deerflow/agents/middlewares/tool_error_handling_middleware.py:112(wrappers:309-344)
E2 For every tool result, what status (success / error / partial_success), error type, "recoverable by the model?" flag and recommended next action is stamped on it? RULING · code
- Answered how
Code: exception text, an
Error:content prefix, a JSONerrorfield (except onread_file, whose JSON is document data), a nonzero bash exit marker, a web_fetch error-page title, or partial-result substrings (truncated,no results found, ...) are matched against keyword rules (_ERROR_RULES); a producer-supplied stamp is kept as is, except an old content-analysis "success" on a bash result whose exit marker reports failure.- Held by
backend/packages/harness/deerflow/agents/middlewares/tool_result_meta.py:263
E3 When a tool result exceeds its budget, is it saved to a file with a synopsis and a pointer, or cut to a head-and-tail excerpt, and which tools are exempt? RULING · code
- Answered how
Code: above
externalize_min_chars(default 12,000) the full text is written to the thread's.tool-resultsdir (or a blob store) and replaced with a typed synopsis plus aread_filepointer; if persistence is impossible, content abovefallback_max_chars(30,000) is cut to 8,000 head + 3,000 tail;read_fileis exempt by default.- Held by
backend/packages/harness/deerflow/agents/middlewares/tool_output_budget_middleware.py:532
E4 Once a file written earlier has since been read or modified again, can the model stop seeing the old written content, and which recent writes must stay visible? RULING · code
- Answered how
Code, only when
elide_superseded_writesis turned on (default off at this pin): replaces thecontentargument of successful, supersededwrite_filecalls in the model-bound request with a placeholder, abovesuperseded_write_min_chars(2,000), keeping the newestkeep_recent_writes(1); state, receipts and journal keep the original.- Held by
backend/packages/harness/deerflow/agents/middlewares/tool_output_budget_middleware.py:1065
E6 When the agent runs bash, in which environment, with which path rewriting, under which deadline, and how is long output cut? RULE · code
- Answered how
Code:
bash_toolinitializes the sandbox, rewrites virtual paths and the working directory, runs the provider'sexecute_commandwithbash_command_timeout(default 600 s) and middle-truncates the output tobash_output_max_chars(default 20,000, 50/50 head/tail, exit marker kept).- Held by
backend/packages/harness/deerflow/sandbox/tools.py:2835(execution:2345)
E7 When a command echoes a credential it was given, which values are replaced with [redacted]? RULE · code
- Answered how
Code replaces every injected or blocked-name env value of at least 8 characters, longest first, with
[redacted]in bash output and in bash error strings.- Held by
backend/packages/harness/deerflow/sandbox/tools.py:2418
E8 For read_file, which part of a long file is returned, and how is the model told where to continue? RULE · code
- Answered how
Code head-truncates to
read_file_output_max_chars(default 50,000) at the last line boundary and appends a marker naming the nextstart_line(or a whole-line / bash continuation for very long lines).- Held by
backend/packages/harness/deerflow/sandbox/tools.py:2566(tool:3259)
E9 Is a write_file / str_replace executed as asked, and when is it refused (size cap, missing match), with what message? RULE · code
- Answered how
Code: a non-append
write_filerefuses content overDEERFLOW_WRITE_FILE_MAX_BYTES(default 80 KiB, 0 disables) with guidance to split; appends are not size-checked;str_replacereplaces one or all occurrences after matching the file's line endings. Whether the write may run at all is decided by a separate gatekeeping seat.- Held by
backend/packages/harness/deerflow/sandbox/tools.py:3375(str_replace_tool:3509)
E10 Given the model's query, which results (titles, URLs, snippets) come back, from which provider, and how many? RULING · external
- Answered how
An external search provider chosen by configuration (DuckDuckGo, Tavily, Brave, Serper, SearXNG, Exa, Firecrawl, InfoQuest, ...) ranks and returns results; each provider's
web_searchtool shapes them into text;image_searchis the same family.- Held by
the configured
web_searchtool, e.g.backend/packages/harness/deerflow/community/ddg_search/tools.py:181(settingtools[]inconfig.yaml)
E11 When the agent fetches a URL, which part of the page counts as its content, and how much of it is kept? RULING · code
- Answered how
Code plus provider: the cited fetch tools keep at most the first 4,096 characters of the page content, with no truncation notice. Three of them (Jina, InfoQuest, Browserless) run DeerFlow's readability extractor (main-article choice); the others keep the content the provider returns.
- Held by
backend/packages/harness/deerflow/community/jina_ai/tools.py:71(readability callbackend/packages/harness/deerflow/community/jina_ai/tools.py:70; same cut atbackend/packages/harness/deerflow/community/infoquest/tools.py:120,backend/packages/harness/deerflow/community/crawl4ai/tools.py:137,backend/packages/harness/deerflow/community/browserless/tools.py:350,backend/packages/harness/deerflow/community/firecrawl/tools.py:170,backend/packages/harness/deerflow/community/fastcrw/tools.py:154,backend/packages/harness/deerflow/community/tavily/tools.py:130,backend/packages/harness/deerflow/community/exa/tools.py:164; constantsbackend/packages/harness/deerflow/community/sofya/tools.py:27,backend/packages/harness/deerflow/community/unbrowse/tools.py:27,backend/packages/harness/deerflow/community/groundroute/tools.py:37)
E12 When an MCP server answers, which content blocks reach the model (text, images, files, resource links), what becomes a placeholder, and when is the answer treated as a failure? RULE · code
- Answered how
Code converts MCP content: text is kept (with local-path rewriting to virtual paths), images are kept, a
ResourceLinkbecomes a text placeholder (an http(s) image also stays an image), adata:/blob:URI is omitted while its placeholder remains, structured content moves to the artifact channel;isError=trueraisesToolException(then E1).- Held by
backend/packages/harness/deerflow/mcp/tools.py:476
E13 For MCP work submitted as a durable task, when is it complete, failed or still running? RULE · external
- Answered how
The remote MCP server reports status through its status tool; code maps
runningtoworking, a validtask_not_foundresult or malformed structured output becomes a permanent failure, a status call that returnsisError=trueis retried, and a background service polls the task with leases.- Held by
remote server status tool, read by
backend/packages/harness/deerflow/mcp/tasks/ordinary.py:204(status map:88,task_not_foundrule:154); polled with leases byMcpTaskServiceatbackend/app/mcp_tasks/service.py:1503-1554
E14 When the graph finishes, is the run recorded as success, error or cancelled, and with which stop reason? RULING (reclassified in pass 1: whether a guard-capped run "succeeded" is a judgment competent people would answer differently; the code answers "success + stop_reason") · code
- Answered how
Code: cancellation wins; else any
deerflow_error_fallbackmarker on a message produced in this run (from C3 or C4) or a journal-recorded fallback markserror; else a delivery-receipt check decides success vs error; a run stopped by a guard cap keeps its stop reason and goes through that same check, so it is recorded assuccessunless delivery fails.- Held by
backend/packages/harness/deerflow/runtime/runs/worker.py:1757(marker scan:3680)
E17 Before a tool runs, are artifact handles in its arguments resolved to their content, and what happens to an unknown handle? RULE · code
- Answered how
Code resolves handles in tool-call arguments when
tool_artifacts.enabledandresolve_handles_in_argsare on; unknown handles become error results inside the receipt ledger.- Held by
backend/packages/harness/deerflow/agents/middlewares/artifact_resolution_middleware.py:45-101
F. Limits and memory
F1 How many graph steps may one run take before it is stopped? RULE · code
- Answered how
The Gateway takes the request's
recursion_limitif it is a positive integer, otherwise the configured default, and caps it atmax_recursion_limit; LangGraph raises when the run exceeds it and the worker marks the runerror.- Held by
backend/app/gateway/services.py:1319
F2 Is the conversation long enough that older context must be compacted now? RULE · external
- Answered how
Before each model call (only when
summarization.enabled), the inherited LangChainSummarizationMiddleware._should_summarizecompares the token count (messages plus the existing summary) with the configured trigger (tokens, messages, or a fraction of the run model's context window).- Held by
backend/packages/harness/deerflow/agents/middlewares/summarization_middleware.py:739
F3 Which older messages get folded into the summary and which stay verbatim? RULING · external
- Answered how
The library's
_determine_cutoff_indexpicks a cutoff from thekeeppolicy (default last 20 messages); DeerFlow then rescues every SystemMessage, tagged dynamic-context reminders and the latest genuine user request from the to-be-summarized side, and drops todo reminders before partitioning.- Held by
backend/packages/harness/deerflow/agents/middlewares/summarization_middleware.py:749
F4 What should the summary of the compacted conversation say? RULING · llm
- Answered how
A chat model (the configured
summarization.model_name, falling back to the run model) gets the summary prompt filled with the messages to compact (chunked when long) and the previous summary, and returns free text that replaces those messages insummary_text.- Held by
backend/packages/harness/deerflow/agents/middlewares/summarization_middleware.py:491
F5 Is the agent stuck repeating the same tool calls, and should it be warned or stopped? RULING · code
- Answered how
After each model response, code hashes the set of tool calls (name plus normalized args) and counts repeats in a sliding window per run; at 3 identical sets it queues a "wrap up" warning for the next model call, at 5 it strips all tool calls and forces a final answer (
stop_reason=loop_capped); a separate per-tool-name frequency layer warns at 30 and stops at 50.- Held by
backend/packages/harness/deerflow/agents/middlewares/loop_detection_middleware.py:634
F6 Has this run spent its token budget? RULE · code
- Answered how
After each model response, code sums
usage_metadataof every AIMessage in state (tracking per-message deltas), compares total/input/output with the configured limits, injects a warning at 80% and at 100% strips tool calls and forces a final answer (stop_reason=token_capped).- Held by
backend/packages/harness/deerflow/agents/middlewares/token_budget_middleware.py:303
F7 Has a particular tool stopped producing anything useful, so it should be blocked? RULING · code
- Answered how
When
tool_progress.enabled, code keeps a per-(thread, tool) state machine: an error, a partial success, or a success whose word set is at least 0.8 Jaccard-similar to recent results counts as a problem; 3 problems warn, 2 more (non-recoverable kinds) block the tool; auth/config/internal errors block at once.- Held by
backend/packages/harness/deerflow/agents/middlewares/tool_progress_middleware.py:528
F10 How many turns may a sub-agent take? RULE · code
- Answered how
The executor converts the sub-agent's
max_turns(general-purpose 150, bash 60, config default 50) into a LangGraph recursion limit scaled by the assembled middleware depth; exceeding it raisesGraphRecursionError, which the executor turns intocompleted(if the last AIMessage has any text) orfailed, both withstop_reason=turn_capped.- Held by
backend/packages/harness/deerflow/subagents/turn_budget.py:128
F11 How long may a sub-agent run before it is timed out? RULE · code
- Answered how
The executor runs the sub-agent as a task and waits on it with
asyncio.wait(..., timeout=timeout_seconds); on timeout it sets the cancel event, recordsTIMED_OUTimmediately and cancels the task, leaving teardown to a supervisor; the parent's poll loop has its own backstop of(timeout + 60) / 5polls.- Held by
backend/packages/harness/deerflow/subagents/executor.py:2335
F12 What should long-term memory learn from this conversation? RULING · llm
- Answered how
After a run (memory on by default,
mode: middleware), the turn's filtered user and final assistant messages are queued; a debounced worker calls the DeerMem memory model with the current memory and the new conversation, and it returns JSON proposing new facts, removals, summary rewrites and reinforcements (staleness and consolidation are F14 and F15).- Held by
backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/updater.py:1991
F13 Which of the memory model's proposed writes are accepted? RULE · code
- Answered how
Code gates each proposal: a fact is accepted only if the model labelled it
scope=user,durability=durable,authority=descriptive; summaries needscope=userandauthority=descriptive; removals needscope=userand a reason; staleness removals must be real aged candidates and are capped per cycle; exact-duplicate facts are rejected.- Held by
backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/updater.py:141
F14 Should an aged fact be kept, removed, or given a longer life? RULING · llm
- Answered how
When
staleness_review_enabled, code selects aged, non-protected facts and adds a review section to the same memory-update call (F12); the model proposesstaleFactsToRemove/staleFactsToExtend, which code intersects with the real candidates, caps per cycle (lowest confidence removed first) and bounds.- Held by
backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/updater.py:1991
F15 Should several related facts be merged into one? RULING · llm
- Answered how
When
consolidation_enabled, code selects candidate groups and adds a consolidation section to the memory-update call; the model proposesfactsToConsolidate, which code validates at apply time.- Held by
backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/updater.py:1991
F16 Which facts are kept when memory is over capacity? RULING · code
- Answered how
Code ranks facts by the configured policy and keeps
max_facts: the defaultconfidencepolicy keeps the facts with the highest stored confidence value; the opt-inhybrid-v1policy keeps a few slots for corrections and fills the rest by a mix of confidence, confirmation freshness and access heat. Imports, new facts and automatic extraction enforce the cap; edits do not.- Held by
backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/eviction.py:157
F17 Is this conversation batch worth paying for a memory extraction call at all? RULING · external
- Answered how
When
memory.prescreen.modeisshadoworenforce(defaultoff), a hosted TypeSafe classifier is asked whether the batch holds anything durable; inenforce, a "skip" verdict drops the extraction call and advances the watermark; any failure means extraction runs as usual.- Held by
backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/updater.py:1927
F18 Which messages are flushed into memory before compaction deletes them? RULE · code
- Answered how
A
before_summarizationhook hands the about-to-be-summarized messages to the memory manager's immediate queue, with the watermark bypassed, unless the agent opted out of memory.- Held by
backend/packages/harness/deerflow/agents/memory/summarization_hook.py:14
F20 Should the model itself save, change or delete a memory fact right now (tool mode)? RULING · llm
- Answered how
With
memory.mode: tool, the lead model getsmemory_add,memory_updateandmemory_delete(plus search and get) and decides when to call them; the write goes to storage through the capacity policy without the extraction scope gate.- Held by
backend/packages/harness/deerflow/agents/memory/tools.py:119
F21 What should the model note down for later in a long task, and what compacted history is archived? RULING · llm
- Answered how
When
task_continuity.enabled(default off), the model may calltask_noteto save keyed working notes that are re-injected into later requests, and code archives compacted messages into bounded batches searchable throughhistory_search/history_read.- Held by
backend/packages/harness/deerflow/agents/task_continuity/tools.py:155
G. Judging the result
G1 Has the thread's active goal been fully met, judging only from what the conversation shows? RULING · llm
- Answered how
After every run turn on a thread with an active
/goal, the worker asks a chat model (the run's own model with thinking off) for a JSON verdict; a parsedsatisfied: truemakes the run a completion candidate, anything else either continues or stands down.- Held by
backend/packages/harness/deerflow/runtime/goal.py:539
G2 Is the finished turn in a state the goal evaluator may judge at all? RULE · code
- Answered how
Before calling the evaluator, worker code stands the goal down without a model call if the turn ended on an unanswered Human Input Card (
needs_user_input) or if there is no durable, fully checkpointed assistant end-of-turn (run_failed,no_durable_end_of_turn).- Held by
backend/packages/harness/deerflow/runtime/runs/worker.py:2806
G3 Should another hidden "keep working" turn be started for the goal? RULE · code
- Answered how
Code: continue only when the verdict is not satisfied, the blocker is
goal_not_met_yet, continuations used <max_continuations(capped at 8), no-progress count <max_no_progress_continuations(default 2), and the run did not end on a token or loop hard stop (token_capped/loop_capped); then a hidden<goal_continuation>HumanMessage restarts the graph.- Held by
backend/packages/harness/deerflow/runtime/goal.py:614
G4 Has the goal stopped making progress? RULING · code
- Answered how
Code hashes the text of the latest visible assistant message; if the blocker and that hash are the same as the previous evaluation's, the no-progress counter increments, otherwise it resets to 0. When the turn made tool calls and the previous evaluation recorded operation hashes, the counter instead resets to 0 only if the turn produced a successful tool result (tool name, arguments, output hash) not in that recorded set, and otherwise increments, whatever the reply text.
- Held by
backend/packages/harness/deerflow/runtime/goal.py:677
G5 Did the run actually hand over the output files it produced? RULING · code
- Answered how
At run end, worker code diffs a before/after workspace snapshot of the outputs directory; if any file changed and none of the changed paths is covered by a
present_filescall this run, the run is markederror("Artifact delivery incomplete") instead of success; a satisfied goal is cleared only after this passes.- Held by
backend/packages/harness/deerflow/runtime/runs/worker.py:402
G7 Do the receipt ids a sub-agent cites in its report point to real, successful tool calls? RULE · code
- Answered how
When a
tasksub-agent completes, code parses every[rN]/[rN tool_name]citation in its report and checks each against the receipts harvested from the child's own tool calls; unknown ids or non-success receipts makecitation_resolvedfalse; a report with action-like wording and zero citations is flagged UNVERIFIED. The verdict is shown to the lead; it never changes the task status.- Held by
backend/packages/harness/deerflow/agents/middlewares/receipt_verification.py:79
G8 Do the lead's acceptance criteria for a delegated task hold, as far as code can tell? RULING · code
- Answered how
When the lead attached
acceptance_criteriatotask(orbatch_task), code checks each criterion after the child finishes:file:exists / non-empty / json-valid / csv-columns andfile_written:by bounded reads in the shared workspace,tests_passed:<cmd>by matching a recorded bash execution with a success exit and a recognised test-summary shape; everything else is UNVERIFIED. The checklist is appended to the result the lead reads.- Held by
backend/packages/harness/deerflow/subagents/acceptance_checks.py:2155
H. Delegation
H1 Should this work go to a sub-agent, and with which type, prompt, acceptance criteria and context? RULING · llm
- Answered how
The lead model decides by emitting a
tasktool call withprompt,subagent_type, optionalacceptance_criteriaandcontext_mode(isolatedorsnapshot); the tool then validates and runs it.- Held by
backend/packages/harness/deerflow/tools/builtins/task_tool.py:755
H2 May a delegation of this type run for this caller? RULE · code
- Answered how
Code rejects the call unless the type is in the registry (built-ins, config custom agents, managed definitions) AND in the caller's snapshotted
allowed_subagentslist;bashis rejected when host bash is not allowed.- Held by
backend/packages/harness/deerflow/tools/builtins/task_tool.py:906
H3 How many sub-agents may the lead start in one response and in one run? RULE · code
- Answered how
After each lead model response, code keeps at most
max_concurrenttaskcalls (resolved against process capacity, 1-64) and at mostmax_totalper run (default 6, 1-50) counted from current-run entries in the durable delegation ledger; excess calls are stripped, and when the run total is exhausted a visible limit note is appended andstop_reason=subagent_limit_cappedis set.- Held by
backend/packages/harness/deerflow/agents/middlewares/subagent_limit_middleware.py:147
H4 Is there a free slot to run this sub-agent now, or must it queue or be refused? RULE · code
- Answered how
A process-wide admission controller (default 3 running) admits the execution, queues it up to
max_queuedwith a timeout, or rejects it immediately under therejectpolicy or when the caller asks for a no-wait slot (the executor does so when the task's input gate cannot queue,backend/packages/harness/deerflow/subagents/executor.py:1690).- Held by
backend/packages/harness/deerflow/subagents/capacity.py:68
H5 Which parts of the parent conversation go along with a delegated task? RULING · code
- Answered how
With
context_mode="snapshot"(chosen by the lead, H1), code captures the parent'ssummary_textplus retained genuine user messages, visible AI messages and paired tool results as one background HumanMessage of neutralized historical data; withisolated(default) only the delegated prompt goes.- Held by
backend/packages/harness/deerflow/subagents/context_snapshot.py:98
H6 What does the sub-agent do, and what does it report back? RULING · llm
- Answered how
The sub-agent runs its own model-tool loop on the delegated prompt, with its own system prompt plus a framework report contract. Its result is the matching direct-return tool result when the last turn ended on one, otherwise its last AIMessage text, otherwise the last message, or "No response generated".
- Held by
backend/packages/harness/deerflow/subagents/executor.py:1933
H7 Did the sub-agent finish, fail, or stop on a cap? RULE · code
- Answered how
At termination the executor reads the final state: a marked LLM-error fallback means FAILED; a direct-return tool error means FAILED; otherwise COMPLETED with any guard stop reason (
token_capped,loop_capped, ormodel_length_cappedwhen the provider cut the response at its output limit,backend/packages/harness/deerflow/subagents/executor.py:1398-1401); a turn-cap error salvages the last AI text as COMPLETED or else FAILED (F10); timeout gives TIMED_OUT (F11).- Held by
backend/packages/harness/deerflow/subagents/executor.py:2018
H8 What does the lead see about a finished delegation, and which earlier delegations stay open in its context? RULE · code
- Answered how
Code formats the status, result, stop reason and verdicts into the
taskToolMessage and its metadata, records each delegation in the durable ledger projected into later model calls, and on a new user turn marks earlier-run delegations stillin_progresswith no reply ascancelled.- Held by
backend/packages/harness/deerflow/agents/middlewares/durable_context_middleware.py:247
H9 Should a large set of tasks be submitted as a durable background batch? RULING · llm
- Answered how
When the SQL-backed batch submitter is installed, the lead model may call
batch_taskwith item keys, self-contained prompts and per-item criteria; a lease-based service runs items through the same executor and slots, and the lead later reads results withbatch_status/read_batch_result.- Held by
backend/packages/harness/deerflow/tools/builtins/batch_task_tool.py:154
H10 What does an external coding agent do with a task handed to it over ACP? RULING · external
- Answered how
When ACP agents are configured, the lead model may call
invoke_acp_agent; DeerFlow launches the configured external agent process (for example a Codex or MiniMax adapter), sends the prompt, and returns only its message text; the external agent decides how to do the work.- Held by
backend/packages/harness/deerflow/tools/builtins/invoke_acp_agent_tool.py:275
I. Learning and feedback
I1 Was this run's answer good (thumbs up or down)? RULING · human
- Answered how
A person rates a run +1 or -1 (with an optional comment) through the feedback API; the rating is stored per run and user and shown back in run and message listings.
- Held by
backend/app/gateway/routers/feedback.py:62
I2 Which saved memories about me are right? RULING · human
- Answered how
A person creates, edits or deletes individual memory facts through the memory API or settings UI; manually authored facts are marked
[MANUAL]in the next extraction prompt and the prompt asks the extraction model to keep them unless the user explicitly corrects them; code does not enforce it.- Held by
backend/app/gateway/routers/memory.py:412
I3 Should the agent rewrite its own persona, skills, tools or model for future turns? RULING · llm
- Answered how
In a custom agent's chat (not on webhook channels), the lead model may call
update_agentto replace its own SOUL.md and change its description, skill allow-list, tool-group allow-list or default model; the change takes effect on the next user turn.- Held by
backend/packages/harness/deerflow/tools/builtins/update_agent_tool.py:78
I4 Should the bootstrap conversation create a new custom agent, and with what persona and config? RULING · llm
- Answered how
In the bootstrap flow, the model calls
setup_agentto persist a new agent's SOUL.md and config.yaml.- Held by
backend/packages/harness/deerflow/tools/builtins/setup_agent_tool.py:58
I5 Should the agent save what it learned as a reusable skill, or edit an existing one? RULING · llm
- Answered how
When
skill_evolution.enabled(default off), the lead model may callskill_manageto create, edit, patch or add files to a custom skill; each write passes the static SkillScan gate (which returns no findings when SkillScan is turned off,backend/packages/harness/deerflow/skills/skillscan/orchestrator.py:228-229) and an LLM moderation call before it lands, and is recorded in skill history after it is written. If the moderation call fails, non-executable content can still be written whensecurity_fail_closedis false (backend/packages/harness/deerflow/skills/security_scanner.py:181-186).- Held by
backend/packages/harness/deerflow/tools/skill_manage_tool.py:353
How this map was made
Four readers each took a part of the agent and wrote seat cards from the source at an earlier commit. The map's author re-read every seat and corrected what the source did not support. For this edition every shown card was carried to the commit named above: its citations whose lines moved were renumbered, and every shown card citing code that changed was re-read at that commit. Reviews by a model from another family (read-only, at the commit named above) checked the answers against the code, and each of their findings was checked against the code before anything changed. Nothing on this page was produced by running their code.