wiki-knowledge

Two deployment modes, resolved by a fixed vault-root order

The plugin supports two deployment modes rather than picking one: dedicated (installed project-scope inside the vault; launch Claude Code from the vault root) and query-from-anywhere (installed user-scope so its skills/agents are available in any repo, with $WIKI_ROOT pointing at the vault). Both are real use cases — querying the wiki from inside an unrelated code repo is a first-class scenario, not an edge case — so vault.py’s resolve_vault_root() (wiki-plugin/scripts/vault.py) checks, in order: $WIKI_ROOT (wins always) → the nearest ancestor of cwd containing a vault marker (wiki/ or .wiki-root) → cwd itself. Never hard-code a path; every script resolves the root through this one function.

The session root — the project a host session’s state belongs to, which is never the vault in query-from-anywhere mode — is a second root resolution, and deliberately a different order: ADR-0025 pins it as a per-host env override → the nearest ancestor carrying that host’s marker (.claude/, .opencode/) → stop at $HOME and return “no project”, with no cwd fallback. Same first two levels, opposite terminal rule: the vault root’s cwd fallback is what lets a command answer “which vault” from anywhere, while a session-state writer that fell back would create a state tree wherever the caller stood (#485).

Consequences

Vault-root resolution and plugin loading are separate problems that must both be satisfied: a project-scope skills-dir plugin loads only from the launch directory’s .claude/skills/ and does not walk up, so dedicated mode requires launching from the vault root, and query-from-anywhere requires installing the plugin user-scope — setting $WIKI_ROOT alone does not make a project-scope install visible from another directory. A /reload-plugins is needed after cd for project-scope installs.

Vault-root resolution and script-path resolution are a third, separate problem (#22): vault.py resolves where the vault’s data lives, but the plugin’s own scripts/ directory isn’t necessarily reachable from cwd at all in query-from-anywhere mode — the vault has no scripts/ of its own. Skill and agent markdown invoke the bundled scripts via the ${CLAUDE_PLUGIN_ROOT} placeholder (a documented Claude Code mechanism substituted into skill/agent content before Claude reads it, not a shell environment variable — it must be written literally in the markdown, e.g. python "${CLAUDE_PLUGIN_ROOT}/scripts/normalize_raw.py", rather than relied upon via shell expansion), which resolves identically regardless of deployment mode or cwd.