---
phase: 10-user-guide-content
plan: 02
type: execute
wave: 1
depends_on: []
files_modified:
  - docs/obsidian.md
  - docs/plugins.md
  - mkdocs.yml
  - scripts/gen_llms_full_txt.py
  - docs/llms.txt
autonomous: true
requirements:
  - UGDE-03

must_haves:
  truths:
    - "A reader can follow the Obsidian setup walkthrough with expected terminal output and understand why each community plugin matters"
    - "A reader can set up and configure the Git plugin from the plugins guide alone, knowing which actions trigger commits and the batch vs immediate mode difference"
    - "A reader can configure the Reweave plugin, understand its 4-signal scoring, and know which note types are excluded from auto-reweave"
    - "The Git and Reweave plugin guides are in a discoverable docs/plugins.md page in the nav"
    - "llms.txt and NAV_ORDER are updated so agent-accessible corpus reflects new plugins.md content"
  artifacts:
    - path: "docs/obsidian.md"
      provides: "Enhanced Obsidian setup walkthrough"
      min_lines: 130
      contains:
        - "ztlctl init --profile obsidian"
        - "dataview"
        - "garden/"
    - path: "docs/plugins.md"
      provides: "Git and Reweave built-in plugin guides"
      min_lines: 120
      contains:
        - "## Git Plugin"
        - "## Reweave Plugin"
        - "batch_commits"
        - "min_score_threshold"
        - "[plugins.git]"
        - "[reweave]"
    - path: "mkdocs.yml"
      provides: "Updated nav with Built-in Plugins page"
      contains: "plugins.md"
    - path: "scripts/gen_llms_full_txt.py"
      provides: "NAV_ORDER updated with plugins.md"
      contains: "plugins.md"
    - path: "docs/llms.txt"
      provides: "llms.txt updated with Built-in Plugins entry"
      contains: "plugins"
  key_links:
    - from: "mkdocs.yml nav"
      to: "docs/plugins.md"
      via: "nav entry between obsidian.md and agentic-workflows.md"
      pattern: "Built-in Plugins.*plugins\\.md"
    - from: "scripts/gen_llms_full_txt.py NAV_ORDER"
      to: "docs/plugins.md"
      via: "User Guide list"
      pattern: "plugins\\.md"
---

<objective>
Enhance docs/obsidian.md from its current 71-line reference stub into a 130+ line setup walkthrough (with terminal output and plugin explanations), then create a new docs/plugins.md page documenting the Git and Reweave built-in plugins with exact config fields, trigger conditions, and common scenarios. Wire the new page into mkdocs.yml nav, NAV_ORDER, and llms.txt.

Purpose: There is currently zero documentation for the Git plugin and Reweave plugin despite both being enabled by default. Every user who runs `ztlctl create note` silently gets auto-reweave and auto-git-commit behavior. The obsidian.md page is correct but too terse for a reader trying to do the setup for the first time.

Output: Enhanced docs/obsidian.md, new docs/plugins.md, updated mkdocs.yml nav, updated NAV_ORDER in gen_llms_full_txt.py, updated docs/llms.txt.
</objective>

<execution_context>
@/Users/shparki/.claude/get-shit-done/workflows/execute-plan.md
@/Users/shparki/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/10-user-guide-content/10-CONTEXT.md
@.planning/phases/10-user-guide-content/10-RESEARCH.md
</context>

<interfaces>
<!-- Plugin config fields extracted from source — these are the facts to document -->

Git plugin (src/ztlctl/plugins/builtins/git.py):
- Triggers via post_action hookspec
- Actions that trigger git: create_note, create_reference, create_task, update, close, archive (stage + commit-if-immediate)
- session_close: commits all staged (batch mode) + optional push
- init: git init + write .gitignore + initial commit "feat: initialize vault '{name}'"
- No-ops: reweave, session_start, check, check_rebuild
- Failure model: try/except around all subprocess calls, DEBUG log, vault ops never fail
- Auto-generated .gitignore content: .ztlctl/backups/ and *.db-journal
- Commit message formats:
  - create_note: "feat: create note {id} — {title}"
  - create_reference: "feat: create reference {id} — {title}"
  - create_task: "feat: create task {id} — {title}"
  - update: "docs: update {id} ({fields_changed})"
  - close/archive: "docs: close {id} — {summary}"
  - session_close: "docs: session {id} — N created, N updated"

GitConfig fields: enabled=true, branch="develop", auto_push=true, commit_style="conventional", batch_commits=true, auto_ignore=true

Reweave plugin (src/ztlctl/plugins/builtins/reweave_plugin.py):
- Triggers via post_action hookspec
- Fires for: create_note, create_reference ONLY
- Skip conditions (in order): result.ok==False, no content_id, subtype=="decision", settings.no_reweave==True, settings.reweave.enabled==False
- Calls ReweaveService.reweave(content_id=content_id) — 4-signal scoring
- 4 scoring signals: BM25 lexical (0.35), Jaccard tag overlap (0.25), graph proximity (0.25), shared topic directory (0.15)

ReweaveConfig fields: enabled=true, min_score_threshold=0.6, max_links_per_note=5, lexical_weight=0.35, tag_weight=0.25, graph_weight=0.25, topic_weight=0.15

Obsidian community plugins (from obsidian.md): dataview, templater-obsidian, folder-notes, omnisearch, obsidian-book-search-plugin
</interfaces>

<tasks>

<task type="auto">
  <name>Task 1: Enhance docs/obsidian.md with setup walkthrough and plugin explanations</name>
  <files>docs/obsidian.md</files>

  <read_first>
    - docs/obsidian.md — current 71-line content (keep as foundation, expand with walkthrough depth)
    - docs/tutorial.md — tone reference (sentence → code block → outcome note pattern)
  </read_first>

  <action>
Expand docs/obsidian.md from 71 lines to 130+ lines. Keep all existing correct content; add the missing walkthrough depth and community plugin explanations. Follow tutorial.md's pattern: short explanatory sentence → code block → brief outcome note.

**Content to add:**

1. **"What This Page Covers" intro paragraph** (new, 2-3 sentences): "This guide walks through setting up the first-party Obsidian integration from vault init through community plugin activation. The obsidian workspace profile scaffolds a curated starter kit optimized for hybrid human-agent knowledge work. You don't need Obsidian to use ztlctl — this guide is for users who want to pair the two."

2. **Setup Walkthrough with expected terminal output** — expand the existing "First Open in Obsidian" section into a numbered setup procedure with `ztlctl init` command and sample output:

   ```bash
   ztlctl init research-vault --profile obsidian --name "Research Vault" --topics "ml,systems"
   ```

   Expected output (show condensed version):
   ```
   ✓ Vault initialized: research-vault/
   ✓ Obsidian starter kit scaffolded (.obsidian/, garden/)
   ✓ Community plugin configs written

   Next steps for Obsidian:
   1. Open research-vault/ in Obsidian and trust it
   2. Settings → Community plugins → Browse → install: dataview, templater-obsidian,
      folder-notes, omnisearch, obsidian-book-search-plugin
   3. Enable all five plugins
   4. Verify settings in .obsidian/ took effect (graph view, templates path)
   ```

   Add `!!! note` admonition: "ztlctl writes the .obsidian/ starter files during init, then leaves them for you to customize. After the first open, .obsidian/ is yours — ztlctl won't overwrite your changes."

3. **Why Each Community Plugin Matters** (new subsection `## Why Each Community Plugin`) — add a rationale column to the existing plugin list:

   | Plugin | Purpose in this workflow |
   |--------|--------------------------|
   | `dataview` | Query your ztlctl-exported dashboard as a live Obsidian database — surfaces stale notes, seed candidates, and decision queue without leaving Obsidian |
   | `templater-obsidian` | Apply garden templates (note.md, grove.md, book.md) scaffolded by ztlctl init — keeps garden entries consistent |
   | `folder-notes` | Makes garden/ subdirectory structure navigable in Obsidian's file explorer — groves and canvases get clickable folder notes |
   | `omnisearch` | Full-text search across both ztlctl notes AND garden/ content in one Obsidian search bar |
   | `obsidian-book-search-plugin` | Fetch metadata for books added to the library/ garden layer — configured to match the book.md template |

4. **Vault Structure Diagram** (new subsection `## Vault Structure`) — show the coexistence of machine-managed and human-managed paths:

   ```
   research-vault/
   ├── ztlctl.toml          # Core config — managed by ztlctl
   ├── .ztlctl/             # Internal state (DB, backups) — managed by ztlctl
   ├── self/                # Identity and methodology files — managed by ztlctl
   ├── notes/               # Atomic knowledge notes — managed by ztlctl
   ├── ops/                 # Tasks and session logs — managed by ztlctl
   ├── sources/             # Ingested source bundles — managed by ztlctl
   ├── .obsidian/           # Obsidian workspace config — scaffolded by ztlctl, then yours
   └── garden/              # Human-managed knowledge garden — never touched by ztlctl
       ├── README.md
       ├── notes/           # Garden notes (seed → budding → evergreen)
       ├── groves/          # Topic clusters
       ├── library/         # Books and long-form sources
       ├── canvases/        # Visual mind maps
       ├── attachments/     # Images and files
       └── templates/       # note.md, grove.md, book.md
   ```

   Add `!!! tip` admonition: "garden/ is intentionally outside ztlctl's indexing. You can freely restructure, rename, and reorganize garden/ content without affecting ztlctl's graph or database."

5. **Using garden/ Alongside ztlctl Queries** (new subsection `## Using garden/ for Enrichment`) — 2-3 sentences + commands:

   "After a ztlctl session, export a review dashboard and open it in Obsidian to guide garden work:"

   ```bash
   # After closing a session, generate a review workbench
   ztlctl export dashboard --viewer obsidian --output ./dashboard

   # Then open dashboard/ in Obsidian alongside your vault
   # The dashboard shows: stale notes, orphan candidates, topic dossiers
   ```

   "The exported dashboard is a machine-layer review workbench — not a mirror of garden/. Use it to decide what to tend next, then do the tending in Obsidian's garden/ directly."

6. Keep all existing sections verbatim: "What Gets Scaffolded", "Curated Community Plugin Preset", "Ownership", "Relationship to Export". The existing content is accurate — only add, don't remove.

7. **Next Steps** (new, at the end):
   ```markdown
   ## Next Steps

   - See [Built-in Plugins](plugins.md) for Git and Reweave plugin configuration
   - See [Agentic Workflows](agentic-workflows.md) for session lifecycle and recipe walkthroughs
   - See [Configuration](configuration.md) for the full ztlctl.toml reference
   ```
  </action>

  <verify>
    <automated>wc -l /Users/shparki/Documents/Workspace/thatdev/ztlctl/docs/obsidian.md</automated>
  </verify>

  <acceptance_criteria>
    - File is 130+ lines (up from 71)
    - Contains "Why Each Community Plugin" section with dataview rationale
    - Contains vault structure diagram showing garden/ vs machine-managed paths
    - Contains `ztlctl init --profile obsidian` command with expected output
    - Contains "Next Steps" section linking to plugins.md and agentic-workflows.md
    - All original sections preserved (What Gets Scaffolded, Curated Community Plugin Preset, Ownership, Relationship to Export)
  </acceptance_criteria>

  <done>docs/obsidian.md is 130+ lines with setup walkthrough showing expected output, community plugin rationale table, vault structure diagram, and next steps linking to new plugins.md.</done>
</task>

<task type="auto">
  <name>Task 2: Create docs/plugins.md with Git and Reweave plugin guides</name>
  <files>docs/plugins.md, mkdocs.yml, scripts/gen_llms_full_txt.py, docs/llms.txt</files>

  <read_first>
    - docs/tutorial.md — tone and depth gold standard (sentence → code block → outcome note)
    - docs/agentic-workflows.md — existing content to understand what session lifecycle info is already documented
    - mkdocs.yml — current nav structure (plugins.md goes between obsidian.md and agentic-workflows.md)
    - scripts/gen_llms_full_txt.py — NAV_ORDER constant to update
    - docs/llms.txt — current llms.txt to update with new page entry
  </read_first>

  <action>
Create docs/plugins.md as a new standalone guide covering both built-in plugins. Then wire it into mkdocs.yml nav, gen_llms_full_txt.py NAV_ORDER, and docs/llms.txt.

**docs/plugins.md structure:**

```markdown
---
title: Built-in Plugins
---

# Built-in Plugins

ztlctl ships two built-in plugins that run automatically in the background: the Git plugin for automatic version control and the Reweave plugin for automatic link discovery. Both are enabled by default. This page explains exactly what they do, when they run, and how to configure them.

## Git Plugin

The Git plugin provides automatic version control for vault operations. When you create a note, the plugin stages the file and — depending on configuration — either commits immediately or batches the commit for session close.

### Prerequisites

!!! note
    The Git plugin requires `git` to be installed and available on your PATH. If git is not found, the plugin logs a debug message and continues silently — vault operations never fail due to git errors.

Verify git is available:

```bash
git --version
```

### What Gets Committed Automatically

Every vault operation that creates or modifies a markdown file triggers a git stage. Commit timing depends on the `batch_commits` setting (see [Configuration](#git-plugin-configuration) below).

| Action | Commit Message Format |
|--------|-----------------------|
| `ztlctl create note` | `feat: create note {id} — {title}` |
| `ztlctl create reference` | `feat: create reference {id} — {title}` |
| `ztlctl create task` | `feat: create task {id} — {title}` |
| `ztlctl update` | `docs: update {id} ({fields_changed})` |
| `ztlctl close` / `ztlctl archive` | `docs: close {id} — {summary}` |
| `ztlctl agent session close` | `docs: session {id} — N created, N updated` |
| `ztlctl init` | `feat: initialize vault '{name}'` |

Operations that are **no-ops** for the Git plugin: `reweave`, `session start`, `check`, `check rebuild`. These do not stage or commit any files.

### Batch Mode vs Immediate Mode

| Mode | Behavior | When to use |
|------|----------|-------------|
| **Batch (default)** | Files are staged on each operation; one commit is made at session close | Session-based workflows — clean history with one commit per session |
| **Immediate** | Files are staged AND committed after every individual operation | Headless or no-session workflows — each note creation is its own commit |

!!! warning
    In batch mode, creating notes outside an active session stages files but never commits them — the commit trigger is `session close`. If you work without sessions, set `batch_commits = false`.

**What git status looks like in batch mode (before session close):**
```bash
$ git status
On branch develop
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   notes/ZTL-0001.md
        new file:   notes/ZTL-0002.md
        modified:   notes/ZTL-0003.md
```

After `ztlctl agent session close`, all staged changes are committed in one operation:
```bash
docs: session LOG-0001 — 2 created, 1 updated
```

### Git Plugin Configuration

In `ztlctl.toml`:

```toml
[plugins.git]
enabled = true
batch_commits = true      # true = commit at session close, false = commit immediately
auto_push = false         # push to remote on session close
auto_ignore = true        # write .gitignore during vault init
```

**All config fields:**

| Field | Default | Meaning |
|-------|---------|---------|
| `enabled` | `true` | Enable or disable the entire plugin |
| `batch_commits` | `true` | Batch all changes into one session-close commit |
| `auto_push` | `true` | Push to remote after session-close commit |
| `auto_ignore` | `true` | Write .gitignore during `ztlctl init` |
| `branch` | `"develop"` | Target branch (informational — plugin does not enforce branch) |
| `commit_style` | `"conventional"` | Commit message format (currently only `"conventional"`) |

The auto-generated `.gitignore` excludes:
```
# ztlctl vault gitignore
.ztlctl/backups/
*.db-journal
```

### Common Scenarios

**Disable automatic commits entirely:**
```toml
[plugins.git]
enabled = false
```

**Use immediate commits (one commit per note):**
```toml
[plugins.git]
batch_commits = false
```

**Push to remote automatically on session close:**
```toml
[plugins.git]
auto_push = true
```

---

## Reweave Plugin

The Reweave plugin automatically discovers connections for new notes and references the moment they are created. It runs the full 4-signal scoring algorithm against all existing content and creates graph edges for items above the threshold.

### What It Does

When you create a note or reference, the Reweave plugin immediately calls the reweave pipeline on the new item. This means your vault's link graph is always up to date without any manual `ztlctl reweave` call.

```bash
# When you run this:
ztlctl create note "Attention mechanisms" --tags "ml/transformers"

# The Reweave plugin automatically runs the equivalent of:
ztlctl reweave --id ZTL-0042
# → finds related notes via BM25 + tag overlap + graph proximity + shared topic
# → creates edges for items scoring above 0.6 (default threshold)
```

### When It Runs (and When It Doesn't)

**Fires for:** `create note`, `create reference` only.

**Does not fire for:** `create task`, `update`, `close`, `archive`, `session close`, or `reweave` (manual reweave is not re-triggered).

**Skip conditions (checked in order):**
1. The create operation failed — skip
2. The created item has no ID — skip
3. `subtype = "decision"` — skip (decision notes have strict lifecycle and must not be auto-mutated)
4. `--no-reweave` flag was passed — skip for this invocation only
5. `[reweave] enabled = false` in config — skip globally

!!! note
    Decision notes (`ztlctl create note --subtype decision`) are intentionally excluded from auto-reweave. Decision notes represent deliberate choices and must not be auto-linked by background processes. Run `ztlctl reweave --id {id}` manually if you want to connect a decision note.

### 4-Signal Scoring

The reweave algorithm scores candidate links using four signals:

| Signal | Default Weight | What It Measures |
|--------|---------------|-----------------|
| BM25 lexical similarity | 0.35 | Shared vocabulary between note bodies |
| Jaccard tag overlap | 0.25 | Proportion of tags in common |
| Graph proximity | 0.25 | How closely connected via existing edges |
| Shared topic directory | 0.15 | Whether notes share a topic routing prefix |

A link is created when the combined score exceeds `min_score_threshold` (default: 0.6).

### Reweave Plugin Configuration

In `ztlctl.toml`:

```toml
[reweave]
enabled = true
min_score_threshold = 0.6   # raise to 0.75 for fewer, higher-quality links
max_links_per_note = 5      # raise for denser graphs
lexical_weight = 0.35
tag_weight = 0.25
graph_weight = 0.25
topic_weight = 0.15
```

**All config fields:**

| Field | Default | Meaning |
|-------|---------|---------|
| `enabled` | `true` | Global enable/disable for auto-reweave |
| `min_score_threshold` | `0.6` | Minimum combined score (0.0–1.0) to create a link |
| `max_links_per_note` | `5` | Maximum new links per auto-reweave run |
| `lexical_weight` | `0.35` | BM25 signal weight |
| `tag_weight` | `0.25` | Tag overlap signal weight |
| `graph_weight` | `0.25` | Graph proximity signal weight |
| `topic_weight` | `0.15` | Topic directory signal weight |

Weights do not need to sum to 1.0 — they are relative, not normalized.

### Common Scenarios

**Disable auto-reweave for a single note:**
```bash
ztlctl create note "Quick capture" --no-reweave
```

**Disable auto-reweave globally:**
```toml
[reweave]
enabled = false
```

**Tune for fewer, higher-quality links:**
```toml
[reweave]
min_score_threshold = 0.75
max_links_per_note = 3
```

**Emphasize tag-based connections (lower lexical weight):**
```toml
[reweave]
lexical_weight = 0.20
tag_weight = 0.45
```

**Run reweave manually for an existing note:**
```bash
ztlctl reweave --id ZTL-0042
```

---

## Next Steps

- See [Agentic Workflows](agentic-workflows.md) for how plugins interact with sessions and MCP recipes
- See [Configuration](configuration.md) for the full ztlctl.toml reference including all plugin config schemas
- See [Obsidian Starter Kit](obsidian.md) for setting up the Obsidian integration
```

**mkdocs.yml nav update:**

Add `Built-in Plugins: plugins.md` to the User Guide section, between `obsidian.md` and `agentic-workflows.md`:

```yaml
  - User Guide:
    - guide/index.md
    - Tutorial: tutorial.md
    - Core Concepts: concepts.md
    - Knowledge Paradigms: paradigms.md
    - Obsidian Starter Kit: obsidian.md
    - Built-in Plugins: plugins.md       # ADD THIS LINE
    - Agentic Workflows: agentic-workflows.md
    - Command Reference: commands.md
    - Configuration: configuration.md
    - Troubleshooting: troubleshooting.md
```

**scripts/gen_llms_full_txt.py NAV_ORDER update:**

Add `"plugins.md"` to the User Guide list, between `"obsidian.md"` and `"agentic-workflows.md"`:

```python
NAV_ORDER = [
    (
        "Getting Started",
        ["index.md", "installation.md", "quickstart.md"],
    ),
    (
        "User Guide",
        [
            "guide/index.md",
            "tutorial.md",
            "concepts.md",
            "paradigms.md",
            "obsidian.md",
            "plugins.md",              # ADD THIS LINE
            "agentic-workflows.md",
            "commands.md",
            "configuration.md",
            "troubleshooting.md",
        ],
    ),
    (
        "Developer Guide",
        ["dev/index.md", "development.md", "mcp.md"],
    ),
]
```

**docs/llms.txt update:**

Read the current llms.txt and add a line for the Built-in Plugins page in the User Guide section. Find the line that lists obsidian.md and add a new line immediately after it:
```
- Built-in Plugins: https://thatdevstudio.github.io/ztlctl/plugins/
```
(Match the URL format used by other User Guide entries in the file.)
  </action>

  <verify>
    <automated>test -f /Users/shparki/Documents/Workspace/thatdev/ztlctl/docs/plugins.md && wc -l /Users/shparki/Documents/Workspace/thatdev/ztlctl/docs/plugins.md && grep "plugins.md" /Users/shparki/Documents/Workspace/thatdev/ztlctl/mkdocs.yml && grep "plugins.md" /Users/shparki/Documents/Workspace/thatdev/ztlctl/scripts/gen_llms_full_txt.py</automated>
  </verify>

  <acceptance_criteria>
    - docs/plugins.md exists and is 120+ lines
    - docs/plugins.md contains "## Git Plugin" and "## Reweave Plugin" headings
    - docs/plugins.md contains batch_commits, min_score_threshold, [plugins.git], [reweave] config examples
    - docs/plugins.md contains the decision-note skip-condition warning
    - mkdocs.yml contains "plugins.md" in the nav between obsidian.md and agentic-workflows.md
    - scripts/gen_llms_full_txt.py NAV_ORDER contains "plugins.md"
    - docs/llms.txt contains "plugins" entry in User Guide section
    - mkdocs build --strict passes with no errors (validates plugins.md nav reference resolves)
  </acceptance_criteria>

  <done>docs/plugins.md created with Git plugin guide (commit table, batch vs immediate, config fields, common scenarios) and Reweave plugin guide (4-signal scoring, skip conditions, config fields, common scenarios). mkdocs.yml nav updated. NAV_ORDER updated. llms.txt updated. mkdocs build --strict passes.</done>
</task>

</tasks>

<verification>
After all tasks complete:

```bash
# Check file line counts
wc -l docs/obsidian.md docs/plugins.md

# Verify nav wiring
grep "plugins.md" mkdocs.yml scripts/gen_llms_full_txt.py

# Verify key content markers
grep -c "batch_commits\|min_score_threshold\|4-signal" docs/plugins.md

# Full build validation
mkdocs build --strict 2>&1 | tail -5
```
</verification>

<success_criteria>
- docs/obsidian.md is 130+ lines with setup walkthrough, community plugin rationale table, vault structure diagram
- docs/plugins.md is 120+ lines with both Git and Reweave plugin guides including exact config fields and commit message formats
- mkdocs.yml nav has "Built-in Plugins: plugins.md" between obsidian.md and agentic-workflows.md
- NAV_ORDER in gen_llms_full_txt.py includes "plugins.md"
- docs/llms.txt has Built-in Plugins entry in User Guide section
- `mkdocs build --strict` exits 0
</success_criteria>

<output>
After completion, create `.planning/phases/10-user-guide-content/10-02-SUMMARY.md`
</output>
