| name | siyuan-second-memory |
| description | Use SiYuan Note as a personal second memory and Knowledge Graph. Triggered when the user wants to remember, recall, link, organize, or reason over personal knowledge — including saving insights, creating concept maps, building topic clusters, logging decisions, and retrieving past context. This skill enforces three hard connection rules: every new document must link to at least one existing document (Mandatory Link Prompt), every outgoing link must create a matching backlink on the target (Backlink Enforcement), and orphan documents are tracked in a weekly review queue. Use it when the user says: 'remember this', 'save this idea', 'what do I know about X', 'link this to Y', 'build a concept map', 'add to my second brain', 'log this decision', 'what have I noted about Z', 'review my notes'. |
| skillType | cli |
SiYuan Second Memory — Knowledge Graph Protocol v2
This skill turns SiYuan Note into a structured personal Knowledge Graph (KG):
every node is a document, every link is a bidirectional SiYuan block reference,
and every document lives in a well-defined taxonomy path.
Three hard rules enforce connectivity — no exceptions:
- Mandatory Link Prompt — every new document must have ≥1 outgoing link before it is considered saved
- Backlink Enforcement — every outgoing link A→B must immediately create a matching backlink B→A
- Orphan Queue — any document that cannot be linked at creation time is flagged in
_Index/orphans for weekly review
1. Taxonomy (Notebook Structure)
All knowledge lives under a single notebook named KG.
KG/
├── Concepts/ # Atomic ideas, definitions, mental models
├── Projects/ # Ongoing work, goals, deliverables
├── People/ # Individuals, relationships, contact context
├── Decisions/ # Choices made, rationale, outcomes
├── Insights/ # Observations, patterns, "aha" moments
├── References/ # Articles, papers, books, external sources
├── Logs/ # Time-stamped event logs, meeting notes, journal
└── _Index/ # Auto-maintained index docs (never edit manually)
├── orphans # Docs with zero confirmed backlinks — review weekly
├── all-tags # Master tag registry
├── recent-decisions
└── cluster-{topic}
Rules:
- One document = one atomic concept, person, project, decision, etc.
- Document titles:
lowercase-with-dashes (e.g., gradient-descent, project-apex)
- Every document must declare Type, Tags, and Link-Status in its opening block
- All cross-references use SiYuan block references
((block-id "Title")) — never plain text
2. The Three Connection Rules
Rule 1 — Mandatory Link Prompt
Trigger: immediately after writing a new document's content, before marking it done.
Protocol:
search "<title keywords>" --mode keyword # attempt 1
search "<main concept>" --mode keyword # attempt 2 (broader)
→ Choose ≥1 link target from results
IF zero candidates found after both attempts:
→ Add doc to _Index/orphans (see Rule 3)
→ Set Link-Status: orphan in the doc metadata
→ Do NOT leave it silently unlinked — silence is not acceptable
Candidate evaluation — link if ANY of these are true:
| Condition | Link type |
|---|
| Same domain / topic | — related concept |
| One is sub-topic of the other | — parent concept / — sub-topic of |
| One was the context for the other | — observed in / — motivated by |
| One contradicts the other | — contradicts |
| One is evidence for the other | — supporting evidence from |
| Same project or person | — part of project / — involves |
Minimum outgoing links per doc type:
| Doc type | Min links | Suggested targets |
|---|
| Concept | 1 | Parent or related concept |
| Insight | 2 | Source context (Project/Log) + parent concept |
| Decision | 2 | Project it affects + concept it relates to |
| Project | 1 | Key concepts it uses |
| Person | 1 | Project or context where known |
| Reference | 1 | Concept it supports or introduces |
| Log | 1 | Project or topic it belongs to |
Rule 2 — Backlink Enforcement
Every outgoing link A→B must be immediately followed by a backlink on B pointing back to A.
A one-way link is a broken edge. This rule is never skipped.
Protocol for each link created:
Step 1 → info <docB-id> --raw # get block IDs of target doc
Step 2 → identify the ## Links block ID in docB
Step 3 → block-update <links-block-id> # append ← backlink entry
Backlink entry format (use ← to distinguish from → outgoing):
- ← ((docA-block-id "Doc A Title")) — {inverted reason}
Direction inversion examples:
| Outgoing link (A→B) | Backlink on B (←A) |
|---|
— builds on this concept | ← extended by |
— motivated this decision | ← decision motivated by this |
— observed in this project | ← contains insight |
— contradicts this | ← contradicted by |
— supporting evidence from | ← supported by |
— sub-topic of | ← has sub-topic |
If docB has no ## Links section yet, append the full section:
node scripts/content.js <docB-id>
node scripts/block-update.js <last-block-id> \
--content "## Links\n\n- ← ((docA-id \"Doc A\")) — {inverted reason}"
Rule 3 — Orphan Queue & Weekly Review
An orphan is any document with Link-Status: orphan — it was saved but no link candidates were found at creation time.
Orphan entry format in _Index/orphans:
- ((doc-block-id "Title")) — added {YYYY-MM-DD} — {reason no link found}
Weekly Review Protocol (say "review my orphan notes" to trigger):
Step 1 → content <_Index/orphans> # list all orphans
Step 2 → for each orphan:
search "<title>" --mode semantic # semantic attempt
search "<summary concept>" --mode keyword # keyword attempt
Step 3 → if candidates found:
apply Rule 1 + Rule 2
update doc: Link-Status: linked
remove from _Index/orphans, add to Resolution Log
Step 4 → if still no match:
leave in queue, update the date note
consider: should this doc be split? retitled?
3. Core Workflows
3a. Save New Knowledge ← most common
Step 1 → exists --title check for duplicates
Step 2 → create create under correct taxonomy path
Step 3 → update write content (Section 4 template)
Step 4 → search ×2 [RULE 1] find ≥1 link candidate
↓ candidates found ↓ no candidates
Step 5a → block-update (new doc) Step 5b → block-update (_Index/orphans)
add → outgoing links add orphan entry
info --raw (each target) update metadata:
block-update (each target) [RULE 2] Link-Status: orphan
add ← backlinks
update metadata:
Link-Status: linked
Step 6 → tags add domain + type + link-status tags
Step 7 → protect if Decision or _Index doc
3b. Recall / Retrieve
Step 1 → search <query> --mode keyword
Step 2 → content <top result doc-ids>
Step 3 → follow ← backlinks to surface connected context
Step 4 → synthesize: doc titles + key extracts + connected nodes
3c. Link Two Existing Nodes
Step 1 → info <docA-id> --raw
Step 2 → info <docB-id> --raw
Step 3 → block-update <docA links-block> add → link to B
Step 4 → block-update <docB links-block> add ← backlink to A [RULE 2]
Step 5 → if either doc was in _Index/orphans:
remove from queue, update Link-Status: linked
3d. Update Existing Knowledge
Step 1 → search → content find and read the doc
Step 2 → block-update update only the changed block
Step 3 → append Changelog entry {date}: {what changed}
Step 4 → if new content implies new links → apply Rule 1+2
3e. Build a Topic Cluster
Step 1 → search <topic> --mode hybrid find all member docs
Step 2 → create _Index/cluster-{topic}
Step 3 → update cluster index write member list with block refs
Step 4 → block-update each member add ← backlink to cluster index
Step 5 → protect cluster index doc
3f. Weekly Review (orphan resolution)
Step 1 → content <_Index/orphans>
Step 2 → for each orphan: search ×2 (keyword + semantic)
Step 3 → link resolved orphans (Rule 1+2), remove from queue
Step 4 → report: N resolved, M still pending
4. Document Format (Markdown Template)
# {Title}
**Type:** {Concept | Project | Person | Decision | Insight | Reference | Log}
**Tags:** #{tag1} #{tag2} #{tag3}
**Created:** {YYYY-MM-DD}
**Updated:** {YYYY-MM-DD}
**Link-Status:** {linked | orphan}
---
## Summary
{One to three sentences. What is this? Why does it matter?}
## Body
{Main content — explanations, arguments, evidence, data, quotes.}
## Key Points
- {Concise bullet. One idea per bullet.}
## Links
- → ((block-id "Related Doc")) — {reason for link}
- ← ((block-id "Doc That Links Here")) — {inverted reason}
## Open Questions
- {Unresolved question or uncertainty}
## Changelog
- {YYYY-MM-DD}: Created · Link-Status: {linked|orphan}
- {YYYY-MM-DD}: {What changed}
New fields vs v1:
Link-Status in metadata (linked / orphan)
← prefix on backlink entries in ## Links
- Changelog tracks link-status changes
5. Tagging Conventions
| Rule | Example |
|---|
| Lowercase, hyphens, no spaces | #machine-learning, #project-apex |
| Max 5 tags per document | — |
| At least 1 domain tag | #iot, #finance, #ai, #health |
| At least 1 type tag | #concept, #decision, #insight, #log |
| 1 status tag | #active, #archived, #draft |
| 1 link-status tag | #linked or #orphan |
Update _Index/all-tags whenever a new tag appears for the first time.
6. Decision Log Format
# Decision: {Short Title}
**Type:** Decision
**Tags:** #decision #{domain} #{project}
**Status:** #decided | #reconsidering | #reversed
**Date:** {YYYY-MM-DD}
**Link-Status:** linked
---
## Context
{What situation prompted this decision?}
## Options Considered
| Option | Pros | Cons |
|--------|------|------|
| {A} | | |
| {B} | | |
## Choice
**Selected:** {Option name}
**Rationale:** {Why this option won.}
## Links
- → ((block-id "Project")) — decision affects this project
- → ((block-id "Concept")) — relates to this concept
- ← ((block-id "Insight")) — insight that informed this decision
## Outcome
{Fill in later: what actually happened?}
Decisions require minimum 2 outgoing links and must be protected immediately after creation.
7. _Index/orphans Document Format
# Index: Orphans
**Type:** Index
**Updated:** {YYYY-MM-DD}
---
## Pending Review
- ((block-id "Doc Title")) — added {YYYY-MM-DD} — {why no link found}
## Resolution Log
- {YYYY-MM-DD}: ((block-id "Doc Title")) → linked to ((block-id "Target")) — {reason}
8. Search Strategy
| Goal | Command | When |
|---|
| Known title | search <title> --mode legacy | Exact lookup |
| Concept recall | search <topic> --mode keyword | Default for Rule 1 attempt 1+2 |
| No keyword match | search <topic> --mode semantic | Orphan review |
| Broad sweep | search <topic> --mode hybrid | Cluster building |
| Check existence | exists --title <title> | Always before create |
Rule 1 requires two keyword searches before declaring orphan. Semantic search is reserved for orphan review (slower, requires QDRANT + OLLAMA).
9. Quality Checks
Run after any batch write session:
| Check | How | Pass condition |
|---|
| No silent orphans | content <_Index/orphans> | Every unlinked doc explicitly listed |
| Backlinks complete | Spot-check 3 random docs | Every → has a ← on target |
| Tags consistent | content <_Index/all-tags> | No variant spellings |
| Decisions protected | info <decision-docId> | Protect attribute present |
| Link-Status accurate | Search #orphan | Count matches _Index/orphans list |
10. Script Reference
node scripts/notebooks.js
node scripts/exists.js --title "doc-title"
node scripts/create.js "doc-title" --path "/KG/{Folder}/doc-title"
node scripts/update.js <docId> --content "$(cat doc.md)"
node scripts/search.js "title keywords" --mode keyword
node scripts/search.js "main concept" --mode keyword
node scripts/info.js <targetDocId> --raw
node scripts/block-update.js <target-links-blockId> \
--content "- ← ((newDoc-blockId \"New Doc Title\")) — {inverted reason}"
node scripts/info.js <_Index/orphans-docId> --raw
node scripts/block-update.js <orphans-list-blockId> \
--content "- ((newDoc-blockId \"Title\")) — added {date} — {reason}"
node scripts/tags.js <blockId> --add "concept,ai,active,linked"
node scripts/protect.js <docId>
node scripts/content.js <_Index/orphans-docId>
node scripts/search.js "<orphan title>" --mode semantic
11. Full Example — Save Flow with All Three Rules
User says: "Remember that normalizing inputs speeds up gradient descent — saw this in Project Apex."
# 1. Check duplicates
exists --title "insight-gradient-normalization" → not found
# 2. Create
create "insight-gradient-normalization" --path "/KG/Insights/insight-gradient-normalization"
# 3. Write content (Link-Status: orphan temporarily)
# 4. RULE 1: find candidates
search "gradient descent" --mode keyword → found: gradient-descent (Concepts/)
search "project apex" --mode keyword → found: project-apex (Projects/)
# candidates found → NOT an orphan
# 5a. Add outgoing links to new doc
block-update <insight-links-blockId>:
"- → ((gradient-descent-id)) Gradient Descent — parent concept
- → ((project-apex-id)) Project Apex — observed in this project"
# 5b. RULE 2: backlink on gradient-descent
info <gradient-descent-docId> --raw
block-update <gradient-descent-links-blockId>:
"- ← ((insight-id \"Insight: Gradient Normalization\")) — contains supporting insight"
# 5c. RULE 2: backlink on project-apex
info <project-apex-docId> --raw
block-update <project-apex-links-blockId>:
"- ← ((insight-id \"Insight: Gradient Normalization\")) — insight generated in this project"
# 6. Update Link-Status
block-update <insight-metadata-blockId>: "**Link-Status:** linked"
# 7. Tag
tags <insight-blockId> --add "insight,machine-learning,project-apex,active,linked"
# Result: 3 documents updated · 2 bidirectional edges created · 0 orphans added
Notes
- SiYuan ≥ 3.6.0 and Node.js ≥ 14.0.0 required
- Set
SIYUAN_BASE_URL and SIYUAN_TOKEN before running any script
SIYUAN_DELETE_SAFE_MODE must remain at default — this skill never modifies it
- This is a protocol layer on top of
siyuan-skill base commands
- v2 changes from v1: added
Link-Status field · ← backlink syntax · _Index/orphans · Rule 1/2/3 enforcement in all workflows · minimum link counts per doc type