---
phase: 11-developer-guide-api-reference
plan: 04
type: execute
wave: 2
depends_on:
  - 11-01
  - 11-02
files_modified:
  - docs/development.md
  - CONTRIBUTING.md
  - docs/dev/index.md
  - docs/llms.txt
  - scripts/gen_llms_full_txt.py
  - docs/llms-full.txt
  - mkdocs.yml
autonomous: true
requirements:
  - DVGD-03
  - DVGD-04

must_haves:
  truths:
    - "docs/development.md contains the 4-layer action model (Data/Service/Controller/Registry)"
    - "docs/development.md explains how CLI and MCP surfaces are auto-generated from ActionRegistry"
    - "docs/development.md explains plugin integration points (where pre_action/post_action fire)"
    - "CONTRIBUTING.md cross-links to docs/development.md for architecture and to the developer guide for plugin authoring"
    - "mkdocs.yml nav Developer Guide section includes Plugin Authoring and API Reference entries"
    - "docs/dev/index.md table includes plugin-guide.md and api-reference.md rows"
    - "llms.txt Developer Guide section includes new page entries"
    - "llms-full.txt is regenerated and includes plugin-guide.md and api-reference.md content"
  artifacts:
    - path: "docs/development.md"
      provides: "Architecture overview with 4-layer action model"
      contains: "ActionRegistry"
    - path: "CONTRIBUTING.md"
      provides: "Cross-links to developer guide and development.md"
      contains: "plugin-guide"
    - path: "docs/dev/index.md"
      provides: "Updated landing page table with all 4 developer guide pages"
      contains: "plugin-guide"
    - path: "docs/llms.txt"
      provides: "Developer Guide section with new page links"
      contains: "Plugin Authoring"
    - path: "docs/llms-full.txt"
      provides: "Regenerated full corpus including new pages"
      contains: "plugin-guide"
    - path: "mkdocs.yml"
      provides: "Nav with Plugin Authoring and API Reference entries"
      contains: "plugin-guide.md"
  key_links:
    - from: "CONTRIBUTING.md architecture section"
      to: "docs/development.md#architecture"
      via: "cross-link replacing inline architecture table"
      pattern: "development.*architecture"
    - from: "mkdocs.yml nav Developer Guide"
      to: "docs/plugin-guide.md"
      via: "Plugin Authoring nav entry"
      pattern: "plugin-guide"
    - from: "scripts/gen_llms_full_txt.py NAV_ORDER"
      to: "docs/plugin-guide.md and docs/api-reference.md"
      via: "NAV_ORDER Developer Guide list"
      pattern: "plugin-guide"
---

<objective>
Wire all new developer guide pages into the site navigation and agent corpus, enhance docs/development.md with the 4-layer action model architecture, and update CONTRIBUTING.md with cross-links to the developer guide.

Purpose: Satisfies DVGD-03 and DVGD-04. Makes plugin-guide.md and api-reference.md discoverable by both human readers (nav) and agents (llms.txt + llms-full.txt). Gives core contributors the architecture mental model they need.
Output: Enhanced development.md, updated CONTRIBUTING.md, wired nav/llms infra.
</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/phases/11-developer-guide-api-reference/11-RESEARCH.md
@.planning/phases/11-developer-guide-api-reference/11-02-SUMMARY.md
</context>

<tasks>

<task type="auto">
  <name>Task 1: Enhance docs/development.md with 4-layer architecture and update CONTRIBUTING.md</name>
  <files>docs/development.md, CONTRIBUTING.md</files>
  <read_first>
    - docs/development.md (full 128 lines — locate existing "Architecture" section to know insertion point)
    - CONTRIBUTING.md (full 220 lines — locate architecture section lines 44-60 and intro section)
    - src/ztlctl/actions/registry.py (ActionRegistry.register, get, list_actions, get_action_registry)
    - src/ztlctl/actions/definitions.py (ActionDefinition, ActionParam field names)
  </read_first>
  <action>
**docs/development.md:**

The existing file has a brief "Architecture" section (a 6-layer diagram + one-line dependency flow). Insert a new subsection **after** the existing architecture diagram and **before** the "Template Overrides" section.

New subsection to insert — "Action Model":

```markdown
### Action Model

ztlctl uses a 4-layer action model that connects user-facing surfaces (CLI, MCP) to service logic:

| Layer | Components | Role |
|-------|-----------|------|
| **Data** | `ActionParam`, `ActionDefinition` | Frozen dataclasses describing an action's name, params, side effect, and surface metadata |
| **Service** | `*Service` classes | Business logic that executes the action and returns a `ServiceResult` |
| **Controller** | `BaseController` subclasses | Wires one `ActionDefinition` to one `Service` call; handles input coercion and error wrapping |
| **Registry** | `ActionRegistry` (singleton) | Indexed map of all registered `ActionDefinition` objects; queried at startup |

**How CLI auto-generation works:**
At startup, the CLI generator calls `get_action_registry().list_actions(category=...)` for each command group. It iterates the returned `ActionDefinition` objects and builds Click commands from `ActionParam` metadata (`cli_is_argument`, `cli_flag`, `cli_multiple`, `cli_name`). No code generation — the CLI surface is driven entirely by the registry at import time.

**How MCP auto-generation works:**
The MCP adapter calls `get_action_registry().list_actions()` and converts each `ActionDefinition` into an MCP tool descriptor using `mcp_when_to_use`, `mcp_avoid_when`, `mcp_common_errors`, and `mcp_example` fields. Same registry, different surface formatter.

**Plugin integration points:**
1. `pre_action` fires before the Controller calls the Service — plugins can abort (return `ActionRejection`) or transform kwargs
2. `post_action` fires after the Controller returns the `ServiceResult` — all plugins receive the call regardless of success/failure
3. `register_note_types()` returns `NoteTypeDefinition` objects — PluginManager creates `ActionDefinition` entries in the registry for CRUD operations on each custom type
4. `register_content_models()` extends the `CONTENT_REGISTRY` so new note subtypes are recognized by `CreateService`

**ServiceResult contract:**
Every Service method returns `ServiceResult`. Controllers unwrap it to emit exit codes (CLI) or structured responses (MCP). Plugins receive the raw `ServiceResult` via `post_action(result=...)`.
```

Constraints from RESEARCH.md:
- Do NOT duplicate development setup commands — those stay in CONTRIBUTING.md
- Do NOT duplicate branching model — CONTRIBUTING.md owns that
- Keep the new section high-level (mental model), not implementation-level detail

---

**CONTRIBUTING.md:**

Make two targeted additions — do NOT remove or rewrite existing content:

1. **Intro paragraph** (insert after the first H2 section, before "## Development Setup"): Add a "Developer Guide" callout paragraph:
```markdown
> **Plugin authors and integrators:** See the [Developer Guide](https://thatdevstudio.github.io/ztlctl/dev/) for the plugin authoring tutorial, hookspec reference, and auto-generated API reference.
```

2. **Architecture section (lines ~44-60):** The existing section has a brief architecture table listing the 6 layers. Replace the inline detail with a cross-link:
```markdown
## Architecture

ztlctl has a 6-layer package structure. For a complete architecture overview including the 4-layer action model, plugin integration points, and how CLI/MCP surfaces are auto-generated, see the [Architecture section in the Contributing guide](https://thatdevstudio.github.io/ztlctl/development/#action-model).

**Package layers (quick reference):**
- `domain/` — types, enums, lifecycle rules (no external deps beyond pydantic)
- `infrastructure/` — SQLite/SQLAlchemy Core, NetworkX graph, filesystem
- `config/` — Pydantic config models, TOML loading
- `services/` — business logic
- `output/` — Rich/JSON formatters
- `commands/` — Click command groups
- `plugins/` — pluggy hookspecs and built-in plugins
- `mcp/` — optional MCP adapter
```

Read the existing architecture section carefully before editing — preserve any content not covered above. The goal is to add a cross-link, not strip information.
  </action>
  <verify>
    <automated>cd /Users/shparki/Documents/Workspace/thatdev/ztlctl && grep -c "ActionRegistry\|ServiceResult\|BaseController" docs/development.md && grep -c "plugin-guide\|Developer Guide" CONTRIBUTING.md</automated>
  </verify>
  <done>
docs/development.md contains "Action Model" section with ActionRegistry, ServiceResult, BaseController, and plugin integration points.
CONTRIBUTING.md contains cross-link to developer guide and reference to development.md architecture section.
No contradictions between the two files.
  </done>
</task>

<task type="auto">
  <name>Task 2: Wire new pages into nav, dev/index.md, llms.txt, gen_llms_full_txt.py, and regenerate llms-full.txt</name>
  <files>mkdocs.yml, docs/dev/index.md, docs/llms.txt, scripts/gen_llms_full_txt.py, docs/llms-full.txt</files>
  <read_first>
    - mkdocs.yml (current Developer Guide nav block — currently: dev/index.md, development.md, mcp.md)
    - docs/dev/index.md (current 11-line table — currently 2 rows: Contributing, MCP Server)
    - docs/llms.txt (current Developer Guide section — currently 3 entries)
    - scripts/gen_llms_full_txt.py (NAV_ORDER Developer Guide list — currently ["dev/index.md", "development.md", "mcp.md"])
  </read_first>
  <action>
**mkdocs.yml** — Update the Developer Guide nav block to match the locked decision from CONTEXT.md exactly:

```yaml
  - Developer Guide:
    - dev/index.md
    - Contributing: development.md
    - Plugin Authoring: plugin-guide.md
    - API Reference: api-reference.md
    - MCP Server: mcp.md
```

Replace the current 3-entry block (dev/index.md, development.md, mcp.md) with this 5-entry block. Keep all other nav sections (Home, User Guide) unchanged.

---

**docs/dev/index.md** — Add 2 new rows to the "In This Guide" table:

Current table:
| Page | What it covers |
|------|----------------|
| [Contributing](../development.md) | Architecture overview, branch workflow, and contribution process |
| [MCP Server](../mcp.md) | MCP tools, resources, prompts, and agent integration patterns |

Updated table (add these 2 rows between Contributing and MCP Server):
| [Plugin Authoring](../plugin-guide.md) | Tutorial and hookspec reference for plugin authors — build your first plugin |
| [API Reference](../api-reference.md) | Auto-generated API reference for all public plugin contracts and the ActionRegistry |

---

**docs/llms.txt** — Add 2 new entries to the Developer Guide section (insert between Contributing and MCP Server):

```
- [Plugin Authoring](https://thatdevstudio.github.io/ztlctl/plugin-guide/): Tutorial and hookspec reference for building ztlctl plugins
- [API Reference](https://thatdevstudio.github.io/ztlctl/api-reference/): Auto-generated API reference for plugin contracts, hookspecs, and the ActionRegistry
```

---

**scripts/gen_llms_full_txt.py** — Update the Developer Guide entry in NAV_ORDER:

Current:
```python
(
    "Developer Guide",
    ["dev/index.md", "development.md", "mcp.md"],
),
```

Updated (insert plugin-guide.md and api-reference.md between development.md and mcp.md):
```python
(
    "Developer Guide",
    ["dev/index.md", "development.md", "plugin-guide.md", "api-reference.md", "mcp.md"],
),
```

---

**docs/llms-full.txt** — Regenerate by running:
```bash
cd /Users/shparki/Documents/Workspace/thatdev/ztlctl && python scripts/gen_llms_full_txt.py
```

This regenerates the file from NAV_ORDER (which now includes plugin-guide.md and api-reference.md). Commit the regenerated file.

Note on api-reference.md: The file contains mkdocstrings `::: module.path` directives, not rendered output. In llms-full.txt it will appear as directive syntax, which is acceptable — the directives convey what the page auto-generates. If this is visually noisy for agents, the directives are self-documenting (`::: ztlctl.plugins.hookspecs`).
  </action>
  <verify>
    <automated>cd /Users/shparki/Documents/Workspace/thatdev/ztlctl && grep "plugin-guide" mkdocs.yml && grep "plugin-guide" docs/dev/index.md && grep "plugin-guide" docs/llms.txt && grep "plugin-guide" scripts/gen_llms_full_txt.py && grep -c "plugin-guide\|api-reference" docs/llms-full.txt</automated>
  </verify>
  <done>
mkdocs.yml Developer Guide nav has 5 entries (dev/index.md, development.md, plugin-guide.md, api-reference.md, mcp.md).
docs/dev/index.md table has 4 rows.
docs/llms.txt Developer Guide section has 4 entries.
scripts/gen_llms_full_txt.py NAV_ORDER Developer Guide list has 5 files.
docs/llms-full.txt is regenerated and includes content from plugin-guide.md and api-reference.md.
`mkdocs build` completes without errors.
  </done>
</task>

</tasks>

<verification>
- `grep -c "ActionRegistry\|ServiceResult\|BaseController" docs/development.md` returns 3+
- `grep "plugin-guide\|Developer Guide" CONTRIBUTING.md` matches both
- `grep "plugin-guide.md\|api-reference.md" mkdocs.yml` matches both
- `grep "Plugin Authoring\|API Reference" docs/dev/index.md` matches both
- `python scripts/gen_llms_full_txt.py && grep -c "plugin-guide\|api-reference" docs/llms-full.txt` returns 2+
- `mkdocs build` exits 0
</verification>

<success_criteria>
docs/development.md contains the complete 4-layer action model and plugin integration point documentation. CONTRIBUTING.md cross-links to the developer guide. mkdocs.yml nav includes all 4 developer guide pages. llms.txt and llms-full.txt include the new pages. `mkdocs build` completes without errors.
</success_criteria>

<output>
After completion, create `.planning/phases/11-developer-guide-api-reference/11-04-SUMMARY.md`
</output>
