niklas‑stephan.de

Agent memory system (Wiki.js KB + git config repo)

Last updated 06/11/2026 · memory, agents, wikijs, git

Current state (2026-11-05): memory lives in Wiki.js, https://wiki.niklas-stephan.de, one page per topic under path kb/ (65 pages after the KB import). Outline’s KB collection was dropped from the sidecar’s index on 2026-11-06 (all 65 KB docs are wiki pages now; indexing both doubled every hit). The full Outline archive ran the same day: the KB collection was renamed ARCHIVE: KB (moved to Wiki.js) in Outline (kept as a frozen copy, nothing deleted), the 78 non-KB docs (Projects, blog, wiki, Welcome) were removed from the semantic index, and the outline MCP target was dropped from the gateway. The sidecar now indexes Wiki.js only (kb,guides,runbooks, locale en). The git directories memories/ and user/ were deleted from the repo on 2026-11-01 (all 78 local docs + user.md verified in Outline first; commit 813a30e, synced on metis/iris/hestia; ThinkPad picks it up at its next mem sync). Outline’s revision history is the archive; superseded memories are archived (title prefix ARCHIVE:, importance low), never deleted.

  • Git mirror: site c13412a9-d28c-45ba-9dd7-2a4a5848a783, git target 6fcd31e3-3684-427d-9969-214cea526f20 -> https://git.handtrixxx.com/kb-agent/wiki-pages.git (basic auth: user kb-agent + its write:repository token from /home/handtrixxx/.git-credentials on handtrixxx.com, branch main; the openchamber-agent token is read-only on this repo, so pushing with it fails with “User permission denied for writing”). Gotchas: the storage REST API rejects personal access tokens (“This endpoint cannot be used with a personal access token”), so config lives in Postgres wiki.storage (restart wikijsapp to reload the target cache); content created before the target was enabled is only picked up by the “Add Untracked Changes” action; page changes queue in wiki."storageOutbox" and the scheduler pushes them every 5 m. Gitea: push-to-create works for orgs only (cannot push-create repository for another user for user repos).
  • Auth: login is Authentik OIDC (strategy 78c1b2fe-d095-4b3c-a197-092902910488, issuer https://auth.handtrixxx.com/application/o/wiki/, client wiki-3e356268, group mapping on) - verified: the Wiki.js audit log shows successful OIDC logins for niklas.stephan@gmail.com. Group mapping works via an Authentik ScopeMapping “wiki group mapping” on scope groups: members of authentik Admins are claimed as Wiki.js Administrators, everyone else as Users (verified in the Authentik DB). Wiki.js matches group names case-insensitively and never creates missing groups, so the target Wiki.js group must exist.
  • Store: one Wiki.js page per topic under kb/ (https://wiki.niklas-stephan.de), header block kb-id / importance / tags / updated / summary, then ---, then the body. Wiki.js keeps page revisions; a git storage target mirrors every page as markdown to Gitea kb-agent/wiki-pages (sync mode, 5 m interval, live since 2026-11-05).
  • Access, three ways to the same data: the Wiki.js MCP (https://wiki.niklas-stephan.de/_mcp: search_pages, browse_tree, get_page, create_page, update_page with baseVersionId + edits, recent_changes; write verbs hidden from the laptop key group in the gateway), the semantic sidecar (https://docs.niklas-stephan.de/semantic/mcp: semantic_search, list_memories, semantic_status), and the shell CLI /data/ai-persistence/bin/kb (list, search, show, new, update, sync, export, scan), which calls the wiki MCP directly and caches an index in .kb-index.json (TTL 6 h). GraphQL is not an option for agents: PATs get 403 on /_api/graphql.
  • Keys (names only, never values): WIKI_MCP_TOKEN (Wiki.js PAT “AI Agent MCP”, in /data/docker/wiki.niklas-stephan.de/.env, the gateway .env, and since 2026-11-06 also /data/ai-persistence/.env on metis/iris/hestia/handtrixxx.com so kb works on every host), SEMANTIC_MCP_TOKEN (/data/docker/docs.niklas-stephan.de/semantic/tokens.txt), plus the legacy OUTLINE_KEY until KB is archived. OpenChamber’s container gets the tokens from its environment and has its own /data/ai-persistence/.env (WIKI + SEMANTIC only).
  • Still git (/data/ai-persistence, Gitea repo kb-agent/ai-persistence, clones on handtrixxx.com/metis/iris/hestia; ThinkPad /home/handtrixxx/code/ai-persistence): agents.md (global rules, rendered into each host’s /data/AGENTS.md), hosts/, skills/, bin/, config/. Changes go through mem sync / mem save (lint + commit + pull —rebase + push). mem new/mem save refuse to touch memories//user/ (maintenance override MEM_ALLOW_MEMORIES=1).
  • Git gotchas that still bite: every clone needs repo-local git config user.name/user.email = agent@<host> or a mem sync rebase aborts (“Identitaet des Commit-Erstellers unbekannt”); if a rebase stops, fix identity, git commit -C <orig>, GIT_EDITOR=true git rebase --continue. Clone drift (stale local commits) is resolved with git checkout --ours + rebase —continue. Gitea: HTTPS + token in ~/.git-credentials, SSH disabled; GitHub PAT likewise via credential helper, never embedded in the remote URL.
  • No scheduled jobs. kb export [--out DIR] (frontmatter markdown snapshot, default /data/ai-persistence/export/, gitignored) and kb scan (secret regex over KB) run by hand. Backup of the data itself: Wiki.js Postgres ./db (service wikijsdb) is under /data, covered by Backrest plan handtrixxx-data (23:00). No restore test of the Postgres directory yet.
  • No cron (decided 2026-11-01): the old 10-min kb-sync cron was removed — agents push via mem save themselves; bin/kb-sync deleted.
  • Dead ends: the Alexandria memory MCP (mcp.handtrixxx.com, memory-system) is discontinued and torn down — do not wire any client to it. OpenClaw was removed 2026-10-23.

History: the git-era memory flow (2026-10-14 to 2026-10-31: memories/ directory, Outline AI collection, kb-sync cron, Alexandria MCP phases) is captured in the archived documents unified-memory-kb-architecture and outline-kb-migration-2026-10 plus Outline’s revision history — reference only, do not follow.

Source: Wiki.js