Skip to content
Back to skills

Code Intelligence

ASecurity

Route codebase-structure questions (who calls X, where used, change-impact) to an existing code-graph first: impact, tests-for, dead cheaper, never more precise; grep routine. Also 'call graph'.

  • 10 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 2, 2026
ai-agentstypescriptrustgophpshellnodegit

Works with

  • cli
  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 12, 2026

npx -y skills add event4u-app/agent-config --skill code-intelligence --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Code Intelligence?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Code Intelligence
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/event4u-app-code-intelligence/badge)](https://www.skillsdirectory.com/skills/event4u-app-code-intelligence)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
model_tier: inherit
name: code-intelligence
description: "Route codebase-structure questions (who calls X, where used, change-impact) to an existing code-graph first: impact, tests-for, dead cheaper, never more precise; grep routine. Also 'call graph'."
domain: engineering
workspaces:
  - engineering
packs:
  - meta
requires_skills:
  - source-discovery
---

# code-intelligence

> For a **structure** question — *who calls X*, *where is Y used*, *what
> imports Z*, *what breaks if I change this symbol* — ask an index that already
> exists before rebuilding the relationship by hand: it is already built, its
> answer is structured, and it costs a fraction of the tokens. It is **not** more
> precise than a blind `grep` — measured on this repository's own source, zero
> classes met the win bar (§ Measured twice) — so grep is the arm you fall back
> to routinely and **with a stated reason**, not grudgingly. This skill routes
> such questions to the native code-graph engine (ADR-124, Class A) or a
> consumer-shipped index first. It is the executable side of
> [`external-code-graph-interop`](../../rules/external-code-graph-interop.md):
> *orchestrator first, owner where it wins*.

## When to use

- The question is about **relationships between code symbols**, not content:
  callers/callees, references, imports, inheritance, change-impact.
- You are about to `grep`/`Read` across many files to reconstruct a call or
  import graph by hand.

**When NOT to use:** content/semantic questions ("what does this function
*mean*", "find the string 'password'"), single-file edits, or a repo with no
code-graph and no appetite to build one — plain `grep`/read is right there.

## Procedure

1. **Detect the source.** `agent-config code-graph detect` — is a fresh consumer
   `graph.json` or native cache present? (A consumer-shipped fresh index wins;
   the native engine covers stale-or-absent — ADR-124 § 2.)
2. **Build if absent and worthwhile.** No graph + a repo in the launch set
   (PHP / TS / JS)? `agent-config code-graph build` (deterministic, LLM-free,
   ~seconds). Skip for a one-off question in an unsupported stack — grep
   instead.
3. **Query.** Pick the verb:
   - `agent-config code-graph query <symbol>` — direct relations of a symbol.
   - `agent-config code-graph affected <symbol>` — reverse: who calls /
     references it (the "impact of changing X" question). `--since <ref>`
     seeds from a git diff.
   - `agent-config code-graph path <a> <b>` — how two symbols connect.
   - `agent-config code-graph explain <symbol>` — 2-hop neighbourhood.
   Pass `--budget <tokens>` to cap output.
4. **Read the confidence.** `EXTRACTED` = syntactic fact — a symbol declared in
   the file, or a name bound to the module specifier the file names; `INFERRED`
   = resolved by hierarchy, or by a repo-wide same-name lookup with no binding
   in the file to justify it; `AMBIGUOUS` = dynamic dispatch / facade, carries
   candidates — treat its target as *one of* the candidates, never as certain.
   Two target shapes are **not nodes** and resolve to nothing you can read:
   `symbol:<name>` (a name this repository does not declare) and
   `external:<module>` / `external:<module>#<name>` (a name imported from
   outside the indexed root — `external:node:path`).
5. **Fall back honestly.** If the graph has no entry for the symbol, grep — and
   say so: *"the graph has no entry for X, so I grepped."* If this command is
   not available, grep and say so.

## Output

Every answer built with this skill MUST:

- **Name the source** that answered — `native`, `consumer`, or `grep-fallback`
  — so the reader knows the provenance and freshness of the relationship claim.
- **Preserve the confidence class** for each relationship surfaced — never
  present an `AMBIGUOUS` edge as a definite call; list its candidates or say
  "ambiguous (dynamic dispatch)".

## Gotcha

- **A stale graph lies confidently.** If `detect` reports the index is N commits
  behind, rebuild (`agent-config code-graph build --update`) before trusting
  relationship answers, or say the answer is from a stale index.
- **Dynamic dispatch is honestly ambiguous — where there is anything to be
  ambiguous ABOUT.** A `$obj->m()` whose name matches a method declared
  somewhere in the repo is `AMBIGUOUS` and carries those candidates: the engine
  being honest, not broken — do not "resolve" them yourself by guessing. A
  dynamic call whose name matches **no** in-repo method (`xs.push()`,
  `map.get()`) is not emitted at all, and the count is published as
  `suppressed_edge_counts.dynamic_no_candidate`. It used to be 39 % of this
  engine's own graph, pointing at `symbol:push`, which is not a node and which
  no query verb could reach.
- **The AMBIGUOUS share is a property of the code, not a constant.** Measured
  2026-09-04 over the three roots the v2 benchmark uses: `AMBIGUOUS` is 0 of 495
  edges under the package's own graph-engine root, 0 of 181 under `src/shared`, and 121 of
  4,002 (3.0 %) under its council root — class-free TypeScript has
  almost no in-repo method to be ambiguous between. A Laravel codebase, where
  facades and injected services dispatch onto real in-repo methods, is the
  opposite case. Read the counts in the graph rather than a remembered ratio.

## Measured twice, and it has not won (v2, 2026-08-29)

Pre-registered, published whichever way it landed:
`internal/bench/reports/code-graph-vs-grep-inrepo-v2-2026-08-29.md`. The native
engine scored against disciplined `git grep` over three in-repo TypeScript
roots, 19 questions, per-class bars fixed before the run and unchanged from v1.

| Class | grep R | graph R | Δ pp | grep P | graph P | verdict |
|---|---|---|---|---|---|---|
| `callers` | 1.000 | 1.000 | +0.0 | 0.611 | 0.667 | TIE |
| `transitive-impact` | 0.611 | 0.500 | −11.1 | 1.000 | 0.667 | NULL |
| `path-between` | 0.917 | **1.000** | +8.3 | 0.778 | **1.000** | TIE |
| `references` | 1.000 | 0.333 | −66.7 | 0.833 | 0.333 | NULL |

**Zero classes met the win bar.** On `path-between` the graph is exact and is the
only class where it out-precises grep; it still ties, because the delta is +8.3 pp
against a +10 pp bar that was fixed before the run.

**The v1 run of 2026-08-28 published a false root cause, corrected 2026-08-29.**
It reported `path-between` as `VOID` because *"both arms measured nothing"*. Only
the grep arm did. The graph answered all three questions and v1's scorer discarded
the answer — it compared each returned symbol against the whole probe string
`"cmdBuild -> getParser"`. v1 also never invoked the shipped `path <a> <b>` verb,
and counted unresolved `symbol:` pseudo-nodes as files, which is the sole reason
its `callers` verdict was NULL with recall tied. v1's numbers are not retro-edited
— they were faithful to v1's own registration — and v1's report now carries the
correction. Do not quote a `path-between` delta near +89 pp: that figure comes
from repairing the graph arm and leaving grep on the broken probe.

**The rule's own wording was corrected by this result.** `external-code-graph-interop`
used to open by saying a committed index answers "far more precisely than a fresh
`grep`". That was never measured, and when it was, it was false for the native
engine on this repository's own code. The rule now gives the reasons that survive
measurement — an index that exists is already built and structured, so it is the
cheap first question — and drops the precision claim its own benchmark refuted.

## Re-run after the extractor repair (2026-09-04) — still no class won

`internal/bench/reports/code-graph-vs-grep-inrepo-v2-rerun-2026-09-04.md`. The
SAME registration, the same corpus SHA, the same per-class bars and the same
arm-B verbs, re-run after the import-binding repair. The 2026-08-29 report is
untouched; this is a second report beside it, which is how v1 was handled too.

| Class | graph R then | graph R now | graph P then | graph P now | verdict then → now |
|---|---|---|---|---|---|
| `callers` | 1.000 | 1.000 | 0.667 | 0.667 | TIE → TIE |
| `transitive-impact` | 0.500 | **0.611** | 0.667 | **1.000** | **NULL → TIE** |
| `path-between` | 1.000 | 1.000 | 1.000 | 1.000 | TIE → TIE |
| `references` | 0.333 | **1.000** | 0.333 | **1.000** | **NULL → TIE** |

**Zero classes met the win bar, again.** Two NULLs became TIEs and nothing
regressed, so the routing verdict below is unchanged — a TIE is not a win, and
no bar was renegotiated after the repair.

Read with two caveats the report states in full. A measured root is live source:
`src/shared` is byte-identical between the runs, the council root moved
by 27 files on `main` in between, and the graph-engine root IS the engine, so
its content necessarily moves whenever the engine does — which is also why the
GREP arm's macro precision moved (0.806 → 0.764) in a run that changed nothing
about grep. Both classes that changed verdict did so on rows whose root did not
drift: `references` moved on the graph-engine and shared roots, `transitive-impact` on
`shared` alone.

**No class is graph-first.** Query the index first because an index that already
exists is cheap to ask and its answer is structured — not because it answers
better. When it returns nothing, that is the common case, and grep remains the
arm to fall back to rather than a grudging afterthought.

The sentence that stood here — *"the arm that won every valid class on this
corpus"* — is withdrawn. It is the framing v1's own report forbids: that report
says the defensible statement is *"zero classes met the pre-registered win
criterion"*, **not** that grep proved superior. It was also false on its own
terms under v2: grep wins two classes, ties two, and is out-precised on both
ties.

Scope, stated so this table is not over-read: it measured the **native** engine
on **this repository's TypeScript**, with a corpus of 19 questions. It is not
comparable to the 2026-07-28 external-corpus run, it is not comparable to v1
either (corpus, arm-B verb set and scorer all moved), and it says nothing about a
consumer-shipped SCIP index. Literal-string probes are reported as a separate
`capability-boundary` class with no floor derived from them: a symbol index
cannot answer them at all, which is where grep stays necessary rather than a
defect in the engine.

## Staleness delivery — which hosts get it for free, and which do not

Migrated verbatim from `external-code-graph-interop` so the obligation stays in
the rule and the per-host delivery detail is paid only on activation.

On a host with a verified `pre_tool_use` contract, the `code-graph-context`
concern supplies this for free: once per session, on the first search or
code read, it delivers the graph's state as structured `additionalContext` —
`code-graph: fresh` or `code-graph: N commit(s) behind`. It is silent when no
graph exists, so hearing nothing is not evidence that the graph is fresh.

**On every other host that carrier does not exist**, and this section is the
delivery: run `agent-config code-graph detect --format json` before trusting a
relationship answer, and say which state you got. Which hosts those are is
`agent-config hooks:status` — resolved from the platform table, never guessed
from the host's name.

Either way the disposition is the same: `behind:N` → `agent-config code-graph
refresh` first, or use grep and say so. This is a freshness obligation, not an
ordering claim; the rule's query-first ordering still governs which source to
reach for.

## The four gate verbs — a diff, not a symbol (2026-09-08)

`query` / `affected` / `path` / `explain` answer a question about a SYMBOL.
Four more answer a question about a DIFF, and they are documented here rather
than in § Procedure for a mechanical reason worth stating: step 4.3 of
`road-to-a-graph-that-is-shipped` verifies that this file's line 164 — the
**No class is graph-first** sentence — is unchanged, and inserting anything
above it moves that line. So the ordering claim K5 protects stays byte-fixed
and the new material sits below it.

Each of the four walks only edges whose resolution mechanism is a stated fact
(never a repo-wide same-name guess, never an untyped receiver), and each prints
the mechanisms it accepted, the mechanisms it refused, and the graph's
staleness — so a narrow answer is distinguishable from a decoupled one:

- `agent-config code-graph impact --diff <rev>` — callers, dependents and test
  files reachable from the changed symbols, plus the producing edges and a
  minimal read set.
- `agent-config code-graph tests-for <symbol>` — the test files that import it.
  An empty list is a finding, not an error.
- `agent-config code-graph untested --diff <rev>` — changed symbols that no test
  file imports.
- `agent-config code-graph dead [--entry-points F | --accept-missing-exports]` —
  symbols with no accepted reference that no declared entry point names. It
  **refuses** rather than answering while an entry-point source cannot be read:
  this engine records no exportedness, so without a supplied list an
  exported-but-unimported symbol is indistinguishable from a dead one, and a
  confident false "dead" invites a deletion the graph cannot justify. Nothing it
  lists is a deletion recommendation.

These answers reach an agent over MCP without shelling out, and the mapping is
**not** one tool per verb — corrected after an independent review found this
paragraph claiming "the same five answers" directly after a list of four:

| MCP tool | answers |
|---|---|
| `graph_impact` | `impact --diff`, **and** `untested --diff` via `untested_only: true` |
| `graph_tests_for` | `tests-for` |
| `graph_dead` | `dead` |
| `graph_query` | `query` |
| `graph_path` | `path` |

`untested` has no tool of its own; it is a flag on `graph_impact`, because the
two answer the same question over the same diff and a sixth tool would have cost
standing context for a boolean. `graph_impact` is the only one that is not
read-only — it runs `git diff --name-only` to resolve its rev — and
`graph_dead`'s refusal arrives as `status: "refused"`, never as `status: "ok"`
with an empty list.

**No ordering claim is added here, and no measurement claim either.** These
verbs are cheaper than reconstructing the same relationship by hand — that is a
claim about the ALTERNATIVE being a manual reconstruction, not about grep.
Nothing on this page says they beat grep, none of the four appears in the v2
benchmark corpus (which measures `callers`, `transitive-impact`, `path-between`
and `references`), and § Measured twice still governs that question.

## Do NOT

- Do NOT rebuild a **fresh** consumer-shipped index — query it (interop
  courtesy).
- Do NOT block or defer a read waiting on the graph — it is an accelerator, not
  a gate.
- Do NOT treat the cache as a source of truth for anything beyond the last
  build; it is a rebuildable artifact.

## See also

- [`external-code-graph-interop`](../../rules/external-code-graph-interop.md) —
  the rule that routes structure questions here.
- [`source-discovery`](../source-discovery/SKILL.md) — evidence-before-structure
  discipline; the graph is one evidence source, still confirmed against the real
  code when load-bearing.
- `agent-config code-graph` — the CLI surface over the engine (build / query / detect / affected).
- [`discovery_graph`](../../scripts/discovery_graph.ts) — this suite's OWN
  artifact relation-graph (`affected`/`explain`). The external code-graph is the
  *source-code* analogue; keep the two apart when answering.

Files in this skill

  • SKILL.md7.8 KB
  • evals/triggers.json3.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.