summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-24 03:30:26 -0500
committerCraig Jennings <c@cjennings.net>2026-05-24 03:30:26 -0500
commit8270a4e94e3bdd7cb52a93f9f4b74c1ae6ad6c4f (patch)
tree73a33c5875b4072574bf9bcc3bb5f3359b7f8570
parent51c8c2fe8069740ce79fdb60431da71a23d9a7f9 (diff)
downloaddotemacs-8270a4e94e3bdd7cb52a93f9f4b74c1ae6ad6c4f.tar.gz
dotemacs-8270a4e94e3bdd7cb52a93f9f4b74c1ae6ad6c4f.zip
docs(todo): split Implement ai-kb tasks into 1a/1b and fold in review-5 hardening
I reorganized the Implement ai-kb children into the Step 1a / 1b phases from the spec: 1a is the safe write path (store, contract, the index/lint/remember/doctor CLI, the adapter, provisioning), and 1b is query/curate/sync, the push timer, and the curation workflow. The remember task now gates the commit on the full ai-kb lint rather than node org-lint, the test tasks target the org-lint fatal-check list and the query --json contract, the push task carries the failure-observability surfaces, and the pointer convention is ID-first throughout.
-rw-r--r--todo.org43
1 files changed, 43 insertions, 0 deletions
diff --git a/todo.org b/todo.org
index 24876fb6..ef9eb9a0 100644
--- a/todo.org
+++ b/todo.org
@@ -41,6 +41,49 @@ Tags are additive. For example, a small wrong-behavior fix can be
=:bug:quick:=, and a feature that requires internal restructuring can be
=:feature:refactor:=.
* Emacs Open Work
+** PROJECT [#B] Implement ai-kb :feature:ai-kb:
+Build v1 of the AI knowledge base per [[file:docs/design/ai-kb.org][docs/design/ai-kb.org]] (Ready; five reviews incorporated, all decisions resolved 2026-05-24). Step 1 splits into 1a (the safe write path — minimum usable) and 1b (retrieval, maintenance, push), since =remember= depends on =index=+=lint= and the adapter depends on =remember=. Step 2 is the Emacs browsing layer. Step 3 and the LLM-Wiki layer are vNext. Children are ordered by build sequence; the server bootstrap is the prerequisite.
+
+*** TODO [#B] ai-kb bare repo on cjennings.net :ai-kb:
+Prerequisite, one-time server bootstrap (not doable by the local script): =sudo git init --bare /var/git/ai-kb.git= + chown on cjennings.net. Leave the github-mirror hook OFF — this repo is private. Required before every per-machine clone.
+
+*** TODO [#B] ai-kb store + contract + seed :ai-kb:
+Step 1a. Clone =git@cjennings.net:ai-kb.git= to =~/.local/share/ai-kb=. Author =AGENT_CONTRACT.org= (canonical repo-resident contract: node format, write protocol, operations, routing) and seed =index.org= + a README/index node with a generated =:ID:=. Node format per spec — provenance (=:CREATED_BY:/:CONFIDENCE:/:VISIBILITY:/:SOURCE:/:STATUS:=), =:PROJECTS:= slugs, type filetags, relation labels. Define the durable external-pointer format as *ID-first*: =ai-kb: <Title> (<UUID>)=, resolved by ID with title fallback (filenames can change in curation).
+
+*** TODO [#B] ai-kb CLI 1a: index, lint, remember, doctor :ai-kb:
+Step 1a. Shell wrapper calling =emacs --batch= for org work. =index= regenerates =index.org= from node properties (never hand-maintained). =lint= = org-lint fatal checks + duplicate IDs + broken id-links (excl =raw/=) + missing required props + bad project slugs + stale/incomplete index + credential scan of nodes *and* =raw/=. =remember= = the write protocol: fetch + =pull --ff-only= (abort on diverge/dirty), write, regenerate index, then run the *full =ai-kb lint=* over the change as the commit gate (not just node org-lint — this is the safety boundary), commit locally, =flock=; no push. =doctor= = health + push-state report (repo, private remote, CLI on PATH, adapter linked, db buildable, no secrets, "ahead N"/"push failed"/"diverged").
+
+*** TODO [#B] claude-rules/ai-kb.md adapter :ai-kb:
+Step 1a. Global L1 rule in rulesets pointing at the repo-resident =AGENT_CONTRACT.org=: path, routing (T1/T2/T3 tiers; per-project =MEMORY.md= shrinks to ID-first pointers into ai-kb), proactive + contradiction rules, concrete "read the index first" triggers, link-grep recipes, "use =ai-kb remember=, never bypass =ai-kb lint=", one-line nudge on unpushed commits / recorded push rejection. =make install= symlinks it into =~/.claude/rules/=.
+
+*** TODO [#B] ai-kb provisioning: setup-ai-kb.sh + make ai-kb-init :ai-kb:
+Step 1a (core; the timer-install line is added with 1b). Idempotent =scripts/setup-ai-kb.sh=: clone (or init+add-remote on first machine), seed, install the CLI on PATH, =ai-kb index=, =ai-kb doctor=. =make ai-kb-init= wraps it. The one-time server bootstrap stays a separate documented step.
+
+*** TODO [#B] ai-kb Step-1a tests :ai-kb:tests:
+Write-path: a write with the remote unreachable still commits locally and does not error; =flock= serializes concurrent =remember=; each org-lint *fatal* check (malformed drawer, missing/dup =:ID:=, invalid required property, missing =#+title:=, unparseable org) rejects the commit, a style warning does not; =remember= aborts the commit when the *full* lint fails (stale index, broken link, secret in =raw/=). Index: regen from a fixture produces expected entries; an out-of-band node appears only after regen. Link recipes: backlink (excl =raw/=) + forward correct. Provisioning (bats): idempotent, valid =:ID:=, =doctor= passes.
+
+*** TODO [#B] ai-kb CLI 1b: query, curate, sync :ai-kb:
+Step 1b. =query <context>= with a *testable contract*: plain-text default + =--json=; fields title/ID/summary/projects/status/updated/path; searches index rows + title/tags/properties/body; default max-results + most-recently-updated ordering; =raw/= paths only as source references; exit codes for no-match / invalid KB / lint-index failure. =curate --dry-run= (four buckets; destructive ops human-only). =sync= (=org-roam-db-sync= against ai-kb).
+
+*** TODO [#B] ai-kb push timer + failure observability :ai-kb:
+Step 1b. =ai-kb-push.timer= + =ai-kb-push.service= =systemd --user= units: push only if ahead, ~15 min; installed + =enable --now= by the setup script (add this line to =setup-ai-kb.sh=). A failed push is logged to a state file (=$XDG_STATE_HOME/ai-kb=), never fatal; surfaced by =ai-kb doctor= and the adapter's startup nudge.
+
+*** TODO [#B] ai-kb-curate workflow in rulesets :ai-kb:
+Step 1b. =~/code/rulesets/.ai/workflows/ai-kb-curate.org= — human-gated curation: the four buckets, node-count trigger, =:LAST_CURATED:= rotation, pointer-integrity (merge/supersede changes the canonical ID, so grep inbound =[[id:]]= + =MEMORY.md= =ai-kb: ... (UUID)= refs and repoint before deleting). Surfaced by =ai-kb doctor= + session startup when due.
+
+*** TODO [#B] ai-kb Step-1b tests :ai-kb:tests:
+=query --json= returns the specified fields/ordering/exit-codes on a fixture KB and =raw/= appears only as a source ref; a simulated push failure is recorded to the state file and surfaced by =ai-kb doctor=.
+
+*** TODO [#B] Emacs: org-roam ai-kb switch + guard :ai-kb:
+Step 2.
+=org-roam-config.el=: ai-kb dir constant + =org-roam-ai.db=; =cj/org-roam-switch-to-ai-kb= / =cj/org-roam-switch-to-personal= with the guard contract — rescope the completed-task→daily hook, sync on entry, restore both vars + the hook exactly on exit, re-assert personal state at startup (abnormal-exit safety). =cj/ai-kb-db-sync= helper; =org-roam-file-exclude-regexp= excludes =raw/=.
+
+*** TODO [#B] Emacs: ai-kb keybindings + which-key :ai-kb:
+Bind the switch + sync commands under the =C-c n= roam prefix (e.g. =C-c n a= → ai-kb, =C-c n A= → personal), avoiding the dense existing set; which-key labels.
+
+*** TODO [#B] Emacs: ai-kb Step-2 ERT tests :ai-kb:tests:
+Switch sets the ai-kb dir + db; switch-back restores the personal values exactly; the completed-task hook does not fire into ai-kb while switched; startup re-asserts personal state after a simulated abnormal exit.
+
** TODO [#C] Manually verify cj/org-finalize-task journal copy :test:
Confirm the live behavior the unit tests mock out. In a real Emacs (org-roam loaded), run =C-; O d= on a level-3 sub-task and on a level-2 task. Expect the sub-task to flip to a dated entry, the level-2 to keep its keyword and gain a date-only CLOSED line, and in both cases a copy to land in today's daily under "Completed Tasks".
Triggered by: 2026-05-22 L56 finalize-task work.