aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-12 03:10:52 -0500
committerCraig Jennings <c@cjennings.net>2026-06-12 03:10:52 -0500
commit8e18033ba47e9b143ce141898cde909080a299ec (patch)
tree9c1ec0200546ace96f03024b8e185e0b14f14581
parentb6d286f1e123f84a8e93b92c9f4711a3190b958d (diff)
downloadrulesets-8e18033ba47e9b143ce141898cde909080a299ec.tar.gz
rulesets-8e18033ba47e9b143ce141898cde909080a299ec.zip
chore: archive session record, file done work, and log a cleanup bug
The archive pass moved four closed subtrees to Resolved while reporting zero moves; the relocation was correct and the reporting defect is filed as a [#D] bug.
-rw-r--r--.ai/sessions/2026-06-12-03-09-helper-spec-cycle-harvest-update-skills.org118
-rw-r--r--inbox/lint-followups.org2
-rw-r--r--todo.org224
3 files changed, 235 insertions, 109 deletions
diff --git a/.ai/sessions/2026-06-12-03-09-helper-spec-cycle-harvest-update-skills.org b/.ai/sessions/2026-06-12-03-09-helper-spec-cycle-harvest-update-skills.org
new file mode 100644
index 0000000..1ef534b
--- /dev/null
+++ b/.ai/sessions/2026-06-12-03-09-helper-spec-cycle-harvest-update-skills.org
@@ -0,0 +1,118 @@
+#+TITLE: Session Context — 2026-06-11 15:18
+#+DATE: 2026-06-11
+
+* Summary
+
+** Active Goal
+The standing no-approvals batch (session-harvest workflow + /update-skills command), then a long collaborative arc taking the helper-instance design — concurrent same-project Claude agents — from a question about session-context suffixes to a fully reviewed, READY-WITH-CAVEATS spec slice. Interleaved: home-consolidation coordination, Craig's triage deltas-only ruling applied to canonical, and rolling inbox processing.
+
+** Decisions
+- Helper instances (Craig, across five same-evening revisions + a coherence pass): agent-roster process-scan is the single detection primitive (claude-scoped for 1.5); ai --helper is the deterministic spawn path with the startup roster check as safety net for raw launches; primary keeps the unset-id singleton, helpers self- or launcher-assign helper-<rand4>; helper-mode.org is the single canonical home of the role contract; tiered write contract (scoped single-heading org edits OK, file-wide passes + inbox + memory + all git mutation primary-only); orphaned helper assumes full closing duties (git ban is concurrency-scoped); primary wrapping over live helpers pauses at hygiene AND commit; three-ring pre-live gate with per-ring rollbacks because template sync makes "live everywhere" the default failure mode.
+- Review cycle: Codex two passes (Not-ready combined → Ready-with-caveats for 1.5 confirmed); all dispositions accepted, document-split modified to dual rubric; phases 2-5 parked behind a five-decision fence + Phase 5 reverification.
+- Emacs surface: ghostel (libghostty-vt) is the terminal; ai-term.el (F9, aiv- tmux sessions, -A attach-or-create = one session per project) is the launch surface; integration shares only agent-roster; helper needs own session/buffer names; ai-term.el change is an .emacs.d handoff.
+- Home consolidation: confirmed-okay sent after the tooling sweep; Craig corrected the todo shape to a single Open Work/Resolved pair (home reshaped same night, spec amended); todo-cleanup multi-pair task cancelled as unnecessary.
+- Triage-intake (Craig via work): deltas-only sweep summaries, all-quiet = one line, failures stay loud; telegram dev-group traffic never reported unless asked.
+- New personal projects are home regroupings — no creation mechanism needed (Craig's cj answer; concurred after verifying no doc says otherwise).
+- update-skills layout deviations: central upstreams/<name>/ manifests (arch-decide is two flat command files); baselines seeded at 2026-06-11 upstream HEADs (fork points unrecoverable).
+- opus committed as the machine-default model after tracing the /model→symlink→tracked-file chain.
+
+** Data Collected / Findings
+- mtime is unreliable for session-file windows (2025 files passed a -newermt filter); filename date prefixes are the filter. Live-tested in session-harvest's snippet.
+- git merge-file signals hard errors as exit 255 (negative C exit), which subprocess reports positive — guard at >=128 or mask errors as conflicts.
+- ai-term.el launch embeds the opener in the tmux new-session string (env injection = prefix); -A means F9 reattaches and cannot spawn a second agent per project.
+- eat/vterm assumption was wrong and self-detectable (ps scan showed neither); "ghostel" was the literal name. never-guess memory strengthened: grep for unrecognized names before concluding typo.
+- Roster detection verified live: pgrep -x claude + /proc/<pid>/cwd showed 4 concurrent agents; self-ancestry exclusion works; eat/vterm-style shells are emacs children but ai-term agents are tmux-parented either way.
+- lint-org false-flagged runtime-registered link types (mu4e:) in batch; fixed via no-op org-link-set-parameters pre-registration (merges, so live mu4e unaffected).
+- todo-cleanup.el lacks the backup-to-/tmp invariant the other two file-wide passes have — Phase 1.5 item.
+- page-signal's GV pager number got deregistered by Signal; re-registration needs Craig (VERIFY filed).
+- Memory-sweep broadcast now ~complete: .emacs.d + 5 via home folds recorded; archsetup and work outstanding.
+
+** Files Modified
+- claude-templates/.ai/workflows/session-harvest.org (new) + INDEX + mirrors — monthly promotion-mining pass, four lanes, KB receipt metrics.
+- scripts/update-skills.py (new, 17 bats) + .claude/commands/update-skills.md + upstreams/{arch-decide,playwright-js,playwright-py}/ manifests + baselines.
+- claude-templates/.ai/workflows/triage-intake.org + triage-intake.telegram.org + mirrors — deltas-only reporting, silent dev groups.
+- docs/design/2026-05-28-generic-agent-runtime-spec.org — helper-instance section (detection/spawn/identity/write-tiers/data-integrity/Emacs contract/wrap-up ordering), dual readiness rubric, decisions fence, three-ring gating with rollbacks, dispositions + history; -review.org (Codex, two passes).
+- claude-templates/.ai/scripts/lint-org.el + tests + mirrors — runtime link-type pre-registration (33 ERT).
+- claude-rules/ none; .claude/settings.json (model: opus); todo.org (tasks closed/filed/cancelled; VERIFYs; sweep logs); 12 commits pushed to cjennings.net plus a roam KB node.
+- Handoffs: home x5 (okay + todo-shape + decision + sweeps ack + lint fix), .emacs.d x2, work x1.
+
+** Next Steps
+- Helper-instance build awaits Craig's go: agent-roster + helper-mode.org + startup/wrap-up branches + ai --helper + .emacs.d handoff, under the three-ring gate ([#B] task carries everything).
+- Craig: re-register the page-signal pager number (VERIFY, captcha/SMS); runtime-arc phases 2-5 go/no-go + five decisions whenever that becomes live.
+- Watch for archsetup + work memory-sweep replies; first session-harvest run due ~2026-07-11.
+
+KB: promoted 1 / consulted no
+
+* Session Log
+
+** respond-to-cj-comments on todo.org (~02:57)
+One cj comment: Craig's answer inside the new-projects-as-areas VERIFY — new personal projects live in home as regroupings, no creation mechanism needed, "tell me if you disagree". Verified before concurring: no template doc directs personal work into ~/projects (first-session.org / install-ai.sh / README clean; only discovery-root scans reference it, still needed for home+work). Concurred. VERIFY-answer pattern applied: dated rewrite at ** with his decision + the situation description, cj block folded in and removed. File clean (0 cj blocks); page-signal VERIFY remains open by design. Committed b6d286f, pushed.
+
+** Spec-response on the second review (~02:47)
+Codex's second pass confirmed convergence: Phase 1.5 Ready with caveats, phases 2-5 Not ready behind the decisions fence, zero new high/medium findings, all dispositions accepted in its Agreed decisions. Response was minimal by design: accepted the one optional editorial edit (Emacs subsection heading renamed from "Open issue ... blocks readiness" to "Emacs launch surface — integration contract"), added a second-pass note under Review dispositions, appended the author history entry. Codex's review-file rewrite, spec history entry, and todo.org updates ride in the same commit. Review cycle is closed; the helper slice awaits Craig's go.
+
+** Generic runtime spec review rerun after response
+Craig said the generic runtime spec had been updated and asked to rerun .ai/workflows/spec-review.org. Re-read the workflow, the updated spec, the prior review artifact, implementation touchpoints (Makefile, claude-templates/bin/ai, install/sync scripts, session-context resolver/tests), and the relevant todo.org tasks. Updated docs/design/2026-05-28-generic-agent-runtime-spec-review.org with the second-pass result: Phase 1.5 helper instances are Ready with caveats; phases 2-5 remain Not ready behind explicit decisions and Phase 5 current-source verification. Added a new Review and iteration history entry to the spec and updated the helper/runtime todo entries to match.
+
+** settings.json model default committed (~02:32)
+Investigated scope for Craig: ~/.claude/settings.json symlinks to rulesets .claude/settings.json = user-level machine-wide config; no project settings carry a model key; tracked file means the default propagates cross-machine via pulls. Any session's /model "save as default" writes this shared file (his /model fable yesterday wrote fable; a later session wrote opus). Craig chose commit: opus is now the machine default (5feaa94, pushed).
+
+** Overnight inbox batch processed (~02:28)
+Five handoffs: (1-3) home memory sweeps recorded under the memories DOING task — jr-estate 2/3/2 (roam 45d8e6c), finances 0/1/0, elibrary 0/0/2 + health 0/0/1 + kit 1/0/2; archsetup and work remain from the broadcast. (4) lint-org.el mu4e:msgid: false positive FIXED in canonical: TDD (new ERT red → lo-runtime-link-types defvar + lo--register-runtime-link-types called in lo-process-file → 33/33 green both copies, CLI bats 2/2); org-link-set-parameters merges so live-mu4e keeps real params. (5) page-signal pager account deregistered (GV re-verification) — filed VERIFY for Craig (captcha/SMS only he can do). Replies sent to home + .emacs.d; all five PROCESSED-renamed; LAST_INBOX_PROCESS → 2026-06-12. settings.json fable→opus change still uncommitted awaiting Craig's call.
+
+** Spec-response: Codex review folded in
+Read Codex's review (rubric Not-ready combined; Phase 1.5 implementable as scoped slice; phases 2-5 blocked on product choices + stale model assumptions). Dispositions: all accepted except the document-split open question (modified to dual rubric in one document). Spec edits: Status split by arc (1.5 READY WITH CAVEATS / 2-5 NOT READY, original checklist fully resolved); per-ring rollback actions + the review's test inventory adopted as normative in the gating section; exact .emacs.d handoff artifact (inbox-send as implementation step one, task closes on confirmation); stale-helper message contract (path/timestamps/actions); roster unsupported-platform = explicit unavailable → no-op; Phase 5 reverification prerequisite; "Decisions required before phases 2-5" subsection (5 items); Recommended next step updated; Review dispositions table + author history entry appended. Codex's todo.org edits kept as-is. NOTE: .claude/settings.json working-tree change found (model fable→opus + key reorder) — not mine, left uncommitted, flagged to Craig. Five new inbox handoffs pending (home x4, .emacs.d page-signal broken).
+
+** Generic runtime spec review applied
+Ran .ai/workflows/spec-review.org against docs/design/2026-05-28-generic-agent-runtime-spec.org. Added docs/design/2026-05-28-generic-agent-runtime-spec-review.org with rubric =Not ready= for the combined spec: Phase 1 is already shipped, Phase 1.5 helper instances are implementable as a scoped slice with rollout/manual-validation caveats, and phases 2-5 remain blocked on product choices plus current local-runtime/model verification. Added the spec's Review and iteration history entry and updated the existing todo.org helper/runtime tracking tasks instead of creating duplicate tasks.
+
+** Session start
+Started 2026-06-11 15:18 CDT. Standing instruction from last wrap: build the monthly session-harvest workflow (todo.org:133) and the /update-skills skill (todo.org:777), both in no-approvals mode. Craig confirmed option 1. Plan: session-harvest workflow first (template workflow + INDEX entry + mirror sync), then update-skills (skill dir + helper script + manifests for arch-decide, playwright-js, playwright-py; V1 scope already specified in the task body from 2026-05-16 design decisions).
+
+** Three decisions confirmed; checklist updated
+Craig: "all three as recommended" — roster-only sharing between ai-term.el and bin/ai, primary stays on the unset-id singleton, helper-mode.org as the single canonical home of the contract. Marked each as decided (Craig, 2026-06-12) in the spec. Readiness checklist: Emacs-surface item and re-read item ticked closed; test-strategy item stays open pending review; added explicit fourth item — independent spec-review cycle (Codex precedent) + spec-response fold-in. Remaining to ready: the review cycle, then the implementation-plan tightening if the review demands it.
+
+** Coherence pass on the helper section (Craig picked option 1)
+Rewrote the churned subsections as one design: "The roster: one detection primitive" (agent-roster as single source, claude-scoped for 1.5 with phases 2-6 generalization noted), "Spawn paths: deterministic launcher, startup safety net" (same three steps, who executes differs; self-assignment mechanism pinned — id recorded in the context file, explicit AI_AGENT_ID prefix where the resolver is invoked), "Identity and the role contract" (helper-mode.org named the single canonical home; protocols/startup/wrap-up point at it; v0-divergence note on the singleton asymmetry). Git-ban forward ref added to the contract. Read ai-term.el's launch code: instruction embedded in tmux new-session string (env injection = prefix), and -A attach-or-create means ONE session per project — helper needs own session name (aiv-<name>-helper-<id>, no -A) and buffer name; spec updated. Craig mid-task asked for ai-term improvement recommendations — added three to the spec (roster-truth badges over name-truth, agent-exit visibility after the exec-bash tail, single source for opener strings via ai --print-opener). Open-decisions symlink item reconciled with the 1.5 answer.
+
+** Emacs surface corrected: ghostel + ai-term.el (Craig's catch)
+Craig flagged that Emacs no longer uses vterm or eat and asked when I last checked — answer: never; the spec's eat/vterm language was an assumption (and "ghostel" in his earlier message was the literal emulator name, not a typo). Verified in ~/.emacs.d/modules/: term-config.el = ghostel (native emulator over libghostty-vt), generic ghostel buffers auto-tmux via cj/term-launch-tmux; ai-term.el = the existing Emacs AI launch surface (F9 flow, .ai/protocols.org fingerprint picker, project-named aiv- tmux sessions, [running]/[detached] badges, startup instruction send, cj/--ai-term-suppress-tmux coordination). Emacs-born agents are therefore tmux-parented — same process shape as bin/ai launches, detection uniform. Spec's Emacs open-issue subsection rewritten with the facts: ai --no-tmux retired; integration = ai-term.el session-create learns roster→export→opener + [helper] picker badge; share only agent-roster between launchers (ai-term owns aiv- naming/placement); the ai-term.el change is a ~/.emacs.d cross-project handoff when implementation starts. [#B] task wording updated.
+
+** Spec marked NOT READY + Emacs surface + test gating (~20:25, Craig's call)
+Craig: Emacs behavior must adjust to use the ai script (sessions are born from Emacs terminal buffers too), and the spec is not done until these issues are sorted and there's a way to test before anything goes live. Verified: eat/vterm shells are children of the emacs process (no separate emulator process), so cwd-based roster detection already sees Emacs-born agents — the gap is the deterministic SPAWN path on the Emacs surface. Spec updated: Status now carries NOT IMPLEMENTATION-READY + a 3-item readiness checklist (Emacs surface, test gating, post-churn re-read); new open-issue subsection on the Emacs launch surface (elisp ai-helper command vs shelling to ai --no-tmux, leaning to the latter so the logic lives once); Test strategy gains the three-ring pre-live gating (bats with sleeper processes + no-op guarantee, sandbox project drills incl. corruption/orphan/raw-launch/Emacs drills, dormant-by-construction pilot via project-scripts before template-wide). The structural risk named: template sync makes "live everywhere" the default failure mode. [#B] task marked BLOCKED ON SPEC READINESS.
+
+** Fourth revision: deterministic launcher + wrap-up ordering (~20:10, Craig's design)
+Craig: (1) a shell script makes the check determinate — launcher does roster→id→launch-with-instructions; (2) what if the helper outlives the primary? dirty worktree. Spec updated: ai --helper re-promoted to THE spawn path (script can't skip a step a model can); startup roster check stays as safety net for raw launches + crashed-vs-live disambiguation; both call the same agent-roster. Wrap-up ordering rules added: helper wrap-up re-runs the roster — orphaned helper assumes full closing duties incl. commit+push (git ban is concurrency-scoped, lifts when alone) so no stranded dirty tree; primary wrapping with live helpers pauses at the commit and asks (commit helper WIP / wait / leave closing to helper). Phase 1.5 + [#B] task updated.
+
+** Detection-first revision (~19:55, Craig's design)
+Craig asked how a second agent would even know the rules (a helper.org to point at? or better, self-detection so he needn't say anything). Proved the detection signal live: pgrep -x claude + readlink /proc/<pid>/cwd showed 4 concurrent agents (work, rulesets=self, .emacs.d, home), self-ancestry exclusion works. Spec revised: new "Detection" subsection — agent-roster script (process scan, cwd-within-root match, self-ancestry exclusion) runs as the FIRST session action before any pull; alone+no-anchor=fresh, alone+anchor=crashed (today's recovery), not-alone=skip startup and execute helper-mode.org (the role-contract workflow, Craig's helper.org realized). Resolves the crashed-vs-live anchor ambiguity. ai --helper demoted to convenience. Known v1 limits noted (non-local cloud sessions invisible; cwd-based match). Phase 1.5 + [#B] task updated to match. Interim recipe given to Craig (AI_AGENT_ID env + explicit helper opener) until this ships. Em-dash slip in prior commit body flagged to Craig (b405fff, pushed; amend needs his force-push consent).
+
+** Data-integrity second pass on the helper spec (~19:40)
+Craig asked what else prevents lost data / corruption, noting he'll run helpers in consolidated home (one todo.org = max blast radius). Added "Data-integrity rules" to the spec section + Phase 1.5 items + [#B] task bullets: (1) live-helper gate before file-wide hygiene passes — they clobber concurrent edits silently; stale crashed-helper files surfaced as judgment, (2) new-primary startup surfaces live .d/ files so helper dirt isn't treated as mess (dirty-tree pull guards already correct), (3) log-before-write journaling for helper shared-file edits, (4) memory writes primary-only (MEMORY.md read-modify-write has no anchors). Backstop: backup-to-/tmp invariant — verified lint-org.el and wrap-org-table.el conform, todo-cleanup.el does NOT (the subtree-moving pass!) — Phase 1.5 fixes it. Plus inbox-send minute-resolution filename collision nit. Manual validation gains a corruption drill.
+
+** Helper-instance spec amendment + kick-off task (~19:30)
+Craig asked how session-context handles multiple agents; answered (shipped but dormant — AI_AGENT_ID resolver live, nothing sets the var). He then asked to finish the spec and file the kick-off task for his real case: a second Claude in the same project doing lookups and safe task updates. Amended docs/design/2026-05-28-generic-agent-runtime-spec.org: Status note, new "Concurrent same-project agents (helper instances)" section (subagent boundary first, ai --helper spawn with auto AI_AGENT_ID + AI_HELPER, tiered shared-file write contract — scoped single-heading org edits OK for helpers, file-wide passes and all git mutation primary-only, light helper startup, helper wrap-up), and migration Phase 1.5 (independent of phases 2-6 go/no-go). Filed [#B] "Helper-instance support — concurrent same-project Claude" implementation task; dated log entry under the Codex-spec task records the split.
+
+** Inbox round two (~19:26): home's reply + .emacs.d memory sweep
+Home's 19:09 reply: HOLD lifted, jr-estate clear; single-pair already reshaped on their side (only clipper's import was in, cheap now), spec D3 + task-merge step 2 + Mode-B excision amended, clipper manifest amended; session archives already merge area-prefixed into home's .ai/sessions/ (both pilots did), so session-harvest needs nothing. Their "kill the [#B]" ask had already happened at 18:25 — handoffs crossed. .emacs.d's 18:23 handoff: first of 10 broadcast projects to finish memory sweep Phase 1.5 (3 promoted to KB in roam a915760, 3 local at Craig's call, 1 deleted as superseded) — recorded as a dated log entry under the memories DOING task, 9 outstanding. Confirmation replies sent to both (19:26); both handoffs PROCESSED-renamed. Inbox at zero.
+
+** Todo-shape decision confirmed: single pair (≈18:25)
+Craig confirmed in-session: one todo queue with a single Open Work / Resolved pair. The [#B] todo-cleanup.el multi-pair task is CANCELLED (existing single-pair tooling works unmodified once home reshapes). Sent home the confirmation handoff (18:25) with the implied actions: reshape philosophy + clipper sections into the single pair before jr-estate, provenance to :MIGRATED_FROM: properties + area tags, update the spec's task-merge step 2 and the rollback excision path.
+
+** Work handoff: triage-intake deltas-only reporting (17:55 arrival, processed ~18:20)
+Craig's guidance relayed from the work project, applied to canonical immediately (his directive, quoted in the handoff). Engine triage-intake.org: Phase C and the output template now specify deltas-only summaries (changed sources only, all-quiet sweep = one "HH:MM sweep: no changes" line, scan failures still lead loudly, suggested-actions line stays), Common Mistake 10 added, changelog entry dated 2026-06-11. Plugin triage-intake.telegram.org: dev-community groups (zed, GNU Emacs, Kitty) reclassified Noise-keep/never-reported — no FYI name+count — unless Craig asks; real DMs from known contacts still Action. sync-check + workflow-integrity OK (45). Committed 647bc61, pushed. Replied to work (18:22, noting their local copy gets overwritten-to-match on sync); handoff PROCESSED-renamed.
+
+** Craig's correction on the consolidated todo shape (17:10-17:16)
+Craig asked whether the spec consolidates to one todo or per-project todos. Answer from the spec: one todo.org, but with per-area Open Work/Resolved level-1 pairs and the source todo deleted. Craig expected a single Home Open Work / Home Resolved pair holding everything. Sent home a reply (17:16) with his expectation + why it matters: single prioritization surface (per-area sections re-fragment the agenda), tooling compatibility (todo-cleanup.el works unmodified on single-pair), provenance can move to per-task :MIGRATED_FROM: properties + area tags. Flagged the trade-off (per-area sections serve the spec's rollback-excision path) and the timing (reshape now while only 2 folds are in, before jr-estate). The [#B] todo-cleanup multi-pair task is HELD pending home's decision — killed if single-pair wins.
+
+** Home consolidation handoffs processed (arrived mid-session 17:03-17:05)
+Home is folding all personal ~/projects AI projects into itself as areas (Craig-approved, spec reviewed, phases 0-2 done: philosophy + clipper). They held remaining folds pending rulesets' tooling okay. Ran the sweep: all discovery mechanisms (broadcast.py, inbox-send, cross-agent-discover, ai launcher, session-harvest) are fingerprint-based and degrade correctly; live references needing Phase 7 updates are protocols.org:522 (personal-set policy paragraph), cross-agent doc sample outputs, working-files.md example path. False positives: "4319 Danneel Street" (street address), "improve my finances" (common noun). Replied confirmed-okay to home's inbox with the reference list + one ask back (keep folded projects' .ai/sessions/ reachable for session-harvest). Filed: [#B] todo-cleanup.el per-area Open Work/Resolved pairs (their addendum's concrete breakage); VERIFY for Craig on new-projects-start-as-home-areas template guidance. Three inbox files PROCESSED-renamed.
+
+** /update-skills shipped
+TDD: 16 bats tests written red, scripts/update-skills.py written to green, +1 regression test from review (git merge-file hard errors exit 255 as positive returncode; guard treats >=128 as error). Live-bootstrapped manifests + baselines for arch-decide (wshobson/agents, files-map for the SKILL.md→arch-decide.md rename, /LICENSE from repo root), playwright-js (lackeyjb/playwright-skill), playwright-py (anthropics/skills webapp-testing). Live check validated: all drift classifies as local-only/local-new against the freshly seeded baselines. Command doc at .claude/commands/update-skills.md (instantly machine-wide via the commands symlink). Design deviations from the 2026-05-16 task spec: central upstreams/<name>/ manifests instead of per-skill .skill-upstream dotfiles (arch-decide is two flat command files now); baselines seeded at today's HEADs since fork-point commits are unrecoverable. make test green (168 bats incl. new suite). Committed. Both todo.org tasks closed DONE with resolutions; the "write the specification here" cj comment resolved as a dated entry pointing at the shipped artifacts.
+
+** Session-harvest shipped
+Committed (feat(workflows): session-harvest monthly promotion-mining pass). Review found and fixed: bare-root path concatenation bug in the inventory snippet, an overclaimed staleness-nudge mechanism, and (from a live run) mtime being unreliable for the window filter — switched to filename-date prefix after 2025 sessions passed an mtime test. /voice personal ran; gate skipped (.ai/ tracked). Starting /update-skills next.
+
+** Session-harvest workflow built
+Wrote claude-templates/.ai/workflows/session-harvest.org: five phases (scope window via :LAST_HARVEST: marker, mine Summary sections with optional per-project subagent fan-out, dedup + codify-grade gates + work-confidentiality scrub, multi-select slate, execute + metrics readout + marker stamp). Four lanes: patterns catalog, KB facts, rule refinements, workflow learnings. Doubles as the KB receipt-line aggregator for the 30-day checkpoint. INDEX.org entry added under Tools and meta. sync-check --fix mirrored both; workflow-integrity OK (45). Design anchors: broadcast.py discovery fingerprint, patterns README intake cadence, knowledge-base.md write boundary, wrap-it-up KB receipt contract.
diff --git a/inbox/lint-followups.org b/inbox/lint-followups.org
new file mode 100644
index 0000000..639ac01
--- /dev/null
+++ b/inbox/lint-followups.org
@@ -0,0 +1,2 @@
+
+* 2026-06-12 Fri — Task-review health: 1 top-level [#A]/[#B]/[#C] tasks unreviewed for >30 days (daily review may have slipped)
diff --git a/todo.org b/todo.org
index bb2b2de..d4ab083 100644
--- a/todo.org
+++ b/todo.org
@@ -34,12 +34,6 @@ Tags are assigned and refreshed by =task-audit=; =task-review= keeps them honest
* Rulesets Open Work
-** CANCELLED [#B] todo-cleanup.el per-area Open Work / Resolved pairs :feature:
-CLOSED: [2026-06-11 Thu]
-=--archive-done= assumes exactly one level-1 "Open Work" and one "Resolved" heading per todo.org. Home's consolidated file briefly carried per-area pairs and the pass skipped. Filed from home's 2026-06-11 addendum, then held the same evening when Craig flagged that he expected a single pair.
-
-Cancelled 2026-06-11: Craig confirmed the decision — one todo queue with a single Open Work / Resolved pair. Home reshapes its consolidated file to that form, and the existing single-pair tooling works unmodified. No code change needed.
-
** TODO [#B] Helper-instance support — concurrent same-project Claude :feature:spec:
:PROPERTIES:
:CREATED: [2026-06-11 Thu]
@@ -61,14 +55,9 @@ Implement Phase 1.5 of the generic-agent-runtime spec ([[file:docs/design/2026-0
Independent of the spec's phases 2-6 (runtime-neutral refactor), which stay gated on their own go/no-go.
-** VERIFY page-signal pager account deregistered — re-registration needs your hands
+** VERIFY [#C] page-signal pager account deregistered — re-registration needs your hands
Reported by .emacs.d 2026-06-12 01:01: the dedicated pager number (+15045173983, the Claude Pager Google Voice number on signal-cli) returns "User ... is not registered" on every send — Signal appears to have deregistered it (GV numbers get periodically re-verified). Re-registration requires captcha/SMS, which only you can do. Until then every page-signal call fails; .emacs.d's config-audit page fell back to email. Wrapper lives at claude-templates/bin/page-signal.
-** 2026-06-12 Fri @ 02:56:58 -0500 New personal projects are home regroupings — no mechanism needed
-Craig's call (2026-06-12): new personal projects will live in home, and there's no project-creation mechanism to build — he'll be working in home and simply decide to group some things differently. Nothing to do.
-
-Concurrence, verified: no template doc directs new personal work into ~/projects (first-session.org, install-ai.sh, and the README carry no such guidance; the only ~/projects references are discovery-root scans, which home and work still need). The situation as it stands: a new personal "project" is an area dir plus tasks inside home's existing =.ai/= machinery, no bootstrap step; =first-session.org= remains the bootstrap for standalone code projects in ~/code, unchanged and correct; "launch finances"-style trigger phrases for folded names degrade politely to the no-match candidate list, worth work only if real friction shows up.
-
** DOING [#C] Check that memories are sync'd across machines via git :spec:
:PROPERTIES:
:LAST_REVIEWED: 2026-06-10
@@ -171,16 +160,6 @@ Expected: all four behave per the spec; any miss promotes to a bug task. (Agent-
:END:
A scheduled headless morning run chaining the existing pieces: startup checks, the triage-intake scan, a system health check — producing the prep doc plus a report and a notify ping, with all remediation propose-only. Staged adoption from the 2026-06-11 insights report's "Self-Healing Daily Ops Orchestrator": read-only first; promote individual routine remediations to auto only after each has a track record. Known blockers to design around: headless MCP auth (interactively-authenticated servers are absent in cron runs) and the consent boundary (triage Phase D, anything destructive).
-** DONE [#C] Monthly session-harvest workflow :feature:
-CLOSED: [2026-06-11 Thu]
-:PROPERTIES:
-:CREATED: [2026-06-11 Thu]
-:LAST_REVIEWED: 2026-06-11
-:END:
-A monthly pass over recent =.ai/sessions/= summaries across projects proposing promotion candidates: patterns for the catalog, durable facts for the KB, rule refinements, workflow learnings. Sibling cadence to the roam-hygiene timer; a workflow run on schedule, not a standing agent. From the 2026-06-11 insights report's "Canonical-Aware Knowledge & Workflow Curator" — the capture/promote machinery exists (pattern catalog, /codify, KB); this adds the mining cadence.
-
-Shipped 2026-06-11 as [[file:.ai/workflows/session-harvest.org][session-harvest.org]] (template + INDEX entry): five phases, four promotion lanes, /codify-grade gates + work-confidentiality scrub, =:LAST_HARVEST:= marker in notes.org, and the KB receipt-line metrics readout for the ~2026-07-10 checkpoint. Window filter reads session-filename date prefixes (mtime proved unreliable in a live test). First run due ~2026-07-11.
-
** TODO [#C] Build =create-documentation= skill for high-quality project/product docs :feature:
:PROPERTIES:
:LAST_REVIEWED: 2026-06-10
@@ -818,93 +797,6 @@ The skill should reject:
public/library/API docs: =llms.txt= or markdown export is valuable, but normal
human navigation remains primary.
-** DONE [#C] Build =/update-skills= skill for keeping forks in sync with upstream :feature:
-CLOSED: [2026-06-11 Thu]
-:PROPERTIES:
-:LAST_REVIEWED: 2026-06-10
-:END:
-
-The rulesets repo has a growing set of forks (=arch-decide= from
-wshobson/agents, =playwright-js= from lackeyjb/playwright-skill, =playwright-py=
-from anthropics/skills/webapp-testing). Over time, upstream releases fixes,
-new templates, or scope expansions that we'd want to pull in without losing
-our local modifications. A skill should handle this deliberately rather than
-by manual re-cloning.
-
-Shipped 2026-06-11: [[file:.claude/commands/update-skills.md][/update-skills command]] + [[file:scripts/update-skills.py][helper script]] (17 bats tests) + three bootstrapped manifests under [[file:upstreams/][upstreams/]]. The first real upstream drift will exercise the interactive per-file/per-hunk flow end to end; the merge mechanics are covered by the test suite.
-
-*** 2026-06-11 Thu @ 17:05:28 -0500 Specification written as the shipped artifacts
-The command doc ([[file:.claude/commands/update-skills.md][update-skills.md]]) carries the user-facing spec: discovery, classification statuses, the per-file confirmation and per-hunk conflict flow, mark-synced semantics, and the missing-baseline fallback. The script's module docstring specifies the manifest schema. Two deviations from the 2026-05-16 design, with reasons: manifests live centrally at =upstreams/<name>/= instead of per-skill =.skill-upstream= dotfile dirs (arch-decide became two flat files in =commands/= and can't carry one — a =files= rename map covers it); baselines were seeded from the 2026-06-11 upstream HEADs since the true fork-point commits are unrecoverable, so pre-existing local modifications classify as =local-only= going forward.
-
-*** 2026-05-16 Sat @ 01:14:20 -0500 original goals and decisions
-**** Design decisions (agreed)
-
-- *Upstream tracking:* per-fork manifest =.skill-upstream= (YAML or JSON):
- - =url= (GitHub URL)
- - =ref= (branch or tag)
- - =subpath= (path inside the upstream repo when it's a monorepo)
- - =last_synced_commit= (updated on successful sync)
-- *Local modifications:* 3-way merge. Requires a pristine baseline snapshot of
- the upstream-at-time-of-fork. Store under =.skill-upstream/baseline/= or
- similar; committed to the rulesets repo so the merge base is reproducible.
-- *Apply changes:* skill edits files directly with per-file confirmation.
-- *Conflict policy:* per-hunk prompt inside the skill. When a 3-way merge
- produces a conflict, the skill walks each conflicting hunk and asks Craig:
- keep-local / take-upstream / both / skip. Editor-independent; works on
- machines where Emacs isn't available. Fallback when baseline is missing
- or corrupt (can't run 3-way merge): write =.local=, =.upstream=,
- =.baseline= files side-by-side and surface as manual review.
-
-**** V1 Scope
-
-- [ ] Skill at =~/code/rulesets/update-skills/=
-- [ ] Discovery: scan sibling skill dirs for =.skill-upstream= manifests
-- [ ] Helper script (bash or python) to:
- - Clone each upstream at =ref= shallowly into =/tmp/=
- - Compare current skill state vs latest upstream vs stored baseline
- - Classify each file: =unchanged= / =upstream-only= / =local-only= / =both-changed=
- - For =both-changed=: run =git merge-file --stdout <local> <baseline> <upstream>=;
- if clean, write result directly; if conflicts, parse the conflict-marker
- output and feed each hunk into the per-hunk prompt loop
-- [ ] Per-hunk prompt loop:
- - Show base / local / upstream side-by-side for each conflicting hunk
- - Ask: keep-local / take-upstream / both (concatenate) / skip (leave marker)
- - Assemble resolved hunks into the final file content
-- [ ] Per-fork summary output with file-level classification table
-- [ ] Per-file confirmation flow (yes / no / show-diff) BEFORE per-hunk loop
-- [ ] On successful sync: update =last_synced_commit= in the manifest
-- [ ] =--dry-run= to preview without writing
-
-**** V2+ (deferred)
-
-- [ ] Track upstream *releases* (tags) not just branches, so skill can propose
- "upgrade from v1.2 to v1.3" with release notes pulled in
-- [ ] Generate patch files as an alternative apply method (for users who prefer
- =git apply= / =patch= over in-place edits)
-- [ ] Non-interactive mode (=--non-interactive= / CI): skip conflict resolution,
- emit side-by-side files for later manual review
-- [ ] Auto-run on a schedule via Claude Code background agent
-- [ ] Summary of aggregate upstream activity across all forks (which forks have
- upstream changes waiting, which don't)
-- [ ] Optional editor integration: on machines with Emacs, offer
- =M-x smerge-ediff= as an alternate path for users who prefer ediff over
- per-hunk prompts
-
-**** Initial forks to enumerate (for manifest bootstrap)
-
-- [ ] =arch-decide= → =wshobson/agents= :: =plugins/documentation-generation/skills/architecture-decision-records= :: MIT
-- [ ] =playwright-js= → =lackeyjb/playwright-skill= :: =skills/playwright-skill= :: MIT
-- [ ] =playwright-py= → =anthropics/skills= :: =skills/webapp-testing= :: Apache-2.0
-
-**** Open questions
-
-- [ ] What happens when upstream *renames* a file we fork? Skill would see
- "file gone from upstream, still present locally" — drop, keep, or prompt?
-- [ ] What happens when upstream splits into multiple forks (e.g., a plugin
- reshuffles its structure)? Probably out of scope for v1; manual migration.
-- [ ] Rate-limit / offline mode: if GitHub is unreachable, should skill fail
- or degrade gracefully? Likely degrade; print warning per fork.
-
** TODO [#C] Build /research-writer — clean-room synthesis for research-backed long-form :feature:
:PROPERTIES:
:LAST_REVIEWED: 2026-06-10
@@ -962,6 +854,12 @@ Triggers that would prompt "let's build it now":
Upstream reference (do not vendor): ComposioHQ/awesome-claude-skills
=content-research-writer/SKILL.md=.
+** TODO [#D] todo-cleanup =--archive-done= reports 0 moves while moving subtrees :bug:
+:PROPERTIES:
+:CREATED: [2026-06-12 Fri]
+:END:
+Observed at the 2026-06-12 wrap: the pass relocated four closed subtrees from Open Work to Resolved (verified by the git diff, 109 lines each way) while printing "todo-cleanup --archive-done: 0 subtree(s) moved". Reporting-only defect, the moves were correct. Likely the counter resets or prints before the move loop tallies. Reproduce with closed level-2 tasks present, then fix the count line (ERT first).
+
** TODO [#D] Revisit =c4-*= rename if a second notation skill ships :chore:
:PROPERTIES:
:LAST_REVIEWED: 2026-06-10
@@ -2682,3 +2580,111 @@ What we're verifying: the SessionStart(clear) hook fires and the fresh context r
- In any project session with a live .ai/session-context.org (this rulesets session qualifies), type /clear
- Send any short message (the injected context loads but the model waits for your next keystroke)
Expected: the reply starts with "flushed." on its own line, restates the Active Goal and immediate Next Step, and does NOT run the startup workflow.
+** 2026-06-12 Fri @ 02:56:58 -0500 New personal projects are home regroupings — no mechanism needed
+Craig's call (2026-06-12): new personal projects will live in home, and there's no project-creation mechanism to build — he'll be working in home and simply decide to group some things differently. Nothing to do.
+
+Concurrence, verified: no template doc directs new personal work into ~/projects (first-session.org, install-ai.sh, and the README carry no such guidance; the only ~/projects references are discovery-root scans, which home and work still need). The situation as it stands: a new personal "project" is an area dir plus tasks inside home's existing =.ai/= machinery, no bootstrap step; =first-session.org= remains the bootstrap for standalone code projects in ~/code, unchanged and correct; "launch finances"-style trigger phrases for folded names degrade politely to the no-match candidate list, worth work only if real friction shows up.
+
+** DONE [#C] Build =/update-skills= skill for keeping forks in sync with upstream :feature:
+CLOSED: [2026-06-11 Thu]
+:PROPERTIES:
+:LAST_REVIEWED: 2026-06-10
+:END:
+
+The rulesets repo has a growing set of forks (=arch-decide= from
+wshobson/agents, =playwright-js= from lackeyjb/playwright-skill, =playwright-py=
+from anthropics/skills/webapp-testing). Over time, upstream releases fixes,
+new templates, or scope expansions that we'd want to pull in without losing
+our local modifications. A skill should handle this deliberately rather than
+by manual re-cloning.
+
+Shipped 2026-06-11: [[file:.claude/commands/update-skills.md][/update-skills command]] + [[file:scripts/update-skills.py][helper script]] (17 bats tests) + three bootstrapped manifests under [[file:upstreams/][upstreams/]]. The first real upstream drift will exercise the interactive per-file/per-hunk flow end to end; the merge mechanics are covered by the test suite.
+
+*** 2026-06-11 Thu @ 17:05:28 -0500 Specification written as the shipped artifacts
+The command doc ([[file:.claude/commands/update-skills.md][update-skills.md]]) carries the user-facing spec: discovery, classification statuses, the per-file confirmation and per-hunk conflict flow, mark-synced semantics, and the missing-baseline fallback. The script's module docstring specifies the manifest schema. Two deviations from the 2026-05-16 design, with reasons: manifests live centrally at =upstreams/<name>/= instead of per-skill =.skill-upstream= dotfile dirs (arch-decide became two flat files in =commands/= and can't carry one — a =files= rename map covers it); baselines were seeded from the 2026-06-11 upstream HEADs since the true fork-point commits are unrecoverable, so pre-existing local modifications classify as =local-only= going forward.
+
+*** 2026-05-16 Sat @ 01:14:20 -0500 original goals and decisions
+**** Design decisions (agreed)
+
+- *Upstream tracking:* per-fork manifest =.skill-upstream= (YAML or JSON):
+ - =url= (GitHub URL)
+ - =ref= (branch or tag)
+ - =subpath= (path inside the upstream repo when it's a monorepo)
+ - =last_synced_commit= (updated on successful sync)
+- *Local modifications:* 3-way merge. Requires a pristine baseline snapshot of
+ the upstream-at-time-of-fork. Store under =.skill-upstream/baseline/= or
+ similar; committed to the rulesets repo so the merge base is reproducible.
+- *Apply changes:* skill edits files directly with per-file confirmation.
+- *Conflict policy:* per-hunk prompt inside the skill. When a 3-way merge
+ produces a conflict, the skill walks each conflicting hunk and asks Craig:
+ keep-local / take-upstream / both / skip. Editor-independent; works on
+ machines where Emacs isn't available. Fallback when baseline is missing
+ or corrupt (can't run 3-way merge): write =.local=, =.upstream=,
+ =.baseline= files side-by-side and surface as manual review.
+
+**** V1 Scope
+
+- [ ] Skill at =~/code/rulesets/update-skills/=
+- [ ] Discovery: scan sibling skill dirs for =.skill-upstream= manifests
+- [ ] Helper script (bash or python) to:
+ - Clone each upstream at =ref= shallowly into =/tmp/=
+ - Compare current skill state vs latest upstream vs stored baseline
+ - Classify each file: =unchanged= / =upstream-only= / =local-only= / =both-changed=
+ - For =both-changed=: run =git merge-file --stdout <local> <baseline> <upstream>=;
+ if clean, write result directly; if conflicts, parse the conflict-marker
+ output and feed each hunk into the per-hunk prompt loop
+- [ ] Per-hunk prompt loop:
+ - Show base / local / upstream side-by-side for each conflicting hunk
+ - Ask: keep-local / take-upstream / both (concatenate) / skip (leave marker)
+ - Assemble resolved hunks into the final file content
+- [ ] Per-fork summary output with file-level classification table
+- [ ] Per-file confirmation flow (yes / no / show-diff) BEFORE per-hunk loop
+- [ ] On successful sync: update =last_synced_commit= in the manifest
+- [ ] =--dry-run= to preview without writing
+
+**** V2+ (deferred)
+
+- [ ] Track upstream *releases* (tags) not just branches, so skill can propose
+ "upgrade from v1.2 to v1.3" with release notes pulled in
+- [ ] Generate patch files as an alternative apply method (for users who prefer
+ =git apply= / =patch= over in-place edits)
+- [ ] Non-interactive mode (=--non-interactive= / CI): skip conflict resolution,
+ emit side-by-side files for later manual review
+- [ ] Auto-run on a schedule via Claude Code background agent
+- [ ] Summary of aggregate upstream activity across all forks (which forks have
+ upstream changes waiting, which don't)
+- [ ] Optional editor integration: on machines with Emacs, offer
+ =M-x smerge-ediff= as an alternate path for users who prefer ediff over
+ per-hunk prompts
+
+**** Initial forks to enumerate (for manifest bootstrap)
+
+- [ ] =arch-decide= → =wshobson/agents= :: =plugins/documentation-generation/skills/architecture-decision-records= :: MIT
+- [ ] =playwright-js= → =lackeyjb/playwright-skill= :: =skills/playwright-skill= :: MIT
+- [ ] =playwright-py= → =anthropics/skills= :: =skills/webapp-testing= :: Apache-2.0
+
+**** Open questions
+
+- [ ] What happens when upstream *renames* a file we fork? Skill would see
+ "file gone from upstream, still present locally" — drop, keep, or prompt?
+- [ ] What happens when upstream splits into multiple forks (e.g., a plugin
+ reshuffles its structure)? Probably out of scope for v1; manual migration.
+- [ ] Rate-limit / offline mode: if GitHub is unreachable, should skill fail
+ or degrade gracefully? Likely degrade; print warning per fork.
+
+** DONE [#C] Monthly session-harvest workflow :feature:
+CLOSED: [2026-06-11 Thu]
+:PROPERTIES:
+:CREATED: [2026-06-11 Thu]
+:LAST_REVIEWED: 2026-06-11
+:END:
+A monthly pass over recent =.ai/sessions/= summaries across projects proposing promotion candidates: patterns for the catalog, durable facts for the KB, rule refinements, workflow learnings. Sibling cadence to the roam-hygiene timer; a workflow run on schedule, not a standing agent. From the 2026-06-11 insights report's "Canonical-Aware Knowledge & Workflow Curator" — the capture/promote machinery exists (pattern catalog, /codify, KB); this adds the mining cadence.
+
+Shipped 2026-06-11 as [[file:.ai/workflows/session-harvest.org][session-harvest.org]] (template + INDEX entry): five phases, four promotion lanes, /codify-grade gates + work-confidentiality scrub, =:LAST_HARVEST:= marker in notes.org, and the KB receipt-line metrics readout for the ~2026-07-10 checkpoint. Window filter reads session-filename date prefixes (mtime proved unreliable in a live test). First run due ~2026-07-11.
+
+** CANCELLED [#B] todo-cleanup.el per-area Open Work / Resolved pairs :feature:
+CLOSED: [2026-06-11 Thu]
+=--archive-done= assumes exactly one level-1 "Open Work" and one "Resolved" heading per todo.org. Home's consolidated file briefly carried per-area pairs and the pass skipped. Filed from home's 2026-06-11 addendum, then held the same evening when Craig flagged that he expected a single pair.
+
+Cancelled 2026-06-11: Craig confirmed the decision — one todo queue with a single Open Work / Resolved pair. Home reshapes its consolidated file to that form, and the existing single-pair tooling works unmodified. No code change needed.
+