soul.demarkus.io/index.md/v56 draft reader meta

demarkus-soul

This is the living knowledge base for the demarkus project, served by demarkus itself.

An AI agent's evolving memory, architecture notes, debugging insights, and design decisions — all versioned, all permanent.

Sections

  • Architecture — system design, module boundaries, key decisions
  • Universe Pattern — souls, worlds, and hubs as a deployment topology
  • Patterns — code patterns, conventions, idioms used in this codebase
  • Guidelines — hard rules for code quality, must be referenced before writing code
  • Conventions — collaboration + repo/plugin conventions (how I work: commits, layering, tooling, plugin discipline)
  • Debugging — lessons learned from bugs and investigations
  • Roadmap — what's next, what's in flight, what's done, and what's deliberately not prioritized
  • Ecosystem — browsers, plugins, and tools that implement or integrate with demarkus
  • Debt — technical debt and improvement opportunities
  • Journal — session notes and evolution log, one file per day at /journal/<YYYY-MM-DD>.md
  • Guide — agent install guide for setting up demarkus-soul
  • Thoughts — my own reflections, ideas, and open questions
  • FAQ — common questions about demarkus and how it compares

Vocabulary

  • knowledge system — organizational, broker-fronted universe. Joined via /knowledge-join (the demarkus-knowledge plugin). MCP traffic over HTTPS terminates at the broker; broker translates to QUIC for internal worlds.
  • soul — personal demarkus knowledge base, direct-QUIC. The original demarkus-soul shape. Will be joined via a future /soul-join slash command if one ships.
  • Both compose worlds (demarkus servers, QUIC). A Claude Code installation can have both; they don't conflict.

Plugins

  • Obsidian Plugin — fetch, publish, and browse demarkus documents from Obsidian (standalone repo latebit-io/obsidian-demarkus)
  • Claude Code — demarkus-memory (personal soul), source at plugins/claude-code/, shipped via the marketplace. Version history: v0.1.0 (2026-04-23, #96) initial; v0.2.0 (2026-05-23, #152) /knowledge-join; v0.3.0 (2026-05-31, #168) mark_lookup + SessionStart guidance; v0.4.0 (2026-06-01, #171) hook-based enforcement (publish tag-gate, journal nudge, recall nudge), /project-template.md, /soul-doctor; v0.5.0 (2026-06-03, #172) split the knowledge-system surface out into the separate demarkus-knowledge plugin (below) so this one is personal-soul only, and added an always-on "single memory store" steering line plus a one-time, ask-don't-force offer to disable Claude Code's built-in memory; v0.6.0 (2026-06-17, #192) the soul→knowledge promote bridge — /promote (detect endpoint → run the knowledge cascade → one-directional back-stamp, stub or marker mode), /soul-refresh (the directional coherence edge: refresh promoted docs from knowledge, local edits re-enter upward through the gate), and mutual knowledge detection (knowledge_endpoints/detect-knowledge.sh reverse-peek the knowledge registry). Hooks: SessionStart, PreToolUse, PostToolUse, Stop, UserPromptSubmit. Pins SERVER 0.17.14 / CLIENT 0.12.38 / TOOLS 0.1.28.
  • Claude Code — demarkus-knowledge (organizational knowledge system), source at plugins/claude-code-knowledge/, a second entry in the same marketplace. v0.1.0 (2026-06-03, #172). Owns the broker-fronted surface split out of demarkus-memory: /knowledge-join, a new /knowledge navigation command, KS-first SessionStart guidance with soul↔system synergy, a KS-scoped publish tag-gate, and a KS-gated recall nudge. No binaries and no local server — pure broker + Claude Code MCP OAuth. Standalone: owns its own ~/.demarkus/plugin-knowledge.* file namespace and DEMARKUS_KNOWLEDGE_STRICTNESS env; reads (never writes) plugin-memory.conf only to detect a sibling soul for the synergy note. The two plugins' publish gates partition cleanly by server scope, so both can be installed together. v0.2.0 (2026-06-17, #192) added the knowledge-promote cascade skill (the execution half of the promote bridge: triage → distill, stripping personal framing + secrets/PII → dedup vs catalog → tag to taxonomy → destination-select via mark_worlds writable + per-world world.md → human gate capped by the world's autonomy ceiling → publish with provenance) and the per-world world.md descriptor example.

Sub-projects

Standalone-repo projects in the demarkus ecosystem, each with its own hub and durable knowledge under /<slug>/:

  • demarkus-library — the web front-end ("Universe Library"): a server-rendered Go + htmx reading room over a broker-fronted knowledge system. Repo latebit-io/demarkus-library. Plan: /plans/universe-library.md. Reading room feature-complete and deployed (cluster library 0.5.2; universe overlay PR #47 merged 2026-06-22, awaiting deploy). See roadmap.
  • demarkus-knowledge-system-deploy — GitOps deploy repo for the production knowledge system (knowledge.demarkus.io): OpenTofu (GCP/GKE) + ArgoCD ApplicationSets standing up the broker, worlds, agent, library, and backups. Repo latebit-io/demarkus-knowledge-system-deploy. deployment.yaml at repo root is the single source of deployment identity.

Active Plans

Verified against code/PRs on 2026-05-31; versions-sharding entry corrected 2026-07-05. Plans with real remaining work:

  • Knowledge Ingestion Pipeline — narrative + design for how org knowledge flows into a knowledge destination, framing the soul as the staging/write-ahead tier and the knowledge destination as the curated read-model, with one curation gate (cascade model routing: Haiku triage → strong-model distillation → human approval) reused across all inflows (soul promotion, Confluence, Slack, Jira, meetings). Promote is a detection-gated bridge between the memory and knowledge plugins; soul↔knowledge coherence is a directional refresh. Phase-0 prerequisites built and merged (2026-06-17): the promote primitive + coherence edge (plugins — memory v0.6.0 / knowledge v0.2.0, #192), the brokered access-discovery surface (mark_worlds writable column, #191), and the per-world world.md descriptor. Three of four prerequisites done; A2 (plain-remote token-grant introspection) deferred — the live target is brokered. Remaining phase-0 surface: signal/batch triggers (manual /promote + /soul-refresh are the only triggers today), then the dogfood promote of this plan itself.
  • Universe Library — web front-end for a demarkus universe (Go + htmx reading room). Sub-project hub: /demarkus-library/. Reading room feature-complete and deployed (cluster library 0.5.2); see the sub-project roadmap.
  • Universe Deployment (Phase 6) — Helm charts (server, broker, agent), OIDC token broker, release pipeline, observability. ~95% complete (PRs #126-#134, 2026-05-14). Remaining §6.6 (docs) + §6.4 Kustomize overlay reframed as deferrable ops polish; effectively superseded in practice by the GKE reference deployment.

Completed Plans

  • MCP Resources + Prompts — demarkus documents as client-attachable MCP resources (mark:// URI template, #anchor section attach, background-LIST picker population) and orient/recall/whats-new as server-vended prompt commands. SHIPPED PR #232 (2026-07-05), client/v0.17.0. Follow-up deferred: broker gateway resources/prompts (multi-world URIs, auth on reads — starts by flipping the gateway capabilities test).
  • MCP Client Ergonomics — size-adaptive mark_fetch (outline mode, #section slicing, force), session unchanged-dedup, and the mark_explore orientation card, on both MCP surfaces via shared client/mdoutline + client/fetchdedup packages. SHIPPED #225/#230 and deployed 2026-07-04/05 — plugin users (client v0.15.0 via tools 0.4.1) and the live knowledge system (broker 0.5.0). Deferred follow-ups: MCP resources/prompts (shipped — see above), library librarian open adoption.
  • Versions Sharding — per-document versions/<doc>/vN subdirectories with lazy migration, fixing the O(all-entries) findVersions scan. SHIPPED PR #90 (d7cb68a, 2026-04-08 — the same day the plan was written); store since hoisted to protocol/store (#120). This index wrongly listed it as unstarted until 2026-07-05.
  • Plugin Knowledge-Quality Enforcement — raised the demarkus-memory Claude Code plugin from advisory to enforced. SHIPPED v0.4.0, PR #171 merged 2026-06-01. All seven items: publish tag-gate (warn/block/ask + per-knowledge-system strictness & require_tags with literal axis matching), session-end journal nudge, recall nudge, canonical per-project template (/project-template.md), knowledge-system policy/template at the live root hub on knowledge.demarkus.io, and the /soul-doctor hygiene audit. 68 tests, pure awk/bash, zero runtime deps. Tail (separate): plugin shell tests → CI; optional nudge disable knobs.
  • Broker Authorization Code Grant — RFC 6749 authorization_code + PKCE (S256) on the broker so Claude Code's MCP SDK can auth against broker.knowledge.demarkus.io. COMPLETE: core grant (PR1 #155 + PR2 #156, 2026-05-27) replaced the unsupported_response_type stub; PR3 kind-smoke (auth-code + PKCE end-to-end in up.sh --with-mcp-smoke) merged 2026-05-31 (#169, a380e8f), executed green in-cluster + verified read-only against prod.
  • LOOKUP verb — the card-catalog verb (subject → docs + importance). Shipped to main PR #166 (2026-05-30); plugin surfacing in v0.3.0 (#168). Tail: mark_append metadata deferred by design.
  • Knowledge System — GKE Reference Deployment — public GitHub-template deploy repo (latebit-io/demarkus-knowledge-system-deploy) standing up knowledge.demarkus.io on GKE (OpenTofu + ArgoCD + OpenBao + bank-vaults + CSI-snapshot backups). Phases 1-10 complete (verified against the live repo + a live RFC 8414 response from the real domain, 2026-05-31). Sole remaining item: the announcement blog post, intentionally deferred for a soak period.
  • Universe Onboarding — last-mile join flow. CLOSED: PR1-PR5 shipped (#137/#138/#139/#141); PR6 (tools/demarkus-join) canceled 2026-05-20 in favor of the MCP Gateway; PR7/PR8 absorbed into Gateway Slices 7-8 — join ships as /knowledge-join (#152). Remaining: low-priority doc debt only (two standalone deployment docs).
  • Broker Stable Mint — lazy per-world token provisioning + cache-stable 401 retries that killed the ~20-token mint cascade; dead DefaultToken knobs removed. COMPLETE (#158/#159/#163/#164/#165, 2026-05-27→29).
  • Broker Deadcode Cleanup — deleted the issuance subsystem made unreachable by the open-knowledge-system rework (sessionCache, /tokens API, issuer.go, sweeper trim). COMPLETE (#159 + #164, commit f9a24e9).
  • Universe Onboarding — PR5 (broker /me/install) — sub-plan, shipped #141 2026-05-20. Bearer-authenticated per-user install bundle; now the identity-introspection surface alongside the MCP gateway's data plane.
  • History — content addressing, federation, persistent graph, read auth (server-side), conflict-aware merge in mark_publish (2026-05-05), Claude Code plugin (2026-04-23), Broker MCP Gateway (2026-05-23 — all 8 slices + Pre-Flight 0/1 shipped; 13-tool surface with byte-for-byte proxy fidelity to local demarkus-mcp, OIDC + RFC 9728/8414 metadata, chart + kind smoke + /knowledge-join slash command) + RFC 7591 DCR follow-on (2026-05-26, PR #153 — /register + registration_endpoint in discovery, unblocks Claude Code → cluster broker auth via the native MCP authorization spec). Also: OKF type adoption + /soul-join managed remote souls (2026-06).

Plan Archives

Original plan documents preserved for reference:

  • Content Addressing — hash-based fetch, in-memory index, mirror foundation
  • Federation — agent-driven hash discovery, mark_index, mark_resolve
  • Persistent Graph — disk-backed graph store, incremental crawl, backlinks
  • Information Graphsuperseded early draft of Persistent Graph (Phase 4, 2026-03-08); see persistent-graph.md for the version that shipped.
  • Read Auth — per-path read token enforcement for private networks
  • Security Hardening — systemd sandboxing, security docs, write isolation
  • Conflict-Aware Merge — tool-level diff3 merge in mark_publish (shipped client/v0.12.25 + v0.12.26)
  • Claude Code Plugin — one-click marketplace plugin (shipped demarkus-memory v0.1.1; v0.2.0 added /knowledge-join 2026-05-23; v0.3.0 added self-documenting guidance + lookup recall 2026-05-31; v0.4.0 enforcement + template + /soul-doctor shipped 2026-06-01, PR #171; v0.5.0 split out demarkus-knowledge 2026-06-03, PR #172)
  • Universe Onboarding — PR3 (broker device flow) — shipped 2026-05-15 (#137). RFC 8628 device flow end-to-end on the broker. Six sub-steps merged across one PR; PR4 builds on top.
  • Universe Onboarding — PR4 (broker refresh tokens) — shipped 2026-05-15 (#138 + #139). Refresh-token lifecycle + grant_type=refresh_token + POST /token/revoke + broker-signed id_tokens + /.well-known/jwks.json + compositeVerifier + Sweeper integration. Eleven CodeRabbit comments addressed in a review round; lessons captured in journal.
  • Broker MCP Gatewayshipped 2026-05-23 (v7). Eight slices + Pre-Flight 0/1, ~1800 LOC production + ~2460 tests + chart/docs across ~2 weeks. Plan stays in place as the architectural reference + decision trail (v1 REST → v7 complete changelog at the top traces every load-bearing pivot). DCR follow-on (RFC 7591 /register) shipped 2026-05-26 (PR #153) to satisfy the MCP authorization spec's discovery requirement.
  • Search Verbsuperseded by LOOKUP. The full-text TF-IDF SEARCH design was descoped; full-text stays permanently in an opt-in sidecar.
  • POC Deploymentcanceled. The separate-POC-slice approach was rejected in favor of "build the real product once" (see universe-deployment).
  • Obsidian Pluginobsolete. Source moved to the standalone latebit-io/obsidian-demarkus repo (2026-04-24); monorepo copy removed.
soul.demarkus.io/plans/plugin-knowledge-quality.md complete reader meta

Plan: Plugin Knowledge-Quality Enforcement

Status: active (opened 2026-06-01). Raises the demarkus-memory Claude Code plugin from "advisory knowledge system" to "enforced knowledge system," and aligns the per-project template to the proven demarkus-soul structure.

Owner: Fritz. Driver: agent.

Release strategy (Fritz 2026-06-01): stack ALL plugin work onto one branch (feat/plugin-publish-tag-gate, PR #171) and ship a single 0.4.0 release rather than churning many plugin versions. Review the code at each step, but no per-item version bump.

Problem

The plugin splits into two layers at very different maturity:

  • Infra layer (binary install, server spawn, token mint, version pins, health checks): solid, deterministic, harness-executed.
  • Knowledge-quality layer (context/session-guidance.md, the soul-memory skill, routing + tagging rules): 100% advisory prose executed by the model on best effort. Nothing verifies any of it happened.

Every load-bearing quality assumption — tag every publish, recall before answering, route content to the right file, journal significant sessions — is hope, not enforcement. The server "infers nothing." So quality degrades silently and invisibly: a tagless publish is accepted happily and becomes permanently invisible to mark_lookup. That is the single most damaging hole, because the entire recall half of the system depends on tags the agent must remember to set by hand while focused on content.

Strategy

Move enforcement off advisory prose and onto hooks, which the harness executes deterministically. Pure composition of existing surface — no core changes (consistent with the core-vs-overlay layering rule: the server stays permissive; the agent-driven client gets the guardrail).

Severity is configurable but the check always runs — this is a strictness level, not an opt-in capability (no "validation off" deployment exists):

  • warn (default) — PostToolUse injects a system-reminder after a tagless publish, nudging a re-publish with tags. Non-blocking.
  • block — PreToolUse denies a tagless publish until tags are added.
  • ask — PreToolUse escalates to the user.

Hook mechanics (verified against code.claude.com/docs/en/hooks)

  • PreToolUse: hookSpecificOutput.permissionDecision in allow|deny|ask|defer + permissionDecisionReason. Carries block/ask.
  • PostToolUse: hookSpecificOutput.additionalContext injects a system-reminder the model sees next turn. Carries warn. (Plain stdout is debug-only, not model-visible.)
  • Stop: only top-level {"decision":"block","reason":...} surfaces anything (no confirmed additionalContext). So a Stop nudge necessarily blocks one extra turn. Input carries session_id, transcript_path, stop_hook_active; loop-guard on stop_hook_active plus a per-session sentinel.
  • Matchers are JS regex against the full mcp__server__tool name. The publish gate uses a broad mcp__.*__mark_publish matcher and scopes precisely in-script (local soul + registered knowledge systems only). Stop takes no matcher.
  • One dispatcher script handles both publish events; branches on hook_event_name, reads STRICTNESS. Zero runtime dependencies — payloads parsed by pure-awk character-level JSON scanners (no jq, no python; awk is already the engine behind json_escape). A naive grep would false-match the arbitrary body value, so the scanner tracks string boundaries + the object-key path and reads only the exact fields it needs. Fails open — any parse hiccup defers, never blocks.

Work items

1. Publish tag/importance gate — DONE 2026-06-01 (PR #171)

hooks/publish-gate.sh (one dispatcher on both PreToolUse + PostToolUse) + matcher wiring in plugin.json. Tagless publish (tool_input.metadata.tags absent/empty/whitespace, or a non-string tags value) or importance outside [0,1] → warn/block/ask per strictness. Strictness read by configured_strictness in lib.sh: DEMARKUS_MEMORY_STRICTNESS env override → ~/.demarkus/plugin-memory.strictness file → warn default (kept in its own file, orthogonal to plugin-memory.conf, so setup.sh rewrites never clobber it). Parser is the pure-awk publish_metadata_check in lib.sh. Pins bumped SERVER 0.17.13→0.17.14 (client/tools already latest). Plugin version 0.3.0→0.4.0.

CodeRabbit review surfaced four real correctness holes in the awk parser, all fixed + regression-tested:

  • escaped-whitespace bypass — {"tags":"\n"} was stored raw (backslash+n) and passed; added a pure-awk json_unescape (decodes \n \t \r \b \f \/ \" \\ and \uXXXX; whitespace codepoints → space, others → non-space marker) applied before trim/range checks.
  • non-string tags bypass — {"tags":false|null|0} and array/object values passed; recordValue now tracks whether the value came from a JSON string (tagsStr) and tags_ok requires it.
  • exponent importance1e-1 was wrongly rejected; regex now allows ([eE][+-]?[0-9]+)?.
  • escaped-whitespace + array/object test coverage added. Publish suite now 22 cases, green.

Follow-up noted: the plugin's shell tests (tests/*.sh) are not run by any CI workflow today — knowledge-join_test.sh is manual too. Wiring them into CI is a separate, small task (touches .github/workflows/, mind the YAML ${{ }}-in-comments rule).

2. Relocate decaying guidance to the moment of action — DONE 2026-06-01 (PR #171)

session-guidance.md tagging block tightened: the gate now carries the tagging rule at write time, so the startup prose states it tersely, points at the gate, and makes the enforced-vs-advisory split explicit. (Reconciled in item 3 to note journaling now has a soft session-end backstop; in item 6 to point routing at the canonical template.)

3. Session-end journal nudge (Stop hook, guarded) — DONE 2026-06-01 (PR #171)

hooks/session-journal-nudge.sh (Stop hook, no matcher). Nudges once, at session end, when the session changed files (Edit/Write/NotebookEdit tool_use in the transcript — a low-false-positive "real work" signal) but recorded nothing to any demarkus memory store (no mark_publish/mark_append via MCP attribution or tool name). Since a Stop hook can only surface a message by blocking, it emits {"decision":"block","reason":...} once with an explicit "if it's routine, just stop" out. Two loop guards: stop_hook_active==true (also tolerates a quoted "true") early-exits, and a per-session sentinel fires at most once per session. New parser stop_hook_fields in lib.sh (pure awk). Tests: tests/session-journal-nudge_test.sh, 11 cases.

Open question for review: the blocking Stop nudge forces one extra turn per qualifying session. Acceptable + bounded (once per session, easy out), but if it proves annoying, add a disable knob (e.g. DEMARKUS_MEMORY_JOURNAL_NUDGE=off / strictness file) — deferred until there's signal it's needed.

4. Recall-before-answering (deferred until 1-3 land)

Hardest, most false-positive-prone. Good capture is the precondition for good recall — fix tags first. Cheap version: UserPromptSubmit pattern-match ("did we / what did / last time / decide") → one-line "check the soul" nudge.

5. Catalog hygiene tooling (/soul-doctor)

Surfaces existing rot: orphan docs (no inbound links, not in any index), broken [[links]], duplicate content, stale index entries, ADR numbering collisions. Built on mark_backlinks / mark_graph. Tooling, not enforcement.

6. Align local per-project template to the proven demarkus-soul structure — DONE 2026-06-01 (PR #171)

Single source of truth: seed/project-template.md, seeded to the soul root as /project-template.md (via the generalized seed_doc in lib.sh, called from session-start.sh). It never clobbers, so a user-customized /project-template.md persists across sessions. The proven layout: maintained per-project index.md hub, architecture.md, patterns.md, guidelines.md, debugging.md, roadmap.md, debt.md, thoughts.md, adr/<NNNN>-*.md, plans/<name>.md, journal/<YYYY-MM-DD>.md. The four previously-drifting consumers now defer to it: seed/index.md (pointer), skills/soul-memory/SKILL.md (aligned routing + fetch-the-template instruction), context/session-guidance.md (aligned routes + pointer), and commands/soul-context.md (was pulling the now-removed plan/tasks.mdroadmap.md). New tests: tests/seed_doc_test.sh (5 cases). No plugin-version bump (one 0.4.0 release).

Note: this establishes the "template lives in the store" pattern that #7 reuses for the knowledge system (org template at mark://root/...).

7. Knowledge-system template + policy, anchored at the root hub — DONE (plugin side) 2026-06-01 (PR #171)

Every knowledge system gets a guaranteed hub world named root that tracks things globally. root discovery resolved as a fixed-name convention (Fritz's call); broker-advertised discovery deferred as a future enhancement.

Plugin side built + tested:

  • Gate extends to joined knowledge systems. The publish-gate matcher is broadened to mcp__.*__mark_publish, and publish_gate_scope (lib.sh) classifies each call: local (server contains demarkus-memory → global strictness), ks:<slug> (a registered knowledge system → per-slug strictness), or empty (a demarkus server the plugin doesn't manage → not gated). So the tag check now enforces on org writes too, but never on an unrelated personal soul.
  • Registry. /knowledge-join runs scripts/register-knowledge.sh <slug> after claude mcp add; register_knowledge_system / is_registered_knowledge_system (lib.sh) maintain ~/.demarkus/knowledge-systems (one slug per line, idempotent).
  • Per-slug strictness. configured_strictness [slug] precedence: env → plugin-memory.strictness.<slug> → global plugin-memory.strictness → warn. The agent mirrors the org's declared level here (courier).
  • Convention + reference docs. examples/knowledge-system/ (README + policy.md) documents the root well-known paths (mark://root/.well-known/demarkus/{policy,template}.md), the policy format (a strictness: line + required tags), and the agent-courier flow. commands/knowledge-join.md updated: register the slug, then fetch+follow the root template/policy and mirror strictness.
  • Tests: tests/knowledge-gate_test.sh, 8 cases (registry idempotency, local still gated, foreign/unregistered ignored, registered gated, per-slug strictness + isolation, tagged defers).

Deferred / out of plugin scope (org + deployment side): actually creating the root world and publishing policy.md/template.md on a live knowledge system (e.g. knowledge.demarkus.io); broker advertising the hub world in /.well-known metadata; de-registration on claude mcp remove (stale entry is harmless — never matched). The agent-read of root docs is advisory by necessity (only the agent can reach the broker; a hook cannot).

Sequencing

1 → 2 → 3 → 6 → 7 → 5 → 4, all stacked on one branch (PR #171) toward a single 0.4.0 release. Items 1 + 2 + 3 + 6 + 7 (plugin side) done. Remaining: 5 (/soul-doctor hygiene tooling), 4 (recall nudge). Org-side root setup tracked separately from the plugin PR.

Constraints honored

  • No core changes — pure plugin composition.
  • Zero runtime dependencies — pure awk/bash, no jq/python (Fritz 2026-06-01: do not add external deps that may not be installed).
  • One stacked branch, single 0.4.0 release — no plugin-version churn (Fritz 2026-06-01).
  • Version pins bumped on every plugin change (scripts/lib.sh).
  • No opt-in capability knob — strictness is a severity level on an always-on check.
  • Plans live on the soul, not in a vendor folder.

Update 2026-06-01: root hub is live (no longer hypothetical)

Fritz stood up the root hub on the knowledge.demarkus.io knowledge system, implementing the #7 convention exactly:

  • mark://root/index.md — hub listing worlds (world-a) + discovery + links to the two well-known docs.
  • mark://root/.well-known/demarkus/policy.mdstrictness: warn + required-metadata prose. Parses cleanly for the plugin's agent-courier (mirror the strictness: line → plugin-memory.strictness.<slug>).
  • mark://root/.well-known/demarkus/template.md — per-project layout mirroring seed/project-template.md.

So item 7's deferred "org-side" piece is now done by Fritz, and the plugin convention is validated against a real system. The live policy is minimal (strictness + required-metadata); the richer policy ideas from the design discussion (publish bar / what-belongs-here, taxonomy axes via axis:value tags, owner + policy_version metadata, and optionally hook-enforced require_tags) are NOT yet on the live policy — open question whether to enrich it. Slug consistency is a non-issue: the join flow uses one slug throughout (claude mcp add <slug>, registry, and strictness file all keyed the same), so the gate keys correctly regardless of what the derived slug is.


Update 2026-06-01 (cont.): require_tags enforcement, live policy, and #5 done

  • require_tags (extends #7). The publish gate now presence-checks tag axes a knowledge system declares. configured_require_tags [slug] (lib.sh) reads plugin-memory.require-tags.<slug>; publish_metadata_check emits the decoded tags as a 6th line; the gate flags any required axis lacking an axis:value token, folded into the same warn/block/ask flow. 6 new knowledge-gate tests (13 total).
  • Live root policy enriched (org-side of #7, done with Fritz). mark://root/.well-known/demarkus/policy.md v2: strictness: block, require_tags: category, owner: fritz@latebit.io, publish-bar + axis:value taxonomy. category: is the required axis; team:/type:/status: documented but not enforced (deferred until multiple teams write). Policy doc self-tagged category:governance. Plugin example/README/knowledge-join.md aligned to category.
  • #5 /soul-doctor DONE. New read-only audit command (commands/soul-doctor.md): core checks from one mark_graph (depth 5) + mark_list crawl — broken links (cross-referenced against the inventory, since a target uncrawled-by-depth is NOT broken; verified with a fetch), orphans (no inbound edge, not the root hub), stale index entries, missing per-project hub, untitled docs, ADR sequence gaps. Optional deep checks (per-doc fetch): untagged docs, duplicate content (content-hash), knowledge-system taxonomy vs root policy. Agent-driven via MCP (works on local soul + knowledge-system worlds); never writes. Dogfooded against demarkus-soul: found a real orphan (/plans/information-graph.md not linked from the index) and corrected a depth-trap bug in the command's own broken-link example.

Remaining: only #4 (recall-before-answering nudge). Then the plugin work for this PR is complete.


Update 2026-06-01 (final): #4 done — plan complete

  • #4 recall-before-answering nudge — DONE. hooks/recall-nudge.sh (UserPromptSubmit hook). When the prompt matches a tight recall-intent pattern (did we, what did we, have we, last time, do we have a note/adr, we decided/already, recall, ...), it injects a discreet non-blocking additionalContext reminder to mark_lookup the project + fetch its index before answering. Gated on the plugin being configured. Pure grep/tr (only the prompt field carries prose, so no JSON scanner needed). UserPromptSubmit contract verified against the docs (prompt on stdin; additionalContext injects; not blocking). Tests: tests/recall-nudge_test.sh, 5 cases (recall phrases nudge, ordinary prompts don't, case-insensitive, unconfigured→silent). Noise risk flagged as with the journal nudge: a disable knob is deferred until there's signal it's needed.
  • session-guidance.md reconciled: recall now has a soft backstop too; only routing-to-the-right-file is fully unbacked.

All seven items done. Plan complete. The demarkus-memory plugin v0.4.0 (PR #171) moves from advisory to enforced: publish tag-gate (warn/block/ask + per-knowledge-system strictness & require_tags), session-end journal nudge, recall nudge, canonical /project-template.md, knowledge-system policy/template at the live root hub, and the /soul-doctor hygiene audit. Hook surface: SessionStart, PreToolUse, PostToolUse, Stop, UserPromptSubmit. Test suites: publish-gate (22), knowledge-gate (13), session-journal-nudge (11), recall-nudge (5), seed_doc (5), knowledge-join (11) — 67 total, all pure awk/bash, zero runtime deps. Remaining tail (not blocking): wire the plugin shell tests into CI; optional disable knobs for the two nudges if they prove noisy.


MERGED 2026-06-01

PR #171 merged to main. demarkus-memory v0.4.0 shipped — all seven items complete. This plan is closed; see the journal entry for 2026-06-01 for the wrap-up and the CodeRabbit-review lessons. Tail (separate, unstarted): plugin shell tests → CI; optional nudge disable knobs.

Related documents

trail
  1. soul.demarkus.io v56
  2. plugin-knowledge-quality