Skip to content

v0.10.0 — Wiki Keeper compounding loop + permission management rebuild

Choose a tag to compare

@denberek denberek released this 27 Apr 03:05

Changelog

0.10.0 — 2026-04-26

Wiki Keeper grows from a nightly batch ingester into a self-maintaining knowledge base in the Karpathy "LLM wiki" sense — and the underlying permission system is rebuilt so UI edits actually reach the spawned Claude process.

Wiki Keeper — compounding loop

  • New skill: wiki-refresh. Regenerates a stable, fenced ## Summary block at the top of every topic page whose claim history has grown. Bounded by its own max_tokens_per_refresh budget. Idempotent.
  • End-of-ingest refresh phase. wiki-ingest tracks every page it touched and chains wiki-refresh at the end of each run. Topic pages stop growing into 200-line changelogs without a synthesis on top.
  • Q&A compounding (Karpathy's central pattern). file_substantive_answers now defaults to on. Substantive wiki-query answers file as both a synthesis page AND dated bullets on each cited topic page. Every meaningful question leaves a per-topic trace, not just a sidecar synthesis.
  • Provenance footer on every answer. Citations carry the summary_refreshed/mtime of each cited page so readers see staleness.

Wiki Keeper — integrity

  • Bidirectional cross-link check in wiki-lint: flags edges where A→B exists in summary/prose but B has no mention of A.
  • Dedup proposals: title-similarity (Levenshtein) + co-citation overlap; never auto-merges.
  • Stale-summary detection in lint: pages whose summary_refreshed is missing or older than summary_stale_days get chained to wiki-refresh automatically.
  • Hash-based watched-mode idempotency: SHA-1 of normalized content. Skips re-processing files whose mtime moved without content change (defends against iCloud / Obsidian Sync touch-without-edit).
  • Failed-source quarantine: inbox files that fail ingest 3 times in a row move to _sources/failed/ with a sidecar .error.md instead of being retried forever.
  • Source-type tags on every dated bullet: [doc], [meeting], [email], [note], [web], [synthesis], [other]. Helps query weight evidence quality.
  • Index sub-MOC awareness: when topics root exceeds index_split_threshold (default 100) or any single type exceeds 30 pages, ingest writes per-type sub-MOCs instead of one flat alphabetical list.
  • Syntheses exempt from orphan flagging if they have outbound links to topic pages they cite.

Wiki Keeper — dashboard

  • New "Wiki Keepers" main nav page. Per-instance card showing scope, log shortcut, and the latest ## Lint YYYY-MM-DD block parsed from log.md. Needs review items render as actionable cards with Dismiss.
  • Settings → Wiki Keeper edit form now exposes max_tokens_per_refresh, index_split_threshold, summary_stale_days, and dedup_similarity_threshold.

Wiki Keeper — schema additions

Topic-page frontmatter gains summary_refreshed: <ISO> and claims_at_refresh: <int>. The auto-managed summary block lives between <!-- wiki-keeper:summary:begin --> and <!-- wiki-keeper:summary:end --> markers — wiki-refresh is the only writer; ## Claims history and user-authored prose elsewhere on the page are untouched.

Permission management — full rebuild

The permission system had silent drift: UI edits wrote allowed_tools/blocked_tools to config.md frontmatter, but the runtime ignored those fields and read permissions.json exclusively. Wiki Keeper Edit → Save was effectively a no-op for permissions, and ChatSessions silently dropped allow/deny rules entirely.

  • Single source of truth. permissions.json is the canonical surface for allow/deny on folder agents. Flat agents get a <name>.permissions.json sidecar — they previously had no allow/deny support at all.
  • Vestigial fields removed. agent.allowedTools / agent.blockedTools deleted from the type. config.md no longer carries allowed_tools / blocked_tools. Migration on read picks up legacy values; saving once rewrites them to the canonical surface.
  • Wiki Keeper canonical permissions. New ensureWikiKeeperPermissions helper merges the canonical allow (Read, Write, Edit, Glob, Grep, Bash(mv *), Bash(mkdir *)) and canonical deny (including defense-in-depth path-traversal patterns: Bash(rm -rf /*), Bash(mv * /*), Bash(cp -r * /*)) into permissions.json. Idempotent — preserves user-added entries. Both createWikiKeeperAgent and updateWikiKeeperAgent call it, so Edit → Save now actually upgrades older keepers.
  • Permissions apply in chat sessions. Previously chat sessions only honored --permission-mode and dropped permissionRules.allow/deny — meaning a Wiki Keeper chatting interactively could not run its allow-listed Bash(mv *) without per-call approval. ChatSession now writes .claude/settings.local.json at process spawn (and restores at close / abort / hibernate / error), via a shared claudeSettings util reused by ExecutionManager.
  • Long-lived sessions resolve fresh. ChatSession.refreshAgent() re-resolves repository.getAgentByName(name) at every process spawn. Permission/model/effort edits made in the UI take effect on the next message in the same chat tab — no need to recreate it. Falls back to construction-time agent if the agent has been deleted.
  • No race between Save and Run. All Wiki Keeper modal handlers await plugin.refreshFromVault() before re-rendering. The 500ms vault-watcher debounce no longer matters.

Federator (design only)

  • New WIKI_KEEPER_FEDERATOR_DESIGN.md specifies a v2 cross-scope orchestrator: a single agent that fans out to multiple keepers, merges cited answers with explicit per-scope provenance, and routes inbox drops to the right keeper. No code in this release.

Tests

  • 12 new tests covering the permission lifecycle, lint report parsing, and wiki-refresh synthesis schema (103 / 103 green).
  • claudeSettings util has dedicated coverage for the settings.local.json write/restore lifecycle.
  • ensureWikiKeeperPermissions covered for fresh write, additive merge, idempotency, invalid-JSON recovery.
  • ChatSession.refreshAgent covered for fresh-fetch and fallback-on-deletion.

Files of note

  • New: defaults/skills/wiki-refresh/skill.md, src/utils/claudeSettings.ts, src/utils/wikiLintReport.ts, WIKI_KEEPER_FEDERATOR_DESIGN.md
  • Significantly rewritten: defaults/skills/wiki-ingest/skill.md, defaults/skills/wiki-query/skill.md, defaults/skills/wiki-lint/skill.md, src/wikiKeeperTemplate.ts
  • Touched: src/types.ts, src/fleetRepository.ts, src/services/chatSession.ts, src/services/executionManager.ts, src/settingsTab.ts, src/views/dashboardView.ts

Migration notes

  • Existing Wiki Keepers: open Settings → Wiki Keepers → ⚙ Edit → Save once. Strips dead allowed_tools / blocked_tools from config.md and merges canonical allow/deny into permissions.json (preserving any custom entries).
  • Existing topic pages: keep working as-is. The first wiki-ingest after upgrade adds the fenced summary block and frontmatter slots to pages it touches.
  • Existing flat agents with allowed_tools / blocked_tools in frontmatter: unchanged behaviorally on read (legacy migration), but a Save through the UI will move the rules into a sidecar <name>.permissions.json and strip the frontmatter fields.