Install
$ agentstack add skill-michelkerkmeester-opencode-skilled-agent-loops-with-spec-kit-memory-deep-context ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Deep Context
Iterative, multi-model codebase-context-gathering loop. It sweeps the existing repository for the code relevant to a feature and synthesizes an implementation/planning-ready Context Report whose highest-value section is a REUSE catalog (existing functions/utilities to extend, cited by file:symbol). It is the "understand" loop that runs before /speckit:plan and /speckit:implement.
It is the fourth deep loop and the third consumer of deep-loop-runtime (alongside deep-research and deep-review). Unlike them it is inward (the codebase, not the web), and unlike a one-shot context lookup it is convergence-gated and multi-model: an operator-composed pool of executors sweeps the same scope in parallel, and cross-executor agreement drives finding confidence.
1. WHEN TO USE
Activation Triggers
Use when:
- You are about to plan or implement a feature and need a verified map of the existing code to reuse, the integration points to touch, and the conventions to follow.
- You want a Context Report that
/speckit:plancan consume in place of its ad-hoc exploration dispatch. - You want diverse model lenses on the same code (e.g. 2 native agents + MiMo + gpt + deepseek) with agreement-weighted confidence.
- A feature spans multiple modules and the blast radius is unclear before you plan.
Keyword triggers:
gather context,map the code for X,what existing code,what can I reusepre-plan context,context loop,context sweep,deep context/deep:context
When NOT to Use
Do not use for:
- Outward/web knowledge discovery — use
deep-research. - Code audit / defect finding — use
deep-review. - Strategy deliberation between competing plans — use
deep-ai-council. - A quick one-shot context lookup — use the
@contextagent.
2. SMART ROUTING
> Pattern: aligned with the [sk-doc smart-router resilience template](../sk-doc/assets/skill/skillsmartrouter.md).
Primary Detection Signal
Request contains "gather context" / "map the code" / "what existing code" / pre-plan understanding?
|
+-- /deep:context invoked? → ALWAYS load guides/quick_reference
+-- "convergence" / "stop" / "saturation"? → load convergence/* (signals, recovery, graph)
+-- "state" / "jsonl" / "registry" / resume? → load state/* (format, jsonl, outputs, reducer)
+-- "reuse" / "REUSE catalog" / "report"? → load state/state_outputs + context_report_template
+-- "sweep" / "executor pool" / "seat"? → load protocol/loop_protocol
+-- Low-confidence or scope not stated? → UNKNOWN_FALLBACK_CHECKLIST
Phase Detection
REQUEST
|
+- STEP 0: Detect scope (feature / spec folder / query provided?)
+- STEP 1: Score intents → loop setup, sweep dispatch, merge/agreement,
convergence, state, coverage graph, or report synthesis
+- STEP 2: Load intent-matched resources (guarded, existence-checked)
+- Phase 1: Frontier seeding + parallel sweep (protocol/loop_protocol)
+- Phase 2: Agreement merge + convergence (state/state_reducer_registry, convergence/*)
+- Phase 3: Synthesis → Context Report (state/state_outputs, context_report_template)
Resource Domains
The router discovers markdown resources recursively from references/ and assets/, then applies intent scoring from INTENT_SIGNALS. References are organized into the same subfolder families as the sibling deep loops:
references/guides/— operator cheat sheet (quick_reference.md); the ALWAYS baseline.references/protocol/—loop_protocol.md: iteration lifecycle, parallel sweep, host-writes-state, merge.references/convergence/—convergence.md(hub),convergence_signals.md(the 5 signals + weights + thresholds),convergence_recovery.md(blocked-stop / stuck recovery),convergence_graph.md(theloop_type='context'coverage-graph stop path).references/state/—state_format.md(packet hub),state_jsonl.md(record types),state_outputs.md(dashboard / Context Report),state_reducer_registry.md(reduce-state.cjs ownership + robustness).assets/context_report_template.md— Context Report schema (REUSE-catalog-first, pointers not bodies).assets/deep_context_config.json— config shape (scope, executor pool, concurrency, thresholds).
Resource Loading Levels
| Level | When to Load | Resources | | ----------- | ---------------------------------------- | -------------------------------------------------- | | ALWAYS | Every skill invocation | references/guides/quick_reference.md | | CONDITIONAL | Intent signals match | The intent-mapped convergence/, protocol/, state/ refs + context_report_template.md | | ON_DEMAND | Explicit deep-dive keyword (see ON_DEMAND_KEYWORDS) | The full reference set |
Smart Router Pseudocode
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"
# Deep-context intent signals: a top-level weight + flat keyword list per intent
# (canonical sibling shape — matches deep-research / deep-review).
INTENT_SIGNALS = {
"LOOP_SETUP": {"weight": 4, "keywords": ["deep context", "context loop", "gather context", "map the code", "pre-plan context", "frontier", "seed", "setup", "init"]},
"SWEEP_DISPATCH": {"weight": 4, "keywords": ["parallel sweep", "executor pool", "by-model", "heterogeneous", "seat", "fanout", "dispatch", "council seats", "multi-model"]},
"MERGE_AGREEMENT": {"weight": 4, "keywords": ["agreement", "merge", "dedup", "contradiction", "attribution", "confidence", "unit_id", "reducer", "registry"]},
"CONVERGENCE": {"weight": 4, "keywords": ["convergence", "stop", "saturation", "relevance gate", "agreement rate", "blocked stop", "STOP_ALLOWED", "recovery", "stuck"]},
"STATE": {"weight": 4, "keywords": ["state file", "jsonl", "dashboard", "packet", "findings-registry", "resume", "state log"]},
"COVERAGE_GRAPH": {"weight": 3, "keywords": ["coverage graph", "loop_type", "node kinds", "covered_by", "confirms", "graph signals", "upsert"]},
"REPORT_SYNTHESIS": {"weight": 4, "keywords": ["context report", "reuse catalog", "reuse", "integration point", "touch list", "synthesis", "report"]},
}
RESOURCE_MAP = {
"LOOP_SETUP": ["references/protocol/loop_protocol.md", "references/state/state_format.md"],
"SWEEP_DISPATCH": ["references/protocol/loop_protocol.md", "references/guides/quick_reference.md"],
"MERGE_AGREEMENT": ["references/state/state_reducer_registry.md", "references/convergence/convergence_signals.md"],
"CONVERGENCE": ["references/convergence/convergence.md", "references/convergence/convergence_signals.md", "references/convergence/convergence_recovery.md", "references/convergence/convergence_graph.md"],
"STATE": ["references/state/state_format.md", "references/state/state_jsonl.md", "references/state/state_outputs.md", "references/state/state_reducer_registry.md"],
"COVERAGE_GRAPH": ["references/convergence/convergence_graph.md"],
"REPORT_SYNTHESIS": ["references/state/state_outputs.md", "assets/context_report_template.md"],
}
LOADING_LEVELS = {
"ALWAYS": ["references/guides/quick_reference.md"],
"ON_DEMAND_KEYWORDS": ["full protocol", "all references", "complete reference", "resume deep context", "state log", "context/iterations", "blocked stop", "coverage graph", "reduce-state", "config schema"],
"ON_DEMAND": [
"references/protocol/loop_protocol.md",
"references/convergence/convergence.md",
"references/convergence/convergence_signals.md",
"references/convergence/convergence_recovery.md",
"references/convergence/convergence_graph.md",
"references/state/state_format.md",
"references/state/state_jsonl.md",
"references/state/state_outputs.md",
"references/state/state_reducer_registry.md",
"assets/context_report_template.md",
],
}
UNKNOWN_FALLBACK_CHECKLIST = [
"State the target feature or module to gather context for.",
"Confirm whether a spec folder exists (or provide a standalone run path).",
"Specify the executor pool (native × N, plus any CLI seats) or accept the default.",
"Confirm verification expectations: what signals will indicate a useful Context Report?",
]
AMBIGUITY_DELTA = 1
def _guard_in_skill(relative_path: str) -> str:
resolved = (SKILL_ROOT / relative_path).resolve()
resolved.relative_to(SKILL_ROOT) # raises if outside 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 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 load_if_available(relative_path: str, inventory, loaded, seen):
guarded = _guard_in_skill(relative_path)
if guarded in inventory and guarded not in seen:
load(guarded)
loaded.append(guarded)
seen.add(guarded)
def score_intents(user_request: str) -> dict[str, int]:
text = (user_request or "").lower()
scores = {intent: 0 for intent in INTENT_SIGNALS}
for intent, cfg in INTENT_SIGNALS.items():
weight = cfg["weight"]
for keyword in cfg["keywords"]:
if keyword in text:
scores[intent] += weight
return scores
def select_intents(scores: dict[str, int]) -> tuple[str, str | None]:
ranked = sorted(scores.items(), key=lambda pair: pair[1], reverse=True)
primary, primary_score = ranked[0]
if primary_score == 0:
return ("LOOP_SETUP", None)
secondary, secondary_score = ranked[1]
if secondary_score > 0 and (primary_score - secondary_score) Depth lives in the references: [protocol/loop_protocol.md](references/protocol/loop_protocol.md) (full lifecycle), the [convergence/](references/convergence/convergence.md) family (stop contract, signals, recovery, graph), and the [state/](references/state/state_format.md) family (packet, JSONL, outputs, reducer). This section is the quick map.
**Process** (host-driven loop; the host = the orchestrating command/agent):
```text
STEP 1: Seed the frontier
├─ Extract anchors from the target feature/query (paths, symbols, errors)
├─ Expand via code_graph_query (blast-radius/calls) into ranked SLICE nodes
└─ Fall back to Glob + Grep when the code graph is stale or absent
↓
STEP 2: Parallel sweep (one iteration)
├─ native seats → parallel batch of @deep-context Task subagents
├─ CLI seats → deep-loop-runtime multi-seat-dispatch + per-kind spawn
└─ Both groups start together; barrier-join (true heterogeneous parallelism)
↓
STEP 3: Merge + agreement (host only)
├─ Dedup findings by unit_id = sha256(path:symbol:kind)
├─ Union per-executor attribution; boost confidence by agreement count
└─ Surface contradictions (CONTRADICTS edges); never silently resolve
↓
STEP 4: Persist + converge
├─ Host writes iteration state + coverage-graph events (loop_type='context')
└─ convergence.cjs --loop-type context → CONTINUE / STOP_ALLOWED / STOP_BLOCKED
↓
STEP 5: Synthesize
└─ At stop, emit Context Report (context/context-report.md + .json)
Output: a Context Report — REUSE catalog (verified file:symbol + signature + how-to-extend + confidence-by-agreement + freshness), integration points, touch list, conventions, pruned dependency subgraph, and gaps/unknowns. It ships pointers, not source bodies (the consumer pulls bodies just-in-time), which avoids context rot and stale-reference failure.
Heterogeneous pool example (opt-in Custom — NOT the default; the default pool is native-only, 2 seats): 2 native agents + 1 MiMo-v2.5-pro (cli-opencode) + 1 gpt (cli-codex) + 1 deepseek-v4-pro (cli-opencode), all sweeping the same scope in parallel; a reuse candidate confirmed by 3 of 5 executors outranks a single-executor find.
Script: scripts/reduce-state.cjs — the agreement-weighted context reducer. Reads the host-written state log + per-seat findings and produces the findings-registry.json and human-readable dashboard. Run from the repository root:
node .opencode/skills/deep-loop-workflows/deep-context/scripts/reduce-state.cjs
Runtime Mirrors (native seat dispatch)
The native @deep-context seat is dispatched by name (agent: deep-context in the loop YAML), resolved by each host runtime from its OWN agents/ directory. It therefore lives as one canonical source plus two runtime mirrors that must stay in sync:
| Runtime | File | Frontmatter | |---------|------|-------------| | OpenCode | .opencode/agents/deep-context.md | canonical source — mode: subagent + permission: block | | Claude Code | .claude/agents/deep-context.md | mirror — tools: allow-list (read-only), same body | | Codex | .codex/agents/deep-context.toml | mirror — developer_instructions = '''…''' + # Converted from: header + sandbox_mode = "read-only", same body |
The body is identical across all three; only the frontmatter format differs. The command and loop YAML are shared — the .claude/ and .codex/ commands/prompts/skills directories are symlinks to .opencode/ — so they intentionally reference the canonical .opencode/ paths and dispatch by name; do NOT fork them per runtime. If a mirror is missing for a runtime, the native seats silently fail to dispatch there (the CLI seats still run, but the cross-executor agreement signal degrades). When you edit the canonical agent, re-sync both mirrors in the same change.
4. RULES
ALWAYS
- Treat every executor seat as a read-only analyzer. The host writes all state (iteration files, coverage-graph, the merged report). Sub-agents must never write the merged report.
- Carry the full lineage prompt contract to every seat: gather-subject + scope/slice + known-context + output schema. A seat told only "analyze" returns generic noise.
- Apply each model's prompt framework via
sk-prompt-small-model(e.g. MiMo → COSTAR, MiniMax → TIDD-EC) using the lineagepromptFrameworkfield. - Verify every cited
file:symbolagainst the code graph before it enters the report; label anything unverified. A stale reference is worse than omission. - **Honor the cli- skill contracts for dispatch* (model id form,
= 0.50— findings are multi-model-confirmed, not single-seat noise.
relevanceFloor >= 0.50— the loop collected focused context, not tangential files.sliceCoverage >= 0.70— the defined scope was swept, not partially skimmed.
7. INTEGRATION POINTS
Triggers: pre-planning context gathering; requests matching "gather context", "map the code for X", "what can I reuse for X", /deep:context.
Pairs with:
deep-loop-runtime— coverage-graph (loop_type='context'), convergence script, parallel seat dispatch, executor config.sk-prompt-small-model— per-model prompt framing for the heterogeneous pool.cli-opencode/cli-codex/cli-claude-code— CLI seat dispatch contracts.system-code-graph— frontier seeding + reference verification./speckit:planand/speckit:implement— downstream consumers of the Context Report.
Packet layout ({spec_folder}/context/):
deep-context-config.json— run config.deep-context-state.jsonl— append-only state log.- `deep-context
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: MichelKerkmeester
- Source: MichelKerkmeester/opencode--skilled-agent-loops-with-spec-kit-memory
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.