Load relevant entities from the bstack knowledge graph (research/entities/) for a given topic. Two-tier scoring: tier-1 (catalog-only, ~5ms — slug + tags + claim + links + sources match against docs/knowledge-index.md) is the fast first pass and the only stage for high-confidence exact-slug/tag queries; tier-2 (body-grep fallback, ~300ms — auto-fires when tier-1 returns < N matches OR its best hit is below the confidence floor, default 18) recovers topics whose vocabulary appears in entity prose but not the dense catalog (hit rate jumps from 70% → 100% on representative queries; this is hit rate ≥1, not true recall@N). Surfaces top-N entity bodies as a single context block the agent reasons over. This is a LOAD skill, not a query DSL — querying is what the agent does once loaded. Implements the LLM-as-index architecture (BRO-1223): substrate canonical, one projection (catalog) routes, agent IS the query engine. Empirical: peak per-query context drops from 29% → 4.6% of 1M (6.3× reduction); cumulative session
Load relevant entities from the bstack knowledge graph (research/entities/) for a given topic. Two-tier scoring: tier-1 (catalog-only, ~5ms — slug + tags + claim + links + sources match against docs/knowledge-index.md) is the fast first pass and the only stage for high-confidence exact-slug/tag queries; tier-2 (body-grep fallback, ~300ms — auto-fires when tier-1 returns < N matches OR its best hit is below the confidence floor, default 18) recovers topics whose vocabulary appears in entity prose but not the dense catalog (hit rate jumps from 70% → 100% on representative queries; this is hit rate ≥1, not true recall@N). Surfaces top-N entity bodies as a single context block the agent reasons over. This is a LOAD skill, not a query DSL — querying is what the agent does once loaded. Implements the LLM-as-index architecture (BRO-1223): substrate canonical, one projection (catalog) routes, agent IS the query engine. Empirical: peak per-query context drops from 29% → 4.6% of 1M (6.3× reduction); cumulative session tokens 23.8× fewer over 10 queries. Default N=10 entities; override with --n. Tier-2 auto-fires on few-OR-weak tier-1 hits (confidence gate, default --tier2-floor 18; BRO-1426 lifts R@5 0.871→0.952, MRR 0.868→0.968 with no flag); force unconditionally with --body-search, disable the gate with --tier2-floor 0. Routing-quality flags (BRO-1422): --terms (query expansion — score agent-supplied synonyms/variants alongside the topic), --expand 1 (graph 1-hop — also load related: neighbours of top hits, capped at --n extra, total ≤ 2x--n), --explain (per-signal score trace); hub-aware tiebreak always on. Output: catalog header + ranked entity blocks with full body. USE WHEN load knowledge graph, kg load, load entities, route to entities, load context for, what do we know about, what entities are relevant to, surface knowledge on, browse the graph for, find entities about, semantic load, topical load, agent-as-index load. NOT FOR PAI session retrieval (use ContextSearch), web research (use Research), Knowledge Archive ingest (use Knowledge), or entity write/edit operations (those are direct Read+Edit + commit per the AGENTS.md §P6 sub-rule on substrate-edit-as-inference-persistence).
argument-hint
["topic"]
effort
low
kg — knowledge graph loader
Load relevant entities for: $ARGUMENTS
Purpose
The bstack knowledge graph lives at research/entities/**/*.md (~250 entities, ~1.1 MB, ~280k tokens). It fits in any 1M-context model with 3.5× headroom — meaning the LLM is the index. This skill performs the routing step: reads the dense catalog at docs/knowledge-index.md, ranks entities by topical relevance, and surfaces the top-N bodies as a single context block.
The agent does the rest: traversal, inference, contradiction detection, semantic comparison — all by reading. There is no SQL layer, no embeddings, no typed-edge schema. The substrate is canonical; the catalog routes; the agent reasons.
Usage
/kg load <topic> # default: top 10 (two-tier; tier-2 auto-fires on few OR weak tier-1 hits)
/kg load <topic> --n 20 # widen the load
/kg load <topic> --type tool # restrict by entity type
/kg load <topic> --terms "recall,persistence" # query expansion: score synonyms/variants too
/kg load <topic> --expand 1 # also load 1-hop related: neighbours of the top hits
/kg load <topic> --explain # show the per-signal score trace for each loaded entity
/kg load <topic> --body-search # force tier-2 body grep unconditionally
/kg load <topic> --tier2-floor 0 # disable the confidence gate (tier-2 only on count<--n)
/kg load <topic> --json # machine-readable output (for piping)
/kg # catalog-only mode: print summary stats + top hubs
Routing-quality flags (BRO-1422)
These raise routing recall without leaving the LLM-as-index architecture
(no sidecar, no embeddings). The gap was never reasoning — a frontier agent
reranking the top-N already beats a small reranker model — it was that whatever
routing drops below N, the agent never sees.
--terms (query expansion). The single biggest recall lever. The catalog
scorer matches literal terms; pass the synonyms/variants the topic implies and
they're scored alongside it. The agent IS the query expander here — no headless
expansion model needed (that's the only reason QMD fine-tunes one). Repeatable
(one value per flag); each value may be comma/space-separated. Topic terms keep
priority on ties.
--expand 1 (graph 1-hop). After ranking, also pull the related:
neighbours of the top hits — the structural advantage flat-document search
(BM25, vector) structurally cannot offer. Automates the "reading frontier"
(Phase 3). Neighbours are deduped against the primary set, ranked by their own
relevance then in-degree, and capped at --n extra entities (so total load
is ≤ 2×) — a hub neighbour (e.g. , in-degree 100+) can't explode the
load. Each is marked (its immediate parent). Only 1 hop is
supported for now (values >1 clamp to 1, so provenance always resolves);
under , expansion is limited to that type (a one-line note is printed)
since cross-type edges aren't resolved.
--n
arcan
↳ via <seed>
via
--type
--explain (score trace). Prints which signals fired per entity
(slug==x(+10) tag==y(+4) … = N catalog, plus a +M tier-2 body grep
residual line when the body grep contributed). Use it to debug routing misses.
hub-aware tiebreak (always on). At equal relevance, the more-connected
entity (higher catalog in-degree) sorts first instead of alphabetically —
a cheap stand-in for a hub-rank RRF term.
Workflow
Phase 1 — Verify catalog freshness
Check docs/knowledge-index.md exists and is fresh:
ls -la ~/broomva/docs/knowledge-index.md
head -5 ~/broomva/docs/knowledge-index.md # check `generated:` timestamp
If the catalog is older than the Stop hook's regeneration cadence (~24h), regenerate first:
python3 ~/broomva/skills/bookkeeping/scripts/bookkeeping.py index
exact alias match: +8 (BRO-1423 — aka: alternate names: kepano synonyms + merged-away dup slugs; querying an alias routes to the canonical)
slug substring: +5
alias substring: +4
tag exact: +4
tag substring: +3
claim substring: +3
link or source substring: +1 each
Sorts; takes top-N candidates
Tier 2 — body-grep fallback (slower, ~300ms, auto-fires when tier-1 is insufficient)
Tier-2 re-scores every entity by reading its body file (+2 per topic term present in the body). It fires automatically on any of:
tier-1 returned fewer than --n matches (too few hits), or
tier-1's best hit is below the confidence floor (hits too weak — default --tier2-floor 18), or
--body-search is forced.
The confidence gate (BRO-1426) is the important one: a paraphrase / body-only query used to fill the top-n with weak distractors, so the old count < --n gate never fired and the real (body-only) answer was never surfaced. Now a weak top score (a lone substring/tag hit scores 3–10; a genuine multi-signal match scores ≳ 18) auto-triggers the body read. Calibrated on the 62-query gold-set: it lifts R@5 0.871 → 0.952 and MRR 0.868 → 0.968with no flag, with 5 gains and 0 per-query regressions (verified floor 0→18; the body bonus only ever pulled body-only answers into contention, never demoted a tier-1 winner). Latency note: because most non-trivial topics have a sub-18 top tier-1 score, tier-2 now fires for the majority of loads — the ~5ms tier-1-only path is the exception (exact-slug/tag hits), the recall-correct default is the ~300ms two-tier pass. Override with --tier2-floor N (set 0 to disable the gate; raise it to fire tier-2 more eagerly).
This catches entities whose topic vocabulary appears in the prose but not in the dense catalog (claim + tags + slug + links + sources).
After scoring, the loader:
4. Resolves each top-N entity to its filesystem path via the path: type/slug.md field in catalog v2 (eliminates slug-clash ambiguity)
5. Reads each entity's full body
6. Prints them as one context block
Phase 3 — Reason over loaded context
Now the agent has the routing layer (catalog) + the relevant entity bodies in context. Use this for:
Semantic similarity — "what other concepts are similar to X?" — the agent reads and compares
Typed edge inference — "does X supersede Y?" — read both, infer from prose
Contradiction detection — "do any of these entities contradict each other?" — read and judge
Pattern matching — "find candidate patterns sourced from a synthesis note that link to active concepts" — read the loaded entities, filter
Reading frontier — "given I know X, what should I read next?" — read X's out-edges, prioritize by in-degree
Phase 4 — Persist inferences back to the substrate (binding reflex)
Per AGENTS.md §P6 sub-rule on substrate-edit-as-inference-persistence: when the agent infers a typed relation from the loaded entities — and the relation is not yet expressed in the substrate — the correct action is to edit the entity's frontmatter related: block or body and commit. Inferences that don't get committed are inferences that didn't happen.
The substrate evolves through reading. A session that loads 20 entities and persists 0 inferences has either genuinely encountered nothing new, or violated the reflex. Both are reportable in the session-close summary.
Output format
The skill prints a context block the agent can ingest:
The bordered blocks make it easy to scan and easy to cite back to disk paths.
Composition with other skills
ContextSearch is upstream (PAI session retrieval) — call it for "what did we do" questions; call this skill for "what do we know" questions
Research is sideways (web research) — call it for external knowledge; call this skill for internal knowledge
bookkeeping is the write side — bookkeeping run ingests new material; this skill reads the result
Knowledge is the archive — call it for ingestion of long-form content; call this skill for routing within already-ingested material
When NOT to use
PAI session questions ("what did we do with X?") — use ContextSearch
Web research ("find papers on X") — use Research
Long-form content ingestion ("read this 50-page PDF and store it") — use Knowledge ingest
Single-entity reads when you already know the slug — just use Read directly on research/entities/{type}/{slug}.md
Catalog generation — that's bookkeeping index, not this skill
Gotchas
Stale catalog — if docs/knowledge-index.md is >24h old, regenerate via bookkeeping index first. The Stop hook does this automatically; if it hasn't fired (e.g., the user has been in a long session), regenerate manually.
Workspace WIP — the catalog reflects what's on disk in research/entities/, including uncommitted user WIP. That's correct behavior. If validating against committed-only state, regenerate from inside a clean worktree.
Token budget — default load is 10 entities (~6-15 KB). Override with --n when you need more, but be mindful of context budget for long sessions.
Execution Log
After completing any workflow, append a single JSONL entry: