research
docs://contents>
docs/sop-referencedoc 01

SOP

The three parts of an SOP Every SOP (Standard Operating Procedure) is a JSON document with a fixed top-level shape. The sop_id is the registry key used by parent SOPs composing this one. The intent_match is the routing string — the engine matches user intent against it to select the SOP to run. The global_config sets run-wide limits that no step can override.

{ "sop_id": "company_profile", "intent_match": "User provides only a company website URL and requests a deep, evidence-backed Company Intelligence Profile built by expanding research across the public web until information becomes repetitive.", "global_config": { "strict_mode": true, "max_global_workflow_timeout_ms": 14400000 }, "policies": [], "state_machine": []} strict_mode: true means verification failures halt the run instead of soft-passing. The timeout is a hard ceiling on the whole workflow — four hours in this case — enforced by the engine, not by any prompt instruction.

The state machine state_machine is an array of steps. Each step is a node in a DAG: dependencies names the steps that must complete before it runs. The engine resolves the graph — sequential steps chain, parallel steps fan out across their dependencies.

Four fields appear on every step:

Field Purpose step_id Unique identifier within the SOP; what dependencies references type sequential or parallel — how the step schedules against siblings action_type The kind of work: HUMAN, EXECUTION, REASONING, or EXECUTE_SUB_SOP verification The prompt that gates whether the step's output is accepted Action types HUMAN — intake and approval gates A HUMAN step parks the run and waits for a person. No compute burns while parked.

{ "step_id": "PR01", "type": "sequential", "action_type": "HUMAN", "dependencies": [], "step_description": "Capture the single required input: the company website URL, the research seed.", "metadata": { "parent_id": "root", "depth": 1, "is_sufficiently_atomic": true }, "Hitl": { "mode": "intake", "prompt": "Gather exactly one field: (1) the company website URL. Do not proceed until it is present. Ask for nothing else." }, "verification": { "include": true, "prompt": "Check the answer contains a usable website address. Set status strictly to Failed if no address was provided." }} The Hitl.mode distinguishes intake gates from approval gates. Verification for a HUMAN step checks the human's answer, not a model output.

EXECUTION — governed tool calls An EXECUTION step calls a tool from the governed registry. The shard names the MCP server the tool lives on. execution_mode is single (one call) or dynamic (fan-out over items).

{ "step_id": "PR02", "type": "sequential", "action_type": "EXECUTION", "dependencies": ["PR01"], "step_description": "Acquire the company's own website once — the seed and reference point for all research, never assumed complete.", "metadata": { "parent_id": "root", "depth": 1, "is_sufficiently_atomic": true }, "execution": { "tool": "tavily_crawl", "shard": "tavily-mcp", "execution_mode": "single", "risk": "" }, "schema_extractor": { "prompt": "Use the website URL from the intake as the 'url' to crawl. Add 'https://' if it's missing; otherwise use it exactly as given." }, "verification": { "include": true, "prompt": "Check the crawl captured this company's own website — real content from their pages, however few, that identifies the company. A small or sparse site is fine. Set status strictly to Failed if the content belongs to a different site or company, or is too thin to recognize the company at all." }} The schema_extractor prompt maps upstream state into the tool's input shape — it is the only place input formatting happens, and it is declared, not improvised.

REASONING — model work, verified A REASONING step is where the LLM works. The planner prompt is declared in the SOP; the verification prompt decides whether the output advances.

{ "step_id": "PR03", "type": "sequential", "action_type": "REASONING", "dependencies": ["PR02"], "planner": { "include": true, "prompt": "Read the company's website content and work out who this company is: its name, brands, products, key people, locations, industry, the words it uses about its customers, and its domains. Keep the exact facts — name, domain, products, people, terminology the site actually states — that will later confirm outside information is about this company rather than a similar one. The site may be small and missing much of this: record what is actually there, leave the rest as not found, never guess." }, "verification": { "include": true, "prompt": "Check the identity is real: a company name, the site's domain, and only information actually found on the site. Missing details on a small site are fine. Set status strictly to Failed if no company name can be established, the domain is wrong, anything was invented, or details clearly belong to a different company." }} Note the phrasing discipline the verification prompt enforces: never guess, record what is actually there, set status strictly to Failed. Verification is the schema checkpoint that stops cascading errors — an invalid REASONING output never becomes the input to the next step.

EXECUTE_SUB_SOP — composition An EXECUTE_SUB_SOP step runs another SOP as a child. In dynamic mode, the child fans out over locked items from the parent's state — one branch per item, no human intake inside the branch.

{ "step_id": "RP08", "type": "parallel", "action_type": "EXECUTE_SUB_SOP", "dependencies": ["RP05B"], "step_description": "Run the complete competitor research branch for every locked competitor — the branch reads its locked item directly; no human intake inside the branch.", "policy": { "include": false }, "execution": { "mode": "dynamic", "sub_sop_id": "competitor_move_deep_dive" }, "verification": { "include": true, "prompt": "Check every locked competitor returned its complete FINAL corrected report from the deep dive branch — the post-audit report with its disposition list — containing: the evidence dossier with verbatim passages, dates, and provenance tiers; the change list; strategic move records with their evidence passages, URLs, corroboration counts counting independent sources only, and verification flags (including 'unverified — single source' where applicable); the thesis; the implications matrix naming the target company; and the full source list with dates and tiers. Set status strictly to Failed if any locked competitor is missing its report, a report lacks its core sections, or any of its three indicator lists." }} This is the composition primitive: SOPs call SOPs, and skills are the top of that ladder. See the skills reference for the full hierarchy.

Verification semantics Every verification prompt shares the same contract: it inspects the step's output against the step's own description, and it can only set two statuses — pass, or strictly Failed. There is no partial credit. A failed step either retries within its declared budget, triggers compensation, or parks for a human — depending on the failure classification. It never silently passes bad data downstream.

Metadata metadata.parent_id and metadata.depth track where the step sits in the composition tree — root for top-level SOPs, the parent step's id for sub-SOP branches. is_sufficiently_atomic flags steps that cannot be decomposed further.