obsidian-plan-wiki
Obsidian Spec Wiki
Create and manage specification wikis as Obsidian-compatible markdown. Feature areas capture both what the system does (specs) and how to build it (plans).
Change Tracking (No LWW)
There is no LWW model. Specs, plans, and code are updated intentionally and together.
Required change workflow:
- Open or reference a
tkticket (https://github.com/wedow/ticket). - Update the relevant feature spec/plan.
- Update the code.
- Add a changelog entry via
tinychange. - Link the
tkticket and feature ID in the changelog entry or spec note.
ADRs: Store decisions in docs/reference/decisions/ with Johnny Decimal IDs. Track updates like any other change.
When to Use
- Creating new project specs or documentation
- Working with existing wikis using the open-questions format:
%% πββοΈ ... %%/%% π€ ... %% - User mentions "wiki", "spec", "feature", or "Obsidian"
- Need to document behavior for agent-driven code updates
One-Shot Usage (LLM Quickstart)
When asked to use this skill, follow this sequence in a single pass:
- Read
docs/AGENTS.md(anddocs/handbook/README.mdif present). - Identify the structure:
features/orworkstreams/(treat workstreams as feature areas). - Use Johnny Decimal with two-digit decimals (
NN.NN).- If the human gives you only an ID like
20.01(or2001), treat it as a handbook lookup: locate and read the matching handbook doc and follow it.
- If the human gives you only an ID like
- Apply the open-questions format with
πββοΈ/π€/βand block IDs. - Record changes via
tkandtinychange(merge todocs/changelog.md).
Wiki Discovery
Check for existing wiki in order:
docs/- Primary locationdocs/wiki/- Nested variantwiki/- Root alternative.plans/*/- Legacy support
First match wins. Always use docs/ for new wikis.
Directory Structure
docs/
βββ README.md # Index with feature table (Johnny Decimal)
βββ CLAUDE.md # Symlink β AGENTS.md
βββ AGENTS.md # Actual agent instructions
βββ changelog.md # Keep a Changelog format (generated via tinychange)
βββ handbook/ # Process/tooling docs (Johnny Decimal)
β βββ 10-docs/ # Documentation workflows
β βββ 50-testing/ # Testing workflows and verification
β βββ 80-agent-behaviour/# Agent autonomy and behaviour rules
βββ plans/ # Timestamped design/implementation plans (optional)
β βββ AGENTS.md # Naming/quality rules for plans
βββ postmortems/ # Incident postmortems and learnings
β βββ AGENTS.md # Naming/structure rules for postmortems
βββ reference/ # Architecture + research (Johnny Decimal)
β βββ decisions/ # ADRs (Johnny Decimal IDs)
βββ features/ # OR workstreams/ (treat as feature areas)
β βββ NN-name/ # Johnny Decimal area (10-19, 20-29, ...)
β βββ README.md # Area summary + feature tables
β βββ AGENTS.md # Optional: area-specific agent rules
β βββ NN.NN-spec.md # Feature specs (what)
β βββ NN.NN-plan.md # Implementation plans (how)
βββ research/ # Oracle outputs (frozen)
CLAUDE.md vs AGENTS.md convention:
CLAUDE.md= symlink toAGENTS.md(NOT a file containing@AGENTS.md)AGENTS.md= actual agent instructions and wiki operations
Why symlink? The @filename convention in file contents causes some tools to ignore the file entirely. A symlink ensures CLAUDE.md is always read as the actual AGENTS.md content.
Key concepts:
- Feature areas = Johnny Decimal functional areas (not temporal phases). Treat everything as a feature (product, infra, tooling, docs)
- Specs = behavior documents (what the system does)
- Plans = implementation documents (how to build it)
- Research = Oracle/Delphi outputs (frozen snapshots)
Plan locations (both valid):
- Feature-scoped plans live with the feature:
docs/features/NN-area/NN.NN-*-plan.md - Cross-cutting or timestamped plans live in
docs/plans/YYYY-MM-DD-HHMM-topic.md(recommended when the plan touches many areas/files)
Codebase AGENTS.md (Required)
Every top-level code or source folder must include an AGENTS.md that explains:
- The folder's purpose
- Feature area IDs it implements (link to
docs/features/) - Boundaries (what does NOT belong here)
- Primary entry points and tests
Core Principles
1. Progressive Disclosure
Load only what's needed:
User asks about auth β Read features/10-core/README.md
User asks about login β Read features/10-core/10.01-auth-spec.md
User asks for overview β Read README.md only
Load only what each task requires.
2. Johnny Decimal Structure
Organize features, handbook, and reference docs using Johnny Decimal (johnnydecimal.com).
Hard rules (avoid drift):
- Use two-digit decimals everywhere:
NN.NN(NOTNN.N, NOTNN, NOT01without.01). - Features: folder
docs/features/NN-name/, filesNN.NN-*-spec.mdandNN.NN-*-plan.md. - Handbook: folder
docs/handbook/NN-area/, filesNN.NN-topic.md. - Reference: folder
docs/reference/NN-area/, filesNN.NN-topic.md.
Johnny lookup flow (common):
- If the human says
20.01(or2001) with no other context, interpret it as "open handbook section 20.01". - Locate it by filename prefix (do not guess the topic slug):
docs/handbook/**/20.01-*.md- If multiple matches exist, pick the closest match by area/README context and link to the others.
Example:
docs/features/10-core/
βββ README.md
βββ 10.01-auth-spec.md
βββ 10.01-auth-plan.md
Example handbook/reference naming:
docs/handbook/20-git/
βββ 20.01-methodic-rebase-merge.md
βββ 20.04-post-merge-hygiene.md
docs/reference/01-design/
βββ 01.07-game-design.md
βββ 01.16-ticket-metadata-audit.md
Johnny decimal drift to watch for:
- Feature specs named
10.01but reference docs named01(missing decimals) β fix reference docs to01.NN-*. - Inconsistent padding (
1.01vs01.01) β always pad to 2 digits.
Migration: fixing 01-only reference files:
- Create a
tkticket for the migration (renames touch many links). - Rename files to
NN.NN-topic.md(choose an unused.NNin that area). - Update all Obsidian wiki links (
[[...]]) that referenced the old filename/path. - Add
tinychange -k docsentry for the rename.
Migration rule: If you rename docs for Johnny compliance, update all wiki links, record a tk ticket, and add a tinychange entry (usually docs kind).
Quick audit (optional):
# Find reference/handbook files missing an NN.NN prefix (heuristic)
rg --files docs/reference docs/handbook | rg -v "/[0-9]{2}\.[0-9]{2}-"
# Find feature docs missing an NN.NN prefix (heuristic)
rg --files docs/features | rg -v "/[0-9]{2}\.[0-9]{2}-"
3. Wiki Links Everywhere
All references use [[wiki-links]]. Broken links = sync signal.
[[features/10-core/10.01-auth-spec|Login Flow]]
[[reference/architecture#auth-middleware|Auth Middleware]]
4. Task Tracking with Obsidian Comments
Track open questions using hidden comments with emoji prefixes and block references. Multi-line is allowed if it improves readability.
%% πββοΈ Human question/task %% ^q-scope-descriptor
%% π€ Agent question waiting on human %% ^q-scope-question
%% β
Question here β Answer here %% ^q-scope-resolved
CRITICAL: Separate each question with a blank line. Obsidian treats consecutive lines as a single block; only the last block ID works.
Format components:
πββοΈ= human wrote this β AGENTS SHOULD ACTION/ANSWERπ€= agent wrote this β AGENTS MUST SKIP (waiting for human)β= resolved β no action needed^q-{scope}-{descriptor}= block ID for Obsidian navigation
WHO ANSWERS WHAT:
| Emoji | Who wrote it | Who should answer/action |
|---|---|---|
| πββοΈ | Human | Agent (this is work for you!) |
| π€ | Agent | Human (skip this, you asked it) |
| β | Resolved | No one |
Conversation threading: Questions can have inline replies. The LAST emoji determines whose turn:
%% π€ Should we cache? πββοΈ yes π€ what limit? %% ^q-cache
Last emoji is π€ β Human's turn. When β
β Done.
Block ID convention: ^q-{scope}-{descriptor}
^q-auth-oauth(auth feature, OAuth question)^q-tabs-persist(tabs feature, persistence question)
Workflow:
- Agent adds
π€question β human answers (agent skips these) - Human answers β convert to
πββοΈ(now actionable by agent) orβ(resolved) - Human adds
πββοΈtask β agent should action this - Resolved format:
%% β question β answer %% ^q-id
Linking to questions:
[[features/10-core/10.01-auth-spec#^q-auth-oauth|OAuth question]]
Search in Obsidian: Search for the emoji.
Find via terminal:
rg "πββοΈ" docs/ # human tasks
rg "π€" docs/ # agent questions
rg "β
" docs/ # resolved
rg "%% .*%%$" docs/ # missing block IDs (lines ending with %%)
Agent responsibility: Add block IDs to any question missing one. Generate the ID from the file's feature/spec and the question topic:
%% π€ how to handle OAuth? %% β missing block ID
%% π€ how to handle OAuth? %% ^q-auth-oauth β fixed
5. Changelog Protocol
Update changelog.md via tinychange. Do not hand-edit.
Setup (once):
tinychange init
Add entry (interactive):
tinychange
Add entry (scripted β preferred for agents):
tinychange -I new -k <fix|test|chore|security|feat|docs|refactor|perf> -m "Your change message" -a AUTHOR
Include the tk ticket ID in the message when available (e.g., "t-9cdc: Add feature X").
Merge entries into docs/changelog.md:
tinychange merge
Ensure tinychange.toml points to docs/changelog.md and uses Keep a Changelog format.
6. Task Tracking with tk
All non-trivial work is tracked via tk (https://github.com/wedow/ticket). A tk ticket is the execution-level unit of work.
Small-change exemption (all must be true): one file, 10 lines or fewer (excluding whitespace-only), and docs-only or comment/typo-only changes. Otherwise, create a ticket.
One-liner to create + start + template a ticket:
ID=$(tk create "Short description of work" -t task -p 1 --tags tag1,tag2 -d "Longer description") && tk start $ID && printf '\n## Goal\nWhat outcome must be achieved.\n\n## Acceptance Criteria\n- [ ] Observable completion conditions\n\n## Verification\n- [ ] Commands, checks, or manual steps\n\n## Worktree\n- .\n' >> .tickets/$ID.md
Ticket body template:
## Goal
What outcome must be achieved.
## Scope
What is included.
## Out of Scope
What is explicitly excluded.
## Acceptance Criteria
- [ ] Observable completion conditions.
## Verification
- [ ] Commands, checks, or manual steps.
## Risks
- [ ] Risk and mitigation.
## Related Files
- `path/to/file`
## Links
- [label](url)
## Worktree
- `.` or `.worktrees/the-tree`
Lifecycle:
tk createβtk start <id>β work βtk close <id>before committing- Include ticket IDs in spec/plan headers and in
tinychangemessages tk listto see open tickets,tk list --status closedfor closed
Linking conventions:
- Spec header includes related tk ticket IDs
- tinychange messages include tk ID (e.g.,
t-9cdc: add salvage system)
Templates
Spec File Template
# NN.NN Spec Name
> **Feature Area:** [[../README|NN-Feature-Area-Name]]
> **Feature ID:** NN.NN
> **Ticket:** tk-000 (optional)
## Behavior
### Contract
- **Input:** description
- **Output:** description
- **Preconditions:** what must be true before
- **Postconditions:** what will be true after
### Scenarios
- When X happens β Y should occur
- When edge case β handle gracefully
## Decisions
### Assumptions
1. [Assumption] - [implication if wrong]
2. [Assumption] - [implication if wrong]
### Failure Modes
| Failure | Detection | Recovery |
|---------|-----------|----------|
| [scenario] | [how to detect] | [what to do] |
### ADR-1: Decision Title
- **Status:** Proposed | Accepted | Deprecated | Superseded
- **Context:** Why this decision was needed
- **Decision:** What we decided
- **Consequences:** What happens as a result
- **Alternatives:** What we considered and rejected
### Open Questions
%% π€ Question needing resolution? %% ^q-specname-topic
## Integration
### Dependencies
- [[path/to/spec|Display Name]] - what we need from it
### Consumers
- [[path/to/spec|Display Name]] - what uses us
### Diagram
```mermaid
graph LR
A --> B
B --> C
### Plan File Template
```markdown
# NN.NN Plan Name
> **Feature Area:** [[../README|NN-Feature-Area-Name]]
> **Related Spec:** [[NN.NN-spec-name]] (optional)
> **Ticket:** tk-000 (optional)
## Goal
What this plan achieves.
## Prerequisites
- [ ] Dependency 1
- [ ] Dependency 2
## Implementation Steps
### Phase 1: [Name]
- [ ] Step 1
- [ ] Step 2
### Phase 2: [Name]
- [ ] Step 3
- [ ] Step 4
## Files to Modify
| File | Changes |
|------|---------|
| `path/to/file` | Description of changes |
## Testing Strategy
How to verify the implementation works.
## Risks & Mitigations
| Risk | Mitigation |
|------|------------|
| [What could go wrong] | [How to prevent/handle] |
## Open Questions
%% π€ Implementation question? %% ^q-planname-topic
Bulletproof Plan Guidelines (Agent-Proof)
Plans are executed by agents that take everything literally. Ambiguity causes expensive mistakes. Use these rules to make plans unambiguous and self-checking.
Rule 1: Naming consistency (CRITICAL)
- Pick ONE name for each new type/table/function/file and use it everywhere.
- If you rename during planning, update the entire doc (do not leave old names around).
Rule 2: Migration semantics (CRITICAL)
- For any new thing that overlaps an existing thing, explicitly state one of:
- REPLACES (old is removed)
- EXTENDS (old stays, new adds behavior)
- COEXISTS WITH (both exist; explain selection rules)
Rule 3: State transitions (CRITICAL)
- For every boolean/enum state, document ALL transitions:
- trigger condition
- which system/reducer executes it
- side effects (what else changes)
Rule 4: Ownership (CRITICAL)
- If touching shared state (DB rows, physics-owned state, caches), state WHO OWNS IT and HOW it may be modified.
- Include a guardrail: "NEVER mutate X directly; always go through Y".
Rule 5: Error paths (required)
- List failure conditions and required cleanup/rollback for each.
Rule 6: Concrete file list (required)
- List EVERY file to create/modify/delete.
- For modified files: list the exact functions to change and what changes.
Rule 7: Tests (required)
- Name test cases, describe assertions, and specify file locations.
Rule 8: Danger Dragons (required)
- Add an explicit "how it should NOT work" section listing common mistakes.
- Include the WHY (what breaks / what incident it prevents).
Plan checklist (before execution):
- Terminology section exists and is consistent
- Migration semantics stated for every overlapping construct
- State transition table exists for every state field
- Error paths listed
- File list is complete
- Test cases are named
- Danger Dragons section exists
Suggested plan add-ons (drop into any plan):
## Terminology
- `ThingA`: definition
- `ThingB`: definition
## Migration
- `OldThing` is REPLACED by `NewThing`.
- References to `OldThing` are updated in: `path/a`, `path/b`.
## State Transitions
| From | To | Trigger | Owner/System | Side Effects |
|------|----|---------|--------------|--------------|
| ... | ...| ... | ... | ... |
## Error Paths
| Condition | Detection | Response | Cleanup |
|----------|-----------|----------|---------|
## Danger Dragons (How it should NOT work)
- β Don't do X
- WHY: breaks Y
Feature Area README Template
# NN Feature Area Name
> Brief description of what this feature area covers.
## Goal
What this feature area achieves.
## Specs
| Spec | Description | Status |
|------|-------------|--------|
| [[NN.NN-spec-name]] | Brief description | Status |
| [[NN.NN-spec-name]] | Brief description | Status |
## Plans
| Plan | Description | Status |
|------|-------------|--------|
| [[NN.NN-plan-name]] | Implementation approach | Status |
## Shared Decisions
ADRs that apply to all specs in this feature area:
- **Decision:** Brief summary
## Integration Points
This feature area connects to:
- [[../20-other-area/README|Other Feature Area]] - how
CLAUDE.md Setup (Symlink)
CLAUDE.md should be a symlink to AGENTS.md, not a file with content:
# From within docs/ directory
ln -s AGENTS.md CLAUDE.md
This ensures CLAUDE.md and AGENTS.md always have identical content. All actual instructions go in AGENTS.md.
AGENTS.md Template
Agent instructions belong here:
# Agent Instructions: [Project Name]
[Project-specific rules here...]
## 00.00 Johnny Lookup
If the human gives you simply an ID like `20.01` (or `2001`), treat it as a **handbook call**.
- Locate and read the matching handbook doc: `docs/handbook/**/20.01-*.md`
- Follow the instructions literally.
- If multiple matches exist, list them and pick the most relevant by context.
---
## Wiki Operations
**IMPORTANT:** When working with this wiki, use the `obsidian-plan-wiki` skill if available. It provides the full spec format and workflow patterns.
This documentation uses Obsidian vault format. Follow these patterns.
### Change Tracking (No LWW)
Specs, plans, and code are updated intentionally and together. Track changes via `tk` tickets and `tinychange` entries.
### Ticketing (tk)
All non-trivial work is tracked via `tk` (https://github.com/wedow/ticket).
**Small-change exemption** (all must be true): one file, β€10 lines, docs-only or comment/typo-only. Otherwise, create a ticket.
Oneshot: `ID=$(tk create "Description" -t task -p 1 --tags tag1,tag2 -d "Details") && tk start $ID && printf '\n## Goal\n...\n' >> .tickets/$ID.md`
Lifecycle: `tk create` β `tk start <id>` β work β `tk close <id>` β commit.
Include ticket IDs in spec/plan headers and in `tinychange` messages.
When logging changes: `tinychange -I new -k <fix|feat|docs|refactor|...> -m "t-XXXX: message" -a AUTHOR`
### Progressive Disclosure
**Don't load everything.** Navigate in layers:
1. **Start at feature area README** - `features/NN-name/README.md`
- Understand scope and current status
- See which specs exist
2. **Read specific specs as needed** - `features/NN-name/NN.NN-*-spec.md`
- Load only the spec you're implementing
- Check "Integration" section for related specs
3. **Dive into reference docs for deep context** - `reference/` or `features/NN-name/reference/`
4. **Check research for background** - `research/topic/`
### Johnny Decimal Features
Feature areas use Johnny Decimal IDs with two-digit decimals. Specs/plans use `NN.NN-` prefixes.
### Open Questions System
See [[handbook/10-docs/10.01-open-questions-system]] for full spec.
**WHO ANSWERS WHAT:**
| Emoji | Who wrote it | Who should answer/action |
|-------|--------------|--------------------------|
| πββοΈ | Human | **Agent** (this is work for you!) |
| π€ | Agent | **Human** (skip this, you asked it) |
| β
| Resolved | **No one** |
### Updating Specs
**Before:** Read Assumptions and Failure Modes
**During:** Mark open questions resolved with `β
`, note discoveries
**After:** Update Success Criteria checkboxes, update README status
### Link Format
| Target | Format |
|--------|--------|
| Same directory | `[text](filename.md)` |
| Parent | `[text](../README.md)` |
| Cross-feature area | `[text](../20-name/README.md)` |
Codebase AGENTS.md
Every top-level code or source folder must include an AGENTS.md that explains:
- The folder's purpose
- Feature area IDs it implements (link to
docs/features/) - Boundaries (what does NOT belong here)
- Primary entry points and tests
Recommended AGENTS.md files for docs/ subfolders:
| Path | Content |
|---|---|
docs/reference/AGENTS.md |
Purpose, Johnny Decimal convention, citation rules |
docs/plans/AGENTS.md |
Purpose, naming convention (YYYY-MM-DD-HHMM-topic.md), plan quality rules |
docs/postmortems/AGENTS.md |
Purpose, naming convention, required sections |
docs/handbook/AGENTS.md |
Purpose, Johnny Decimal areas, update rules |
Referencing postmortems from code AGENTS.md:
When a past incident is relevant to a code folder, link the postmortem directly in that folder's AGENTS.md so agents encounter the lesson at the point of danger:
> **Post-mortem:** [[postmortems/YYYY-MM-DD-topic]] β Brief description of what went wrong.
Root README Template
# Project Wiki
> **For Claude:** Start here. Read feature area READMEs for context, then specific specs as needed.
## Feature Areas
| # | Feature Area | Description |
|---|--------------|-------------|
| 10 | [[features/10-name/README\|Name]] | Description |
## Quick Links
- [[AGENTS]] - Rules for agents
- [[changelog]] - What changed and when
- [[handbook/README]] - Process and tooling handbook
- [[reference/architecture]] - System overview
- [[reference/decisions]] - ADRs
## Postmortems
Incident learnings (read these before repeating known mistakes):
- [[postmortems/YYYY-MM-DD-topic]] - Description
## Research
Oracle/Delphi outputs (frozen snapshots):
- [[research/topic]] - Description
Workflow Patterns
Creating a New Wiki
- Create
docs/directory structure - Write README.md with feature area table (Johnny Decimal)
- Create AGENTS.md with actual agent instructions
- Create CLAUDE.md as a symlink:
ln -s AGENTS.md CLAUDE.md - Initialize changelog via
tinychange init - Create feature area folders with README.md
- Create
docs/plans/with AGENTS.md (optional but recommended) - Create
docs/postmortems/with AGENTS.md - Create
docs/handbook/with at least10-docs/and80-agent-behaviour/ - Add specs as needed
Adding a Spec
- Create
NN.NN-spec-name.mdin feature area folder - Add
tkticket in the header if applicable - Fill in Behavior (contract + scenarios)
- Document Decisions (ADRs)
- Map Integration (dependencies + consumers with wiki links)
- Update feature area README table
- Update changelog via CLI
Adding a Plan
- Create
NN.NN-plan-name.mdin feature area folder - Link to related spec if one exists
- Add
tkticket in the header if applicable - Fill in Implementation Steps with checkboxes
- List Files to Modify
- Document Risks & Mitigations
- Update feature area README plans table
- Update changelog via CLI
Research Workflow
When a %% πββοΈ ... %% or %% π€ ... %% comment needs research:
Simple question: Launch oracle agent Complex/uncertain: Use Delphi (3 parallel oracles + synthesis)
Store results in research/, link from spec:
%% β
question β see [[research/topic]] %% ^q-scope-topic
Keeping Specs and Code in Sync
Specs and code are updated together. If you discover drift:
- Open or link a
tkticket. - Decide the intended behavior (document in spec or ADR).
- Update spec/plan and code to match that decision.
- Add a
tinychangeentry.
Updating Specs During Implementation
Before: Read the spec's Assumptions and Failure Modes.
During implementation:
- Add implementation notes to the spec
- Mark open questions as resolved:
%% β Decided β [outcome] %% - Note any discovered failure modes
After completing:
- Update Success Criteria checkboxes
- Add commit hash if significant
- Update feature area README status if needed
Link Format
Use relative markdown links (Obsidian-compatible):
| Target | Link Format |
|---|---|
| Same directory | [text](filename.md) |
| Parent directory | [text](../README.md) |
| Subdirectory | [text](reference/file.md) |
| Cross-feature area | [text](../20-context-menu/README.md) |
| Heading anchor | [text](file.md#section-name) |
When to Create New Documentation
| Situation | Action |
|---|---|
| New feature area | Create new feature area directory |
| New behavior to document | Create numbered spec file (NN.NN-spec.md) |
| New implementation approach | Create numbered plan file (NN.NN-plan.md) |
| Deep technical topic | Add to reference/ subdirectory |
| Research question | Use Oracle, save to research/ |
| Feature-area-specific rules | Create AGENTS.md in feature area |
| New code/source folder | Create AGENTS.md in that folder |
| Agent mistake or system failure | Create postmortem in postmortems/ |
| Recurring agent situation | Create handler in handbook/80-agent-behaviour/ |
| Spec drifted from code | Run spec divergence audit |
| Tickets drifted from reality | Run ticket divergence audit |
Best Practices
- Specs describe behavior - What it does (contract, scenarios)
- Plans describe implementation - How to build it (steps, files, risks)
- All references are wiki links - Broken links signal sync issues
- Update changelog via CLI immediately - Don't hand-edit
- One spec per feature/component - Keep focused
- Research before deciding - Use oracles for uncertain questions
- Optional AGENTS.md per feature area - For scoped agent rules
- CLAUDE.md is a symlink - Points to AGENTS.md via symlink
Postmortems
When things go wrong β agent mistakes, system failures, expensive debugging loops β capture the incident so future sessions don't repeat it.
Location and Naming
docs/postmortems/
βββ AGENTS.md # Rules for this directory
βββ YYYY-MM-DD-HHMM-topic.md # Individual postmortems
Naming: YYYY-MM-DD-HHMM-topic.md (24h time, local). Example: 2026-02-01-0957-ts-refactor.md
Postmortem AGENTS.md
# Agent Instructions: docs/postmortems
Purpose: incident postmortems and learnings.
Naming:
- `YYYY-MM-DD-HHMM-topic.md` (24h time, local).
Rules:
- Follow `/AGENTS.md` and `docs/AGENTS.md`.
- Include a `tk` ticket ID in the header when available.
- Cover summary, timeline, root cause, fix, and prevention.
Postmortem Template
# Post Mortem: [Title] ([Date])
## What Was Requested
What was the intended outcome.
## What Actually Happened
### Phase 1: [Name] (Good/Bad)
Chronological narrative of what occurred.
### Phase N: [Name]
Continue phases as needed.
## Root Causes
### 1. [Root Cause Title]
Explain the root cause with specifics. Include code examples showing the wrong vs right approach.
## Cost
- Compute/time spent
- Work lost or reverted
- Impact on schedule
## Lessons
1. **[Lesson title]** - Specific, actionable takeaway
2. **[Lesson title]** - Another takeaway
## Prevention
What changes to process, tooling, or rules prevent recurrence.
When to Write a Postmortem
- Agent destroyed work through incorrect cleanup (deletion, revert)
- Agent bypassed existing systems (duplicated instead of reusing)
- Expensive debugging loop (>30 minutes on something avoidable)
- Feature shipped broken because verification was skipped
- Parallel agent coordination failure
Referencing Postmortems
Link postmortems from the relevant AGENTS.md or spec to ensure agents encounter the lesson at the point of danger:
## SpacetimeDB: Search Before You Implement (CRITICAL)
> **Post-mortem:** [[postmortems/2026-01-30-2352-npc-brain-velocity-bypass]] β Agent skipped codebase exploration, directly mutated velocity, broke physics.
Agent Behaviour Rules
Define explicit behaviour expectations in the handbook. These prevent agents from defaulting to passive, task-following mode when autonomous work is needed.
Location
docs/handbook/80-agent-behaviour/
βββ 80.01-autonomous-work.md
βββ 80.02-document-feature.md
βββ 80.03-stale-trees.md # (or other operational handlers)
What Goes Here
Agent behaviour docs are short, direct instructions for recurring situations. They tell agents what to do without waiting for human direction.
| Doc | Purpose | Example Content |
|---|---|---|
80.01-autonomous-work.md |
Set expectations for initiative | "Don't wait for permission to proceed to the next step. Complete the full unit of work." |
80.02-document-feature.md |
Handler: "document this" | "Document the feature in docs/, include all implementation details, ensure nothing is out of date." |
80.03-stale-trees.md |
Handler: worktree cleanup | "Walk through all worktrees, identify stale/unmerged/active branches, report status." |
Writing Effective Agent Behaviour Docs
- Be direct. These are orders, not suggestions.
- One handler per file. Each doc covers one situation.
- Include the trigger. What situation activates this instruction?
- Include the expected output. What should the agent deliver?
- Keep them short. 1-10 lines. If it's longer, it's a handbook entry, not a behaviour rule.
Example: Autonomous Work
## Autonomous
Complete the full unit of work. Do not stop at 60% because it's slow or hard.
Do not present partial results and ask if you should continue β finish the job.
Example: Document Feature Handler
Document this work/feature in `docs/` in `main`. Document it for other agents
as specifically as possible β include as many details as possible. Make sure
existing docs are not out of date.
Spec and Ticket Divergence Audits
Over time, specs drift from code and tickets drift from reality. Detect and fix this.
Spec Divergence Audit
Trigger: Human requests audit, or on a regular cadence (e.g., end of cycle).
Process:
- Use subtask agents to explore divergence between specs in
docs/features/and the actual codebase. - For each spec, check: does the code match the documented behavior?
- If code has moved beyond the spec β update spec.
- If spec describes behavior not yet implemented β note as planned.
- If spec and code contradict β flag for human decision.
Agent instruction file:
# docs/handbook/15-planning/15.02-spec-divergence.md
## Instructions:
- Use subtask agents to explore the current state of divergence between spec and codebase.
Ticket Divergence Audit
Trigger: Human requests audit, or ticket count gets unwieldy.
Process:
- Use subtask agents to explore the current state of tickets (
openandin_progress) vs what is in the codebase. - If code shows work done but ticket is open β
tk close <ticket-id>. - If code is in progress β mark ticket as
in_progresswith a note. - If ticket is indecipherable β mark
closed.
Agent instruction file:
# docs/handbook/15-planning/15.02-ticket-divergence.md
## Instructions:
- Use subtask agents to explore the current state of tickets `open` and `in-progress` vs what is in the codebase.
- If code shows work done but ticket is open β `tk close <ticket-id>`
- If code is in progress β mark ticket as `in-progress` with a note
- If ticket is indecipherable β mark `closed`
Video-Based NHITL Testing
When E2E tests check state labels but not actual behaviors, combine video recording with visual analysis for true verification.
The Problem
A test can "pass" while the feature is broken. State assertions (action === 'Engage') don't verify behavior (projectiles fired, damage dealt).
The Solution: Visual Verification Loop
1. Run E2E test with video recording enabled
2. Test completes (pass or fail)
3. Extract frames from test-results/*.webm using video-explorer skill
4. Agent analyzes frames visually:
- "Frame 00:03: Label shows 'Engage'"
- "Frame 00:03-00:08: No projectiles visible"
- "Diagnosis: State set but action not triggering"
5. Fix the actual issue (not just make the test pass)
6. Re-run and verify visually
Configuration
Enable video recording in your E2E test config:
// e2e/playwright.config.ts (or equivalent)
use: {
video: 'on', // Record ALL tests, not just failures
}
Video Analysis Commands (video-explorer)
# Overview of test video
videx overview test-results/<test-name>/video.webm 1 480
# Zoom into specific moment
videx range test-results/<test-name>/video.webm 0:03-0:08 --fps=5
# Single frame detail
videx zoom test-results/<test-name>/video.webm 0:05
What to Look For
Build a lookup table for your domain:
| Behavior | Visual Indicator |
|---|---|
| Action triggered | Expected visual effect appears |
| Entity moving | Position changes across frames |
| State change | UI element updates |
| Damage/health | Progress bar changes |
Handbook Entry Template
# NN.NN Video-Based NHITL Testing
## Problem
E2E tests check state labels but not actual behaviors.
## Solution: Visual Verification Loop
[Flow diagram as above]
## Configuration
[Test config snippet]
## What to Look For
[Domain-specific visual indicator table]
Benefits
- True behavior verification β see what actually happens, not just state changes
- NHITL debugging β agent watches the video, finds problems autonomously
- Evidence-based fixes β know exactly what's broken before coding
- Regression detection β visual diff between expected and actual behavior
Refactors: Create + Wire + Delete + Run
Refactoring is replacement, not duplication. A refactor unit of work is not complete until the new code is imported/used, the old code is deleted, and the system is verified by running.
The Unit of Work (Non-Negotiable)
For any extraction/move:
- Create the new file/location (if needed)
- Move the implementation
- Update ALL consumers to import/use the new location (wire it)
- Delete the old implementation
- Verify (typecheck/tests/run) BEFORE moving on
βNot Importedβ Protocol
- New code with 0 incoming imports is unfinished work, not dead code.
- The response is to wire it in, not delete it.
Quick check (heuristic):
# For a new file name, verify at least one incoming import exists
rg "from .*<module>" docs/ src/ || true
Parallelization Rule
- If B depends on A (B imports A), B cannot be done in parallel with A.
- Prefer sequential refactor steps; parallelize only truly independent modules.
Refactor Verification (Minimum)
- Typecheck/lint/tests as applicable
- Run the app/system and verify the user-facing behavior (not only compilation)
- If you canβt run it, record that explicitly in the ticket Verification section
Session Handoff (When Refactor Spans Sessions)
Write a short handoff note in the ticket or a plan file:
- What was created
- What was wired
- What is NOT wired yet (do not delete)
- Next steps