diff options
Diffstat (limited to '.ai/workflows')
44 files changed, 102 insertions, 62 deletions
diff --git a/.ai/workflows/INDEX.org b/.ai/workflows/INDEX.org index 88721ed..b031dbe 100644 --- a/.ai/workflows/INDEX.org +++ b/.ai/workflows/INDEX.org @@ -1,5 +1,5 @@ #+TITLE: Workflow Index -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-04-25 * Purpose @@ -110,8 +110,8 @@ This index must list every =.org= file in =.ai/workflows/= except this one and e - Situational triggers: "broadcast the <event> to all projects", "broadcast that <situation>", "let every project know I'll be away ..." - =flashcard-review.org= — review an org-drill flashcard file, restructure cards to question-form headings (no answer hints), audit content accuracy against project source-of-truth via subagent, rewrite source preserving SRS state, regenerate the Anki =.apkg= to =~/sync/phone/anki/=. Person cards use "Who is X? Tell me about their Y."; talking-points cards stay as-is. Script behavior: =flashcard-to-anki.py= strips =:PROPERTIES:= drawers + =SCHEDULED:= / =DEADLINE:= planning lines from Anki output. - Triggers: "review the flashcards", "update the flashcards", "review the drill deck", "update the drill deck", "refresh the Anki cards", "let's run the flashcard-review workflow" -- =page-me.org= — set a timed notification. - - Triggers: anything containing the word "page" used as a verb ("page me", "page me in 10 minutes", "page me at 3pm") +- =page-me.org= — set a timed notification (desktop =notify=; phone via =agent-page= when Craig is away). + - Triggers: anything containing the word "page" used as a verb ("page me", "page me in 10 minutes", "page me at 3pm", "page my phone") - =status-check.org= — proactive long-running-job updates. - Triggers: "keep me posted on this", "provide status checks on this job", "let me know when it's done", "monitor this for me". Auto: any job estimated 10+ min. - =create-workflow.org= — define a new workflow. diff --git a/.ai/workflows/add-calendar-event.org b/.ai/workflows/add-calendar-event.org index 2650fb7..5dd6c42 100644 --- a/.ai/workflows/add-calendar-event.org +++ b/.ai/workflows/add-calendar-event.org @@ -1,5 +1,5 @@ #+TITLE: Add Calendar Event Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-02-01 * Overview diff --git a/.ai/workflows/broadcast.org b/.ai/workflows/broadcast.org index 60e9ed1..cc14f00 100644 --- a/.ai/workflows/broadcast.org +++ b/.ai/workflows/broadcast.org @@ -1,5 +1,5 @@ #+TITLE: Broadcast Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-29 * Overview diff --git a/.ai/workflows/clean-todo.org b/.ai/workflows/clean-todo.org index a1b2af5..48d3084 100644 --- a/.ai/workflows/clean-todo.org +++ b/.ai/workflows/clean-todo.org @@ -1,5 +1,5 @@ #+TITLE: Clean-Todo Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-11 * Overview diff --git a/.ai/workflows/code-quality.org b/.ai/workflows/code-quality.org index 2406f4c..3ac3e9d 100644 --- a/.ai/workflows/code-quality.org +++ b/.ai/workflows/code-quality.org @@ -1,5 +1,5 @@ #+TITLE: Code-Quality Sweep Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-28 * Overview diff --git a/.ai/workflows/daily-prep.org b/.ai/workflows/daily-prep.org index b6989e7..3103bc7 100644 --- a/.ai/workflows/daily-prep.org +++ b/.ai/workflows/daily-prep.org @@ -1,5 +1,5 @@ #+TITLE: Daily Prep Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-11 * Overview diff --git a/.ai/workflows/delete-calendar-event.org b/.ai/workflows/delete-calendar-event.org index 5bb92a1..7de0086 100644 --- a/.ai/workflows/delete-calendar-event.org +++ b/.ai/workflows/delete-calendar-event.org @@ -1,5 +1,5 @@ #+TITLE: Delete Calendar Event Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-02-01 * Overview diff --git a/.ai/workflows/edit-calendar-event.org b/.ai/workflows/edit-calendar-event.org index 662f0b4..27a9dd3 100644 --- a/.ai/workflows/edit-calendar-event.org +++ b/.ai/workflows/edit-calendar-event.org @@ -1,5 +1,5 @@ #+TITLE: Edit Calendar Event Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-02-01 * Overview diff --git a/.ai/workflows/email-assembly.org b/.ai/workflows/email-assembly.org index 003459c..699dbc0 100644 --- a/.ai/workflows/email-assembly.org +++ b/.ai/workflows/email-assembly.org @@ -1,5 +1,5 @@ #+TITLE: Email Assembly Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-01-29 * Overview diff --git a/.ai/workflows/extract-email.org b/.ai/workflows/extract-email.org index 3a70bea..c68bafe 100644 --- a/.ai/workflows/extract-email.org +++ b/.ai/workflows/extract-email.org @@ -1,5 +1,5 @@ #+TITLE: Extract Email Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-02-06 * Overview diff --git a/.ai/workflows/find-email.org b/.ai/workflows/find-email.org index 0ef9615..d71ed3e 100644 --- a/.ai/workflows/find-email.org +++ b/.ai/workflows/find-email.org @@ -1,5 +1,5 @@ #+TITLE: Find Email Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-02-01 * Overview diff --git a/.ai/workflows/first-session.org b/.ai/workflows/first-session.org index 60118a2..147026f 100644 --- a/.ai/workflows/first-session.org +++ b/.ai/workflows/first-session.org @@ -1,5 +1,5 @@ #+TITLE: First Session Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings Run this workflow on the first Claude Code session for a new project. It establishes the git/.ai policy, orients Claude to the diff --git a/.ai/workflows/flashcard-review.org b/.ai/workflows/flashcard-review.org index 31027b3..09af348 100644 --- a/.ai/workflows/flashcard-review.org +++ b/.ai/workflows/flashcard-review.org @@ -1,5 +1,5 @@ #+TITLE: Drill Deck Review Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-30 * Overview diff --git a/.ai/workflows/helper-mode.org b/.ai/workflows/helper-mode.org index cdec200..a6acfa7 100644 --- a/.ai/workflows/helper-mode.org +++ b/.ai/workflows/helper-mode.org @@ -1,5 +1,5 @@ #+TITLE: Helper Mode Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-15 * Overview diff --git a/.ai/workflows/inbox.org b/.ai/workflows/inbox.org index acfd11d..3bd9335 100644 --- a/.ai/workflows/inbox.org +++ b/.ai/workflows/inbox.org @@ -1,5 +1,5 @@ #+TITLE: Inbox Workflow (Engine) -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-23 * Overview diff --git a/.ai/workflows/journal-entry.org b/.ai/workflows/journal-entry.org index 3f476a7..c70dfe8 100644 --- a/.ai/workflows/journal-entry.org +++ b/.ai/workflows/journal-entry.org @@ -1,5 +1,5 @@ #+TITLE: Journal Entry Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2025-11-07 * Overview diff --git a/.ai/workflows/meeting-prep.org b/.ai/workflows/meeting-prep.org index 162ae30..563328b 100644 --- a/.ai/workflows/meeting-prep.org +++ b/.ai/workflows/meeting-prep.org @@ -1,5 +1,5 @@ #+TITLE: Meeting-Prep Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-10 * Overview diff --git a/.ai/workflows/meeting-prep.pre-wire.org b/.ai/workflows/meeting-prep.pre-wire.org index 6a156c0..3e27c2a 100644 --- a/.ai/workflows/meeting-prep.pre-wire.org +++ b/.ai/workflows/meeting-prep.pre-wire.org @@ -1,5 +1,5 @@ #+TITLE: Meeting-Prep — Pre-Wire Method (supporting doc) -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-10 Supporting document for the [[file:meeting-prep.org][meeting-prep workflow]]'s Phase 3.5. The workflow carries the condensed, in-flow version of pre-wiring; this file is the full Manager Tools method, kept beside the workflow (same name + =.pre-wire= suffix) so it travels with the workflow. Source casts: "How to Prewire a Meeting" (2007) and "Peer Prewire" (2015). diff --git a/.ai/workflows/no-approvals.org b/.ai/workflows/no-approvals.org index 9e1c894..5f54b96 100644 --- a/.ai/workflows/no-approvals.org +++ b/.ai/workflows/no-approvals.org @@ -1,5 +1,5 @@ #+TITLE: No-Approvals Mode -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-28 * Overview diff --git a/.ai/workflows/open-tasks.org b/.ai/workflows/open-tasks.org index 02a0847..205d95c 100644 --- a/.ai/workflows/open-tasks.org +++ b/.ai/workflows/open-tasks.org @@ -1,5 +1,5 @@ #+TITLE: Open Tasks Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-04-25 * Overview diff --git a/.ai/workflows/page-me.org b/.ai/workflows/page-me.org index 8069830..bfa92c6 100644 --- a/.ai/workflows/page-me.org +++ b/.ai/workflows/page-me.org @@ -1,5 +1,5 @@ #+TITLE: Page Me Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-01-31 #+UPDATED: 2026-02-27 @@ -113,6 +113,19 @@ notify info "Page" "Your message here" --persist The =--persist= flag keeps the notification on screen until manually dismissed. All page-me notifications should use =--persist= by default. +** Paging Craig's phone (away from the machine) + +The timed =notify= alarm above is the desktop channel. When Craig is away from the machine (or asks to be paged "on my phone"), use the agent pager instead — a Signal push to his phone from any machine or agent runtime: + +#+begin_src bash +agent-page "Build finished — ready for your eyes" + +# Timed phone page: same at-daemon pattern, different channel +echo "agent-page 'Meeting starts in 5'" | at 3:25pm +#+end_src + +Channel selection and the pager's mechanics live in protocols.org "Paging Craig — the agent pager". When in doubt, fire both: the desktop notification persists for whenever he returns, the phone push reaches him now. + ** Managing Alarms #+begin_src bash diff --git a/.ai/workflows/process-meeting-transcript.org b/.ai/workflows/process-meeting-transcript.org index 4dd340f..d0806ad 100644 --- a/.ai/workflows/process-meeting-transcript.org +++ b/.ai/workflows/process-meeting-transcript.org @@ -1,5 +1,5 @@ #+TITLE: Process Meeting Transcript Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-02-03 * Overview @@ -10,16 +10,16 @@ This workflow defines the process for processing meeting recordings from start t Trigger this workflow when: - Craig says "process the transcript" or "process the recording" or similar -- New recording files (.mkv) appear in ~/sync/recordings/ after meetings +- New recording files (.mkv, .m4a, or .flac) appear in ~/sync/recordings/ after meetings - Craig wants to process meeting recordings into labeled transcripts * Prerequisites -- Recording file(s) exist in ~/sync/recordings/ (*.mkv) +- Recording file(s) exist in ~/sync/recordings/ (*.mkv, *.m4a, or *.flac) - Calendar files available at ~/.emacs.d/data/*cal.org for meeting titles - AssemblyAI transcription script at ~/.emacs.d/scripts/assemblyai-transcribe - AssemblyAI API key stored in ~/.authinfo.gpg (machine api.assemblyai.com) -- ffmpeg available for audio extraction +- ffmpeg available for audio extraction (video .mkv only; .m4a and .flac skip extraction) * The Workflow @@ -43,13 +43,13 @@ Classification is per recording, not per session — a single run can carry this Find and match recording files with calendar events. *Run sub-steps 1 and 3 (recording list + calendar dump) as a single parallel batch* — they're independent. Sub-step 2 (parse timestamps) and sub-step 4 (matching) work from those two outputs in-memory, so they're sequential after the batch. -1. **List recordings:** Find all recording files in ~/sync/recordings/ (video .mkv or audio-only .m4a) +1. **List recordings:** Find all recording files in ~/sync/recordings/ (video .mkv or audio-only .m4a / .flac) #+begin_src bash - ls -la ~/sync/recordings/*.mkv ~/sync/recordings/*.m4a 2>/dev/null + ls -la ~/sync/recordings/*.mkv ~/sync/recordings/*.m4a ~/sync/recordings/*.flac 2>/dev/null #+end_src - Audio-only recordings (.m4a) are used when no screen content is expected. These skip Step 3 (audio extraction) since they're already in a transcribable format. + Audio-only recordings (.m4a or lossless .flac) are used when no screen content is expected. These skip Step 3 (audio extraction) since they're already in a transcribable format. FLAC is the recorder's current audio format — its frames are self-contained, so an interrupted recording still decodes. -2. **Extract timestamps:** Parse date/time from each filename (format: YYYY-MM-DD-HH-MM-SS.mkv or .m4a) +2. **Extract timestamps:** Parse date/time from each filename (format: YYYY-MM-DD-HH-MM-SS.mkv, .m4a, or .flac) 3. **Match with calendar:** Check ~/.emacs.d/data/*cal.org for meetings at those times #+begin_src bash @@ -74,7 +74,7 @@ Per =cross-project.md=: transcribe and label here, then deliver the *labeled tra ** Step 3: Extract Audio (video recordings only) -*Skip this step for .m4a files* — they are already audio and can go directly to transcription. +*Skip this step for .m4a and .flac files* — they are already audio and can go directly to transcription. For .mkv video recordings, extract audio for transcription: @@ -96,11 +96,11 @@ Output: /tmp/FILENAME.m4a (temporary, deleted after transcription) #+begin_src bash # For .mkv files (audio was extracted to /tmp/): ~/.emacs.d/scripts/assemblyai-transcribe /tmp/FILENAME.m4a > ~/sync/recordings/FILENAME.txt - # For .m4a files (transcribe directly): + # For .m4a or .flac files (transcribe directly — AssemblyAI accepts both natively): ~/.emacs.d/scripts/assemblyai-transcribe ~/sync/recordings/FILENAME.m4a > ~/sync/recordings/FILENAME.txt #+end_src -2. **Clean up:** Delete intermediate .m4a file after successful transcription (only for .mkv extractions — do NOT delete original .m4a recordings) +2. **Clean up:** Delete intermediate .m4a file after successful transcription (only for .mkv extractions — do NOT delete original .m4a or .flac recordings) #+begin_src bash rm /tmp/FILENAME.m4a #+end_src @@ -181,13 +181,13 @@ Present the speaker identification table to Craig for confirmation: ** Step 9: Copy Recording to Meetings Folder -1. Ensure engagement meetings folder exists and patterns are in .gitignore (~*/meetings/*.mkv~ and ~*/meetings/*.m4a~) +1. Ensure engagement meetings folder exists and patterns are in .gitignore (~*/meetings/*.mkv~, ~*/meetings/*.m4a~, and ~*/meetings/*.flac~) 2. Copy the recording file with descriptive name: #+begin_src bash # Video recordings: cp ~/sync/recordings/YYYY-MM-DD-HH-MM-SS.mkv {engagement}/meetings/YYYY-MM-DD_HH-MM-meeting-name.mkv - # Audio-only recordings: + # Audio-only recordings (.m4a or .flac — copy with the original extension): cp ~/sync/recordings/YYYY-MM-DD-HH-MM-SS.m4a {engagement}/meetings/YYYY-MM-DD_HH-MM-meeting-name.m4a #+end_src Example: ~deepsat/meetings/2026-02-03_11-02-standup-ipm-grooming.mkv~ diff --git a/.ai/workflows/read-calendar-events.org b/.ai/workflows/read-calendar-events.org index be66bf4..5eac529 100644 --- a/.ai/workflows/read-calendar-events.org +++ b/.ai/workflows/read-calendar-events.org @@ -1,5 +1,5 @@ #+TITLE: Read Calendar Events Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-02-01 * Overview diff --git a/.ai/workflows/readability-audit.org b/.ai/workflows/readability-audit.org index 8223a03..90ad366 100644 --- a/.ai/workflows/readability-audit.org +++ b/.ai/workflows/readability-audit.org @@ -1,5 +1,5 @@ #+TITLE: Readability Audit Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-28 * Overview diff --git a/.ai/workflows/rename-artifact.org b/.ai/workflows/rename-artifact.org index 7b9f15b..a8d1246 100644 --- a/.ai/workflows/rename-artifact.org +++ b/.ai/workflows/rename-artifact.org @@ -1,5 +1,5 @@ #+TITLE: Rename an .ai Artifact -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-31 * Summary diff --git a/.ai/workflows/send-email.org b/.ai/workflows/send-email.org index 065f925..82d2286 100644 --- a/.ai/workflows/send-email.org +++ b/.ai/workflows/send-email.org @@ -1,5 +1,5 @@ #+TITLE: Email Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-01-26 * Overview diff --git a/.ai/workflows/session-harvest.org b/.ai/workflows/session-harvest.org index c48d689..54a7c09 100644 --- a/.ai/workflows/session-harvest.org +++ b/.ai/workflows/session-harvest.org @@ -1,5 +1,5 @@ #+TITLE: Session-Harvest Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-11 * Overview diff --git a/.ai/workflows/spec-create.org b/.ai/workflows/spec-create.org index 1249181..39758a0 100644 --- a/.ai/workflows/spec-create.org +++ b/.ai/workflows/spec-create.org @@ -1,5 +1,5 @@ #+TITLE: Spec-Create Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-09 * Overview @@ -47,6 +47,8 @@ Capture, in this order: ** Phase 2 — Design, alternatives, decisions 1. *Design* — overview first, then detail. Write the reasoning as *prose, not bullet dumps* — prose exposes weak logic that bullets let you hide. Use bullets only for genuinely enumerable lists. When the thing has an interface, use the *two-altitude* split (Rust RFC): explain it once for a user/caller, once for an implementer. + + *Non-trivial UI.* When the deliverable is a real UI (a panel, a multi-control surface, an interacting visual layout — not a single dialog, a CLI flag, or a one-off prompt), the design isn't settled on the page. Run the research → ~5 distinct working-prototype directions → iterate-one-to-final process in =claude-rules/ui-prototyping.md= before treating the UI design as done, and add a =Prototype iterations= subsection under the spec's status heading linking every iteration (final linked in the design section). A UI design decision moves to =DONE= only once it's been seen working in a prototype. 2. *Alternatives considered* — the load-bearing section authors skip and reviewers need most. For each option, force a why-not with the MADR grammar: "Good, because… / Bad, because… / Neutral, because…". Even one rejected option, with the reason, beats presenting one path as inevitable. 3. *Decisions* — capture each real choice as an org =TODO= task carrying an inline mini-ADR (Nygard's spine): - The heading is =** TODO <Decision name>=. It flips to =DONE= when the decision-maker agrees with the call; until then it stays =TODO=. diff --git a/.ai/workflows/spec-review.org b/.ai/workflows/spec-review.org index d4998eb..0da8e65 100644 --- a/.ai/workflows/spec-review.org +++ b/.ai/workflows/spec-review.org @@ -134,6 +134,7 @@ Work the spec against these. Each is a source of concrete findings, not a box to - *Security & privacy.* API keys safe? Debug logs leaking secrets or private issue text? Confirmations before mutating shared workspace objects? Personal vs shared distinguished? Local files holding sensitive descriptions/comments? Anything to redact from messages/logs? Any work-tracker integration may handle private company data. - *UX & accessibility.* Discoverable commands? Recoverable mistakes? Prompts ordered to the task? Safe, useful defaults? Informative-not-noisy status messages? Does the UI avoid implying unsupported actions are supported? Match the upstream product's permissions/concepts? Are customizations named in user language, with clear defaults and docstrings? For Emacs packages, command names, completion candidates, buffer layout, defcustom names, and message wording *are* the UX. - *Operational-panel UI traps.* Applies when the spec covers a user-facing panel, dialog, or control surface; skip otherwise. Lists that mix saved, current, and generated items must name each item's source. Refresh or scan actions must not gate data that could be shown immediately. Add-forms must not ask the user to retype values the system already discovered. Destructive confirmations read in future tense before the action and verified-result tense after it. Diagnostics, performance, logging, and repair affordances are reviewed as one coherent flow before extra pages or buttons are added. A popup launched from a bar, tray, or tool surface should visually belong to that launcher. (Promoted from archsetup's Waybar network-panel review, 2026-06-30.) +- *Prototype process for non-trivial UI.* Applies when the deliverable is a real UI (a panel, a multi-control surface, an interacting visual layout — not a single dialog or CLI flag); skip otherwise. Verify the =claude-rules/ui-prototyping.md= process ran: category research is cited in Goals/Design, the final prototype is linked in the design section, a =Prototype iterations= subsection under the status heading lists every pass, and each UI design decision is backed by a prototype it was seen working in rather than asserted on the page. A non-trivial-UI spec with decisions but no prototype evidence is a =:blocking:= finding. - *Test strategy and coverage.* Characterization tests before behavior changes? Pure functions to unit-test? API responses needing fixtures? Command flows needing stubs? Regression tests for prior bugs? Boundary/error cases? What's covered elsewhere and shouldn't be re-tested? Which existing tests must change? How is coverage generated, summarized, and used to find untested/refactor-worthy code? Prefer tests that lock contracts: representation shape, query compilation, sync no-op, conflict refusal, pagination, dirty-buffer protection, log redaction, and long-running/slow-operation behavior via fakes rather than flaky live dependencies. - *Observability & operations.* How does a user see what the package is doing? Progress messages for long ops? Useful, safe debug logging? Are logs structured enough to isolate issues from a bug report? Are commands provided to inspect/clear caches, test connectivity, diagnose backends/tools, copy redacted debug info, or reproduce command invocations? How are terminal states discovered: completion, failure, partial success, stalled/hung, cancelled, cleanup-unverified, and "needs user action"? Does the product notify only when useful, avoid noisy success spam, and keep non-success states visible until acknowledged? For generated org files, headers should often carry source, filter/view name, refresh time, count, truncation state. - *Comparable-product sentiment.* When there are obvious adjacent products, research what users love and hate about them from official docs plus current community reports. Do not cargo-cult their feature set; translate findings into the spec's scope. For each loved behavior, say whether the spec provides it, intentionally omits it, or defers it. For each hated behavior, say whether the spec avoids, resolves, inherits, or accepts it. diff --git a/.ai/workflows/startup.org b/.ai/workflows/startup.org index 4e3d417..929d482 100644 --- a/.ai/workflows/startup.org +++ b/.ai/workflows/startup.org @@ -1,5 +1,5 @@ #+TITLE: Startup Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-04-25 * Summary diff --git a/.ai/workflows/status-check.org b/.ai/workflows/status-check.org index efff16d..4a9972c 100644 --- a/.ai/workflows/status-check.org +++ b/.ai/workflows/status-check.org @@ -1,5 +1,5 @@ #+TITLE: Status Check Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-02-02 * Overview diff --git a/.ai/workflows/summarize-emails.org b/.ai/workflows/summarize-emails.org index 6ac5e6f..c9c7001 100644 --- a/.ai/workflows/summarize-emails.org +++ b/.ai/workflows/summarize-emails.org @@ -1,5 +1,5 @@ #+TITLE: Summarize Emails Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-02-14 * Overview diff --git a/.ai/workflows/suspend.org b/.ai/workflows/suspend.org index 1c16bb9..3691f60 100644 --- a/.ai/workflows/suspend.org +++ b/.ai/workflows/suspend.org @@ -1,5 +1,5 @@ #+TITLE: Session Suspend Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-28 * Overview diff --git a/.ai/workflows/sync-email.org b/.ai/workflows/sync-email.org index 52a7caf..863b400 100644 --- a/.ai/workflows/sync-email.org +++ b/.ai/workflows/sync-email.org @@ -1,5 +1,5 @@ #+TITLE: Sync Email Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-02-01 * Overview diff --git a/.ai/workflows/task-audit.org b/.ai/workflows/task-audit.org index 7d2b758..aa50176 100644 --- a/.ai/workflows/task-audit.org +++ b/.ai/workflows/task-audit.org @@ -1,5 +1,5 @@ #+TITLE: Task Audit Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-22 * Overview diff --git a/.ai/workflows/task-review.org b/.ai/workflows/task-review.org index ba1571a..7ea2e8e 100644 --- a/.ai/workflows/task-review.org +++ b/.ai/workflows/task-review.org @@ -1,5 +1,5 @@ #+TITLE: Task Review Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-20 * Overview @@ -92,7 +92,7 @@ Set =:LAST_REVIEWED:= to today's date (from above) in the task's =:PROPERTIES:= Body... #+end_example -The exact date string matters: =task-review-staleness.sh= and the wrap-up health check both parse =:LAST_REVIEWED: YYYY-MM-DD=. +Format: =:LAST_REVIEWED:= takes a bare ISO date (=2026-05-20=) or an org-native inactive timestamp (=[2026-05-20 Tue]=, matching the =CREATED:=/=CLOSED:= cookies beside it); =task-review-staleness.sh= and the wrap-up health check normalize both to the date. A value that is neither is a data error — the staleness script warns loudly to stderr (naming the file, line, and value) and leaves the task out of the stale count rather than silently reporting a freshly-reviewed task as never-reviewed. Stamp a clean date and the warning never fires. *** Killing a task diff --git a/.ai/workflows/triage-intake.cmail.org b/.ai/workflows/triage-intake.cmail.org index d818c72..8d8abfb 100644 --- a/.ai/workflows/triage-intake.cmail.org +++ b/.ai/workflows/triage-intake.cmail.org @@ -1,5 +1,5 @@ #+TITLE: Triage Intake — cmail (Proton) Source -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-26 # Source plugin for the triage-intake engine. See triage-intake.org for the diff --git a/.ai/workflows/triage-intake.github-prs.org b/.ai/workflows/triage-intake.github-prs.org index c1bc796..644421c 100644 --- a/.ai/workflows/triage-intake.github-prs.org +++ b/.ai/workflows/triage-intake.github-prs.org @@ -1,5 +1,5 @@ #+TITLE: Triage Intake — Personal GitHub PRs Source -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-26 # Source plugin for the triage-intake engine. See triage-intake.org for the diff --git a/.ai/workflows/triage-intake.org b/.ai/workflows/triage-intake.org index a5a3bda..fde67a7 100644 --- a/.ai/workflows/triage-intake.org +++ b/.ai/workflows/triage-intake.org @@ -1,5 +1,5 @@ #+TITLE: Triage Intake Workflow (Engine) -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-01 * Summary @@ -414,7 +414,7 @@ The sentinel is checked into git, but git tracks content, not mtime — so an mt 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 telegram plugin's failure path points at this rule. +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 signal-cli account lock while another client held it, and the failure looked identical to a quiet source. Failures now lead the summary in a ⚠ SCAN FAILED banner; the telegram plugin's failure path points at this rule. **** 2026-05-26: Refactor into engine + source plugins Split the monolithic workflow into a source-agnostic engine (this file) and per-source plugins named =triage-intake.<source>.org=. The engine carries the anchor/sentinel logic, the four-bucket model, the Phase A-D orchestration, the todo.org persistence convention, and the exit criteria. Each source's scan/classify/render/action knowledge moved to its own plugin. General plugins (personal-gmail, personal-calendar, cmail, github-prs) live in =.ai/workflows/= and are template-synced; project-specific plugins (a work project's Linear, work Gmail, work Slack, enterprise PRs) live in the project's =.ai/project-workflows/= and are never synced. Phase 0 globs *both* directories — the loud requirement, because missing the project dir silently halves the sweep. Naming convention: first dot is the engine/plugin boundary, deeper dots reserved for sub-adapters. This removed all DeepSat/Linear specifics from the engine; they become work-project plugins. diff --git a/.ai/workflows/triage-intake.personal-calendar.org b/.ai/workflows/triage-intake.personal-calendar.org index bf7d543..b5ee67a 100644 --- a/.ai/workflows/triage-intake.personal-calendar.org +++ b/.ai/workflows/triage-intake.personal-calendar.org @@ -1,5 +1,5 @@ #+TITLE: Triage Intake — Personal Calendar Source -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-26 # Source plugin for the triage-intake engine. See triage-intake.org for the diff --git a/.ai/workflows/triage-intake.personal-gmail.org b/.ai/workflows/triage-intake.personal-gmail.org index aa0554d..7fb1231 100644 --- a/.ai/workflows/triage-intake.personal-gmail.org +++ b/.ai/workflows/triage-intake.personal-gmail.org @@ -1,5 +1,5 @@ #+TITLE: Triage Intake — Personal Gmail Source -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-05-26 # Source plugin for the triage-intake engine. See triage-intake.org for the @@ -21,10 +21,29 @@ Personal Gmail unread in the inbox since the anchor: 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=. +⚠ *Express every anchor cutoff as the literal UNIX epoch* — =after:1784177122= and =before:1784177122= for the same anchor, never the =YYYY/MM/DD= form. This governs *both* anchored queries: the scan above and the backlog-residue probe below. They must meet at the same instant or mail falls between them permanently. Gmail's day-resolution operators fail two different ways: =after:YYYY/MM/DD HH:MM:SS= is not valid syntax at all — 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 — while =before:YYYY/MM/DD= is valid but excludes the named day entirely, so pairing it with a second-resolution scan leaves the whole anchor day covered by neither query. The engine supplies =<anchor-epoch>= because this source declares =ANCHOR: epoch=. + +The rule binds the *anchor* windows only. The date-slice walk below deliberately uses =before:<oldest-full-day-seen>= at day resolution — safe there because consecutive slices overlap and get deduped by message id. ⚠ *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-epoch>" maxResults=5 +#+end_src + +The cutoff is the epoch, matching the scan's =after:<anchor-epoch>= — see the epoch rule above. + +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. Shipped with a day-resolution cutoff that hid the entire anchor day; fixed to epoch 2026-07-16 after a home sweep reported the backlog clear while two July-15 messages sat unread.) + ** Classify Bias: *trash-leaning* — personal Gmail is high noise volume. diff --git a/.ai/workflows/triage-intake.telegram.org b/.ai/workflows/triage-intake.telegram.org index 9caa4e1..5039a8b 100644 --- a/.ai/workflows/triage-intake.telegram.org +++ b/.ai/workflows/triage-intake.telegram.org @@ -1,5 +1,5 @@ #+TITLE: Triage Intake — Telegram Source -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-06-09 # Source plugin for the triage-intake engine. See triage-intake.org for the diff --git a/.ai/workflows/work-the-backlog.org b/.ai/workflows/work-the-backlog.org index b0666e7..090841d 100644 --- a/.ai/workflows/work-the-backlog.org +++ b/.ai/workflows/work-the-backlog.org @@ -1,5 +1,5 @@ #+TITLE: Work the Backlog -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-07-02 * Overview @@ -152,7 +152,7 @@ With paging on, fire one page when the set is done or the cap is hit — end-of- notify info "Page" "<project>: <N> done, <M> remaining — <one-line summary>" --persist #+end_src -=--persist= keeps it on screen until dismissed, and =info= is the page-me urgency convention (persistent but never crash-scary). The page fires when the set completes *or* the cap stops the run — either way exactly once. The message carries the project name, the completed count, and the remaining count (with skipped tasks noted in the run summary) so Craig can confirm ready and name the next project in one reply. There is no separate page-signal call — =notify= is the paging surface. +=--persist= keeps it on screen until dismissed, and =info= is the page-me urgency convention (persistent but never crash-scary). The page fires when the set completes *or* the cap stops the run — either way exactly once. The message carries the project name, the completed count, and the remaining count (with skipped tasks noted in the run summary) so Craig can confirm ready and name the next project in one reply. =notify= is the desktop paging surface; a run that expects Craig to be away also fires =agent-page= with the same message (the Signal phone channel — protocols.org "Paging Craig — the agent pager"). * Metrics diff --git a/.ai/workflows/wrap-it-up.org b/.ai/workflows/wrap-it-up.org index d0c4e75..5ce88a5 100644 --- a/.ai/workflows/wrap-it-up.org +++ b/.ai/workflows/wrap-it-up.org @@ -1,5 +1,5 @@ #+TITLE: Session Wrap-Up Workflow -#+AUTHOR: Craig Jennings & Claude +#+AUTHOR: Craig Jennings #+DATE: 2026-04-20 * Overview @@ -202,9 +202,14 @@ else followups=".ai/lint-followups.org" fi [ -f todo.org ] && emacs --batch -q -l .ai/scripts/lint-org.el \ - --followups-file="$followups" todo.org + --fix --followups-file="$followups" todo.org #+end_src +The =--fix= flag is required for the writes: lint-org's CLI default is +report-only (a linter reports, it doesn't write), and this wrap-up pass is +the deliberate exception that applies fixes — its diff rides the wrap-up +commit for review. + =lint-org= runs =org-lint= over =todo.org=, auto-applies four mechanical categories (=item-number= counters, bare =#+begin_src= → =#+begin_example=, multi-line planning-info merged onto one line, =**X.**= → =*X.*=), and |
