| name | graphrag-knowledge |
| version | 4.15.0 |
| description | プロジェクトの永続的な設計知識 (採用判断/却下案/制約/目的/リスク/運用知識と、それらを貫く横断構造) を vault を単一正本に安全に読み書きする。作業の最上流と一段落で発火する。【読み — 着手前に先に引く (コードやファイルを読む前にこれを起動)】① 「○○を実装/修正/改善/リファクタしたい」「○○がバグってる/動かない/エラー」「○○周りを整理/調査/レビュー/設計したい」と課題や依頼を受け取った直後 (レビュー自体は graphrag-pr-review / graphrag-design-review の担当 — 本 skill はその上流の知識引き)、触る領域の Decision / Risk / Constraint / 運用知識を `ask` で先に引く (1発で網羅、連打しない)。② 「前回の続き」「引き継ぎ」「過去どう判断した」「なぜこの設計に」と経緯を問われた時。③ 「影響範囲」「どこに波及」と影響伝播を辿りたい時。【書き戻し — 一段落で能動的に (ユーザーの「覚えて」を待たない)】④ 実装/修正が一段落した時・commit 直前 (無言のアクショントリガ — 採用判断/却下案/リスク/運用ハマりを書き戻し、決着した focus の Investigation を閉じる)。⑤ 「Xで行く」「Xはやめる」「今後はY」と結論/却下が確定した時、「覚えて/記録して」と指示された時 (詳細は §Proactive Persistence)。 |
GraphRAG Knowledge
A skill that lets agents accumulate knowledge in a vault (Obsidian Markdown) as the single source of truth, enabling thorough decision-making even from vague requests. Defines retrieval procedures, focus continuity, read/write boundaries, mutation procedures, and reporting format.
Overview / How to call
CLI for safely reading and writing a persistent knowledge graph. All verbs go through a single launcher:
node --experimental-strip-types ${CLAUDE_PLUGIN_ROOT}/graphrag/cli.ts <verb> [args]
Hereafter $CLI = the launcher above, $REF = ${CLAUDE_PLUGIN_ROOT}/references.
Verbs fall into 4 categories: read (ask), write (add-* / commit-mutation), index (carve), inspect (inspect). Details in §Recipe / §Headline verbs. Primitives (per-stage fine-grained operations) in §Primitive verbs + $REF/cli-primitives.md.
Graph-backed review (sibling skills)
This skill is the read/write foundation. Three derived skills review changes and proposals at the concept level using the graph as backbone (shared method: $REF/graph-review-method.md). Goal is controllability ("delegate broadly, but don't cross the guardrails"), not QA. They advise, never hard-reject:
/graphrag-knowledge:graphrag-design-review — pre-implementation design review against graph (knowledge axis)
/graphrag-knowledge:graphrag-pr-review — PR/diff review against graph (crosscut + knowledge axes: boundaries, constraints, rejected options, operational burns, risks, goals), detecting concept deltas in 3 tiers
/graphrag-knowledge:graphrag-review-doc — generate concept-level explanation doc (HTML) for human reviewers
Checkpoint / clear handoff lifecycle (separate from review): /graphrag-knowledge:graphrag-checkpoint flushes the live session to the graph before /compact (A: work-state → active Investigation raw_content + ConversationChunk; B: unpersisted durable knowledge → normal knowledge nodes, wired back via derived_from/led_to), then fires checkpoint-mark --investigation <id> to write a one-shot restore intent into the reserved __checkpoint__ key of ask-state.json. Restore is automatic on /clear only — the clear-restore.mjs SessionStart hook consumes the one-shot intent (60-min expiry, plus a three-tier identity match: declared session_dir → project root → strict cwd) and injects the snapshot. Nothing is injected after compact; run brief --mode resume manually to reach the same Investigation.
Invariants (non-negotiable design boundaries)
- Vault is the single source of truth. Knowledge lives in the vault (frontmatter = canonical, body = human projection). Search, indexing, and writes all read the vault.
graph.json is an indexer output / round-trip verification artifact, NOT the source of truth. Do not hand-edit vault for normal knowledge insertion (commit-mutation / add-* handle lock / OCC / atomic publish / git commit).
- Never let the LLM write raw queries. The LLM touches exactly two surfaces:
- Read: ranked JSON (
ask / brief / search / evidence output) and deterministic JSON (grep / show output).
- Write: typed-add CLI args, or mutation plan JSON (
reason / nodes / edges) validated and applied to the vault by commit-mutation.
Any change that thins this layer or exposes a raw query path to the LLM is a design violation.
- Semantic is non-negotiable. Search ranking combines lexical (exact/partial/word-coverage, normalized to [0,1]) and semantic (cosine, clamped to [0,1]) with equal weight (max 100 each). There is no SILENT lexical fallback (no vector index →
ask hard-errors). The only exception is the explicit ask --lexical-only escape hatch for embedding-endpoint outages — caller-invoked, and the output is loudly marked DEGRADED (retrieval_mode.semantic:false); it never engages on its own.
- Vault round-trips. Frontmatter (YAML) is canonical, body is human projection. The vault import→build round-trip equivalence test is the sole gate for serialization changes.
Anti-patterns (DO NOT)
- DO NOT translate "read/trace the graph" into grep / glob / read. Do not read vault
.md files directly — for conceptual queries use ask; for exact matches (id fragments, code identifiers, body text, type-scoped enumeration) use $CLI grep; to read a node in full (description / raw_content included) use $CLI show <id>. The CLI auto-discovers the vault (§Setup) and hard-errors if not found. Falling back to filesystem grep/cat on vault .md is a design violation — every read need now has a CLI verb.
- DO NOT grep / read
graphrag/*.ts source code. Everything the LLM needs is in this file and $REF/. Do not re-derive types from schema.ts (§Schema quick-ref is enough). Do not re-derive CLI invocation ($CLI <verb> is enough).
- DO NOT edit
vault/ directly. The vault is the source of truth, but write through commit-mutation / add-* only (CLI guarantees lock / OCC / atomic publish / git commit).
- DO NOT create duplicate nodes. Always check existing nodes via
ask before creating. Prefer skip / update / supersede / review over new creation. The write-time duplicate gate (duplicate_check, §Mutation Plan) catches suspects as a last resort, but do not skip the ask pre-check just because the gate exists (sole scoped exception: the checkpoint rescue pass — graphrag-checkpoint §B). To acknowledge a suspect as intentionally distinct, use --dup-ack <id[,id...]>.
- DO NOT ignore the vault the CLI reports writing to. Every write verb prints
[graphrag] vault: <path> (source: <layer>) to stderr and returns vault_dir / vault_dir_source in its JSON — this printed line is the primary wrong-vault tripwire when cwd changes (worktree, subdirectory, different branch checkout). Verify it on the first write; inspect remains available for pre-flight checks. If the vault is unexpected, use --vault <path> or set GRAPHRAG_VAULT_DIR in .graphrag/.env.
- DO NOT
git merge vault files. Git merge cannot detect semantic duplicates, missing lineage, or contradictory edges — it produces a broken vault. Use → judgment packets → for semantic-unit application (§Parallel work, ).
Setup prerequisites (retrieval hard-errors without these)
- Vault directory must exist. Resolution priority (high→low): shell env
GRAPHRAG_VAULT_DIR > local .graphrag/.env (walk-up) > cwd .env > auto-discovered .graphrag/vault (walk-up) > ~/.graphrag/.env. Loading is first-wins, so local config always overrides the home fallback. The walk-up anchors on the closest .graphrag/ directory that has either a .env or a vault/ — a worktree's own .graphrag/vault beats a parent repo's .graphrag/.env. Placing the vault at .graphrag/vault requires zero env configuration; for vaults in external repos, set GRAPHRAG_VAULT_DIR=<absolute-path> in .graphrag/.env. Hard-errors if nothing found.
- Embedding backend. Auto-resolution order when unconfigured: Ollama (
http://localhost:11434/v1) → LM Studio (http://localhost:1234/v1) → bundled in-process embedding (~/.graphrag/embedder, machines that ran $CLI embedder-setup once; multilingual-e5-small, no server/daemon). Server model pinned to nomic-embed-text. Hard-errors if nothing is available — the error names embedder-setup as the easiest fix (pnpm required, ~500MB once, offline afterwards). Never auto-installs from the read path.
- Per-machine global config:
~/.graphrag/.env (lowest priority, fallback only). Put per-machine (not per-vault) values here — typically GRAPHRAG_EMBEDDING_ENDPOINT / GRAPHRAG_EMBEDDING_API_KEY / GRAPHRAG_EMBEDDING_MODEL — so each repo's .graphrag/.env stays vault-only (GRAPHRAG_VAULT_DIR, GRAPHRAG_VAULT_MODE).
- Launcher reads
.env once at startup. All verbs see the same env — no per-verb inconsistency.
- State layout. Tracked config lives at the
.graphrag/ root (vault/, VAULT.md, carving.json, .env, world.json); machine-local/regenerable files live under .graphrag/cache/ (vector indexes, , , / ; legacy root-level files are still read as fallback). is a safe cleanup when no writer is running. : ignore and , never ignore wholesale — full table: §.
Focus continuity and read-only triage
- Context continuity unit is focus / active Investigation, not session. New focus within same session = new context.
- Resume / active-focus check / next-action extraction are read-only triage. Do not start graph updates, vector index updates, or investigation cleanup during triage.
- Triage is not a completion condition. Unless the user only asked for status, report stale blockers and completed next_actions as candidates, then proceed to the main task.
Retrieval ladder and ask cutoff
Start from the minimum step that answers the request; climb this ladder before opening sources.
- Resume / active focus:
$CLI brief --mode resume (read-only triage)
- Typical:
$CLI ask "<question>" — auto-escalation brief→evidence + auto-incrementing --call-number (no manual LLM annotation needed)
- For fine control (e.g. changing neighbors): use primitives (
search / evidence) directly
Read files surfaced by GraphRAG first; broaden only when ask results are insufficient. Do not mix graph-derived facts with speculation. Missing knowledge is a temporary investigation gap, not a new persistent node.
Query discipline (dual-language keywords, --gist)
Search combines lexical + semantic (§Invariants #3), so query vocabulary determines the hit surface.
- Include both natural-language and code-language terms. Knowledge is distilled in natural language (e.g. "duplicate detection") while code uses English identifiers (e.g.
duplicate_check). Using only one narrows the surface. Even in a casual Japanese query, adding 1–2 code terms helps both channels (e.g.: ask "重複ノードを弾く duplicate_check の仕組み").
- Query formula:
<topic/phenomenon in natural language> + <1–2 code identifiers> (+ a node-type word such as Decision / Risk / 制約 when hunting a specific type). Compose one good query from this formula instead of firing several narrow ones.
- Use
--gist "<expected one-liner>" for multi-query. When the question alone is hard to hit, add the expected answer as --gist — it embeds question and gist separately and matches against both.
- Example:
ask "なぜ vault を単一正本にした" --gist "graph.json は索引器の中間表現であって正本ではない"
--graph-rerank on|off (default off; hub-biased net-negative; consider on only for balanced island-structure graphs).
Stacking aliases (giving knowledge nodes alternate names)
Node aliases: string[] is wired to embedding and lexical aliasExact (exact match on alias) — aliasExact is the strongest lexical signal. Add aliases via --aliases "a,b,c" (comma-separated, available on all typed-add verbs) for nodes you want to be easily retrievable. Include both natural-language and code-language terms.
Authority nodes MUST carry their code vocabulary as aliases. When a Decision/OK/Constraint declares an authority ("the authority for X is function/constant Y"), put the authority symbol AND the literals it owns into aliases (e.g. ERROR_STATUSES, zero_bytes). This is not just for retrieval: delta-check uses identifier-shaped aliases as the authority's vocabulary fingerprint — when a commit adds those tokens outside the authority's home files, it flags the second implementation in the act (authority_echoes). Plain lowercase English words (migration) don't work as fingerprints; distinctive identifiers (zero_bytes, decideAutoUnmount, constraint-check) do.
Only OWNED vocabulary belongs in fingerprints. Library / runtime / general API names (execFile, tar.gz, fileType) fire on every legitimate use — field measurement: 8 of 9 echo firings in one month were such false positives, and readers learn to ignore echoes (crying wolf kills the lane). The write path runs a deterministic alias ownership probe at registration (alias already widespread outside the evidence home → alias_probe warning, non-blocking), and stocktake aggregates actual firings as echo_stats for periodic fingerprint stocktake — retire a hot alias via op:update on the owning node's aliases.
Cutoff judgment (reading ask output)
- If auto-escalation reaches
evidence and returns empty, the knowledge truly does not exist. Try one different keyword only. Do not repeat.
repeat_state: excessive (call_number ≥ 3) → stop graph search, switch to code / doc direct reading.
- Match
state_note (e.g. "superseded — check refines reverse for successor") → follow the note, prefer successor/active nodes.
cross_vault_resolved — cross-vault edge targets are resolved inline (title/summary); if that is insufficient, follow the pointer with $CLI ask "<question>" --vault <path>. This is graph-structural pointer traversal, not heuristic search — follow it proactively.
- Full field reference:
$REF/ask-output-guide.md.
Recipe
| Goal | Command |
|---|
| Answer a vague question comprehensively | $CLI ask "<question>" |
| Persist a single Decision | $CLI add-decision --system <s> --slug <slug> --title "..." --summary "..." --evidence file:<s>:<path> [--sets-policy-for <id,...>] [--premise <id,...>] [--from-investigation <id>] [--refines <decision-id>] [--reduces-risk <risk-id,...>] |
| Record a failed attempt | $CLI add-rejected-option --system <s> --slug <slug> --title "<tried approach>" --summary "<failure mode>" --rejected-in-favor-of decision:<s>:<chosen> |
| Record operational knowledge | $CLI add-ok --system <s> --slug <slug> --title "..." --summary "..." --evidence file:<s>:<path> [--premise <id,...>] [--refines <id>] [--reduces-risk <id,...>] |
| Record a risk | $CLI add-risk --system <s> --slug <slug> --title "..." --summary "..." --evidence file:<s>:<path> [--risks-in <id,...>] |
| Record an investigation episode | $CLI add-investigation --system <s> --slug <slug> --title "..." --summary "..." --raw-content "key commits:\n- 2026-MM-DD <hash> <subject>" |
| Record a constraint (invariant) | $CLI add-constraint --system <s> --slug <slug> --title "..." --summary "..." --constrains <id,...> + enforcement choice (required): --enforced-by file:<s>:<path/to/check> (the test/lint/type check that FAILS on violation; also write a comment marker graphrag:enforces constraint:<s>:<slug> inside that file) OR --unenforceable "<why>" (external condition — law/SLA — no check can express). --constrains required ≥1 (target Decision|File|OK). [--premise goal:<s>:<slug>] = debt-shadow: this constraint's premise is that Goal being unsettled ("until X is done, Y cannot be trusted") |
| Record a goal | $CLI add-goal --system <s> --slug <slug> --title "..." --summary "..." [--refines <goal-id>] [--derived-from <id>] [--state planned|active|achieved|abandoned] [--evidence file:<s>:<path>] — for deferred work ("later" / "Step N"), use --state planned + --evidence pointing at the files where the debt lives, so delta-check resurfaces it when a commit touches them |
|
--evidence is required by schema for add-* (Decision/RejectedOption/Risk/OK without source backing get validation-rejected). Provide at least one file:<system>:<path>. Exceptions: add-constraint takes no evidence — requires --constrains <id,...> (target Decision|File|OK, ≥1) plus an enforcement choice (--enforced-by or --unenforceable; system vaults only — a prose-only constraint enforces nothing and decays into a diary entry). add-goal also needs no evidence.
--evidence file:<s>:<path> / --enforced-by file:<s>:<path> auto-create the File node when the path exists on disk (reported as file_auto_created); a nonexistent path is an explicit error.
--system and --slug are validated against ^[a-z0-9][a-z0-9._-]*$.
- All verbs:
[--aliases "a,b,c"] / [--description "..."] / [--dup-ack <id[,id...]>]
Headline verbs (chained, multi-stage in one command)
ask "<q>" — auto-escalation brief→search→evidence + auto-incrementing --call-number (reads vault). Every ask carries area_map (the touched area's registered Component/Layer/Concern) — consult it before deciding where new code lives — and, when the vault holds unguarded Constraints, enforcement_debt (migration rail: relay to the user once per session). --format md returns the same payload as a readable markdown digest (use it instead of piping JSON through jq/python). --lexical-only is the explicit escape hatch for embedding-endpoint outages (keyword-only, output loudly marked DEGRADED — absence of hits is weak evidence there). Delivered nodes may carry evidence_stale (⚠ the evidence file changed after the node was last verified — verify against the file; op:update clears it). Details: $REF/ask-output-guide.md
carve --root <repo> --system <name> — index → concern-hint → policy-suggest → carving-check chain. Post-index, File and Component/Layer candidate summaries are machine templates (summary_provisional). You must read them and rewrite to meaningful summaries, then remove summary_provisional (leaving it causes concern-hint rejection / carving-check ERROR). Concern (crosscut) discovery is driven by LLM conceptual modeling — concern-hint machine candidates (for Concern discovery) are for blind-spot checking only ($REF/conceptual-pass.md §2).
commit-mutation <plan.json> — via vault writer (lock → OCC → vault import → normalize/validate → atomic delta write → vector-index update (non-fatal) → git commit). Failure is all-or-nothing rollback.
add-decision / add-ok / add-risk / add-investigation / add-rejected-option / add-constraint / add-goal — builds plan from args + applies to vault. Use --dup-ack <id[,id...]> to pass duplicate gate suspects.
- Retries are safe (idempotent replay). Re-sending an op:create with identical content (e.g. after a timeout) is absorbed as a successful no-op (
idempotent_replay in the output) — do NOT diagnose "node already exists" after a timeout; that error now only fires when the content actually differs (then use op:update). index_status.ok:false also does NOT mean the write failed — the mutation is committed; the index self-heals on the next ask/mutation.
Primitive verbs (per-stage, fine-grained control)
Headline = multi-stage sugar (quick/typical). Primitive = direct per-stage control. No hierarchy — choose by control granularity. Flag details: $REF/cli-primitives.md.
| verb | role |
|---|
brief | summary response (resume / query mode, reads vault) |
search | ranked neighbor expansion (reads vault) |
evidence | provenance-attached answer packet (reads vault) |
grep | deterministic full-field match across ALL node fields incl. id / type / description / raw_content (enumeration, not ranking — the sanctioned replacement for grepping vault .md). Flags: --regex --types A,B --limit N --case-sensitive |
show | full node content verbatim (every frontmatter field + description + raw_content) + incident edges — the sanctioned replacement for cat-ing vault .md. Missing ids resolve through the tombstone ledger (301 successor / 410 gone) |
index | deterministic indexing (git ls-files + role classification + deps) → graph.json |
vector-index | build vector index (from vault) |
vault-build | graph.json → vault (empty-vault initial build only; wipes & rebuilds. Guarded: refuses if the existing vault holds nodes absent from the source graph, since those non-indexed knowledge nodes would be lost. --force to override) |
vault-import | vault → graph.json (for round-trip verification) |
concern-hint | machine hints for Concerns (embedding proximity clustering). For blind-spot checking after LLM modeling |
edge-suggest-policy | sets_policy_for candidate extraction |
carving-check | carving quality gate |
xref-check | cross-vault ref + VAULT.md parent integrity check (read-only): resolves each vault: edge, reports resolved/tombstoned (deleted per ledger — 301 with successor / 410 without)/broken/orphan/unresolvable + parent status. With --root <repo>, also sweeps the repo's graphrag:see / graphrag:enforces comment markers and verifies each target is alive (broken / tombstoned 301 / superseded) — the periodic full sweep; the diff-scoped variant lives in |
Parallel work and semantic merge (vault branch)
Parallel knowledge graph work is isolated via vault git branches; merging uses per-node/edge semantic analysis, not git's file-level merge (git misses rephrased duplicates, lineage-free Decision collisions, semantically contradictory edges). branch-merge --branch <ref> produces a judgment packet (JSON) from the 3-state diff (fork point / branch / main), read-only. Resolution: LLM reads the packet, composes the merged state as a mutation plan, and applies via commit-mutation to main's vault. Full procedure: $REF/branch-merge.md.
Schema quick-reference
graphrag/schema.ts is canonical. Three presets — the axis is lifecycle × grounding (拠り所), and the enumeration is closed at three (a fourth "mandate/与件" preset was rejected: external givens are written as Source pointers + entity-authored interpretation, see $REF/schema-quickref-principal.md §与件 pattern):
- system (13 node types / 16 edge types, default) — 人工物: knowledge grounded in code you own.
- project (16 / 23,
schema: project) — 企て: a time-bounded initiative; the vault closes with its Goal.
- principal (14 / 20,
schema: principal) — 当事者: the deciding/signing entity (company, subsidiary, standing unit); perpetual, = project minus Task/Milestone. Admission test: is the author/signer/allocator of the knowledge the operating entity itself?
The schema field in the vault's VAULT.md frontmatter decides the preset. Run inspect to check the vault type first, then read only the matching quickref: system → $REF/schema-quickref-system.md, project → $REF/schema-quickref-project.md, principal → $REF/schema-quickref-principal.md. Never read more than one at once. For initial construction of a project/principal vault, see the graphrag-vault-init skill. Judgment criterion: chose from alternatives → Decision; learned from operation → OperationalKnowledge. When unsure, use Decision.
Mutation Plan
{
reason: string, // required — why this mutation
nodes: Array<{ op: "create"|"update"|"delete", id, type?, title?, summary?, description?, raw_content?, updates? }>,
edges: Array<{ op: "create"|"delete", id, type, from, to }>,
duplicate_ack?: string[], // only when acknowledging duplicate gate suspects (existing node ids)
successors?: Array<{ old, new }> // 301: map deleted node ids to their replacements (tombstone ledger)
}
- Passing
null as an updates value deletes that field (e.g. { "state": null } to withdraw state).
- Every node delete is recorded in the vault's tombstone ledger (
.tombstones/YYYY-MM.jsonl, same commit): {id, type, title, deleted_at, reason, successor?, cascaded_edges?} — "did this id die / when / why / what replaced it" stays answerable from the living vault, and cascaded edge tuples are kept as repair material. Deleting and creating the same id in one plan is rejected (no replace semantics); successors maps old→different new ids and is validated (old must be deleted by the plan, new must exist after it). Template: $REF/mutation-templates.md §Delete + replace.
op: "update" refreshes the node's generated_at to now (= "re-verified as of now"; staleness-check converges) unless the plan sets generated_at explicitly.
summary = one-line headline (stays in frontmatter, primary search carrier).
description = distilled prose about the node (appears in vault body ## 説明 with round-trip marker, also enters embedding). Write for every node in principle. Guidelines:
- Aggregate types (especially Concern): not a list of constituents, but what the collection means as a whole — the meaning that emerges only at the aggregate level.
- Judgment types (Decision/Risk/Constraint/RejectedOption/OperationalKnowledge): why it was decided that way.
raw_content = raw primary information (conversation logs, how it was decided, Slack URLs, etc.). Do not discard even for judgment types: low volume, becomes the primary source for tracing "why" later. Subject to §Content hygiene — never verbatim abuse or personal information; sanitize while distilling.
commit-mutation (and typed-add) enforce validateGraph passage (rejects unknown types, disallowed pairs, missing evidence, duplicate ids, state vocabulary violations).
| Goal | Recommended method |
|---|
| Single new Decision/OK/Risk/Investigation/RejectedOption/Goal/Constraint | typed-add (add-*) — no JSON needed |
| New Concern/Layer/Component, Update, Delete, policy reversal | commit-mutation <plan.json> — templates: $REF/mutation-templates.md |
Write-time duplicate gate (duplicate_check)
The vault writer gates op:create (embedding cosine ≥ 0.92 same-type, document-space, plus lexical exact title/alias match). Suspects are returned as {new_id, existing_id, similarity, basis: embedding|lexical, existing: {type,title,summary,state}, next_step}; acknowledge intentionally-distinct ones via --dup-ack <id,...> / duplicate_ack. Advisory extras (never reject): cross_type_suspects (Decision↔OK, Risk↔Constraint), index_stale + reason when the vector index lags vault HEAD, and precheck: {recent_ask_hits, note} when creating knowledge nodes with an empty ask-trail. Mechanism details: $REF/mutation-templates.md.
What to persist / When the LLM proactively writes
Only persist conclusions, constraints, risks, and operational knowledge that will be reused across sessions. Confine in-progress trial-and-error to raw_content.
Proactive Persistence
Do not wait for the user to say "remember this." Write via add-* immediately when the following language markers or actions appear. Always run duplicate check (ask / brief) first (§Anti-patterns).
- Implementation/fix/improvement/refactor reached a milestone (action trigger): just before committing or after finishing changes and reporting to user. Write back the underlying adoption decision, rejected alternatives, risks encountered, operational gotchas. This is a silent action — actively watch for it (easier to miss than verbal markers).
→
add-decision / add-rejected-option / add-risk / add-ok (whichever applies)
→ Additionally: if this focus's active Investigation has reached its conclusion, include an op:update on that Investigation (state: closed) in the same plan. There is no other natural trigger to close it — the write-back boundary itself is the closing moment.
- User states a conclusion: "we'll go with X", "X is not an option", "X doesn't work", "from now on, Y"
→
add-decision / add-rejected-option / add-risk (whichever applies)
- LLM itself states a conclusion: "we should X", "avoid Y" in future tense
→ same as above
- A substantive failed attempt (= RejectedOption + optionally Investigation):
"tried approach X, hit constraint Y, had to retreat." Capture this especially — the #1 type that leaves no trace outside source code; not writing it means repeating the same failure.
→
add-rejected-option --title "<tried approach>" --summary "<failure mode>" --rejected-in-favor-of <chosen Decision id>
→ if the story spans multiple events, also add-investigation and connect via led_to
- A bug's root cause was a violated invariant (action trigger — fires when you write the regression test):
the regression test you just wrote IS the invariant's mechanical enforcer — register both in one move.
Invariants have no natural write trigger of their own ("ownership is undecided" never happens as an event),
so this moment — a boundary got crossed and you just pinned it with a test — is the one reliable chance to
turn the invariant into a registered, machine-guarded Constraint instead of a diary entry about the fix.
→
add-constraint --title "<invariant>" --summary "<what must hold>" --constrains <violated-target-id,...> --enforced-by file:<s>:<path/to/regression.test> + write the graphrag:enforces constraint:<s>:<slug> marker into the test
- You deferred work (action trigger — fires the moment you write "later"):
the words "later" / "in a separate step" / "Step 2" / "別段階で" / "あとで" — in a commit message, a code
comment, or your own report — ARE deferred work being created. This is the single most reliably lost knowledge
type: the session that says "later" is the one that just decided NOT to do it, so motivation to register is at
its minimum, and a promise living only in a commit message dies with the session ("あとでやる、って記憶を毎回失う").
→
→ wires the Goal to the files where the debt lives (documented_by), so resurfaces it
the moment any commit touches that place; lists open Goals at session start;
catches the ones that sat too long. When the work gets done or dies, update state (achieved / abandoned) at the
write-back boundary.
→ Fallback when the debt has no existing home (e.g. a reservation for a NEW capability): wire to
the extension seed file — the file you would inevitably touch first when starting the work — or, if truly
placeless, register without evidence and note that it rides only the resume/stocktake lanes (2 of 3). A
placeless Goal is legitimate; an unwired Goal that HAD a findable home is a lost delta-check lane.
→ ("until X is done, Y misbehaves"), also register the
debt-shadow: .
The Goal reaches whoever touches the WORK's home; the shadow Constraint reaches whoever touches the side that
currently lies — different audiences, both needed. stocktake flags the shadow () once the Goal settles.
Vault isolation guard
Write policy for external vaults is governed by GRAPHRAG_VAULT_MODE (§Setup). When unset, the CLI hard-errors and forces user confirmation.
Write output suggestions
Post-write suggestions (binding/relations/led_to/premise_candidates/binding_debt) are all suggest-only and non-fatal. Judge and confirm, or decline with a reason. Edges are never auto-wired. Binding candidates carry apply.plan_fragment — paste it into a commit-mutation plan's edges to confirm in one step. Details: $REF/mutation-templates.md §suggestions.
What NOT to persist
- Session-local exploratory notes
- Trivial scratch (variable renames, temporary lint fixes, etc.)
- Ad-hoc observations not stated in future tense
Content hygiene (all node types, all fields — hard rule)
The vault is a durable artifact that outlives the session and travels with the repo — anything written here may be read by future collaborators and injected into future contexts. This rule applies to every field of every node type (title / summary / description / raw_content); the highest-risk paths are verbatim conversation capture into ConversationChunk and Investigation raw_content.
- Never record abusive language, insults, or disparagement of people verbatim — even when quoting the user or a conversation log, and even inside
raw_content. Venting is not knowledge. Extract the substance and drop the wrapper: the constraint, the decision, or the cause of the frustration survives; the phrasing does not. E.g. an expletive-laden complaint about a library becomes "library X fails at ~ (user priority signal: strong frustration)".
- Never record personal information beyond what the work itself needs: no home/postal addresses, phone numbers, private email addresses, credentials/tokens/secrets, health or private-life details. Refer to people by role, or by an identity already public in the repo (e.g. Git author name), and only when the knowledge genuinely requires attribution.
- "Do not discard raw information" (§Mutation Plan,
raw_content) means do not discard substance — it is not a license for verbatim transcripts. Sanitizing while distilling is part of writing, not a fidelity loss; if a quote must be kept for meaning, keep the sanitized paraphrase and note that it is paraphrased.
- No opt-out exists today. If the user explicitly asks to record such content verbatim, say the vault has no unsafe/verbatim mode and write the sanitized form instead (a per-vault opt-in mode is a possible future extension, deliberately not implemented).
Topology Gap Review
When a bug or oversight is found, ask: "could this have been prevented if the graph had the right structure?" If yes, add the missing Concern/Component + edges via commit-mutation (topology cultivation). Details: $REF/topology-gap-review.md.
Drift Reconciliation (incidentally noticed divergence)
Only applies when you've retrieved the relevant node via GraphRAG AND read the corresponding code in the same context. Even if you notice "graph description ≠ current source," do NOT auto-fix (high false-positive risk without full investigation; wrong update/delete destroys information). Present to user in structured format ([u]pdate / [d]elete / [s]kip / [i]nvestigate — 4 choices) and apply via commit-mutation after their ruling. Format details: $REF/drift-reconciliation.md. Systematic drift audits are separate — only on explicit user request.
Reporting format (user-facing)
Report graph changes in natural language, in the conversation language (what knowledge changed / what relationships were connected / why it was kept / verification status). Do not dump node IDs / edge IDs / raw commit-mutation JSON output to the user — demote IDs to parenthetical references. Reports must connect to "so, what do we do next?"
Reference links
$REF/cli-primitives.md: full flag reference for all primitives
$REF/mutation-templates.md: plan templates for Concern / Layer / Component / Update / Delete / policy reversal + suggestions details
$REF/schema-quickref-system.md: system preset (13+16) / allowed pairs / state vocabulary / enforcement contract / policy-reversal recipe
$REF/schema-quickref-project.md: project preset (16+23) / allowed pairs / state vocabulary / cross-vault ref / judgment criteria
$REF/schema-quickref-principal.md: principal preset (14+20) / 与件 (mandate) pattern / excepts / admission test / bootstrap consumption events
$REF/ask-output-guide.md: detailed ask output field guide (match_confidence / repeat_state / world_hints / standout)
$REF/topology-gap-review.md: graph structure self-reflection protocol on bug discovery
$REF/branch-merge.md: semantic merge procedure for vault branches
$REF/drift-reconciliation.md: drift presentation format and post-ruling application
$REF/indexing-and-carving.md: must read for initial indexing and conceptual pass
$REF/carving-rationale.md: core value of the 13 node types + edge grammar, RejectedOption as first-class, Layer≠Concern≠Component
$REF/interpretation-guidance.md: universal guidance for File interpretation summaries (primary lever for retrieval quality)
$REF/conceptual-pass.md: conceptual interpretation pass procedure
$REF/carving-rules.md: carving quality guards (no sequential slugs / completeness / duplicate detection / automated verification commands)
$REF/graph-review-method.md: graph-informed review method (used by the pr-review / design-review / review-doc skills)