Adaptive vault reader skill. Receives a natural language question, uses graph.json as the primary index (Phase 2.0) before any glob/grep, then self-assesses whether more context is needed. Escalates to live /graphify only when graph coverage is insufficient, or to /bedrock:learn
Installs just this skill. Get the whole plugin for auto-invocation.
β‘ How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itselfClaude auto-loads it when your prompt matches the work.
You can call itInvoke it directly when you want it.
Slash command/ask
ποΈ Context preview
The summary Claude sees to decide when to auto-load this skill.
Adaptive vault reader skill. Receives a natural language question, uses graph.json as the primary index (Phase 2.0) before any glob/grep, then self-assesses whether more context is needed. Escalates to live /graphify only when graph coverage is insufficient, or to /bedrock:learn
π Stats
Stars83
Forks8
LanguageHTML
LicenseMIT
π¦ Ships with bedrock
</> SKILL.md
ask.SKILL.md
---name: ask
description: >
Adaptive vault reader skill. Receives a natural language question,
uses graph.json as the primary index (Phase 2.0) before any glob/grep,
then self-assesses whether more context is needed. Escalates to live /graphify
only when graph coverage is insufficient, or to /bedrock:learn for remote content
ingestion. Answers simple questions with zero graphify calls.
Use when: "bedrock ask", "bedrock-ask", "/bedrock:ask", any question about the vault,
"what do we know about", "who owns", "what's the status of", "tell me about",
"how does it work", or any Second Brain query.
user_invocable: true
allowed-tools: Bash, Read, Glob, Grep, Skill, Agent
---# /bedrock:ask β Adaptive Vault Reader
## Plugin Paths
Entity definitions and templates are in the plugin directory, not at the vault root.
Use the "Base directory for this skill" provided at invocation to resolve the paths:
- Entity definitions: `<base_dir>/../../entities/`
- Templates: `<base_dir>/../../templates/{type}/_template.md`
- Plugin CLAUDE.md: `<base_dir>/../../CLAUDE.md` (already automatically injected into context)
Where `<base_dir>` is the path provided in "Base directory for this skill".
---
Resolve which vault to query. This skill can be invoked from any directory.
**Step 1 β Parse `--vault` flag:**
Check if the input arguments include `--vault <name>`. If found, extract the vault name and remove it from the arguments (the remaining text is the question).
**Step 2 β Resolve vault path:**
1. **If `--vault <name>` was provided:**
Read the vault registry at `<base_dir>/../../vaults.json`. Find the entry matching the name.
If not found: error β "Vault `<name>` is not registered. Run `/bedrock:vaults` to see available vaults."
If found: set `VAULT_PATH` to the entry's `path` value.
2. **If no `--vault` flag β CWD detection:**
Read `<base_dir>/../../vaults.json`. Check if the current working directory is inside any registered vault path
(CWD starts with a registered vault's absolute path). If multiple match, use the longest path (most specific).
If found: set `VAULT_PATH` to the matching vault's `path`.
3. **If CWD detection fails β default vault:**
From the registry, find the vault with `"default": true`.
If found: set `VAULT_PATH` to the default vault's `path`.
4. **If no resolution:**
Error β "No vault resolved. Available vaults:" followed by the registry listing.
"Use `--vault <name>` to specify, or run `/bedrock:setup` to register a vault."
**Step 3 β Validate vault path:**
```bash
test -d "<VAULT_PATH>" && echo "exists" || echo "missing"
```
If missing: error β "Vault path `<VAULT_PATH>` does not exist on disk. Run `/bedrock:setup` to re-register."
**Step 4 β Read vault config:**
```bash
cat <VAULT_PATH>/.bedrock/config.json 2>/dev/null
```
Extract `language` and other relevant fields for use in later phases.
**From this point forward, ALL vault file operations use `<VAULT_PATH>` as the root.**
- Entity directories: `<VAULT_PATH>/actors/`, `<VAULT_PATH>/people/`, etc.
- Graphify output: `<VAULT_PATH>/graphify-out/`
---
## Overview
This skill receives a natural language question and answers it using an adaptive,
vault-first approach. It always reads vault content first, then decides whether
to escalate to graphify or /learn ased on what's actually needed β not what the
question looks like in isolation.
**You are an adaptive context orchestrator agent. You only READ β never write, edit, or delete files directly.**
Writes happen exclusively through `/bedrock:learn` delegation (which flows through `/bedrock:preserve`).
If the query reveals outdated or missing information and no remote source is available to ingest,
suggest that the user run `/bedrock:preserve` or `/bedrock:learn` to update the vault.
---
## Phase 0 β Read Configuration
### 0.1 Load config
Read `.bedrock/config.json` from the vault root:
```bash
if [ -f ".bedrock/config.json" ]; then
cat .bedrock/config.json
else
echo "config_not_found"
fi
```
- **If config exists:** extract the value of `query.max_graphify_calls`. Store as `max_graphify_calls`.
- **If config does not exist or field is absent:** set `max_graphify_calls = 3` (default).
- **Valid range:** 1β5. If the value is outside this range, clamp to the nearest bound and log a warning.
---
## Phase 1 β Analyze the Question
### 1.1 Classify the question
Read the user's question and identify:
1. **Mentioned entities** β names of systems, people, teams, topics, projects, or discussions.
Infer from the mentioned entities or the question context.
3. **Type of information sought:**
- **Status/overview** β "what is X?", "what's the status of X?"
- **Architecture/stack** β "how does X work?", "what's the stack of X?"
- **People/teams** β "who owns X?", "who works with Y?"
- **History/decisions** β "what was decided about X?", "what happened with Y?"
- **Relationships** β "what depends on X?", "how does Y relate to Z?"
- **Deprecation** β "what is being deprecated?", "what's the deprecation plan for X?"
### 1.2 Assess clarity
If the question is too ambiguous to produce a targeted search (e.g.: "tell me everything",
"how does the system work?", "what's going on?"), ask for clarification:
> "Your question is broad. Can you specify: which system, team, or topic would you like to know more about?"
If the question mentions something that clearly isn't part of the vault (e.g.: something personal,
unrelated technology), inform: "I didn't find anything in the vault about this."
### 1.3 Phase 1 classification result
At the end, you should have:
- **search_terms**: list of names, aliases, and keywords to search for
- **domains**: list of relevant domains (may be empty if not identified)
- **info_type**: classification of the type of information sought
- **explicit_entities**: entities mentioned directly by name (if any)
---
## Phase 2 β Graph-First Search
This phase **always runs** for every question. It uses the cumulative knowledge graph
as the primary index when available, falling back to glob/grep for terms not represented
in the graph. Never skip this phase.
### 2.0 Check graph.json and score nodes
Before any glob/grep, check if the cumulative knowledge graph is available:
```bash
if [ -f "<VAULT_PATH>/graphify-out/graph.json" ] && [ -s "<VAULT_PATH>/graphify-out/graph.json" ]; then
echo "graph_available"
else
echo "graph_not_available"
fi
```
**If `graph_available`:**
1. Read `<VAULT_PATH>/graphify-out/graph.json` β extract only the `nodes` array (skip edges to avoid context explosion on large graphs). If the nodes array exceeds 500 entries, read only the first 500 β graphify orders nodes by centrality, so high-value nodes come first.
2. From the nodes array, extract per node: `id`, `label`, `file_type`, `source_file`, `community`, `is_god_node`.
3. Score nodes by relevance to the search terms from Phase 1:
- **Primary signal:** node `label` contains or closely matches any search term
- **Secondary signal:** node belongs to a community that contains other high-scoring nodes (community resonance)
- **Boost:** `is_god_node: true` nodes get elevated priority when their label is even loosely relevant to the query
4. Select top N nodes (N β€ 15, same limit as the current entity read budget). Track which search terms produced β₯ 1 matching node and which produced none.
5. For each selected node with a non-null `source_file`:
- Resolve the corresponding vault `.md` file: search for the `source_file` basename in entity directories
- If found: read the full entity file β this node is fully resolved (skip steps 2.2β2.4 for this entity)
- If not found: record graph metadata only (label, community, relevant edge labels) β use this metadata in Phase 5 response to surface the concept even without a vault file
6. For each search term that produced **zero** matching graph nodes β proceed to steps 2.2β2.4 (glob/grep) for **that term only**.
**If `graph_not_available`:**
Skip to step 2.1. No warning β this is the normal path for fresh vaults.
---
### 2.1 Read entity definitions
Use Read to read the entity definition files from the plugin (see "Plugin Paths" section):
- If the question is about a system β read `<base_dir>/../../entities/actor.md`
- If the question is about a person β read `<base_dir>/../../entities/person.md`
- If the question is about a team β read `<base_dir>/../../entities/team.md`
- If the question is about a topic/deprecation β read `<base_dir>/../../entities/topic.md`
- If the question is about a meeting/decision β read `<base_dir>/../../entities/discussion.md`
- If the question is about a project/initiative β read `<base_dir>/../../entities/project.md`
- If you don't know the type β read all entity definitions from the plugin to classify correctly
Rationale: remote content must be internalized first for the vault to be complete.
Graphify can run on richer data after ingestion. If both apply, handle remote content first,
then re-assess whether graphify is still needed.
**After determining the outcome:**
- `vault_sufficient` β skip directly to **Phase 4** (recency) then **Phase 5** (respond)
- `needs_graphify` β proceed to **Phase 3-G**
- `needs_remote_content` β proceed to **Phase 3-T**
---
### Phase 3-G β Graphify Escalation
Execute only when the self-assessment determines `needs_graphify`.
#### 3-G.0 Assess graph coverage
Before escalating to a live `/graphify` call, assess whether the cumulative `graph.json`
already covers the gap identified in Phase 3.1. Live `/graphify` invocations are a last resort β
they re-extract what is likely already indexed.
**Step 1 β Check if graph was available in Phase 2.0:**
- If Phase 2.0 determined `graph_not_available`: display the warning below, ask the user whether to build the graph now, and wait for their response before proceeding.
- If Phase 2.0 determined `graph_available`: proceed to Step 2.
> [!warning] Knowledge graph unavailable
> The knowledge graph is not available (`<VAULT_PATH>/graphify-out/graph.json` missing or empty).
> The answer below is based on vault content only β it may be incomplete for this type of question.
After displaying the warning, ask the user:
> "O knowledge graph nΓ£o estΓ‘ disponΓvel, o que pode tornar esta resposta incompleta. Deseja reconstruΓ-lo agora antes de continuar?
> Se sim, rode: `/graphify build` β isso indexa todos os atores cadastrados no vault e pode levar alguns minutos.
> Responda **sim** para aguardar e tentar novamente, ou **nΓ£o** para continuar com o conteΓΊdo disponΓvel."
- **If the user responds "sim" (or equivalent affirmative):**
1. Inform: "Aguardando `/graphify build`β¦"
2. Invoke `/graphify build` via the Skill tool
3. After completion, re-run the Phase 2.0 availability check
4. If `graph.json` is now available, continue to Step 2
5. If still unavailable: inform the user and skip to Phase 4 with vault-only content
- **If the user responds "nΓ£o" (or equivalent negative), or does not respond:**
Skip to Phase 4 with vault-only content. Never block indefinitely.
**Step 2 β Assess coverage for the specific gap:**
Using the nodes collected in Phase 2.0, evaluate whether the gap identified in Phase 3.1 is covered:
- If the gap is about relationships or dependencies: check whether `graph.json` nodes for the relevant entities have edges. If yes, read the edges section of `graph.json` filtered to those node IDs and incorporate into the working context. Only invoke live `/graphify` if edges are also insufficient.
- If the gap is about a domain or concept with **zero** graph nodes (Phase 2.0 produced no matches for those search terms): live `/graphify` is warranted β proceed to 3-G.1.
- **When in doubt, escalate.** The coverage assessment is a soft gate β if there is any uncertainty about whether the graph covers the gap, proceed to 3-G.1 and invoke live `/graphify`.
#### 3-G.1 Formulate graphify calls
Based on the gap between what you have (Phase 2 content) and what the question needs,
formulate 1βN graphify calls. Use the same modes as before:
| Gap identified | Graphify mode |
|---|---|
| Need to understand a single entity's code structure | `explain "<entity>"` |
| Need to find how two entities connect | `path "<entityA>" "<entityB>"` |
| Need broad relationship or dependency context | `query "<question about the gap>"` |
The LLM decides the calls based on what's missing β not from a pre-planned decomposition.
Never exceed `max_graphify_calls`.
#### 3-G.2 Execute graphify calls sequentially
For each call, invoke `/graphify` via the Skill tool. Append the structured JSON output instruction:
```
After completing the traversal, return ONLY a JSON object with this structure (no prose, no markdown fences):
- If there is conflicting information between sources, point out the discrepancy.
7. **Fleeting note promotion detection (criterion 3: active relevance):**
When a fleeting note is referenced in the response because it is relevant to the query:
- Check if it meets promotion criteria (see `<base_dir>/../../entities/fleeting.md`):
- Critical mass (>3 paragraphs with sources)
- Corroboration (confirmed by an existing permanent)
- If any criterion is met, add at the end of the response:
`> [!info] Promotion suggested: [[fleeting-note-name]] can be promoted to permanent/bridge`
- `/bedrock:ask` does NOT promote automatically β it only flags. Promotion happens when
`/bedrock:preserve` is invoked with the instruction to promote.
### 5.2 Post-response suggestions
When appropriate, suggest actions to the user:
- If information is outdated: "The vault may be outdated about [X]. Consider running `/bedrock:learn <source>` to update."
- If the question revealed gaps: "I didn't find [Y] in the vault. If you have this information, you can use `/bedrock:preserve` to record it."
- If the question is complex and the response incomplete: "For a more complete view, you may also want to run `/bedrock:learn <URL>` to ingest additional sources."
---
## Critical Rules
| Rule | Detail |
|---|---|
| Vault-first principle | Phase 2 ALWAYS runs before any escalation. Read vault content first, decide later. Never skip Phase 2. |
| LLM self-assessment | The decision to escalate is made by the LLM after reading vault content (Phase 3.1), not by a heuristic rule table. Use the guidance provided, but the LLM makes the final call. |
| Escalation priority | When multiple outcomes apply: `needs_remote_content` > `needs_graphify` > `vault_sufficient`. Internalize first, then analyze. |
| No direct writes | `/ask` NEVER writes, edits, or deletes files directly. All writes are delegated through `/bedrock:learn` β `/bedrock:preserve`. |
| Teach delegation via Skill tool | Invoke `/bedrock:learn` via the Skill tool. `/learn` owns its confirmation gate. `/ask` cannot bypass it. |
| Graphify via Skill tool | Invoke `/graphify` via the Skill tool β NEVER call the Python API directly. |
| Max graphify calls | Read `query.max_graphify_calls` from `.bedrock/config.json` (default: 3, valid range: 1β5). Only consumed when graphify is actually invoked. |
| Graph unavailable warning | When `needs_graphify` but `graphify-out/graph.json` is missing, display `> [!warning]` callout with `/graphify build` instruction. Continue with vault-only content. |
| Best-effort escalation | If graphify fails or teach fails or user declines: continue with available content. NEVER block the response. |
| Limit of 15 entities | Do not read more than 15 entities total across Phase 2 + Phase 3 |
| Limit of 2 teach URLs | Do not invoke `/bedrock:learn` for more than 2 URLs per `/bedrock:ask` invocation |
| No fabrication | Respond ONLY with information found in the vault or obtained through escalation. Never fabricate data. |
| Clarification before guessing | If the question is ambiguous, ask for clarification. Do not assume. |
| Vault language with technical terms in English | Response always in the vault's configured language |
| Bare wikilinks | `[[name]]`, never `[[dir/name]]` |
| Consolidated entities = up-to-date | Actors, people, teams do not need temporal ranking |
| Dated discussions/topics = prioritize recent | Sort by date in filename (YYYY-MM-DD) |
| Sensitive data | NEVER display credentials, tokens, PANs, CVVs found in the vault |
| Fleeting notes with disclaimer | ALWAYS flag information from fleeting notes with `(source: fleeting note β unconsolidated information)` |
| Promotion as side-effect | When a relevant fleeting note meets promotion criteria, flag with callout. Do NOT promote automatically. |
| Weight hierarchy | permanent > bridge > index > fleeting. Use as guideline, not mathematical formula. |
| Vault resolution first | Resolve `VAULT_PATH` before any file operation β never assume CWD is the vault |
| All entity paths use `<VAULT_PATH>/` prefix | `<VAULT_PATH>/actors/`, not `actors/` |
| Graph-first in Phase 2 | Phase 2.0 always runs before glob/grep. grep is a fallback for search terms that produced no matching graph nodes, not the primary strategy. |