diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-11 18:22:12 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-11 18:22:12 -0500 |
| commit | 647bc6119a19b9d8dc1d1860e6b253c1390b1e9b (patch) | |
| tree | 69e3b6a0a1728af26eedc1df8751f74143f57caa | |
| parent | f9fce0dae795d8e17bb79d967da152c15077345c (diff) | |
| download | rulesets-647bc6119a19b9d8dc1d1860e6b253c1390b1e9b.tar.gz rulesets-647bc6119a19b9d8dc1d1860e6b253c1390b1e9b.zip | |
feat(triage): deltas-only sweep summaries and silent telegram dev groups
A sweep now reports only what changed: a new invite, a moved or cancelled event, a message needing attention. Unchanged sources get no block. An all-quiet sweep renders as one line. Scan failures keep their loud banner and the suggested-actions line stays when actions are queued.
Telegram dev-community group traffic (zed, GNU Emacs, Kitty) is dropped from sweep reports entirely unless Craig asks. Real DMs from known contacts still surface as Action.
| -rw-r--r-- | .ai/workflows/triage-intake.org | 28 | ||||
| -rw-r--r-- | .ai/workflows/triage-intake.telegram.org | 20 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/triage-intake.org | 28 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/triage-intake.telegram.org | 20 |
4 files changed, 74 insertions, 22 deletions
diff --git a/.ai/workflows/triage-intake.org b/.ai/workflows/triage-intake.org index 173f051..b804de1 100644 --- a/.ai/workflows/triage-intake.org +++ b/.ai/workflows/triage-intake.org @@ -104,10 +104,20 @@ One markdown summary surfaced inline to Craig. Order: A failed scan is never folded into "quiet." Quiet means the scan ran and found nothing; a failure means the sweep is blind on that channel, and the reader must know which. The same applies to a precondition skip the user hasn't standing-approved (e.g. a messaging client that needs a temporary server spin-up): run the lifecycle or report the failure — don't silently narrow the sweep. 1. *Top signals to act on* — bullet list of 3-7 items, ordered by urgency, *Action only*. Each bullet links to the source (permalink, thread URL, PR number). -2. *Per-source breakdown* — one short section per *loaded* source, in =ORDER=, using that plugin's =Render= shape: Action items detailed, FYI items as a short list, Noise as a tally only ("Noise: 12 trash candidates, 4 keep, 0 starred"). -3. *Suggested actions* — explicit list of state changes Craig could take this run (trash these N messages, mark-read these M, star this Action item, respond to this invite, merge PRs #X and #Y, etc.). +2. *Per-source breakdown* — one short section per loaded source *that has changes*, in =ORDER=, using that plugin's =Render= shape: Action items detailed, FYI items as a short list, Noise as a tally only ("Noise: 12 trash candidates, 4 keep, 0 starred"). +3. *Suggested actions* — explicit list of state changes Craig could take this run (trash these N messages, mark-read these M, star this Action item, respond to this invite, merge PRs #X and #Y, etc.). This line stays whenever there are queued actions, regardless of how quiet the sweep was. -Format target: scannable in 30 seconds, full read in 2 minutes. Don't pad. If a source returned zero items, write "Calendar — quiet" or "PRs — nothing new since 14:30 yesterday." +*Deltas only.* The summary reports what *changed* since the anchor: a new invite, a new/moved/cancelled calendar event, a new message needing attention. A source with no changes gets no block — no "Calendar — quiet", no "PRs — nothing new" roll-call. A sweep where nothing changed anywhere renders as a single line: + +#+begin_example +17:39 sweep: no changes +#+end_example + +(Craig, 2026-06-11: "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?") + +Scan failures are the standing exception: a failed or skipped scan always renders loudly per point 0 above and is never folded into the no-change line — "no changes" is a claim about channels the sweep could actually see. + +Format target: scannable in 30 seconds, full read in 2 minutes. Don't pad. **** Sub-step: write each Action item into =todo.org= as its own =:quick:= task @@ -253,7 +263,13 @@ If both fail, fall through to the resolution order above (prep doc → session f ** Output Template -The summary follows this shape (omit any source that genuinely returned nothing; render one block per *loaded* source in =ORDER=, using each plugin's =Render= shape): +The summary follows this shape (deltas only: a source with no changes gets no block; when *nothing* changed anywhere, the whole summary collapses to the one-line form below — plus any scan-failure banners and the suggested-actions line if actions are queued): + +#+begin_example +17:39 sweep: no changes +#+end_example + +When there are changes, render one block per changed source in =ORDER=, using each plugin's =Render= shape: #+begin_example **Anchor:** <previous run timestamp> → now (<elapsed> elapsed) @@ -287,6 +303,7 @@ Order matters: top-signals first because that's what Craig reads in 30 seconds b 7. *Running this alongside daily-prep.* Daily-prep already does this as Phase 3 — don't duplicate. 8. *Mixing Action and FYI in the top-signals list.* Top signals = Action only. FYI lives in the per-source detail. 9. *Reporting a failed or skipped scan as a quiet source.* A hung receive, a dead daemon, or a skipped spin-up looks identical to "no new messages" in the output unless it's flagged. The 2026-06-10 sweep shipped with Signal silently missing because the scan hung on an account lock. Failures lead the summary, in their own banner line. +10. *Rendering a per-source quiet roll-call.* "Calendar — quiet" / "PRs — nothing new" lines on every silent source bury the one change that matters and pad a no-change sweep into a report. Deltas only: changed sources get blocks, unchanged sources get nothing, and an all-quiet sweep is one line (Craig's 2026-06-11 ruling in Phase C). * History / Design Notes @@ -306,6 +323,9 @@ Gap-window bug: a run had Phase A fire at 13:35 and the sentinel set at 15:04, s **** 2026-05-13: Move the sentinel from mtime to content (cross-machine survivability) The sentinel is checked into git, but git tracks content, not mtime — so an mtime anchor is per-machine. Fix: write the captured epoch into the sentinel's content (=EPOCH ISO-8601=), read with =awk 'NR==1 {print $1}'=, mtime as back-compat fallback. +**** 2026-06-11: Deltas-only reporting (Phase C + Output Template + Common Mistake 10) +Craig, via the work project's same-day handoff: "we only need to report if anything's changed when we do triage intake." Sweep summaries report deltas only — a new invite, a new/moved/cancelled event, a new message needing attention. Unchanged sources get no block (the "Calendar — quiet" roll-call is retired), and an all-quiet sweep renders as a single "HH:MM sweep: no changes" line. Failures keep their loud banner (never folded into the no-change line) and the suggested-actions line stays when actions are queued. Same ruling: the telegram plugin's dev-community group traffic is dropped from reports entirely unless Craig asks (see that plugin's 2026-06-11 note). + **** 2026-06-10: Loud failure surfacing (Phase C item 0 + Common Mistake 9) Craig: "highlight any failures in daily triage loudly. I get important communication from all these channels." Trigger: the 2026-06-10 sweep shipped with Signal silently missing — a standalone receive hung on the account lock while the signel daemon owned it, and the failure looked identical to a quiet source. Failures now lead the summary in a ⚠ SCAN FAILED banner; the signal and telegram plugins' failure paths point at this rule. diff --git a/.ai/workflows/triage-intake.telegram.org b/.ai/workflows/triage-intake.telegram.org index a318f12..9caa4e1 100644 --- a/.ai/workflows/triage-intake.telegram.org +++ b/.ai/workflows/triage-intake.telegram.org @@ -200,9 +200,11 @@ work contact is Action, full stop. unsolicited, no prior thread. - =Deleted Account-NNNN= threads, blank-title chats, bot channels (=Z-Library Official=), Telegram's own =✔️Telegram= service notices. -- *FYI:* unread in dev-community groups Craig follows — =GNU Emacs=, =zed=, - =Kitty=, and similar. Worth awareness, no response owed. List the group + - unread count; don't enumerate the messages. +- *Noise-keep (never reported):* unread in dev-community groups Craig follows — + =GNU Emacs=, =zed=, =Kitty=, and similar. Skipped in sweep reports entirely — + not even a name + count line — unless Craig specifically asks about them + (Craig's ruling, 2026-06-11, via the work project's handoff). Leave them + unread; they're reading material, not signal. - *Action:* a real text/voice/media message from a *known personal contact* in an existing one-to-one thread — an explicit ask, a question, a reply owed. On a spam-heavy account these are rare; when one appears, surface it prominently @@ -217,13 +219,17 @@ groups + 0 real personal DMs. Expect most sweeps to look like this — a clean #+begin_example **Telegram — N unread chats (M real after filtering).** <one-line summary> - Action: <real DMs from known contacts, sender + gist, reply owed called out> -- FYI: <dev groups — name + count> - Noise: K joined-Telegram notices, J spam/bot/deleted (tally only) #+end_example -Omit the block if there are zero unread chats. If the only unread is -join-notices + spam + groups (the common case), render the one-line summary plus -the Noise tally and skip Action entirely. +Dev-community group traffic never appears here — no FYI line, no name + count — +unless Craig asks for it in that sweep (2026-06-11 ruling). Real DMs from known +contacts still surface as Action. + +Omit the block entirely when there's nothing but group traffic, join-notices, +and spam — under the engine's deltas-only rule that's a no-change source. Render +the block only when there's an Action item or a Noise tally worth a state-change +suggestion (e.g. a trash batch). ** Actions diff --git a/claude-templates/.ai/workflows/triage-intake.org b/claude-templates/.ai/workflows/triage-intake.org index 173f051..b804de1 100644 --- a/claude-templates/.ai/workflows/triage-intake.org +++ b/claude-templates/.ai/workflows/triage-intake.org @@ -104,10 +104,20 @@ One markdown summary surfaced inline to Craig. Order: A failed scan is never folded into "quiet." Quiet means the scan ran and found nothing; a failure means the sweep is blind on that channel, and the reader must know which. The same applies to a precondition skip the user hasn't standing-approved (e.g. a messaging client that needs a temporary server spin-up): run the lifecycle or report the failure — don't silently narrow the sweep. 1. *Top signals to act on* — bullet list of 3-7 items, ordered by urgency, *Action only*. Each bullet links to the source (permalink, thread URL, PR number). -2. *Per-source breakdown* — one short section per *loaded* source, in =ORDER=, using that plugin's =Render= shape: Action items detailed, FYI items as a short list, Noise as a tally only ("Noise: 12 trash candidates, 4 keep, 0 starred"). -3. *Suggested actions* — explicit list of state changes Craig could take this run (trash these N messages, mark-read these M, star this Action item, respond to this invite, merge PRs #X and #Y, etc.). +2. *Per-source breakdown* — one short section per loaded source *that has changes*, in =ORDER=, using that plugin's =Render= shape: Action items detailed, FYI items as a short list, Noise as a tally only ("Noise: 12 trash candidates, 4 keep, 0 starred"). +3. *Suggested actions* — explicit list of state changes Craig could take this run (trash these N messages, mark-read these M, star this Action item, respond to this invite, merge PRs #X and #Y, etc.). This line stays whenever there are queued actions, regardless of how quiet the sweep was. -Format target: scannable in 30 seconds, full read in 2 minutes. Don't pad. If a source returned zero items, write "Calendar — quiet" or "PRs — nothing new since 14:30 yesterday." +*Deltas only.* The summary reports what *changed* since the anchor: a new invite, a new/moved/cancelled calendar event, a new message needing attention. A source with no changes gets no block — no "Calendar — quiet", no "PRs — nothing new" roll-call. A sweep where nothing changed anywhere renders as a single line: + +#+begin_example +17:39 sweep: no changes +#+end_example + +(Craig, 2026-06-11: "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?") + +Scan failures are the standing exception: a failed or skipped scan always renders loudly per point 0 above and is never folded into the no-change line — "no changes" is a claim about channels the sweep could actually see. + +Format target: scannable in 30 seconds, full read in 2 minutes. Don't pad. **** Sub-step: write each Action item into =todo.org= as its own =:quick:= task @@ -253,7 +263,13 @@ If both fail, fall through to the resolution order above (prep doc → session f ** Output Template -The summary follows this shape (omit any source that genuinely returned nothing; render one block per *loaded* source in =ORDER=, using each plugin's =Render= shape): +The summary follows this shape (deltas only: a source with no changes gets no block; when *nothing* changed anywhere, the whole summary collapses to the one-line form below — plus any scan-failure banners and the suggested-actions line if actions are queued): + +#+begin_example +17:39 sweep: no changes +#+end_example + +When there are changes, render one block per changed source in =ORDER=, using each plugin's =Render= shape: #+begin_example **Anchor:** <previous run timestamp> → now (<elapsed> elapsed) @@ -287,6 +303,7 @@ Order matters: top-signals first because that's what Craig reads in 30 seconds b 7. *Running this alongside daily-prep.* Daily-prep already does this as Phase 3 — don't duplicate. 8. *Mixing Action and FYI in the top-signals list.* Top signals = Action only. FYI lives in the per-source detail. 9. *Reporting a failed or skipped scan as a quiet source.* A hung receive, a dead daemon, or a skipped spin-up looks identical to "no new messages" in the output unless it's flagged. The 2026-06-10 sweep shipped with Signal silently missing because the scan hung on an account lock. Failures lead the summary, in their own banner line. +10. *Rendering a per-source quiet roll-call.* "Calendar — quiet" / "PRs — nothing new" lines on every silent source bury the one change that matters and pad a no-change sweep into a report. Deltas only: changed sources get blocks, unchanged sources get nothing, and an all-quiet sweep is one line (Craig's 2026-06-11 ruling in Phase C). * History / Design Notes @@ -306,6 +323,9 @@ Gap-window bug: a run had Phase A fire at 13:35 and the sentinel set at 15:04, s **** 2026-05-13: Move the sentinel from mtime to content (cross-machine survivability) The sentinel is checked into git, but git tracks content, not mtime — so an mtime anchor is per-machine. Fix: write the captured epoch into the sentinel's content (=EPOCH ISO-8601=), read with =awk 'NR==1 {print $1}'=, mtime as back-compat fallback. +**** 2026-06-11: Deltas-only reporting (Phase C + Output Template + Common Mistake 10) +Craig, via the work project's same-day handoff: "we only need to report if anything's changed when we do triage intake." Sweep summaries report deltas only — a new invite, a new/moved/cancelled event, a new message needing attention. Unchanged sources get no block (the "Calendar — quiet" roll-call is retired), and an all-quiet sweep renders as a single "HH:MM sweep: no changes" line. Failures keep their loud banner (never folded into the no-change line) and the suggested-actions line stays when actions are queued. Same ruling: the telegram plugin's dev-community group traffic is dropped from reports entirely unless Craig asks (see that plugin's 2026-06-11 note). + **** 2026-06-10: Loud failure surfacing (Phase C item 0 + Common Mistake 9) Craig: "highlight any failures in daily triage loudly. I get important communication from all these channels." Trigger: the 2026-06-10 sweep shipped with Signal silently missing — a standalone receive hung on the account lock while the signel daemon owned it, and the failure looked identical to a quiet source. Failures now lead the summary in a ⚠ SCAN FAILED banner; the signal and telegram plugins' failure paths point at this rule. diff --git a/claude-templates/.ai/workflows/triage-intake.telegram.org b/claude-templates/.ai/workflows/triage-intake.telegram.org index a318f12..9caa4e1 100644 --- a/claude-templates/.ai/workflows/triage-intake.telegram.org +++ b/claude-templates/.ai/workflows/triage-intake.telegram.org @@ -200,9 +200,11 @@ work contact is Action, full stop. unsolicited, no prior thread. - =Deleted Account-NNNN= threads, blank-title chats, bot channels (=Z-Library Official=), Telegram's own =✔️Telegram= service notices. -- *FYI:* unread in dev-community groups Craig follows — =GNU Emacs=, =zed=, - =Kitty=, and similar. Worth awareness, no response owed. List the group + - unread count; don't enumerate the messages. +- *Noise-keep (never reported):* unread in dev-community groups Craig follows — + =GNU Emacs=, =zed=, =Kitty=, and similar. Skipped in sweep reports entirely — + not even a name + count line — unless Craig specifically asks about them + (Craig's ruling, 2026-06-11, via the work project's handoff). Leave them + unread; they're reading material, not signal. - *Action:* a real text/voice/media message from a *known personal contact* in an existing one-to-one thread — an explicit ask, a question, a reply owed. On a spam-heavy account these are rare; when one appears, surface it prominently @@ -217,13 +219,17 @@ groups + 0 real personal DMs. Expect most sweeps to look like this — a clean #+begin_example **Telegram — N unread chats (M real after filtering).** <one-line summary> - Action: <real DMs from known contacts, sender + gist, reply owed called out> -- FYI: <dev groups — name + count> - Noise: K joined-Telegram notices, J spam/bot/deleted (tally only) #+end_example -Omit the block if there are zero unread chats. If the only unread is -join-notices + spam + groups (the common case), render the one-line summary plus -the Noise tally and skip Action entirely. +Dev-community group traffic never appears here — no FYI line, no name + count — +unless Craig asks for it in that sweep (2026-06-11 ruling). Real DMs from known +contacts still surface as Action. + +Omit the block entirely when there's nothing but group traffic, join-notices, +and spam — under the engine's deltas-only rule that's a no-change source. Render +the block only when there's an Action item or a Noise tally worth a state-change +suggestion (e.g. a trash batch). ** Actions |
