From learning-loop
Analyzes knowledge vault notes for coverage gaps, confidence tensions, and blindspots. Generates counterpoints and rewrites; supports topic, auto-pick, or sweep modes with depth scaled to note maturity.
npx claudepluginhub robinslange/learning-loop --plugin learning-loopThis skill uses the workspace's default tool permissions.
The vault grows by accumulation. `/gaps` shakes the cage. It surfaces tensions, questions absences, and flags thin ice. The truth doesn't need to defend itself: weak beliefs get questioned, strong beliefs get stress-tested.
Guides Next.js Cache Components and Partial Prerendering (PPR): 'use cache' directives, cacheLife(), cacheTag(), revalidateTag() for caching, invalidation, static/dynamic optimization. Auto-activates on cacheComponents: true.
Processes PDFs: extracts text/tables/images, merges/splits/rotates pages, adds watermarks, creates/fills forms, encrypts/decrypts, OCRs scans. Activates on PDF mentions or output requests.
Share bugs, ideas, or general feedback.
The vault grows by accumulation. /gaps shakes the cage. It surfaces tensions, questions absences, and flags thin ice. The truth doesn't need to defend itself: weak beliefs get questioned, strong beliefs get stress-tested.
/gaps "topic": focused analysis on a specific topic/gaps: auto-picks the densest unchallenged cluster in the vault/gaps --sweep: runs across all major domain clustersParse from the invocation. All have defaults.
| Parameter | Options | Default |
|---|---|---|
| topic | any string | auto-pick if absent |
| depth | shallow / medium / deep | scales to note maturity |
| sweep | flag | off |
| dry-run | flag | off |
Depth auto-scaling:
This skill emits provenance events for pipeline observability. Run each Bash command silently.
At session start (after scope identified):
node "${CLAUDE_PLUGIN_ROOT}/scripts/provenance-emit.js" '{"agent":"gaps","skill":"gaps","action":"session-start","intent":"TOPIC","config":{"depth":"DEPTH"}}'
At session end:
node "${CLAUDE_PLUGIN_ROOT}/scripts/provenance-emit.js" '{"agent":"gaps","skill":"gaps","action":"session-end","notes_analysed":N,"counterpoints_created":N,"rewrites":N,"thin_ice":N,"tensions":N,"blindspots":N}'
Per-note tracking is handled automatically by the PostToolUse hook.
Use AskUserQuestion to help users discover and configure parameters when no arguments are provided.
No arguments (/gaps):
Before auto-picking, ask:
What would you like to challenge? Options:
- A topic: e.g.,
/gaps "theanine": focused analysis on one domain- Auto-pick: I'll find the densest unchallenged cluster
- Sweep: analyse all major domain clusters (
--sweep)- Dry-run: show what would be analysed without running (
--dry-run)Optional:
--depth shallow|medium|deep(defaults to note maturity)
Topic provided (/gaps "topic"):
Proceed immediately. Depth auto-scales to note maturity.
Flags provided (/gaps --sweep, /gaps --dry-run):
Proceed immediately.
Auto-pick (/gaps with no topic):
node PLUGIN/scripts/vault-search.mjs cluster --threshold 0.7#gaps-reviewed tagSweep (/gaps --sweep):
Dry-run (--dry-run):
Spawn all three subagents in the same turn (a single message with three Agent tool calls, not sequential):
Vault Scout (discovery-vault-scout):
{{VAULT}}/), angle (if any)Adversarial Researcher (discovery-researcher):
Domain Survey Researcher (discovery-researcher):
Determine depth from vault scout results:
Spawn the Gap Analyser (gap-analyser):
PLUGIN/agents/_skills/Show the gap analyser's report. Group findings:
For each finding, offer actions inline:
Thin ice: "empty-stomach-maximizes-theanine-at-both-gates"
: mechanistic inference from transporter competition.
Direct meal-timing studies?
→ [C] Create counterpoint note [D] Flag for /deepen [skip]
Blindspot: The field of n-of-1 methodology covers adaptive randomization designs,
which the vault has no notes on.
→ [R] Research with /discovery [C] Create placeholder note [skip]
Based on user choices:
Create counterpoint note (free: just inbox):
note-writer with:
0-inbox/#counterpoint tag in frontmatterRewrite original note (ask permission first):
note-writer with existing_note contentFlag for /deepen:
/deepen queue shown at the endResearch blindspot (via /discovery):
/discovery queue shown at the endCreate placeholder note (for blindspots):
note-writer with the domain survey's description of the missing territory#blindspot and links to the nearest related vault note0-inbox/ as a stub for later /deepenBatch actions:
If Step 4 launched any note-writer subagents (counterpoints, rewrites, or blindspot stubs), their Write/Edit calls bypassed PostToolUse: backlinks and edge inference didn't run. Run the unlinked-body sweep documented in skills/_shared/hook-replay.md to catch them. Idempotent: safe even if Step 4 wrote nothing.
PLUGIN_DATA="${CLAUDE_PLUGIN_DATA:-$(node "${CLAUDE_PLUGIN_ROOT}/scripts/resolve-paths.mjs" PLUGIN_DATA)}"
LL_VAULT="$(node -e "const c=JSON.parse(require('fs').readFileSync(process.argv[1]+'/config.json','utf-8'));console.log(c.vault_path.replace(/^~/,require('os').homedir()))" "$PLUGIN_DATA")"
ll-search index "$LL_VAULT" "$LL_VAULT/.vault-search/vault-index.db" 2>&1 | tail -1
SWEEP_CANDIDATES="${TMPDIR:-/tmp}/ll-${CLAUDE_SESSION_ID:-$$}-sweep-candidates.txt"
LL_VAULT="$LL_VAULT" python3 - <<'PY' > "$SWEEP_CANDIDATES"
import os, re
root = os.environ["LL_VAULT"]
for d in ["0-inbox", "1-fleeting", "2-literature", "3-permanent", "5-maps"]:
for dirpath, _, files in os.walk(os.path.join(root, d)):
for f in files:
if not f.endswith(".md"): continue
p = os.path.join(dirpath, f)
try:
body = open(p).read()
body = re.sub(r"^---\n.*?\n---\n", "", body, count=1, flags=re.DOTALL)
if not re.search(r"\[\[[^\]]+\]\]", body):
print(p)
except: pass
PY
if [ -s "$SWEEP_CANDIDATES" ]; then
node "${CLAUDE_PLUGIN_ROOT}/scripts/sweep-hook-replay.mjs" --stdin < "$SWEEP_CANDIDATES"
fi
rm -f "$SWEEP_CANDIDATES"
Skip if Step 4 took no actions. Report failures in Step 6.
After analysis completes:
gaps-reviewed: YYYY-MM-DD to frontmatter of reviewed notesGaps: "[topic]"
Depth: [depth] | Notes analysed: [N]
Thin ice: [N] findings
Tensions: [N] findings
Blindspots: [N] (domain: [N], framing: [N])
Absences: [N] (central: [N], adjacent: [N])
Actions taken: [N] counterpoints created, [N] rewrites, [N] flagged for /deepen, [N] blindspot stubs created
After all clusters are processed:
Vault Sweep Complete
Clusters analysed: [N]
Cross-cluster tensions: [list any findings that span domains]
Vault-wide thin ice: [total count]
Vault-wide blindspots: [total count]
Vault-wide absences: [total count]
Most challenged domain: [cluster with most findings]
Strongest domain: [cluster with fewest findings]
agents/_skills/#counterpoint tag and backlink to challenged note