Wookie is a local, Markdown, LLM-first project wiki and an agent-to-agent coordination layer. One Rust binary owns the storage format, linking rules, project resolution, session lifecycle, and Git history, so every agent working on a project sees the same knowledge and can announce work that may affect the others.
Wikis live outside the project checkout under ~/.wookie/. Nothing is added to
the repository being documented.
cargo install --path .
cd /path/to/project
wookie init
wookie prime --query "understand the architecture"
wookie read index --expandInstall guidance for the agents you use:
wookie plugin install claude
wookie plugin install codex
wookie plugin status --strictStart a coordination session and keep its id in the environment:
export WOOKIE_SESSION="$(wookie session start --agent codex --id-only)"
wookie notificationsFor a non-trivial implementation, create a checked, guide-linked plan and open its live board:
wookie plan guide --query "redesign retry exhaustion handling"
# Use the host's native plan mode to author and save plan.toml.
wookie plan check plan.toml
wookie plan attach plan.toml
wookie planAgents move segments through the fixed todo, doing, blocked, and done
states with wookie plan update, record meaningful context with wookie plan log, then use wookie plan archive to preserve the completed record and close
the session.
To use Linear as the external epic view, wookie plan linear export produces a
deterministic Project-and-issues manifest. An agent creates those records
through Linear MCP, persists their complete mapping with plan linear link,
and uses plan linear reconcile to preview or confirm semantic status
alignment. Wookie stores no Linear credential and performs no hidden network
write.
After meaningful work, publish enough metadata for another agent to judge its relevance without opening the full notice:
printf '%s\n' 'Retry callers must now handle the terminal state.' | \
wookie notify \
--summary "Changed retry exhaustion behavior" \
--kind code-change \
--importance high \
--paths src/retry.rs,tests/retry.rsnotify, notifications, notification read, and notification dismiss use
WOOKIE_SESSION when --session is omitted.
wookie init registers the current project. After that, commands resolve a
wiki from the current directory; linked Git worktrees resolve to the main
checkout's wiki, and --wiki <slug> selects one explicitly from anywhere.
Independent clones remain independent unless both roots are registered.
Each wiki is its own Git repository. Mutations auto-commit by default. Focused
operations stage only the paths they own, and a per-wiki lock serializes the
complete git add plus git commit transaction across concurrent processes.
~/.wookie/
config.toml global registry and defaults
my-project/
wookie.toml roots and sparse per-wiki overrides
.gitignore
.history.lock/ transient Git transaction lock (ignored)
.publish.lock/ shared writer/publisher lock (ignored)
.publish-journal.json interrupted publish recovery (ignored)
.unlocks/ per-section rules state (ignored)
.cache/retrieval-v1.json disposable retrieval parse index (ignored)
protocols/ project-scoped Markdown page scaffolds
findings/finding.md
pages/
architecture/overview.md
code/src/scheduler.md
workflow/checks.md
sessions/
session-20260721-143052-7f3a/
session.toml immutable base session record
plan.toml immutable attached plan, when present
archive.md immutable derived final plan record
activity/ append-only status/heartbeat events
activity-....toml
notifications/ append-only Markdown notices
notify-....md
inbox/ receiver-local acknowledgements (ignored)
notify-....read
notify-....dismissed
inbox.toml legacy read state, if present (ignored)
WOOKIE_HOME overrides ~/.wookie, which is useful for isolated automation
and tests. Home-directory discovery supports the usual Unix and Windows
environment variables.
Wookie separates mechanical work from judgment:
- The binary owns page format, links, sections, locking, indexing, storage, and deterministic worklists.
- The invoking LLM decides what matters, writes useful summaries, fills documentation, and executes critique or ingest instructions.
- Descriptive knowledge stays on demand. Normative rules are locked and checkable. A small pinned set is included in every context prime.
Pages are Markdown with tool-owned frontmatter, a standalone first-paragraph
summary, and [[wikilinks]]. Links inside code spans and fences are ignored.
Broken links are an intentional growth mechanism: wookie expand creates
every eligible stub, then prints a bounded worklist for filling them. The
default limit and token budget inherit retrieval.search_limit and
retrieval.search_tokens; --limit and --tokens override only the response,
never stub creation. Omission totals and a continuation command keep every
stub reachable. Use wookie expand --all only when an exhaustive current
worklist is intentional. Unknown frontmatter fields round-trip unchanged.
Every page can be filed in a top-level section declared in wookie.toml. With
no custom section table, these defaults apply:
| Section | Kind | Purpose |
|---|---|---|
architecture/ |
info | Structure, boundaries, subsystem interactions |
code/ |
info | Module reference seeded by ingest |
decisions/ |
info | Why the system works this way |
guides/ |
info | Build, test, release, and debug procedures |
findings/ |
info | Audit findings, remediation, verification evidence |
style/ |
rules | Code style and review conventions |
workflow/ |
rules | Commit, branch, PR, review, and release process |
Rules sections are locked by default. Writes, deletes, moves, and stub creation
cannot change them until wookie unlock <section> opens a short window. Agents
must obtain explicit user permission first; MCP additionally requires
user_approved: true. Each rules section should have a checks page.
wookie critique assembles the changed files, checks pages, rules, and an
output contract for the invoking agent to execute. Its default is a bounded
map with exact wookie read <id> continuations; --all explicitly includes
complete normative bodies. Configure the default ceiling with
audit.critique_tokens or override one run with --tokens.
The lock also covers indirect mutations: a move that would rewrite a backlink
inside a locked rules page fails before the move starts, and doctor --fix
does not repair a locked rules page.
wookie ingest --level quick|standard|deep inventories a project, seeds code
stubs, and emits a documentation worklist. Once that work is actually done,
rerun ingest and use its exact receipt-bound data.mark_command;
--mark-reconciled (alias: --mark) never performs a blind HEAD write. It
rejects a changed worklist, wiki, policy, or target commit and requires the
audit error gate to pass before recording the project commit. Worklist display
is bounded by default (--limit, --tokens); --all is the explicit
exhaustive opt-in, while every receipt always covers the complete worklist.
An ambiguous metadata commit blocks further mutations until the operator runs
wookie ingest --recover accept|rollback. Rollback restores the recorded
pre-mark config; when the exact mark commit already landed, it preserves
history by appending a verified compensating config-only commit. Interrupted
recovery can be retried safely.
Later runs map code changes to pages through each page's sources frontmatter
and return confidence-ranked reconciliation worklists in JSON.
wookie prime --query "the actual task" is the normal task-start command. Its
complete output has a configured token ceiling and contains standing
instructions, section summaries, ranked page suggestions, selection reasons,
telemetry, and a continuation cursor. wookie search is ranked and bounded by
default. context remains the exhaustive catalog; search --all visits every
matching page without a response budget while retaining at most five matching
body lines per page.
Prime returns a query-independent state_hash for --since deltas and a
query/options/state context_hash for cursor binding. Reusing a state hash
with a new task omits unchanged section structure but still returns standing
instructions and freshly ranked suggestions.
Pins are instruction (concise normative content), summary (the standalone
first paragraph), or discoverable (metadata plus an explicit wookie read
command, never inline content). Legacy pin: true behaves as an instruction
pin. If an instruction page contains ## Agent instructions, prime extracts
that section instead of its rationale. Standing pins must contain real,
non-stub text. An oversized instruction set fails visibly; standing rules are
never silently truncated.
Protocols are inert Markdown templates stored under the wiki's protocols/
directory. They support fixed id, title, and date substitutions—no hooks,
dependencies, or executable code. Discover them with wookie protocol list
and create a page with wookie new <id> --protocol <name>.
Findings use ordinary pages, source metadata, links, and controlled tags such
as finding, severity/high, and status/open. The built-in
findings/finding protocol keeps this workflow extensible without a second
database.
wookie publish --check validates a strict multi-page manifest and returns a
compact plan, changed-line excerpts, provenance errors, link/orphan effects,
and applicable rules within publish.output_tokens (4,000 by default). Use
--tokens <n> for a one-off bound or explicitly opt into exhaustive page
images with --full-diff. The preview's review_token can be supplied to
--apply --expect-plan <token> to reject any manifest, catalog,
configuration, policy, revision, or plan drift.
--apply revalidates after taking the shared mutation lock, journals exact
before/after images plus the full catalog, configuration, effective policy,
and lock-control state, writes the complete plan, and creates one path-scoped
history unit from the recorded pre-finalizer HEAD. Dirty target paths, no-op
plans, and rendered pages over the canonical 16 MiB limit are rejected.
Ordinary failures roll back content, metadata, permissions, and Git index
state; unrelated hook mutations or ambiguous history retain the journal and
require explicit --recover rollback or --recover accept. Rules use
rules propose, review, and explicitly approved apply; review creates a
cryptographic receipt, and only that exact revalidated plan is authorized
inside the transaction without opening a section-wide unlock window.
wookie status is the compact operator dashboard. doctor, critique,
expand, and ingest expose stable wookie.report/v1 JSON for CI; provenance
checks can validate page sources against an explicit project revision.
wookie plan is a deliberately small planning layer over existing pages and
sessions. wookie plan guide --query "$TASK" gives an agent the strict
wookie.plan/v1 TOML contract before a non-trivial plan is written. The agent
uses its host's native planning mode when available—Codex Plan mode, Claude's
planning workflow, or the equivalent—to author and review that artifact;
Wookie does not replace the host planner. Every segment carries a
justification, architectural decisions, verification, dependencies, and an
existing non-stub Wookie guide page. plan check validates the definition
without changing the wiki; plan attach stores it immutably in the active
session. Retrying the identical canonical attachment is idempotent; attaching
a different replacement is rejected.
The bare wookie plan command serves a short-lived read-only board on
127.0.0.1, using an ephemeral port by default. Version 1 has no LAN/public
bind option. It shows the fixed todo, doing, blocked, and done columns,
animates recorded transitions, and exposes card detail plus the session
timeline. There is no drag-and-drop write path: agents use plan update and
plan log, which append typed activity events. The board can show only
Wookie-recorded activity, not private model reasoning or arbitrary shell/editor
actions.
An optional Linear bridge maps the plan to one Linear Project and each segment to one issue. It remains agent-mediated: Wookie exports, validates, links, and reconciles semantic state while Linear MCP performs provider reads and writes. The board shows the persisted epic and issue links. There is no background sync daemon or embedded Linear credential.
wookie plan archive requires every segment to be done unless
--allow-incomplete is explicit. The final typed event records counts and
receipt hashes and closes the session; a deterministic immutable archive.md
makes the final record easy to read. The attached plan, archive, and activity
remain under normal session retention until an applied prune removes the
session. Their Git retention depends on wiki auto-commit and
history.commit_sessions. See Live plans for the schema,
complete workflow, JSON/MCP usage, and local-server security model.
Sessions are project-scoped identities named
session-<UTC-date>-<UTC-time>-<unique-id>. The base session.toml stays
immutable; heartbeats, closes, and debounced command activity are separate
append-only events. This avoids shared-file lost updates when agents work in
parallel.
Notifications are immutable Markdown records with TOML metadata:
- source session, one-line summary, kind, importance, timestamp, and affected paths;
- optional receiving session ids (
--to), routing metadata, and a retry-safe idempotency key; - optional Git branch, commit, worktree, and dirty paths, attached by default;
- an optional Markdown body that ordinary polling does not load.
Polling scans and validates bounded TOML frontmatter for every retained notice, then returns compact metadata. Bodies are loaded only for a direct read, an idempotent-publish comparison, or a text filter whose query did not already match the summary.
An empty target list is a broadcast. Normal polling routes a targeted notice only to the named active sessions; targeting is not confidentiality or an authorization boundary for users who can access the local wiki files. A source cannot target itself. Reusing an idempotency key in one source session returns the original notification when the payload matches and fails if it differs.
Each receiver acknowledges a notice by creating one .read or .dismissed
marker. These files are local and Git-ignored, so concurrent acknowledgements
cannot overwrite one another or pollute durable history. The legacy shared
inbox.toml format remains readable.
New sessions default to a zero-hour lookback, so old notifications do not flood
their unread queue. Configure or override the lookback when history matters;
notifications --all explicitly includes acknowledged and pre-session
history. Polling can filter by source, kind, minimum importance, path prefix,
branch, metadata, timestamps, age, and text, then bound and order the results.
Malformed notification metadata and malformed session entries are reported as
warnings during collection scans while valid entries continue to work. A
direct operation on a corrupt session or notice fails; body-only corruption is
discovered only when an operation loads that body. session list can find
stale sessions, and session prune previews its exact deletion set unless
--apply is passed. It prunes closed sessions by default and supports
age/cutoff and keep-latest guards.
Delivery is cooperative polling, not push. Installed guidance checks after session start, before overlapping edits, after substantial work, and before commit or handoff.
Configuration has two layers:
~/.wookie/config.tomlholds the wiki registry and complete global defaults.<wiki>/wookie.tomlholds project roots plus sparse per-wiki overrides.
Per-wiki sessions.*, history.*, retrieval.*, audit.*, and publish.*
fields are optional individually. Setting one does not freeze the rest:
omitted fields continue to inherit future global default changes.
Configuration is typed, rejects unknown fields, and is validated before it is
written.
wookie config keys
wookie config show --effective
wookie config get sessions.poll_limit --effective
wookie config set sessions.poll_limit 50
wookie config set audit.critique_tokens 6000
wookie config unset sessions.poll_limit
wookie config set --global defaults.sessions.poll_limit 50
wookie config show --global--string prevents TOML parsing for a literal string. Registry keys and ingest
state have dedicated lifecycle commands and cannot be changed through generic
configuration. Because sections.* can change rules and their locks, those
edits require --user-approved after explicit approval.
Retrieval configuration controls prime/search budgets, limits, excerpt size,
and per-section diversity. Retrieval token budgets have an immutable
1,000,000-token ceiling, and result/per-section limits cannot exceed 1,000.
Audit configuration controls source provenance and
the compact critique token ceiling;
publish configuration controls base-revision enforcement, orphan policy, and
the normal check/review output budget.
Session configuration controls feature enablement, lookback, stale and
retention windows, pruning, polling limits, payload limits, Git context,
heartbeats, and default kind/importance. History configuration controls lock
timeouts, stale-lock recovery, whether session operations are committed, and
whether a Git history error warns or fails the command. auto_commit can be
set globally or per wiki.
All managed paths are checked below the real wiki directory. Existing path
components may not be symlinks, so a symlink under pages/, protocols/, or sessions/
cannot redirect a read, write, delete, or prune outside the wiki. Page ids and
wiki slugs reject traversal and absolute paths.
Mutable files use same-directory atomic replacement. Unix uses rename;
Windows uses replace-existing MoveFileExW, preserving the cross-platform
atomic-write contract. Immutable session records are fully written and synced
before atomic no-replace publication (a hard link on Unix and rename on
Windows), so readers never observe partial records. Page
moves preflight every backlink, keep both ids resolvable while rewriting, and
roll back completed rewrites on failure; if rollback itself is incomplete,
both page ids are retained and the error explains the state.
Git history uses a transient lock directory with an atomic owner marker plus
configurable wait and stale thresholds. Age alone never steals a valid lock:
reclamation also requires the
recorded owner process to be gone, and ownership is rechecked before removal.
Path-scoped commits keep concurrent commands from accidentally staging or
labelling each other's changes. History failures warn by default and can be
made fatal with history.fail_on_commit_error.
wookie init [slug] create and register a wiki
wookie list list wikis
wookie prime --query "..." bounded task-aware startup map
wookie context exhaustive page catalog
wookie toc list every page by section
wookie read <id> [--expand[=N]] read a page and linked summaries
wookie new / write / rm / mv page lifecycle
wookie expand [<id>] [--limit N] create all stubs; bound only the worklist
wookie expand [<id>] --all explicitly list every current stub
wookie search / links bounded retrieval and graph relationships
wookie ingest [--level L] emit a bounded receipt-bound worklist
wookie ingest --mark --expect-worklist SHA256 record a validated sync point
wookie critique [--revision REV] bounded rules-review map (use --all for full bodies)
wookie doctor [--fix|--strict] check or repair wiki health
wookie status [--strict] compact wiki health dashboard
wookie protocol list|show|write project-scoped page scaffolds
wookie publish [--check|--apply] transactional multi-page publication
wookie rules propose|review|apply explicitly approved rules workflow
wookie unlock / lock approved rules-section write window
wookie session start|list|show session lifecycle and discovery
wookie session heartbeat|close append activity/status events
wookie session prune preview or apply retention cleanup
wookie plan guide|check|attach author and attach a validated plan
wookie plan [--port N|--no-open] open the read-only localhost board
wookie plan show|update|log|archive inspect, progress, and finish a plan
wookie plan linear export|link|reconcile
bridge a plan to Linear through MCP
wookie notify publish a notification
wookie notifications poll and filter compact metadata
wookie notification read|dismiss acknowledge one notification
wookie config show|get|set|unset|keys inspect or edit typed configuration
wookie roots edit registered project roots
wookie rename-wiki / remove-wiki wiki lifecycle
wookie obsidian [--print] open pages as an Obsidian vault
wookie plugin install|status manage agent guidance
wookie serve MCP server over stdio
Use --json for machine-readable CLI output. Use wookie <command> --help
for every flag and filter.
wookie serve implements newline-delimited JSON-RPC 2.0 over stdio. Its tools
mirror page, wiki, plan, session, notification, critique, doctor, ingest, lock,
and configuration operations. Tools that resolve a wiki accept optional
wiki and cwd fields. Plan agents use plan_guide, plan_check,
plan_attach, plan_snapshot, plan_update, plan_log,
plan_linear_export, plan_linear_link, plan_linear_reconcile, and
plan_archive;
the interactive browser launcher remains a local CLI operation.
claude mcp add wookie -- wookie serveSuccessful tool calls expose JSON objects once through object-valued
structuredContent; content carries only a short pointer so large bounded
prime, search, and publish results do not consume the model context twice.
Human-only results remain unchanged in content. Failed calls set
isError: true and retain a readable diagnostic.
Both integrations are generated from templates/guidance.md:
- Claude Code:
~/.claude/skills/wookie/SKILL.md - Codex: a managed
<!-- wookie:start/end -->block in~/.codex/AGENTS.md
The generated content carries the Wookie package version. wookie plugin status [claude|codex] reports each integration as current, stale, or
missing; --strict exits nonzero unless every selected integration is
current. Re-run plugin install after upgrading Wookie.
- Guide index
- Live plans
- Session lifecycle
- Publishing notifications
- Inbox polling and triage
- Agent and MCP coordination
- Session maintenance and pruning
- Configuration reference
- Storage, safety, and concurrency
- Bounded retrieval
- Page protocols
- Transactional publishing
- Audit and CI
- Rules and findings
- Build and self-host the documentation
The guides form a searchable static mdBook. Preview them locally:
cargo install mdbook --version 0.5.3 --locked
mdbook serve --hostname 127.0.0.1Or build and run the included unprivileged, read-only container:
docker compose -f compose.docs.yml up --build -d --waitThe site is available at http://localhost:8080. It contains product
documentation only and never mounts or exposes live data from ~/.wookie.
See the self-hosting guide for static deployment,
reverse-proxy, update, and security guidance.
cargo fmt --all -- --check
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo test --locked --all-targets --all-features
mdbook buildGitHub Actions runs format and Clippy checks on Linux and the full test suite on Linux, macOS, and Windows. It also builds and boots the documentation container, checks representative routes, and validates its health endpoint. See SPEC.md for the precise model and invariants.