| name | deep-research |
| description | Autonomous deep-research loop: iterative investigation, externalized state, convergence detection, fresh context per pass. |
| allowed-tools | ["Read","Write","Edit","Bash","Grep","Glob","Task","WebFetch","memory_context","memory_search"] |
| argument-hint | [topic] [:auto|:confirm] [--max-iterations=N] [--convergence=N] |
| version | 1.13.1.0 |
Autonomous Deep Research Loop
Note: Task is allowed for the command executor that manages the loop. The @deep-research agent itself is LEAF-only and does not dispatch sub-agents.
Iterative research protocol with fresh context per iteration, externalized state, and convergence detection for deep technical investigation.
Runtime path resolution:
- OpenCode/Copilot runtime:
.opencode/agents/*.md
- Claude runtime:
.claude/agents/*.md
- Codex runtime:
.codex/agents/*.toml
Operator contract precedence for this skill surface:
- Command entrypoint syntax in
.opencode/commands/deep/research.md
- Convergence math in
references/convergence/convergence.md and the deep-research YAML workflow
- Runtime agent inventories from the checked-in runtime directories above
Convergence Threshold Semantics
Default: 0.05 on newInfoRatio (fully-new=1.0, partially-new=0.5, +0.10 simplicity bonus, capped 1.0)
Semantic: convergenceThreshold compares newly discovered information against accumulated research knowledge with negative-knowledge emphasis. Lower = more iterations / higher signal threshold.
NOT INTERCHANGEABLE with siblings:
deep-review uses 0.10 default on weighted P0/P1/P2 severity ratio
deep-ai-council uses 0.20 default on adjudicator-verdict stability
Carrying threshold expectations across siblings will cause unexpected iteration counts. See this skill's changelog and decision records for the cross-sibling threshold research and parity invariants that confirm thresholds do not carry across siblings.
1. WHEN TO USE
Activation Triggers
Use this skill when:
- Deep investigation requiring multiple rounds of discovery
- Topic spans 3+ technical domains or sources
- Initial findings need progressive refinement
- Overnight or unattended research sessions
- Research where prior findings inform subsequent queries
Keyword triggers:
autoresearch
deep research
autonomous research
research loop
iterative research
multi-round research
deep investigation
comprehensive research
Use Cases
Use deep-research for multi-round technical investigation, source triangulation, repeated exploration with fresh context, and research sessions where prior findings should shape the next focus.
When NOT to Use
- Simple, single-question research (use direct codebase search or
/speckit:plan)
- Known-solution documentation (use
/speckit:plan)
- Implementation tasks (use
/speckit:implement)
- Quick codebase searches (use
@context or direct Grep/Glob)
- Fewer than 3 sources needed (single-pass research suffices)
2. SMART ROUTING
Pattern: aligned with the sk-doc smart-router resilience template.
Resource Domains
The router discovers markdown resources recursively from references/ and assets/, then applies intent scoring from RESOURCE_MAP. Keep routing domain-focused rather than hardcoding exhaustive inventories.
references/guides/quick_reference.md for the first-touch operator cheat sheet.
references/protocol/loop_protocol.md for lifecycle, dispatch, reducer sequencing, and command-owned state flow.
references/protocol/spec_check_protocol.md for bounded spec.md anchoring and generated-fence write-back.
references/convergence*.md for stop contracts, signals, recovery, graph gates, and reference-only convergence ideas.
references/state*.md for packet layout, JSONL records, markdown outputs, reducer ownership, and reconstruction.
references/guides/capability_matrix.md for runtime parity.
assets/*.md for markdown templates and prompt assets that are safe to route through guarded markdown loading.
Resource Loading Levels
| Level | When to Load | Resources |
|---|
| ALWAYS | Every skill invocation | Quick reference baseline |
| CONDITIONAL | If intent signals match | Loop, convergence, state, spec anchoring, runtime parity references |
| ON_DEMAND | Only on explicit request | Full reference set and markdown assets |
Phase Signals
| Phase | Signal | Primary Resources |
|---|
| Init | No JSONL exists or setup context | loop_protocol.md, state_format.md, state_jsonl.md |
| Iteration | Dispatch context includes iteration number | loop_protocol.md, state_outputs.md, convergence_signals.md |
| Stuck | Dispatch context includes recovery language | convergence_recovery.md, state_reducer_registry.md |
| Synthesis | STOP candidate or final report | convergence.md, state_outputs.md, spec_check_protocol.md |
Smart Router Pseudocode
The authoritative routing logic for scoped loading, weighted intent scoring, ambiguity handling, and graceful fallback.
- Pattern 1: Runtime Discovery -
discover_markdown_resources() recursively scans references/ and assets/.
- Pattern 2: Existence-Check Before Load -
load_if_available() guards paths, checks inventory, and suppresses repeats with seen.
- Pattern 3: Extensible Routing Key - intent labels route to loop resource families without static file inventories.
- Pattern 4: Multi-Tier Graceful Fallback -
UNKNOWN_FALLBACK_CHECKLIST requests disambiguation and missing families return a helpful notice.
from pathlib import Path
SKILL_ROOT = Path(__file__).resolve().parent
RESOURCE_BASES = (SKILL_ROOT / "references", SKILL_ROOT / "assets")
DEFAULT_RESOURCE = "references/guides/quick_reference.md"
INTENT_SIGNALS = {
"LOOP_SETUP": {"weight": 4, "keywords": ["autoresearch", "deep research", "research loop", "autonomous research", "setup", "init"]},
"ITERATION": {"weight": 4, "keywords": ["iteration", "next round", "continue research", "research cycle", "delta", "focus"]},
"CONVERGENCE": {"weight": 4, "keywords": ["convergence", "stop condition", "diminishing returns", "legal stop", "newInfoRatio"]},
"RECOVERY": {"weight": 4, "keywords": ["stuck", "recovery", "timeout", "reconstruct", "blocked stop", "blocked_stop"]},
"STATE": {"weight": 4, "keywords": ["state file", "jsonl", "strategy", "dashboard", "registry", "lineage"]},
"SPEC_ANCHORING": {"weight": 3, "keywords": ["spec.md", "generated fence", "folder_state", "lock", "spec anchoring"]},
"RUNTIME_PARITY": {"weight": 3, "keywords": ["runtime", "capability", "parity", "codex", "claude"]},
"RESOURCE_MAP": {"weight": 3, "keywords": ["resource map", "resource-map", "inventory", "coverage gate"]},
}
RESOURCE_MAP = {
"LOOP_SETUP": ["references/protocol/loop_protocol.md", "references/state/state_format.md", "references/state/state_jsonl.md", "references/protocol/spec_check_protocol.md"],
"ITERATION": ["references/protocol/loop_protocol.md", "references/state/state_outputs.md", "references/convergence/convergence_signals.md"],
"CONVERGENCE": ["references/convergence/convergence.md", "references/convergence/convergence_signals.md", "references/convergence/convergence_graph.md"],
"RECOVERY": ["references/convergence/convergence_recovery.md", "references/state/state_reducer_registry.md"],
"STATE": ["references/state/state_format.md", "references/state/state_jsonl.md", "references/state/state_outputs.md", "references/state/state_reducer_registry.md"],
"SPEC_ANCHORING": ["references/protocol/spec_check_protocol.md", "references/state/state_outputs.md"],
"RUNTIME_PARITY": ["references/guides/capability_matrix.md"],
"RESOURCE_MAP": ["references/protocol/loop_protocol.md", "references/state/state_outputs.md"],
}
LOADING_LEVELS = {
"ALWAYS": [DEFAULT_RESOURCE],
"ON_DEMAND_KEYWORDS": ["full protocol", "all references", "complete reference", "resume deep research", "state log", "research/iterations", "deltas", "overnight research", "active lineage", "reference-only", "optimizer"],
"ON_DEMAND": [
"references/protocol/loop_protocol.md",
"references/protocol/spec_check_protocol.md",
"references/convergence/convergence.md",
"references/convergence/convergence_signals.md",
"references/convergence/convergence_recovery.md",
"references/convergence/convergence_graph.md",
"references/convergence/convergence_reference_only.md",
"references/state/state_format.md",
"references/state/state_jsonl.md",
"references/state/state_outputs.md",
"references/state/state_reducer_registry.md",
"references/guides/capability_matrix.md",
],
}
UNKNOWN_FALLBACK_CHECKLIST = [
"Confirm setup vs iteration vs convergence vs state recovery",
"Confirm the target spec folder and research packet",
"Provide the current phase, latest iteration, or failing state file",
"Confirm whether full references or quick routing guidance are needed",
]
def _task_text(task) -> str:
return " ".join([
str(getattr(task, "text", "")),
str(getattr(task, "query", "")),
" ".join(getattr(task, "keywords", []) or []),
]).lower()
def _guard_in_skill(relative_path: str) -> str:
resolved = (SKILL_ROOT / relative_path).resolve()
resolved.relative_to(SKILL_ROOT)
if resolved.suffix.lower() != ".md":
raise ValueError(f"Only markdown resources are routable: {relative_path}")
return resolved.relative_to(SKILL_ROOT).as_posix()
def _guard_resource_map(resource_map: dict[str, list[str]]) -> None:
for intent, resources in resource_map.items():
for relative_path in resources:
guarded = _guard_in_skill(relative_path)
if guarded.startswith("references/"):
tail = guarded.removeprefix("references/")
if "/" not in tail and "-" in Path(tail).stem:
raise ValueError(f"RESOURCE_MAP must target canonical references, not compatibility stubs: {intent} -> {guarded}")
def discover_markdown_resources() -> set[str]:
docs = []
for base in RESOURCE_BASES:
if base.exists():
docs.extend(path for path in base.rglob("*.md") if path.is_file())
return {doc.relative_to(SKILL_ROOT).as_posix() for doc in docs}
def score_intents(task) -> dict[str, float]:
text = _task_text(task)
scores = {intent: 0.0 for intent in INTENT_SIGNALS}
for intent, cfg in INTENT_SIGNALS.items():
for keyword in cfg["keywords"]:
if keyword in text:
scores[intent] += cfg["weight"]
return scores
def select_intents(scores: dict[str, float], ambiguity_delta: float = 1.0, max_intents: int = 2) -> list[str]:
ranked = sorted(scores.items(), key=lambda item: item[1], reverse=True)
if not ranked or ranked[0][1] <= 0:
return ["LOOP_SETUP"]
selected = [ranked[0][0]]
if len(ranked) > 1 and ranked[1][1] > 0 and (ranked[0][1] - ranked[1][1]) <= ambiguity_delta:
selected.append(ranked[1][0])
return selected[:max_intents]
def route_deep_research_resources(task):
_guard_resource_map(RESOURCE_MAP)
_guard_resource_map({"ALWAYS": LOADING_LEVELS["ALWAYS"], "ON_DEMAND": LOADING_LEVELS["ON_DEMAND"]})
inventory = discover_markdown_resources()
scores = score_intents(task)
intents = select_intents(scores)
loaded = []
seen = set()
def load_if_available(relative_path: str) -> None:
guarded = _guard_in_skill(relative_path)
if guarded in inventory and guarded not in seen:
load(guarded)
loaded.append(guarded)
seen.add(guarded)
for relative_path in LOADING_LEVELS["ALWAYS"]:
load_if_available(relative_path)
if max(scores.values() or [0]) < 0.5:
return {
"intents": intents,
"intent_scores": scores,
"load_level": "UNKNOWN_FALLBACK",
"needs_disambiguation": True,
"disambiguation_checklist": UNKNOWN_FALLBACK_CHECKLIST,
"resources": loaded,
}
matched_intents = []
for intent in intents:
before_count = len(loaded)
for relative_path in RESOURCE_MAP.get(intent, []):
load_if_available(relative_path)
if len(loaded) > before_count:
matched_intents.append(intent)
text = _task_text(task)
if any(keyword in text for keyword in LOADING_LEVELS["ON_DEMAND_KEYWORDS"]):
for relative_path in LOADING_LEVELS["ON_DEMAND"]:
load_if_available(relative_path)
result = {"intents": intents, "intent_scores": scores, "resources": loaded}
if not matched_intents:
result["notice"] = f"No knowledge base found for intent(s): {', '.join(intents)}"
return result
3. HOW IT WORKS
Invocation Contract
This skill is invoked exclusively through /deep:research:auto or /deep:research:confirm. The command YAML owns state, dispatch, convergence, and synthesis.
Never simulate the loop with ad hoc shell dispatch, nested CLI loops, direct @deep-research Task dispatch, /tmp prompt files, or state outside the resolved local research packet.
Executor Selection Contract
The YAML workflow owns executor selection. Native @deep-research is the default path; CLI executors are routed through the workflow, not through ad hoc shell loops.
Cross-CLI delegation is possible inside each executor sandbox but discouraged. Do not invoke the same CLI from within itself, and do not assume auth from a parent executor propagates to child CLIs.
Executor invariants:
- Produce a non-empty iteration markdown file at
{state_paths.iteration_pattern}.
- Append a JSONL delta record to
{state_paths.state_log} with required fields: type, iteration, newInfoRatio, status, and focus.
- Respect the LEAF-agent constraint: no sub-dispatch, no nested loops, and max 12 tool calls per iteration.
Failure modes include iteration_file_missing, iteration_file_empty, jsonl_not_appended, jsonl_missing_fields, and jsonl_parse_error. Three consecutive failures route to stuck recovery.
Lifecycle Contract
Runtime-supported lifecycle modes:
| Mode | Meaning |
|---|
new | First run against the spec folder |
resume | Continue the active lineage and append a typed resumed JSONL event |
restart | Archive the existing research tree, mint a fresh sessionId, increment generation, and append a typed restarted event |
Deferred modes are fork and completed-continue. They are reserved but not runtime-supported.
Code-Graph Readiness TrustState Surface
The live code-graph readiness contract reaches four TrustState values: live, stale, absent, and unavailable.
cached, imported, rebuilt, and rehomed remain declared in the shared TrustState type for compatibility, but the readiness helpers used here do not emit them today.
Resource Map Integration
When {spec_folder}/resource-map.md exists at init, deep research promotes it from ad hoc context to canonical packet state.
- Persist
resource_map_present: true in deep-research-config.json.
- Read the map once during init and summarize it into
deep-research-strategy.md Known Context.
- The snapshot MUST include per-section entry counts across
READMEs, Documents, Commands, Agents, Skills, Specs, Scripts, Tests, Config, and Meta.
- The snapshot MUST also include a one-line theme summary for each resource-map section so later iterations inherit the map's structure without rereading the entire file.
- Per-iteration prompts surface
resource-map.md as the exclusion set for previously inventoried files.
- Treat files already listed on the map as known inventory, not as net-new discoveries.
- Only flag files as gaps when they look relevant to the active investigation and are missing from the map.
- Final synthesis cites
{spec_folder}/resource-map.md in research.md References when the map was present at init.
- Convergence also emits
{artifact_dir}/resource-map.md from research delta evidence unless the operator passes --no-resource-map.
When {spec_folder}/resource-map.md is absent at init:
- Persist
resource_map_present: false.
- Write
resource-map.md not present; skipping coverage gate into Known Context.
- Omit the exclusion-set hint from iteration guidance.
- Continue the loop normally; absence is informational, not a failure.
Architecture: 3-Layer Integration
/deep:research owns the YAML workflow, which initializes state, dispatches one LEAF iteration at a time, evaluates convergence, synthesizes research/research.md, and saves continuity. The @deep-research agent executes only one research cycle per dispatch.
State Packet Location
The research state packet always lives under the target spec's local research/ folder. Root-spec targets use {spec_folder}/research/ directly. Child-phase and sub-phase targets use flat-first: a first run with an empty research/ directory writes flat at {spec_folder}/research/. A pt-NN subfolder ({basename(spec_folder)}-pt-{NN}) is allocated only when prior content already exists in research/ for a non-matching target (continuation runs reuse the existing flat artifact or matching pt-NN packet). This avoids the unnecessary pt-01 wrapper on first runs.
Example (first run on a child phase): .../026-graph.../019-system-hardening/001-initial-research/004-desc-regen/ writes to 004-desc-regen/research/ directly.
Example (subsequent run with prior content for a different target): 004-desc-regen/research/004-desc-regen-pt-02/ (pt-NN allocated as a sibling to the prior content).
State files include deep-research-config.json, deep-research-state.jsonl, deep-research-strategy.md, deep-research-findings-registry.json, deep-research-dashboard.md, .deep-research-pause, .deep-research.lock, resource-map.md, research.md, and iterations/iteration-NNN.md.
v(next): deep-research-findings-registry.json is the canonical registry name for sibling-skill consistency.
Core Innovation: Fresh Context Per Iteration
Each agent dispatch gets a fresh context window. State continuity comes from files, not memory. This solves context degradation in long research sessions.
Adapted from: karpathy/autoresearch (loop concept), AGR (fresh context "Ralph Loop"), pi-autoresearch (JSONL state), autoresearch-opencode (context injection).
Data Flow
Init creates config, strategy, and state logs. Each loop reads state, checks convergence, dispatches @deep-research, writes iteration markdown and JSONL deltas, refreshes reducer-owned state, and either continues or synthesizes and saves continuity.
Late-INIT can also anchor the research run to spec.md: the workflow acquires the advisory lock, classifies folder_state, seeds or appends bounded context before LOOP, and then syncs one generated findings block back into spec.md during SYNTHESIS while keeping research/research.md canonical.
That contract is exact:
folder_state is always one of no-spec, spec-present, spec-just-created-by-this-run, or conflict-detected
- the advisory lock lives at
research/.deep-research.lock from late INIT through save, skip-save, or cancel cleanup
- post-synthesis write-back replaces exactly one
<!-- BEGIN GENERATED: deep-research/spec-findings --> ... <!-- END GENERATED: deep-research/spec-findings --> fence under the chosen host anchor
- the full bounded mutation rules live in spec_check_protocol.md
Key Concepts
Research continuity is externalized to files, each iteration starts fresh, convergence uses newInfoRatio/stuck/question signals, strategy and registry are reducer-owned, JSONL remains append-only, and final synthesis consolidates research/research.md.
4. RULES
ALWAYS
- Read state first -- Agent must read JSONL and strategy.md before any research action
- Init validates the research charter (Non-Goals + Stop Conditions in
deep-research-strategy.md, Step 5a): appends empty placeholders if missing, presents the charter for review in confirm mode.
- One focus per iteration -- Pick ONE research sub-topic from strategy.md "Next Focus"
- Externalize findings -- Write to iteration-NNN.md, not held in agent context
- Update strategy -- Append to "What Worked"/"What Failed", update "Next Focus"
- Report newInfoRatio -- Every iteration JSONL record must include newInfoRatio
- Respect exhausted approaches -- Never retry approaches in the "Exhausted" list
- Cite sources -- Every finding must cite
[SOURCE: url] or [SOURCE: file:line]
- Use generate-context.js for memory saves -- Never manually create memory files
- Treat research/research.md as workflow-owned -- Iteration findings feed synthesis; the workflow owns the canonical
research/research.md
- Document ruled-out directions per iteration -- Every iteration must include what was tried and failed
- Report newInfoRatio + 1-sentence novelty justification -- Every JSONL iteration record must include both
- Quality guards must pass before convergence -- Source diversity, focus alignment, and no single-weak-source checks must pass before STOP can trigger
- Respect reducer ownership -- The workflow reducer, not the agent, is the source of truth for strategy machine-owned sections, dashboard metrics, and findings registry updates
- Use canonical packet names only -- Write
deep-research-* artifacts and research/.deep-research-pause; legacy names are read-only migration aliases
- Invoke through the command workflow -- Use
/deep:research:auto or /deep:research:confirm, and let the YAML workflow own dispatch
NEVER
- Dispatch sub-agents -- @deep-research is LEAF-only (NDP compliance)
- Hold findings in context -- Write everything to files
- Exceed TCB -- Target 8-11 tool calls per iteration (max 12)
- Ask the user -- Autonomous execution; make best-judgment decisions
- Skip convergence checks -- Every iteration must be evaluated
- Modify config after init -- Config is read-only after initialization
- Overwrite prior findings -- Append to research/research.md, never replace
- Implement fixes during research -- Report findings only; implementation is a separate follow-up step.
- Simulate loop dispatch -- Do not write custom shell loops, nested CLI loops,
/tmp prompt dispatchers, or direct Task loops for @deep-research. Command-driven fan-out via step_fanout_spawn in the YAML is SUPPORTED — use --executor/--executors/--concurrency flags on the command; ad-hoc shell fan-out and intra-lineage wave orchestration remain forbidden.
Iteration Status Enum
complete | timeout | error | stuck | insight | thought
insight: Low newInfoRatio but important conceptual breakthrough
thought: Analytical-only iteration, no evidence gathering
EXPERIMENTAL / REFERENCE-ONLY FEATURES
These concepts remain documented for future design work, but they are not part of the live executable contract for /deep:research:
- Wave orchestration -- parallel question fan-out and pruning within a single lineage remains reference-only (intra-lineage wave)
- Checkpoint commits -- per-iteration git commits
- Multi-lineage fan-out -- SUPPORTED via
--executor/--executors flags on the command (see §8 EXAMPLES). Each lineage is an independent full loop in {artifact_dir}/lineages/{label}/, converging independently. This is not "wave orchestration"; it is N independent loops.
- Alternate CLI dispatch -- process-isolated
claude -p or similar dispatch modes are used internally by fanout-run.cjs; do not write them ad-hoc from within a research session
ESCALATE IF
- 3+ consecutive timeouts -- Infrastructure issue, not research problem
- State file corruption unrecoverable -- Cannot reconstruct from JSONL or iteration files
- All approaches exhausted with questions remaining -- Research may need human guidance
- Security concern in findings -- Proprietary code or credentials discovered
- All recovery tiers exhausted -- No automatic recovery path remaining
5. REFERENCES
Core documentation: references/guides/quick_reference.md, references/protocol/loop_protocol.md, references/protocol/spec_check_protocol.md, references/convergence/convergence.md, and references/state/state_format.md.
Focused convergence references: references/convergence/convergence_signals.md, references/convergence/convergence_recovery.md, references/convergence/convergence_graph.md, and references/convergence/convergence_reference_only.md.
Focused state references: references/state/state_jsonl.md, references/state/state_outputs.md, and references/state/state_reducer_registry.md.
Templates: assets/deep_research_config.json, assets/deep_research_strategy.md, assets/deep_research_dashboard.md, assets/prompt_pack_iteration.md.tmpl, and assets/runtime_capabilities.json.
Cross-skill alignment: deep-research owns iterative investigation. Its shared resource family mirrors deep-review and deep-ai-council, but its vocabulary remains novelty, sources, negative knowledge, question coverage, and research synthesis rather than severity findings or council agreement.
6. SUCCESS CRITERIA
Loop Completion
- Research loop ran to convergence or max iterations
- All state files present and consistent (config, JSONL, strategy)
- research/resource-map.md produced from converged deltas unless
config.resource_map.emit == false (operator flag: --no-resource-map)
- research/research.md produced with findings from all iterations
- Canonical continuity surfaces updated via generate-context.js
Quality Gates
Blocking gates: valid config/strategy/state before loop, iteration markdown plus JSONL plus reducer refresh per iteration, final research/research.md and convergence report after loop, and quality guards for source diversity/focus/no weak single source. Continuity save is expected but non-blocking.
Convergence Report
Every completed loop produces a convergence report:
- Stop reason (converged, max_iterations, all_questions_answered, stuck_unrecoverable)
- Total iterations completed
- Questions answered ratio
- Average newInfoRatio trend
7. INTEGRATION POINTS
Framework Integration
This skill operates within the behavioral framework defined in the active runtime's root doc (CLAUDE.md, AGENTS.md, or CODEX.md).
Key integrations:
- Gate 2: Skill routing via
skill_advisor.py (keywords: autoresearch, deep research)
- Gate 3: File modifications require spec folder question per the root doc Gate 3
- Continuity:
/speckit:resume is the operator-facing recovery surface; canonical packet continuity is written via generate-context.js
- Orchestrator: @orchestrate dispatches @deep-research as LEAF agent
Continuity Integration
Before research, recover context with /speckit:resume using handover.md -> _memory.continuity -> spec docs. During each iteration, write iterations/iteration-NNN.md, append JSONL, and let the reducer refresh strategy/registry/dashboard. After research, save continuity through generate-context.js.
Command Integration
| Command | Relationship |
|---|
/deep:research | Primary invocation point |
/speckit:resume | Canonical recovery surface before resuming or extending an active packet |
/speckit:plan | Next step after deep research completes |
/memory:save | Manual memory save (deep research auto-saves) |
8. REFERENCES AND RELATED RESOURCES
The router discovers reference and markdown asset docs dynamically. Start with references/guides/quick_reference.md, then route to loop protocol, spec anchoring, convergence, state, runtime parity, or recovery references based on intent.
Scripts: scripts/reduce-state.cjs, scripts/runtime-capabilities.cjs.
Related skills: deep-review for iterative audit loops, deep-loop-runtime for shared executor/state/coverage-graph runtime, and system-spec-kit for command-owned state, packet anchoring, and continuity saves.