From f573c35885583900e3e319cea384606c4e0321cf Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Mon, 13 Jul 2026 23:50:33 -0500 Subject: chore: archive completed tasks and close out the day's records The archive sweep moves the finished routing feature and the cancelled ntfy proposal into Resolved, todo.org carries the day's review stamps and dated build entries, and the session record lands under its dated name. --- .ai/notes.org | 2 +- ...3-23-48-runtime-portability-pager-local-llm.org | 191 +++++++++++++++++++++ archive/task-archive.org | 180 +++++++++++++++++++ todo.org | 190 +------------------- 4 files changed, 377 insertions(+), 186 deletions(-) create mode 100644 .ai/sessions/2026-07-13-23-48-runtime-portability-pager-local-llm.org 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: 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- 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: = 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//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//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//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. diff --git a/todo.org b/todo.org index eb5af19..b9a71d4 100644 --- a/todo.org +++ b/todo.org @@ -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: = 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//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//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//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. -- cgit v1.2.3