with one click
openlore-debug
// Debug a problem by anchoring root-cause analysis in openlore structural knowledge. Uses orient + search_specs + analyze_impact to form an explicit hypothesis before reading code. Enforces RED/GREEN test verification.
// Debug a problem by anchoring root-cause analysis in openlore structural knowledge. Uses orient + search_specs + analyze_impact to form an explicit hypothesis before reading code. Enforces RED/GREEN test verification.
Persistent architectural memory for this codebase. Call `orient(task)` before reading source files to get the relevant functions, callers, spec sections, and insertion points for any task — saving 15,000–50,000 tokens of file-by-file rediscovery.
Run a full static analysis of a project using openlore and summarise the results — architecture, call graph, top refactoring issues, and duplicate code. No LLM required.
Transform a feature idea into an annotated story. Detects greenfield vs brownfield automatically — uses Domain Sketch for greenfield (no existing code), Constrained Option Tree for brownfield (existing codebase with openlore analysis).
Apply the refactoring plan produced by openlore-plan-refactor. Reads .openlore/refactor-plan.md and re-reads it before each change to stay on track. Requires a confirmed plan to exist before running.
Reverse-engineer OpenSpec specifications from an existing codebase. Performs "code archaeology" — extracting what code actually does and documenting it as structured OpenSpec specs across all detected domains.
Implement a story on a brownfield codebase using openlore structural context. Runs orient + risk check before coding, validates against specs, enforces a test gate before drift check.
| name | openlore-debug |
| description | Debug a problem by anchoring root-cause analysis in openlore structural knowledge. Uses orient + search_specs + analyze_impact to form an explicit hypothesis before reading code. Enforces RED/GREEN test verification. |
| license | MIT |
| compatibility | openlore MCP server |
| user-invocable | true |
| allowed-tools | ["ask_followup_question","use_mcp_tool","read_file","write_file","str_replace_based_edit","replace_in_file","run_command"] |
Trigger this skill when the user reports a bug or unexpected behaviour on a codebase that has openlore analysis available, with phrasings like:
/openlore-debugThe rule: form an explicit hypothesis before reading any code. Do not browse files speculatively.
Prerequisite: openlore analysis must exist (openlore analyze has been run).
If orient returns "error": "no cache" → run analyze_codebase first, then retry.
Ask the user for:
$PROJECT_ROOT — project root directoryDo not proceed to Step 2 until all four are known.
If the user cannot reproduce the bug reliably, note it and proceed anyway — but flag that the fix may be speculative until reproduction is confirmed.
Capture:
$BUG_DESCRIPTION — one-line summary of the symptom (e.g. "payment retry does not reset counter after success")$REPRO_STEPS — reproduction sequence<use_mcp_tool>
<server_name>openlore</server_name>
<tool_name>orient</tool_name>
<arguments>{
"directory": "$PROJECT_ROOT",
"task": "$BUG_DESCRIPTION",
"limit": 7
}</arguments>
</use_mcp_tool>
Extract:
$CANDIDATE_FUNCTIONS — top 3–5 functions structurally related to the symptom$DOMAINS_AFFECTED — spec domains involved$CALL_PATHS — call chains relevant to the symptomIf openspec/specs/ exists:
<use_mcp_tool>
<server_name>openlore</server_name>
<tool_name>search_specs</tool_name>
<arguments>{
"directory": "$PROJECT_ROOT",
"query": "$BUG_DESCRIPTION",
"limit": 5
}</arguments>
</use_mcp_tool>
Look for:
$DOMAINS_AFFECTEDIf no specs exist, skip this step and note the absence.
For the top 2 candidate functions from Step 2, get minimal context first (callers, callees, body, test coverage in one call):
<use_mcp_tool>
<server_name>openlore</server_name>
<tool_name>get_minimal_context</tool_name>
<arguments>{"directory": "$PROJECT_ROOT", "functionName": "$CANDIDATE_FUNCTION"}</arguments>
</use_mcp_tool>
Then check structural properties:
<use_mcp_tool>
<server_name>openlore</server_name>
<tool_name>analyze_impact</tool_name>
<arguments>{
"directory": "$PROJECT_ROOT",
"symbol": "$CANDIDATE_FUNCTION",
"depth": 2
}</arguments>
</use_mcp_tool>
If the repro involves a request flow (HTTP request, event, message queue), confirm the call chain before forming the hypothesis:
<use_mcp_tool>
<server_name>openlore</server_name>
<tool_name>trace_execution_path</tool_name>
<arguments>{
"directory": "$PROJECT_ROOT",
"from": "$ENTRY_POINT",
"to": "$CANDIDATE_FUNCTION"
}</arguments>
</use_mcp_tool>
This replaces speculative file browsing — the path is structural fact, not inference. Skip if $ENTRY_POINT is unknown or the repro is not request-driven.
Using the call paths, risk scores, spec constraints, and traced path gathered so far, state an explicit hypothesis before reading any code:
"Hypothesis:
$FUNCTIONdoes not reset$STATEwhen$CONDITIONbecause it is called from$CALLERwhich does not pass$PARAMETER."
The hypothesis must:
Do not read source files before forming this hypothesis.
Read the source of the hypothesised function(s):
<use_mcp_tool>
<server_name>openlore</server_name>
<tool_name>get_function_skeleton</tool_name>
<arguments>{
"directory": "$PROJECT_ROOT",
"filePath": "$TARGET_FILE"
}</arguments>
</use_mcp_tool>
Then read the full function body if needed.
| Result | Action |
|---|---|
| Hypothesis confirmed | Proceed to Step 6 |
| Hypothesis refuted | Return to Step 4 with a revised hypothesis (max 3 iterations before asking the user for more context) |
| Cause is in a caller, not the function itself | Extend analyze_impact one level up, revise hypothesis |
Document the confirmed hypothesis explicitly before writing any fix.
Apply the minimal fix that resolves the confirmed hypothesis.
Do not modify functions outside the scope identified in Steps 2–5 without
re-running the gate (orient + analyze_impact) on the new scope.
Small model constraint: each edit must touch a contiguous block of at most 50 lines. Split larger fixes into sequential edits.
Do not refactor, rename, or clean up unrelated code while fixing the bug.
RED first (if no existing test covers this case):
Write a test that reproduces the bug using $REPRO_STEPS. Run it. It must fail
(RED) — confirming the bug is real and the test is meaningful.
Apply the fix, then run the test again. It must pass (GREEN).
Full suite:
Run the full test suite. If any pre-existing test breaks, fix the regression before closing the bug.
| Situation | Action |
|---|---|
| New test RED → fix → GREEN, suite green | Proceed to Step 8 |
| Cannot reproduce in a test | Note it, apply fix, confirm manually, add a note in the story/issue |
| Suite regression introduced | Fix regression. Do not proceed. |
Only if the fix changes a documented behaviour:
<use_mcp_tool>
<server_name>openlore</server_name>
<tool_name>check_spec_drift</tool_name>
<arguments>{"directory": "$PROJECT_ROOT"}</arguments>
</use_mcp_tool>
| Drift type | Resolution |
|---|---|
gap on modified function | The spec described expected behaviour that changed — update the spec |
stale | Fix the stale reference |
uncovered | Not caused by this fix — note it, propose openlore generate |
| No drift | Proceed to Step 9 |
Every real bug reveals an invariant that was not documented. Capture it so future
agents benefit from this discovery via search_specs.
9a — Identify the invariant
State the invariant that was violated, in one sentence:
"
$FUNCTIONmust always$CONDITIONwhen$TRIGGER— violating this causes$OBSERVED_SYMPTOM."
If the bug was caused by a missing guard, a wrong assumption about caller order, or an undocumented state constraint — that is the invariant.
9b — Locate the spec
<use_mcp_tool>
<server_name>openlore</server_name>
<tool_name>get_spec</tool_name>
<arguments>{
"directory": "$PROJECT_ROOT",
"domain": "$DOMAIN_AFFECTED"
}</arguments>
</use_mcp_tool>
9c — Add the invariant
Append to the relevant domain spec under a ### Known Invariants section
(create it if absent). Wrap the section in <!-- manual --> / <!-- /manual -->
markers so openlore generate preserves it on re-generation:
<!-- manual -->
### Known Invariants
- `$FUNCTION`: $INVARIANT_STATEMENT
— discovered via bug fix on $DATE, root cause: $ROOT_CAUSE_SUMMARY
<!-- /manual -->
If the domain spec does not exist yet (uncovered from Step 8), note the
invariant in the story/issue instead and flag it for the next openlore generate run.
9d — Evaluate cross-cutting scope
Ask: is this bug an instance of a general failure pattern, or specific to this domain?
| Signal | Cross-cutting antipattern? |
|---|---|
| Bug involves an assumption about external state, ordering, or caller contract | Yes |
| Bug is reproducible in other domains with the same pattern | Yes |
Bug is specific to a data invariant in $DOMAIN | No — domain spec only |
If cross-cutting, append to .claude/antipatterns.md (if absent, create it with the
header from the antipatterns template):
## AP-{NNN} — {pattern name}
- **Class**: {state | concurrency | boundary | assumption | resource | ordering}
- **Symptom**: {what broke — one sentence}
- **Rule**: {detection rule — "When X, always verify Y"}
- **Discovered**: $DATE via $BUG_DESCRIPTION
9e — Inform the user
"Invariant added to
openspec/specs/$DOMAIN/spec.md."
If an antipattern was added:
"Cross-cutting antipattern AP-{NNN} added to
.claude/antipatterns.md. Future brainstorm and implementation sessions will check this rule."
check_spec_drift before tests are green