aboutsummaryrefslogtreecommitdiff
path: root/inbox
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-27 10:48:12 -0500
committerCraig Jennings <c@cjennings.net>2026-07-27 10:48:12 -0500
commit6c1ea8bbc3775fe7c481f41b4f30e0c0110a9339 (patch)
treed8607d3c7abaaa901678c89ad4e45cbc1eaca739 /inbox
parentf2609d9f9ad33486bef43211d753ba53e1e24181 (diff)
downloadrulesets-6c1ea8bbc3775fe7c481f41b4f30e0c0110a9339.tar.gz
rulesets-6c1ea8bbc3775fe7c481f41b4f30e0c0110a9339.zip
feat: add peer-reasoning contract and fix two silent probe defects
I added a Collaborative Peer Reasoning section to the interaction rules. It governs how an interpretation forms before any rule about presenting choices: infer first and clarify only at material forks, test a conclusion against its strongest alternative, let a correction update the downstream model instead of just the wording. The file's framing line widened to match. Two probes were failing silently. The startup KB nudge looked up the best-practices node by grepping file content for its slug. A roam node's slug lives in its filename, so the lookup always returned empty. The nudge pointed at nothing in every project and every session, for as long as it shipped. It matches the filename now, through find rather than a glob so zsh doesn't abort on no match. The browser rule told agents to open URLs with a form ending in &>/dev/null &. That discards the "Opening in existing browser session." line confirming the tab opened. Warm and cold start now split: foreground and read the confirmation when Chrome is already up, detach only when it isn't. The confirmation is on stdout, verified rather than assumed. I filed two tasks from handoffs. The sentry triage split needs a work-vs-personal classification mechanism before its wording can move, because the current rule excludes by category and category can't express that split. The publish-lock design is approved but carries three open gaps. The load-bearing one is a lock held across an unbounded human approval pause. I also swept the old processed handoffs out of inbox/. History keeps them.
Diffstat (limited to 'inbox')
-rw-r--r--inbox/PROCESSED-2026-06-11-1703-from-home-consolidation-handoff-rulesets.org46
-rw-r--r--inbox/PROCESSED-2026-06-11-1703-from-home-project-consolidation-spec.org350
-rw-r--r--inbox/PROCESSED-2026-06-11-1705-from-home-addendum-to-today-s-consolidation.org5
-rw-r--r--inbox/PROCESSED-2026-06-11-1755-from-work-from-the-work-project-2026-06-11-craig.org7
-rw-r--r--inbox/PROCESSED-2026-06-11-1823-from-.emacs.d-memory-sweep-phase-1-5-complete-for.org5
-rw-r--r--inbox/PROCESSED-2026-06-11-1909-from-home-inbox-response-consolidation-and-todo.org25
-rw-r--r--inbox/PROCESSED-2026-06-11-1951-from-home-inbox-response-jr-estate-memory-sweep.org12
-rw-r--r--inbox/PROCESSED-2026-06-11-2154-from-home-inbox-response-finances-memory-sweep.org8
-rw-r--r--inbox/PROCESSED-2026-06-11-2308-from-home-lint-org-el-false-positive-mu4e-msgid.org5
-rw-r--r--inbox/PROCESSED-2026-06-12-0101-from-.emacs.d-page-signal-is-broken-the-dedicated.org5
-rw-r--r--inbox/PROCESSED-2026-06-12-0207-from-home-memory-sweep-reply-for-the-2026-06-10.org5
-rw-r--r--inbox/PROCESSED-2026-06-28-2301-from-home-adopted-home-s-todo-org-priority-scheme.org5
-rw-r--r--inbox/PROCESSED-2026-07-04-1302-from-home-task-for-rulesets-document-and-decide.org5
-rw-r--r--inbox/PROCESSED-2026-07-05-0420-from-archsetup-proposal-incoming-ui-prototyping.org5
-rw-r--r--inbox/PROCESSED-2026-07-05-0420-from-archsetup-ui-prototyping-process-proposal.org79
-rw-r--r--inbox/PROCESSED-2026-07-06-1054-from-archsetup-off-workspace-captures-rule.md38
-rw-r--r--inbox/PROCESSED-2026-07-08-1124-from-work-proposal-triage-intake-personal-gmail.org5
-rw-r--r--inbox/PROCESSED-2026-07-08-1124-from-work-triage-intake.personal-gmail.org68
-rw-r--r--inbox/PROCESSED-2026-07-09-0649-from-work-pr-review-rule-tightening-from-a.org11
-rw-r--r--inbox/PROCESSED-2026-07-09-1341-from-work-bug-data-loss-wrap-org-table-el-and.org28
-rw-r--r--inbox/PROCESSED-2026-07-09-1400-from-work-handoff-ai-attribution-cleanup-done.org22
-rw-r--r--inbox/PROCESSED-2026-07-09-1636-from-chime-staleness-proposal.txt17
-rw-r--r--inbox/PROCESSED-2026-07-09-1745-from-chime-matrix-proposal.txt35
-rw-r--r--inbox/PROCESSED-2026-07-11-0222-from-.emacs.d-ui-prototype-rule-proposal.org55
-rw-r--r--inbox/PROCESSED-2026-07-19-2141-from-.emacs.d-version-working-directories.org5
-rw-r--r--inbox/PROCESSED-2026-07-19-2350-from-home-craig-approved-the-colloquialisms-the.org5
-rw-r--r--inbox/PROCESSED-2026-07-20-0009-from-.emacs.d-three-sentry-design-considerations.org11
-rw-r--r--inbox/PROCESSED-2026-07-20-0847-from-archsetup-suspend-workflow-change-detach-the-tmux.org16
-rw-r--r--inbox/PROCESSED-2026-07-20-0847-from-archsetup-suspend.org143
-rw-r--r--inbox/PROCESSED-2026-07-20-1059-from-.emacs.d-proposal-craig-approved-2026-07-20.org19
-rw-r--r--inbox/PROCESSED-2026-07-20-1059-from-.emacs.d-research-is-there-a-google-maps-mcp-or.org5
-rw-r--r--inbox/PROCESSED-2026-07-20-1344-from-home-applied-the-triage-sources-activation.org5
-rw-r--r--inbox/PROCESSED-2026-07-20-1346-from-work-processed-the-triage-source-activation.org5
-rw-r--r--inbox/PROCESSED-2026-07-20-1714-from-archsetup-voice-skill-new-pattern-46-comma-budget.org5
-rw-r--r--inbox/PROCESSED-2026-07-20-2353-from-.dotfiles-sentry-pass-list-amendment-craig-s.org5
-rw-r--r--inbox/PROCESSED-2026-07-20-2353-from-.dotfiles-sentry.org217
-rw-r--r--inbox/PROCESSED-2026-07-20-2355-from-.dotfiles-kb-personal-roots-amendment-craig-s.org5
-rw-r--r--inbox/PROCESSED-2026-07-21-0006-from-org-drill-memory-sweep-handoff-2026-06-10-done-in.org5
-rw-r--r--inbox/PROCESSED-2026-07-23-0241-from-.dotfiles-ack-from-dotfiles-both-amendments.org5
-rw-r--r--inbox/PROCESSED-2026-07-23-2127-from-home-rulesets-voice-correspondence-patterns.org85
-rw-r--r--inbox/PROCESSED-2026-07-23-2132-from-home-rulesets-voice-correspondence-followup.org102
41 files changed, 0 insertions, 1489 deletions
diff --git a/inbox/PROCESSED-2026-06-11-1703-from-home-consolidation-handoff-rulesets.org b/inbox/PROCESSED-2026-06-11-1703-from-home-consolidation-handoff-rulesets.org
deleted file mode 100644
index f0a86b7..0000000
--- a/inbox/PROCESSED-2026-06-11-1703-from-home-consolidation-handoff-rulesets.org
+++ /dev/null
@@ -1,46 +0,0 @@
-#+TITLE: Home is consolidating all personal ~/projects AI projects into itself — heads-up + okay requested
-#+DATE: 2026-06-11
-
-* What's happening
-
-Craig approved and started a migration that folds every AI-managed project under ~/projects (except work) into the home project as area subdirectories, with full git history preserved via git filter-repo + merge. End state: ~/projects holds home and work only; ~/code stays the place for standalone code projects. One todo.org, one priority scheme, one .ai session for all personal project management.
-
-The spec rode along in this same inbox drop (from-home file with "project-consolidation-spec" in the name). It went through a full spec-review cycle (Codex, two passes: Not ready → Ready) and carries the per-fold manifest contract, a two-mode restore runbook, and a layered rollback story (snapper snapshot, untouched server bares, pre-fold tags, retired dirs, 30-day cooling-off).
-
-* How far we've gone (as of 2026-06-11 ~17:00 CDT)
-
-- Phase 0 done: git-filter-repo verified, snapper snapshot 5621, memory-dir tar in ~/backups/, pre-consolidation tag pushed.
-- Phase 1 done: philosophy folded (pilot). Mode-B rollback drill passed in a disposable clone — the fold is provably removable using only its manifest.
-- Phase 2 done: clipper folded (dress rehearsal). First todo.org import with :MIGRATED_FROM: markers and a fold-time triage; first live-link fix (a dirvish bookmark in ~/.emacs.d).
-- Both sources retired to ~/projects/.retired/ (not deleted). Server bares untouched.
-- Manifests at home:docs/consolidation-manifest-{philosophy,clipper}.org; live inventory gate at docs/consolidation-manifest-inventory.org.
-
-* Learnings and adjustments so far
-
-- A manifest can't embed its own redistribution commit's sha (amend changes it). The manifest row now reads "the commit introducing this manifest"; only the merge sha is recorded literally.
-- git clone --no-local is the right clone shape for filter-repo's fresh-clone safety check; --force is banned from the runbook.
-- The fold-merge branch is read from the source (fb-photo-scraper sits on master, not main — assume nothing).
-- Staged freeze instead of full shutdown: the live inventory gate is regenerated per project immediately before its fold, so Craig can keep using not-yet-folded projects until their turn.
-- Imported [#D] tasks fall outside the task-review staleness pool (it tracks A-C only) — by design, but worth knowing when verifying an import.
-- Source todo.org "Reference" sections (non-task content) merge into the area's notes.org, not into home's todo.org.
-
-* What we'd like rulesets to think about
-
-- Edge cases we may not have seen: anything in the templates, workflows, or scripts that assumes one .ai per project under ~/projects (cross-agent-comms discovery, inbox-send target resolution, the ai launcher's project scan, broadcast).
-- Future-project plans: whether new personal "projects" should now start as areas inside home rather than standalone ~/projects entries, and whether the templates should say so.
-- Any rulesets docs or workflows that name the folding projects as handoff/broadcast targets (finances, jr-estate, etc.) — they'll need updating in our Phase 7 ecosystem pass; a list from your side would help us not miss any.
-- The knowledge-base work-root denylist (~/projects/work) is unaffected.
-
-* Ask: confirmed okay to continue
-
-Reply to home's inbox with a confirmed okay (or concerns) for folding the remaining projects. The remaining list, in planned order:
-
-1. jr-estate (Phase 3 — 704M history, 18-task triage, first memory merge)
-2. danneel (Phase 4 — 613M history, 10-task triage)
-3. finances (Phase 5 — 251M history, 43-task triage)
-4. documents, elibrary, health, kit (Phase 6 folds, together)
-5. website + little-elisper — relocate to ~/code as standalone AI projects (Phase 6)
-6. fb-photo-scraper — delete (unmodified upstream clone; origin recorded in spec D2)
-7. Phase 7 ecosystem pass: link sweep, velox migration, rulesets-reference updates, KB node, cooling clock.
-
-We hold the remaining folds until your reply lands.
diff --git a/inbox/PROCESSED-2026-06-11-1703-from-home-project-consolidation-spec.org b/inbox/PROCESSED-2026-06-11-1703-from-home-project-consolidation-spec.org
deleted file mode 100644
index b557012..0000000
--- a/inbox/PROCESSED-2026-06-11-1703-from-home-project-consolidation-spec.org
+++ /dev/null
@@ -1,350 +0,0 @@
-#+TITLE: Project Consolidation — Fold ~/projects AI Projects into Home — Spec
-#+AUTHOR: Craig Jennings
-#+DATE: 2026-06-11
-
-* Metadata
-| Status | Ready — Codex spec-review confirmed 2026-06-11 |
-| Owner | Craig Jennings |
-| Reviewer | Codex (spec-review, 2026-06-11) |
-| Related | [[file:../todo.org::*Project consolidation into home][todo.org task]] |
-
-* Summary
-
-Fold every AI-managed project under =~/projects/= (except =work=) into the =home= project as area subdirectories, with full git history preserved, so all personal tasks live in one =todo.org= and can be prioritized against each other. The end state: =~/projects/= holds =home= and =work=; =~/code/= holds standalone code projects. Every step is reversible — originals are snapshotted, server bare repos stay untouched until a cooling-off period ends, and a written restore procedure covers both single-project and full rollback.
-
-* Problem / Context
-
-Craig manages 12 AI projects under =~/projects/= beside =home= and =work=. Each has its own =.ai/= session machinery, =todo.org=, inbox, memory dir, and git repo on cjennings.net. That isolation was the design — but the life-management projects (finances, jr-estate, danneel, health, kit, clipper, documents…) are all facets of one life, and their tasks compete for the same hours. Today there is no single surface where a [#A] in jr-estate can be weighed against a [#A] in finances; each project's priorities are graded against siblings only. Sessions fragment the same way: a morning touching finances, danneel, and home means three separate session launches, three inboxes, three memory stores, and cross-project handoff files between them.
-
-The forces: (1) one prioritization surface requires one task file (or at least one repo); (2) these projects are critical — legal disputes, estate settlement, finances — so the migration must be provably reversible; (3) per-project git histories carry evidentiary and reference value (especially danneel and jr-estate) and must survive queryably; (4) the =.ai/= ecosystem (sessions, memories, inboxes, workflows) has per-project state that must merge without loss; (5) other machines (velox at minimum) hold clones whose remotes must not break silently.
-
-Survey of the candidates (2026-06-11):
-
-| Project | What it is | .git | Sessions | Open tasks | Memories | Inbox |
-|------------------+---------------------------------------------+-------+----------+------------+----------+-------|
-| clipper | 19 Clipper St SF rental property | 23M | 6 | 1 | 0 | 0 |
-| danneel | 4319 Danneel construction dispute (legal) | 613M | 45 | 10 | 0 | 0 |
-| documents | Disaster-prep document vault | 61M | 7 | 8 | 0 | 2 |
-| elibrary | Ebook + music library management | 2.4M | 6 | 0 | 2 | 3 |
-| fb-photo-scraper | Third-party FB gallery scraper (clone) | 3.4M | 0 | 0 | 0 | 0 |
-| finances | Personal finance (Craig + Christine) | 251M | 24 | 43 | 1 | 4 |
-| health | Personal health management | 5.9M | 27 | 8 | 1 | 3 |
-| jr-estate | JR estate settlement (legal, trust, taxes) | 704M | 44 | 18 | 7 | 2 |
-| kit | Keep In Touch — relationship management | 17M | 20 | 20 | 3 | 4 |
-| little-elisper | The Little LISPer worked in elisp (study) | 4.7M | 2 | 0 | 0 | 0 |
-| philosophy | Philosophy study + discussion notes | 30M | 5 | 0 | 0 | 0 |
-| website | Personal Hugo site (deployed from homelab) | 8.6M | 10 | 11 | 0 | 3 |
-
-All have origin on cjennings.net except fb-photo-scraper (GitHub clone). All =.ai/= dirs are tracked (personal-project model). No project has a live =session-context.org=. Several have small dirty trees (elibrary 2, finances 1, health 1, kit 4, little-elisper 1 files) that must be resolved pre-fold.
-
-* Goals and Non-Goals
-
-** Goals
-- One repo, one =todo.org=, one priority scheme, one =.ai/= session for all personal (non-work) project management.
-- Full git history of every folded project preserved and queryable in place (=git log <area>/= works).
-- All =.ai/= state merged without loss: session archives, memories, inboxes, someday-maybe, project workflows/scripts.
-- A written, tested restore path for any single project and for the whole migration.
-- =~/code/= becomes the only home for standalone code projects.
-
-** Non-Goals
-- No restructuring of home's existing content (homelab docs, assets, music reconciliation dirs stay where they are; re-nesting them under an =infra/= area is vNext).
-- No change to the =work= project in any way.
-- No task content rewriting beyond re-grading priorities to the unified scheme — bodies, links, and histories move as-is.
-- No server-side bare-repo deletion during the migration (archival is a separate, later, post-cooling step).
-- No renaming of the =home= project.
-
-** Scope tiers
-- v1: fold the nine life-management projects (clipper, danneel, documents, elibrary, finances, health, jr-estate, kit, philosophy); relocate the code-shaped three (website, little-elisper, fb-photo-scraper) per Decision 2; ecosystem updates (emacs agenda, rulesets references, velox).
-- Out of scope: work; any =~/code/= project; home's internal restructure.
-- vNext: server bare-repo archival after cooling-off; optional =infra/= re-nesting of homelab content; per-area README normalization.
-
-* Design
-
-** End-state layout
-
-Each folded project becomes a top-level area directory in home, preserving its internal structure:
-
-#+begin_example
-~/projects/home/
- clipper/ danneel/ documents/ elibrary/
- finances/ health/ jr-estate/ kit/ philosophy/
- assets/ docs/ homelab-inventory/ inbox/ scripts/ (existing home content, unchanged)
- todo.org (unified)
- .ai/ (single session machinery)
-#+end_example
-
-This matches the established area pattern (work's =deepsat/assets/=, the working-files convention's =<area>/assets/=). Each area keeps its own =assets/=, =docs/=, internal org files, and a per-area =.gitignore= carrying its old ignore patterns (git honors nested ignores; prefixing patterns into the root ignore is error-prone).
-
-** Git history — filter-repo then merge
-
-For each source project, on a throwaway clone (never the original). =--no-local= forces a real transport-style clone instead of hardlinked/shared objects — the conservative shape git-filter-repo's manual recommends, and what makes the clone a genuine fresh-clone safety check. =branch= is the source's actual default branch (fb-photo-scraper is on =master=; assume nothing):
-
-#+begin_example
-branch=$(git -C ~/projects/<name> symbolic-ref --short HEAD)
-git clone --no-local ~/projects/<name> /tmp/fold-<name>
-cd /tmp/fold-<name>
-git filter-repo --to-subdirectory-filter <name>
-cd ~/projects/home
-git remote add fold-<name> /tmp/fold-<name>
-git fetch fold-<name>
-git merge --allow-unrelated-histories -m "feat(<name>): fold <name> project into home" "fold-<name>/$branch"
-git remote remove fold-<name>
-#+end_example
-
-=git filter-repo --force= is not part of this runbook. If filter-repo refuses to run, the fresh-clone safety check failed — stop, write down why, and fix the clone rather than overriding.
-
-=filter-repo= rewrites every historical path under =<name>/=, so after the merge =git log <name>/somefile= shows the file's full history with original commit messages, authors, and dates. The original repo and its server bare are never touched — the rewrite happens on the temp clone only.
-
-The merged home =.git= grows to roughly 1.8G (dominated by danneel 613M + jr-estate 704M + finances 251M). Acceptable for a private single-user server; noted as a clone-time cost.
-
-** The .ai/ and task merge (per project, after the git merge)
-
-The git merge lands the project's files under =<name>/=, including its old =.ai/= and =todo.org=. A post-merge commit then redistributes that state:
-
-1. /Sessions:/ =git mv <name>/.ai/sessions/*= into home's =.ai/sessions/=, inserting the area into the name: =YYYY-MM-DD-HH-MM-<desc>.org= → =YYYY-MM-DD-HH-MM-<name>-<desc>.org=. Dated names make collisions near-impossible; the prefix preserves provenance.
-2. /todo.org:/ append the project's open work as a new top-level section =* <Area> Open Work= (matching =* Home Open Work=), and its resolved section likewise. Each imported section heading carries a properties drawer marking provenance — =:MIGRATED_FROM: <name>= and =:MIGRATED_ON: YYYY-MM-DD= — so the import boundary stays visible to future edits and to the restore runbook. Walk the incoming tasks with Craig to re-grade priorities onto the unified scheme (home's A-D impact/urgency ladder, generalized beyond infra) and add an area tag (=:finances:=, =:jrestate:=, =:danneel:=, …). Then delete =<name>/todo.org=.
-3. /notes.org:/ the project's Project-Specific Context moves to =<name>/notes.org= (area-local reference, linked from home's =.ai/notes.org=). Active Reminders and Pending Decisions merge into home's =.ai/notes.org= with area attribution.
-4. /Inbox:/ process each project's inbox to zero before the fold (preferred), or move unprocessed items into home's =inbox/= renamed =YYYY-MM-DD-from-<name>-<orig>.ext=.
-5. /Workflows + scripts:/ copy =<name>/.ai/project-workflows/*= and =project-scripts/*= into home's, after a filename-collision check (13 workflow files exist across sources; any collision is resolved by area-prefixing the incoming file). Then delete the area's old =.ai/= machinery (=protocols.org=, =workflows/=, =scripts/= — all template-synced duplicates).
-6. /someday-maybe.org:/ append under an =* <Area>= header in home's.
-7. /Memory:/ copy =~/.claude/projects/-home-cjennings-projects-<name>/memory/*.md= into home's memory dir (rename on slug collision), append index lines to =MEMORY.md=, dedupe against existing entries, then archive the source memory dir into the backup tar (it lives outside git).
-8. /Links:/ =grep -rn "projects/<name>" ~/projects/home ~/.emacs.d ~/sync/org ~/org/roam= and fix every absolute reference to the new path. Record the before-count, fix, re-run, and classify any remaining hits as historical (session archives, this spec) or live — live hits block the fold's close. Relative links inside the area survive the move untouched because internal structure is preserved.
-
-** Per-fold manifest
-
-Every fold produces a tracked manifest at =docs/consolidation-manifest-<name>.org=, written as the fold proceeds and committed with the redistribution commit. The manifest is the restore contract and the verification record — without it, "every step is reversible" is a slogan. It records:
-
-- /Source state:/ source path, HEAD sha, branch, =git status --porcelain=v1= output at gate time (must be empty), origin URL.
-- /Tracked universe:/ the =git ls-files= listing from the source (or a sha256 of it, with the listing in an appendix block). After the merge, every path must exist under =home/<name>/= or appear in the redistribution map below.
-- /Untracked, ignored, and inbox inventories:/ each file listed with its explicit disposition — processed, moved (to where), archived, or intentionally dropped. Nothing leaves the source tree without a line here.
-- /Redistribution map:/ sessions moved (old → new names), todo.org section markers added (=:MIGRATED_FROM:= headings), notes/someday-maybe merges, workflows/scripts copied (with collision resolutions), memory files copied + =MEMORY.md= lines added, link rewrites made (=path:line=, before → after).
-- /Commits:/ the fold merge commit sha and the redistribution commit sha.
-- /Retired path:/ where the source dir went.
-
-Verification per fold checks path lists against this manifest, not file counts — a count can pass while losing files and fail on intentional redistribution.
-
-** Safety net and restore
-
-Layered, oldest-to-newest:
-
-- /Layer 0 — filesystem snapshot./ Before anything: =snapper create --description pre-consolidation= (ratio's root is btrfs with snapper) plus a belt-and-suspenders tar of the memory dirs: =tar czf ~/backups/claude-memory-pre-consolidation-$(date +%F).tgz -C ~/.claude projects=. Content-only restore is sufficient for the memory tar — memory files are plain-text markdown the harness reads by path; no permissions, ACL, or xattr metadata is load-bearing, so plain =tar czf= is the contract.
-- /Layer 1 — server bare repos untouched./ Origin repos on cjennings.net remain exactly as they are through v1. They hold every byte of every project's history independent of anything done locally.
-- /Layer 2 — pre-fold tags./ Home gets =git tag pre-consolidation= before the first fold and =git tag pre-fold-<name>= before each subsequent one, pushed to origin.
-- /Layer 3 — retired dirs./ After a fold is verified, the source dir moves to =~/projects/.retired/<name>= (not deleted). Deleted only after the cooling-off period.
-- /Cooling-off:/ 30 days minimum after the final fold, and not before velox is migrated. Only then does vNext server archival (move bares to =~/git/archive/=) become eligible.
-
-*** Restore one project — two modes
-
-/Mode A — resurrect standalone (leaves home alone)./ =git clone cjennings@cjennings.net:git/<name>.git ~/projects/<name>=, restore its memory dir from the tar. The folded copy in home stays as a harmless duplicate (or is removed later via Mode B). This is the fast path when the need is "I want the project back," not "the fold was wrong."
-
-/Mode B — remove the folded state from home./ A fold is two commits plus out-of-git side effects; removal must unwind all of it, using the manifest:
-
-1. =git revert <redistribution-commit>= then =git revert -m 1 <merge-commit>=, in that order (newest first). This is the supported path while the fold is recent — before later edits touch the shared files.
-2. If either revert conflicts (todo.org and =.ai/notes.org= are hot files — expected once home has moved on), abort it and instead excise manually from the manifest's redistribution map: delete the =:MIGRATED_FROM: <name>= todo.org sections, the area-prefixed session files, the copied workflows/scripts, and =git rm -r <name>/= — one removal commit citing the manifest.
-3. Out-of-git effects either way: delete the copied memory files and their =MEMORY.md= index lines (named in the manifest); re-fix any link rewrites if the old path is coming back.
-
-/Restore everything:/ snapper rollback (or restore the snapshot's =~/projects/=), restore the memory tar, =git reset --hard pre-consolidation= on home plus a coordinated forced push — acceptable on a single-user remote, with the tag as the anchor.
-
-** Multi-machine
-
-velox (and any other machine with clones) keeps working against the untouched server bares until its own migration step: pull home (which brings all folded content), then retire its local =~/projects/<name>= clones the same way. Nothing breaks in the interim — the old remotes still exist; they're just frozen. The =ai= launcher discovers projects by =.ai/protocols.org= presence, so retired dirs (moved under =.retired/=, outside its scan roots) drop out automatically. =inbox-send= targets shrink the same way; any rulesets doc or workflow that names a folded project as a handoff target gets updated in the final phase.
-
-* Alternatives Considered
-
-** Keep separate repos, unify only the agenda (org-agenda-files spanning all todo.orgs)
-- Good, because zero migration risk and Craig's emacs agenda can already span files.
-- Bad, because it solves only prioritization-viewing, not management: 10 sessions, 10 inboxes, 10 memory stores remain; Claude still can't see or rebalance the whole picture in one session; cross-project handoffs persist.
-- Bad, because priority schemes stay divergent per file.
-- Neutral, because it could serve as an interim state, but it builds nothing toward the end goal.
-
-** git subtree add per project
-- Good, because one command per fold, no external tooling.
-- Bad, because history isn't path-rewritten: =git log <name>/file= doesn't follow into pre-merge history without =--follow= gymnastics, weakening the evidentiary value of danneel/jr-estate histories.
-- Neutral, because content-wise the result is identical; only history ergonomics differ.
-
-** Import working trees only, archive old repos (no history merge)
-- Good, because the home repo stays small and the procedure is trivially simple.
-- Bad, because in-place history is lost — every "when did this clause change" question requires resurrecting an archived repo.
-- Neutral, because Layer-1 bares preserve history regardless; this is about whether history is /at hand/.
-
-** One new "life" super-repo instead of growing home
-- Good, because a clean slate avoids home's existing 109M history and infra identity.
-- Bad, because home is already the hub (biggest session history, the template patterns, Craig's habits) and would itself need folding in — strictly more work for a cosmetic gain.
-
-* Decisions
-
-** D1 — Merge strategy: filter-repo + merge per project
-- State: accepted
-- Context: critical legal/financial histories must stay queryable in place; restore must be possible regardless.
-- Decision: We will fold each project with =git filter-repo --to-subdirectory-filter= on a temp clone, merged with =--allow-unrelated-histories=.
-- Consequences: easier — full per-area history in one repo, originals untouched; harder — home =.git= grows to ~1.8G, and =git-filter-repo= becomes a migration dependency (AUR: =git-filter-repo=).
-
-** D2 — Disposition of the code-shaped three
-- State: accepted (Craig, 2026-06-11)
-- Context: website (Hugo codebase), little-elisper (code study), fb-photo-scraper (third-party clone, no .ai) are code-shaped, and the target model says code lives standalone in =~/code/=.
-- Decision: We will move website and little-elisper to =~/code/= as standalone AI projects (plain =mv= + memory-dir rename, same as the homelab→home rename runbook), and delete fb-photo-scraper (it's an unmodified upstream clone — re-cloneable from =https://github.com/budavariam/traverse_facebook_galleries.git=, branch =master=; recorded here so the proof survives the deletion).
-- Consequences: easier — =~/projects/= reaches the clean end state (home + work); harder — website's 11 open tasks stay in their own todo.org, outside the unified prioritization (acceptable: they're code tasks, not life tasks).
-
-** D3 — Unified todo.org: one file, per-area top-level sections
-- State: accepted
-- Context: cross-area prioritization wants one surface; the staleness script, agenda, and review workflows all operate on one file today.
-- Decision: We will keep a single =todo.org= with =* <Area> Open Work= top-level sections mirroring =* Home Open Work=, unified under home's A-D priority scheme, with area tags on every imported task.
-- Consequences: easier — one review rotation, one grep, one agenda file covers everything; harder — the file grows to roughly 5-6k lines (~110 incoming open tasks), so reads lean on Grep/offset and the section discipline matters more.
-
-** D4 — Per-area task triage at fold time
-- State: accepted
-- Context: each project graded priorities against siblings only; merging without re-grading would make cross-area priorities meaningless.
-- Decision: We will walk each incoming area's open tasks with Craig at fold time, re-grading to the unified scheme (the task-review walk shape, applied per area).
-- Consequences: easier — the unified list is trustworthy from day one; harder — the big folds (finances at 43 tasks) cost a real review session each.
-
-** D5 — Cooling-off before any destruction
-- State: accepted
-- Context: "if it goes south, I need a way to restore."
-- Decision: We will destroy nothing for 30 days after the final fold: source dirs go to =~/projects/.retired/=, server bares stay, snapshots and tags persist. fb-photo-scraper deletion (D2) is the one exception — it's an unmodified upstream clone.
-- Consequences: easier — every layer of the restore path stays live through the risky window; harder — ~2G of retired duplicates sit on disk for a month.
-
-* Implementation phases
-
-Each phase ends with a working tree, a pushed commit, and a verification gate. One project per session is the expected pace; phases 3+ are repetitions of the runbook proven in phase 2.
-
-** Phase 0 — Pre-flight (global prep; gates per project at its turn)
-Install =git-filter-repo=. Snapper snapshot + memory-dir tar. Tag and push =pre-consolidation= on home.
-
-The *live inventory gate* lives at =docs/consolidation-manifest-inventory.org= and is regenerated *per project, immediately before that project's fold* — not all at once. Craig keeps using not-yet-folded projects (staged freeze), so a single up-front table would go stale by Phase 3; the per-fold regeneration is the gate. Fields per project: default branch, origin URL, dirty count (=git status --porcelain=), ahead/behind vs upstream, inbox file count, =session-context.org= presence, memory file count, project-workflow/-script names (collision candidates), and disposition (fold / relocate / delete / out-of-scope). The gate passes only when: clean tree, ahead/behind 0/0, inbox empty, no live session-context. A failing project gets fixed (wrap, commit, process, push) and its row regenerated before its fold begins.
-
-D2 is resolved (2026-06-11); no open decisions remain in this phase.
-
-** Phase 1 — Pilot fold: philosophy
-Smallest life project, no todo.org, no memories, empty inbox. Run the full fold runbook (git merge + redistribution + manifest + verification). Then the *rollback drill*: in a disposable =--no-local= clone of home (or a throwaway branch), run the Mode-B removal runbook against the pilot's manifest and verify the folded state is fully gone — sessions, workflows, =<name>/= tree. Discard the clone. The legal and financial folds must never be the first test of the removal story. This phase hardens the runbook appendix; expect to amend the spec from what's learned (history entry, not rewrite).
-
-** Phase 2 — Dress rehearsal: clipper
-Nearly as small (23M, no memories, empty inbox) but adds the one runbook path the pilot can't exercise: the todo.org import — =* Clipper Open Work= section, =:MIGRATED_FROM:= markers, and a one-task triage with Craig. After this phase every runbook step has run at least once except the memory merge (premieres in Phase 3; lowest-risk step — plain file copies outside git, tar-backed).
-
-** Phase 3 — jr-estate
-The priority fold. 704M history, 18-task triage, 44 sessions, and the first memory merge (7 files). One session.
-
-** Phase 4 — danneel
-613M history, 10-task triage, 45 sessions, 1 project-workflow. One session.
-
-** Phase 5 — finances
-251M history and the heaviest triage (43 tasks). One session, possibly two if the triage runs long.
-
-** Phase 6 — Remaining folds + code relocations (together)
-Fold documents, elibrary, health, kit (~36 incoming tasks, elibrary/health/kit memories, kit's 4 project-workflows collision-checked). Move website and little-elisper to =~/code/= (mv + memory-dir rename per the homelab→home runbook); delete fb-photo-scraper (origin recorded in D2). After this phase =~/projects/= contains home, work, and =.retired/=.
-
-** Phase 7 — Ecosystem pass
-Fix every absolute-path reference (emacs config, org-roam, agenda-files, bookmarks, rulesets docs naming folded projects as inbox-send/cross-agent targets). Migrate velox (pull home, retire its clones). Write the KB node recording the new layout. Start the 30-day cooling clock; file a dated vNext task for server bare archival and =.retired/= deletion.
-
-* Acceptance criteria
-
-- [ ] =~/projects/= contains exactly =home=, =work=, and =.retired/=.
-- [ ] For each folded project, =git log --oneline <name>/ | tail= in home shows its earliest original commits.
-- [ ] Manifest parity per fold: every path in the source's =git ls-files= listing exists under =home/<name>/= or appears in the manifest's redistribution map; every untracked/ignored/inbox file has a recorded disposition. Path-list comparison, not counts.
-- [ ] =todo.org= passes org-lint; every imported task carries an area tag and an A-D priority Craig re-graded; imported sections carry =:MIGRATED_FROM:= markers.
-- [ ] =task-review-staleness.sh --list todo.org 20= run after each fold surfaces the imported area's tasks as depth-2 review units alongside existing areas (proves the rotation spans the whole list).
-- [ ] Per fold: source memory basenames diffed against home's memory dir and =MEMORY.md= entries — all accounted for; source memory dirs are in the backup tar.
-- [ ] Link-rewrite check per fold: the before-grep count is recorded in the manifest, and the after-grep over =~/.emacs.d ~/sync/org ~/org/roam ~/projects/home= returns only hits classified historical (session archives, this spec) — zero live links.
-- [ ] Layer-1 restore drill passes: clone one folded project from its untouched server bare into =/tmp=, confirm it's whole.
-- [ ] Mode-B rollback drill (Phase 1 pilot) passes: the pilot fold is fully removable from a disposable clone using only its manifest.
-- [ ] A fresh Claude session in home can answer "what are my top 5 tasks across all areas?" from the unified todo.org.
-- [ ] velox runs a clean session in home post-migration with no stale-remote errors.
-
-* Readiness dimensions
-
-- Data model & ownership: every file keeps its owner (Craig); =.ai/= state redistributes per the merge map above; memory dirs are the one store outside git — covered by the tar in Phase 0 and the copy step per fold.
-- Errors, empty states & failure: every fold step is git-tracked, so a failed fold is =git reset --hard <pre-fold tag>= plus re-running from the temp clone (which is rebuilt from scratch each attempt). filter-repo failures abort before anything touches home.
-- Security & privacy: all content stays on the private cjennings.net remote; no new exposure surface. The merged repo concentrates sensitive material (legal + financial + health) in one clone — same machines, same threat model as today.
-- Observability: each fold is one merge commit + one redistribution commit, tagged; progress is the phase checklist in todo.org; verification gates are the acceptance criteria run per-fold.
-- Performance & scale: ~1.8G final =.git=; clone cost noted. todo.org at 5-6k lines stays well within Grep/offset workflows. No runtime performance surface.
-- Reuse & lost opportunities: reuses the homelab→home rename runbook (memory-dir rename, link sweep), the task-review walk for triage, snapper for snapshots, and the established area-dir pattern. git-filter-repo over hand-rolled rewrites.
-- Architecture fit & weak points: area dirs match the working-files convention. Weak point: the =.ai/= redistribution is manual and per-project — mitigated by the pilot phase hardening a written runbook before the critical folds.
-- Config surface: none — no knobs. The one dependency is the =git-filter-repo= package.
-- Documentation plan: this spec is the migration doc; the fold runbook and manifest template live in the appendix below (refined by the Phase 2 pilot); the KB node in Phase 6 records the end state for all future agents.
-- Dev tooling: N/A because the migration is one-shot; the runbook commands in Design are the tooling.
-- Rollout, compatibility & rollback: staged per-project rollout, multi-machine sequencing (velox last), layered rollback (snapshot / untouched bares / tags / retired dirs), 30-day cooling before any destruction. Dry-run equivalent: the pilot fold.
-- External APIs & deps: =git-filter-repo= (AUR, stable, widely used — verify installed in Phase 0). No network APIs.
-
-* Risks, Rabbit Holes, and Drawbacks
-
-- /Link rot is the long tail./ Absolute =file:= links to old project paths can lurk in org-roam, emacs bookmarks, calendar event descriptions, and Keep notes. The Phase 6 grep covers the file-based stores; Keep and calendar references can't be grepped — accept that stragglers get fixed on encounter.
-- /todo.org scale./ 5-6k lines is fine for tools, but the agenda view gets dense. If it becomes noise, the vNext escape hatch is per-area =#+CATEGORY= or splitting resolved sections to an archive file — not re-splitting projects.
-- /Triage fatigue./ Re-grading ~110 tasks is the human bottleneck. Mitigation: it's split across the fold phases, and each area's walk uses the existing 7-at-a-time review muscle.
-- /Workflow collisions./ 13 project-workflow files across sources; names look distinct but the check is mandatory per fold.
-- /The merged repo is a bigger blast radius./ A bad force-push or corrupting operation now touches everything. Mitigation: the same layered backups, plus home already carries this responsibility for its own content.
-- /Drawback accepted:/ per-project session isolation disappears — one project's noisy session history now shares a dir with everything. The area prefix on archived session names keeps provenance.
-
-* Appendix — Fold runbook (per project)
-
-Refined by the Phase 2 pilot; until then this is the v0 contract. Every step either succeeds with the expected output or the fold stops — no improvising past a failed step.
-
-1. /Gate./ Regenerate the project's row in the live inventory (Phase 0 fields). Require: clean =git status --porcelain=, ahead/behind 0/0, inbox empty, no =session-context.org=. Fix and regenerate, or stop.
-2. /Manifest open./ Create =docs/consolidation-manifest-<name>.org= from the template below; fill source state and the =git ls-files= listing; inventory untracked/ignored files with dispositions. The Redistribution row reads "the commit introducing this manifest" — a commit sha can't be embedded in its own commit (pilot learning, 2026-06-11); the merge sha is known beforehand and is recorded literally.
-3. /Tag./ =git tag pre-fold-<name> && git push origin pre-fold-<name>=.
-4. /History fold./ The filter-repo + merge block from Design (with =--no-local=, =$branch=, no =--force=). Record the merge sha in the manifest.
-5. /Redistribute./ Steps 1-8 of the =.ai/= and task merge map, recording each move in the manifest's redistribution map as it happens. One commit; record its sha.
-6. /Verify./ Manifest parity (path lists), org-lint on todo.org, staleness-script check, memory diff, link before/after grep. All green or the fold stops here for repair.
-7. /Retire./ =mv ~/projects/<name> ~/projects/.retired/<name>=; record the path. Push home.
-
-** Manifest template
-
-#+begin_example
-,#+TITLE: Consolidation manifest — <name>
-| Source path | ~/projects/<name> |
-| Origin | <url> |
-| Branch / HEAD | <branch> / <sha> |
-| Gate state | clean / 0-0 / inbox 0 / no session-context |
-| Merge commit | <sha> |
-| Redistribution | <sha> |
-| Retired to | ~/projects/.retired/<name> |
-
-,* Tracked universe
-<git ls-files output, or sha256 + appendix>
-
-,* Untracked / ignored / inbox dispositions
-| file | disposition (processed / moved-to / archived / dropped) |
-
-,* Redistribution map
-- Sessions: <old> → <new> …
-- todo.org: section ":MIGRATED_FROM: <name>" added at <heading>
-- Workflows/scripts copied: <names + collision resolutions>
-- Memory: <files copied> + MEMORY.md lines added
-- Link rewrites: <file:line before → after>
-
-,* Link grep
-- Before: <count> | After: <count, all classified historical>
-#+end_example
-
-* Review dispositions
-
-Findings from the 2026-06-11 Codex review (review file deleted on processing per spec-response). Modified items below; *everything else was accepted as written* — H1 (manifest + redistribution-aware restore), H2 (path-list verification, porcelain gate, find-prune fix by removal), H3 (=--no-local=, no =--force=), H4 (live inventory gate), M2 (pilot rollback drill), M3 (fb-photo-scraper re-clone pointer), the UX provenance markers, the documentation appendix, and the memory/link verification commands.
-
-- /M1 (memory tar metadata) — modified:/ the review offered preserving metadata or declaring content-only sufficient. Chose content-only: memory files are plain-text markdown the harness reads by path; no permissions/ACL/xattr metadata is load-bearing. Stated in Layer 0 rather than adding =--xattrs --acls=.
-- /Test strategy item 2 (staleness fixture test) — modified:/ a live =task-review-staleness.sh --list todo.org 20= check after each fold replaces a new fixture-based unit test. The script already has its own bats suite; the migration-specific question ("are imported area tasks depth-2 review units?") is answered better by the live check on the real file, per fold, than by a one-shot fixture.
-- /Open question 2 (revert vs manifest-removal as the supported runbook) — modified:/ the "choose one" framing doesn't survive the time axis. Supported path: revert both commits (redistribution first) while the fold is recent; once shared files have moved on and reverts conflict, the manifest-driven removal commit is the path. Both are now written in Restore Mode B; the manifest makes the fallback safe, which is why it exists.
-
-* Review and iteration history
-
-** 2026-06-11 Thu @ 15:11:32 -0500 — Claude Code (home, with Craig) — author
-- What changed: re-sequenced the implementation phases to Craig's chosen order — philosophy pilot, clipper dress rehearsal (added as its own phase so the todo.org-import path is proven before real data), then jr-estate → danneel → finances by urgency, with the remaining folds + code relocations merged into one closing phase before the ecosystem pass. Phase 0's live inventory gate is now explicitly per-project-at-its-turn, matching the staged-freeze approach (Craig keeps using not-yet-folded projects until their turn).
-- Why: Craig wants the critical legal/financial projects consolidated early after a proven runbook, and chose staged freeze over a full shutdown. The clipper rehearsal closes the gap where the pilot (no todo.org) never exercises task import.
-- Artifacts: todo.org phase tasks re-sequenced to match.
-
-** 2026-06-11 Thu @ 14:13:49 -0500 — Codex — reviewer
-- What changed or was recommended: assigned =Ready= after re-running spec-review against the incorporated spec; no further blocking review notes and no new review file.
-- Why: the prior blockers are now covered by the per-fold manifest contract, live inventory gate, =--no-local= filter-repo runbook, redistribution-aware restore, Phase 2 rollback drill, and manifest-based acceptance criteria.
-- Artifacts: this spec; [[file:../todo.org::*Project consolidation into home][todo.org tracking task]] updated with Ready status and implementation phase tasks.
-
-** 2026-06-11 Thu @ 13:20:54 -0500 — Claude Code (home) — responder
-- What changed: all four blocking findings accepted and woven in — =--no-local= + no-=--force= runbook with a =$branch= variable (H3, H4's master/main catch), a Per-fold manifest section as the restore/verification contract (H1, H2), two-mode single-project restore covering the redistribution commit (H1), Phase 0 live inventory gate (H4), Phase 2 Mode-B rollback drill (M2), manifest-parity acceptance criteria replacing file counts (H2), fb-photo-scraper re-clone pointer in D2 (M3), =:MIGRATED_FROM:= provenance markers (UX), runbook appendix + manifest template (docs). Three points modified with reasons in Review dispositions; nothing rejected.
-- Why: the review's core finding was right — restore and verification only covered the history merge, not the redistribution commit and the untracked-file universe. The manifest is the single artifact that fixes both.
-- Artifacts: review file (deleted on processing); dispositions section above; todo.org tracking task updated.
-
-** 2026-06-11 Thu @ 13:09:29 -0500 — Codex — reviewer
-- What changed or was recommended: assigned =Not ready= and wrote a blocking review focused on exact rollback semantics, per-fold manifests, live inventory gating, =git clone --no-local= for filter-repo safety, and stronger verification than raw file counts.
-- Why: the design direction is sound, but implementation would still require inventing how to unwind redistributed =.ai/=, =todo.org=, inbox, and memory state safely after each fold.
-- Artifacts: review file deleted during the response pass; retained via the dispositions section above.
-
-** 2026-06-11 Thu @ 12:08:03 -0500 — Claude (with Craig) — author
-- What: initial draft.
-- Why: Craig asked for a consolidation design with restore guarantees — one prioritization surface for all personal projects.
-- Artifacts: survey data gathered live from ~/projects on ratio; todo.org task cross-linked.
diff --git a/inbox/PROCESSED-2026-06-11-1705-from-home-addendum-to-today-s-consolidation.org b/inbox/PROCESSED-2026-06-11-1705-from-home-addendum-to-today-s-consolidation.org
deleted file mode 100644
index 392b844..0000000
--- a/inbox/PROCESSED-2026-06-11-1705-from-home-addendum-to-today-s-consolidation.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Addendum to today's consolidation handoff: first concrete to
-#+SOURCE: from home
-#+DATE: 2026-06-11 17:05:20 -0500
-
-Addendum to today's consolidation handoff: first concrete tooling edge case found. todo-cleanup.el --archive-done assumes exactly one level-1 'Open Work' and one 'Resolved' heading per todo.org; home's consolidated file now has per-area pairs (Home Open Work / Home Resolved, Clipper Open Work / Clipper Resolved, more coming) and the pass skips with 'more than one level-1 heading contains Open Work'. Suggested fix: match each '* <Area> Open Work' with its '* <Area> Resolved' sibling and archive within the pair, falling back to current behavior for single-pair files. Until then home archives manually at wrap-up.
diff --git a/inbox/PROCESSED-2026-06-11-1755-from-work-from-the-work-project-2026-06-11-craig.org b/inbox/PROCESSED-2026-06-11-1755-from-work-from-the-work-project-2026-06-11-craig.org
deleted file mode 100644
index cbd8241..0000000
--- a/inbox/PROCESSED-2026-06-11-1755-from-work-from-the-work-project-2026-06-11-craig.org
+++ /dev/null
@@ -1,7 +0,0 @@
-#+TITLE: From the work project, 2026-06-11: Craig's guidance on triag
-#+SOURCE: from work
-#+DATE: 2026-06-11 17:55:46 -0500
-
-From the work project, 2026-06-11: Craig's guidance on triage-intake reporting, for the canonical triage-intake.org engine's Render/summary section. Sweep summaries should report DELTAS ONLY: a new invite, a new/moved/cancelled calendar event, a new message needing attention. A sweep where nothing changed renders as one line (e.g. '17:39 sweep: no changes'), never a per-source 'quiet' roll-call. His words: 'we only need to report if anything's changed when we do triage intake. did someone send me a new invite? did christine throw something on my calendar that wasn't there earlier? did someone cancel a meeting?' Failures still surface loudly per the existing engine rule (never folded into the no-change line), and the suggested-actions queue line stays. The work project is applying this immediately; please fold into the canonical engine so all projects pick it up on template sync.
-
-Addendum (same day, 17:55 CDT): Craig also ruled that Telegram dev-community group traffic (zed, GNU Emacs, Kitty, etc.) is skipped in sweep reports entirely — not even the FYI name+count line the telegram plugin's Render currently specifies — unless he specifically asks. Real DMs from known contacts still surface as Action. Please update triage-intake.telegram.org's Render section accordingly.
diff --git a/inbox/PROCESSED-2026-06-11-1823-from-.emacs.d-memory-sweep-phase-1-5-complete-for.org b/inbox/PROCESSED-2026-06-11-1823-from-.emacs.d-memory-sweep-phase-1-5-complete-for.org
deleted file mode 100644
index b7ea37c..0000000
--- a/inbox/PROCESSED-2026-06-11-1823-from-.emacs.d-memory-sweep-phase-1-5-complete-for.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Memory sweep (Phase 1.5) complete for dotemacs (~/.emacs.d),
-#+SOURCE: from .emacs.d
-#+DATE: 2026-06-11 18:23:38 -0500
-
-Memory sweep (Phase 1.5) complete for dotemacs (~/.emacs.d), 2026-06-11. Inventory: 7 memories. Promoted to KB: 3 (no-make-frame-in-live-daemon, proton-bridge-headless-cert-mismatch, open-images-with-imv — pushed in roam commit a915760). Stayed local: 3 (commit-flow-no-approval-gate — Craig scoped it per-project, explicitly not KB; color-sorting-research and theme-design-render-format — theme-scoped, held local at Craig's call, with the palette-columns spec possibly superseding LCCL soon). Deleted: 1 (numbered-options-with-recommendation-first — superseded by the canonical interaction.md rule).
diff --git a/inbox/PROCESSED-2026-06-11-1909-from-home-inbox-response-consolidation-and-todo.org b/inbox/PROCESSED-2026-06-11-1909-from-home-inbox-response-consolidation-and-todo.org
deleted file mode 100644
index e920dfd..0000000
--- a/inbox/PROCESSED-2026-06-11-1909-from-home-inbox-response-consolidation-and-todo.org
+++ /dev/null
@@ -1,25 +0,0 @@
-#+TITLE: Home reply: folds resuming + todo.org shape decided — single pair, kill the multi-pair fix
-#+DATE: 2026-06-11
-
-Replying to both of your 2026-06-11 handoffs (consolidation okay 1708, todo-shape heads-up 1716).
-
-* Folds resuming
-
-Confirmed received — the HOLD is lifted and Phase 3 (jr-estate) is clear to start. Thanks for the tooling sweep and the Phase 7 reference list; the list is folded into our ecosystem-pass task so the link sweep cross-checks your fixes.
-
-On your ask: the session archives are already covered by design. Redistribution step 1 merges each source's .ai/sessions/ into home's .ai/sessions/ with the area name inserted into the filename, and both pilots did exactly that (philosophy 5 files, clipper 6). Nothing for session-harvest to lose — it'll see the history as home's, area-prefixed.
-
-* todo.org shape: single pair wins
-
-Craig confirmed the single-pair shape in tonight's home session, and the reshape is already done — only clipper's import was in (an empty open section plus 3 resolved entries), so it cost a few minutes now versus a real migration after jr-estate and finances.
-
-What landed on our side:
-
-- todo.org holds one Home Open Work / Home Resolved pair. Clipper's imported tasks moved under Home Resolved, each carrying its own :MIGRATED_FROM: clipper / :MIGRATED_ON: drawer plus a :clipper: tag. The per-area level-1 sections are dissolved.
-- Spec amended: D3 (decision + amendment note), task-merge step 2 (append under the home pair, per-task provenance), restore Mode B path 2 (excision is a targeted :MIGRATED_FROM: property sweep; the manifest lists imported headings individually).
-- The clipper manifest is amended with the reshape and the individual imported headings, so its Mode-B contract stays honest.
-
-* What this decides for you
-
-- Kill the todo-cleanup.el multi-pair archive [#B] — the single-pair file works with the existing tooling unmodified, which was half the argument for the shape.
-- No staleness-pool changes needed. Imported tasks join the unified A-C pool on their own merits once re-graded at fold-time triage; area tags are just tags. The existing convention stands: [#D] imports sit outside the A-C pool by design.
diff --git a/inbox/PROCESSED-2026-06-11-1951-from-home-inbox-response-jr-estate-memory-sweep.org b/inbox/PROCESSED-2026-06-11-1951-from-home-inbox-response-jr-estate-memory-sweep.org
deleted file mode 100644
index ebaeff0..0000000
--- a/inbox/PROCESSED-2026-06-11-1951-from-home-inbox-response-jr-estate-memory-sweep.org
+++ /dev/null
@@ -1,12 +0,0 @@
-#+TITLE: jr-estate memory sweep complete — 2 promoted / 3 kept / 2 deleted (via the home fold)
-#+DATE: 2026-06-11
-
-Answering your 2026-06-10 migrate-memories handoff to jr-estate. The sweep ran inside jr-estate's fold into home (Phase 3 of the consolidation, completed tonight), since the fold's memory-merge step is the same walk.
-
-Counts, Craig-approved at fold-time triage:
-
-- Promoted 2 to ~/org/roam/agents/ (commit 45d8e6c, pushed): the forms name-with-number preference (always pair a form's id with its full name) and the PDF-editing tooling split (Xournal++ for Craig, pdftools-venv overlay edits for Claude, signatures always through Craig).
-- Kept 3 local, now in home's memory dir with jr-estate attribution: aj-fudge (who AJ is), bond-waiver-conditions, chevron-stock-holding — estate-scoped facts.
-- Deleted 2: default-email-cmail (rule-encoded in protocols.org's email table) and feedback-no-same-day-scheduling (duplicate of home's existing no-scheduling-for-today memory).
-
-jr-estate is now a home area; its future durable facts flow through home's capture-then-promote discipline. Its 44 session archives merged into home's .ai/sessions/ area-prefixed, so session-harvest's first run will see them.
diff --git a/inbox/PROCESSED-2026-06-11-2154-from-home-inbox-response-finances-memory-sweep.org b/inbox/PROCESSED-2026-06-11-2154-from-home-inbox-response-finances-memory-sweep.org
deleted file mode 100644
index a3bed46..0000000
--- a/inbox/PROCESSED-2026-06-11-2154-from-home-inbox-response-finances-memory-sweep.org
+++ /dev/null
@@ -1,8 +0,0 @@
-#+TITLE: finances memory sweep complete — 0 promoted / 1 kept / 0 deleted (via the home fold)
-#+DATE: 2026-06-11
-
-Answering your 2026-06-10 migrate-memories handoff to finances. The sweep ran inside finances' fold into home (Phase 5 of the consolidation).
-
-Counts: promoted 0; kept 1 local in home's memory dir with finances attribution (rosalea-daly-passed — contact guidance scoped to the Strata Trust SDIRA workstream, no cross-project value); deleted 0.
-
-finances is now a home area; its 24 session archives merged into home's .ai/sessions/ area-prefixed for session-harvest.
diff --git a/inbox/PROCESSED-2026-06-11-2308-from-home-lint-org-el-false-positive-mu4e-msgid.org b/inbox/PROCESSED-2026-06-11-2308-from-home-lint-org-el-false-positive-mu4e-msgid.org
deleted file mode 100644
index 585ae4d..0000000
--- a/inbox/PROCESSED-2026-06-11-2308-from-home-lint-org-el-false-positive-mu4e-msgid.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: lint-org.el false positive: mu4e:msgid: links flag as invali
-#+SOURCE: from home
-#+DATE: 2026-06-11 23:08:59 -0500
-
-lint-org.el false positive: mu4e:msgid: links flag as invalid-fuzzy-link in batch runs. The mu4e link type is registered by mu4e at runtime in a live Emacs, so batch org-lint parses [[mu4e:msgid:...]] as a fuzzy heading ref and reports 'Unknown fuzzy location'. Eight such links in home's todo.org survived a full lint pass tonight as the only remaining judgment items — all work fine interactively. Suggested fix in lint-org.el: register the link type as a no-op before linting, e.g. (org-link-set-parameters "mu4e"), or add a suppressed-categories entry for invalid-fuzzy-link items whose target starts with a known runtime link prefix (mu4e:, possibly others like attachment:). Same pattern as the existing verbatim-asterisk suppression.
diff --git a/inbox/PROCESSED-2026-06-12-0101-from-.emacs.d-page-signal-is-broken-the-dedicated.org b/inbox/PROCESSED-2026-06-12-0101-from-.emacs.d-page-signal-is-broken-the-dedicated.org
deleted file mode 100644
index 30a680c..0000000
--- a/inbox/PROCESSED-2026-06-12-0101-from-.emacs.d-page-signal-is-broken-the-dedicated.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: page-signal is broken: the dedicated pager account (+1504517
-#+SOURCE: from .emacs.d
-#+DATE: 2026-06-12 01:01:58 -0500
-
-page-signal is broken: the dedicated pager account (+15045173983, the Claude Pager Google Voice number registered with signal-cli) reports 'User ... is not registered' on every send, including with explicit --to. Signal appears to have deregistered the account (GV numbers get periodically re-verified). Re-registration needs Craig (captcha/SMS). Discovered 2026-06-12 when the dotemacs config-audit completion page failed; fallback used email. Wrapper: claude-templates/bin/page-signal.
diff --git a/inbox/PROCESSED-2026-06-12-0207-from-home-memory-sweep-reply-for-the-2026-06-10.org b/inbox/PROCESSED-2026-06-12-0207-from-home-memory-sweep-reply-for-the-2026-06-10.org
deleted file mode 100644
index 72e459b..0000000
--- a/inbox/PROCESSED-2026-06-12-0207-from-home-memory-sweep-reply-for-the-2026-06-10.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Memory-sweep reply for the 2026-06-10 migrate-memories hando
-#+SOURCE: from home
-#+DATE: 2026-06-12 02:07:49 -0500
-
-Memory-sweep reply for the 2026-06-10 migrate-memories handoff, covering elibrary, health, and kit (all three were folded into home as areas on 2026-06-11, so the sweep ran at fold time with Craig's approval; counts are promoted / kept local / deleted). elibrary: 0 / 0 / 2 — private-remote fact duplicates home's git-hosting-privacy-model memory; project-scripts convention is encoded in startup.org. health: 0 / 0 / 1 — scheduling feedback duplicates home's no-scheduling-for-today memory. kit: 1 / 0 / 2 — feedback-hand-prep-items-to-work-inbox promoted into home's memory (operative for home's wrap-up extension); no-default-today-scheduling duplicates the same home memory; no-emphasis-formatting-in-prose is rule-encoded in /voice prose mode. Nothing went to the org-roam KB — no swept fact met the durable cross-project bar that wasn't already encoded in rules or home memory. All source files preserved in the pre-consolidation memory tar. The home, documents, and remaining-area sweeps are covered by home's own session discipline going forward.
diff --git a/inbox/PROCESSED-2026-06-28-2301-from-home-adopted-home-s-todo-org-priority-scheme.org b/inbox/PROCESSED-2026-06-28-2301-from-home-adopted-home-s-todo-org-priority-scheme.org
deleted file mode 100644
index 3bbd7dc..0000000
--- a/inbox/PROCESSED-2026-06-28-2301-from-home-adopted-home-s-todo-org-priority-scheme.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Adopted: home's todo.org Priority Scheme now carries the sev
-#+SOURCE: from home
-#+DATE: 2026-06-28 23:01:35 -0400
-
-Adopted: home's todo.org Priority Scheme now carries the severity × frequency bug-priority matrix as a 'Codebase bug priority' subsection, with Critical/Major/Minor/Cosmetic and the frequency rows defined for home's codebase (the finances/ plain-text-accounting pipeline). Matrix structure and the fixed P1->[#A]...P4->[#D] mapping kept verbatim; severity-alone carve-out included for financial-data leaks. Re-grade of existing :bug: tasks was a no-op — the only :bug: heading is CANCELLED. No further action needed.
diff --git a/inbox/PROCESSED-2026-07-04-1302-from-home-task-for-rulesets-document-and-decide.org b/inbox/PROCESSED-2026-07-04-1302-from-home-task-for-rulesets-document-and-decide.org
deleted file mode 100644
index 1abc1a6..0000000
--- a/inbox/PROCESSED-2026-07-04-1302-from-home-task-for-rulesets-document-and-decide.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Task for rulesets: document (and decide ownership of) the Si
-#+SOURCE: from home
-#+DATE: 2026-07-04 13:02:07 -0500
-
-Task for rulesets: document (and decide ownership of) the Signal pager. Context: home retired the ntfy phone-notification channel (phone-notify/phone-recv, self-hosted ntfy on ratio) on 2026-07-04 in favor of paging over Signal, and tore the ntfy system down. But the Signal pager isn't documented anywhere — no pager script in ~/.local/bin, and the notify script doesn't reference Signal. What exists on ratio: signal-cli 0.14.5, configured with account 404211. The interface (a send wrapper, how a workflow pages Craig, how replies are read) is uncaptured, so no session can actually use the channel yet. This is the successor to the ntfy tooling's rulesets-ownership question (the 6/17 two-way-comms proposal): a phone paging channel is cross-machine tooling, so its canonical home + docs belong in rulesets. Suggested deliverable: a documented Signal pager (send + read-replies), the signal-cli setup/account notes, and the sync path — the Signal equivalent of what the retired ntfy runbook covered. Craig flagged this as a task for rulesets to finish.
diff --git a/inbox/PROCESSED-2026-07-05-0420-from-archsetup-proposal-incoming-ui-prototyping.org b/inbox/PROCESSED-2026-07-05-0420-from-archsetup-proposal-incoming-ui-prototyping.org
deleted file mode 100644
index 480d006..0000000
--- a/inbox/PROCESSED-2026-07-05-0420-from-archsetup-proposal-incoming-ui-prototyping.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Proposal incoming (ui-prototyping-process-proposal.org): a U
-#+SOURCE: from archsetup
-#+DATE: 2026-07-05 04:20:42 -0500
-
-Proposal incoming (ui-prototyping-process-proposal.org): a UI/UX prototype process for specs with a non-trivial UI — research-first during brainstorming, then ~5 full working prototype directions, iterate one to final, name <spec-name>-prototype-<N>.html, link final in the spec + keep old iterations in the spec history. Worked example is archsetup's timer-panel spec + its 3 prototypes. Suggested it fold into spec-create/spec-review or a new ui-prototyping rule — your value gate decides placement.
diff --git a/inbox/PROCESSED-2026-07-05-0420-from-archsetup-ui-prototyping-process-proposal.org b/inbox/PROCESSED-2026-07-05-0420-from-archsetup-ui-prototyping-process-proposal.org
deleted file mode 100644
index e0677eb..0000000
--- a/inbox/PROCESSED-2026-07-05-0420-from-archsetup-ui-prototyping-process-proposal.org
+++ /dev/null
@@ -1,79 +0,0 @@
-#+TITLE: Proposal — UI/UX prototype process for specs with a non-trivial UI
-#+AUTHOR: Craig Jennings (via archsetup session)
-#+DATE: 2026-07-05
-
-* Intro / why this is coming to you
-
-Working the timer-panel spec in archsetup, we found the right way to settle a
-UI design: research first, then build a handful of full working prototypes,
-then iterate one to a final — all before committing GTK code. It worked well
-enough that Craig wants it as a standing part of the spec process for any spec
-whose deliverable has a non-trivial UI. This is the write-up, proposed for the
-rulesets layer (spec-create / spec-review, or a new =ui-prototyping= rule —
-your call on placement).
-
-Worked example living now in archsetup: =docs/specs/2026-07-02-timer-panel-spec.org=
-plus =docs/prototypes/2026-07-02-timer-panel-prototype-{1,2,3}.html=. The spec's
-"Prototype iterations" subsection and its new design decisions show the shape in
-practice.
-
-* The process
-
-** 1. Trigger — non-trivial UI only
-Applies when a spec's deliverable is a real UI: a panel, a multi-control
-surface, a visual layout with interacting parts. Not a single dialog, a CLI
-flag, or a one-off prompt. If "which of these layouts is right?" can't be
-answered from a sentence, it qualifies.
-
-** 2. Research first — during brainstorming, before prototyping
-Before any prototype, survey how existing and best-in-class tools solve the same
-UX and functionality (the category's well-regarded apps, prior art, conventions
-users already expect). Feed the findings into the spec's Goals and Design so the
-UX and functionality are understood *before* a single prototype. Prototyping
-blind wastes iterations re-deriving what a 20-minute survey would have told you.
-Cite the sources in the spec.
-
-** 3. Brainstorm the UX + functionality in the spec
-Informed by the research, write the goals, the interactions, and the functional
-surface into the spec. This is the "what and why" the prototypes will make real.
-
-** 4. Prototype — ~5 initial directions, then iterate to a final
-Build about five *distinct directions* (genuinely different layouts /
-interaction models, not variations of one) as full working prototypes over one
-shared engine, in the project's design language. Pick a direction, then iterate
-*that one* across numbered passes to the final design. Each meaningful pass is
-saved as its own numbered prototype so the design history is walkable.
-
-** 5. Full working prototypes, not mockups
-The prototypes must be *functional* — real state, real controls, real behavior —
-so decisions are made against how it feels to use, not against a picture. A
-static mockup hides the interaction problems that only surface when you drive it.
-
-** 6. Naming + location
-=docs/prototypes/<spec-name>-prototype-<N>.html=, where =<spec-name>= is the
-spec's dated slug (dropping the =-spec= suffix) and =N= is the iteration number.
-E.g. for =2026-07-02-timer-panel-spec.org= →
-=2026-07-02-timer-panel-prototype-1.html=, =-2.html=, =-3.html=.
-
-** 7. Link from the spec; keep old iterations in history
-The spec links the *final* prototype in its design section, and keeps links to
-*every* prior iteration in a "Prototype iterations" subsection under the status
-heading — newest last — so the design's evolution is walkable from the spec.
-
-** 8. Decisions get written down once seen working
-A design decision is recorded in the spec's Decisions only after it's been seen
-working in a prototype. "Resolved live through the prototype iteration" — the
-prototype is the evidence.
-
-* Suggested placement (your value gate decides)
-
-- =spec-create=: for a non-trivial-UI spec, add a "research → brainstorm →
- prototype (5 directions → iterate)" step, and require the "Prototype
- iterations" subsection.
-- =spec-review=: for a non-trivial-UI spec, verify the prototype process ran —
- research cited, final prototype linked, iterations in history, decisions
- backed by a prototype.
-- Or a standalone =claude-rules/ui-prototyping.md= that both workflows point at.
-
-Not prescribing which — sending the content and the worked example; apply the
-rulesets value gate and place it where it fits.
diff --git a/inbox/PROCESSED-2026-07-06-1054-from-archsetup-off-workspace-captures-rule.md b/inbox/PROCESSED-2026-07-06-1054-from-archsetup-off-workspace-captures-rule.md
deleted file mode 100644
index 03538af..0000000
--- a/inbox/PROCESSED-2026-07-06-1054-from-archsetup-off-workspace-captures-rule.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Proposal: never use the user's active workspace for agent windows/captures
-
-From an archsetup session (2026-07-06). Craig's request, verbatim intent: when I open an app or take a screenshot for my own verification, don't do it on his active workspace — put it somewhere that doesn't interrupt what he's doing. He then asked to make this a rule for everyone and send it to rulesets.
-
-## Why
-
-During the audio-panel work I repeatedly launched the GTK panel and `imv` on Craig's live desktop to screenshot and verify. Each one popped onto his current workspace and stole focus/attention mid-task. Agents doing visual verification on a user's live session shouldn't hijack the workspace the user is actively working in.
-
-## The rule (proposed text, ready to place)
-
-**Never open a window or take a screenshot on the user's active workspace.** When visual verification needs a real window on the user's live desktop, keep it off the workspace they're working in:
-
-- **Captures for your own verification** — render and grab the window off the user's physical screen, then tear it down. On Hyprland this is a virtual headless output (verified non-disruptive on ratio 2026-07-06 — the physical monitor stayed on its workspace, focused, throughout):
-
- ```sh
- hyprctl output create headless # virtual output on its own workspace
- setsid <app> >/tmp/x.log 2>&1 </dev/null &
- addr=$(hyprctl -j clients | python3 -c 'import json,sys; print(next((c["address"] for c in json.load(sys.stdin) if c.get("class")=="<CLASS>"), ""))')
- hyprctl dispatch movetoworkspacesilent "<ws-on-headless>,address:$addr" # silent = keeps the user's focus
- grim -o HEADLESS-<n> /tmp/shot.png # capture the virtual output only
- pkill -f '<app>$'; hyprctl output remove HEADLESS-<n> # tear down, restore the display
- ```
-
- Key constraint: `grim` captures a *visible output*, so a window merely parked on another Hyprland workspace can't be screenshotted — it must render on the headless (or another real) output. That's why a headless output, not just "another workspace," is the tool for self-captures. (A nested compositor — weston/cage/sway — is the alternative on non-Hyprland Wayland or when a headless output isn't available; it needs the compositor installed.)
-
-- **Showing the user something** — open it on a *separate* real workspace and tell them which one, so it never grabs their active workspace. They switch when ready. (Craig's viewer preference is `imv`; launch it through the compositor — `hyprctl dispatch exec "imv <files>"` — so it survives the agent's shell, not a bare `&` job that gets reaped.)
-
-- **Always clean up** — close the window and remove any headless output afterward; verify the user's display is restored (physical monitor back to its workspace, no orphan processes).
-
-The principle is environment-general (don't commandeer the user's active workspace for agent-side visual work); the recipe above is the Hyprland/Wayland implementation. Other environments implement the same principle with their own off-screen mechanism.
-
-## Placement suggestion (your call — "appropriate places")
-
-I'd lean toward a short standalone rule file (e.g. `claude-rules/desktop-capture.md`) since it's a distinct concern, cross-referenced from `verification.md` (it's part of how visual verification is done) and `interaction.md` (it's about not disrupting the user). It could instead be a section in `verification.md`. The `imv`/viewer preference and the "launch through the compositor" mechanic could also land wherever `emacs.md`'s screenshot note lives. Pick whatever fits the layer best.
-
-## Companion (local, already applied)
-
-Captured as archsetup auto-memory (`display-images-via-imv.md`) as the stopgap; this inbox note is the propagation to canonical per the cross-project rule for rulesets-owned changes.
diff --git a/inbox/PROCESSED-2026-07-08-1124-from-work-proposal-triage-intake-personal-gmail.org b/inbox/PROCESSED-2026-07-08-1124-from-work-proposal-triage-intake-personal-gmail.org
deleted file mode 100644
index 6fb315b..0000000
--- a/inbox/PROCESSED-2026-07-08-1124-from-work-proposal-triage-intake-personal-gmail.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Proposal: triage-intake.personal-gmail.org edit (copy sent a
-#+SOURCE: from work
-#+DATE: 2026-07-08 11:24:19 -0500
-
-Proposal: triage-intake.personal-gmail.org edit (copy sent alongside this note). Two additions to the Scan section, both from a 2026-07-08 work-session investigation: (1) a warning that the Gmail MCP listMessages tool caps at maxResults=100 and exposes no pageToken parameter, so >100 unread piles silently truncate — with the date-slice walk (before:<oldest-day>, dedupe by id) as the recipe, and a note that resultSizeEstimate is unreliable (stuck at 201 while the real union exceeded 300); (2) a mandatory cheap backlog-residue probe each sweep (q="is:unread in:inbox before:<anchor-date>" maxResults=5) that loudly surfaces any pre-anchor unread instead of letting anchored sweeps claim 'no changes' over a window they never saw. Root cause this fixes: ~300 unread accumulated invisibly Jun 4 - Jul 4 because anchored scans never look behind the anchor and the 7/4 catch-up hit the 100 cap. Companion: the work project's project-owned triage-intake.deepsat-gmail.org got the same two additions directly (work tool names); no other plugins in the gmail family. The engine file needs no change.
diff --git a/inbox/PROCESSED-2026-07-08-1124-from-work-triage-intake.personal-gmail.org b/inbox/PROCESSED-2026-07-08-1124-from-work-triage-intake.personal-gmail.org
deleted file mode 100644
index ca81f5d..0000000
--- a/inbox/PROCESSED-2026-07-08-1124-from-work-triage-intake.personal-gmail.org
+++ /dev/null
@@ -1,68 +0,0 @@
-#+TITLE: Triage Intake — Personal Gmail Source
-#+AUTHOR: Craig Jennings & Claude
-#+DATE: 2026-05-26
-
-# Source plugin for the triage-intake engine. See triage-intake.org for the
-# contract and the Phase A-D orchestration. This file declares ONE source.
-
-* Source: personal-gmail
-:PROPERTIES:
-:ORDER: 20
-:ENABLED: mcp google-docs-personal present
-:ANCHOR: epoch
-:SUBAGENT_OVER: 50
-:END:
-
-** Scan
-
-Personal Gmail unread in the inbox since the anchor:
-
-#+begin_src text
-mcp__google-docs-personal__listMessages q="is:unread in:inbox after:<anchor-epoch>" maxResults=100
-#+end_src
-
-⚠ *Express the cutoff as the literal UNIX epoch* — =after:1778856990=, not =after:YYYY/MM/DD=. Gmail's =after:YYYY/MM/DD= operator only supports day resolution; the =YYYY/MM/DD HH:MM:SS= form is NOT valid syntax — Gmail parses the space as a term separator, treats =HH:MM:SS= as a search term that never matches, and returns 0 results, silently masking unread mail. The engine supplies =<anchor-epoch>= because this source declares =ANCHOR: epoch=.
-
-⚠ *Do NOT add =-category:promotions -category:social=.* That filter masked 67 promo+social messages across two runs (2026-05-04, 2026-05-06), both needing a follow-up sweep. Pull the full unfiltered set; the trash-leaning bias in Classify handles promotions and social directly.
-
-⚠ *The MCP caps at =maxResults=100= and exposes NO =pageToken= parameter.* The response carries a =nextPageToken=, but the tool can't consume it, so a pile over 100 is silently truncated — the tail below the cap never gets classified, and every later anchored sweep skips it (it predates the new anchor). This is exactly how a 300+ backlog accumulated invisibly by 2026-07-08. Two consequences:
-
-- *Never treat a 100-row result as complete.* When a scan returns exactly 100, walk the tail in *date slices*: re-query with =before:<oldest-full-day-seen>= (day resolution), repeat until a page returns fewer than 100, dedupe by message id across slices (the day-resolution boundary overlaps).
-- *Never report =resultSizeEstimate= as a count.* It's unreliable — observed stuck at "201" across three different queries whose real union exceeded 300.
-
-*** Backlog-residue check (every sweep — cheap, mandatory)
-
-The anchored scan is blind to anything unread from *before* the anchor. After it, run one probe for pre-anchor residue:
-
-#+begin_src text
-mcp__google-docs-personal__listMessages q="is:unread in:inbox before:<anchor-YYYY/MM/DD>" maxResults=5
-#+end_src
-
-If it returns any messages, surface one loud line in the sweep summary: "Backlog: unread predating the anchor exists (N+ shown; date-slice to inventory)" and offer a backlog sweep. Never fold the residue into a quiet sweep — an anchored "no changes" claim is only true for the window the scan saw. (Added 2026-07-08 after ~300 pre-anchor unread accumulated unseen; the probe returns actual messages, so it works where the estimate lies.)
-
-** Classify
-
-Bias: *trash-leaning* — personal Gmail is high noise volume.
-
-- *Noise-trash:* newsletters, Substacks, retail/SaaS marketing, social digests, redundant aggregator digests (Notion/Miro daily), wrong-recipient mail, past-event calendar artifacts.
-- *Noise-keep:* receipts, order confirmations, statements — low value but worth the audit trail.
-- *FYI:* substantive personal mail with no action owed.
-- *Action:* an explicit ask, a reply owed, a time-sensitive personal matter.
-
-** Render
-
-#+begin_example
-**Personal Gmail — N unread.** <one-line classification summary>
-- Action: <items, if any, with thread links>
-- FYI: <items, if any>
-- Noise: N trash candidates, M keep
-#+end_example
-
-Omit the block if zero unread.
-
-** Actions
-
-- trash :: =mcp__google-docs-personal__trashMessage= id=<message-id> (recoverable from Gmail Trash for 30 days)
-- mark-read :: =mcp__google-docs-personal__modifyMessageLabels= id=<message-id> removeLabelIds=["UNREAD"]
-- star+read :: =mcp__google-docs-personal__modifyMessageLabels= id=<message-id> addLabelIds=["STARRED"] removeLabelIds=["UNREAD"]
-- attach-fetch:: =.ai/scripts/gmail-fetch-attachments.py --profile personal --message-id <message-id> --output-dir <PATH>=
diff --git a/inbox/PROCESSED-2026-07-09-0649-from-work-pr-review-rule-tightening-from-a.org b/inbox/PROCESSED-2026-07-09-0649-from-work-pr-review-rule-tightening-from-a.org
deleted file mode 100644
index 80dc4bc..0000000
--- a/inbox/PROCESSED-2026-07-09-0649-from-work-pr-review-rule-tightening-from-a.org
+++ /dev/null
@@ -1,11 +0,0 @@
-#+TITLE: PR-review rule tightening from a DeepSat review session (Cra
-#+SOURCE: from work
-#+DATE: 2026-07-09 06:49:14 -0500
-
-PR-review rule tightening from a DeepSat review session (Craig, 2026-07-09). Two changes to the review-code skill:
-
-1. No praise on approvals — stronger than the current 'Posted Summary Voice' rule. That section currently permits 'the verdict plus at most a bare positive ("Clean.", "Solid fix.")'. Craig's ruling: an approve summary carries NO praise at all, not even the bare positive. Lead the summary with the substantive pointer (the inline design note), then the verdict. Example he approved: 'One design note inline, not a blocker. Approving.' The praise-strips / correction-explains split still holds for findings; approvals just drop the praise clause entirely. Suggest editing the 'Posted Summary Voice' section (and /voice personal pattern #40 if it encodes the 'bare positive allowed' carve-out) to remove the bare-positive permission.
-
-2. Always show inline comment text at the review gate — Phase 5 / the publish-flow gate should require printing the FULL inline prose that will post, alongside the summary body, never the summary alone with the inline merely described ('I'd pair it with one inline on...'). Craig approves the exact words that post under his name, so the exact words must be on screen. Suggest making this explicit in review-code Phase 5 (Terminal display) and in commits.md Step 2 Shape 1 (the print-the-draft step).
-
-Both are cross-project (any PR review), so they belong in the rulesets layer, not just the DeepSat project. Also captured in the work project's harness memory as feedback_no_praise_on_approvals_show_inline for immediate use.
diff --git a/inbox/PROCESSED-2026-07-09-1341-from-work-bug-data-loss-wrap-org-table-el-and.org b/inbox/PROCESSED-2026-07-09-1341-from-work-bug-data-loss-wrap-org-table-el-and.org
deleted file mode 100644
index a128d0a..0000000
--- a/inbox/PROCESSED-2026-07-09-1341-from-work-bug-data-loss-wrap-org-table-el-and.org
+++ /dev/null
@@ -1,28 +0,0 @@
-#+TITLE: BUG (data loss): wrap-org-table.el and lint-org.el corrupt o
-#+SOURCE: from work
-#+DATE: 2026-07-09 13:41:56 -0500
-
-BUG (data loss): wrap-org-table.el and lint-org.el corrupt org example blocks.
-
-Both scripts scan for lines beginning with "|" and rewrite them as org tables. They do not skip #+begin_example / #+begin_src / #+begin_quote regions, so ASCII art using pipe characters gets mangled into tables. Both write to disk with no confirmation.
-
-Reproduced 2026-07-09 in the work project against an architecture doc containing an ASCII pipeline diagram that uses | and v as flow arrows:
-
- Before: After:
- | | |
- v |---|
- v
-
-and a plain indented block became a bordered org table with |---| rules inserted between every line.
-
-Two separable defects:
-
-1. Table detection is line-based. Both helpers should use org-element-at-point (or org-in-block-p) to skip example/src/quote/verse blocks rather than matching /^\s*|/.
-
-2. lint-org.el mutates its input. Passing five files to it reformatted all five on disk -- one of them by 1949 lines. Its documented job is to report judgment items. A linter must not write. If the reformat is wanted, it belongs behind an explicit --fix flag.
-
-Impact: silent data loss on any org file that mixes tables and example blocks, which is most architecture docs. In this case the good content was already staged in git and was recoverable. It would not have been otherwise.
-
-No local fix attempted: .ai/scripts/ is rulesets-owned and the startup rsync would revert it. Filed as a task on the work side (Org-table helpers corrupt example blocks) so it is tracked there until the canonical fix lands.
-
-Suggested test: run wrap-org-table.el against a file containing a #+begin_example block whose lines start with "|" and assert the block is byte-identical afterward.
diff --git a/inbox/PROCESSED-2026-07-09-1400-from-work-handoff-ai-attribution-cleanup-done.org b/inbox/PROCESSED-2026-07-09-1400-from-work-handoff-ai-attribution-cleanup-done.org
deleted file mode 100644
index a37a54a..0000000
--- a/inbox/PROCESSED-2026-07-09-1400-from-work-handoff-ai-attribution-cleanup-done.org
+++ /dev/null
@@ -1,22 +0,0 @@
-#+TITLE: HANDOFF: AI-attribution cleanup done from the work session (
-#+SOURCE: from work
-#+DATE: 2026-07-09 14:00:05 -0500
-
-HANDOFF: AI-attribution cleanup done from the work session (Craig approved doing it from here).
-
-What changed in rulesets, uncommitted in your working tree:
-
-1. 103 files: rewrote the org header "#+AUTHOR: Craig Jennings & Claude" to "#+AUTHOR: Craig Jennings". Breakdown: 43 .ai/workflows, 43 claude-templates/.ai/workflows, 5 docs/specs, 5 docs/design, 2 .ai (notes, protocols), 2 claude-templates/.ai, 2 references, 1 working/. Exactly one line changed per file (103 insertions, 103 deletions, zero non-AUTHOR lines). Prose mentions of Claude were not touched.
-
-2. claude-rules/commits.md: added "Document author metadata" to the No-AI-Attribution list, plus a new subsection "Generated documents carry the human author only". It explains that the propagation mechanism is imitation (no template stamps the line; agents copy it from neighbouring files), names the employer-policy stakes, and carves out two exceptions.
-
-Held back deliberately, please confirm you agree:
-- .ai/sessions/ (14 files) left as-is. They are historical records of what happened, not live artifacts.
-- docs/design/2026-05-28-generic-agent-runtime-spec.org and its -review sibling keep "#+AUTHOR: Codex". Codex actually wrote them, so renaming would be a false attribution rather than removing one.
-- .ai/scripts/tests/fixtures/todo-sample.org keeps "#+AUTHOR: synthetic fixture" (test data).
-
-Not committed. The tracked tree was clean at 0/0 against origin/main before these edits, so the diff is exactly this change and nothing else. Review and commit on your side.
-
-Why it came up: the work project noticed its generated daily-prep docs carry the co-author line. Craig pointed out that his own repo tolerates it, but employers whose policy is that work product carries employee names alone would not. Nothing has leaked yet: the arch docs pushed to the company GHE lost the #+AUTHOR line in the pandoc conversion. The exposure was prospective, via a planned Markdown-to-Notion publisher.
-
-Companion item already in your inbox: the wrap-org-table.el / lint-org.el data-loss bug (2026-07-09-1341).
diff --git a/inbox/PROCESSED-2026-07-09-1636-from-chime-staleness-proposal.txt b/inbox/PROCESSED-2026-07-09-1636-from-chime-staleness-proposal.txt
deleted file mode 100644
index cc741b2..0000000
--- a/inbox/PROCESSED-2026-07-09-1636-from-chime-staleness-proposal.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Proposal: task-review-staleness.sh should accept org-style :LAST_REVIEWED: values, or fail loudly.
-
-Hit this in chime today. I stamped :LAST_REVIEWED: [2026-07-09 Thu] — an org inactive timestamp, matching the CREATED: and CLOSED: cookies sitting right next to it in the same drawer. The script expects a bare 2026-07-09.
-
-The failure is silent and inverted. In count mode, `date -d "[2026-07-09 Thu]"` fails, and the unparseable branch counts the task as STALE. So a freshly-reviewed task reports as never-reviewed, and a full review pass leaves the startup nudge saying exactly what it said before. In list mode the sort-key regex also rejects it, so the task sorts as 0000-00-00 (oldest) and gets re-walked first. Both modes punish the stamp for being in the wrong format, and neither says so.
-
-I fixed my side (bare dates, matching the precedent in home/todo.org). The trap is worth closing, because the bracketed form is the plausible guess: every other date in an org PROPERTIES drawer is bracketed, and nothing in task-review.org or todo-format.md says LAST_REVIEWED is different.
-
-Two options, either fine:
-
-1. Accept both. Strip a leading bracket and a trailing weekday + bracket before parsing, inside extract_tasks. Org-native stamps then work and existing bare stamps keep working.
-
-2. Fail loudly. When a LAST_REVIEWED value is present but unparseable, print a warning naming the file, line, and value rather than folding it into the stale count. A malformed stamp is a data error, and treating it as "never reviewed" hides it forever.
-
-I lean toward both: accept the org form, warn on anything still unparseable. Today a project can run task reviews for months while the staleness count never drops, and nothing ever explains why.
-
-Also worth a line in todo-format.md or task-review.org stating the expected format. The script is currently the only place it's written down, and you have to read its awk to find it.
diff --git a/inbox/PROCESSED-2026-07-09-1745-from-chime-matrix-proposal.txt b/inbox/PROCESSED-2026-07-09-1745-from-chime-matrix-proposal.txt
deleted file mode 100644
index 53c20c8..0000000
--- a/inbox/PROCESSED-2026-07-09-1745-from-chime-matrix-proposal.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-Proposal: todo-format.md's bug matrix should warn against double-counting rarity.
-
-Adding the severity x frequency matrix to chime today, I mis-graded a bug by exactly one mistake, and I think the rule invites it.
-
-The task: chime's async watchdog interrupts a child that outlives its timeout, but never escalates to kill. I graded it Minor severity ("a zombie child and a leaked process buffer accumulate slowly") x rare edge case ("the watchdog must fire AND the child must survive SIGINT") = P4 = [#D].
-
-Then I read async.el. Its cleanup guards on (eq 'exit (process-status proc)) and only kills the process buffer in the zero-exit branch, so a signal-killed child (status 'signal) skips it entirely. Every watchdog interrupt leaks a buffer; the surviving-SIGINT zombie is the rare sub-case, not the leak. And the watchdog nils the process handle, so the same tick spawns a replacement — if the hang cause persists, another child is abandoned every timeout period. Roughly 30 leaked buffers an hour, indefinitely, invisibly. A real incident had a child stuck 15+ hours.
-
-Severity was the wrong input, not frequency. "Accumulates slowly" describes a bounded trickle. This accumulates at a fixed rate forever once entered, with no workaround short of restarting Emacs. That's Major. Major x rare edge = P3 = [#C], which is where it landed.
-
-The generalizable error: I let the rarity of *entering* the failure state discount the *severity* of being in it. But frequency already carries that rarity. Grading it twice buries exactly the bugs that compound — the ones where a rare trigger produces unbounded harm.
-
-Suggested addition to the matrix section:
-
- Don't double-count rarity. Grade severity by the rate of harm once the
- failure state is entered, not by how rare it is to enter. Frequency
- already carries the rarity; letting it discount severity too grades the
- same fact twice, and that buries compounding bugs. A leak that repeats
- every timeout period until the process restarts is Major even when
- reaching that state is a rare edge case.
-
-Two smaller additions I made to chime's scheme, both of which I'd put in the global rule:
-
- Record the grading in the task body — the severity band, the frequency
- row, and the arithmetic. A bare priority cookie can't be argued with; a
- stated read can be re-checked against the source and corrected. That's
- how this task moved [#D] -> [#C] an hour after I graded it.
-
- Disagreeing with a grade means fixing an input. If a letter looks wrong,
- re-read the severity band and the frequency row against the source and
- correct whichever is wrong. Don't override the letter directly — that
- turns the matrix into a formality and puts you back to grading by
- instinct.
-
-The last one is the one I care about. Craig's first instinct on seeing the [#D] was to restore the [#B] it had before. The matrix earns its keep only if a disagreement forces a re-read of the inputs rather than a manual override, and the rule text currently doesn't say so.
diff --git a/inbox/PROCESSED-2026-07-11-0222-from-.emacs.d-ui-prototype-rule-proposal.org b/inbox/PROCESSED-2026-07-11-0222-from-.emacs.d-ui-prototype-rule-proposal.org
deleted file mode 100644
index eeb60e7..0000000
--- a/inbox/PROCESSED-2026-07-11-0222-from-.emacs.d-ui-prototype-rule-proposal.org
+++ /dev/null
@@ -1,55 +0,0 @@
-#+TITLE: Proposal: UI features require a prototype phase before build-to-spec
-#+AUTHOR: Craig Jennings
-#+DATE: 2026-07-11
-
-* The rule (Craig approved promotion 2026-07-11)
-
-When a spec'd feature has a UI, don't build straight from the spec. After the
-initial spec, run several UI/UX prototype feedback loops — iteratively driving
-the remaining functionality alongside the look and feel — then fold what settled
-back into the spec. Only then "build to the prototype": the built feature should
-look and behave as close to the prototype as possible, and any deviation is
-documented in an addendum section of the prototype/spec itself.
-
-* Where it should live (rulesets session decides exact home)
-
-Two natural homes; probably both:
-
-1. The =brainstorm= skill's Phase 3. Today Phase 3 presents the design in chunks
- and stops. Add: if the feature has a UI, the design isn't "accepted" until it
- has been through a prototype UI/UX phase (several feedback loops), and the
- spec records what the prototype settled. The spec's Next Steps then say
- "build to the prototype," not "build to the spec."
-
-2. A spec-lifecycle rule (=docs-lifecycle.md=, or a small new workflow rule).
- The lifecycle for a UI feature gains a prototype stage between DRAFT/READY and
- build, and the spec carries a "Prototype & deviations" addendum section that
- the build keeps current.
-
-Companion touch points to reconcile: =spec-create= (emit the prototype stage +
-the deviations-addendum section for UI specs), =spec-response= (a UI spec
-decomposes into a prototype loop first, then build-to-prototype tasks),
-=start-work= (its verify phase already drives the UI end-to-end; here the bar is
-"matches the prototype," with deviations logged).
-
-* Why — worked example (takuzu, 2026-07-11)
-
-Building the takuzu (Binairo) Emacs game. The spec chose "colored tiles, glyph
-overlay optional." Built straight to that and the first launch in Craig's actual
-terminal frame was all black — the dark background-color faces read as black and
-the cursor was a GUI-only =:box=, so the whole grid was invisible. The
-colored-tiles-are-readable assumption was false in the real environment. A
-prototype loop caught it on the first screenshot; had we "built to spec" and
-called it done, we'd have shipped an unusable board. The fix (glyphs as the
-primary signal, inverse-video cursor) is exactly the kind of adjustment that only
-surfaces by looking at the running UI, and it now needs to flow back into the
-spec so the build target is the prototype, not the original spec text.
-
-Jotto (the other game spec'd the same day) also has a UI and will follow the same
-path.
-
-* Requested action
-
-Fold the rule into the brainstorm skill and the spec-lifecycle rules so it
-governs every project's UI features, then re-sync. This proposal is the durable
-channel; the two game projects apply it locally in the meantime.
diff --git a/inbox/PROCESSED-2026-07-19-2141-from-.emacs.d-version-working-directories.org b/inbox/PROCESSED-2026-07-19-2141-from-.emacs.d-version-working-directories.org
deleted file mode 100644
index 6ce239f..0000000
--- a/inbox/PROCESSED-2026-07-19-2141-from-.emacs.d-version-working-directories.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Craig's ruling from the .emacs.d project: working/ contains
-#+SOURCE: from .emacs.d
-#+DATE: 2026-07-19 21:41:10 -0500
-
-Craig's ruling from the .emacs.d project: working/ contains the project work currently being developed, so it must be version-controlled and saved from creation rather than excluded until graduation. Ephemeral or disposable artifacts belong in a project temp/ directory (gitignored) or system /tmp, not working/. Please update the canonical working-files convention and any template/install .gitignore behavior so working/ is tracked across projects. Clarify that graduation reorganizes durable working artifacts into permanent homes; it does not mark the point when they first become durable. In .emacs.d we are removing /working/ from .gitignore, adding /temp/, and checking in the complete current working set.
diff --git a/inbox/PROCESSED-2026-07-19-2350-from-home-craig-approved-the-colloquialisms-the.org b/inbox/PROCESSED-2026-07-19-2350-from-home-craig-approved-the-colloquialisms-the.org
deleted file mode 100644
index ef5c753..0000000
--- a/inbox/PROCESSED-2026-07-19-2350-from-home-craig-approved-the-colloquialisms-the.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Craig approved the colloquialisms + 'the list' before-close-
-#+SOURCE: from home
-#+DATE: 2026-07-19 23:50:02 -0500
-
-Craig approved the colloquialisms + 'the list' before-close-queue convention — go ahead and wire the rulesets side (the protocols.org colloquialisms reference and the wrap-it-up.org queue-drain step). Home already adopted its own version locally (the 'the list' / 'tell <project>' section is committed in home's notes.org), so this is just the canonical rulesets wiring plus the short design pass on where the reference and queue live and the exact wrap-it-up insertion point.
diff --git a/inbox/PROCESSED-2026-07-20-0009-from-.emacs.d-three-sentry-design-considerations.org b/inbox/PROCESSED-2026-07-20-0009-from-.emacs.d-three-sentry-design-considerations.org
deleted file mode 100644
index 9a545f8..0000000
--- a/inbox/PROCESSED-2026-07-20-0009-from-.emacs.d-three-sentry-design-considerations.org
+++ /dev/null
@@ -1,11 +0,0 @@
-#+TITLE: Three sentry-design considerations captured in the shared ro
-#+SOURCE: from .emacs.d
-#+DATE: 2026-07-20 00:09:58 -0500
-
-Three sentry-design considerations captured in the shared roam inbox (rulesets-owned), routed here during a sentry inbox-zero pass from .emacs.d:
-
-1. Bug/enhancement logging during sentry: only if the project owns a codebase, file bugs by default and enhancements only if asked; review-and-accept/decline them during the morning sentry reconciliation. (Note: .emacs.d ran exactly this by hand tonight — findings logged to its session anchor for reconcile — so this is live-tested design input worth folding into the sentry workflow.)
-2. System-health during sentry: decide what parts are safe to check, and how to keep the two daily drivers (ratio/velox) from running it simultaneously (lock/coordination question).
-3. Keeping the sibling machine (velox/ratio) up-to-date during sentry.
-
-These are rulesets backlog items about the sentry workflow itself; process per rulesets inbox conventions.
diff --git a/inbox/PROCESSED-2026-07-20-0847-from-archsetup-suspend-workflow-change-detach-the-tmux.org b/inbox/PROCESSED-2026-07-20-0847-from-archsetup-suspend-workflow-change-detach-the-tmux.org
deleted file mode 100644
index 9348a50..0000000
--- a/inbox/PROCESSED-2026-07-20-0847-from-archsetup-suspend-workflow-change-detach-the-tmux.org
+++ /dev/null
@@ -1,16 +0,0 @@
-#+TITLE: Suspend workflow change — detach the tmux client on every su
-#+SOURCE: from archsetup
-#+DATE: 2026-07-20 08:47:17 -0500
-
-Suspend workflow change — detach the tmux client on every suspend. Applied locally in archsetup as a stopgap (startup sync overwrites it); please apply to the canonical claude-templates/.ai/workflows/suspend.org. The edited file is attached alongside this note.
-
-What changed: added Step 6 to suspend.org. After the brief handoff, detach the tmux client viewing the aiv-<project> session as the very last tool call:
- sess=$(tmux display-message -p '#S' 2>/dev/null)
- [ -n "$sess" ] && tmux detach-client -s "$sess"
-Also updated the 'Where suspend sits among its neighbors' bullet and the 'What suspend does NOT do' section to draw the detach-vs-teardown line.
-
-Key distinction: detach is NOT teardown. wrap-it-up's teardown KILLS the aiv-<project> session (and must defer to the Stop hook because it kills the session the agent runs in, which would cut the valediction). Suspend's detach leaves the session and the agent process ALIVE in the background and only disconnects the view, so it can run inline as the final action — the handoff text is preserved in the tmux pane and shown on re-attach. Degrade gracefully when not in tmux ($TMUX unset -> skip, session stays attached).
-
-Why: Craig now cycles live agent sessions in Emacs with alt-space, and rotates through everything (including re-attaching detached ai-term sessions) with shift+alt+space. A suspended session left attached clutters the active rotation; detaching parks it in the re-attachable set, which is what makes suspend-and-walk-away work. So every suspension should end in a detach.
-
-Companion files: suspend.org is the only change. No hook / settings.json change needed (detach needs no deferred hook, unlike teardown). wrap-it-up.org is unaffected — its teardown section is the contrast the new suspend text references, no edit required.
diff --git a/inbox/PROCESSED-2026-07-20-0847-from-archsetup-suspend.org b/inbox/PROCESSED-2026-07-20-0847-from-archsetup-suspend.org
deleted file mode 100644
index 166f9c9..0000000
--- a/inbox/PROCESSED-2026-07-20-0847-from-archsetup-suspend.org
+++ /dev/null
@@ -1,143 +0,0 @@
-#+TITLE: Session Suspend Workflow
-#+AUTHOR: Craig Jennings
-#+DATE: 2026-06-28
-
-* Overview
-
-This workflow captures the live state of a session when Craig must leave
-abruptly, so a future session resumes with nothing lost. It is the fast,
-capture-only workflow for departure: it writes down where every thread stands,
-notes any uncommitted work, then STOPS — no cleanup, no archive, no teardown.
-
-Triggered by Craig saying "suspend the session," "suspend," "I need to go,"
-"stick a pin in everything," or similar. "I need to go" is broad — if it reads
-as a conversational aside rather than a request to suspend, confirm before
-running.
-
-* Where suspend sits among its neighbors
-
-Three workflows touch the session anchor (=.ai/session-context.org=); keep them
-straight:
-
-- =flush= ([[file:../../flush/SKILL.md]] / =/flush=) — *stay and sharpen.*
- Refreshes the anchor in place, prompts Craig to type =/clear=, and a hook
- resumes the *same* logical session in a fresh context. Craig is still here.
-- *suspend* (this workflow) — *leave.* Captures richly into the anchor, leaves
- the file in place, detaches the tmux client so the session parks in the
- re-attachable set, and Craig walks away. The next session is a cold startup
- that detects the present anchor and resumes from it — or Craig re-attaches the
- still-live session directly.
-- =wrap-it-up= ([[file:wrap-it-up.org][wrap-it-up.org]]) — *end.* Writes the
- Summary, archives the anchor into =.ai/sessions/=, commits + pushes, and runs
- the phrase-dependent teardown.
-
-Suspend and flush share one core — capture into the anchor, leave it in place.
-They differ in the exit (leave vs clear-and-continue) and the resume path
-(startup vs the =/clear= hook). Suspend reuses flush's capture discipline (its
-Phase 1 anchor-refresh) rather than restating it, and adds a richer,
-resume-weighted Session Log entry because it's written for a cold resume after a
-gap, not a same-session reset.
-
-* Suspend vs wrap-up — the one structural difference
-
-=wrap-it-up= ARCHIVES =.ai/session-context.org= (renames it into
-=.ai/sessions/=); its absence at the next startup is the signal that the last
-session ended cleanly.
-
-Suspend does the opposite: it LEAVES =.ai/session-context.org= in place. Its
-presence at startup is exactly the signal that the previous session was
-interrupted, so the startup workflow reads it and resumes. Suspend provides only
-the *capture* half — startup's existing interrupted-session path (Phase A checks
-for the anchor, Phase B reads it, Phase C offers to resume) is the *resume* half,
-already built.
-
-So: never archive, never rename the context file in a suspend. Capture into it
-and leave it.
-
-* What gets captured
-
-The point is zero lost information, weighted toward RESUME. Into the
-=* Session Log= of =.ai/session-context.org=, append one dated
-=** YYYY-MM-DD ... — SUSPENDED= entry holding:
-
-1. *Open threads — resume here.* For each active or pending thread: the topic,
- its status (ACTIVE / PINNED / SET ASIDE / DEFERRED), the immediate next
- step, and the pointers needed to act on it cold (files + line numbers,
- commit SHAs, the specific finding or decision). This is the core; spend the
- most words here. Order newest / most-active first.
-2. *Pending decisions / open questions* awaiting Craig — anything blocked on
- his input, with enough context that the answer is actionable.
-3. *Shipped this session* — a terse list of what landed, each with its commit
- SHA, so the resume knows what is already done and need not re-derive it.
-4. *Uncommitted work* — anything modified on disk but not committed, named
- file by file, so the resume knows what state the tree is in.
-5. *Key findings not yet recorded elsewhere* — anything learned this session
- that isn't already in a commit, a file, or memory, so it survives.
-6. *Background work* — any running task, agent, or job, and how to check it.
-7. *Resume hint* — the single most likely "start here" next action.
-
-Also update the top of =* Summary= (Active Goal) with a one-line SUSPENDED
-pointer to the entry, so startup reading the top sees the current state even
-when the Summary body is from an earlier thread.
-
-* Steps
-
-1. *Write the SUSPENDED entry* into the Session Log, per "What gets captured"
- above. Timestamp with =date "+%Y-%m-%d %a @ %H:%M:%S %z"=.
-2. *Update the Active Goal pointer* at the top of =* Summary=.
-3. *Record uncommitted work, don't force-commit it.* A suspend records state, it
- does not tidy it. Name every uncommitted change in the SUSPENDED entry and
- leave the tree as it is — on an abrupt departure, a dirty tree (like any
- crash) is safer than a blind commit of arbitrary mid-work state. (If a
- project defines a standing always-commit set in its own workflow, commit only
- that set — but the default shared behavior is to leave the tree alone.)
-4. *Leave =.ai/session-context.org= in place.* Do not archive it.
-5. *Brief handoff* — one or two lines: what was captured, where the resume
- pointer is, the most-active thread. This is the last thing Craig sees before
- the view detaches (Step 6), so deliver it complete.
-6. *Detach the tmux client.* As the final action, detach the client viewing the
- =aiv-<project>= session so it drops out of Craig's active view while staying
- alive in the background. This is a DETACH, not a teardown: the session and the
- agent process keep running, nothing is killed, no context is lost.
-
- #+begin_src bash
- sess=$(tmux display-message -p '#S' 2>/dev/null)
- [ -n "$sess" ] && tmux detach-client -s "$sess"
- #+end_src
-
- Run it as the very last tool call, after the handoff text has rendered — tmux
- preserves the pane, so Craig sees the full handoff when he re-attaches. Unlike
- wrap-up's teardown (which must defer to a =Stop= hook because it kills the
- session the agent runs in, which would cut off the valediction), detach runs
- inline: it disconnects the view but leaves the agent's session alive, so
- nothing is cut off. Degrade gracefully — if not inside tmux (=$TMUX= unset, no
- session), skip silently and the session simply stays attached.
-
- Why detach on every suspend: Craig cycles his live agent sessions in Emacs
- with alt-space, and rotates through everything — including re-attaching
- detached ai-term sessions — with shift+alt+space. A suspended session left
- attached clutters the active rotation; detaching parks it in the
- re-attachable set, which is what makes suspend-and-walk-away work. Re-attach
- is one keystroke (shift+alt+space) or =tmux attach -t aiv-<project>=.
-
-* What suspend does NOT do
-
-Speed over completeness. A suspend deliberately skips everything wrap-it-up
-does beyond capture:
-
-- No =* Summary= rewrite beyond the one-line Active Goal pointer.
-- No todo.org cleanup / archive-done.
-- No KB / memory promotion sweep.
-- No Linear / board reconciliation.
-- No session-record archive (the file stays live).
-- No teardown. Suspend DETACHES the tmux client (Step 6) but never kills the
- session: the =aiv-<project>= session and the agent process stay alive in the
- background, only the view disconnects. It drops no =Stop=-hook teardown
- sentinel, so the wrap-teardown hook stays dormant. Teardown — killing the
- session — is wrap-it-up's job, not suspend's; detach is the lighter move that
- parks a still-live session.
-- No blind commit of working files (step 3).
-- No valediction. A suspend is a pause, not a goodbye.
-
-If Craig later wants the clean end, he runs wrap-it-up, which picks up the
-captured state and finishes the job.
diff --git a/inbox/PROCESSED-2026-07-20-1059-from-.emacs.d-proposal-craig-approved-2026-07-20.org b/inbox/PROCESSED-2026-07-20-1059-from-.emacs.d-proposal-craig-approved-2026-07-20.org
deleted file mode 100644
index 4934cdf..0000000
--- a/inbox/PROCESSED-2026-07-20-1059-from-.emacs.d-proposal-craig-approved-2026-07-20.org
+++ /dev/null
@@ -1,19 +0,0 @@
-#+TITLE: PROPOSAL (Craig-approved 2026-07-20): silent-until-signal pa
-#+SOURCE: from .emacs.d
-#+DATE: 2026-07-20 10:59:59 -0500
-
-PROPOSAL (Craig-approved 2026-07-20): silent-until-signal pattern for in-session monitor loops — apply to auto triage-intake, auto inbox-zero, and sentry.
-
-Problem: in-session cron/loop monitors surface a visible LLM turn on every fire even when nothing changed, so a long session fills with 'no new items' / 'quiet fire' noise. A background subagent does NOT fix it — it notifies on every completion, including the empty ticks.
-
-Proposed pattern — split silent detection from LLM judgment:
-- A shell-level watcher (systemd user timer, or a backgrounded loop) does detection silently: diff the source (roam inbox, or triage sources) against a seen-list every N minutes, producing ZERO output on an empty check.
-- Only a genuinely new item surfaces — the watcher drops a handoff into the project inbox/, and the existing inbox-boundary stop-hook surfaces it at the next natural boundary. The LLM then does the implement-vs-file/route judgment, only when there's something.
-- The watcher-owned seen-list replaces the in-anchor 'Dispositioned' list.
-
-Apply to:
-- auto inbox-zero (the roam-inbox monitor) — the case this came from (.emacs.d session, 2026-07-20).
-- auto triage-intake — same shape (silent scan, surface only real items).
-- sentry — quiet fires should collapse to JUST the check-time, a one-line heartbeat ('sentry checked HH:MM, nothing'), not a full per-pass digest. An all-quiet night becomes a short timestamp list instead of a wall of SKIP/no-op lines; only a fire that actually did or queued something writes a full digest. (Craig's explicit ask.)
-
-Why rulesets: triage-intake.org, inbox.org, and sentry.org all live in rulesets, and the detection/judgment split is generic. Open questions for the rulesets session: watcher mechanism (systemd timer vs in-session background vs the Monitor tool); where the seen-list lives; passive inbox-drop vs paging.
diff --git a/inbox/PROCESSED-2026-07-20-1059-from-.emacs.d-research-is-there-a-google-maps-mcp-or.org b/inbox/PROCESSED-2026-07-20-1059-from-.emacs.d-research-is-there-a-google-maps-mcp-or.org
deleted file mode 100644
index 20aaae1..0000000
--- a/inbox/PROCESSED-2026-07-20-1059-from-.emacs.d-research-is-there-a-google-maps-mcp-or.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Research: is there a Google Maps MCP (or similar) that can r
-#+SOURCE: from .emacs.d
-#+DATE: 2026-07-20 10:59:58 -0500
-
-Research: is there a Google Maps MCP (or similar) that can report the locations of devices that are sharing their location with you? If none exists, research how hard it would be to build one. (Captured in the shared roam inbox, routed here since it's rulesets-owned research.)
diff --git a/inbox/PROCESSED-2026-07-20-1344-from-home-applied-the-triage-sources-activation.org b/inbox/PROCESSED-2026-07-20-1344-from-home-applied-the-triage-sources-activation.org
deleted file mode 100644
index e7dcdf1..0000000
--- a/inbox/PROCESSED-2026-07-20-1344-from-home-applied-the-triage-sources-activation.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Applied the :TRIAGE_SOURCES: activation on home — declared p
-#+SOURCE: from home
-#+DATE: 2026-07-20 13:44:00 -0500
-
-Applied the :TRIAGE_SOURCES: activation on home — declared personal-gmail cmail personal-calendar telegram github-prs in notes.org Workflow State. Triage stays active after the sync.
diff --git a/inbox/PROCESSED-2026-07-20-1346-from-work-processed-the-triage-source-activation.org b/inbox/PROCESSED-2026-07-20-1346-from-work-processed-the-triage-source-activation.org
deleted file mode 100644
index 10ccfe4..0000000
--- a/inbox/PROCESSED-2026-07-20-1346-from-work-processed-the-triage-source-activation.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Processed the triage-source-activation handoff. work DOES pu
-#+SOURCE: from work
-#+DATE: 2026-07-20 13:46:45 -0500
-
-Processed the triage-source-activation handoff. work DOES pull general sources, so I declared them: :TRIAGE_SOURCES: cmail personal-calendar telegram in .ai/notes.org Workflow State. Excluded personal-gmail and github-prs (personal, not work-triage sources). Project-specific DeepSat plugins (deepsat-slack/gmail/calendar/ghe-prs/ghe-branches, linear) stay active by presence. Thanks for the heads-up before the sync would have quieted them.
diff --git a/inbox/PROCESSED-2026-07-20-1714-from-archsetup-voice-skill-new-pattern-46-comma-budget.org b/inbox/PROCESSED-2026-07-20-1714-from-archsetup-voice-skill-new-pattern-46-comma-budget.org
deleted file mode 100644
index e999567..0000000
--- a/inbox/PROCESSED-2026-07-20-1714-from-archsetup-voice-skill-new-pattern-46-comma-budget.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Voice skill: new pattern #46 (comma budget, personal mode) a
-#+SOURCE: from archsetup
-#+DATE: 2026-07-20 17:14:02 -0500
-
-Voice skill: new pattern #46 (comma budget, personal mode) added at Craig's direction, 2026-07-20 archsetup session. His words: 'no more than two commas per sentence. we should add that to the /voice personal pass.' Paired edit already made in your working tree via the ~/.claude/skills/voice symlink: voice/SKILL.md (frontmatter count 45->46, Modes, Your Task, Craig's Voice intro, new #46 section, Process steps 2+8, Reference) and voice/references/voice-profile.org (new §46 with basis + before/after from the Hyprland issue draft that prompted it). #46 joined the attestation high-recurrence set at birth. Nothing else touched; review and commit rulesets-side.
diff --git a/inbox/PROCESSED-2026-07-20-2353-from-.dotfiles-sentry-pass-list-amendment-craig-s.org b/inbox/PROCESSED-2026-07-20-2353-from-.dotfiles-sentry-pass-list-amendment-craig-s.org
deleted file mode 100644
index 9f2fbf6..0000000
--- a/inbox/PROCESSED-2026-07-20-2353-from-.dotfiles-sentry-pass-list-amendment-craig-s.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Sentry pass-list amendment (Craig's order, 2026-07-21, from
-#+SOURCE: from .dotfiles
-#+DATE: 2026-07-20 23:53:35 -0500
-
-Sentry pass-list amendment (Craig's order, 2026-07-21, from the dotfiles session): sentry never checks email or messengers, and gains a bug-finding pass. Attached alongside this note is dotfiles' edited .ai/workflows/sentry.org — reconcile it into the canonical claude-templates copy. Three changes: (1) Overview pass list now reads 'triage (no mail or messengers)' and adds 'bug finding'. (2) Pass 3 loads only non-mail, non-messenger triage plugins (calendar, PR/ticketing); cmail, Gmail variants, Telegram, Signal, chat DMs are never loaded by a sentry fire — a manual 'triage intake' still scans everything. (3) New pass 11 'Bug finding': static analysis + config sanity + one rotating targeted code-read area per fire; verified findings filed as graded bug tasks per the severity-times-frequency matrix; find, never fix unattended. No companion files need reconciling — triage-intake.org already documents that sentry invokes it under the no-approvals contract; the plugin subset is sentry's own concern.
diff --git a/inbox/PROCESSED-2026-07-20-2353-from-.dotfiles-sentry.org b/inbox/PROCESSED-2026-07-20-2353-from-.dotfiles-sentry.org
deleted file mode 100644
index 8369c46..0000000
--- a/inbox/PROCESSED-2026-07-20-2353-from-.dotfiles-sentry.org
+++ /dev/null
@@ -1,217 +0,0 @@
-#+TITLE: Sentry — Overnight Hygiene Supervisor
-#+AUTHOR: Craig Jennings
-#+DATE: 2026-07-19
-
-* Overview
-
-Sentry is an interval loop that keeps a project's hygiene current while Craig is away. Each fire walks a fixed list of hygiene passes — roam pull, inbox zero, triage (no mail or messengers), todo cleanup, task audit, working-files hygiene, spec board, link integrity, git health, prep freshness, bug finding — and commits each pass's writing to a throwaway daily branch. Nothing pushes. In the morning Craig reviews the branch, squash-merges what he wants, and deletes it.
-
-The design goal is a project that greets the morning already tidy, with every judgment call and every destructive action parked in an approval queue rather than executed unattended. Sentry does the mechanical sweeping; Craig does the deciding.
-
-This file is the engine. It owns the entry gates, the branch mechanics, the lock model, the per-fire pass runner, the digest and approval queue, the skip semantics, and the stop-sentry shutdown. The =agent-lock= helper (=.ai/scripts/agent-lock=) provides the locks. The passes reuse existing workflows (=inbox.org=, =triage-intake.org=, =clean-todo.org=, =task-audit.org=) under sentry's unattended contract.
-
-* When to Use This Workflow
-
-Craig arms sentry at the end of a session, with the machine left running, to have overnight hygiene done by morning.
-
-Triggers:
-
-- "start sentry", "run sentry", "arm sentry", "sentry mode"
-- "let sentry watch this overnight", "keep this tidy overnight"
-- "start sentry hourly", "start sentry every <interval>" (sets the loop interval)
-
-Stop trigger (see Stop Sentry below):
-
-- "stop sentry", "stand down sentry", "sentry off"
-
-Sentry is deliberately *not* auto-armed. Running it in a project is a per-project grant (the =:COMMIT_AUTONOMY:= marker) plus a deliberate launch with Craig at the terminal for the entry gates.
-
-* Prerequisite — the autonomy ticket
-
-Sentry commits unattended. =commits.md= gates commits on Craig's approval, so sentry needs standing, per-project authorization to run at all. Before anything else, read the project's =.ai/notes.org= Workflow State block for:
-
-: :COMMIT_AUTONOMY: yes
-
-If the marker is absent or not =yes=, decline to start and name the marker:
-
-: Sentry needs ":COMMIT_AUTONOMY: yes" in .ai/notes.org Workflow State to run — it commits unattended. Add it to grant, or run the hygiene passes by hand.
-
-No half-running mode: a project without the grant doesn't run sentry's read-only passes either. The grant is one line away, so this is a deliberate opt-in, not a barrier.
-
-* Entry — interactive, with Craig present
-
-Craig types the sentry trigger, so the first moves run with him at the terminal. Do them in order; each gate that fails stops entry until Craig answers.
-
-1. *Autonomy ticket* — the prerequisite above. Absent → decline and stop.
-
-2. *Dirty-tree gate.* =git diff --quiet HEAD= (tracked modifications only; untracked and gitignored files never block — an inbox drop or scratch file is not in-progress work). If the tracked tree is dirty, describe what's dirty and offer, inline-numbered per =interaction.md=:
-
- 1. Finish the job — commit the in-progress work first (recommended if it's a coherent unit)
- 2. Stash it — =git stash= and start sentry on a clean tree
- 3. Roll back named changes — discard specific files (names them)
-
- Wait for an answer. Sentry can't start unattended from a dirty state; that's the point.
-
-3. *Green-suite gate.* Run the project's full suite (=make test=, or the project's equivalent — detect it). Read the output. If anything is red, describe the failures and offer to investigate before arming. The loop starts only on a green baseline, because every unattended fire measures itself against "did I break this?" and a pre-existing red poisons that check.
-
-4. *Prior sentry branch.* =git branch --list 'sentry/*'=. An unmerged =sentry/*= branch from a previous night means the morning review didn't happen. Surface it and offer to squash-merge or delete it now (Craig is present); don't stack a second sentry branch on the first.
-
-5. *Reconcile the project branch.* Fetch and fast-forward-only against upstream — the same reconcile =startup= runs:
-
- : git fetch --all --prune
- : git rev-list --left-right --count @{u}...HEAD
-
- Zero-behind → continue. Behind-only and clean → =git merge --ff-only @{u}=. Diverged → surface to Craig (he's present); don't auto-resolve.
-
-6. *Create the daily branch.* From HEAD:
-
- : git switch -c "sentry/$(date +%F)-$(uname -n)"
-
- The host suffix (=uname -n=) stops a same-date collision between the two daily drivers. The working tree now sits on this branch overnight — the launch hands the repo to sentry until the morning merge. Reclaiming it mid-night means stopping sentry first (see Stop Sentry). Note the Emacs buffer-revert caveat to Craig if he has the repo open: files change on disk under him overnight, so buffers want reverting after the morning merge (see =emacs.md=).
-
-7. *Arm the loop.* Start =/loop= at the interval (default hourly; Craig's "every <interval>" phrase overrides) with the per-fire body being one sentry fire (the Pass Runner below). Confirm the arming in one line: interval, branch name, project.
-
-* The lock model
-
-Two locks, both served by =.ai/scripts/agent-lock= (names only; the helper owns the paths, which live on tmpfs under =$XDG_RUNTIME_DIR/agent-locks/=, host-local and cleared on reboot).
-
-*Single-runner lock* (=sentry-<project>=, where =<project>= is the repo-root basename: =basename "$(git rev-parse --show-toplevel)"= — the same derivation =wrap-it-up.org='s guard uses, so the two agree on the lock name). Each fire acquires it at fire start and releases it at fire end, and refreshes it between passes (the heartbeat, so a live fire's lock never ages past one pass). If =/loop= fires again while a previous fire still holds it, the new fire's acquire fails and the fire skips with one digest line — no two fires run at once. The bounded wait is short (a few seconds); a live fire means defer, not queue.
-
-*Roam-write lock* (=roam-write=). A pass that edits a file under =~/org/roam= acquires it, runs =capture-guard --wait= (the human-capture layer stays underneath), edits the working tree, triggers =systemctl --user start roam-sync.service=, and releases. The lock spans only edit-plus-trigger. Sentry never runs =git= against =~/org/roam= — roam-sync stays the repo's only committer (the 2026-06-24 one-git-owner rule). Pass 1's =pull --ff-only= is the sole, read-only exception.
-
-Every reclaim of a stale lock surfaces in the digest — the helper prints the reclaim note, and the fire records it. A reclaim during a genuinely slow pass is possible, so it's never silent.
-
-* The Pass Runner — one contract per pass
-
-Each fire, after acquiring the single-runner lock and verifying branch state (below), walks the pass list in order. Every pass follows the same four-step contract:
-
-1. *Probe* — a cheap existence check for the pass's target (named per pass below). Absent → the pass is one skip line in the digest and nothing more. This is what makes the pass list portable: passes self-activate where their target exists and stay silent elsewhere, with zero per-project configuration.
-
-2. *Work* — run the pass under the unattended contract. Quick, solo, already-agreed mechanical actions execute. Anything destructive or requiring judgment does *not* execute — it appends to the morning-approval queue (what, why, the exact command or edit that fires on approval). A pass runs fully or not at all; there is no reduced-form pass.
-
-3. *Session-context entry* — append the pass's digest line to the =session-context.org= Session Log (path resolved via =.ai/scripts/session-context-path=). This precedes the commit so a crash between them still leaves the trail.
-
-4. *Commit* — if the pass wrote to disk, commit it: =chore(sentry): <pass> — <what changed>=. One commit per writing pass. A probe-skip or a no-op pass writes nothing and commits nothing.
-
-Between passes, refresh the single-runner lock (=agent-lock refresh sentry-<project>=) — the heartbeat.
-
-** Branch-state verification (fire start, before the passes)
-
-After acquiring the lock, confirm the fire is safe to run:
-
-- *On the right branch* — HEAD is =sentry/<today>-<host>=. If the loop was armed on a prior day and crossed midnight, the branch keeps the arming date; that's fine, morning teardown handles it. If HEAD is somehow *not* a sentry branch (an interrupted stop, a manual checkout), skip the whole fire with a digest line rather than committing onto main.
-- *Clean of foreign changes* — =git diff --quiet HEAD= excluding the spine set (=session-context.org= / =session-context.d/=, resolved via =session-context-path=). Sentry's own spine writes must not trip this; a genuinely unexpected dirty tree (something outside the spine changed and wasn't committed by a prior pass) poisons the fire — skip it with a digest line, the next fire retries.
-
-* Unattended safety — skip, never degrade
-
-With no one at the terminal, any unsafe state makes the affected scope skip with one digest line, and the next fire retries. Unsafe states and their scope:
-
-- *Unexpected dirty tree* (non-spine) → skip the whole fire.
-- *Lost or un-acquirable single-runner lock* → skip the fire (another fire holds it, or the helper is missing).
-- *A pass's own precondition unmet* (its probe fails, or a dependency is dirty) → skip that pass only.
-- *Red suite at fire-end* (see below) → the commits stay on the branch, flagged in the digest for morning review; the fire doesn't roll back.
-
-Skips are never silent and never partial. A pass line in the digest means the pass fully ran; a skip line names why it didn't.
-
-** Multi-day stall notification
-
-An unmerged prior =sentry/*= branch at fire start (the morning review never happened) skips the fire. After the *second consecutive* fire skipped for this reason, send one persistent desktop notification naming the project and branch:
-
-: sentry stalled: <branch> unmerged — merge or delete to resume
-
-Then repeat at most daily. Persistent notify matches the paging convention — it stays on screen until dismissed. A multi-day stall never stays silent.
-
-* The pass list (v1)
-
-In order. Each names its detection probe. A pass whose probe fails is one skip line.
-
-1. *Roam pull* — =git -C ~/org/roam pull --ff-only=. Probe: =~/org/roam= is a git clone. Skipped when the roam tree is dirty (roam-sync owns that case) or the clone is absent. Read-only and ff-only — the one narrow exception to "don't touch roam git," so later passes read a fresh tree.
-
-2. *Inbox zero* — run =inbox.org= roam mode under the no-approvals contract: quick+solo+agreed items execute, shared-asset and convention proposals park (prepared diff, =VERIFY= task, sender reply) in the approval queue. Edits to =~/org/roam/inbox.org= take the roam-write lock + =capture-guard=. Probe: the roam clone or a project =inbox/= exists. Tidying the shared roam inbox is allowed from *any* project session, work included — it's housekeeping on a shared resource, not a durable KB-node write, so the work-denylist doesn't gate it (=knowledge-base.md=). Never park it as a cross-project boundary crossing.
-
-3. *Triage intake — mail and messenger sources excluded.* Run =triage-intake.org=, loading only the non-mail, non-messenger source plugins (calendar, PR/ticketing sources). The mail and messenger plugins — cmail, any Gmail variant, Telegram, Signal, chat DMs — are never loaded by a sentry fire: Craig ruled 2026-07-21 that sentry doesn't check email or messengers (a manual "triage intake" still scans everything). Probe: at least one non-mail, non-messenger plugin present for this project. Destructive actions (deleting, archiving, sending) queue; they never fire unattended.
-
-4. *Todo cleanup* — the =clean-todo.org= mechanics (hygiene pass + =--archive-done= + =--convert-subtasks=). Probe: a root =todo.org=.
-
-5. *Task audit* — =task-audit.org=. Probe: a root =todo.org=. Priority regrades and consolidations queue for review; factual staleness fixes that are unambiguous execute.
-
-6. *Working-files hygiene* — flag =working/<slug>/= directories whose backing task is closed (a filing candidate per =working-files.md=). Probe: a =working/= directory exists. The filing itself queues (it's a judgment move).
-
-7. *Spec status board* — the =docs-lifecycle= grep for spec keywords, surfacing any =DOING= spec whose bound build parent is closed. Probe: =docs/specs/= exists.
-
-8. *Link integrity* — broken =file:= links in the project's org files, via =lint-org.el=. Probe: =lint-org.el= present. Report-only into the digest; no unattended rewrites.
-
-9. *Git health* — uncommitted drift, unpushed commits on other branches, stale branches, main-behind-origin. Probe: =.git=. Report into the digest.
-
-10. *Prep + symlink freshness* — stale daily-prep docs, broken symlinks. Probe: the prep dir / symlinks exist (work and home only, in practice).
-
-11. *Bug finding* — hunt for real bugs in the project's codebase: static analysis (=shellcheck= for shell, the project's linters and test suite for its languages), config sanity checks, plus one targeted code-reading area per fire — rotate the area across fires and name it in the digest, so coverage accumulates over a night instead of re-reading the same corner. Probe: the project carries a codebase (source under version control beyond org/tooling files). File each verified finding as a graded bug task in =todo.org= per the severity × frequency matrix (=todo-format.md=), deduped against existing tasks; an unverifiable suspicion is a digest line, not a task. Find, never fix unattended — a proposed fix or any remediation beyond the task filing queues for morning approval with its exact edit. (Added at Craig's order 2026-07-21, first dogfooded in dotfiles.)
-
-(KB lesson promotion — the proposal's eleventh pass — is deferred to vNext. An unattended judgment pass writing to the shared knowledge base waits until sentry has quiet weeks behind it and a designed detection heuristic. See the filed lesson-detection-heuristic task.)
-
-* Fire-end — conditional suite, then the digest commit
-
-After the passes:
-
-1. *Conditional suite run.* If any pass this fire modified files *outside* the org/spine set (a code-touching pass, rare but possible via fixtures), run the full suite once. A green run confirms the fire's commits are safe; a red run flags the digest for morning review — the commits stay on the branch (nothing is pushed, so the morning gate catches it). No per-pass suite runs: the entry run is the green baseline, and hourly per-commit runs would turn a seconds-long fire into minutes all night. Fires that only touched org/spine files skip this.
-
-2. *Digest commit.* Commit any accumulated spine writes in one sweep — =chore(sentry): digest — <date> <time> fire= — so even a read-only fire (all passes probe-skipped or no-op) leaves a clean tree. This is what lets the next fire's branch-state check see a clean, spine-excluded tree.
-
-3. *Release the single-runner lock.*
-
-* The digest and the approval queue
-
-*Digest.* Each fire appends its lines to the =session-context.org= Session Log (the spine the fire already writes), so it survives a crash, rides the session archive, and is on screen in the running session. One block per fire: the timestamp, then one line per pass (ran + what, or skipped + why), plus any lock reclaim notes.
-
-*Approval queue.* Destructive and judgment actions accumulate under one heading in the same file — =* Sentry approval queue (<date>)= — newest last. Each item carries three things: *what* (the action), *why* (what triggered it), and the *exact command or edit* that fires on approval. The morning review is Craig reading this heading top to bottom and running or discarding each item.
-
-* Morning teardown — Craig's, documented not automated
-
-Sentry never merges its own branch. In the morning Craig:
-
-1. Reviews the digest and the approval queue in =session-context.org=.
-2. Runs or discards each approval-queue item.
-3. Reviews the branch: =git log main..sentry/<date>-<host>= and the diff.
-4. Squash-merges what he wants (=git switch main && git merge --squash sentry/<date>-<host>=, then one clean commit) or cherry-picks selectively.
-5. Deletes the branch: =git branch -D sentry/<date>-<host>=.
-6. Reverts any Emacs buffers still showing the pre-merge on-disk state (=emacs.md= buffer-revert caveat).
-
-A bad night is discarded by deleting one branch — nothing reached main, nothing was pushed.
-
-* Stop Sentry
-
-Trigger: "stop sentry" (and synonyms above). Sentry owns its own shutdown:
-
-1. *Cancel the loop* — stop the =/loop= (=ScheduleWakeup= stop / the loop's stop path). No further fires.
-2. *Release the single-runner lock* if this context holds it.
-3. *Branch disposition* — offer, inline-numbered:
- 1. Squash-merge the day's branch into main now (walk the morning teardown steps 3-5 interactively)
- 2. Leave it named for later review (=sentry/<date>-<host>= stays; review at leisure)
-4. *Approval queue* — offer to walk the queued items now, or carry them (they stay under the heading for whenever Craig reviews).
-
-Stopping sentry is the only way to reclaim the working tree mid-night. The entry gate fronts the handoff; stop-sentry ends it.
-
-* Wrap-up interaction
-
-=wrap-it-up.org= refuses while sentry is live: it detects the single-runner lock (=agent-lock status sentry-<project>= → held) and stops with "sentry is active — say 'stop sentry' first." The shutdown logic lives here, not in wrap-up; wrap-up carries only the one guard.
-
-* Common Mistakes
-
-1. *Running without the =:COMMIT_AUTONOMY:= grant* — sentry commits unattended; the marker is the entry ticket, and its absence is a hard stop, not a degrade.
-2. *Starting from a dirty or red tree* — the entry gates exist because an unattended fire can't tell Craig's in-progress work from a regression. Answer the gate; don't bypass it.
-3. *Committing onto main* — every writing pass commits to the daily =sentry/*= branch. A fire that finds HEAD off the sentry branch skips rather than commits.
-4. *Running a =git= write against =~/org/roam=* — roam-sync is the only committer. Sentry edits the tree under the roam-write lock and triggers the sync; it never commits or pushes roam.
-5. *A per-pass suite run* — the suite runs at entry (baseline) and conditionally at fire-end (only when a pass touched non-org files). Hourly per-commit runs all night is the anti-pattern the suite policy exists to prevent.
-6. *Executing a judgment or destructive action unattended* — those queue for the morning with their exact command. The pass did its detection; Craig makes the call.
-7. *A silent skip* — every skip writes a digest line naming why. A missing pass with no line reads as "ran clean" when it didn't.
-8. *Degrading a pass to a reduced form* — a pass runs fully or skips. No half-passes.
-9. *Letting an unmerged branch stall silently* — after two consecutive unmerged-branch skips, the persistent desktop notify fires. Don't suppress it.
-10. *Merging sentry's branch automatically* — the morning teardown is Craig's. Sentry creates and commits; it never merges or deletes its own branch.
-
-* Living Document
-
-Sentry ships with ten mechanical passes and a deferred KB pass. The pass list, the interval default, and the queue-vs-execute line for each pass are the knobs most likely to move with dogfooding. Fold in what the live trial surfaces — a pass that queues too eagerly, a probe that misfires, a digest line that wants more detail. Refine as the signal arrives.
-
-* History
-
-Built 2026-07-19 from the sentry spec (=docs/specs/2026-07-14-sentry-workflow-spec.org=, ID f6c51f27-d7a2-4b63-9ff9-5ba005a66dfb) — 10 decisions and 12 review findings resolved before the build. Phase 1 shipped the =agent-lock= helper (commit =a8b6cf4=); this file is Phase 2, the engine. Phase 3 reconciles the roam writers (=inbox.org=, =knowledge-base.md=) to acquire the roam-write lock and adds the =wrap-it-up.org= guard.
diff --git a/inbox/PROCESSED-2026-07-20-2355-from-.dotfiles-kb-personal-roots-amendment-craig-s.org b/inbox/PROCESSED-2026-07-20-2355-from-.dotfiles-kb-personal-roots-amendment-craig-s.org
deleted file mode 100644
index d45abe6..0000000
--- a/inbox/PROCESSED-2026-07-20-2355-from-.dotfiles-kb-personal-roots-amendment-craig-s.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: KB personal-roots amendment (Craig's order, 2026-07-21, from
-#+SOURCE: from .dotfiles
-#+DATE: 2026-07-20 23:55:01 -0500
-
-KB personal-roots amendment (Craig's order, 2026-07-21, from the dotfiles session): add ~/.dotfiles to the personal-project roots in claude-rules/knowledge-base.md. Today the Writing section classifies personal as 'project root sits under ~/code/, ~/projects/, or ~/.emacs.d and is not denylisted', which makes ~/.dotfiles classify Unknown and blocks KB writes — tonight it couldn't promote the sentry pass-list rule, and the 2026-07-04 session hit the same wall with the xdg-desktop-portal Requisite=graphical-session.target gotcha. Dotfiles is a personal single-user repo (private cjennings.net remote), so Craig wants it KB-write-eligible. Suggested edit: extend the personal classification to '~/code/, ~/projects/, ~/.emacs.d, or ~/.dotfiles'. The startup KB probe and knowledge-base.md are the only places that enumerate the roots as far as we know — reconcile any other copy the rulesets session finds.
diff --git a/inbox/PROCESSED-2026-07-21-0006-from-org-drill-memory-sweep-handoff-2026-06-10-done-in.org b/inbox/PROCESSED-2026-07-21-0006-from-org-drill-memory-sweep-handoff-2026-06-10-done-in.org
deleted file mode 100644
index 340262a..0000000
--- a/inbox/PROCESSED-2026-07-21-0006-from-org-drill-memory-sweep-handoff-2026-06-10-done-in.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Memory-sweep handoff (2026-06-10) done in org-drill. Counts:
-#+SOURCE: from org-drill
-#+DATE: 2026-07-21 00:06:44 -0500
-
-Memory-sweep handoff (2026-06-10) done in org-drill. Counts: 0 promoted to KB / 1 kept local / 0 deleted. The single memory (no-markup-chat-output — never use code fences, bold, or backtick spans in chat) is cross-project, but its durable home is interaction.md rather than a KB node; a separate proposal to fold it into that rule follows in your inbox. Also processed your 2026-06-12 priority-scheme handoff: scheme section added to org-drill's todo.org (derived from existing usage, pending Craig's ratification). One deviation: no commit — org-drill gitignores todo.org per its code-project convention.
diff --git a/inbox/PROCESSED-2026-07-23-0241-from-.dotfiles-ack-from-dotfiles-both-amendments.org b/inbox/PROCESSED-2026-07-23-0241-from-.dotfiles-ack-from-dotfiles-both-amendments.org
deleted file mode 100644
index ffd2335..0000000
--- a/inbox/PROCESSED-2026-07-23-0241-from-.dotfiles-ack-from-dotfiles-both-amendments.org
+++ /dev/null
@@ -1,5 +0,0 @@
-#+TITLE: Ack from dotfiles: both amendments verified in the rulesets
-#+SOURCE: from .dotfiles
-#+DATE: 2026-07-23 02:41:58 -0500
-
-Ack from dotfiles: both amendments verified in the rulesets canonical. knowledge-base.md line 25 now lists ~/.dotfiles as a personal root, and claude-templates/.ai/workflows/sentry.org carries the amended overview line, the pass-3 mail/messenger exclusion, and pass 11 bug finding. Good call applying the sentry edits by hand instead of rsyncing my copy — I hadn't noticed my rewrite dropped the :TRIAGE_SOURCES: activation probe, and a straight copy would have taken the heartbeat/digest split out with it. I've updated the dotfiles memory to record that the canonical owns this now, so no local re-apply after a sync. Nothing needed back.
diff --git a/inbox/PROCESSED-2026-07-23-2127-from-home-rulesets-voice-correspondence-patterns.org b/inbox/PROCESSED-2026-07-23-2127-from-home-rulesets-voice-correspondence-patterns.org
deleted file mode 100644
index 72beba6..0000000
--- a/inbox/PROCESSED-2026-07-23-2127-from-home-rulesets-voice-correspondence-patterns.org
+++ /dev/null
@@ -1,85 +0,0 @@
-#+TITLE: Proposal — two correspondence patterns for the voice skill (prose mode)
-
-* What this is
-
-Craig taught two structural rules while I drafted a Signal reply for him on
-2026-07-23. They aren't in the voice skill yet. He asked whether they belong in
-=/voice personal=; I said no, because personal mode is publish artifacts only
-(commits, PR titles and bodies, PR review comments) and email and Signal are
-prose mode. Sending the proposal here since rulesets owns =voice/=.
-
-I did *not* edit =~/code/rulesets/voice/SKILL.md= from the home session. The
-=~/.claude/skills/voice= symlink points straight at the canonical, so a local
-"stopgap" edit would have been an unflagged write into rulesets' scope. Home
-carries a memory as its stopgap instead.
-
-* The two rules, as Craig stated them
-
-1. *Order by what matters most to the recipient*, not by what's easiest to
- answer or the order they wrote it. Their news outranks your logistics. A
- direct question they asked can sort *below* personal news they shared.
-2. *Group each topic into one paragraph.* Everything on a subject goes
- together rather than fragmenting across several paragraphs.
-
-* The worked case
-
-His sister sent a long catch-up: 30+ lbs lost, a deep from-scratch cooking run
-(sourdough, English muffins, tortillas, home-roasted deli meat), a mixer she's
-considering, and one direct question about whether he subscribes to MasterClass.
-
-My first draft opened with the MasterClass answer, because it was the only
-explicit question, and split the cooking material across three paragraphs.
-
-Craig reordered it: weight first, then one paragraph carrying the entire cooking
-thread, then MasterClass, then the personal close. His framing was "start with
-what would be the most important things to her."
-
-The lesson is that leading with the easy answer reads as transactional, and a
-topic split across paragraphs reads as a checklist rather than a person talking.
-
-* The conflict that needs resolving in the same edit
-
-Pattern #43 currently reads, in part:
-
-#+begin_quote
-Never merge short paragraphs into multi-sentence ones in a "clean prose" pass
-(corpus: 41-74% of Craig's paragraphs are exactly one sentence, depending on
-register).
-#+end_quote
-
-Rule 2 above is a merge instruction. Taken naively the two patterns contradict,
-and a future run gets whipsawed.
-
-They aren't actually in conflict, but the boundary has to be stated or the
-skill can't act on both:
-
-- *#43 governs an angle shift.* A one-sentence paragraph stands when the next
- thought moves to a different subject. Craig's openers and closers stay
- one-sentence, and they did in the final draft.
-- *The new rule governs one topic that got fragmented.* Three paragraphs all
- about cooking become one.
-
-Proposed formulation: same topic → one paragraph. New angle → new paragraph.
-Whichever way this is written, #43's "never merge" line needs a qualifier
-pointing at the new pattern, or it will keep reading as absolute.
-
-* Scope
-
-These govern *correspondence* (email, Signal, letters), which is narrower than
-prose mode's current surface. Prose mode also covers journals, working notes,
-and documents with no recipient, where "order by what matters to the recipient"
-has no referent. Worth deciding whether that's a tag on the two patterns, a
-sub-mode, or just a sentence in each rule.
-
-* What I'd suggest, but rulesets owns the call
-
-Two new prose-mode patterns, correspondence-scoped, plus a one-line qualifier on
-#43 naming the boundary. Numbering and the profile entries are yours. The
-=voice-profile.org= side wants the worked before/after above, since the
-reordering is the whole lesson and it doesn't survive as a rule line alone.
-
-* Provenance
-
-home session 2026-07-23, drafting a Signal reply to Craig's sister. Home holds a
-=correspondence-structure-rules= memory as its interim, marked as pending this
-proposal.
diff --git a/inbox/PROCESSED-2026-07-23-2132-from-home-rulesets-voice-correspondence-followup.org b/inbox/PROCESSED-2026-07-23-2132-from-home-rulesets-voice-correspondence-followup.org
deleted file mode 100644
index 1dfc788..0000000
--- a/inbox/PROCESSED-2026-07-23-2132-from-home-rulesets-voice-correspondence-followup.org
+++ /dev/null
@@ -1,102 +0,0 @@
-#+TITLE: Follow-up — better design for the correspondence patterns (supersedes the earlier proposal)
-
-* What this supersedes
-
-The 2026-07-23 21:27 handoff from home, =rulesets-voice-correspondence-patterns.org=.
-That one proposed *two* new prose-mode patterns and flagged a conflict with #43
-to be resolved. It asked the right question and proposed a worse answer. Craig
-and I worked it further the same evening. Take this design instead.
-
-* The reconciliation: there was no conflict
-
-I claimed rule 2 ("group each topic into one paragraph") contradicted #43
-("never merge short paragraphs"). It doesn't.
-
-#43 already carries the answer in the phrase *"when the next thought shifts
-angle."* The failure was reading "angle" at sentence granularity. Moving from
-her baking to the mixer to tortillas felt like three angles when I drafted it.
-It isn't. That's one topic with three facets. Moving from cooking to MasterClass
-is a real shift.
-
-So the fix is calibration, not a new competing rule: *angle means topic, not
-sentence.*
-
-Read that way the two rules are one rule seen from both sides. #43 protects the
-break *between* topics, which is where Craig's cadence actually lives. The
-grouping behavior fills in what happens *within* a topic, which #43 never
-specified and I filled in wrong.
-
-* The evidence is in the final draft
-
-Every one-sentence paragraph survived Craig's edit: the weight-loss opener, the
-MasterClass answer, the "I miss you and I love you" line, the closing ask for
-call times. Each is its own topic.
-
-The only merge was three paragraphs that were all cooking.
-
-So his edit didn't violate #43. It corrected my misreading of it. That's the
-strongest argument for folding this into #43 rather than adding a rule beside
-it: a pattern that has to be reconciled against its neighbor is a pattern that
-gets misapplied, and this one already was.
-
-* Proposed change (smaller than the first proposal)
-
-*One new pattern — recipient-priority ordering.* Correspondence-scoped, prose
-mode. Nothing in the skill covers it today.
-
-#+begin_quote
-In a reply, lead with what matters most to the recipient, not with what's
-easiest to answer or the order they wrote it. Their news outranks your
-logistics. A direct question they asked can sort below personal news they
-shared, because the news is what they care about.
-#+end_quote
-
-Scope note: this needs a recipient, so it applies to email, Signal, and letters.
-It has no referent in a journal, a working note, or a document addressed to
-nobody, all of which prose mode also covers. Worth a tag or a scope sentence.
-
-*One clarification to #43 — not a new pattern.* Three edits to the existing rule:
-
-1. State that "shifts angle" means shifts *topic*.
-2. Add that a single topic consolidates into one paragraph even when each
- sentence in it is a complete thought.
-3. Keep the never-merge line, re-framed as a protection *across topic
- boundaries*, which is what it was always defending.
-
-* The guard (Craig's number)
-
-Within-topic consolidation must not produce a wall. Craig set the ceiling at
-*about 5 to 6 sentences*, after which find a natural break and split there.
-
-Honest note on the worked example below: the cooking paragraph as sent runs
-seven sentences, slightly over its own guard. Craig called it an exception
-rather than re-cutting a message that had already gone out. The guard is the
-rule, that paragraph is a hair over it, and both facts belong in the record.
-
-* Worked before/after (for voice-profile.org)
-
-Her message: 30+ lbs lost, a deep from-scratch cooking run (sourdough, English
-muffins, tortillas, home-roasted deli meat), a mixer she's considering, and one
-direct question about whether Craig subscribes to MasterClass.
-
-*My first draft* opened with the MasterClass answer, because it was the only
-explicit question, and split the cooking material across three paragraphs.
-
-*Craig's order:* weight, then one paragraph carrying the entire cooking thread,
-then MasterClass, then the personal close. His framing: "start with what would
-be the most important things to her."
-
-The lesson: leading with the easy answer reads as transactional, and one topic
-split across paragraphs reads as a checklist rather than a person talking.
-
-* Mode confirmation
-
-Prose, confirmed with Craig. Personal mode stays publish artifacts only
-(commits, PR titles and bodies, PR review comments). Email and Signal are prose.
-
-* Provenance
-
-home session 2026-07-23, drafting and sending a Signal reply to Craig's sister.
-Home holds a =correspondence-structure-rules= memory as its interim; it will
-want updating to match this design once rulesets lands it, since it currently
-describes the earlier two-pattern framing.