--- name: wiki-capture description: > Turn the current conversation or finding into a structured permanent wiki note. Use for save/capture/preserve requests; QUICK MODE writes a fast _raw/ note. Supports named-vault routing such as @research save this. This captures current discussion, not external source ingestion. --- # Wiki Capture — Conversation to Wiki Note You are preserving knowledge from the current conversation as a permanent wiki note. The goal is to extract the *substance* — the knowledge itself — not a summary of what was said. **Writing profile:** Before drafting or rewriting natural-language Markdown in any mode, read and apply the `Writing Profile Resolution` section in `llm-wiki/SKILL.md`. Framework schema, provenance, safety, and operation-specific requirements take precedence. `WRITING.md` preferences apply only to newly drafted or rewritten natural-language Markdown; preserve source content and structured records. This skill has three modes: - **Full mode (default)** — classify the content and write a finished, cross-linked wiki page directly into the right category. This is the rest of this document (Steps 1–7). - **Quick mode (`--quick`)** — zero-friction staging: drop findings to `_raw/` in under 60 seconds with no manifest/index/log/QMD writes. Used for mid-session capture and by the session-end Stop hook. See below, then stop — do **not** run the full-mode steps. - **Correction mode (`--correction`)** — capture one atomic correction as derived knowledge while leaving the immutable conversation/source untouched. Use the template below, then update only the derived consumers and tracking links. ## Quick Mode (`--quick`) Trigger when invoked as `/wiki-capture --quick`, by "quick capture" / "capture this finding" / "save this bug fix" / "save this gotcha" / "drop this to raw" / "quick save to wiki", or automatically by the session-end Stop hook. **Speed contract:** Inline only. No subagents. No QMD. No manifest/`index.md`/`log.md`/`hot.md` writes. Target: <60 seconds. Promotion to full wiki pages happens later via `/wiki-ingest`. 1. **Resolve config** (Config Resolution Protocol in `llm-wiki/SKILL.md`): get `OBSIDIAN_VAULT_PATH` and `OBSIDIAN_RAW_DIR` (default: `$OBSIDIAN_VAULT_PATH/_raw`). Ensure `$OBSIDIAN_RAW_DIR` exists; create it if not. Capture does not independently reinterpret validator schema inputs. When `OBSIDIAN_ALLOWED_LIFECYCLES`, `OBSIDIAN_ALLOWED_RELATIONSHIP_TYPES`, `OBSIDIAN_REQUIRED_TRUST_FIELDS`, or `OBSIDIAN_SCHEMA_SOURCE` is present, preserve it for the downstream lint/trust consumer: CLI values take precedence over environment/config values, which take precedence over framework defaults, and explicit blank or whitespace-only values fail closed. Omit a variable to use defaults. 2. **Gate — KEEP or SKIP?** Before extracting, judge whether this session has capture value. This keeps the skill safe to call automatically without spamming `_raw/`. - **SKIP** (exit with "Nothing worth capturing in this session.") if ALL are true: the conversation is purely conversational (planning/Q&A/explanation) with no implementation; no errors, debugging, or problem-solving visible; nothing surprising or undocumented; every finding is already obvious from the docs. - **KEEP** (proceed) if ANY are true: a fix or workaround was found through investigation; non-obvious library/API/framework behavior was confirmed (edge case, undocumented constraint, time-costing gotcha); a debugging session reached a concrete conclusion; a reusable pattern emerged. - When invoked **via the Stop hook, err toward SKIP** — only KEEP on clear evidence. When invoked **manually, err toward KEEP** — the user called it for a reason. 3. **Scan for reusable findings** — non-obvious bugs and root causes, framework/library gotchas, surprising API behavior, investigated workarounds, environment/toolchain quirks, patterns from debugging. Skip PM updates, config already in CLAUDE.md, inconclusive back-and-forth, anything obvious from the docs, and pleasantries. If nothing material emerged, say so and stop. 4. **Cluster by topic** — one `_raw/` file per topic cluster, not per finding. Name each as a kebab-case slug (e.g. `swift-actor-reentrancy`, `nextjs-hydration-mismatch`). 5. **Infer project context** from repo names, file paths, framework mentions, error messages. Use the most specific name you can reliably infer; else `null`. 6. **Write raw files** — for each cluster, write `$OBSIDIAN_RAW_DIR/-.md`. Read `references/RAW-FORMAT.md` for the full frontmatter spec, finding-block body structure, and provenance/confidence calibration. Per-cluster fields that vary: `title`, `tags` (2–4 from taxonomy), `summary` (≤200 chars), `project` (inferred or `null`), `base_confidence` (0.6 discussed → 0.75 fix applied → 0.9 test confirmed), `provenance.extracted`/`provenance.inferred` (sum to 1.0), `lifecycle_changed` (today), `sources` (`" session ()"`). 7. **Confirm** — list staged files and tell the user to run `/wiki-ingest` to promote them: ``` Staged to _raw/: _raw/2026-05-27-swift-actor-reentrancy.md — "Actor reentrancy causes deadlock in async forEach" Run /wiki-ingest to promote these to full wiki pages. ``` Quick mode deliberately does **not** write the manifest, `index.md`, `log.md`, `hot.md`, or refresh QMD — promotion via `/wiki-ingest` handles all of that. **Stop here; do not run the full-mode steps below.** --- ## Correction Mode (`--correction`) Use this mode when a user or stronger authority corrects a claim derived from an immutable conversation, tool result, or other raw source. Never edit or copy the raw source. Resolve config, read the vault `AGENTS.md`, and update an existing derived page when one owns the claim; otherwise create the smallest owner-compliant derived correction page. Record exactly one atomic claim pair. `speaker_type` is semantic and must be assessed independently of a serialized message `role` (a tool result may be serialized as `role=user`). Do not include raw transcript excerpts. ```yaml correction_id: source_locator: source_text_sha256: <64 lowercase hex chars> serialized_role: speaker_type: user | assistant | teammate | tool_result | slack_member original_claim: subject: assertion: corrected_claim: subject: assertion: authority_class: contract | decision | code | test | deploy | runtime | db | narrative verification_state: verified | inferred | unverified | contradicted asserted_at: effective_at: as_of: supersedes: [] consumer_propagation: kw: open | not_applicable | complete ob: open | not_applicable | complete requirements: open | not_applicable | complete code: open | not_applicable | complete tests: open | not_applicable | complete ai_memory: open | not_applicable | complete corrected_at: ``` Before any derived write, compute `source_pre_sha256` directly from the immutable source and require it to equal `source_text_sha256`. After writing the correction and updating derived consumers, recompute `source_post_sha256` from the same locator. Abort and report an immutability violation unless `source_pre_sha256 == source_post_sha256 == source_text_sha256`. This verification is mandatory even when the correction write succeeds. After writing the derived correction, link the immutable source to the created/updated page through `.manifest.json`, append only the correction ID and affected-page counts to `log.md`, and propagate the atomic correction to every consumer independently. Mark a consumer `complete` only after verifying that consumer; do not collapse mixed results into a single aggregate status. Keep secrets, raw excerpts, and source copies out of the correction record. --- ## Full Mode ## Before You Start 1. **Resolve config** — follow the Config Resolution Protocol in `llm-wiki/SKILL.md` (inline `@name` override → walk up CWD for `.env` → global config → prompt setup). This gives `OBSIDIAN_VAULT_PATH` and `OBSIDIAN_LINK_FORMAT` (default: `wikilink`). 2. Read `$OBSIDIAN_VAULT_PATH/index.md` to understand existing wiki content (avoid duplicates) 3. Read `$OBSIDIAN_VAULT_PATH/hot.md` if it exists — it gives context on recent activity When writing internal links in Step 5, apply the link format from `llm-wiki/SKILL.md` (Link Format section) using the `OBSIDIAN_LINK_FORMAT` value. ## Step 1: Identify What's Worth Preserving Scan the conversation. Ask: what knowledge emerged here that would be valuable in 3 months with no memory of this chat? Worth preserving: - Decisions made and *why* they were made - Analysis, frameworks, mental models developed - Technical findings, patterns, or procedures - Synthesized understanding of a topic - Clear explanations of a concept that took effort to arrive at - Key facts from an external source discussed in the conversation Skip: - Logistics, scheduling, pleasantries - Exploratory back-and-forth where no conclusion was reached - Content that's already in the wiki If nothing material emerged, tell the user and stop. ## Step 2: Classify the Content Type Assign one of five types — this determines the target folder and tone: | Type | Description | Target folder | |---|---|---| | `synthesis` | Multi-step analysis or an answer to a specific question that required reasoning | `synthesis/` | | `concept` | A definition, framework, or mental model (what a thing *is*) | `concepts/` | | `source` | Summary of an external document, article, or resource discussed | `references/` | | `decision` | A strategic, architectural, or design choice and its rationale | `synthesis/` | | `session` | A complete discussion summary when the conversation spans multiple topics | `journal/` | If the content clearly belongs to a specific project (detected from context or user mention), place it under `projects///` instead. ## Step 3: Rewrite as Declarative Knowledge Do **not** write a summary of the conversation. Write the knowledge itself, in declarative present tense: - Not: "The user asked about X and Claude explained that..." - Yes: "X works by..." - Not: "We decided to use Y because..." - Yes: "Y is preferred over Z because [reason]. [^[inferred] if the rationale was implied, not stated explicitly]" Apply provenance markers per `llm-wiki`: - *Extracted* — explicitly stated in the conversation (no marker) - *Inferred* — generalized or synthesized from the conversation → `^[inferred]` - *Ambiguous* — disputed, uncertain, or contradictory → `^[ambiguous]` ## Step 4: Generate a Slug and Title Derive a clear, descriptive title from the content. Slugify it: - Lowercase, words separated by hyphens - Max 50 characters - Avoid dates in the slug (the frontmatter has `created`) ## Step 5: Write the Wiki Note Create the file at the target path with required frontmatter: ```yaml --- title: >- category: <synthesis|concepts|references|journal|skills> tags: [<2-5 domain tags from taxonomy>] sources: - conversation:<ISO-date> created: <ISO-8601 timestamp> updated: <ISO-8601 timestamp> summary: >- <1-2 sentences, ≤200 chars, answering "what knowledge does this page hold?"> provenance: extracted: 0.X inferred: 0.X ambiguous: 0.X base_confidence: 0.42 lifecycle: draft lifecycle_changed: <ISO date today> --- ``` Body structure by type: **synthesis / decision:** ```markdown # Title ## Context <What prompted this — the problem or question being addressed> ## Finding / Decision <The core knowledge or conclusion> ## Reasoning <Why this is the case or why this choice was made> ## Implications <What follows from this — what to watch for, next steps, trade-offs> ## Related <[[wikilinks]] to connected pages> ``` **concept:** ```markdown # Title <Definition in one clear sentence.> ## What It Is <Explanation of the concept> ## How It Works <Mechanism or structure> ## When to Use <Applicability, conditions, trade-offs> ## Related <[[wikilinks]]> ``` **source:** ```markdown # Title > Source: <title or URL> ## What It Covers <What the source is about> ## Key Points <Bulleted claims with provenance markers> ## Open Questions <What it raises but doesn't answer — omit if none> ## Related <[[wikilinks]]> ``` **session:** ```markdown # Title *Session captured: <date>* ## Topics Covered <Brief list> ## Key Takeaways <The 3-5 most important things that emerged> ## Decisions Made <Any explicit decisions, with rationale> ## Open Questions <What remains unresolved> ## Related <[[wikilinks]]> ``` Every note must link to at least 2 existing wiki pages. Search `index.md` before writing. If fewer than 2 related pages exist, create minimal stubs for the most important concepts referenced. ## Step 5b: Update the Owner Profile and Todo Index The memory surface is only as good as what gets written into it. This is the step that keeps it alive — without it the profile stays empty and the session recap has nothing to inject. **Durable facts about the person.** If the conversation revealed something stable about how the user works — their stack, their conventions, their constraints, their timezone — record it: ```bash obsidian-wiki memory profile set <key> "<value>" --confidence 0.85 --source "session:<date>" ``` Apply the same KEEP/SKIP discipline as Step 1, and one extra rule that matters more: - **Only what the user actually told you**, directly or by clear demonstration. Never infer a durable fact about a person from a document that was ingested — that is the document's content and belongs on a page, not in their profile. - **Stable, not incidental.** "Uses Postgres" is a fact. "Ran a migration today" is an event; that belongs in the log. - **Calibrate the confidence.** Stated outright is ~0.9. Demonstrated repeatedly is ~0.75. Inferred from one session's behaviour is ~0.5 — and if you are below 0.5, do not write it at all. - **Correct, don't duplicate.** `profile set` replaces an existing key, so updating a changed fact is the same command. **Open threads.** If the conversation left work unfinished, record it so the next session picks it up: ```bash obsidian-wiki memory todo add "<the open thread>" --origin "<page or project>" ``` Re-adding an open thread with the same text touches it rather than duplicating, so this is safe to call when you are unsure whether it already exists. If the conversation *closed* a thread that is already listed, close it: ```bash obsidian-wiki memory todo list --vault "$OBSIDIAN_VAULT_PATH" obsidian-wiki memory todo done <id> ``` Never close a thread the user did not actually finish. Staleness is reported by the tooling; it is not your job to tidy the list. **In quick mode**, do this step but skip Step 6 — profile and todo writes are cheap, locked, and are the whole point of capturing. ## Step 6: Update Tracking Files One locked call updates all three: ```bash obsidian-wiki memory sync CAPTURE \ type=<type> page="<path>" title="<title>" \ --takeaways "<what this capture changes about the picture, if anything>" ``` Never hand-edit `index.md`, `log.md`, or `hot.md` — see `.skills/llm-wiki/references/MEMORY.md`. Omit `--takeaways` when the capture does not shift the overall picture; the previous takeaways carry across. ## Step 7: Confirm to User Report the saved path and title: ``` Saved to: projects/<name>/synthesis/<slug>.md Title: <Title> Type: synthesis ``` ## Quality Checklist - [ ] Content rewritten as declarative knowledge (not a chat transcript) - [ ] Type classified correctly; target path is in the right folder - [ ] Frontmatter complete with title, category, tags, sources, summary, provenance - [ ] At least 2 wikilinks to existing pages - [ ] `index.md`, `log.md`, and `hot.md` updated - [ ] Confirmed save path to user ## QMD Refresh After Vault Writes QMD is a search index, not the source of truth. If `$QMD_WIKI_COLLECTION` is empty or unset, skip this step. Run it only after this skill has written or rewritten vault markdown. If QMD refresh fails, do not roll back the vault changes; report the QMD status separately. Use `$QMD_CLI` if set; otherwise use `qmd`. ```bash ${QMD_CLI:-qmd} update ``` If the output says vectors are needed or embeddings may be stale, run: ```bash ${QMD_CLI:-qmd} embed ``` Verify the collection with either: ```bash ${QMD_CLI:-qmd} ls "$QMD_WIKI_COLLECTION" ``` or, when a specific page path is known: ```bash ${QMD_CLI:-qmd} get "qmd://$QMD_WIKI_COLLECTION/<page>.md" -l 5 ``` Record one of: - `QMD refreshed: update + embed + verified` - `QMD refreshed: update only + verified` - `QMD skipped: QMD_WIKI_COLLECTION unset` - `QMD skipped: qmd CLI unavailable` - `QMD failed: <short error summary>`