skill-sources/reflect/SKILL.md
Find connections between notes and update MOCs. Requires semantic judgment to identify genuine relationships. Use after /reduce creates notes, when exploring connections, or when a topic needs synthesis. Triggers on "/reflect", "/reflect [note]", "find connections", "update MOCs", "connect these notes".
npx skillsauth add agenticnotetaking/arscontexta reflectInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Read these files to configure domain-specific behavior:
ops/derivation-manifest.md — vocabulary mapping, platform hints
vocabulary.notes for the notes folder namevocabulary.note / vocabulary.note_plural for note type referencesvocabulary.reflect for the process verb in outputvocabulary.topic_map / vocabulary.topic_map_plural for MOC referencesvocabulary.cmd_reweave for the next-phase suggestionvocabulary.inbox for the inbox folder nameops/config.yaml — processing depth, pipeline chaining
processing.depth: deep | standard | quickprocessing.chaining: manual | suggested | automaticIf these files don't exist, use universal defaults.
Processing depth adaptation:
| Depth | Connection Behavior | |-------|-------------------| | deep | Full dual discovery (MOC + semantic search). Evaluate every candidate. Multiple passes. Synthesis opportunity detection. Bidirectional link evaluation for all connections. | | standard | Dual discovery with top 5-10 candidates. Standard evaluation. Bidirectional check for strong connections only. | | quick | Single pass — either MOC or semantic search. Accept obvious connections only. Skip synthesis detection. |
Target: $ARGUMENTS
Parse immediately:
[[note name]] or note name: find connections for that {vocabulary.note}--handoff: output RALPH HANDOFF block at endExecute these steps:
--handoff in target: output RALPH HANDOFF blockSTART NOW. Reference below explains methodology — use to guide, not as output.
Find connections, weave the knowledge graph, update {vocabulary.topic_map_plural}. This is the forward-connection phase of the processing pipeline.
The network IS the knowledge.
Individual {vocabulary.note_plural} are less valuable than their relationships. A {vocabulary.note} with fifteen incoming links is an intersection of fifteen lines of thought. Connections create compound value as the vault grows.
This is not keyword matching. This is semantic judgment — understanding what {vocabulary.note_plural} MEAN to determine how they relate. A {vocabulary.note} about "friction in systems" might deeply connect to "verification approaches" even though they share no words. You are building a traversable knowledge graph, not tagging documents.
Quality over speed. Explicit over vague.
Every connection must pass the articulation test: can you say WHY these {vocabulary.note_plural} connect? "Related" is not a relationship. "Extends X by adding Y" or "contradicts X because Z" is a relationship.
Bad connections pollute the graph. They create noise that makes real connections harder to find. When uncertain, do not connect.
Check for recent additions:
Focus on connecting a specific {vocabulary.note}:
Synthesize an area:
External loop mode for /ralph:
Before using semantic search, verify the index is current. This is self-healing: if {vocabulary.note_plural} were created outside the pipeline (manual edits, other skills), reflect catches the drift before searching.
mcp__qmd__status to get the indexed document count for the target collectionLOCKDIR="ops/queue/.locks/qmd.lock"
while ! mkdir "$LOCKDIR" 2>/dev/null; do sleep 2; done
qmd_count=$(qmd status 2>/dev/null | grep -A2 '{vocabulary.notes_collection}' | grep 'documents' | grep -oE '[0-9]+' | head -1)
rm -rf "$LOCKDIR"
file_count=$(ls -1 {vocabulary.notes}/*.md 2>/dev/null | wc -l | tr -d ' ')
qmd update && qmd embed
Run this check before proceeding. If stale, sync and continue. If current, proceed immediately.
Before searching for connections, deeply understand the source material.
For each {vocabulary.note} you are connecting:
What you are looking for:
If a task file exists (pipeline execution): read the task file to see what the extraction phase discovered. The reduce notes, semantic neighbor field, and classification provide critical context about why this {vocabulary.note} was extracted and what it relates to.
Use dual discovery: {vocabulary.topic_map} exploration AND semantic search in parallel. These are complementary, not sequential.
Capture discovery trace as you go. Note which {vocabulary.topic_map_plural} you read, which queries you ran (with scores), which searches you tried. This becomes the Discovery Trace section in output — proving methodology was followed, not reconstructed after the fact.
Primary discovery (run in parallel):
Path 1: {vocabulary.topic_map} Exploration — curated navigation
If you know the topic (check the {vocabulary.note}'s Topics footer), start with the {vocabulary.topic_map}:
{vocabulary.topic_map_plural} tell you what thinking exists and how it is organized. Someone already decided what matters for this topic.
Path 2: Semantic Search — find what {vocabulary.topic_map_plural} might miss
Three-tier fallback for semantic search:
Tier 1 — MCP tools (preferred): Use mcp__qmd__deep_search (hybrid search with expansion + reranking):
Tier 2 — bash qmd with lock serialization: If MCP tools fail or are unavailable:
LOCKDIR="ops/queue/.locks/qmd.lock"
while ! mkdir "$LOCKDIR" 2>/dev/null; do sleep 2; done
qmd query "[note's core concepts]" --collection {vocabulary.notes_collection} --limit 15 2>/dev/null
rm -rf "$LOCKDIR"
The lock prevents multiple parallel workers from loading large models simultaneously.
Tier 3 — grep only: If both MCP and bash fail, log "qmd unavailable, grep-only discovery" and rely on {vocabulary.topic_map} + keyword search only. This degrades quality but does not block work.
Evaluate results by relevance — read any result where title or snippet suggests genuine connection. Semantic search finds {vocabulary.note_plural} that share MEANING even when vocabulary differs. A {vocabulary.note} about "iteration cycles" might connect to "learning from friction" despite sharing no words.
Why both paths:
{vocabulary.topic_map} = what is already curated as relevant semantic search = neighbors that have not been curated yet
Using only search misses curated structure. Using only {vocabulary.topic_map} misses semantic neighbors outside the topic. Both together catch what either alone would miss.
Secondary discovery (after primary):
Step 3: Keyword Search
For specific terms and exact matches:
grep -r "term" {vocabulary.notes}/ --include="*.md"
Use grep when:
Choosing between semantic and keyword:
| Situation | Better Tool | Why | |-----------|-------------|-----| | Exploring unfamiliar territory | semantic | vocabulary might not match meaning | | Finding synonyms or related framings | semantic | same concept, different words | | Known terminology | keyword | exact match, no ambiguity | | Verifying coverage | keyword | ensures nothing missed | | Cross-domain connections | semantic | concepts bridge domains, words do not | | Specific phrase lookup | keyword | faster, more precise |
Step 4: Description Scan
Use ripgrep to scan {vocabulary.note} descriptions for edge cases:
Flag candidates with a reason (not just "related").
Step 5: Link Following
From promising candidates, follow their existing links:
This is graph traversal. You are exploring the neighborhood.
For each candidate connection, apply the articulation test.
The Articulation Test:
Complete this sentence:
[[note A]] connects to [[note B]] because [specific reason]
If you cannot fill in [specific reason] with something substantive, the connection fails.
Valid Relationship Types:
| Relationship | Signal | Example | |-------------|--------|---------| | extends | adds dimension | "extends [[X]] by adding temporal aspect" | | grounds | provides foundation | "this works because [[Y]] establishes..." | | contradicts | creates tension | "conflicts with [[Z]] because..." | | exemplifies | concrete instance | "demonstrates [[W]] in practice" | | synthesizes | combines insights | "emerges from combining [[A]] and [[B]]" | | enables | unlocks possibility | "makes [[C]] actionable by providing..." |
Reject if:
Agent Traversal Check:
Ask: "If an agent follows this link, what do they gain?"
| Agent Benefit | Keep Link | |---------------|-----------| | Provides reasoning foundation (why something works) | YES | | Offers implementation pattern (how to do it) | YES | | Surfaces tension to consider (trade-off awareness) | YES | | Gives concrete example (grounds abstraction) | YES | | Just "related topic" with no decision value | NO |
The vault is built for agent traversal. Every connection should help an agent DECIDE or UNDERSTAND something. Connections that exist only because they feel "interesting" without operational value are noise.
Synthesis Opportunity Detection:
While evaluating connections, watch for synthesis opportunities — two or more {vocabulary.note_plural} that together imply a higher-order claim not yet captured.
Signs of a synthesis opportunity:
When you detect a synthesis opportunity:
Connections live in the prose, not just footers.
Inline Links as Prose:
The wiki link IS the argument. The title works as prose when linked.
Good patterns:
Since [[other note]], the question becomes how to structure that memory for retrieval.
The insight that [[throughput matters more than accumulation]] suggests curation, not creation, is the real work.
This works because [[good systems learn from friction]] — each iteration improves the next.
Bad patterns:
This relates to [[other note]].
See also [[throughput matters more than accumulation]].
As discussed in [[good systems learn from friction]], systems improve.
If you catch yourself writing "this relates to" or "see also", STOP. Restructure so the claim does the work.
Where to add links:
Relevant Notes Format:
relevant_notes:
- "[[note title]] — extends this by adding the temporal dimension"
- "[[another note]] — provides the mechanism this claim depends on"
Context phrases use standard relationship vocabulary: extends, grounds, contradicts, exemplifies, synthesizes, enables.
Bidirectional Consideration:
When adding [[A]] to [[B]], ask: should [[B]] also link to [[A]]?
Not always. Relationships are not always symmetric:
Add the reverse link only if following that path would be useful for agent traversal.
Reweave Task Filtering (when adding bidirectional links):
When you edit an older {vocabulary.note} to add a reverse link, you MAY flag it for full reconsideration via reweave. But SKIP reweave flagging if ANY of these apply:
| Skip Condition | Rationale |
|----------------|-----------|
| Note has >5 incoming links | Already a hub — one more link does not warrant full reconsideration |
| Note has type: tension in YAML | Structural framework, not content that evolves |
| Note was reweaved in current batch | Do not re-reweave what was just reweaved |
| Note is a {vocabulary.topic_map} | {vocabulary.topic_map_plural} are navigation, not claims to reconsider |
Check incoming links:
grep -r '\[\[note name\]\]' {vocabulary.notes}/*.md | wc -l
If >= 5, skip reweave flagging.
{vocabulary.topic_map_plural} are synthesis hubs, not just indexes.
When to update a {vocabulary.topic_map}:
{vocabulary.topic_map} Size Check:
After updating Core Ideas, count the links:
grep -c '^\- \[\[' "{vocabulary.notes}/[moc-name].md"
If approaching the split threshold (configurable, default ~40): note in output "{vocabulary.topic_map} approaching split threshold (N links)" If exceeding: warn "{vocabulary.topic_map} exceeds recommended size — consider splitting"
Splitting is a human decision (architectural judgment required), but /reflect should surface the signal.
{vocabulary.topic_map} Structure:
# [Topic Name]
[Opening synthesis: Claims about the topic. Not "this {vocabulary.topic_map} collects {vocabulary.note_plural}" but "the core insight is Y because Z." This IS thinking, not meta-description.]
## Core Ideas
- [[claim note]] — what it contributes to understanding
- [[another claim]] — how it fits or challenges existing ideas
## Tensions
- [[claim A]] and [[claim B]] conflict because... [genuine unresolved tension]
## Gaps
- nothing about X aspect yet
- need concrete examples of Y
- missing: comparison with Z approach
---
Agent Notes:
- YYYY-MM-DD: [what was explored]. [the insight or dead end].
Updating Core Ideas:
Add new {vocabulary.note_plural} with context phrase explaining contribution:
- [[new note]] — extends the quality argument by showing how friction teaches you what to check
Order matters. Place {vocabulary.note_plural} where they fit the logical flow, not alphabetically.
Updating Tensions:
If the new {vocabulary.note} creates or resolves tension:
## Tensions
- [[composability]] demands small notes, but [[context limits]] means traversal has overhead. [[new note]] suggests the tradeoff depends on expected traversal depth.
Document genuine conflicts. Tensions are valuable, not bugs.
Updating Gaps:
Remove gaps that are now filled. Add new gaps discovered during reflection.
Agent notes are breadcrumbs for future navigation.
Add agent notes when:
Format:
Agent Notes:
- YYYY-MM-DD: [what was explored]. [the insight or finding].
Good agent notes:
- 2026-02-15: tried connecting via "learning" — too generic. better path: friction -> verification -> quality. the mechanism chain is tighter.
- 2026-02-15: [[claim A]] and [[claim B]] form a tight pair. A sets the standard, B teaches the method.
Bad agent notes:
- 2026-02-15: read the {vocabulary.topic_map} and added some links.
- 2026-02-15: connected [[note A]] to [[note B]].
The test: would this help a future agent navigate more effectively?
For every connection added, can you complete:
[[A]] connects to [[B]] because [specific reason]
If any connection fails this test, remove it.
For every inline link, read the sentence aloud. Does it flow naturally? Would you say this to a friend explaining the idea?
Bad: "this is related to [[note]]" Good: "since [[note]], the implication is..."
For every A -> B link, explicitly decide: should B -> A exist? Document your reasoning if the relationship is asymmetric.
After updating a {vocabulary.topic_map}, read the opening synthesis. Does it still hold? Do new {vocabulary.note_plural} extend or challenge it?
If the synthesis is now wrong or incomplete, update it.
Verify every wiki link target exists. Never create links to non-existent files.
# Check that a link target exists
ls {vocabulary.notes}/"target name.md" 2>/dev/null
Sometimes a {vocabulary.note} genuinely does not connect yet. That is fine.
If a {vocabulary.note} connects to 5+ {vocabulary.note_plural} across different domains, it might be too broad.
Split detection criteria:
How to evaluate:
Ask: "If I link to this {vocabulary.note} from context X, does irrelevant content Y come along?"
If yes, the {vocabulary.note} bundles multiple ideas that should be separate.
Split detection output:
### Split Candidate: [[broad note]]
**Indicators:**
- Connects to 7 {vocabulary.note_plural} across 3 domains
- Makes distinct claims about: (1) capture workflows, (2) synthesis patterns, (3) tool selection
- Linking from [[note A]] would drag in unrelated content about tool selection
**Proposed split:**
- [[capture workflows matter less than synthesis]] — the first claim
- [[tool selection follows from workflow needs]] — the third claim
- Keep original {vocabulary.note} focused on synthesis patterns
**Action:** Flag for human decision, do not auto-split
When NOT to split:
When new content contradicts existing {vocabulary.note_plural}:
If you find {vocabulary.note_plural} with no connections:
After reflecting, report:
## Reflection Complete
### Discovery Trace
**Why this matters:** Shows methodology was followed. Blind delegation hides whether dual discovery happened. Trace enables verification.
**{vocabulary.topic_map} exploration:**
- Read [[moc-name]] — found candidates: [[note A]], [[note B]], [[note C]]
- Followed link from [[note A]] to [[note D]]
**Semantic search:** (via MCP | bash fallback | grep-only)
- query "[core concept from note]" — top hits:
- [[note E]] (0.74) — evaluated: strong match, mechanism overlap
- [[note F]] (0.61) — evaluated: weak, only surface vocabulary
- [[note G]] (0.58) — evaluated: skip, different domain
**Keyword search:**
- grep "specific term" — found [[note H]] (already in {vocabulary.topic_map} candidates)
### Connections Added
**[[source note]]**
- -> [[target]] — [relationship type]: [why]
- <- [[incoming]] — [relationship type]: [why]
- inline: added link to [[note]] in paragraph about X
### {vocabulary.topic_map} Updates
**[[moc-name]]**
- Added [[note]] to Core Ideas — [contribution]
- Updated Tensions: [[A]] vs [[B]] now includes [[C]]
- Removed from Gaps: [what was filled]
- Agent note: [what was learned]
### Synthesis Opportunities
[{vocabulary.note_plural} that could be combined into higher-order insights, with proposed claim]
### Flagged for Attention
- [[orphan note]] — could not find connections
- [[broad note]] — might benefit from splitting
- Tension between [[X]] and [[Y]] needs resolution
Successful reflection:
The test: if someone follows the links you added, do they find genuinely useful context? Does the path illuminate understanding?
Never:
Always:
This skill is about building a knowledge graph that compounds in value. Every connection you add is a traversal path that future thinking can follow. Every connection you do not add keeps the graph clean.
Quality beats quantity. One genuine connection is worth more than ten vague ones.
The graph is not just storage. It is an external thinking structure. Build it with care.
When invoked with --handoff, output this structured format at the END of the session. This enables external loops (/ralph) to parse results and update the task queue.
Detection: Check if $ARGUMENTS contains --handoff. If yes, append this block after completing normal workflow.
Handoff format:
=== RALPH HANDOFF: {vocabulary.reflect} ===
Target: [[note name]]
Work Done:
- Discovery: {vocabulary.topic_map} [[moc-name]], query "[query]" (MCP|bash|grep-only), grep "[term]"
- Connections added: N (articulation test: PASS)
- {vocabulary.topic_map} updates: [[moc-name]] Core Ideas section
- Synthesis opportunities: [count or NONE]
Files Modified:
- {vocabulary.notes}/[note name].md (inline links added)
- {vocabulary.notes}/[moc-name].md (Core Ideas updated)
- [task file path] ({vocabulary.reflect} section)
Learnings:
- [Friction]: [description] | NONE
- [Surprise]: [description] | NONE
- [Methodology]: [description] | NONE
- [Process gap]: [description] | NONE
Queue Updates:
- Advance phase: {vocabulary.reflect} -> {vocabulary.reweave}
- Reweave candidates (if any pass filter): [[note]] | NONE (filtered: hub/tension/recent)
=== END HANDOFF ===
When running in handoff mode via /ralph, the prompt includes the task file path. After completing the workflow, update the ## {vocabulary.reflect} section of that task file with:
Critical: The handoff block is OUTPUT, not a replacement for the workflow. Do the full reflect workflow first, update task file, then format results as handoff.
When running interactively (NOT via /ralph), YOU must advance the phase in the queue. /ralph handles this automatically, but interactive sessions do not.
After completing the workflow, advance the phase:
# get timestamp
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# advance phase (current_phase -> next, append to completed_phases)
jq '(.tasks[] | select(.id=="TASK_ID")).current_phase = "{vocabulary.reweave}" |
(.tasks[] | select(.id=="TASK_ID")).completed_phases += ["{vocabulary.reflect}"]' \
ops/queue/queue.json > tmp.json && mv tmp.json ops/queue/queue.json
The handoff block's "Queue Updates" section is not just output — it is your own todo list when running interactively.
After connection finding completes, output the next step based on ops/config.yaml pipeline.chaining mode:
current_phase: "{vocabulary.reweave}"The chaining output uses domain-native command names from the derivation manifest.
tools
Apply plugin knowledge base updates to an existing generated system. Consults the Ars Contexta research graph for methodology improvements, proposes skill upgrades with research justification. Never auto-implements. Triggers on "/upgrade", "upgrade skills", "check for improvements", "update methodology".
documentation
Interactive walkthrough for new users. Learn by doing — each step creates real content in your vault. Three tracks (researcher, manager, personal) with a universal learning arc. Triggers on "/tutorial", "walk me through", "how do I use this".
testing
Scaffold a complete knowledge system. Detects platform, conducts conversation, derives configuration, generates everything. Validates against 15 kernel primitives. Triggers on "/setup", "/setup --advanced", "set up my knowledge system", "create my vault".
testing
Re-derive your knowledge system from first principles when structural drift accumulates. Analyzes dimension incoherence, vocabulary mismatch, boundary dissolution, and template divergence. Preserves all content while restructuring architecture.