aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-05 05:59:57 -0500
committerCraig Jennings <c@cjennings.net>2026-06-05 05:59:57 -0500
commit13816d00d6bf0f6d4a878c4cb5cd27ac03f3a9ea (patch)
tree46dcea2035b3eb843a58698f5e2ab57ffb0b2c06
parent83bf3cb50c88f91730656a2242141567551063ac (diff)
downloadrulesets-13816d00d6bf0f6d4a878c4cb5cd27ac03f3a9ea.tar.gz
rulesets-13816d00d6bf0f6d4a878c4cb5cd27ac03f3a9ea.zip
docs(design): add org-roam knowledge-base spec for shared agent memory
The spec adopts the existing ~/sync/org/roam/ KB (Syncthing-synced, 484 files) as the shared store agents read from and write to, so cross-machine memory sync comes for free instead of needing new infrastructure. It recommends the mechanics (queried as files, capture in harness memory then promote durable facts to the KB, a claude-rules pointer, an :agent: write schema) and leaves the work/personal write boundary for ratification. Supersedes the dedicated-repo and two-tier approaches for the storage-and-sync half.
-rw-r--r--.ai/notes.org2
-rw-r--r--.ai/sessions/2026-06-05-05-58-pattern-catalog-and-roam-memory-spec.org94
-rw-r--r--docs/design/2026-06-05-org-roam-knowledge-base-spec.org84
-rw-r--r--todo.org59
4 files changed, 214 insertions, 25 deletions
diff --git a/.ai/notes.org b/.ai/notes.org
index bf5e1b7..1ec9528 100644
--- a/.ai/notes.org
+++ b/.ai/notes.org
@@ -79,6 +79,6 @@ Format:
Markers maintained by workflows to record when they last ran. Read by other workflows that gate their behavior on freshness.
:LAST_AUDIT: 2026-05-28
-:LAST_INBOX_PROCESS: 2026-06-03
+:LAST_INBOX_PROCESS: 2026-06-05
Format: one =:MARKER: YYYY-MM-DD= line per workflow. Workflows overwrite their own marker on completion.
diff --git a/.ai/sessions/2026-06-05-05-58-pattern-catalog-and-roam-memory-spec.org b/.ai/sessions/2026-06-05-05-58-pattern-catalog-and-roam-memory-spec.org
new file mode 100644
index 0000000..81642ad
--- /dev/null
+++ b/.ai/sessions/2026-06-05-05-58-pattern-catalog-and-roam-memory-spec.org
@@ -0,0 +1,94 @@
+#+TITLE: Session Context
+#+DATE: 2026-06-04
+
+* Summary
+
+** Active Goal
+
+Clean startup that turned into processing two work-project inbox handoffs (both rulesets-tooling improvements), then building the long-pending pattern catalog, then pivoting the memory-sync task onto a shared org-roam KB and drafting its spec. Three feature commits pushed; one spec drafted for review.
+
+** Decisions
+
+- *voice #38 elevated to a mandatory final pass* (handoff #1). The terse/Orwell cut runs as an explicit standalone last step before any draft is shown, not one of 41 walked mid-list. Reviewed the work agent's pre-staged edits, shipped them.
+- *make install folded into startup Phase A.0* (handoff #2). A skill added to rulesets + pushed reached files via git pull but not the ~/.claude symlink; now make install runs after the rulesets pull, idempotent, quiet on all-skip, with a Phase C surfacing bullet.
+- *Pattern catalog built and shipped.* Approved the spec as written (all 5 decisions + 3 open questions). Built six seed patterns + README + pointer rule.
+- *Catalog format: .org, not .md.* First drafted .md (justified from DECISION 1's "mirrors memory/ and claude-rules/"); Craig chose .org. Converted with #+KEYWORD frontmatter; pointer claude-rules/patterns.md stays .md (Makefile glob + rules layer require it).
+- *Memory-sync task pivoted to a shared org-roam KB.* Pressure-tested the two-tier idea, then Craig redirected: ~/sync/org/roam/ already exists (484 files, Syncthing-synced since 2023), so sync is already solved. Drafted a spec adopting it as the shared agent substrate. DECISION 5 (work/personal write boundary) left for Craig's ratification.
+
+** Data Collected / Findings
+
+- flush skill was linked at 00:20 (work agent's manual make install) — confirmed the gap was real; make install is idempotent (skip/link/WARN/relink).
+- All 7 catalog .org files parse via emacs --batch org-element-parse-buffer; cross-links resolve; each pattern has slug-matches-filename + 7 keyword fields; zero em-dashes.
+- ~/sync/org/roam/ = 484 org files, Syncthing-synced (not git). rulesets memory dir is unmanaged (7 files, no enclosing git); 13 per-project memory dirs total, all at-risk.
+- The dedicated-repo memory approach was built then reversed (pooled work + personal); no ~/.claude-memory clone remains.
+
+** Files Modified
+
+- voice/SKILL.md, voice/references/voice-profile.org, claude-rules/commits.md — #38 terse final pass (commit 4779ce8).
+- claude-templates/.ai/workflows/startup.org + .ai/ mirror — make install in Phase A.0 + Phase C surfacing (commit 3eed289).
+- patterns/ (6 .org seed patterns + README.org) + claude-rules/patterns.md pointer — the catalog (commit 83bf3cb).
+- docs/design/2026-06-05-org-roam-knowledge-base-spec.org — new spec, NOT yet committed (lands in the wrap-up commit).
+- todo.org — pattern catalog DONE + CLOSED; memories task pivoted with org-roam progress entry + VERIFY for DECISION 5.
+- .ai/notes.org — :LAST_INBOX_PROCESS: → 2026-06-05.
+- Replies sent to work's inbox for both handoffs; both rulesets inbox handoffs cleared.
+
+** Next Steps
+
+- *Memory/org-roam (the resume point):* Craig ratifies spec DECISION 5 (work/personal write boundary — options A/B/C, C recommended) plus the Syncthing-topology and node-granularity / harness-memory-fate / write-review open questions. Then implement claude-rules/knowledge-base.md + the write schema. See the VERIFY under the memories task in todo.org.
+- First real test of the pattern catalog: a consuming agent reaching for a pattern while designing a prompt flow.
+- The make install startup step takes effect on every project's next session; voice #38 and the catalog are live on this machine now.
+- Open [#C]s untouched: create-documentation skill, lint-org append-vs-converged question, the rotation batch.
+
+* Session Log
+
+** Startup + inbox handoff: elevate voice #38 to a mandatory final pass
+
+Clean startup (2026-06-04 23:53 CDT). No crash anchor, no reminders/pending decisions, zero stale tasks. One open A/B task surfaced: the pattern-catalog spec (#B), gated on Craig's review.
+
+Craig asked to re-check the inbox before moving on. A new handoff had landed at 00:04 from the work project (2026-06-05-0005-from-work-rulesets-note.org): elevate voice pattern #38 (terse / omit-needless-words cut) from one-of-41-walked-mid-list to a mandatory standalone *final* pass run right before any draft is shown. Trigger at work: a commit message went out needing two manual Orwell-walk requests before it read terse, even though /voice personal had run — the gap was execution position, not the rule text.
+
+The handoff's three claimed edits were already staged in this repo's working tree (the work agent edited them here). Verified all three against the diff:
+- voice/SKILL.md — new Process step 7 (standalone terse pass, prose+personal; general skips), "Present" bumped to step 8, Output Format item 7 added.
+- voice/references/voice-profile.org — §38 "Execution position" subsection + 2026-06-05 history entry (SKILL/profile pairing rule honored).
+- claude-rules/commits.md — one sentence appended to the Single-skill gate naming #38 as the last pass before printing.
+
+Craig chose option 1 (ship it). Ran the publish flow:
+- Step 0 reconcile: 0/0 clean.
+- Step 1 review-code --staged: Approve, no Critical/Important. One cosmetic Minor (Output Format item 4 "Final rewrite" slightly misnamed now that the true final comes from the terse pass) — left as-is. Verified the SKILL.md renumber introduced no stale step references.
+- Step 2: drafted commit msg, /voice personal (41 patterns; #33 semicolon split, #32 first-person, #38 terse trim; #39 names of SKILL.md/commits.md kept under the commits.md edge case — they're the change itself in their own repo). Craig approved.
+
+Committed 4779ce8 as Craig (c@cjennings.net), pushed 46e1d37..4779ce8 to origin/main.
+
+Verified live on this machine: ~/.claude/skills/voice and ~/.claude/rules/commits.md are symlinks into the rulesets checkout, so the change is already in effect — no re-install needed here. Other machines pick it up on next rulesets startup pull (symlinked free; copy-based would need make install there).
+
+Replied to work's inbox (2026-06-05-0016-from-rulesets-done...org) confirming. Removed the processed handoff from rulesets/inbox/; inbox clean (exit 0). Bumped :LAST_INBOX_PROCESS: 2026-06-03 → 2026-06-05 in notes.org (rides to wrap-up commit).
+
+** Started pattern-catalog walkthrough, interrupted by second work handoff: make install at startup
+
+Began walking Craig through the pattern-catalog spec (docs/design/2026-06-02-pattern-catalog-spec.org) — five DECISION calls + three open questions. My read: all five land where I'd put them, the three open-question leans are sensible, approve-and-build. Craig was about to decide when he asked to check the inbox again.
+
+Second work handoff (2026-06-05-0023): fold make install into startup Phase A.0. Root cause (verified): a skill added to rulesets + pushed reaches files via git pull but not the ~/.claude symlink — make install only links what's new and pull doesn't run it. flush sat uninstalled from 2026-06-02 until a manual install tonight (symlink ts 00:20). Verified make install is idempotent (skip/link/WARN/relink) and ran the exact proposed block live (prints "nothing new to link" on this fully-linked machine).
+
+Craig chose option 1 (implement now). Added to both canonical (claude-templates/.ai/workflows/startup.org) and the .ai/ mirror, byte-identical:
+- Phase A.0: new "*** Install rulesets symlinks into ~/.claude (idempotent)" subsection after the rulesets pull — guarded make -C "$HOME/code/rulesets" install, grep filters to link/relink/WARN, quiet "nothing new to link" otherwise, no cd.
+- Phase C: new "Newly-installed symlinks" surfacing bullet — link → check available-skills (registered=note available / absent=restart prompt), WARN=human collision, all-skip=silent.
+
+Publish flow: Step 0 reconcile 0/0. review-code --staged Approve, no Critical/Important, one cosmetic Minor (2>&1 into grep could mask a make-install error as "nothing new" — benign, left). /voice personal on commit msg (subject trimmed <72, #13 em-dash→colon, #33 semicolon→period, #35 split, #38 terse; #39 ~/.claude/.ai names kept under the own-repo edge case). Craig approved.
+
+Committed 3eed289, pushed 4779ce8..3eed289. Replied to work (2026-06-05-0028-from-rulesets-done...org), cleared handoff, inbox clean. Note: takes effect on every project's next session (it's a startup doc); no restart needed for the doc itself.
+
+Next: resume the pattern-catalog decision Craig was about to make.
+
+** Built the pattern catalog (approved as written, converted to org)
+
+Craig approved the spec as written (option 1). Read the four pearl source notes in docs/design/ for the real pattern content (didn't reconstruct from memory). Built patterns/ with 6 seed patterns + README + claude-rules/patterns.md pointer. First draft was .md (justified from DECISION 1's "mirrors memory/ and claude-rules/"); I flagged the .md-vs-.org call. Craig said convert to org.
+
+Converted all 6 patterns + README to .org with #+KEYWORD frontmatter (#+SLUG/#+PRINCIPLE/#+PROBLEM/#+TAGS/#+SOURCE/#+EXAMPLES), dropped em-dashes, org [[file:...]] links. The pointer claude-rules/patterns.md stays .md — the Makefile RULES glob is claude-rules/*.md and Claude Code loads .md rules, so a .org pointer wouldn't install or load. Verified: all 7 org files parse via emacs --batch org-element-parse-buffer; all cross-links resolve; every pattern has slug-matches-filename + 7 keyword fields; zero em-dashes.
+
+Publish flow (run on the .md draft, re-verified after org conversion): review-code --staged Approve, no Critical/Important, one Minor (pearl names in examples — fine for the private rulesets remote, watch downstream if cited in a deepsat artifact). /voice personal on commit msg (subject 69 chars, em-dash→colon/comma, 2 semicolons→periods, passive opener→active); after org conversion I corrected the last paragraph (.md→.org, README.md→README.org, dropped a new semicolon).
+
+todo.org: parent ** TODO [#B] Cross-project pattern catalog → DONE + CLOSED [2026-06-05 Fri]; the VERIFY rewritten to two dated log entries (spec approved + catalog built), both reflecting the .org decision.
+
+Committed 83bf3cb, pushed 3eed289..83bf3cb. todo.org + notes.org marker + session-context still unstaged — ride to wrap-up.
+
+Open: the .md-vs-.org choice is resolved (.org). Catalog's first real test is a consuming agent reaching for a pattern while designing a prompt flow.
diff --git a/docs/design/2026-06-05-org-roam-knowledge-base-spec.org b/docs/design/2026-06-05-org-roam-knowledge-base-spec.org
new file mode 100644
index 0000000..5799fc1
--- /dev/null
+++ b/docs/design/2026-06-05-org-roam-knowledge-base-spec.org
@@ -0,0 +1,84 @@
+#+TITLE: Org-roam as the shared agent knowledge substrate — Spec
+#+AUTHOR: Craig Jennings & Claude
+#+DATE: 2026-06-05
+
+One-page spec for adopting the existing org-roam knowledge base as the shared, cross-project knowledge store agents read from and write to. Drafted for Craig's review. The five decisions below each carry a recommended call, marked DECISION. DECISION 5 (the work/personal write boundary) is the one that needs Craig's ratification rather than a default; the others are mechanics.
+
+* Problem
+
+Per-project agent memory lives at =~/.claude/projects/<encoded-cwd>/memory/=, a harness-owned path that is unmanaged and unsynced, so it doesn't survive a new-machine setup. Two earlier approaches were explored and dropped: a dedicated =claude-memory.git= repo (built, then reversed because it pooled work-confidential and personal memory into one repo), and a two-tier split (general lessons to rules, project memory to each project's =.ai/=, which left public-remote code projects' memory at-risk by design).
+
+The simplification: =~/sync/org/roam/= already exists. 484 org files curated since 2023, synced across machines by Syncthing. Cross-machine sync is already solved for anything living there. So the task stops being "build a memory-sync system" and becomes "point agents at the knowledge base that already syncs."
+
+* Current state
+
+Three distinct layers, today:
+
+- *Rules* (=claude-rules/*.md= symlinked into =~/.claude/rules/=, plus per-project =CLAUDE.md=). Always-on instructions, loaded every session. Synced via the rulesets clone.
+- *Harness memory* (=~/.claude/projects/<enc>/memory/=). Small, per-project, auto-recalled by the harness into system reminders. Unsynced, at-risk.
+- *Org-roam KB* (=~/sync/org/roam/=). Large, human-curated, Syncthing-synced. Not currently agent-readable or agent-writable by convention.
+
+This spec leaves the rules layer untouched. It connects the KB to agents and redefines harness memory's role.
+
+* Design
+
+** DECISION 1 — The KB is a queried substrate, accessed as files, not via the org-roam package
+
+An agent is a harness process, not an Emacs session. It cannot call org-roam's Elisp API or read its SQLite cache. It treats =~/sync/org/roam/= as what it physically is: a directory of plain org files with =#+title=, =#+filetags=, an =:ID:= property drawer, and =[[id:UUID][desc]]= links. The agent searches with ripgrep over content and tags, and follows a link by grepping for its target =:ID:=. 484 tagged, linked text files is a strong agent substrate. The backlink graph and db are Craig's Emacs convenience; the files are the agent's interface.
+
+** DECISION 2 — Capture in harness memory, promote into the KB
+
+Harness memory and the KB are kept, with distinct roles that mirror the pattern-catalog's capture-on-landing / promote-on-review cadence:
+
+- *Harness memory = capture.* Fast, automatic, per-project, relevance-recalled. Treated as an ephemeral working set: regenerable, allowed to be at-risk, because nothing durable depends on it surviving.
+- *Org-roam KB = promote.* Durable or cross-machine-valuable facts get written into the KB, where Syncthing carries them to every machine and Craig curates them.
+
+This resolves the original at-risk problem without a new sync mechanism: the valuable knowledge lives in the synced KB; what stays in unsynced harness memory is by definition the low-value, regenerable hot set. Promotion is a deliberate step (a wrap-up or task-audit pass, or an explicit prompt), not automatic.
+
+** DECISION 3 — Surfacing: a pointer rule
+
+A new =claude-rules/knowledge-base.md= rule (auto-installs via the Makefile RULES glob, same as =patterns.md=) tells the agent: the KB lives at =~/sync/org/roam/=; query it with ripgrep before relying on a remembered project fact, a prior decision, or reference material; follow =[[id:]]= links by grepping the ID; and write durable facts back per the schema in DECISION 4, honoring the scope rule in DECISION 5. The rule is the bridge; it carries the path, the query method, the write schema, and the boundary.
+
+** DECISION 4 — Write schema, so the KB stays trustworthy
+
+Agent-written nodes follow org-roam conventions so Craig's Emacs indexes them on the next =org-roam-db-sync=, and carry a marker so agent notes stay distinguishable from Craig's hand-authored ones:
+
+#+begin_example
+:PROPERTIES:
+:ID: <generated uuid>
+:END:
+#+title: <concise title>
+#+filetags: :agent:<scope>:
+
+<the fact, with [[id:...]] links to related nodes>
+#+end_example
+
+Filename follows roam's timestamp-prefix convention (=YYYYMMDDHHMMSS-slug.org=). The =:agent:= filetag makes =rg '#\+filetags:.*:agent:'= a clean inventory of what agents wrote, so Craig can review or prune. Node granularity (one node per fact vs a per-project agent-notes node appended to) is an open question below.
+
+** DECISION 5 — The work/personal write boundary (needs Craig's ratification)
+
+This is the decision that sank the dedicated-repo design and it returns here. =~/sync/org/roam/= is Craig's personal KB on his personal machines. The risk is asymmetric and lives on the write side: if a work (DeepSat) agent writes into it, confidential work facts pool into a personal all-machines store. Reading is lower-risk and already governed by the content-scope rules in =commits.md= (personal facts must not surface in team artifacts).
+
+Three options:
+
+- *A — Work walled off.* The shared KB is personal-only. Work agents neither read nor write it; work keeps its knowledge in its own project tree. Zero leak risk, but work gains nothing from the KB.
+- *B — One KB, tag-scoped.* Everything in the KB, every node tagged =:work:= / =:personal:= / =:general:=. Agents recall only current-scope plus =:general:=, and a rule forbids cross-scope surfacing. Maximal sharing, but confidential work data sits one tag-mistake away from the wrong machine or artifact.
+- *C — Read-shared, write-scoped (recommended default).* Any project may read the shared KB. Personal projects write to it; work writes only to its own store, never the shared KB. Captures the reading value everywhere while keeping confidential work data physically out of the personal Syncthing KB. The inverse risk (personal facts in work output) stays governed by existing content-scope rules.
+
+Recommended: C, pending Craig's read on two facts only he has — how sensitive the work memory is, and whether Syncthing even replicates =~/sync/= to any work machine (if it doesn't, a work-machine agent can't read the KB regardless, which pushes toward A for work). If work confidentiality is strict, fall back to A.
+
+* Acceptance
+
+- =claude-rules/knowledge-base.md= exists: KB path, when-to-query, how-to-query (ripgrep + ID-follow), the write schema, and the ratified scope rule from DECISION 5.
+- The write schema is documented and produces nodes Craig's =org-roam-db-sync= indexes cleanly.
+- An agent in a personal project can find a relevant prior note by querying the KB, and append a new node that shows up in Craig's org-roam.
+- The harness-memory-as-capture / KB-as-promote split is documented, with the promotion trigger named.
+- The work/personal boundary is decided and encoded in the rule.
+
+* Open questions for Craig
+
+- *DECISION 5 itself* — A, B, or C. The central call.
+- *Syncthing topology* — does =~/sync/= replicate to any work machine? Bounds DECISION 5.
+- *Node granularity* — one node per fact (roam-native, linkable, more files) vs a per-project agent-notes node appended to (less sprawl, less linkable). Spec leans per-fact nodes tagged =:agent:=.
+- *Harness memory's fate* — keep the thin auto-recalled hot set (spec's lean, DECISION 2), or retire it entirely and have the agent query the KB at session start instead.
+- *Write review* — Syncthing has no git-style review gate. Do agent writes land freely, or get a lightweight review (e.g. written to an =:agent:inbox:= tag Craig promotes)? Relates to trust in DECISION 4.
diff --git a/todo.org b/todo.org
index 248c900..212bf03 100644
--- a/todo.org
+++ b/todo.org
@@ -34,30 +34,6 @@ Tags are assigned and refreshed by =task-audit=; =task-review= keeps them honest
* Rulesets Open Work
-** TODO [#B] Cross-project pattern catalog :spec:thinking:
-:PROPERTIES:
-:LAST_REVIEWED: 2026-06-02
-:END:
-
-From pearl handoffs [[file:docs/design/2026-05-27-pattern-catalog-pearl-notes.org][2026-05-27]] + [[file:docs/design/2026-05-28-pattern-catalog-no-empty-input.org][2026-05-28 follow-up]].
-
-Meta-question: how do good patterns travel from project A to project B? Pearl shipped three worked examples worth capturing — one-prompt picker with typed prefix (pearl-pick-source), magit-transient state buttons, and "no empty input as meaningful" (none-sentinel as first candidate). Each is a small principle with wide surface area; without a catalog, every project re-derives them from scratch.
-
-Open design questions before any implementation:
-- Catalog format — structured (one pattern per file with frontmatter) vs free-form doc
-- Surfacing mechanism — agent-driven (model spots opportunity) vs human-driven (Craig grep-searches)
-- Anti-patterns included or only what worked
-- Intake cadence — every time one lands, or batch review
-- Home — rulesets repo (agent visibility) vs Linear doc vs per-project cross-links
-
-Pearl recommends a one-page spec (problem + design + open questions + acceptance) before implementation. Pearl available to come back for spec-review iterations.
-
-*** 2026-05-28 Thu @ 08:12:55 -0500 Pearl shipped patterns 4-6, filed alongside the prior two
-Three more pearl handoffs landed and were filed during this audit. Filed: [[file:docs/design/2026-05-28-pattern-catalog-prompt-labels-and-defaults.org][prompt-labels-and-defaults]] (patterns 4-5: label-matches-behavior, default-most-common with friction-proportional-to-consequence) and [[file:docs/design/2026-05-28-pattern-catalog-prompt-collapse.org][prompt-collapse]] (pattern 6: collapse N orthogonal prompts into one enriched prompt). The catalog's evidence base is now four pearl notes in =docs/design/= covering six patterns plus the synthesizing principle Pearl articulated — "choices on screen, accurately labeled, ordered by what the user most often wants, friction sized to the cost of being wrong."
-
-*** VERIFY Review the pattern-catalog spec (5 decisions + 3 open questions)
-One-page spec drafted 2026-06-02: [[file:docs/design/2026-06-02-pattern-catalog-spec.org][2026-06-02-pattern-catalog-spec.org]]. It makes a recommended call on each of the five open design questions — format (one file per pattern with frontmatter), home (a =patterns/= dir in rulesets), surfacing (a thin =claude-rules/patterns.md= pointer, agent-driven), anti-patterns (a field within each pattern), intake (capture-on-landing, promote-on-review) — plus three smaller open questions (directory name, generalize-now-vs-lazily, whether a =/pattern= skill is worth it). Implementation is gated on your review. Pearl is available for spec-review iterations.
-
** TODO [#C] Check that memories are sync'd across machines via git :spec:
:PROPERTIES:
:LAST_REVIEWED: 2026-06-02
@@ -98,6 +74,14 @@ Created bare =git@cjennings.net:claude-memory.git=, cloned to =~/.claude-memory=
*** 2026-05-24 Sun @ 01:53:35 -0500 Reversed the migration — back to unmanaged per-project memory
Cancelled the follow-up brainstorm and undid the dedicated-repo migration at Craig's call. Moved all 7 memory dirs back to =~/.claude/projects/<enc>/memory/= (content preserved), deleted the =~/.claude-memory= clone, and deleted the bare =claude-memory.git= on the server. Memory is back to its original at-risk state, so the task reopens at [#C] pending a direction. The brainstorm landed on a two-tier idea for whenever this resumes: promote general lessons into a rulesets-tracked file symlinked into =~/.claude/rules/= (loaded into every project natively, one repo), and keep project-specific memory under each project's own =.ai/memory/= (committed where =.ai/= is tracked, at-risk where it's gitignored). Not implemented.
+
+*** 2026-06-05 Fri @ 05:57:35 -0500 Pivot: adopt the existing org-roam KB as the shared agent substrate
+Pressure-tested the two-tier idea, then Craig redirected: a shared org-roam knowledge base any project can read and write makes this simpler. Ground truth verified: =~/sync/org/roam/= already exists (484 org files, curated since 2023, Syncthing-synced, not git). So cross-machine sync is already solved, and the task stops being "build a memory-sync system" and becomes "point agents at the KB that already syncs." The dedicated-repo and two-tier approaches are both superseded for the storage+sync half.
+
+Wrote a one-page spec: [[file:docs/design/2026-06-05-org-roam-knowledge-base-spec.org][2026-06-05-org-roam-knowledge-base-spec.org]]. Five decisions, mechanics recommended: (1) KB is a queried substrate accessed as files (ripgrep + follow =[[id:]]= by grep), not via the org-roam package; (2) capture in harness memory, promote durable facts into the KB (same cadence as the pattern catalog) — resolves the at-risk problem since the valuable knowledge moves to the synced KB; (3) a =claude-rules/knowledge-base.md= pointer rule carries path/query/write-schema/boundary; (4) write schema = roam-valid node + =:agent:= filetag so agent notes stay distinguishable and index on the next =org-roam-db-sync=. The rules layer (=claude-rules/=, =CLAUDE.md=) is untouched — the KB replaces the memory tier, not the rules tier.
+
+*** VERIFY Decide the work/personal write boundary (spec DECISION 5) + ratify the org-roam-KB spec
+The spec's central decision needs Craig's call: the shared KB is personal and on all personal machines, so a work (DeepSat) agent writing into it pools confidential work facts there. Three options in the spec: A — work walled off (personal-only KB); B — one KB tag-scoped (=:work:=/=:personal:=/=:general:=, agent forbidden to cross-surface); C (recommended) — read-shared, write-scoped (any project reads; personal projects write to the KB, work writes only to its own store). Recommendation C hinges on two facts only Craig has: how sensitive work memory is, and whether Syncthing replicates =~/sync/= to any work machine (if not, a work agent can't read it regardless, pushing work toward A). Other open questions in the spec: node granularity (per-fact vs per-project agent-notes node), harness memory's fate (keep thin hot-set vs retire), and whether agent writes land freely or via an =:agent:inbox:= review (Syncthing has no git gate). Once DECISION 5 lands, implement the pointer rule + write schema.
** TODO [#C] Build =create-documentation= skill for high-quality project/product docs :feature:
:PROPERTIES:
:LAST_REVIEWED: 2026-06-02
@@ -2497,3 +2481,30 @@ CLOSED: [2026-06-02 Tue]
:LAST_REVIEWED: 2026-06-02
:END:
From Craig (2026-06-02). The Approach phase should consider whether the work needs a spec when one doesn't already exist. For a big task, this isn't a silent skip — the pre-confirmation summary must explicitly report why a spec isn't needed, so the decision is visible and challengeable at the gate rather than assumed. Small tasks can pass without comment. Edit the start-work skill's Approach-gate phase to add the spec-needed consideration and the big-task report-why-not requirement.
+** DONE [#B] Cross-project pattern catalog :spec:thinking:
+CLOSED: [2026-06-05 Fri]
+:PROPERTIES:
+:LAST_REVIEWED: 2026-06-02
+:END:
+
+From pearl handoffs [[file:docs/design/2026-05-27-pattern-catalog-pearl-notes.org][2026-05-27]] + [[file:docs/design/2026-05-28-pattern-catalog-no-empty-input.org][2026-05-28 follow-up]].
+
+Meta-question: how do good patterns travel from project A to project B? Pearl shipped three worked examples worth capturing — one-prompt picker with typed prefix (pearl-pick-source), magit-transient state buttons, and "no empty input as meaningful" (none-sentinel as first candidate). Each is a small principle with wide surface area; without a catalog, every project re-derives them from scratch.
+
+Open design questions before any implementation:
+- Catalog format — structured (one pattern per file with frontmatter) vs free-form doc
+- Surfacing mechanism — agent-driven (model spots opportunity) vs human-driven (Craig grep-searches)
+- Anti-patterns included or only what worked
+- Intake cadence — every time one lands, or batch review
+- Home — rulesets repo (agent visibility) vs Linear doc vs per-project cross-links
+
+Pearl recommends a one-page spec (problem + design + open questions + acceptance) before implementation. Pearl available to come back for spec-review iterations.
+
+*** 2026-05-28 Thu @ 08:12:55 -0500 Pearl shipped patterns 4-6, filed alongside the prior two
+Three more pearl handoffs landed and were filed during this audit. Filed: [[file:docs/design/2026-05-28-pattern-catalog-prompt-labels-and-defaults.org][prompt-labels-and-defaults]] (patterns 4-5: label-matches-behavior, default-most-common with friction-proportional-to-consequence) and [[file:docs/design/2026-05-28-pattern-catalog-prompt-collapse.org][prompt-collapse]] (pattern 6: collapse N orthogonal prompts into one enriched prompt). The catalog's evidence base is now four pearl notes in =docs/design/= covering six patterns plus the synthesizing principle Pearl articulated — "choices on screen, accurately labeled, ordered by what the user most often wants, friction sized to the cost of being wrong."
+
+*** 2026-06-05 Fri @ 00:47:59 -0500 Spec approved as written — all 5 decisions + 3 open questions accepted
+Craig approved the spec ([[file:docs/design/2026-06-02-pattern-catalog-spec.org][2026-06-02-pattern-catalog-spec.org]]) as written. Confirmed: one file per pattern with frontmatter; home =patterns/= in rulesets; thin =claude-rules/patterns.md= pointer, agent-driven; anti-patterns as a per-pattern field; capture-on-landing/promote-on-review intake. Open questions resolved to the spec's leans: directory name =patterns/=; concrete-now, generalize-on-second-use; manual promote flow first, no =/pattern= skill yet. Built as =.org= files with =#+KEYWORD= frontmatter (Craig's call over the initial =.md= draft); the =claude-rules/patterns.md= pointer stays =.md= since the rules layer and the Makefile glob require it.
+
+*** 2026-06-05 Fri @ 00:47:59 -0500 Built the catalog — 6 seed patterns + pointer + README
+Created =patterns/= with the six seed patterns (one-prompt-picker-typed-prefix, transient-state-buttons, no-empty-input-as-meaningful, label-matches-behavior, default-most-common-friction-proportional, collapse-orthogonal-prompts), each carrying the frontmatter contract (name/principle/problem/tags/source/examples) plus Problem/Do/Anti-pattern/Applicability/Related sections. =patterns/README.org= states the root principle, the frontmatter contract, and the intake cadence. =claude-rules/patterns.md= is the agent-facing pointer, auto-installed via the Makefile RULES glob. Sourced from the four pearl notes in =docs/design/=.