diff options
| -rw-r--r-- | .ai/notes.org | 2 | ||||
| -rw-r--r-- | .ai/sessions/2026-07-13-23-48-runtime-portability-pager-local-llm.org | 191 | ||||
| -rw-r--r-- | archive/task-archive.org | 180 | ||||
| -rw-r--r-- | todo.org | 190 |
4 files changed, 377 insertions, 186 deletions
diff --git a/.ai/notes.org b/.ai/notes.org index 52c92b0..380d4a8 100644 --- a/.ai/notes.org +++ b/.ai/notes.org @@ -82,6 +82,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-07-04 -:LAST_INBOX_PROCESS: 2026-07-11 (11 handoffs cleared. 6 shipped: triage-intake gmail 100-cap 81ca16f; PR-review drop-praise 99bd213; ui-prototyping rule 53f6ce6; desktop-capture rule 8ddd3d3; bug-matrix double-count 06ca6c7; staleness org-date parse cfbabf1. 2 filed as tasks: org-table-helpers data-loss bug [#B], Signal-pager doc [#C]. AI-attribution handoff confirmed already-landed. All senders replied.) +:LAST_INBOX_PROCESS: 2026-07-13 (three passes: morning 3 handoffs incl. two shared-asset rule proposals shipped; evening validate-el fix + 4 acks; roam inbox emptied twice, 10 foreign items routed to owners) Format: one =:MARKER: YYYY-MM-DD= line per workflow. Workflows overwrite their own marker on completion. diff --git a/.ai/sessions/2026-07-13-23-48-runtime-portability-pager-local-llm.org b/.ai/sessions/2026-07-13-23-48-runtime-portability-pager-local-llm.org new file mode 100644 index 0000000..8e55623 --- /dev/null +++ b/.ai/sessions/2026-07-13-23-48-runtime-portability-pager-local-llm.org @@ -0,0 +1,191 @@ +#+TITLE: Session Context — 2026-07-13 +#+AUTHOR: Craig Jennings + +* Summary + +** Active Goal + +A marathon (05:14–23:59) that became four arcs: (1) the runtime-portability children — all eight resolved, ending with a working local-LLM agent lane; (2) the EAT sixel investigation — persistent terminal images plus two dead .emacs.d agents root-caused (OOM from an EXDATE infinite loop, fixed cross-project); (3) the agent pager — Signal paging reconciled, verified, wrapped in a universal agent-page command; (4) full backlog hygiene — inbox zero on both surfaces repeatedly, task-review staleness driven to zero. + +** Decisions + +- Craig kept the fable model pin (d5bc9b3 accidentally committed only a case change — harness rewrote the file pre-staging; corrected in e91073d). +- Thin-pointer AGENTS.md over a generated monolith for non-Claude bootstrap ("1 is the way to go. definitely"). +- All four inventory decisions approved (PreCompact prose downgrade, Stop-teardown via codex notify/manual, Signal-pager portability note, knowledge-base.md capture-layer sentence). +- Signal pager re-graded [#C]→[#B]; ntfy two-way-comms task KILLED (infrastructure torn down 07-04; agent-page + Signal runbook are successors). +- Drop all four legacy ollama models after verification; MoE over dense for Strix Halo; Vulkan backend forced over ROCm (systemd override). +- "Agent pager" naming (the Slough House of pagers); paging documented as two channels everywhere. +- EXDATE fix applied from here (cross-project, Craig-directed); jotto SVG rule and takuzu EAT-visuals rule both accepted with changes; .emacs.d's validate-el.sh load-prefer-newer fix accepted verbatim. + +** Data Collected / Findings + +- tmux transmits sixel only when TERM_SIXEL is set AND the client's cell pixel size is known; stock EAT 0.9.4 silently drops the CSI 14 t query (no t case in its dispatch). EAT persists sixel in scrollback natively; through tmux, passthrough images are write-once but native-path images survive redraws. +- Both .emacs.d agent deaths were kernel OOM kills (111GB emacs) from calendar-sync--get-exdates reading (match-end 0) after split-string clobbered the match data — infinite loop only on comma-separated EXDATE lines far enough into the string. My first two diagnoses (stale sentinel; double-reply keystroke leak) were wrong; the double-reply was real but non-lethal. +- signal-mcp is a velox-local MCP server, not claude.ai-side; the pager identity +15045173983 lives in velox's signal-cli; ratio's signal-cli is Craig's own number (no push). Receive-staleness warnings on both accounts. +- Strix Halo: ROCm allocates correctly but first-touch loads at <25MB/s (unusable for 61GB); Vulkan loads the same model in 44s. gpt-oss:120b: 37.9 tok/s; qwen3-coder:30b: 76 tok/s; both 100% GPU. num_ctx matters (native 128K balloons loads). codex --oss needs --local-provider=ollama explicitly (config.toml append lands in the last TOML table, silently inert). +- The remembered old launcher was aix + hey, removed from dotfiles 2026-04-20 (dab0d5a); bin/ai is their unified successor. lint-org.el's mutate-on-lint defect self-demonstrated during this wrap (no damage — no pipes in example blocks). + +** Files Modified + +Rulesets (16 commits, all pushed through 3984392): SVG rule (cac1aa1), visuals rule + zsh note (8703150), model pin ×2 (d5bc9b3, e91073d), runtime child tasks (1b638e6), inventories doc + decisions + skill parity (44bc344, 0ee94ab), AGENTS.md entry + install paths (6cd3aa3), launcher --runtime / local lane / agent picker (04c3b29, 1b98a9e, 3eed2e1), agent-page + two-channel paging docs (49be354), validate-el.sh fix (7e61dc0), model-floor status (21d14e0), review close-outs (0de6e09, 3984392). Plus dotfiles 5055ef1 (tmux sixel conf, pushed) and .emacs.d 56a3ed86 (EXDATE fix, committed there). System: ollama 0.31.2 + Vulkan override; ~/.codex/AGENTS.md link; two KB node writes (roam-synced). + +** Next Steps + +- Craig's maiden voyage: ai → pick local:gpt-oss:120b → takuzu; watch for skipped startup/gates/session-log/commit-rules — that's the model-floor eval running live. The formal scripted eval remains on the child. +- Signal-pager [#B]: runbook, receive timer on velox, ssh-vs-linked-device decision. +- Watch for .emacs.d's ai-term multi-LLM work (they're shelling out to ai --print-runtimes); upstream EAT PR is their [#D]. +- Backlog is fully current; org-table [#B] bug and launcher-hardening [#C] are the natural next builds. + +* Session Log + +** 2026-07-13 Mon 15:25 — SECOND .emacs.d death root-caused: OOM from an EXDATE infinite loop (my first diagnosis was wrong) + +Craig reported death #2 (launch 14:32, [exited] 14:55:36) — AFTER my double-reply fix, so that diagnosis fell. Corrections to the record: the transcript "queue-operations" are harness task-notification bookkeeping, NOT leaked keystrokes (my death-1 keystroke story loses its evidence — the double-reply leak was real and measured but likely never killed anything); the final "background task killed" entries are claude's SIGHUP handling. Hard evidence chain: EAT scrollback shows no bash prompt before [exited] (session destroyed under a live claude); journalctl nails BOTH deaths to the second — kernel OOM killer at 13:41:57 (emacs, 111GB anon-rss!) and 14:55:36, each inside the session's tmux-spawn scope, which systemd then failed, killing the pane → single-window session gone. The bomb: tests/test-calendar-sync--get-exdates.el's two comma-separated tests (NEW in a9e61207, the off-anchor EXDATE fix) hang forever: calendar-sync--get-exdates sets pos from (match-end 0) AFTER split-string, whose internal string-match clobbers match data → pos becomes the last comma's offset within the VALUE; when that's smaller than the EXDATE line's position, the loop re-matches the same line forever, growing the list to OOM. Verified: exact test string hangs the loaded .elc; bytecode disassembly confirms match-end after split-string; comma-less values don't clobber (failed string-match preserves match data), which is why only the two new tests bomb. Fix shape: capture (match-end 0) into a local BEFORE split-string (or save-match-data). Daemon check: calendar-sync loaded but NO timer → no live-daemon exposure right now. Side finding for the handoff: test-ai-term--show-or-create.el leaks one real tmux list-sessions call past its mocks (read-only, benign, but a mock gap; caught with a tmux PATH shim). Suite-under-shim full run unnecessary — OOM evidence is conclusive. Instruction-bootstrap build parked mid-scoping (no edits yet). Next: Craig decides fix-from-here vs handoff to the .emacs.d agent. + +** 2026-07-13 Mon 23:50 — inbox cleared again + task review COMPLETE (staleness zero) + +Handoff round: .emacs.d's validate-el.sh load-prefer-newer fix accepted verbatim (diff = exactly the two claimed evals; suite green; commit 7e61dc0 PUSHED; reply sent); takuzu ack deleted (all five routed captures filed there as three [#B] tasks); two more acks arrived mid-work and were processed (.emacs.d multi-LLM work underway, will shell out to ai --print-runtimes — interop achieved; home recorded the pager recipe) — sent home a one-line addendum pointing at agent-page so its memory doesn't fossilize the raw ssh recipe. Then the remaining 11 reviews, Craig-delegated: ntfy two-way-comms KILLED (CANCELLED — home tore down ntfy 07-04; Signal pager + agent-page are the successors); triage-intake phone-push re-pointed at agent-page (send half buildable now, recv waits on the Signal runbook); coverage-summary docs task tagged :quick:solo:; three tasks gained missing drawers; the rest confirmed. STALENESS NOW ZERO — the whole backlog is current. Commit 3984392 PUSHED. Emacsd handoff sent earlier re ai-term alignment. Everything on origin through 3984392. Remaining: Craig's takuzu local trial (his keyboard, likely tomorrow) and the wrap. + +** 2026-07-13 Mon 23:22 — agent picker shipped: bare ai asks which brain first + +Craig asked where fzf went and wanted the flow to offer LLMs before projects. Built TDD (9/9 launcher bats, suite 441/0): build_runtime_choices (claude first, codex-as-ChatGPT, one local:<model> line per live ollama model, 3s-timeout query, dead server drops lines), pick_runtime feeding the runtime map, dispatch restructured (picker only on bare ai without --runtime/AI_RUNTIME; check_deps moved after final runtime known), --print-runtimes test seam, usage updated (sed range widened to 2,23 for the grown header). Live print verified: all four lines. Commit 3eed2e1, PUSHED. Also answered: the remembered old launcher was aix + hey in dotfiles, removed 2026-04-20 (dab0d5a) when bin/ai unified them — no shadowed script exists; and the rofi/zenity UI-picker exploration stands offered but unbuilt (rofi -dmenu -multi-select = nearest drop-in; zenity = real GTK checklist; fuzzel single-select only). Roam-ask "agentically democratic" now substantially delivered. Still open: Craig's takuzu local trial, 11 task reviews, wrap. 23:24: sent emacsd the ai-term alignment handoff (runtime map strings incl. the --local-provider gotcha, picker shape + --print-runtimes as a shell-out option, verified perf numbers + Vulkan/num_ctx caveats, AGENTS.md bootstrap note) — Craig is actively working ai-term multi-LLM with that project. + +** 2026-07-13 Mon 23:06 — local runtime LIVE: ai --runtime local = codex --oss over ollama + +Craig pushed (e91073d..21d14e0 landed) and chose to wire the local lane. Shipped TDD (7/7 launcher bats, suite 439/0): local → codex --oss --local-provider=ollama -m $AI_LOCAL_MODEL (default gpt-oss:120b), AGENT_BIN/AGENT_CMD split for the deps check. End-to-end verified: codex exec --oss through local gpt-oss returned a correct completion (~7K tokens). Gotchas learned: codex needs the provider named (flag beats config — appending oss_provider to config.toml lands in the last TOML table and silently does nothing; a stray append was made and removed, ~/.codex/config.toml back to original). Also: upstream-patch question answered — .emacs.d shipped its durable home as c53671b0 (DONE, pushed) and filed the upstream PR as its own [#D] with working/eat-sixel-patch/; nothing needed from rulesets. Recommendation given for the live local trial: takuzu (well-traveled, 78+ tests, 5 fresh small tasks, known Claude baseline); watch for skipped startup/gates/session-log/commit-rules + practical tok/s. Commit 1b98a9e PUSHED. During the edit I briefly clobbered the 16:39 dated heading in todo.org (Edit replaced a heading instead of inserting above it) — caught and repaired in the same minute. Remaining for the session: Craig's live takuzu trial (his keyboard), the leftover 11 task reviews, wrap. + +** 2026-07-13 Mon 20:20 — local inference stack verified end to end; model thread CLOSED + +The gpt-oss saga resolved: ROCm on gfx1151 allocates/offloads correctly but first-touch loads at <25MB/s — two 40-min load attempts died to client timeouts (one mine, one the ceiling; a third was killed externally ~19:00, unexplained). qwen3-coder verified first on ROCm (5s load, 76 tok/s, 100% GPU) proving the generate path, isolating the problem to big-model load speed. Fix: systemd override /etc/systemd/system/ollama.service.d/strix-halo-vulkan.conf (OLLAMA_IGPU_ENABLE=1 + ROCR_VISIBLE_DEVICES="") → Vulkan/RADV as sole inference device → gpt-oss:120b loads in 44 SECONDS, "verified", 37.9 tok/s, 100% GPU. Craig's approved drops executed: tinyllama + llama3 rm'd from the service store, the orphaned 45GB ~/.ollama user store purged. KB node rewritten with the end-state (backend, override path + revert note, per-model numbers, num_ctx gotcha, MoE-not-dense lesson) and roam-synced. Model-floor child updated: remaining work is purely the instruction-following eval (gpt-oss as target, qwen as comparator). Commit 21d14e0. Unpushed now 9: 44bc344..21d14e0. All threads from today are closed or cleanly parked; ready to wrap whenever Craig calls it. + +** 2026-07-13 Mon 18:32 — agent pager shipped; pager thread effectively closed for today + +Full sequence since 17:15: routed all 10 foreign roam items to owners via inbox-send (roam inbox at true zero, takuku typo flagged); Signal reconcile — pager identity +15045173983 lives in velox's signal-cli (signal-mcp = velox-local MCP config, NOT claude.ai-side; corrected the 14:40 inference), ratio's signal-cli is Craig's own number; live page from velox buzzed Craig's phone (confirmed). Then Craig directed universal paging + the "agent pager" rename: NEW claude-templates/bin/agent-page (velox-direct/ssh-relay, UUID baked in, fallback hint; 4 bats, PATH-stubbed; live-verified through the real script — second buzz), protocols.org Paging-Craig rewritten (two channels, signal-mcp demoted), page-me.org + work-the-backlog + INDEX updated, mirror synced, make install linked it (velox inherits next session). Suite 438/0. Commits: 0de6e09 (review+filings), 49be354 (agent pager, incl. the Signal task's dated entries + interim-recipe-to-home note). home got the recipe handoff at 18:14. Signal task remains [#B] with sharpened deliverables: runbook, receive timer, ssh-vs-linked-device. Unpushed count now 8 (44bc344..49be354). Model verification still pending: gpt-oss smoke test backgrounded (bkpjmp2iu), then qwen3-coder smoke, then the four legacy drops + KB update. + +** 2026-07-13 Mon 17:15 — task review finished (Craig delegated the close) + +Craig said "finish the task review" — applied my judgments across the remaining 6 (+1 from the morning = 8 of 18 total; 11 remain for future daily rotations). Changes: Signal pager re-graded [#C]→[#B] (paging is a real capability gap post-inventory — flagged for veto); install-ai-on-PATH tagged :quick:solo:; wrap-up-routing validation gained its missing PROPERTIES drawer; the rest confirmed as-is, all stamped 2026-07-13. Committed 0de6e09 together with the inbox-zero filings. Next per Craig: "handle some of those roam inbox items" — all 10 remaining are foreign, so the sanctioned shapes are inbox-send routing or launching owner agents; presenting options. + +** 2026-07-13 Mon 17:08 — inbox zero (roam mode) run + +Craig called inbox zero mid task-review (review paused at item 2 of 7, roam-only startup, recommendation pending). Local inbox clear. Roam scan: 12 total, 2 rulesets-claimed, 9 foreign (4 archsetup, 4 takuzu, 1 emacsd), 1 mis-prefixed "takuku:" (plainly takuzu's — left in place, typo flagged to Craig), 0 unowned, 0 empty. Claimed items deduped against today's work: the agent-switching ask is partly shipped (--runtime claude|codex 04c3b29; codex = the ChatGPT CLI; ollama/qwen = the reserved local runtime on the model-floor child) — folded as a dated entry on the generic-agent-runtime parent. The new work filed as [#C] "ai launcher hardening — bug hunt + refactor pass" :refactor:solo: (interactive runtime picker rides it). Roam edit: both claimed items removed under a clean capture-guard, roam-sync triggered (10 items remain, all foreign). todo.org edits uncommitted. Monitor for pulls retired at Craig's cue earlier; pull ETA ~18:30 at 12MB/s. + +** 2026-07-13 Mon 16:45 — session plumbing closed with a no-build verdict (8 of 8 children resolved; model-floor eval pending pulls) + +Assessed the four plumbing pieces: session-context-path runtime-aware by design; anchor cycle plain-files-portable; self-inject harness-agnostic (payload is the only Claude-shaped part — codex auto-flush = payload variant, second injected line carries the resume instruction, no hook needed); session-clear-resume.sh stays Claude-only. Section added to the inventories doc, child closed, commit 3ef5580 (suite 434/0). ALL EIGHT runtime children are now resolved or reduced: 6 shipped/closed, launcher shipped, model-floor's remaining work is the evaluation itself, blocked only on the pulls (~19:00 ETA). Unpushed: 44bc344, 0ee94ab, 6cd3aa3, 04c3b29, 3ef5580. + +** 2026-07-13 Mon 16:42 — launcher runtime flag shipped (7 of 8 children done) + +While the pulls run (rate settled ~0.5GB/min, ETA ~19:00): built ai --runtime claude|codex TDD — 6-test bats file driving a new --print-launch seam (prints the pane command, no tmux), runtime→CLI map with local reserved (clear error naming the model-eval dependency), AI_RUNTIME env support, runtime-aware deps check, CLAUDE_CMD→AGENT_CMD at all three launch sites. Verified: codex --help confirms positional-prompt parity with claude; live smoke prints correct commands both runtimes. Suite 434/0. Commit 04c3b29; child closed as dated entry. NOTE: Craig's real sessions launch via .emacs.d's ai-term (aiv-<proj> per-project sessions), NOT bin/ai (shared "ai" session, window per project) — the Emacs-side multi-LLM support is .emacs.d's June handoff, unchanged here. Craig also approved dropping tinyllama + llama3:8b ("annoying little pest") — all four legacy models go after verification. Remaining child: session plumbing, local model floor (eval blocked on pulls). Unpushed: 44bc344, 0ee94ab, 6cd3aa3, 04c3b29. + +** 2026-07-13 Mon 16:40 — ollama upgraded 0.17.7→0.31.2, model pulls running + +Craig picked option 1 (drop both llamas after the new models verify) and directed the full sequence. Research (WebSearch): Strix Halo wants MoE models (bandwidth-bound decode; dense 70B ≈ single-digit t/s) — gpt-oss:120b (~55 t/s reported on this chip) + qwen3-coder:30b (~100 t/s, 256K ctx) are the picks; ollama 0.17.7 was far behind. Upgraded via the official installer (sudo, NOPASSWD): 0.31.2, systemd unit recreated, service active. GPU discovery healthy out of the box: ROCm sees gfx1151 iGPU, 107.4GiB available; Vulkan RADV device present but gated behind OLLAMA_IGPU_ENABLE=1 (community says Vulkan outperforms ROCm on gfx1151 — A/B during the model-floor eval, not now). DISCOVERY: the service uses /usr/share/ollama/.ollama (system store) — holds two MORE models my earlier "complete" inventory missed (tinyllama 637MB, llama3:8b 4.7GB); the 45GB ~/.ollama store is separate and invisible to the service. KB node needs both corrections (stores + new versions) after pulls complete. Pulls running in background (btkrc1y0n, sequential: gpt-oss:120b 65GB then qwen3-coder:30b 19GB) into the system store; du-based Monitor armed (be6nrzl5d). Disk: 3.0T free, no constraint (df is aliased to dfc — use command df). Pending Craig: extend the drop list to tinyllama + llama3? Pending me after pulls: smoke-test both models w/ GPU offload check, ollama rm the drops, purge the orphaned ~/.ollama user store, update KB node + model-floor child, session log. + +** 2026-07-13 Mon 16:15 — local-runtime inventory gathered and promoted to the KB + +Craig asked about ollama; gathered the full local-inference picture. ratio: ollama 0.17.7 (/usr/local/bin, no systemd unit, on-demand), 45GB store with llama3.1:8b + llama3.3 70B, Strix Halo Radeon 8060S iGPU + 125GiB unified RAM — a real inference box, and the on-disk 70B matches the model-floor estimate. velox: no ollama, Iris Xe, 60GiB — out of scope for local inference. codex CLI installed + authed on ratio. Promoted to the KB as agents/20260713161222-local-llm-inference-inventory-daily-drivers.org (committed, roam-sync triggered — first KB write in a long while, the contribute nudge finally earned). Folded the inventory into the model-floor child's body: the evaluation can run TODAY on ratio against the on-disk 70B (scripted startup + publish-flow transcript, grade instruction-following) — no procurement needed. todo.org edit uncommitted. + +** 2026-07-13 Mon 16:10 — instruction bootstrap shipped (6 of 8 children done) + +Memory sentry ran clean during Craig's relaunch (zero alerts, daemon flat 1.97GB, third .emacs.d session alive since 15:44 and healthy). Queue resumed: built the thin-pointer AGENTS.md TDD (bats red→green): canonical claude-templates/AGENTS.md; make install CODEX_DIR stanza (→ ~/.codex/AGENTS.md, live on ratio now; velox auto-picks-up via startup's make install); install-ai.sh seed-only copy at bootstrap; rulesets root tracked symlink as dogfood. NEW scripts/tests/install-agents-entry.bats (3 tests) + 2 install-ai.bats tests. Riders: todo.org line-1357 prose reworded (lint misread "file:→id:" as a dead link), lint-followups.org cleared. Suite 428/0. Commit 6cd3aa3 (also closes the child + adds a dated entry on the agent-source task's thread 2). Inbox: two .emacs.d acks processed + deleted (the dead 14:34 one, and the live session's 15:47 — HEAD 56a3ed86 confirmed, staged eat work intact, mock-leak filed [#C] there, no action needed). Unpushed rulesets commits: 44bc344, 0ee94ab, 6cd3aa3. Remaining children: launcher runtime flag (scoping next — codex mapping clear, local mapping blocked on the model-floor/default-runtime decision), session plumbing, local model floor. Then the org-table bug + 6 task reviews. + +** 2026-07-13 Mon 15:32 — EXDATE bomb fixed, .emacs.d suite green end-to-end, agent cleared to relaunch + +Craig chose fix-from-here. Applied the capture-line-end-before-split fix to calendar-sync-recurrence.el (with a why-comment naming the clobber mechanism), deleted + recompiled the .elc, reloaded into the daemon (live Emacs calendar-safe again). Verification: the two previously-infinite tests pass in microseconds; all 12 exdates tests green; all 56 calendar-sync files green; then the FULL suite ran to completion for the first time today — all 599 elisp files + 18 bats green, including the dead agent's uncommitted eat-config guard tests. Committed 56a3ed86 in .emacs.d with a pathspec so the agent's staged eat work stayed untouched; not pushed. Superseding handoff sent to .emacs.d inbox (2026-07-13-1530): corrected diagnosis (journalctl OOM evidence), fix details, the show-or-create mock-leak finding, the double-reply note downgraded to latent-bug status, explicit safe-to-relaunch incl. the suite. Craig can relaunch the .emacs.d agent now. Resume thread: instruction-bootstrap build (thin-pointer AGENTS.md, Craig approved shape) was mid-scoping when death #2 interrupted — Makefile install stanza + install-ai.sh seeding + canonical claude-templates/AGENTS.md + bats, TDD. + +** 2026-07-13 Mon 14:55 — pin pulled: four decisions applied, skill parity done + +Craig pulled the pin and approved all four inventory decisions. Applied: knowledge-base.md capture-layer sentence (non-Claude runtimes capture into the session log), Signal-pager task gained the runtime-portability motivation entry, decisions recorded in the doc, VERIFY closed as a dated entry. Commit 44bc344. Then the skill-parity child: inventoried 11 skills + 18 commands, key finding is that one resolution sentence in the bootstrap entry file makes all 29 portable to any file-reading harness (auto-invocation degrades to by-name, which the publish flow already uses; flush excluded, session-plumbing owns it; native registration optional nicety). Section appended to the inventories doc, child closed as dated entry, commit 0ee94ab. Both commits local/unpushed (with 44bc344). 5 of 8 children done. Remaining: instruction bootstrap (needs Craig's design input, overlaps the Multiple agent-source improvements task), launcher runtime flag, session plumbing, local model floor. + +** 2026-07-13 Mon 14:30 — PIVOT RESOLVED: .emacs.d agent death root-caused and fixed + +Craig's urgent pivot: the .emacs.d agent session (launched 13:20) died — tmux session aiv-_emacs_d gone, [exited] in the launcher shell. Investigation chain: stale-sentinel theory disproved (multiple turns survived; no sentinels; hook tests clean). Real cause: DOUBLE XTWINOPS REPLIES. The .emacs.d agent had picked up our eat-xtwinops handoff, designed an advice-based fix (cj/--eat-answer-xtwinops :before eat--t-handle-output, written to modules/eat-config.el 13:33, test file 13:32), and evaluated it into the live daemon — where MY morning spike (patched parser with its own CSI t clause, loaded 10:52) was still active. Two answerers → tmux consumes reply #1, forwards reply #2 to the active pane as raw keystrokes (ESC + junk) — and Emacs ptys report 0 pixel size so EVERY frame resize re-queries. Its transcript (83070ecd, ends 13:41:57) shows the signature: four empty queue-operations, then background make test killed as claude exited. Exact final exit trigger unreconstructable from the transcript; the leak itself confirmed empirically: probe showed 2 replies per query. Fix: reloaded stock eat.elc into the daemon 14:27 (advice survives redefinition and is now sole answerer); re-probe = 1 reply. Probe buffer cleaned up. Handoff sent to .emacs.d (2026-07-13-1427): root cause, safe-to-resume, the latent no-op-claim bug in its advice comment (must guard against upstream shipping the clause or the double-reply returns), rerun its killed ERT, and the coordination lesson (our 10:58 handoff should have disclosed the live spike — our omission). Craig can relaunch the .emacs.d agent now; it resumes from its own anchor. + +** 2026-07-13 Mon @ 14:16:49 -0500 — SUSPENDED (urgent pivot; supersedes the 13:22 entry) + +Open threads, most active first: +- ACTIVE: runtime-portability children under the generic-agent-runtime parent (todo.org ~line 231). Done: hook parity, MCP portability, memory story — all three now dated entries pointing at docs/design/2026-07-13-runtime-portability-inventories.org. AWAITING CRAIG: the *** VERIFY with four decisions (PreCompact prose downgrade; Stop-teardown via Codex notify/manual; Signal-pager portability note; knowledge-base.md capture-layer sentence) — all recommended yes, he was about to answer when the pivot hit. Next child queued: skill parity (decision matrix over voice/review-code/flush etc.: re-register per harness vs fold into .ai/workflows/), then instruction bootstrap, launcher flag, session plumbing, local model floor. +- PINNED (from 13:22, still queued): org-table helpers bug ([#B] :bug:solo:, todo.org ~line 66) + the todo.org "→id" dead-link rider from lint-followups.org. +- PINNED: task review, 6 of 7 unwalked; they stay at the head of the next batch. +- SET ASIDE: sixel/EAT — .emacs.d has the patch filed [#B] with the durable-home design call coming to Craig; after it lands + velox pulls dotfiles and .emacs.d, run the velox test (client_cell_width nonzero, then magick sixel in a tmux window, Craig's eyes). + +Pending decisions: the four VERIFY items above. Nothing else blocks. + +Shipped since the 13:22 suspend (all pushed): 828f70a..1b638e6 (SVG rule cac1aa1, visuals rule 8703150, model d5bc9b3, todo folds dc13bce, child-task filing 1b638e6) and e91073d (model fix — d5bc9b3 had committed opus→Opus from a harness rewrite, not the fable flip; e91073d lands fable as Craig chose). + +Uncommitted work: todo.org (three children converted to dated entries + the new *** VERIFY), docs/design/2026-07-13-runtime-portability-inventories.org (new file, untracked), this anchor. Commit shape when resumed: docs+todo together as the inventories chore/feat commit. + +Key findings not recorded elsewhere: none — everything is in the inventories doc, the todo entries, or this log. Inbox is clear (the 13:23 .emacs.d ack was read and deleted). + +Background work: none running. + +Resume hint: read the *** VERIFY under the generic-agent-runtime parent, get Craig's four answers, apply the two tiny approved edits (Signal-pager note + knowledge-base.md sentence), commit todo.org + the inventories doc, then start the skill-parity matrix. + +** 2026-07-13 Mon @ 13:22:43 -0500 — SUSPENDED + +Craig stuck a pin in everything mid task-review walk. Resume-weighted state: + +Open threads, most active first: +- PINNED: org-table helpers bug ([#B] :bug:solo:, todo.org line 66). Craig queued it as the next work item ("2 then 1" — review done-ish, this is the 1). Fully specified in the task body: two defects (line-based table detection mangles example/src blocks; lint-org.el writes without --fix), repro from work 2026-07-09, regression test named. TDD it: canonical scripts live in claude-templates/.ai/scripts/, mirror-synced; tests are ERT via make test. Start here. +- PINNED: task review, stopped after 1 of 7. Batch was the staleness --list top 7; task 1 (build-to-prototype [#B]) kept + stamped 2026-07-13. Items 2-7 (roam-only startup, WIP sync gate, install-ai PATH, org-table bug, Signal pager, KB orphan pass) unreviewed — they stay at the head of the next run's batch automatically. +- SET ASIDE: sixel/EAT thread — rulesets + dotfiles halves are DONE and shipped; waiting on Craig to fast-track the eat-xtwinops.patch handoff sitting in .emacs.d/inbox/ (2026-07-13-1058-from-rulesets-*). After .emacs.d lands it and velox pulls dotfiles + .emacs.d, run the velox test: restart EAT/tmux server on velox, tmux display -p '#{client_cell_width}' nonzero, then magick logo: sixel:- into a tmux window, Craig eyeballs. Note ratio's working state is runtime-only until the .emacs.d patch lands (Emacs restart loses it; tmux server restart loses the feature flags — the dotfiles conf now covers that half). +- DEFERRED: lint-followups.org rider — dead file link at todo.org (was line 1314 pre-edit; re-grep for "→id"), promised as a rider on the next work item. +- POST-SUSPEND ADDITION (13:27): Craig asked for the ChatGPT/local-LLM gap assessment to be filed. Found the existing parent (** TODO [#D] Generic agent runtime support — Codex spec v0) and added 8 child tasks under it (instruction bootstrap, skill parity, hook parity, launcher flag, session plumbing, memory story, MCP portability, local model floor) plus a dated decomposition entry. todo.org edit uncommitted, riding with the review stamp. + +Pending decisions / open questions for Craig: none blocking. (Model flip resolved: keep fable, committed.) + +Shipped this session (all local, UNPUSHED except dotfiles): +- rulesets cac1aa1 — SVG-first rendering rule (emacs.md + ui-prototyping.md cross-link), jotto proposal accepted, reply sent. +- rulesets 8703150 — Showing Craig Visuals rule (interaction.md) + zsh word-split note (protocols.org canonical+mirror), takuzu proposal accepted with corrections, reply sent. +- rulesets d5bc9b3 — model opus→fable (Craig: keep). rulesets dc13bce — todo.org Signal-pager fold. +- dotfiles 5055ef1 — tmux terminal-features sixel lines, COMMITTED AND PUSHED to origin; inbox handoff there rewritten as applied-FYI. +- Handoffs delivered: jotto (acceptance), takuzu (acceptance + capability correction), emacsd (eat-xtwinops.patch + intro), dotfiles (superseded by direct apply). + +Uncommitted work: todo.org (the :LAST_REVIEWED: 2026-07-13 stamp on the build-to-prototype task — one drawer line, safe to commit with the next housekeeping/wrap). .ai/session-context.org is this live anchor (untracked, stays). + +Key findings not recorded elsewhere: none — the sixel investigation's durable facts live in the two rule commits, the emacsd/dotfiles handoffs, and this log. The four unpushed rulesets commits are the main crash exposure; push happens at wrap. + +Background work: none running. tmux sixel test windows killed; *sixel-probe* buffer killed; tmux server carries runtime-only settings (terminal-features sixel entries, allow-passthrough all) that are now redundant with the pushed dotfiles conf (passthrough) or pending the .emacs.d patch (features). + +Resume hint: start the org-table helpers bug via TDD (regression test first: a #+begin_example block of pipe-prefixed lines must survive wrap-org-table.el byte-identical), and fold in the todo.org:1314 link fix as the rider. + +** 2026-07-13 Mon 05:14 — Startup + inbox processing begins + +Ran startup: rulesets pull skipped (dirty tree — .claude/settings.json shows model opus→fable, same harness flip Craig reverted on 2026-07-11), nothing new to link, no branches behind, .ai/ synced from templates. No crashed session. Notes.org: no reminders, no pending decisions. Staleness: 18 top-level tasks unreviewed >7 days. Roam inbox: 8 items, none rulesets-owned (4 takuzu, 3 archsetup, 1 emacs.d). + +Inbox had 3 handoffs. Processed the home FYI (2026-07-11-1208, Signal pager ack): folded as a dated sub-entry into the [#C] "Document (and own) the Signal pager" task body — home confirms rulesets owns it, and reports signal-mcp wasn't connected in its 2026-07-09 session and its signal-cli is registered as Craig's own number (note-to-self pushes nothing), so home currently has no live page channel. Deleted the inbox file. No reply sent — the handoff was itself home's ack of our earlier reply; nothing to close. + +Remaining: two shared-asset proposals (jotto SVG-rendering rule, takuzu EAT-image-display rule) — skeptical reviews done, surfacing to Craig for approval next. + +** 2026-07-13 Mon 05:25 — jotto SVG rule shipped + +Craig approved option 1 (accept with changes). Added the SVG Rendering section to claude-rules/emacs.md (consider-by-default phrasing, full constraint sheet, hybrid guidance verbatim) and the svg.el port-target paragraph to claude-rules/ui-prototyping.md section 3. /review-code --staged: approve, one Minor wording nit self-fixed (1:1 repetition). make test green (273 ok, ERT clean — the 9 grep hits were test names containing "error"). Commit cac1aa1 as Craig. Replied to jotto via inbox-send.py (landed in jotto's inbox), deleted the inbox file. Note: bare inbox-send isn't on PATH in this shell — used .ai/scripts/inbox-send.py directly. Settings.json model flip still undecided (Craig hasn't answered keep-or-revert). Next: takuzu EAT-image proposal. + +** 2026-07-13 Mon 09:40 — EAT sixel capability verified live (takuzu claim corrected) + +Craig challenged takuzu's "EAT can't display images" claim; verified it's wrong on capability. Findings: EAT 0.9.4 fully implements Sixel — advertises it in DA (\e[?12;4c, feature 4 = sixel), answers XTSMGRAPHICS, renders via eat-sixel-render-formats (xpm first; daemon has xpm+svg). Live test: magick logo → sixel, wrapped in tmux passthrough DCS (ESC Ptmux; with doubled ESCs), cat from a VISIBLE pane → full-color 640px image rendered in the EAT buffer (Craig's screenshot 09:36:42). Caveats found: (1) image is a transient screen-anchored overlay — any scroll/redraw drops it; (2) tmux allow-passthrough "on" drops passthrough from invisible panes — set allow-passthrough "all" globally at RUNTIME ONLY (needs tmux.conf for persistence, both daily drivers); (3) img2sixel/libsixel 1.10.5 on ratio is broken — exit 0, zero bytes, all formats; use magick ... sixel: instead; (4) writes into the Claude Code TUI pane get instantly repainted over — draw in a separate visible pane. Test window killed, cleanup done. Next: re-present takuzu disposition with corrected facts. + +** 2026-07-13 Mon 09:55 — Root cause of sixel vanishing: tmux grid, not EAT + +Craig asked why the image is irretrievable once offscreen. Isolated it: created a background plain-EAT buffer (*sixel-probe*, eat-make, no window shown) in the daemon, fed it the RAW sixel (no tmux), scrolled 60 lines, re-scanned: all 60 image cells persist at pos 163, before display-begin 654 — EAT keeps sixel in scrollback natively (each cell is a buffer char with an XPM-tile display property, per eat--t-sixel-flush-line). So tmux is the killer: passthrough bypasses tmux's grid, tmux's model of those lines is text-only, and every repaint (scroll/window-switch/output) rewrites them, destroying EAT's image cells. Nothing upstream stores the pixels → irretrievable. Follow-up lead: tmux 3.7b binary has sixel compiled in, but client_termname is xterm-256color (TERM override somewhere in the launch chain — EAT would normally set eat-truecolor), whose terminfo doesn't advertise sixel, so tmux's native sixel path never engages. Native path would need terminal-features 'xterm*:sixel' + client reattach to test. *sixel-probe* buffer left alive so Craig can see the scrollback image; kill at wrap. + +** 2026-07-13 Mon 11:00 — EAT XTWINOPS spike: full native-sixel fix, verified, handed off + +Craig chose the spike (option 1). Found the final gate in tmux source (cloned 3.7b shallow to scratchpad): tty_cmd_sixelimage falls back to the text placeholder when TERM_SIXEL is unset OR tty xpixel/ypixel are 0. First was cleared by terminal-features 'xterm*:sixel'; second was the blocker — Emacs never fills pty pixel fields, and tmux's fallback query (CSI 18t + CSI 14t at attach) is silently swallowed by EAT (no 't' case in its CSI dispatch; confirmed client_cell_width 0x0). Spike: copied eat.el to scratchpad, added eat--t-send-window-size-report (answers CSI 14/16/18 t from char-width/height + disp dims, mirroring the XTSMGRAPHICS reply) + one dispatch case. Byte-compiled clean, loaded into the live daemon (survived — this session runs in EAT), probe confirmed replies (R14 4;576;880, R16 6;24;11, R18 8;24;80). After Craig's reattach: client_cell_width 11x24, and the invisible-window grid-redraw test PASSED — wizard image drawn from tmux's grid, survives window switches, scrolling, AND resizing (Craig verified visually). Note: first probe buffer vanished mid-session (unexplained; daemon uptime 1.5d rules out restart), recreated fine. img2sixel (libsixel 1.10.5) broken on ratio — magick sixel: is the working encoder. Velox verified over tailscale: same sixel-enabled tmux 3.7b + imagemagick — ready once configs land. Handoffs sent: emacsd got the eat-xtwinops.patch + intro (durable home, TDD productionization, upstream to codeberg akib/emacs-eat); dotfiles got the two tmux.conf lines. Everything on ratio is RUNTIME-ONLY until those land (Emacs restart loses the patch, tmux server restart loses the flags). Remaining: takuzu disposition (rule now reflects working persistent sixel), model-flip question, cleanup (sixel-final window, *sixel-probe* buffer). + +** 2026-07-13 Mon 12:00 — takuzu rule shipped, dotfiles committed + pushed + +Craig approved option 1 and directed the dotfiles commit+push. Applied: (1) rulesets 8703150 — Showing Craig Visuals section in interaction.md (never rely on SendUserFile display; browser/imv lane per desktop-capture.md; sixel quick-glance lane behind the client_cell_width capability gate) + zsh no-word-split note in protocols.org canonical + mirror (sync-check --fix). Suite green 423/0. Corrective acceptance reply sent to takuzu (its capability claim corrected with the CSI 14 t findings); inbox file deleted — local inbox now clear. (2) dotfiles 5055ef1 committed as Craig and pushed to origin (cjennings.net): two terminal-features sixel lines in common/.tmux.conf (allow-passthrough already on); dotfiles suite 10/10 OK; the pending rulesets handoff in dotfiles/inbox rewritten as an already-applied FYI. Cleanup done earlier this turn-series: sixel-final tmux window killed, *sixel-probe* buffer killed. Plan: Craig fast-tracks the emacsd patch, then a velox end-to-end test after velox pulls both repos. Still open: model flip (settings.json, unanswered), todo.org Signal-pager fold uncommitted. + +** 2026-07-13 Mon 13:35 — resumed: runtime-portability work begun, three inventories done + +Craig pulled the pin ("commit and push that, then let's work on all those remaining tasks"). Pushed 828f70a..1b638e6 (5 commits incl. the child-task filing), then found and fixed a defect: d5bc9b3 had committed opus→Opus (harness rewrote the file to "Opus" before staging), NOT the fable flip Craig chose — corrected + pushed as e91073d. Mid-work inbox arrival: .emacs.d ack of the EAT patch (filed [#B] there, design call going to Craig) — pure FYI, deleted. Then the three inventory children: wrote docs/design/2026-07-13-runtime-portability-inventories.org (hooks: only PreCompact + Stop carry porting work, AskUserQuestion moot, validators ride githooks; MCP: nine local servers portable, signal-mcp is claude.ai-side only so paging has NO off-Claude path — Signal-pager task is the fix; memory: KB already cross-agent, one sentence gap in knowledge-base.md). Converted the three children to dated entries, added a *** VERIFY carrying the four decisions (all recommended yes). todo.org + new doc uncommitted. Next children: skill parity (decision matrix), instruction bootstrap, launcher flag, session plumbing, local model floor. + +** 2026-07-13 Mon 12:15 — task review stopped early at Craig's call + +Craig picked "2 then 1" (task review, then org-table bug). Review batch was the 7 oldest-unreviewed; task 1 (build-to-prototype rule extension [#B]) kept as-is and stamped :LAST_REVIEWED: 2026-07-13 (assessed not-quick, not-solo — placement decision pending). Craig then said "let's stop here" — review closed early, 6 tasks untouched for the next run. The org-table bug (queued item 1) not started. todo.org edit uncommitted; ambiguity noted: "stop here" might mean stop-review or end-session — asked Craig which. + +** 2026-07-13 Mon 12:05 — model flip kept, housekeeping committed + +Craig chose to keep the fable model flip (deliberate this time, unlike the 2026-07-11 revert). Committed d5bc9b3 (settings model opus→fable) and dc13bce (todo.org Signal-pager fold). Both mechanical, subject-only messages; the 11:45 green suite run covers this tree state. Working tree now clean except the live session-context file. Rulesets has 4 unpushed commits (cac1aa1, 8703150, d5bc9b3, dc13bce); push at wrap per usual flow. Session remaining: nothing pending from the inbox; awaiting Craig's next move (emacsd fast-track, then velox test). diff --git a/archive/task-archive.org b/archive/task-archive.org index 1bff51a..9e053b4 100644 --- a/archive/task-archive.org +++ b/archive/task-archive.org @@ -1827,3 +1827,183 @@ From Craig via the roam inbox (2026-07-02, routed by archsetup): downstream proj 2026-07-02 Thu @ 05:09:58 -0400 — Craig (speedrun pre-flight): policy + audit. Scope read found startup's git gates already ignore untracked/ignored files; state the policy in startup.org and audit every dirty-check in the synced workflows to match (monitor-inbox's bare porcelain check is the known offender; tracked-modification blocking stays). Resolution 2026-07-02: template-freshness policy stated in startup.org Phase A.0 (dirty = tracked modifications only; untracked/gitignored never block pulls, ffs, or monitoring gates; the rsync WIP-guard named as the one deliberate exception — it holds back rulesets' own outbound WIP). Full audit of dirty-checks across synced workflows: startup's two git gates already complied; inbox.org monitor mode was the one offender — its precondition now uses --untracked-files=no with the explicit-staging rationale, and its close-out sweeps tracked changes only. triage-intake auto mode borrows monitor's gates, so it inherits the fix by reference. +** DONE [#B] Wrap-up inbox/transcript routing to destination projects :feature:spec: +CLOSED: [2026-07-04 Sat] +:PROPERTIES: +:CREATED: [2026-06-13 Sat] +:LAST_REVIEWED: 2026-06-24 +:END: +Optional wrap-up step that surfaces filed keepers belonging to another project, recommends a destination, and routes each to that project's =inbox/= via =inbox-send= (the destination's own =process-inbox= files it; transcript filing deferred to vNext). Spec: [[id:00b47414-2213-4a99-be35-48ceb266fc08][wrapup-routing-spec.org]] — Ready, [9/9] decisions. Source proposal: [[file:docs/design/2026-06-13-wrapup-inbox-transcript-routing-proposal.org]]. + +*** 2026-06-21 Sun @ 02:06:37 -0400 Spec-review + spec-response complete — Ready +Craig's review challenge reshaped the design from a direct cross-repo =todo.org= move to =inbox-send= delivery into the destination's inbox (safer: reuses the sanctioned cross-project path, gets provenance + per-project filing for free, degrades gracefully where a destination has an =inbox/= but no =todo.org=). D2/D3 superseded; D7 (inbox-send delivery), D8 (=:ROUTE_CANDIDATE:= marker at file time), D9 (local source removal + reject-flow recovery) added. Spec-review file consumed and deleted. Implementation-task breakdown filed below (spec-response Phase 6). + +*** 2026-06-24 Wed @ 00:21:20 -0400 Reconcile — marker sub-task repointed at inbox.org +The 2026-06-23 inbox consolidation (24ca58d) merged =process-inbox= + =monitor-inbox= + =inbox-zero= into one =inbox.org= engine (process/monitor/roam modes) and deleted the three old files. The =:ROUTE_CANDIDATE:= marker sub-task targeted =process-inbox.org='s Phase D — repointed it to =inbox.org= process mode (core §3 "File as TODO"). No build has started, so this is a target-rename only; the spec design is unaffected. + +*** 2026-06-28 Sun @ 13:02:42 -0400 Built the recommendation engine + destination discovery +Added =.ai/scripts/route_recommend.py= (canonical + mirror): pure =recommend(item, projects) → (destination, confidence)= with strong (name/path literal, word-boundary matched, dot-stripped alias aware), weak (distinctive name-token overlap), and none tiers; a multi-way top-tier tie downgrades to weak with a deterministic pick (most overlap, then alphabetical); empty list → none. The CLI (=--item=, =--exclude=) reuses =inbox-send.py='s =discover_projects= via importlib so the candidate set matches inbox-send's project universe. 13 tests (the five spec'd cases + boundary/path/strong-beats-weak + 3 sandboxed CLI integration tests), full =make test= green. Covers spec Phases 1 + 3. Next sub-tasks (=:ROUTE_CANDIDATE:= marker, wrap-up router) call this engine. + +*** 2026-07-02 Thu @ 00:36:12 -0400 Phases 2 + 4 + test surface landed — marker, router, route-batch helper +inbox.org's "File as TODO" disposition now runs route_recommend on each keeper and stamps =:ROUTE_CANDIDATE: <destination>= on strong/weak matches (none stamps nothing; local keepers stay unstamped) — spec Phase 2 / D8. wrap-it-up.org Step 3 gained the optional router directly after the inbox sanity check, with the gate-vs-optional split named in the prose: surface the batch (task / destination / delivery mode / confidence, weak visibly labeled), go/skip, empty set = zero interaction — spec Phase 4 / D7 / D9. The go path is mechanical: new =.ai/scripts/route-batch= (--list read-only, --go extracts the subtree minus the marker with children riding along and headings promoted, delivers via inbox-send for provenance, removes the local subtree only after a successful send; a failed send leaves the task in place and exits non-zero). Test surface: engine unit tests existed (13); route-batch adds a 9-test bats suite (list/backlog-exclusion, empty-set silence, list-modifies-nothing = skip semantics, delivery + provenance + children, local-task survival, drawer-minus-marker, inbox-without-todo.org delivery, empty go, failed-send recovery). cross-project.md notes the router as a sanctioned cross-project write path. make test green, sync clean. + +*** 2026-07-04 Sat @ 11:49:59 -0500 Flipped the spec to IMPLEMENTED; parent closed +The routing build shipped green: route_recommend.py (destination discovery + recommendation, 13 unit tests), the =:ROUTE_CANDIDATE:= marker in inbox process mode, the wrap-it-up router sub-step, and route-batch (9 bats tests). Spec [[id:00b47414-2213-4a99-be35-48ceb266fc08][wrapup-routing]] flipped DOING → IMPLEMENTED. Manual end-to-end validation and the transcript vNext promoted to their own tasks. +** DONE [#C] Check that memories are sync'd across machines via git :spec: +CLOSED: [2026-07-04 Sat] +:PROPERTIES: +:LAST_REVIEWED: 2026-06-28 +:END: +v1 implemented end-to-end 2026-06-10 (Phases 0-4, all shipped + pushed) and the agent-KB spec is IMPLEMENTED. Both daily drivers (velox + ratio) carry the =roam.git= clone + sync-timer. Cross-machine sync verified as a full round-trip 2026-07-04: velox created a probe node 2026-07-01 and ratio held it; ratio then deleted it and velox pulled the deletion. Both clones sit at the same HEAD with zero sync-conflict files and both roam-sync timers active. The work/unknown-project write-refusal checks need live sessions in those projects and are tracked as a standalone manual-validation task below. +*** 2026-05-14 Thu @ 19:14:11 -0500 Investigate current memory storage + +Memory files live at +[[file:/home/cjennings/.claude/projects/-home-cjennings-code-rulesets/memory/][~/.claude/projects/-home-cjennings-code-rulesets/memory/]] +— four files including =MEMORY.md= and three individual entries +(=feedback_never_guess.md=, =project_ai_scripts_canonical_source.md=, +=reference_pdftools_venv.md=). The directory is a plain unmanaged dir +(no symlink, no enclosing git checkout). Neither +[[file:/home/cjennings/.claude/][~/.claude/]] itself nor any subtree +containing the project-memory dirs is tracked in +[[file:/home/cjennings/code/archsetup/][archsetup]] or +[[file:/home/cjennings/code/rulesets/][rulesets]]. Without a symlink +into a stowed or tracked location, memory files don't survive a new +machine setup or a dotfiles restore. + +Proposed setup: stow =~/.claude/projects= → +=archsetup/dotfiles/common/.claude/projects/= (path doesn't exist yet +— it's the target location pending VERIFY). +Create the destination in archsetup, move existing per-project +=projects/<encoded-cwd>/memory/= dirs there, run =stow= to link, then +commit + push archsetup. After that, every machine running =stow= +picks up the same memory tree. + +*** 2026-05-23 Sat @ 16:12:48 -0500 Decided: dedicated private repo, not stow +Worked through dotfiles → rulesets → dedicated repo. Dropped stow/dotfiles (machine config, wrong cadence) and rulesets (it's pulled first in every session, so memory edits would dirty its tree and skip the startup =git pull --ff-only=). Chose a dedicated private repo on cjennings.net: storage is unified there while recall stays per-project (the encoded-cwd subdirs), since pooling recall would hurt relevance and risk work-private facts surfacing in personal-project artifacts. + +*** 2026-05-23 Sat @ 16:12:48 -0500 Shipped: claude-memory.git + folded symlinks +Created bare =git@cjennings.net:claude-memory.git=, cloned to =~/.claude-memory= (later deleted in the reversal below), moved all 7 per-project =memory/= dirs in (54 files; work has 40) and replaced each live =~/.claude/projects/<enc>/memory= with a folded dir-symlink so new memory lands in the clone and a push syncs it. Added =link-claude-memory.sh= (idempotent — recreates the symlinks on a new machine after clone) + README. Private repo, never GitHub (carries work/DeepSat memory). Initial import pushed (=f496370=). + +*** 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: [[id:08a5ec99-9e1e-40e4-8241-e8a41e9de49f][agent-knowledge-base-spec.org]] (originally docs/design/2026-06-05-org-roam-knowledge-base-spec.org; superseded by the 2026-06-10 spec-create rewrite at the new path). 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. + +*** 2026-06-10 Wed @ 14:29:20 -0500 Spec ratified — write boundary is option C; rewritten to spec-create format +Craig answered via cj annotations in the spec (2026-06-10): DECISION 5 is option C (read-shared, write-scoped — work agents never write the KB). Syncthing does replicate ~/sync/ to a work machine and Craig is fine with how C handles it. Node granularity: per-fact nodes. Write review: agent writes land freely in the KB only — explicitly not permission to post to email, Linear, or any public channel without review and consent. The spec was rewritten into the spec-create format at [[id:08a5ec99-9e1e-40e4-8241-e8a41e9de49f][agent-knowledge-base-spec.org]] (old draft removed). Implementation explicitly held pending Craig's go-ahead; one decision still open (D7, next VERIFY). + +*** 2026-06-10 Wed @ 14:35:40 -0500 Spec review — not ready +Review written at docs/agent-knowledge-base-spec-review.org (deleted on disposition completion; content summarized in the spec's Review dispositions). Rubric: =Not ready=. Blockers: resolve D7 (keep vs retire harness memory) and define the executable personal/work/unknown write-boundary classifier plus work-side write/refusal destination. Medium notes: use concrete ripgrep commands that exclude =*.sync-conflict-*= files, and define seed-node approval/rollback. + +*** 2026-06-10 Wed @ 14:44:00 -0500 D7 resolved — keep harness memory as the capture layer +Craig ratified "keep" in chat (2026-06-10). Harness memory stays the ephemeral, auto-recalled capture layer; the KB holds promoted durable facts; Phase 3's wrap-up promotion cadence is mandatory. Spec D7 flipped to accepted; D2 stands as written. + +*** 2026-06-10 Wed @ 14:44:00 -0500 Project classification defined — work-root denylist, unknown refuses +Resolved in the spec-response pass: =knowledge-base.md= carries an explicit work-root denylist (initially =~/projects/work=) as the source of truth. Personal = under a known project parent (=~/code/=, =~/projects/=, =~/.emacs.d=) and not denylisted → KB writes allowed. Work or unknown → no KB write; the agent reports the refusal with a one-line redacted summary of the fact. v1 adds no new work-side store — work projects keep their existing project-tree conventions. See the "Project classification and write routing" section of [[id:08a5ec99-9e1e-40e4-8241-e8a41e9de49f][the spec]]. Denylist completeness is the one open caveat (next VERIFY). + +*** 2026-06-10 Wed @ 14:44:00 -0500 Codex review incorporated — spec ready with caveats +Spec-response pass processed the 2026-06-10 Codex review with D7 = keep as a pre-agreed input. Both blockers cleared (D7 accepted; classification/write-routing section added). Mediums accepted: canonical rg commands with conflict-file exclusion, Phase 2 seed-node approval/rollback mechanics, Makefile no-change note, Testing/Verification section. Three recommendations modified, none rejected — see the spec's Review dispositions. Review file deleted per the workflow. Rubric: ready with caveats (denylist confirmation). Implementation tasks broken out below; implementation itself awaits Craig's go. + +*** 2026-06-10 Wed @ 17:29:37 -0500 Work-root denylist confirmed — ~/projects/work only +Craig confirmed (2026-06-10, in chat): the denylist is just =~/projects/work=. Archangel is not work-scoped. The spec's one caveat clears — status now ready. Phase 1 is unblocked, but implementation still awaits Craig's explicit go. + +*** 2026-06-10 Wed @ 17:57:08 -0500 Spec amended — D8 git transport + migration/metrics/docs/maintenance folds +Craig's five design questions answered and folded into the spec, and D8 ratified (Shape A): the KB moves out of the =~/sync/org= Syncthing share into its own git repo on cjennings.net, with an =agents/= subdirectory for agent writes, a systemd auto-sync timer for Craig's edits, opt-in-by-clone replication (work machine doesn't clone), and the phone staying on the on-demand =~/sync/phone= pattern. Folded in: inclusion criteria + a Phase 1.5 guided memory sweep, a Success metrics section with a 30-day checkpoint, the seed node redefined as the KB's own documentation, and Phase 4 maintenance automation. Phases renumbered 0-4; tasks below updated. Implementation still held. + +*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 0 done — roam migrated to git +Backed up (~/roam-backup-2026-06-10.tar.gz), copied to =~/org/roam=, 63 conflict files deleted (424 org files), git repo with origin =git@cjennings.net:roam.git= (initial commit 515693d), old location replaced with a transition symlink. Emacs =roam-dir= updated in user-constants.el + live-reloaded (db rebuilt, 416 nodes); handoff to .emacs.d for the commit. =roam-sync.sh= (6 bats green) on a 15-min systemd user timer, installed + enabled + round-trip verified. Old-path references repointed (protocols task-list pointer, journal workflow, notes template). archsetup handoff covers dotfiles adoption + other-machine clones. rulesets commit fcf554a. + +*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 1 done — knowledge-base.md rule live +=claude-rules/knowledge-base.md= written (path, git discipline, query commands, agents/ write schema, denylist + refusal contract, inclusion criteria, capture-then-promote). =make install= linked it machine-wide; verified the link, a known-note query, and conflict-glob exclusion with a planted file. Commit d071f1f. + +*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 1.5 done — rulesets swept, 10 projects broadcast +Rulesets' 6 memories classified: 3 promoted as =agents/= nodes (notify-attention pattern, pdftools venv, gpg-agent SSH TTL trap), 2 kept local (rule-encoded in verification.md / interaction.md), 1 kept + de-staled (ai-scripts-canonical updated for the claude-templates subtree fold). Sweep handoff broadcast to the 10 other memory-bearing projects (archsetup, org-drill, pearl, .emacs.d, elibrary, finances, health, home, jr-estate, kit); work skipped by the boundary; the orphaned =linear-emacs= memory dir (project retired, likely pearl's predecessor) noted for Craig. + +*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 2 done — seed/doc node written and indexed +=agents/20260610181640-how-the-agent-knowledge-base-works.org= written: the KB's user-facing guide (what agents do, how it syncs, finding/pruning agent content, the rule pointer). Index verified programmatically: =org-roam-node-from-title-or-alias= resolves it with tags (agent reference); node count 416 → 420. Craig's visual check remains in the manual-testing child. + +*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 3 done — wrap-up promotes + records the KB receipt +wrap-it-up.org Step 1 gains the promotion check (inclusion-criteria bar) and the mandatory "KB: promoted N / consulted yes-no" Summary line; validation checklist enforces it. Mirror synced, integrity OK (44), parse OK. Commit 242b95e. + +*** 2026-06-11 Thu @ 19:26:26 -0500 .emacs.d memory sweep complete (first broadcast response) +First of the 10 broadcast projects to report Phase 1.5 done (handoff 18:23). Inventory 7: promoted 3 to KB (no-make-frame-in-live-daemon, proton-bridge-headless-cert-mismatch, open-images-with-imv — roam commit a915760), kept 3 local at Craig's call (commit-flow-no-approval-gate per-project-scoped; two theme-scoped ones possibly superseded by the palette-columns spec), deleted 1 (superseded by canonical interaction.md rule). 9 projects' sweeps outstanding. + +*** 2026-06-12 Fri @ 02:25:12 -0500 Five more sweeps complete via the home folds +Overnight handoffs from home closed five more broadcast targets, each swept at fold-time triage with Craig's approval: jr-estate 2 promoted (forms name-with-number, PDF-editing tooling split; roam 45d8e6c) / 3 kept with area attribution / 2 deleted as rule-encoded or duplicate; finances 0/1/0 (rosalea-daly contact fact kept local); elibrary 0/0/2, health 0/0/1, kit 1/0/2 (hand-prep-items-to-work-inbox promoted into home's memory; the rest duplicated rules or home memories). Nothing from these five met the KB bar that wasn't already encoded. All folded projects' session archives merged area-prefixed into home's .ai/sessions/, so session-harvest's first run sees them. Home covers its own and remaining areas' sweeps through ongoing discipline; still pending from the broadcast: archsetup and work. + +*** 2026-07-04 Sat @ 11:52:00 -0500 Manual validation — checks 1 + 4 verified; refusal checks split out +Check 1 (seed node in org-roam + rg inventory) verified on velox 2026-07-01 (55 =:agent:= nodes matched the live org-roam DB). Check 4 (cross-machine sync) verified as a full round-trip 2026-07-04: velox pushed a probe 2026-07-01, ratio held it, ratio deleted it, velox pulled the deletion; both clones at the same HEAD, zero sync-conflict files, both timers active. Checks 2 + 3 (work / unknown-project write refusal) need live sessions in those projects — promoted to a standalone manual-validation task. + +*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 4 done — monthly hygiene automation live +=scripts/kb-hygiene.sh= (6 bats green, shellcheck clean, read-only by design) inventories =:agent:= nodes, flags orphans / duplicate titles / conflict files, and writes an org report into the rulesets inbox; =roam-hygiene.timer= (monthly, Persistent) installed + enabled. Live run against the real KB verified (4 agent nodes, 428 files, 0 conflicts). Conditional vNext stays in the spec's scope tiers: a =/promote= command if the wrap-up prompt proves insufficient, an =:agent:inbox:= staging tag if free writes prove too noisy. Commit b014095. + +*** 2026-06-30 Tue @ 13:53:34 -0400 ratio roam clone + sync-timer confirmed (cross-machine half done) +Verified ratio over tailscale ssh: =~/org/roam= is a clone of =git@cjennings.net:roam.git= (HEAD auto-synced 13:11 today), and =roam-sync.timer= is enabled and actively firing (last run 5 min prior, next in 10). Both unit files present. velox was already confirmed, so the one-time clone+timer setup is now done on both daily drivers — the (b) half of this VERIFY's remaining work. Only the manual-validation child (work/unknown-project refusal checks needing Craig's eyes) is left before DONE. Cleared the matching "Current open instance" line in =daily-drivers.md=. + +*** 2026-07-01 Wed @ 21:52:15 -0400 Manual-validation checks 1 + 4 (velox half) verified; ratio unreachable +Check 1 (seed node in org-roam + rg inventory): 55 =:agent:= nodes found by the rg inventory AND 55 nodes under =agents/= indexed in the live org-roam DB (emacsclient query) — match. Check 4 (cross-machine edit): created a temporary probe node =agents/20260701214910-kb-sync-validation-probe.org=, triggered =roam-sync= — committed and pushed to origin within seconds (f0252bb), zero =sync-conflict= files. The ratio half could NOT be verified tonight: =tailscale ping ratio= pongs via DERP, but ssh to 100.71.182.1:22 times out (machine likely suspended). Probe left in place; when ratio is back, confirm with: ssh cjennings@100.71.182.1 'ls ~/org/roam/agents/ | grep kb-sync-validation-probe' — then delete the probe node. Checks 2 + 3 (work/unknown-project refusal) still need live sessions in those projects, and "work machine has no KB clone" needs the work machine named + checked. +** DONE [#C] Spec storage location + lifecycle-status convention :spec: +CLOSED: [2026-07-04 Sat] +:PROPERTIES: +:CREATED: [2026-06-15 Mon] +:LAST_REVIEWED: 2026-06-24 +:SPEC_ID: 80b0787b-4a60-4c82-8a16-b383d3e3c8f2 +:END: +Two coupled documentation conventions for rulesets to adopt, surfaced by .emacs.d while triaging ~28 design docs. Both land in =spec-create= ([[file:.ai/workflows/spec-create.org]]) and likely a new =docs-lifecycle= rule under =claude-rules/=. Source proposal: [[file:docs/design/2026-06-15-spec-storage-lifecycle-proposal.org]] (.emacs.d handoff 2026-06-15). + +The two conventions: +- *Location split* — formal specs live in =docs/specs/=; =docs/design/= keeps working notes, brainstorms, inventories, reviews. A spec is a doc proposing a buildable change with a Decisions section and phases; everything else is a note. +- *Glanceable lifecycle status* — a spec's state (draft / doing / implemented / superseded / cancelled) is visible without opening the file, plus an authoritative in-file record. + +We handle the task in priority order. Mechanism decided 2026-06-28; migrates into the spec when built. + +*** Decisions (settled 2026-06-28 — migrate into the spec when built) +1. *Location split — adopt.* =docs/specs/= for formal specs, =docs/design/= for notes (brainstorms, inventories, reviews). A spec is a doc proposing a buildable change with a Decisions section and phases; everything else is a note. Document in spec-create and the docs-lifecycle rule. +2. *Status mechanism — org-keyword authoritative.* The spec's =#+TODO:= state on its top heading is authoritative (specs already carry =#+TODO: TODO | DONE SUPERSEDED CANCELLED=), mirrored in a =Status= field in the Metadata table. Drop the filename suffix entirely — it's redundant with the Status field and adds rename churn across a cross-linked, template-synced doc set. (Craig 2026-06-28, choosing org-keyword over his earlier filename-suffix lean.) +3. *Link safety — adopt =org-id= ([[id:...]]) for cross-doc spec links.* Decouples link stability from the status mechanism; good hygiene regardless. +4. *Generalize.* Capture the shape (lifecycle state authoritative-in-artifact, formal-vs-notes split, rename-safe links) as a general =docs-lifecycle= convention in =claude-rules/=, with spec-create as the first instance. +5. *Retrofit existing files across ALL projects* (Craig 2026-06-28). The convention is worthless if legacy docs stay misfiled — every project's existing =docs/design/= pile (the ~28 in .emacs.d that surfaced this) must be sorted: formal specs move to =docs/specs/=, notes stay in =docs/design/=, inbound =file:= links updated. This is a one-time per-project migration that template sync can't perform, so the spec must design the reach mechanism. Proposed shape: a synced classify-and-move helper under =.ai/scripts/= (heuristic: a doc with a Decisions section + phases/Metadata is a spec) that proposes moves for confirmation and relinks, plus a startup nudge gated on a per-project =:LAST_SPEC_SORT:= marker so each project runs it once. Classification is a judgment call — the helper proposes, a human confirms. + +Follow-up once built: update spec-create to emit into =docs/specs/= with the org-keyword status; write the =docs-lifecycle= rule; ship the retrofit helper + startup nudge; retrofit rulesets' own =docs/design/= first as the pilot; send a note if .emacs.d should pilot before generalizing. + +*** 2026-07-01 Wed @ 22:13:00 -0400 Spec drafted — first resident of docs/specs/, awaiting review +Wrote [[id:80b0787b-4a60-4c82-8a16-b383d3e3c8f2][the spec]] from the five settled decisions, dogfooding its own conventions: it lives in the new =docs/specs/=, opens with the =* DRAFT Docs lifecycle= status heading (org keyword authoritative, =:ID:= for id-links, dated history in the body), and drops the status filename suffix. It pins the one mechanism the decisions left open — where the keyword lives: a prepended top-level status heading with vocabulary =DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED=, additive and retrofittable, giving both the one-line =rg= board and free org-agenda scanning. Four build phases: rule + template updates → =spec-sort= helper (classify/confirm/move/relink, bats) → rulesets pilot (41 design files, 3 spec-spine candidates, 2 stray root specs) → startup nudge gated on =:LAST_SPEC_SORT:= + .emacs.d note. Status DRAFT until Craig's review flips it READY. + +*** 2026-07-01 Wed @ 22:22:34 -0400 Codex spec-review complete — Not ready +Review findings live in [[id:cc77a7f6-e4c3-488a-ac3b-e739420a5c2b][the spec]]. Four blockers before implementation: the proposed lifecycle =#+TODO:= line drops the =TODO=/=DONE= states needed by Decisions and Review findings cookies; =spec-sort= needs an exact relink/unsupported-residue contract; the sort marker/startup nudge must name the actual =.ai/notes.org= state surface and detection flow; and the stricter =docs/specs/= review precondition must not strand legacy specs before retrofit. + +*** 2026-07-01 Wed @ 22:30:06 -0400 Second review merged + responder pass — all nine findings fixed +A fresh-context Claude reviewer independently rated the draft Not ready, converging on Codex's keyword-vocabulary blocker (adding the cross-sequence uniqueness wrinkle) and contributing five unique findings — the biggest: nobody owned the DOING→IMPLEMENTED flip, the exact mechanism whose failure produced this spec. Craig approved fixing all nine. Fixed in place: two-sequence collision-free keyword header (dogfooded in the spec's own header; org now computes the [5/5] and [9/9] cookies — verified in batch), transition-ownership table incl. spec-response's mandatory flip-to-IMPLEMENTED task + task-audit safety net, single classification predicate (Decisions AND Implementation phases), the -spec.org rename step, the full relink data-safety contract (rewritten roots / report-only surfaces / dry-run default / residue-grep gate), the =.ai/notes.org= marker + Phase A probe + Phase C nudge contract, the legacy-location compatibility rule, the org-id Emacs-resolution prerequisite for .emacs.d, and the three-line transition definition. Ledger + per-finding responses in the spec's Review findings section. Status stays DRAFT pending Craig's READY flip. + +*** 2026-07-01 Wed @ 22:41:33 -0400 Codex spec-review rerun — Not ready +Fresh review after the response/READY flip added five new blocking findings in [[id:cc77a7f6-e4c3-488a-ac3b-e739420a5c2b][the spec]] and demoted the spec back to DRAFT. Remaining blockers: shared helper/workflow edits must name the canonical =claude-templates/.ai/= + mirror sync contract; task-audit needs an explicit spec-to-task binding before it can police =DOING= specs; =spec-sort --apply= needs a failure-safe/rollback contract; the org-id Emacs prerequisite must be executable before link conversion; and lifecycle status confirmation must be evidence-based so the retrofit does not encode stale reality. + +*** 2026-07-01 Wed @ 22:46:52 -0400 Second responder pass — all fourteen findings closed +Fixed Codex's five re-review findings: the canonical-placement contract now opens the retrofit section (helper + tests + workflow edits land in claude-templates first, sync-check --fix propagates, sync-check-clean is an acceptance criterion); spec-response stamps a =:SPEC_ID:= property on the build parent, and task-audit's query checks that parent's keyword — which dissolves the flip-task chicken-and-egg; =--apply= got the fail-safe contract (clean-tree preflight, validate-then-write from a recorded plan, named recovery recipe); id-link conversion is staged (pilot rewrites =file:= links only; =id:= conversion is a follow-up gated on the concrete .emacs.d id-index mechanism — Craig picked this fork); and status confirmation is evidence-based (evidence panel, conservative non-terminal default, terminal states need a stated reason). Also de-cookified bracket tokens in prose that org's cookie updater would mangle. Status stays DRAFT; the READY flip belongs to the reviewers this round — verify pass dispatched. + +*** 2026-07-01 Wed @ 23:22:50 -0400 Codex spec-review rerun — Ready +Codex re-read the revised [[id:80b0787b-4a60-4c82-8a16-b383d3e3c8f2][docs lifecycle spec]] after the second responder pass. All fourteen findings are closed, decisions remain [5/5], and the remaining implementation contracts are concrete enough to build and test. Status flipped to READY in the spec; implementation can proceed. + +*** 2026-07-01 Wed @ 23:34:15 -0400 Decomposed into build tasks; spec flipped READY → DOING +spec-response Phase 6 run: this parent now carries the =:SPEC_ID:= binding (the spec's status-heading UUID), the phase tasks below track the build, and the spec's status heading is DOING. Completeness pass done: all ten acceptance criteria have homes across the phase tasks; vNext (org-agenda view) was already filed as the [#D] task below. + +*** 2026-07-01 Wed @ 23:39:10 -0400 Phase 1 landed — docs-lifecycle rule + four spec-workflow updates +claude-rules/docs-lifecycle.md written and linked machine-wide (make install). Canonical-side updates: spec-create Phase 5 + template (docs/specs/ location, two-sequence keyword header, DRAFT status heading with :ID:, transition mechanics), spec-review (location expectation with the legacy compatibility rule keyed on :LAST_SPEC_SORT:, plus the DRAFT→READY flip — and the demote-back-to-DRAFT path a failed re-review takes), spec-response Phase 6 (owns READY→DOING, stamps :SPEC_ID: on the build parent, always emits the flip-to-IMPLEMENTED task), task-audit Phase B (the :SPEC_ID: reconcile query, checking the parent's keyword rather than counting children). Mirror synced; make test green end to end. + +*** 2026-07-01 Wed @ 23:57:44 -0400 Phase 2 landed — spec-sort helper + 30-test bats suite +Built claude-templates/.ai/scripts/spec-sort (Python, TDD — the 30-test bats suite written red-first in claude-templates/.ai/scripts/tests/spec-sort.bats) covering the full retrofit contract: spine classification with the -spec.org-name-without-spine anomaly case, evidence panel (Status field, cookies, linking todo.org task, dated history, artifact existence) with conservative non-terminal proposals, per-candidate --confirm/--skip gate with --reason required on terminal keywords, clean-worktree preflight (--allow-dirty prints what recovery loses), validate-then-write from a recorded plan file, relink across the rewritten roots (inbound AND the moved doc's own outbound relative links) with report-only for sessions + synced templates (naming the canonical claude-templates file), bare-path mentions blocking until --acknowledge-bare, named recovery on injected mid-apply failure, post-apply residue gate, idempotent :LAST_SPEC_SORT: stamp. Real-data dry run against rulesets' pile matched predictions: 5 candidates, 4 anomalies, 30 notes, 0 bare, 10 report-only (incl. the startup.org synced-template case Codex flagged). make test green; sync-check clean. + +*** 2026-07-02 Thu @ 00:18:28 -0400 Phase 3 pilot ran — rulesets' pile sorted, board live +Craig confirmed all five proposed keywords as-is plus the IMPLEMENTED reason; spec-sort --apply moved the five specs to docs/specs/ (agent-knowledge-base IMPLEMENTED, inbox-workflow-consolidation READY, autonomous-batch-execution READY, encourage-kb-contribution READY, wrapup-routing DOING — joining the docs-lifecycle spec's DOING on the board), rewrote 12 todo.org links plus the moved specs' own outbound links, and stamped :LAST_SPEC_SORT: 2026-07-02. Acceptance verified: status board matches reality, all re-homed specs carry -spec.org, residue zero in the rewritten roots (one acknowledged self bare mention rode along inside inbox-workflow-consolidation-spec), no id: links emitted, make test green. Surfaced and left in place: the four -spec.org-named files in docs/design without a spec spine (generic-agent-runtime, pattern-catalog, daily-prep-template, auto-triage-intake) — notes by predicate, misleading names; rename or leave is a Craig call. Report-only references: 9 frozen session archives + the synced startup.org (canonical edit lands with Phase 4's nudge work). + +*** 2026-07-02 Thu @ 00:23:32 -0400 Phase 4 landed — startup nudge live, .emacs.d notified +Added the spec-sort probe to startup.org Phase A (item 12) and the one-line nudge to Phase C's findings list, canonical-side, mirror synced. One refinement over the spec's sketch: the stray-root check uses find instead of compgen, because compgen is bash-only and zsh aborts on an unmatched glob — the original snippet false-negatived on stray root specs under zsh (spec snippet updated with a note). Fixture-verified in both shells: fires on an unsorted docs/design and on a stray docs/*-spec.org, silent with the marker stamped, silent with no docs at all. Also fixed startup.org's own stale reference to the moved encourage-kb-contribution spec (the pilot's report-only finding). Sent .emacs.d the convention-live note with its ~28-doc pile nudge and the id-index ask (org-id-extra-files enumeration or periodic org-id-update-id-locations, verify by clicking the docs-lifecycle spec's :ID:), asking it to tag the owning task :blocker: since rulesets' id-conversion task waits on it. + +*** 2026-07-02 Thu @ 05:12:33 -0400 Converted spec-target file: links to id: form (rulesets) +All 13 file:docs/specs/ links lived in todo.org (zero in .ai/ or docs/ outside specs). 11 converted straight to [[id:UUID][label]] (bare links labeled with the spec filename); the 2 links carrying a ::*Review findings search target got full fidelity by minting an :ID: on that heading in the docs-lifecycle spec (cc77a7f6-e4c3-488a-ac3b-e739420a5c2b) — the id index scans whole files, so heading-level ids resolve. Residue grep zero; every id verified against its target's :ID:. Gate had cleared earlier tonight via .emacs.d's org-spec-links.el delivery (verified org-id-find on their side); M-x cj/org-id-refresh-spec-locations is the fix if a fresh id doesn't resolve on click. + +*** 2026-07-04 Sat @ 11:46:31 -0500 Flipped the spec to IMPLEMENTED +All four build phases had shipped (docs-lifecycle rule + spec-workflow updates, spec-sort helper + 30-test bats suite, rulesets pilot + status board, startup nudge) plus the conversion of file-style links to id-style links, so the spec's status heading went DOING → IMPLEMENTED with a dated history line and the Metadata mirror, per the transition-ownership table. Parent closed; manual validation promoted to its own task. @@ -353,14 +353,6 @@ Once specs carry lifecycle TODO keywords under =docs/specs/=, add a custom org-a :END: From Craig via the roam inbox (2026-07-02, routed by archsetup). Teardown-by-default already shipped (bare "wrap it up" closes the window; "with summary" keeps it). Craig's follow-on: "maybe we cut the summary altogether. help me think through when I'd want a summary and how I would recognize it before confirming and then having it close." Run that think-through with him (brainstorm-shaped, not solo), then adjust wrap-it-up.org's Step 6 + trigger phrases to the outcome. -** CANCELLED [#C] ntfy phone channel as general two-way agent-comms :feature:spec: -CLOSED: [2026-07-13 Mon] -:PROPERTIES: -:CREATED: [2026-06-20 Sat] -:LAST_REVIEWED: 2026-06-24 -:END: -Killed at the 2026-07-13 task review: home retired and tore down the ntfy channel on 2026-07-04, so this proposal's transport no longer exists. Its living successors are the Signal pager ([#B] task above — one identity on velox, runbook pending) and agent-page (shipped 2026-07-13), which cover the send half; two-way (read-replies) rides the Signal runbook. -Proposal from the home project (2026-06-17): promote the self-hosted ntfy-over-Tailscale phone channel it built and verified on ratio into a general two-way agent-comms tool rulesets owns. Full proposal: [[file:docs/design/2026-06-17-ntfy-agent-comms-proposal.org]] (as-built runbook stays in the home project at =working/phone-notifications/spec.org=). What rulesets would decide: canonicalize =phone-notify= (send) plus a new =phone-recv= (check-since) as synced bin scripts; the per-machine config/secret convention (token in =~/.config/phone-notify/config= chmod 600 today, vs GPG-encrypted in dotfiles); a reference =ntfy-inbound-handler= plus systemd user-unit for event-driven delivery (Tier A subscriber routes inbound to inbox/notify, Tier B inbound spawns an agent session, Tier C notify a live session — harness research); approval-button workflows for the commits.md gates when Craig is away from the desk (tap-to-approve, the high-value concrete use); and the relationship to the retired cross-agent-comms scripts (ntfy may be the transport they lacked). Worked via =spec-create=. Blocks the triage-intake phone-push task below. ** TODO [#C] triage-intake.org auto mode — push each sweep to phone (ntfy) :feature:solo: :PROPERTIES: :CREATED: [2026-06-20 Sat] @@ -1224,183 +1216,11 @@ speculatively — defense-specific notations are narrow enough that each skill should be driven by a concrete contract need, not aspiration. * Rulesets Resolved -** DONE [#B] Wrap-up inbox/transcript routing to destination projects :feature:spec: -CLOSED: [2026-07-04 Sat] -:PROPERTIES: -:CREATED: [2026-06-13 Sat] -:LAST_REVIEWED: 2026-06-24 -:END: -Optional wrap-up step that surfaces filed keepers belonging to another project, recommends a destination, and routes each to that project's =inbox/= via =inbox-send= (the destination's own =process-inbox= files it; transcript filing deferred to vNext). Spec: [[id:00b47414-2213-4a99-be35-48ceb266fc08][wrapup-routing-spec.org]] — Ready, [9/9] decisions. Source proposal: [[file:docs/design/2026-06-13-wrapup-inbox-transcript-routing-proposal.org]]. - -*** 2026-06-21 Sun @ 02:06:37 -0400 Spec-review + spec-response complete — Ready -Craig's review challenge reshaped the design from a direct cross-repo =todo.org= move to =inbox-send= delivery into the destination's inbox (safer: reuses the sanctioned cross-project path, gets provenance + per-project filing for free, degrades gracefully where a destination has an =inbox/= but no =todo.org=). D2/D3 superseded; D7 (inbox-send delivery), D8 (=:ROUTE_CANDIDATE:= marker at file time), D9 (local source removal + reject-flow recovery) added. Spec-review file consumed and deleted. Implementation-task breakdown filed below (spec-response Phase 6). - -*** 2026-06-24 Wed @ 00:21:20 -0400 Reconcile — marker sub-task repointed at inbox.org -The 2026-06-23 inbox consolidation (24ca58d) merged =process-inbox= + =monitor-inbox= + =inbox-zero= into one =inbox.org= engine (process/monitor/roam modes) and deleted the three old files. The =:ROUTE_CANDIDATE:= marker sub-task targeted =process-inbox.org='s Phase D — repointed it to =inbox.org= process mode (core §3 "File as TODO"). No build has started, so this is a target-rename only; the spec design is unaffected. - -*** 2026-06-28 Sun @ 13:02:42 -0400 Built the recommendation engine + destination discovery -Added =.ai/scripts/route_recommend.py= (canonical + mirror): pure =recommend(item, projects) → (destination, confidence)= with strong (name/path literal, word-boundary matched, dot-stripped alias aware), weak (distinctive name-token overlap), and none tiers; a multi-way top-tier tie downgrades to weak with a deterministic pick (most overlap, then alphabetical); empty list → none. The CLI (=--item=, =--exclude=) reuses =inbox-send.py='s =discover_projects= via importlib so the candidate set matches inbox-send's project universe. 13 tests (the five spec'd cases + boundary/path/strong-beats-weak + 3 sandboxed CLI integration tests), full =make test= green. Covers spec Phases 1 + 3. Next sub-tasks (=:ROUTE_CANDIDATE:= marker, wrap-up router) call this engine. - -*** 2026-07-02 Thu @ 00:36:12 -0400 Phases 2 + 4 + test surface landed — marker, router, route-batch helper -inbox.org's "File as TODO" disposition now runs route_recommend on each keeper and stamps =:ROUTE_CANDIDATE: <destination>= on strong/weak matches (none stamps nothing; local keepers stay unstamped) — spec Phase 2 / D8. wrap-it-up.org Step 3 gained the optional router directly after the inbox sanity check, with the gate-vs-optional split named in the prose: surface the batch (task / destination / delivery mode / confidence, weak visibly labeled), go/skip, empty set = zero interaction — spec Phase 4 / D7 / D9. The go path is mechanical: new =.ai/scripts/route-batch= (--list read-only, --go extracts the subtree minus the marker with children riding along and headings promoted, delivers via inbox-send for provenance, removes the local subtree only after a successful send; a failed send leaves the task in place and exits non-zero). Test surface: engine unit tests existed (13); route-batch adds a 9-test bats suite (list/backlog-exclusion, empty-set silence, list-modifies-nothing = skip semantics, delivery + provenance + children, local-task survival, drawer-minus-marker, inbox-without-todo.org delivery, empty go, failed-send recovery). cross-project.md notes the router as a sanctioned cross-project write path. make test green, sync clean. - -*** 2026-07-04 Sat @ 11:49:59 -0500 Flipped the spec to IMPLEMENTED; parent closed -The routing build shipped green: route_recommend.py (destination discovery + recommendation, 13 unit tests), the =:ROUTE_CANDIDATE:= marker in inbox process mode, the wrap-it-up router sub-step, and route-batch (9 bats tests). Spec [[id:00b47414-2213-4a99-be35-48ceb266fc08][wrapup-routing]] flipped DOING → IMPLEMENTED. Manual end-to-end validation and the transcript vNext promoted to their own tasks. -** DONE [#C] Check that memories are sync'd across machines via git :spec: -CLOSED: [2026-07-04 Sat] -:PROPERTIES: -:LAST_REVIEWED: 2026-06-28 -:END: -v1 implemented end-to-end 2026-06-10 (Phases 0-4, all shipped + pushed) and the agent-KB spec is IMPLEMENTED. Both daily drivers (velox + ratio) carry the =roam.git= clone + sync-timer. Cross-machine sync verified as a full round-trip 2026-07-04: velox created a probe node 2026-07-01 and ratio held it; ratio then deleted it and velox pulled the deletion. Both clones sit at the same HEAD with zero sync-conflict files and both roam-sync timers active. The work/unknown-project write-refusal checks need live sessions in those projects and are tracked as a standalone manual-validation task below. -*** 2026-05-14 Thu @ 19:14:11 -0500 Investigate current memory storage - -Memory files live at -[[file:/home/cjennings/.claude/projects/-home-cjennings-code-rulesets/memory/][~/.claude/projects/-home-cjennings-code-rulesets/memory/]] -— four files including =MEMORY.md= and three individual entries -(=feedback_never_guess.md=, =project_ai_scripts_canonical_source.md=, -=reference_pdftools_venv.md=). The directory is a plain unmanaged dir -(no symlink, no enclosing git checkout). Neither -[[file:/home/cjennings/.claude/][~/.claude/]] itself nor any subtree -containing the project-memory dirs is tracked in -[[file:/home/cjennings/code/archsetup/][archsetup]] or -[[file:/home/cjennings/code/rulesets/][rulesets]]. Without a symlink -into a stowed or tracked location, memory files don't survive a new -machine setup or a dotfiles restore. - -Proposed setup: stow =~/.claude/projects= → -=archsetup/dotfiles/common/.claude/projects/= (path doesn't exist yet -— it's the target location pending VERIFY). -Create the destination in archsetup, move existing per-project -=projects/<encoded-cwd>/memory/= dirs there, run =stow= to link, then -commit + push archsetup. After that, every machine running =stow= -picks up the same memory tree. - -*** 2026-05-23 Sat @ 16:12:48 -0500 Decided: dedicated private repo, not stow -Worked through dotfiles → rulesets → dedicated repo. Dropped stow/dotfiles (machine config, wrong cadence) and rulesets (it's pulled first in every session, so memory edits would dirty its tree and skip the startup =git pull --ff-only=). Chose a dedicated private repo on cjennings.net: storage is unified there while recall stays per-project (the encoded-cwd subdirs), since pooling recall would hurt relevance and risk work-private facts surfacing in personal-project artifacts. - -*** 2026-05-23 Sat @ 16:12:48 -0500 Shipped: claude-memory.git + folded symlinks -Created bare =git@cjennings.net:claude-memory.git=, cloned to =~/.claude-memory= (later deleted in the reversal below), moved all 7 per-project =memory/= dirs in (54 files; work has 40) and replaced each live =~/.claude/projects/<enc>/memory= with a folded dir-symlink so new memory lands in the clone and a push syncs it. Added =link-claude-memory.sh= (idempotent — recreates the symlinks on a new machine after clone) + README. Private repo, never GitHub (carries work/DeepSat memory). Initial import pushed (=f496370=). - -*** 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: [[id:08a5ec99-9e1e-40e4-8241-e8a41e9de49f][agent-knowledge-base-spec.org]] (originally docs/design/2026-06-05-org-roam-knowledge-base-spec.org; superseded by the 2026-06-10 spec-create rewrite at the new path). 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. - -*** 2026-06-10 Wed @ 14:29:20 -0500 Spec ratified — write boundary is option C; rewritten to spec-create format -Craig answered via cj annotations in the spec (2026-06-10): DECISION 5 is option C (read-shared, write-scoped — work agents never write the KB). Syncthing does replicate ~/sync/ to a work machine and Craig is fine with how C handles it. Node granularity: per-fact nodes. Write review: agent writes land freely in the KB only — explicitly not permission to post to email, Linear, or any public channel without review and consent. The spec was rewritten into the spec-create format at [[id:08a5ec99-9e1e-40e4-8241-e8a41e9de49f][agent-knowledge-base-spec.org]] (old draft removed). Implementation explicitly held pending Craig's go-ahead; one decision still open (D7, next VERIFY). - -*** 2026-06-10 Wed @ 14:35:40 -0500 Spec review — not ready -Review written at docs/agent-knowledge-base-spec-review.org (deleted on disposition completion; content summarized in the spec's Review dispositions). Rubric: =Not ready=. Blockers: resolve D7 (keep vs retire harness memory) and define the executable personal/work/unknown write-boundary classifier plus work-side write/refusal destination. Medium notes: use concrete ripgrep commands that exclude =*.sync-conflict-*= files, and define seed-node approval/rollback. - -*** 2026-06-10 Wed @ 14:44:00 -0500 D7 resolved — keep harness memory as the capture layer -Craig ratified "keep" in chat (2026-06-10). Harness memory stays the ephemeral, auto-recalled capture layer; the KB holds promoted durable facts; Phase 3's wrap-up promotion cadence is mandatory. Spec D7 flipped to accepted; D2 stands as written. - -*** 2026-06-10 Wed @ 14:44:00 -0500 Project classification defined — work-root denylist, unknown refuses -Resolved in the spec-response pass: =knowledge-base.md= carries an explicit work-root denylist (initially =~/projects/work=) as the source of truth. Personal = under a known project parent (=~/code/=, =~/projects/=, =~/.emacs.d=) and not denylisted → KB writes allowed. Work or unknown → no KB write; the agent reports the refusal with a one-line redacted summary of the fact. v1 adds no new work-side store — work projects keep their existing project-tree conventions. See the "Project classification and write routing" section of [[id:08a5ec99-9e1e-40e4-8241-e8a41e9de49f][the spec]]. Denylist completeness is the one open caveat (next VERIFY). - -*** 2026-06-10 Wed @ 14:44:00 -0500 Codex review incorporated — spec ready with caveats -Spec-response pass processed the 2026-06-10 Codex review with D7 = keep as a pre-agreed input. Both blockers cleared (D7 accepted; classification/write-routing section added). Mediums accepted: canonical rg commands with conflict-file exclusion, Phase 2 seed-node approval/rollback mechanics, Makefile no-change note, Testing/Verification section. Three recommendations modified, none rejected — see the spec's Review dispositions. Review file deleted per the workflow. Rubric: ready with caveats (denylist confirmation). Implementation tasks broken out below; implementation itself awaits Craig's go. - -*** 2026-06-10 Wed @ 17:29:37 -0500 Work-root denylist confirmed — ~/projects/work only -Craig confirmed (2026-06-10, in chat): the denylist is just =~/projects/work=. Archangel is not work-scoped. The spec's one caveat clears — status now ready. Phase 1 is unblocked, but implementation still awaits Craig's explicit go. - -*** 2026-06-10 Wed @ 17:57:08 -0500 Spec amended — D8 git transport + migration/metrics/docs/maintenance folds -Craig's five design questions answered and folded into the spec, and D8 ratified (Shape A): the KB moves out of the =~/sync/org= Syncthing share into its own git repo on cjennings.net, with an =agents/= subdirectory for agent writes, a systemd auto-sync timer for Craig's edits, opt-in-by-clone replication (work machine doesn't clone), and the phone staying on the on-demand =~/sync/phone= pattern. Folded in: inclusion criteria + a Phase 1.5 guided memory sweep, a Success metrics section with a 30-day checkpoint, the seed node redefined as the KB's own documentation, and Phase 4 maintenance automation. Phases renumbered 0-4; tasks below updated. Implementation still held. - -*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 0 done — roam migrated to git -Backed up (~/roam-backup-2026-06-10.tar.gz), copied to =~/org/roam=, 63 conflict files deleted (424 org files), git repo with origin =git@cjennings.net:roam.git= (initial commit 515693d), old location replaced with a transition symlink. Emacs =roam-dir= updated in user-constants.el + live-reloaded (db rebuilt, 416 nodes); handoff to .emacs.d for the commit. =roam-sync.sh= (6 bats green) on a 15-min systemd user timer, installed + enabled + round-trip verified. Old-path references repointed (protocols task-list pointer, journal workflow, notes template). archsetup handoff covers dotfiles adoption + other-machine clones. rulesets commit fcf554a. - -*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 1 done — knowledge-base.md rule live -=claude-rules/knowledge-base.md= written (path, git discipline, query commands, agents/ write schema, denylist + refusal contract, inclusion criteria, capture-then-promote). =make install= linked it machine-wide; verified the link, a known-note query, and conflict-glob exclusion with a planted file. Commit d071f1f. - -*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 1.5 done — rulesets swept, 10 projects broadcast -Rulesets' 6 memories classified: 3 promoted as =agents/= nodes (notify-attention pattern, pdftools venv, gpg-agent SSH TTL trap), 2 kept local (rule-encoded in verification.md / interaction.md), 1 kept + de-staled (ai-scripts-canonical updated for the claude-templates subtree fold). Sweep handoff broadcast to the 10 other memory-bearing projects (archsetup, org-drill, pearl, .emacs.d, elibrary, finances, health, home, jr-estate, kit); work skipped by the boundary; the orphaned =linear-emacs= memory dir (project retired, likely pearl's predecessor) noted for Craig. - -*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 2 done — seed/doc node written and indexed -=agents/20260610181640-how-the-agent-knowledge-base-works.org= written: the KB's user-facing guide (what agents do, how it syncs, finding/pruning agent content, the rule pointer). Index verified programmatically: =org-roam-node-from-title-or-alias= resolves it with tags (agent reference); node count 416 → 420. Craig's visual check remains in the manual-testing child. - -*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 3 done — wrap-up promotes + records the KB receipt -wrap-it-up.org Step 1 gains the promotion check (inclusion-criteria bar) and the mandatory "KB: promoted N / consulted yes-no" Summary line; validation checklist enforces it. Mirror synced, integrity OK (44), parse OK. Commit 242b95e. - -*** 2026-06-11 Thu @ 19:26:26 -0500 .emacs.d memory sweep complete (first broadcast response) -First of the 10 broadcast projects to report Phase 1.5 done (handoff 18:23). Inventory 7: promoted 3 to KB (no-make-frame-in-live-daemon, proton-bridge-headless-cert-mismatch, open-images-with-imv — roam commit a915760), kept 3 local at Craig's call (commit-flow-no-approval-gate per-project-scoped; two theme-scoped ones possibly superseded by the palette-columns spec), deleted 1 (superseded by canonical interaction.md rule). 9 projects' sweeps outstanding. - -*** 2026-06-12 Fri @ 02:25:12 -0500 Five more sweeps complete via the home folds -Overnight handoffs from home closed five more broadcast targets, each swept at fold-time triage with Craig's approval: jr-estate 2 promoted (forms name-with-number, PDF-editing tooling split; roam 45d8e6c) / 3 kept with area attribution / 2 deleted as rule-encoded or duplicate; finances 0/1/0 (rosalea-daly contact fact kept local); elibrary 0/0/2, health 0/0/1, kit 1/0/2 (hand-prep-items-to-work-inbox promoted into home's memory; the rest duplicated rules or home memories). Nothing from these five met the KB bar that wasn't already encoded. All folded projects' session archives merged area-prefixed into home's .ai/sessions/, so session-harvest's first run sees them. Home covers its own and remaining areas' sweeps through ongoing discipline; still pending from the broadcast: archsetup and work. - -*** 2026-07-04 Sat @ 11:52:00 -0500 Manual validation — checks 1 + 4 verified; refusal checks split out -Check 1 (seed node in org-roam + rg inventory) verified on velox 2026-07-01 (55 =:agent:= nodes matched the live org-roam DB). Check 4 (cross-machine sync) verified as a full round-trip 2026-07-04: velox pushed a probe 2026-07-01, ratio held it, ratio deleted it, velox pulled the deletion; both clones at the same HEAD, zero sync-conflict files, both timers active. Checks 2 + 3 (work / unknown-project write refusal) need live sessions in those projects — promoted to a standalone manual-validation task. - -*** 2026-06-10 Wed @ 18:21:33 -0500 Phase 4 done — monthly hygiene automation live -=scripts/kb-hygiene.sh= (6 bats green, shellcheck clean, read-only by design) inventories =:agent:= nodes, flags orphans / duplicate titles / conflict files, and writes an org report into the rulesets inbox; =roam-hygiene.timer= (monthly, Persistent) installed + enabled. Live run against the real KB verified (4 agent nodes, 428 files, 0 conflicts). Conditional vNext stays in the spec's scope tiers: a =/promote= command if the wrap-up prompt proves insufficient, an =:agent:inbox:= staging tag if free writes prove too noisy. Commit b014095. - -*** 2026-06-30 Tue @ 13:53:34 -0400 ratio roam clone + sync-timer confirmed (cross-machine half done) -Verified ratio over tailscale ssh: =~/org/roam= is a clone of =git@cjennings.net:roam.git= (HEAD auto-synced 13:11 today), and =roam-sync.timer= is enabled and actively firing (last run 5 min prior, next in 10). Both unit files present. velox was already confirmed, so the one-time clone+timer setup is now done on both daily drivers — the (b) half of this VERIFY's remaining work. Only the manual-validation child (work/unknown-project refusal checks needing Craig's eyes) is left before DONE. Cleared the matching "Current open instance" line in =daily-drivers.md=. - -*** 2026-07-01 Wed @ 21:52:15 -0400 Manual-validation checks 1 + 4 (velox half) verified; ratio unreachable -Check 1 (seed node in org-roam + rg inventory): 55 =:agent:= nodes found by the rg inventory AND 55 nodes under =agents/= indexed in the live org-roam DB (emacsclient query) — match. Check 4 (cross-machine edit): created a temporary probe node =agents/20260701214910-kb-sync-validation-probe.org=, triggered =roam-sync= — committed and pushed to origin within seconds (f0252bb), zero =sync-conflict= files. The ratio half could NOT be verified tonight: =tailscale ping ratio= pongs via DERP, but ssh to 100.71.182.1:22 times out (machine likely suspended). Probe left in place; when ratio is back, confirm with: ssh cjennings@100.71.182.1 'ls ~/org/roam/agents/ | grep kb-sync-validation-probe' — then delete the probe node. Checks 2 + 3 (work/unknown-project refusal) still need live sessions in those projects, and "work machine has no KB clone" needs the work machine named + checked. -** DONE [#C] Spec storage location + lifecycle-status convention :spec: -CLOSED: [2026-07-04 Sat] +** CANCELLED [#C] ntfy phone channel as general two-way agent-comms :feature:spec: +CLOSED: [2026-07-13 Mon] :PROPERTIES: -:CREATED: [2026-06-15 Mon] +:CREATED: [2026-06-20 Sat] :LAST_REVIEWED: 2026-06-24 -:SPEC_ID: 80b0787b-4a60-4c82-8a16-b383d3e3c8f2 :END: -Two coupled documentation conventions for rulesets to adopt, surfaced by .emacs.d while triaging ~28 design docs. Both land in =spec-create= ([[file:.ai/workflows/spec-create.org]]) and likely a new =docs-lifecycle= rule under =claude-rules/=. Source proposal: [[file:docs/design/2026-06-15-spec-storage-lifecycle-proposal.org]] (.emacs.d handoff 2026-06-15). - -The two conventions: -- *Location split* — formal specs live in =docs/specs/=; =docs/design/= keeps working notes, brainstorms, inventories, reviews. A spec is a doc proposing a buildable change with a Decisions section and phases; everything else is a note. -- *Glanceable lifecycle status* — a spec's state (draft / doing / implemented / superseded / cancelled) is visible without opening the file, plus an authoritative in-file record. - -We handle the task in priority order. Mechanism decided 2026-06-28; migrates into the spec when built. - -*** Decisions (settled 2026-06-28 — migrate into the spec when built) -1. *Location split — adopt.* =docs/specs/= for formal specs, =docs/design/= for notes (brainstorms, inventories, reviews). A spec is a doc proposing a buildable change with a Decisions section and phases; everything else is a note. Document in spec-create and the docs-lifecycle rule. -2. *Status mechanism — org-keyword authoritative.* The spec's =#+TODO:= state on its top heading is authoritative (specs already carry =#+TODO: TODO | DONE SUPERSEDED CANCELLED=), mirrored in a =Status= field in the Metadata table. Drop the filename suffix entirely — it's redundant with the Status field and adds rename churn across a cross-linked, template-synced doc set. (Craig 2026-06-28, choosing org-keyword over his earlier filename-suffix lean.) -3. *Link safety — adopt =org-id= ([[id:...]]) for cross-doc spec links.* Decouples link stability from the status mechanism; good hygiene regardless. -4. *Generalize.* Capture the shape (lifecycle state authoritative-in-artifact, formal-vs-notes split, rename-safe links) as a general =docs-lifecycle= convention in =claude-rules/=, with spec-create as the first instance. -5. *Retrofit existing files across ALL projects* (Craig 2026-06-28). The convention is worthless if legacy docs stay misfiled — every project's existing =docs/design/= pile (the ~28 in .emacs.d that surfaced this) must be sorted: formal specs move to =docs/specs/=, notes stay in =docs/design/=, inbound =file:= links updated. This is a one-time per-project migration that template sync can't perform, so the spec must design the reach mechanism. Proposed shape: a synced classify-and-move helper under =.ai/scripts/= (heuristic: a doc with a Decisions section + phases/Metadata is a spec) that proposes moves for confirmation and relinks, plus a startup nudge gated on a per-project =:LAST_SPEC_SORT:= marker so each project runs it once. Classification is a judgment call — the helper proposes, a human confirms. - -Follow-up once built: update spec-create to emit into =docs/specs/= with the org-keyword status; write the =docs-lifecycle= rule; ship the retrofit helper + startup nudge; retrofit rulesets' own =docs/design/= first as the pilot; send a note if .emacs.d should pilot before generalizing. - -*** 2026-07-01 Wed @ 22:13:00 -0400 Spec drafted — first resident of docs/specs/, awaiting review -Wrote [[id:80b0787b-4a60-4c82-8a16-b383d3e3c8f2][the spec]] from the five settled decisions, dogfooding its own conventions: it lives in the new =docs/specs/=, opens with the =* DRAFT Docs lifecycle= status heading (org keyword authoritative, =:ID:= for id-links, dated history in the body), and drops the status filename suffix. It pins the one mechanism the decisions left open — where the keyword lives: a prepended top-level status heading with vocabulary =DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED=, additive and retrofittable, giving both the one-line =rg= board and free org-agenda scanning. Four build phases: rule + template updates → =spec-sort= helper (classify/confirm/move/relink, bats) → rulesets pilot (41 design files, 3 spec-spine candidates, 2 stray root specs) → startup nudge gated on =:LAST_SPEC_SORT:= + .emacs.d note. Status DRAFT until Craig's review flips it READY. - -*** 2026-07-01 Wed @ 22:22:34 -0400 Codex spec-review complete — Not ready -Review findings live in [[id:cc77a7f6-e4c3-488a-ac3b-e739420a5c2b][the spec]]. Four blockers before implementation: the proposed lifecycle =#+TODO:= line drops the =TODO=/=DONE= states needed by Decisions and Review findings cookies; =spec-sort= needs an exact relink/unsupported-residue contract; the sort marker/startup nudge must name the actual =.ai/notes.org= state surface and detection flow; and the stricter =docs/specs/= review precondition must not strand legacy specs before retrofit. - -*** 2026-07-01 Wed @ 22:30:06 -0400 Second review merged + responder pass — all nine findings fixed -A fresh-context Claude reviewer independently rated the draft Not ready, converging on Codex's keyword-vocabulary blocker (adding the cross-sequence uniqueness wrinkle) and contributing five unique findings — the biggest: nobody owned the DOING→IMPLEMENTED flip, the exact mechanism whose failure produced this spec. Craig approved fixing all nine. Fixed in place: two-sequence collision-free keyword header (dogfooded in the spec's own header; org now computes the [5/5] and [9/9] cookies — verified in batch), transition-ownership table incl. spec-response's mandatory flip-to-IMPLEMENTED task + task-audit safety net, single classification predicate (Decisions AND Implementation phases), the -spec.org rename step, the full relink data-safety contract (rewritten roots / report-only surfaces / dry-run default / residue-grep gate), the =.ai/notes.org= marker + Phase A probe + Phase C nudge contract, the legacy-location compatibility rule, the org-id Emacs-resolution prerequisite for .emacs.d, and the three-line transition definition. Ledger + per-finding responses in the spec's Review findings section. Status stays DRAFT pending Craig's READY flip. - -*** 2026-07-01 Wed @ 22:41:33 -0400 Codex spec-review rerun — Not ready -Fresh review after the response/READY flip added five new blocking findings in [[id:cc77a7f6-e4c3-488a-ac3b-e739420a5c2b][the spec]] and demoted the spec back to DRAFT. Remaining blockers: shared helper/workflow edits must name the canonical =claude-templates/.ai/= + mirror sync contract; task-audit needs an explicit spec-to-task binding before it can police =DOING= specs; =spec-sort --apply= needs a failure-safe/rollback contract; the org-id Emacs prerequisite must be executable before link conversion; and lifecycle status confirmation must be evidence-based so the retrofit does not encode stale reality. - -*** 2026-07-01 Wed @ 22:46:52 -0400 Second responder pass — all fourteen findings closed -Fixed Codex's five re-review findings: the canonical-placement contract now opens the retrofit section (helper + tests + workflow edits land in claude-templates first, sync-check --fix propagates, sync-check-clean is an acceptance criterion); spec-response stamps a =:SPEC_ID:= property on the build parent, and task-audit's query checks that parent's keyword — which dissolves the flip-task chicken-and-egg; =--apply= got the fail-safe contract (clean-tree preflight, validate-then-write from a recorded plan, named recovery recipe); id-link conversion is staged (pilot rewrites =file:= links only; =id:= conversion is a follow-up gated on the concrete .emacs.d id-index mechanism — Craig picked this fork); and status confirmation is evidence-based (evidence panel, conservative non-terminal default, terminal states need a stated reason). Also de-cookified bracket tokens in prose that org's cookie updater would mangle. Status stays DRAFT; the READY flip belongs to the reviewers this round — verify pass dispatched. - -*** 2026-07-01 Wed @ 23:22:50 -0400 Codex spec-review rerun — Ready -Codex re-read the revised [[id:80b0787b-4a60-4c82-8a16-b383d3e3c8f2][docs lifecycle spec]] after the second responder pass. All fourteen findings are closed, decisions remain [5/5], and the remaining implementation contracts are concrete enough to build and test. Status flipped to READY in the spec; implementation can proceed. - -*** 2026-07-01 Wed @ 23:34:15 -0400 Decomposed into build tasks; spec flipped READY → DOING -spec-response Phase 6 run: this parent now carries the =:SPEC_ID:= binding (the spec's status-heading UUID), the phase tasks below track the build, and the spec's status heading is DOING. Completeness pass done: all ten acceptance criteria have homes across the phase tasks; vNext (org-agenda view) was already filed as the [#D] task below. - -*** 2026-07-01 Wed @ 23:39:10 -0400 Phase 1 landed — docs-lifecycle rule + four spec-workflow updates -claude-rules/docs-lifecycle.md written and linked machine-wide (make install). Canonical-side updates: spec-create Phase 5 + template (docs/specs/ location, two-sequence keyword header, DRAFT status heading with :ID:, transition mechanics), spec-review (location expectation with the legacy compatibility rule keyed on :LAST_SPEC_SORT:, plus the DRAFT→READY flip — and the demote-back-to-DRAFT path a failed re-review takes), spec-response Phase 6 (owns READY→DOING, stamps :SPEC_ID: on the build parent, always emits the flip-to-IMPLEMENTED task), task-audit Phase B (the :SPEC_ID: reconcile query, checking the parent's keyword rather than counting children). Mirror synced; make test green end to end. - -*** 2026-07-01 Wed @ 23:57:44 -0400 Phase 2 landed — spec-sort helper + 30-test bats suite -Built claude-templates/.ai/scripts/spec-sort (Python, TDD — the 30-test bats suite written red-first in claude-templates/.ai/scripts/tests/spec-sort.bats) covering the full retrofit contract: spine classification with the -spec.org-name-without-spine anomaly case, evidence panel (Status field, cookies, linking todo.org task, dated history, artifact existence) with conservative non-terminal proposals, per-candidate --confirm/--skip gate with --reason required on terminal keywords, clean-worktree preflight (--allow-dirty prints what recovery loses), validate-then-write from a recorded plan file, relink across the rewritten roots (inbound AND the moved doc's own outbound relative links) with report-only for sessions + synced templates (naming the canonical claude-templates file), bare-path mentions blocking until --acknowledge-bare, named recovery on injected mid-apply failure, post-apply residue gate, idempotent :LAST_SPEC_SORT: stamp. Real-data dry run against rulesets' pile matched predictions: 5 candidates, 4 anomalies, 30 notes, 0 bare, 10 report-only (incl. the startup.org synced-template case Codex flagged). make test green; sync-check clean. - -*** 2026-07-02 Thu @ 00:18:28 -0400 Phase 3 pilot ran — rulesets' pile sorted, board live -Craig confirmed all five proposed keywords as-is plus the IMPLEMENTED reason; spec-sort --apply moved the five specs to docs/specs/ (agent-knowledge-base IMPLEMENTED, inbox-workflow-consolidation READY, autonomous-batch-execution READY, encourage-kb-contribution READY, wrapup-routing DOING — joining the docs-lifecycle spec's DOING on the board), rewrote 12 todo.org links plus the moved specs' own outbound links, and stamped :LAST_SPEC_SORT: 2026-07-02. Acceptance verified: status board matches reality, all re-homed specs carry -spec.org, residue zero in the rewritten roots (one acknowledged self bare mention rode along inside inbox-workflow-consolidation-spec), no id: links emitted, make test green. Surfaced and left in place: the four -spec.org-named files in docs/design without a spec spine (generic-agent-runtime, pattern-catalog, daily-prep-template, auto-triage-intake) — notes by predicate, misleading names; rename or leave is a Craig call. Report-only references: 9 frozen session archives + the synced startup.org (canonical edit lands with Phase 4's nudge work). - -*** 2026-07-02 Thu @ 00:23:32 -0400 Phase 4 landed — startup nudge live, .emacs.d notified -Added the spec-sort probe to startup.org Phase A (item 12) and the one-line nudge to Phase C's findings list, canonical-side, mirror synced. One refinement over the spec's sketch: the stray-root check uses find instead of compgen, because compgen is bash-only and zsh aborts on an unmatched glob — the original snippet false-negatived on stray root specs under zsh (spec snippet updated with a note). Fixture-verified in both shells: fires on an unsorted docs/design and on a stray docs/*-spec.org, silent with the marker stamped, silent with no docs at all. Also fixed startup.org's own stale reference to the moved encourage-kb-contribution spec (the pilot's report-only finding). Sent .emacs.d the convention-live note with its ~28-doc pile nudge and the id-index ask (org-id-extra-files enumeration or periodic org-id-update-id-locations, verify by clicking the docs-lifecycle spec's :ID:), asking it to tag the owning task :blocker: since rulesets' id-conversion task waits on it. - -*** 2026-07-02 Thu @ 05:12:33 -0400 Converted spec-target file: links to id: form (rulesets) -All 13 file:docs/specs/ links lived in todo.org (zero in .ai/ or docs/ outside specs). 11 converted straight to [[id:UUID][label]] (bare links labeled with the spec filename); the 2 links carrying a ::*Review findings search target got full fidelity by minting an :ID: on that heading in the docs-lifecycle spec (cc77a7f6-e4c3-488a-ac3b-e739420a5c2b) — the id index scans whole files, so heading-level ids resolve. Residue grep zero; every id verified against its target's :ID:. Gate had cleared earlier tonight via .emacs.d's org-spec-links.el delivery (verified org-id-find on their side); M-x cj/org-id-refresh-spec-locations is the fix if a fresh id doesn't resolve on click. - -*** 2026-07-04 Sat @ 11:46:31 -0500 Flipped the spec to IMPLEMENTED -All four build phases had shipped (docs-lifecycle rule + spec-workflow updates, spec-sort helper + 30-test bats suite, rulesets pilot + status board, startup nudge) plus the conversion of file-style links to id-style links, so the spec's status heading went DOING → IMPLEMENTED with a dated history line and the Metadata mirror, per the transition-ownership table. Parent closed; manual validation promoted to its own task. +Killed at the 2026-07-13 task review: home retired and tore down the ntfy channel on 2026-07-04, so this proposal's transport no longer exists. Its living successors are the Signal pager ([#B] task above — one identity on velox, runbook pending) and agent-page (shipped 2026-07-13), which cover the send half; two-way (read-replies) rides the Signal runbook. +Proposal from the home project (2026-06-17): promote the self-hosted ntfy-over-Tailscale phone channel it built and verified on ratio into a general two-way agent-comms tool rulesets owns. Full proposal: [[file:docs/design/2026-06-17-ntfy-agent-comms-proposal.org]] (as-built runbook stays in the home project at =working/phone-notifications/spec.org=). What rulesets would decide: canonicalize =phone-notify= (send) plus a new =phone-recv= (check-since) as synced bin scripts; the per-machine config/secret convention (token in =~/.config/phone-notify/config= chmod 600 today, vs GPG-encrypted in dotfiles); a reference =ntfy-inbound-handler= plus systemd user-unit for event-driven delivery (Tier A subscriber routes inbound to inbox/notify, Tier B inbound spawns an agent session, Tier C notify a live session — harness research); approval-button workflows for the commits.md gates when Craig is away from the desk (tap-to-approve, the high-value concrete use); and the relationship to the retired cross-agent-comms scripts (ntfy may be the transport they lacked). Worked via =spec-create=. Blocks the triage-intake phone-push task below. |
