aboutsummaryrefslogtreecommitdiff
path: root/claude-templates
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-23 21:22:43 -0400
committerCraig Jennings <c@cjennings.net>2026-06-23 21:22:43 -0400
commit3da27255a6e0b2fdac9e124820aae567fa353644 (patch)
tree04ddde9d2582d82baae3bde0383ab4a168760595 /claude-templates
parent36262858461711bcb104896007a513691113fee8 (diff)
downloadrulesets-3da27255a6e0b2fdac9e124820aae567fa353644.tar.gz
rulesets-3da27255a6e0b2fdac9e124820aae567fa353644.zip
feat(inbox-zero): sweep empty roam entries on triage
An aborted org-capture can leave a heading with no title and no body (just stars and maybe a TODO keyword). Those belong to nobody and were piling up in the shared roam inbox. inbox-zero now buckets them as empty in Phase B and removes them in Phase D in the same edit as the claimed items. An empties-only run still enters Phase D and commits, so the sweep runs on every triage, not only when this project owns something. A heading with any title or body is never touched.
Diffstat (limited to 'claude-templates')
-rw-r--r--claude-templates/.ai/workflows/inbox-zero.org15
1 files changed, 8 insertions, 7 deletions
diff --git a/claude-templates/.ai/workflows/inbox-zero.org b/claude-templates/.ai/workflows/inbox-zero.org
index 5979ec0..231f721 100644
--- a/claude-templates/.ai/workflows/inbox-zero.org
+++ b/claude-templates/.ai/workflows/inbox-zero.org
@@ -55,8 +55,9 @@ Use the project root basename plus its common aliases (=.emacs.d= ↔ =emacs=, a
- *claimed* — prefixed for this project
- *foreign* — prefixed for another project → leave
- *unowned* — no project prefix
-4. *Summarize the scan* (Craig's requirement, every scan): report the total item count in the inbox, then the count that appears related to this project. "Appears related" is the union of claimed items (exact prefix) and any unowned item whose topic plainly concerns this project's domain (a content judgment, surfaced as a candidate, never auto-claimed). Foreign-prefixed items are not "related" — they belong to their owner.
-5. If both claimed and related-unowned are empty, report the total and stop (the common case for most wraps).
+ - *empty* — a heading with no title and no body: just stars, optionally a =TODO=/keyword, and whitespace (e.g. =** =, =** TODO =, =*** TODO =). These are aborted or accidental captures, owned by nobody, and safe to delete regardless of project. A heading with any title text or any body content is never empty.
+4. *Summarize the scan* (Craig's requirement, every scan): report the total item count in the inbox, then the count that appears related to this project. "Appears related" is the union of claimed items (exact prefix) and any unowned item whose topic plainly concerns this project's domain (a content judgment, surfaced as a candidate, never auto-claimed). Foreign-prefixed items are not "related" — they belong to their owner. Note the empty count separately.
+5. If claimed, related-unowned, *and* empty are all absent, report the total and stop (the common case for most wraps). Empty entries on their own are enough to enter Phase D — the cleanup runs even when this project owns nothing else in the inbox, since empties belong to nobody and removing them is what "check the inbox" should always do.
* Phase C — File each claimed roam item into todo.org
@@ -77,12 +78,12 @@ The roam inbox lives in a git repo (=~/org/roam=, auto-synced by the =roam-sync=
- *On-demand / interactive run* → stop and surface: "You have a live org-capture session open against the roam inbox (=<buffer>=) — finalize it (=C-c C-c=) or abort it (=C-c C-k=) and I'll continue." Re-run the guard and resume once it returns clean.
- *Wrap-up sub-step* → don't block the wrap. Skip the roam reconcile for this run and surface one line: "Skipped roam-inbox reconcile — a live org-capture is open against it; claimed items stay and get caught next run." The items were already filed into =todo.org= in Phase C, so the next inbox-zero run's Phase C status-check drops the duplicates and its Phase D removes them from the roam inbox — the skip self-heals, it doesn't lose anything.
2. *Pull first* (=git -C ~/org/roam pull --ff-only=). If it can't fast-forward (dirty tree, divergence), surface and stop. Don't auto-stash, auto-merge, or force. Resolve before removing items.
-3. *Remove only the claimed items.* Never touch foreign or unowned items.
-4. *Commit the roam repo as its own commit* (separate from any project wrap commit): =chore(inbox): route <project> tasks to <project>/todo.org=. Push, or leave for the =roam-sync= timer. Surface a blocked push; don't force.
+3. *Remove the claimed items and the empty entries.* Never touch foreign or unowned (titled) items. Empty entries (Phase B's =empty= bucket — a heading with no title and no body) are removed on every triage regardless of who would own a titled version, since an aborted capture belongs to nobody. The claimed-item removal and the empty sweep happen in the same edit.
+4. *Commit the roam repo as its own commit* (separate from any project wrap commit). Subject by what changed: =chore(inbox): route <project> tasks to <project>/todo.org= when items were claimed, =chore(inbox): drop empty entries= when the run only swept empties, or both clauses when it did both. Push, or leave for the =roam-sync= timer. Surface a blocked push; don't force.
* Phase E — Surface
-Report: local project inbox disposition first (processed count and whether it is clear), then roam disposition: moved (with their new priorities and tags), folded, dropped-as-done. Then the residue: foreign items (left for their owners, count only) and unowned items (count plus the headings that appear related to this project, for manual claim or prefix). Same "summarize what we kept" shape.
+Report: local project inbox disposition first (processed count and whether it is clear), then roam disposition: moved (with their new priorities and tags), folded, dropped-as-done, and empty entries swept (count). Then the residue: foreign items (left for their owners, count only) and unowned items (count plus the headings that appear related to this project, for manual claim or prefix). Same "summarize what we kept" shape.
If triaging this batch surfaced a durable, cross-project fact (a reference pointer worth keeping, a pattern worth recording), consider writing it to the agent KB as one =:agent:= node (see =knowledge-base.md=; personal projects only). Skip silently when nothing durable came up — never pad an empty run with a KB line.
@@ -91,14 +92,14 @@ If triaging this batch surfaced a durable, cross-project fact (a reference point
- No project-local =inbox/= and no =~/org/roam/inbox.org= → silent no-op.
- Project-local =inbox/= exists but has no pending handoffs → continue to roam scan.
- No =~/org/roam/inbox.org= after the local inbox check → report the local inbox disposition and stop.
-- No claimed and no related-unowned roam items → report the total, stop.
+- No claimed, no related-unowned, and no empty roam entries → report the total, stop.
- Roam pull blocked → surface, stop before editing.
* Caller integration
** Startup (read-only nudge)
-Startup already checks the project-local =inbox/= via =inbox-status= and processes it through =process-inbox.org= when needed. It also reads =~/org/roam/inbox.org= and produces the roam scan summary; Phase C surfaces one line: "Roam inbox: N items total, M appear related to this project — say 'inbox zero' to file them." Offered as one of the priority options. Startup never auto-files roam items; it counts and offers.
+Startup already checks the project-local =inbox/= via =inbox-status= and processes it through =process-inbox.org= when needed. It also reads =~/org/roam/inbox.org= and produces the roam scan summary; Phase C surfaces one line: "Roam inbox: N items total, M appear related to this project (K empty entries to sweep) — say 'inbox zero' to file them." Offered as one of the priority options. The empty count rides along so a clean-up-only run still gets offered. Startup never auto-files or auto-sweeps roam items; it counts and offers (the read-only nudge never edits, so empties are reported, not removed, until a real triage runs).
** Wrap-up (Step 3 sub-step)