Skip to main content

investigate

Routes a code investigation to one of four modes — bug, test gap, architecture, implementation — and runs the query sequence that mode needs. Use when asked to investigate, trace, or debug code.

معلومات المصدر

المستودع
MadAppGang/magus
آخر نشاط في المصدر
١٥ سبتمبر ٢٠٢٦ في ٠٢:٤٥
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٠
التفرعات
٤

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
investigate
description
Routes a code investigation to one of four modes — bug, test gap, architecture, implementation — and runs the query sequence that mode needs. Use when asked to investigate, trace, or debug code.
allowed-tools
Bash, Agent, Read, Grep, Glob
user-invocable
false
# Investigate One investigation, one mode. Pick the mode from the request, announce it, then run that mode's sequence. The retrieval mechanics live in the `code-search` skill; this skill is about which questions to ask and in what order. ## Routing | Mode | Trigger keywords | Question sequence | |---|---|---| | **Bug** | debug, error, broken, failing, crash | full context → inbound → outbound → transitive impact | | **Test gap** | test, coverage, edge case, mock | inbound filtered to test files → gap detection | | **Architecture** | architecture, design, structure, layer | structural map → centrality → dependency closure | | **Implementation** *(default)* | how does, implementation, data flow | locate → inbound → outbound → full context | **Collision order: Bug > Test > Architecture > Implementation.** No keyword matches → Implementation. **Announce the routing before executing it** — print the query, the chosen mode, and the one-line reason. A wrong route is then correctable in one turn instead of after the investigation is spent. ## Discipline that applies to every mode - **Never rank-truncate a result set.** Ranking already put the important results first; cutting by line count deletes them. Narrow with `scope` instead. - **An error and an empty result look alike and mean opposite things.** Establish which one you have before you report either. - **Name the method** behind every finding. Lexical search is the right tool for exact strings, counts and filename patterns — using it is routing, not a fallback. Using it without saying so is the defect. - **Blocked, never stalled.** A subagent has no tool for asking the user a question. If you cannot proceed, do not wait for an answer that cannot arrive and do not decide on the user's behalf: return a result beginning `BLOCKED:` naming what is missing and what would unblock it, and let the dispatching orchestrator ask. - **Centrality is relative.** Treat it as tiers — core, key, ordinary, leaf — never as a number to threshold. An absent centrality means unknown, not low. --- ## Architecture mode **Use when:** "what is the architecture", "how are the layers structured", "find the design patterns", "map the system". The highest-centrality symbols *are* the architecture. Start there, and skip the leaves. **Find the layers** by running the same structural query against three vocabulary families and reading the file distribution of the results: ``` code_search(query: "controller handler endpoint route") # presentation code_search(query: "service business logic domain") # business code_search(query: "repository persistence database query") # data ``` Boundaries and wiring show up under `interface contract abstract`, `inject provider module` and `config bootstrap initialize`. **Find the patterns** the same way — the pattern names are in the source: ``` code_search(query: "factory create builder") code_search(query: "interface abstract contract") code_search(query: "event emit subscribe") code_search(query: "repository persist unit of work") ``` **Then take the closure.** Direct callers are one level; the blast radius of an architectural change is the transitive closure, grouped by depth. ``` find_dependents(symbol: "PaymentService") impact(symbol: "PaymentService", max_depth: 3) ``` **Report:** detected pattern, core abstractions with their centrality tier and file:line, the layer diagram, the major flows, and the health indicators. ### Persist what you derived Architecture knowledge is expensive to re-derive and cheap to record. Write it down once derived — as bullet summaries plus `file:line` pointers, **never pasted code**. Code goes stale on the next edit; pointers survive it. --- ## Implementation mode (default) **Use when:** "how does X work", "trace the data flow", "where is X defined". 1. **Locate** the symbol — exact span, kind, signature, export status. 2. **Inbound edges** — every place that calls it. This is the impact of changing it. 3. **Outbound edges** — everything it calls. These are its dependencies and the data-flow path. 4. **Full context** when the change is non-trivial: definition plus both directions at once. Edge kind matters as much as edge existence: `call`, `import`, `extends` and `implements` have different blast radii. Say which kind an edge is when it changes the conclusion. **Direct callers are one level. `impact` is the transitive closure.** Refactoring decisions need the closure; a direct-caller count under-states the work every time. **Before editing:** confirm the symbol resolves, confirm its current signature, think, then edit. Never grep → read → edit. Index-derived signatures are captured at index time and can lag the file — when the name is overloaded or generic, read the declaration at the returned span rather than trusting the summary. **Report:** primary location with `file:line`, inbound edges, outbound edges, and the end-to-end flow. --- ## Test gap mode **Use when:** "what is tested", "find the coverage gaps", "audit test quality", "missing tests", "edge cases". Tests appear in the graph as **callers of the code they test**. Zero test callers on code that has production callers is the high-priority case. 1. Take the inbound edges of each critical symbol. 2. Classify each caller as test or production by path, using one pattern set: ``` *.test.* *.spec.* __tests__/ tests/ *_test.go *_test.py test_*.py src/test/java/ *_test.rs ``` 3. **Report both counts.** Production callers > 0 and test callers = 0 is the finding worth escalating; low-centrality untested code is not a gap worth reporting. **The convention is incomplete, and the verdict must say so.** Filename matching misses integration tests in non-standard locations, inline test modules (Rust `#[cfg(test)]`), end-to-end suites that reach the code indirectly, and any language whose convention is not in the list above. A "0 test callers" result from filename matching alone is a hypothesis, not a coverage verdict. **Two methods will disagree, and that is information.** Mock registration (`vi.mock`, `jest.mock`) and generated cases (`describe.each`) are call sites that AST edges miss but a reference-level lookup finds. When the two counts differ, report both rather than picking one. **Report:** framework, test file count, a per-function table of test callers, then the high-priority list (production callers, no test callers) and the medium list (few test callers, no error scenarios). --- ## Bug mode **Use when:** "why is X broken", "find the bug source", "root cause analysis", "trace this error". **Trace backwards through callers to find the cause; trace forwards through callees to find the effect.** The full chain is the root-cause picture. 1. Locate the symbol named in the error, and take its full context. 2. Walk inbound edges outward — caller of the symbol, caller of that caller — until the chain reaches something that explains the symptom. 3. Walk outbound edges to see what the failure propagates into. 4. Take the transitive impact for post-fix verification and regression scope. **Check the type boundary explicitly.** Mismatches between a symbol's actual signature and what its callers assume are a leading cause of runtime errors, and they are invisible in a call graph that only records that an edge exists. Read the declaration and read one caller. **Error origin hunting:** map the error vocabulary (`throw error exception`), locate the error type, then take *its* inbound edges — whoever constructs it is where the condition is detected. **State mutation tracking:** locate the mutator (`set state update mutate`), then enumerate who calls it. **Report:** symptom → the backwards call chain → root cause with `file:line` → the evidence that establishes it → the count of affected locations. Every step carries its evidence; a root cause asserted without a chain is a guess. --- ## Reading "0 callers" **Zero inbound edges has three readings, and they are not interchangeable:** 1. **Entry point** — expected and correct. CLI mains, HTTP handlers, exported public API, test-only helpers. 2. **Dead code** — genuinely unreachable. 3. **A call the graph cannot see** — dynamic import, reflection, bracket dispatch, event or callback registration, dependency-injection wiring, or a consumer in another repository. **Never collapse the three.** Report which one you concluded and the evidence for it. **This skill does not authorise deletion.** A dead-code verdict needs all three of: zero inbound edges, low centrality, and **not exported** — an export is a public contract whose consumers may be outside this tree. Even with all three, the finding is labelled *requires manual review* until a human has checked it against the dynamic-dispatch list above. **High centrality with zero callers means something broke recently** — a deleted call site, a botched merge — and is an investigation, not a cleanup. Low centrality with zero callers is a cleanup *candidate*, which is a proposal, not a verdict.
عرض على GitHub