Skip to content
Back to skills

Search

ASecurity

Code-intelligence search over wicked-estate's static + injected code-relationship graph (ADR 0005): index (build/refresh), blast-radius (dependents), lineage (data/dependency flow), path (the ordered hops from A to B), hotspots (PageRank centrality), service-map (infra + code), narrate (orientation walkthrough). Every graph read is ONE call on every seat, in every session kind — the read-only estate shim (`wicked-garden run scripts/_estate_client.py --readonly call …`). Use when: "index the ...

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 18, 2026
ai-agentspythonrustgobashnodedockergit

Works with

  • cursor
  • terminal
  • cli

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

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

Scanned October 18, 2026

npx -y skills add mikeparcewski/wicked-garden --skill search --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Search?

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

Security grade badge for Search
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mikeparcewski-search/badge)](https://www.skillsdirectory.com/skills/mikeparcewski-search)

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
---
name: wicked-garden-search
description: |
  Code-intelligence search over wicked-estate's static + injected
  code-relationship graph (ADR 0005): index (build/refresh), blast-radius
  (dependents), lineage (data/dependency flow), path (the ordered hops from
  A to B), hotspots (PageRank centrality), service-map (infra + code),
  narrate (orientation walkthrough).
  Every graph read is ONE call on every seat, in every session kind — the
  read-only estate shim (`wicked-garden run scripts/_estate_client.py
  --readonly call …`).

  Use when: "index the codebase"; "what breaks if I change X" / "blast
  radius" / "impact analysis"; "trace lineage" / "upstream or downstream of a
  symbol"; "how does A reach B" / "does A ever call B"; "most-referenced
  symbols" / "god objects" / "coupling hotspots"; "map the services"; "architecture walkthrough" / "narrate this codebase".

  NOT for concept/memory search — use `wicked-garden-mem`; a bare symbol
  lookup is the estate `SearchEntity` tool through the same shim.
metadata:
  role: router
  phases: "*"
  archetypes: "*"
---

# wicked-garden:search — code-intelligence over the estate graph

All actions delegate to **wicked-estate**, which owns the unified static + injected code-relationship
graph as of ADR 0005 (superseding the brain-homed graph of ADR 0004). Garden no longer maintains its own
graph; it consumes estate's. Garden contributes its proprietary **archetype** edges to estate's graph via
the drop-in TOML rules in `.wicked-estate-extractors/archetype.toml` (auto-discovered by `wicked-estate index`).

## Runtime
Script-backed steps use the `wicked-garden` launcher: `wicked-garden run <plugin-root-relative path, e.g. scripts/…> [args]`. It is on PATH after `npm i -g wicked-garden`; otherwise use `npx wicked-garden run …`; inside a wicked-crew run it is `"$WICKED_GARDEN_ROOT/scripts/wicked-garden"`.
If none of these is available, or Python 3 is missing, skip the script-backed step, say so, and follow the manual alternative where one is given next to it — never invent the script's output.
Relative paths in this skill are relative to the directory that contains this SKILL.md.

## Routing

| Action | Answers | Where |
|--------|---------|-------|
| `index` | build/refresh the code-intelligence index | § Index / freshness |
| `blast-radius` | "what breaks if I change X?" (dependents) | § Blast radius |
| `lineage` | "where does this flow from / to?" (data flow) | § Lineage |
| `path` | "how does A reach B?" — the ordered hops between two symbols | § Path |
| `hotspots` | most-central symbols, god-objects | [refs/hotspots.md](refs/hotspots.md) |
| `service-map` | service architecture from infra + code | [refs/service-map.md](refs/service-map.md) |
| `narrate` | codebase orientation / architecture walkthrough | [codebase-narrator/SKILL.md](codebase-narrator/SKILL.md) |
| `answer` | cited answer from the estate knowledge/memory stores | [refs/answer.md](refs/answer.md) |

Doctrine / which-rules-apply: **Steering** (the governance rules, 7 steering types) is in the same stores — the estate `knowledge.recall` tool through the shim — `wicked-garden run scripts/_estate_client.py --readonly call '{"tool":"knowledge.recall","arguments":{"scope_prefix":"wiki:",…}}'` (`wiki:` is a historical prefix) — + the estate `rules.recall` tool the same way (§ Resolving symbols) (cited, read-only); management: wicked-core `crates/wicked-governance/STEERING.md`.

## Index / freshness (shared by every action)

The graph lives in **wicked-estate** (ADR 0005): a 75-language tree-sitter
static graph **plus** injected domain edges, built by the estate binary — no
external engine, no Node version floor.

1. **Build / refresh** (operator work at a terminal — never from a seat; see the rule below the list) — one
   command rebuilds the static graph **and** re-applies every injected-edge rule
   (per-repo TOML drop-ins under `.wicked-estate-extractors/`, e.g. garden's archetype rules):
   ```bash
   wicked-estate index <path>        # DB defaults to .wicked-estate/graph.db
   ```
   Incremental and idempotent — unchanged files are skipped; editing the extractor
   rules forces a full re-extract. The estate binary the shim spawns serves the same DB, so a refresh is
   immediately visible to the tools. Freshness is lazy (opt-in `wicked-estate watch`);
   estate prints a `STALENESS: N commit(s) since last index` marker — re-run when stale.
2. **Verify**: `wicked-estate stats` reports node/edge counts plus `unresolved=N`
   (references no resolver could bind — a health signal, not an error count); archetype
   wiring shows as injected edges (provenance `extractor:archetype-*`).

**From a seat — any seat, any session kind** (a governed run's unit, a chat turn, any session
where you are the agent): the graph is handed to you already indexed and the write CLI is **never**
yours: never `wicked-estate index`, never `wicked-estate scip|tfstate|import-telemetry|compact|watch`,
never `wicked-estate clusters --annotate`. A stale graph is *reported* through its
`STALENESS` marker, not rebuilt — the shim's `call` prints it under `diagnostics`, beside any
`CLAMPED:` line (a bound the server lowered), so read that list before trusting a result. Binary resolution: `WICKED_ESTATE_BIN` env → `PATH` → `~/.local/bin`.

## Resolving symbols + the one way to the graph (shared by every action)

**The one way to the graph — on every seat, in every session kind** (a governed run's unit, a chat
turn, a human session at a terminal): the estate shim in read-only mode, store pinned by the
environment. Every estate tool named in this skill is reachable through its `call` action:
```bash
wicked-garden run scripts/_estate_client.py --readonly call '{"tool":"BlastRadius","arguments":{"symbol":"<name>"}}'
```
`--readonly` is literal (the spawned estate binary reads only; `WICKED_ESTATE_READONLY=1` rides
every worker so it spawns read-only by default). The store rides `WICKED_ESTATE_DB` /
`WICKED_HOME` / `WICKED_MEMORY_DB` from the environment, or `--db <path>`; the shim refuses an
unpinned store (`{"ok": false, "reason": …}`) — report that, never guess a store. There is no
other transport: no estate tool is registered on any seat, so there is nothing to "connect",
nothing to fall back to, and no second rung — a grep is not the graph.

**Resolve the symbol.** Estate tools take symbol **names** directly (a file node's name is its
repo-relative path, e.g. `scripts/_bus.py`); when a name is ambiguous or you need the node id,
resolve it first:
```bash
wicked-garden run scripts/_estate_client.py --readonly call '{"tool":"SearchEntity","arguments":{"name":"<symbol>"}}'
```
`name` is the exact / substring symbol match; `query` is full-text over the knowledge stores and
answers `matches: []` for a code symbol — a 0-hit `query` does not mean the graph is empty.

**Name the path that answered** (`shim` or `ungrounded`) in every result. If the shim answers
`{"ok": false, …}` or the fence denies the call, write `estate: not available (<reason>)` in your
output and continue **UNGROUNDED** — report the gap; do not substitute grep for the graph. A
denied call is final: record it — no variants, no wrappers, no retry
(`wicked-garden-governed-worker` A2/A5). The `wicked-estate` CLI is not a rung: its write verbs
are never run from a seat (§ Index / freshness) and its read verbs are not how a seat grounds.

## Blast radius — "what breaks if I change X?"

Analyze what would be affected if you changed a symbol — traces **dependents**
(what uses this) over the code-relationship graph, including injected edges
(bus/dispatch/capability/archetype) that grep and a static call-graph cannot see.
For **data-flow tracing** (UI field → DB column or reverse) use the `lineage` action.

**Arguments**: `symbol` (required — a file path like `src/app.py`, or a symbol
name); `--depth` (optional traversal depth; estate default 8, max 24).
Starting from a **file path** returns its **importer files** as dependents
(File→File import edges), so `blast-radius scripts/_bus.py` answers "which
files import this file" — no longer an empty "no resolved dependents".

1. **Freshness** (§ Index / freshness) — read the `STALENESS` marker and report it; never
   rebuild from a seat.
2. **Resolve the symbol** (§ Resolving symbols).
3. **Query blast radius from estate** (static + injected dependents in one
   answer — the authoritative layer): the estate **`BlastRadius`**
   tool with `{"symbol": "<name-or-path>", "depth": <n>}` through the shim (§ Resolving symbols).
   The `dependents` array includes relationships grep can't see: a command that
   *dispatches* an agent, a consumer that *subscribes* to an event, an agent that
   *declares* a capability — and archetype→playbook relationships via garden's
   `.wicked-estate-extractors/archetype.toml` (provenance `extractor:archetype-playbook`).
   **The whole answer, not page 1** (estate#279): estate pages a wide answer (`next_cursor`), and
   the shim's `call` follows every cursor and joins the pages, so `dependents` is complete. Read
   `complete` in the result: `false` means a page failed or a depth/node cap cut the walk (see
   `diagnostics`), and you report it as partial, never as the full blast radius.
   Results carry confidence + provenance per edge and an `unresolved_callers` count —
   reference sites **no resolver could bind** (repeat call sites of a bound relationship
   are NOT counted, so `0` is legitimate for a fully-resolved hot symbol).
4. **Path**: the shim (§ Resolving symbols + the one way to the graph) — or `ungrounded`, said so.
5. Report: **dependents** (static + injected, with provenance), total blast-radius
   count, files affected, the graph's staleness, and **which path answered** (`shim` / `ungrounded`).

Examples: `blast-radius scripts/_bus.py` · `blast-radius UserService --depth 3`.

## Lineage — "where does this flow from / to?"

Trace flow through the code-relationship graph. Downstream = what the symbol depends
on; upstream = what depends on it. Includes injected edges grep can't see.

For pure "what breaks if I change X?" use the `blast-radius` action.

**Arguments**: `symbol` (required — a file path or symbol name);
`--direction` (optional, default `downstream`): `downstream` (dependencies),
`upstream` (dependents), or `both`; `--depth` (optional traversal depth;
estate default 24 for `Lineage` and 8 for `BlastRadius`, max 24).

1. **Freshness** (§ Index / freshness) — report the `STALENESS` marker; never rebuild from a seat.
2. **Resolve the symbol** (§ Resolving symbols).
3. **Trace** with the estate tools through the shim:
   - **downstream** (what it depends on): the **`Lineage`** tool with
     `{"symbol": "<name>"}` → `dependencies` (with `"relation": "flows_to"`, value flow →
     `dependencies` are the consumers and `flows` the hops). Lineage's default depth is its
     ceiling (24), and the shim follows `next_cursor` to the end of the answer (estate#279):
     check `complete` and report a `false` as partial.
   - **upstream** (what depends on it): the **`BlastRadius`** tool with
     `{"symbol": "<name>"}` → `dependents`.
   - **both**: run both and present each direction. (A bounded multi-hop walk
     with edge-kind filters is available via the **`TraverseGraph`** tool.)
   - **a route between two named symbols** ("how does A reach B?"): the `path`
     action (§ Path) — never hand-assemble it from `TraverseGraph` edge lists.
   Each result includes injected edges (e.g. a consumer reached via a bus
   rule, an archetype via `extractor:archetype-playbook`) with confidence +
   provenance per edge.
4. **Path**: the shim (§ Resolving symbols + the one way to the graph) — or `ungrounded`, said so.
5. Report each path (source → sink), file locations per step, provenance of
   injected hops, gaps, and **which path answered** (`shim` / `ungrounded`).

Examples: `lineage scripts/_bus.py --direction upstream` · `lineage User.email --direction both`.

## Path — "how does A reach B?"

The ordered hops from one symbol to another — the route itself, not a reachability set you
search by hand. Use it whenever the question names two ends ("how does this handler reach the
DB write?", "does A ever call B, and through what?"); never reassemble a route from
`TraverseGraph`'s edge list.

**Arguments**: `from` and `to` (required — an exact symbol name, or a SymbolId as handed back
by `SearchEntity` / `TraverseGraph`); `depth` (optional; estate default 8, max 16); `max_nodes`
(optional; estate default 1000, max 5000).

1. **Freshness** (§ Index / freshness) — report the `STALENESS` marker; never rebuild from a seat.
2. **Resolve both ends** (§ Resolving symbols) when either name is ambiguous.
3. **Query the route** — the estate **`Path`** tool through the shim:
   ```bash
   wicked-garden run scripts/_estate_client.py --readonly call '{"tool":"Path","arguments":{"from":"<symbol-A>","to":"<symbol-B>","depth":8}}'
   ```
   `hops[]` is the route in order; each hop carries `kind`, `confidence`, `provenance` and
   `resolved_by`, with both endpoints denormalized (`name`, `file`, `line`) — name the
   intermediate functions and open only those files.
4. **Read `found` together with its bound flags — a bounded absence is not proof of absence.**
   `found: false` with `depth_bounded: false` AND `node_bounded: false` is a **proven** absence
   in the indexed graph. `found: false` with `depth_bounded` or `node_bounded` set means the
   search hit its depth or node budget: report "no route within depth N / M nodes", never "A
   never reaches B"; widen `depth` / `max_nodes` (within the caps) or try the reverse direction
   before concluding. `unresolved: "from"` / `"to"` names an operand estate could not resolve —
   an input problem, not a route verdict: resolve the name (§ Resolving symbols) and retry.
   A hop with low `confidence` is heuristic — say so when you report it.
5. **Which path answered**: the shim (§ Resolving symbols + the one way to the graph) — or
   `ungrounded`, said so.
6. Report the hops in order (source → target, edge kind, confidence, file:line at each end), the
   bound flags, the graph's staleness, and **which path answered** (`shim` / `ungrounded`).

Examples: `path handle_request write_row` · `path scripts/_bus.py scripts/_estate_client.py --depth 12`.

## Hotspots — most-central symbols

Rank symbols by PageRank centrality to expose god-objects, coupling
hotspots, and high-impact refactor targets — the estate `RankHotspots`
tool through the shim. → Full procedure: [refs/hotspots.md](refs/hotspots.md)

## Service map — detect the service architecture

Detect services and their connections from infrastructure config
(docker-compose/k8s/helm) plus code patterns; report as table, json, or
mermaid. → Full procedure: [refs/service-map.md](refs/service-map.md)

## Narrate — codebase orientation

For "give me an architecture walkthrough" / "narrate this codebase" / "where
should I start reading", use the nested skill:
[codebase-narrator/SKILL.md](codebase-narrator/SKILL.md) — produces a guided
reading order, annotated directory map, data-flow diagram, and gotchas list.

## Answer — cited synthesis ("ask the record")

For "answer this from the knowledge base" / "what does the record say about X", load
[refs/answer.md](refs/answer.md) — synthesizes an answer strictly from wicked-estate `knowledge.recall` +
`memory.recall` results, citing each claim's `source`. Shared with the `wicked-garden-mem` skill's `answer` action.

Files in this skill

  • SKILL.md15.3 KB
  • codebase-narrator/SKILL.md4.7 KB
  • codebase-narrator/refs/output-template.md2.6 KB
  • refs/answer.md3.7 KB
  • refs/hotspots.md2.1 KB
  • refs/service-map.md2.4 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.