| name | openlore-review-changes |
| description | Risk-aware code review using detect_changes + get_minimal_context + get_cluster. Surfaces the riskiest changed functions, interprets callType/coverage/cluster density, and produces a go/no-go recommendation. No code written. |
| license | MIT |
| compatibility | openlore MCP server |
openlore: Review Changes
When to use this skill
Trigger this skill whenever the user asks to review, audit, or check the safety of recent changes, with phrasings like:
- "review my changes"
- "what did I break?"
- "is this branch safe to merge?"
- "pre-PR check"
- "what's risky in this diff?"
- "check the blast radius of my changes"
- explicit command
/openlore-review-changes
No code is written. Output is a risk-ranked review with a go/no-go recommendation.
Step 1 — Confirm directory and base ref
Ask: which project? Diff against which base? (default: main)
Store as $DIRECTORY and $BASE_REF.
Step 2 — Detect changed functions and risk scores
Call the openlore MCP tool detect_changes with:
{"directory": "$DIRECTORY", "base": "$BASE_REF"}
The risk score is multiplicative: likelihood × impact.
likelihood = how much was changed × how poorly covered it is ("called" tests count full; "imported"-only count 0.3×)
impact = structural blast radius (log fanIn + distance-weighted transitive callers weighted by callType + external boundary calls)
A function with fanIn=0 calling nothing external scores 0 regardless of change size — correct; focus on non-zero scores.
Present a risk-ranked table:
| Rank | Function | File | riskScore | blastRadius | fanIn | testedBy |
|---|
Flag:
riskScore ≥ 5 → 🔴 HIGH — must inspect
riskScore 2–5 → 🟡 MEDIUM — inspect if time allows
riskScore < 2 → 🟢 LOW
Step 3 — Deep-inspect each HIGH function
For each function with riskScore ≥ 5, call get_minimal_context:
{"directory": "$DIRECTORY", "functionName": "$FUNCTION_NAME"}
What to read:
function.riskLevel — "high" means the tool expanded caller/callee lists to 24. All shown entries are in the blast radius.
callers[*].callType — all "awaited" = async interface frozen; any signature change breaks every caller without a compile error in JS. Mixed = looser coupling.
callees[*].isExternal: true — function touches an external boundary (HTTP/DB). Failures here propagate outward and may not be caught in unit tests.
testedBy[*].confidence — "called" = direct test (strong safety net). "imported" = test file only imports the module; vi.mock() can neutralize it entirely. Only "imported" = effectively untested.
For each HIGH function, state:
$FUNCTION_NAME ($FILE):
Interface frozen? [yes — all callers await | no — mixed]
External boundary? [yes: $CALLEES | no]
Effective coverage: [strong (called) | weak (imported only) | none]
Verdict: [safe | needs direct tests first | coordinate with callers before merge]
Step 4 — Check cluster density for non-safe HIGH functions
For any HIGH function whose verdict is not "safe":
{"directory": "$DIRECTORY", "functionName": "$FUNCTION_NAME"}
Read stats.clusterDensity:
| Density | Meaning | Action |
|---|
| < 0.05 | Sparse — shared utilities | Change isolated; safe to land independently |
| 0.05–0.15 | Moderate coupling | Review internalCallGraph for transitively dependent functions |
| > 0.15 | Dense — tightly interwoven | Coordinate whole cluster; consider feature flag or staged rollout |
Step 5 — Coverage gap check
For each HIGH or MEDIUM function with testedBy empty or all "imported":
"⚠️ $FUNCTION_NAME has no direct test coverage. Changes here are not caught by the test suite unless a test directly calls this function. Recommend adding a characterisation test before merging."
Suggest a concrete test scenario based on the function body from get_minimal_context.
Step 6 — Output the review
Summary
- Total changed: N | HIGH: N | MEDIUM: N | Coverage gaps: N
Risk table
(from Step 2)
Function verdicts (HIGH only)
(from Steps 3–4)
Go / No-Go
- ✅ Safe to merge — no HIGH-risk uncovered functions
- ⚠️ Merge with caution — HIGH-risk functions exist but covered by direct tests
- 🛑 Do not merge — HIGH-risk uncovered functions with frozen interfaces or external boundaries
Absolute constraints
- Never skip Step 3 for HIGH-risk functions — riskScore alone is not enough
- Always interpret
callType — determines whether interface change is breaking
- Always interpret
testedBy.confidence — "imported" is not strong coverage
- Do not recommend merging any function with
riskScore ≥ 5, zero direct tests, and an external callee