System Deep Loop
One skill, four active workflow families, one nested runtime layer. system-deep-loop is the public, advisor-routable home for active deep-loop personas; runtime/ is the frozen, MCP-free infrastructure layer it consumes (formerly the separate deep-loop-runtime skill, merged into this hub 2026-07-08). This hub holds NO per-mode convergence, state, or synthesis logic — each active mode keeps its own contract in its packet, and the hub only routes by workflowMode through mode-registry.json.
Use @context for one-shot retrieval, /deep:research for iterative investigation with a bounded context snapshot, /deep:review for iterative audit with a bounded review snapshot, or /speckit:plan for implementation planning.
1. WHEN TO USE
Use this skill (through the hub) for any active deep-loop workflow. Invoke it as Skill(system-deep-loop) (optionally with a mode hint such as research: <request>); the hub classifies the request, resolves a workflowMode, and loads the matching nested mode packet. Active /deep:* commands and native agent types remain as complementary surfaces over the same packets.
| Mode | Use it for | Packet | Command | Agent |
|---|
| research | Outward, web + code iterative investigation → research/research.md | system-deep-loop/deep-research/ | /deep:research | deep-research |
| review | Iterative review loop → P0/P1/P2 findings + verdict | system-deep-loop/deep-review/ | /deep:review | deep-review |
| ai-council | Multi-seat planning deliberation → ai-council/** artifacts | system-deep-loop/deep-ai-council/ | /deep:ai-council | ai-council |
| improvement (3 lanes) | Evaluator-first improvement: agent-improvement, model-benchmark, skill-benchmark | system-deep-loop/deep-improvement/ | /deep:agent-improvement · /deep:model-benchmark · /deep:skill-benchmark | deep-improvement |
When NOT to Use
- A single quick read/edit (no loop) — use the relevant code or doc skill directly.
- Backend/runtime support (executor, coverage-graph, scoring, fan-out) — that is
runtime/, consumed here, not invoked as a user workflow (formerly the separate deep-loop-runtime skill).
2. SMART ROUTING
Routing is registry-driven (invokable-hub, Option E) in two stages. Stage 1 (hub → mode): mode-registry.json is the single source of truth; the hub reads it and does not re-derive the mapping. When invoked as Skill(system-deep-loop[, "<mode>: <request>"]), the hub classifies the request to a workflowMode, resolves it through the registry, and loads registry[mode].packet. The advisor routes any deep-loop query to the single identity system-deep-loop; the hub then picks the mode. Stage 2 (mode → leaves): the root ROUTER.md maps the request's deep-loop intent to the exact packet-local leaf resources that mode loads. The two layers stay separate: the hub never emits leaf paths, and the surface router never re-decides the mode. The /deep:* commands and native agent types remain as complementary surfaces — they reach the same packets through static routers/agent definitions — and the hub holds NO per-mode logic.
Compiled routing (default-on, flag-gated, additive). Resolve the mode via the compiled router contract first:
node .opencode/bin/compiled-route.cjs --hub system-deep-loop --prompt "<task>"
Follow the returned decision — route (use its targets), clarify/defer (disambiguate), reject (refuse). On a {"servingAuthority":"legacy"} sentinel or any error, use the routing below. The front door self-gates on serving-authority. Compiled routing is now the default for system-deep-loop; set SPECKIT_COMPILED_ROUTING=0 to force legacy routing fleet-wide — the explicit kill-switch.
Surface Router — per-mode leaf sets
Stage 2 of routing lives in ROUTER.md at the hub root, next to SKILL.md and README.md. It defines the per-mode leaf-intent model (the research loop protocol/state/convergence leaves, the review loop protocol/completion/convergence leaves, the ai-council loop protocol/scoring/output-schema leaves, the agent-improvement candidate/score/promotion-gate leaves, and the model- and skill-benchmark evaluator leaves), the machine-readable DEFAULT_RESOURCE / INTENT_SIGNALS / RESOURCE_MAP block that the deterministic router-replay and benchmarks parse, and the how-to-read rules (dominant intent → one leaf set; near-tied intents → deduped union; no keyword match → hub defer, never a silent default to a mode). Every RESOURCE_MAP path is packet-qualified and converts to the canonical (workflowMode, leafResourceId) pair at the one contract boundary.
ROUTER.md stays a separate document on purpose: the router-replay contract resolves the hub's mode from hub-router.json and reads the leaf sets from the surface document — the machine block must not move into SKILL.md (the replay would treat it as the hub's own router and lose the mode projection) or into hub-router.json (schema handoff-ambiguity rule).
This hub is an intent/registry router, not a keyed resource-discovery router: at runtime it omits discover_markdown_resources and only guards registry-selected packet loads, never selecting hub-level references/<key>/ or assets/<key>/ resources by runtime key. It does carry a second-layer surface router at the root ROUTER.md — a benchmark/replay artifact (mirroring sk-prompt/sk-code) that maps a resolved mode's intent to packet-qualified child leaves so router-replay can emit canonical {workflowMode, leafResourceId} typed pairs against leaf-manifest.json. That surface layer never re-decides the mode and is not a runtime hub discovery surface; the hub still routes by workflowMode through mode-registry.json alone.
Note on the frontmatter allowed-tools grant
The hub's own routing logic is read-only (classify, guard a path, load a packet). The frontmatter allowed-tools list is nonetheless broad because, per the two-axis hub canon contract, a hub's tool grant MUST equal the exact union of every registered mode's toolSurface.allowed in mode-registry.json — not the tool set the hub's own logic uses. This is a hard invariant enforced by parent-skill-check.cjs (check 3j: "hub allowed-tools equals the union of mode tool surfaces"); narrowing the frontmatter grant to only what routing-only logic needs would fail that check and break every mode whose toolSurface isn't a subset of the narrowed list. Treat the breadth of allowed-tools as evidence of the child modes' combined needs, not of mutating logic living in the hub.
The three-tier discriminator
workflowMode — the public active mode key: research, review, ai-council, and the three improvement lanes agent-improvement, model-benchmark, skill-benchmark.
runtimeLoopType — the graph-backed convergence key consumed by runtime/scripts/convergence.cjs (validated against active research|review|council). Explicit null for custom and improvement backends; never inferred from workflowMode. Note ai-council maps to runtimeLoopType: council.
backendKind — which backend runs the mode: runtime-loop-type (research/review/ai-council) or improvement-host (deep-improvement/scripts/shared/loop-host.cjs --mode).
Routing rule
UNKNOWN_FALLBACK_CHECKLIST = [
"Confirm whether this is research, review, ai-council, or one improvement lane (agent-improvement, model-benchmark, skill-benchmark) work",
"Confirm the target artifact: research.md, a review verdict, ai-council deliberation artifacts, or an improvement candidate",
"Confirm the matching /deep:* command or agent type when one is already known",
"Confirm the backend expectations: runtimeLoopType (research/review/council) or the improvement-host lane",
]
classify the request to a workflowMode (dominant deep-loop intent; mode hint like "research: ..." overrides)
guard mode-registry.json inside SKILL_ROOT and read it as data
if classifier confidence is low or no mode dominates:
→ return UNKNOWN_FALLBACK with disambiguation_checklist = UNKNOWN_FALLBACK_CHECKLIST
else:
→ resolve workflowMode from the hint / classified intent (or the /deep:* command / advisor alias)
→ find registry[mode]; if missing, return UNKNOWN_FALLBACK instead of loading a guessed path
→ guard registry[mode].packet/SKILL.md inside SKILL_ROOT and load it only if the packet directory and SKILL.md both exist
e.g. registry["research"].packet → system-deep-loop/deep-research/SKILL.md
(the 3 improvement modes all share the system-deep-loop/deep-improvement/ packet)
→ if registry[mode].runtimeLoopType !== null: backend = convergence.cjs --loop-type <runtimeLoopType>
else: backend = improvement loop-host (--mode), per backendKind
Router-driven loads MUST use _guard_in_skill(relative_path) before load(), reject paths that escape this skill or do not end in .md, and check if packet_base.exists() plus if packet_skill.exists() before loading. The fallback must name the unresolved workflowMode when known, avoid loading any guessed packet, and ask the operator to provide one of the registered modes or the matching /deep:* command.
Intent classification favors the single dominant active deep-loop mode; a mode hint (research: ..., review: ..., ai-council: ..., or an improvement lane) overrides the classifier. The legacy advisor projection maps stay hardcoded and drift-guarded against the registry, and the command files remain static routers with hardcoded asset/mode routing; neither resolves from mode-registry.json at runtime, but both stay equal to its projection.
Per-mode behavior is not flattened: each active packet keeps its own convergence math, state shape, artifacts, and tool-permission guards (research has WebFetch; review/ai-council are code/inward-only; improvement is the only direct mutation family). Exactly one graph-metadata.json — this hub's — is preserved, so the advisor discovers exactly one skill identity regardless of which surface (hub Skill(), /deep:* command, or agent) reaches a mode.
3. HOW IT WORKS
Layout
system-deep-loop/
SKILL.md # this routing hub (no per-mode logic)
ROUTER.md # stage-two surface router (deep-loop intent -> leaf sets)
mode-registry.json # the three-tier discriminator + advisorRouting (single source of truth)
graph-metadata.json # the ONE advisor identity for the whole skill
deep-research/ deep-review/ deep-ai-council/ deep-improvement/ # active mode packets
shared/synthesis/ # workflows-shared synthesis (e.g. emitResourceMap)
Each active mode packet keeps its own SKILL.md, references/, scripts/, assets/, feature-catalog/, or manual-testing-playbook/ as applicable, with internal paths repointed and no per-packet graph-metadata.json — only this hub carries one, so the advisor discovers exactly one skill. The deep-ai-council packet folder follows the standard folder == packetSkillName convention (deep-ai-council); its legacy public surfaces (the /deep:ai-council command and the ai-council agent) intentionally keep the shorter ai-council key, so always resolve the packet path through mode-registry.json rather than hardcoding it.
Backend
All modes consume runtime/ (frozen, MCP-free): executor config, prompt-pack, validation, atomic state, coverage-graph, Bayesian scoring, fan-out, the council primitives, and the promoted plumbing (capability resolver, artifact-root, loop-lock CLI, lifecycle taxonomy). The runtime never gains an improvement loopType — improvement stays host-driven.
4. RULES
✅ ALWAYS
- ALWAYS resolve a mode through
mode-registry.json (read the packet key; never hardcode a router mapping or packet path in the hub).
- ALWAYS keep advisor projection maps hardcoded and drift-guarded against the registry; command mode routing is still hardcoded in the command files and does not resolve through
mode-registry.json.
- ALWAYS keep each mode's convergence/state/artifact contract in its packet — the hub stays logic-free.
- ALWAYS keep exactly one
graph-metadata.json (this hub's) so the advisor sees one skill identity, whether a mode is reached via Skill(system-deep-loop), a /deep:* command, or an agent.
- ALWAYS keep the root
ROUTER.md RESOURCE_MAP in sync with leaf-manifest.json — the leaf sets dual-read to canonical typed pairs at the one contract boundary; the three improvement lanes stay distinct (workflowMode, leafResourceId) pairs even though they share the deep-improvement packet.
- ALWAYS keep
Skill(system-deep-loop) hub routing, the /deep:* commands, and the agent types as complementary surfaces over the same packets — never let one surface fork per-mode logic out of its packet.
⛔ NEVER
- NEVER add an
improvement loopType to runtime/convergence.cjs (improvement is host-driven; runtimeLoopType stays null).
- NEVER infer
runtimeLoopType from workflowMode — read it from the registry (explicit null is load-bearing).
- NEVER let a read-only mode (research/review/ai-council) reach the improvement mutation scripts (
promote-candidate.cjs/rollback-candidate.cjs).
- NEVER add a
graph-metadata.json or a discoverable skill marker inside a mode packet or shared/.
⚠️ ESCALATE IF
- A new mode is needed beyond the six registered — extend
mode-registry.json and open a packet, do not bolt logic onto the hub.
- A change would require the runtime to gain MCP tools or an improvement loopType — that contradicts the architecture; escalate.
5. REFERENCES
- Backend:
.opencode/skills/system-deep-loop/runtime/ (frozen, consumed by every mode; nested infrastructure, not a separate skill).
- Mode packets:
deep-research/SKILL.md, deep-review/SKILL.md, deep-ai-council/SKILL.md, deep-improvement/SKILL.md (per-mode detail).
- Commands: the active
/deep:* commands under .opencode/commands/deep/ (complementary surface).
- Registry:
mode-registry.json (the routing contract — the authoritative packet paths).
- Surface router:
ROUTER.md (deep-loop intent to packet-local leaf sets).
6. SUCCESS CRITERIA
- The hub resolves one primary active
workflowMode for the request through mode-registry.json (improvement folds to the right lane via the registry, never by array order).
- The selected mode packet owns the detailed convergence/state/artifact workflow; the hub stayed routing-only.
Skill(system-deep-loop[, hint]) reaches a mode, and the /deep:* commands and agent types still reach the same packets.
- Exactly one
graph-metadata.json exists for the whole skill; no packet carries its own.
7. INTEGRATION POINTS
Modes
research — outward web + code iterative investigation (research/research.md).
review — iterative review loop, P0/P1/P2 findings + verdict.
ai-council — multi-seat planning deliberation (ai-council/** artifacts).
improvement (3 lanes) — evaluator-first agent/model/skill improvement.
Surfaces and Consumers
Skill(system-deep-loop) is the invokable hub; active /deep:* commands and the agent types (deep-research, deep-review, ai-council, deep-improvement) are complementary surfaces over the same packets.
runtime/ is the frozen, MCP-free backend every mode consumes (nested infrastructure, not a separate skill).
/speckit:plan consumes @context packages plus research/review outputs; spec-folder docs consume research/review output.
8. RELATED RESOURCES
- Pattern:
.opencode/skills/sk-doc/sk-create-skill/references/parent-skill/parent-skills-nested-packets.md (parent-skill hub + nested packets, the one-graph-metadata invariant).
- Sibling example:
.opencode/skills/sk-prompt/ (the same invokable-hub + mode-registry.json Option E pattern).
- Registry:
mode-registry.json (this hub's routing contract).