Query vault knowledge with tiered retrieval using index.md and summary fields
Answer questions by searching the project's Obsidian vault for knowledge.
{vault_path}/_meta/vault-schema.md to understand vault structureBefore routing, check which backends are available:
# Derive vault_path from context-discovery
VAULT_PATH="<from CLAUDE.md>"
# T1: NotebookLM — check vault path and project root for config
HAS_T1=false
if command -v notebooklm &>/dev/null; then
if [ -f "$VAULT_PATH/.notebooklm/config.json" ] || [ -f ".notebooklm/config.json" ]; then
HAS_T1=true
fi
fi
# T2: MemPalace — check for the specific project wing
HAS_T2=false
if command -v mempalace &>/dev/null; then
if [ -L "$VAULT_PATH" ]; then
PROJECT_WING=$(readlink -f "$VAULT_PATH" | sed 's|[/.]|-|g')
else
PROJECT_WING=$(echo "$PWD" | sed 's|[/.]|-|g')
fi
if mempalace status 2>/dev/null | grep -q "WING: $PROJECT_WING"; then
HAS_T2=true
fi
fi
# Conversation wing (for shared vaults where vault wing ≠ conversation wing)
CONVO_WING=$(echo "$PWD" | sed 's|[/.]|-|g')
# T3: Obsidian-CLI — will check by invoking obsidian:obsidian-cli skill
HAS_T3="check-at-use"
# T4: index.md — always available
HAS_T4=false
[ -f "$VAULT_PATH/index.md" ] && HAS_T4=true
Log unavailable tiers:
/wiki-update to generate index.md or configure T1/T2/T3."Determine query type:
Factual lookup:
.notebooklm/config.json (check {vault_path}/.notebooklm/ first, then project root .notebooklm/) to get notebook IDnotebooklm ask "{query}" --notebook {notebook_id}Synthesis / Relationship:
$(echo "$PWD" | sed 's|[/.]|-|g')mempalace search "{query}" --wing="$PROJECT_WING" --results 10mempalace search "{query}" --wing="$CONVO_WING" --results 5Gap (what don't we know):
Search (find all mentions):
obsidian:obsidian-cli skill:
obsidian search query="{search term}" limit=10obsidian read file="{name}"Browse (what pages exist):
This is the existing retrieval flow, renamed from "Tiered Retrieval" to avoid collision with T1-T4.
Step 3a — Index scan (always):
Read {vault_path}/index.md. Search for pages matching the query by title, tags, and summary. Build a candidate list of 5-10 pages.
Step 3b — Summary scan (if needed):
For each candidate, read the summary: field from frontmatter. Filter to the 3-5 most relevant pages based on summary content.
Step 3c — Full read (selective): Read full content of the top 3 candidates only. Follow up to 1 wikilink hop for additional context.
Compose the answer with citations using [[page-name]] wikilink notation. Include:
If the user says "quick answer" or "just scan": use only T4 Step 3a (index scan). Return matching page titles and summaries without reading full pages.
Machine-readable subcontract consumed by /ark-context-warmup. Spec: docs/superpowers/specs/2026-04-12-ark-context-warmup-design.md. Calling convention: docs/superpowers/plans/2026-04-12-ark-context-warmup-implementation.md D6.
Wiki-query already exposes the right behavior as a skill — this contract just tells warm-up which scenario-aware queries to run and how to extract findings. The actual implementation lives in the /wiki-query workflow; warm-up invokes it via the inline command pattern below.
warmup_contract:
version: 1
commands:
- id: scenario-query
# Warm-up invokes wiki-query inline via its T4 scan path (index.md + summaries).
# For the warm-up's purposes, we only need the top-3 most relevant summaries, not the full T1/T2/T3 routing.
shell: 'python3 "$ARK_SKILLS_ROOT/skills/wiki-query/scripts/warmup_scan.py" --vault {{vault_path}} --query {{query}} --top 3 --json'
inputs:
vault_path:
from: env
env_var: WARMUP_VAULT_PATH
required: true
query:
from: template
template_id: scenario_query
output:
format: json
extract:
matches: '$.matches' # [{title, summary, path}]
tier_used: '$.tier' # always "T4" for warmup
required_fields: [matches]
prompt_templates:
# Two-layer indirection: /ark-context-warmup sets WARMUP_SCENARIO_QUERY_TEMPLATE
# to the appropriate scenario_templates entry below before dispatching the
# wiki lane. The executor's _interpolate_template iterates until a fixed
# point, so the outer {WARMUP_SCENARIO_QUERY_TEMPLATE} expansion plus the
# inner {WARMUP_TASK_TEXT} in the scenario template both resolve in one
# resolve_input call. Use single-brace — shell-style ${VAR} is not a
# supported placeholder form.
scenario_query: |
{WARMUP_SCENARIO_QUERY_TEMPLATE}
scenario_templates:
# Picked by warm-up based on WARMUP_SCENARIO env var; template substituted into scenario_query above.
greenfield: 'Has anything like {WARMUP_TASK_TEXT} been built before? Existing components or prior design decisions?'
bugfix: 'Have we seen bugs related to {WARMUP_TASK_TEXT} before? Known failure modes, incident notes, prior fixes?'
migration: 'Past migration notes for {WARMUP_TASK_TEXT}? Rollback procedures, prior framework changes?'
performance: 'Past optimization work on {WARMUP_TASK_TEXT}? Benchmarks, bottleneck analyses?'
hygiene: 'Related refactors or audits on {WARMUP_TASK_TEXT}? Tech debt notes, prior cleanup?'
ship: 'Deploy runbooks, rollback steps, prior incidents for {WARMUP_TASK_TEXT}? Environment-specific gotchas?'
knowledge-capture: 'What vault pages already exist on {WARMUP_TASK_TEXT} topic? Recent session coverage?'