diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-29 14:51:53 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-29 14:51:53 -0500 |
| commit | 664bf01ceaccf730cb636463cc8587cd1d966192 (patch) | |
| tree | e964f6c88d986454c5a2acfc99dfb55964fbba2b /.ai/workflows/page-signal.org | |
| parent | c3cf9a592ea6779ad59f0d79577e29777fce49f6 (diff) | |
| download | rulesets-664bf01ceaccf730cb636463cc8587cd1d966192.tar.gz rulesets-664bf01ceaccf730cb636463cc8587cd1d966192.zip | |
feat(signal): page-signal CLI wrapper + workflows + cross-project broadcast helper
Three coupled additions ship together.
claude-templates/bin/page-signal is a bash wrapper around signal-cli
send. It defaults to --note-to-self for safety. The wrapper supports
--file for attachments, --to <+number> for outbound (explicit per
call, no defaults, no batch), --quiet, and --json. Exit codes: 0
sent, 1 signal-cli failure, 2 usage error, 3 signal-cli not
installed.
claude-templates/.ai/workflows/page-signal.org carries the
discrimination rules and safety rails. When desktop notify covers it,
don't reach for Signal. Long-running task completion is the canonical
case. Outbound to other contacts requires explicit Craig instruction
per send. A known-limitation note covers the current notification
gap. signal-cli registered on Craig's primary number means messages
don't fire notifications until the pending Google Voice registration
lands.
claude-templates/.ai/workflows/cross-project-broadcast.org and its
helper cross-project-broadcast.py fan out a single message file to
every AI project's inbox in one operation. Discovery is
fingerprint-based: any directory under ~/code, ~/projects, ~/.emacs.d
with both .ai/protocols.org and a top-level inbox/ is broadcastable.
Senders are auto-excluded. Verified discovery against 23
broadcastable targets.
Makefile's install target gains a general bin/ loop. The previous
version hardcoded bin/ai. The new version iterates over every
executable under claude-templates/bin/ and symlinks each into
~/.local/bin/. install-hooks (existing Claude hook installer) is
unchanged. install-githooks (sync-check pre-commit hook setup, added
earlier today) is unchanged. The bin/ loop now picks up bin/page-signal
automatically.
INDEX entries for both new workflows landed under Tools and meta.
No bats tests on the new scripts. page-signal was smoke-tested with a
live send. The send succeeded. The notification gap is covered by the
workflow's known-limitation note. cross-project-broadcast.py was
smoke-tested via --list against the live project set. Tests can be
added when the broadcast pattern proves out across multiple use cases.
Diffstat (limited to '.ai/workflows/page-signal.org')
| -rw-r--r-- | .ai/workflows/page-signal.org | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/.ai/workflows/page-signal.org b/.ai/workflows/page-signal.org new file mode 100644 index 0000000..a772603 --- /dev/null +++ b/.ai/workflows/page-signal.org @@ -0,0 +1,87 @@ +#+TITLE: Page Signal Workflow +#+AUTHOR: Craig Jennings & Claude +#+DATE: 2026-05-29 + +* Overview + +Send Craig a Signal message via =page-signal= when desktop notifications won't reach him. Signal fires cross-device, so a page arrives on his phone even when he's away from the desk. The wrapper lives at =~/.local/bin/page-signal= (rulesets-installed; symlinked from =claude-templates/bin/page-signal=). + +Defaults to =--note-to-self= for safety. Outbound (paging another contact) requires an explicit =--to <+number>= every call. No defaults, no batch. + +*Known limitation (2026-05-29):* =signal-cli= is currently registered with Craig's primary number, so messages from it appear as "you sending from a linked device" rather than as an incoming message from a third party. Signal's mobile clients do not fire push notifications for these. Pages land in the conversation but don't ring the phone. The fix is to register =signal-cli= with a separate number (Craig's Google Voice number is the pending plan, see todo.org TODO scheduled 2026-05-29). Until that registration lands, this workflow is best used for *desktop-visible* paging (the notify wrapper, status outputs) rather than for reaching Craig cross-device. The wrapper itself works correctly; only the notification routing is awaiting the second-account registration. + +* When to Use This Workflow + +User triggers (rare; this is usually invoked by other workflows or by Claude autonomously per the rules below): + +- "page me on signal" / "signal me when X is done" +- "send a signal note about <thing>" + +Automatic invocation: + +- *Long-running task completion* — when a task estimated >10 min finishes successfully or fails, fire =page-signal= in addition to =notify= so Craig sees it on his phone if he's away. +- *Cross-device deliverables* — when generating a file or screenshot Craig will want on his phone (a quick reference, a meeting prep summary, etc.), attach via =page-signal --file=. +- *Operator-attention events* — when an autonomous run needs Craig's eyes and the desktop notify might miss him. + +* When NOT to Use This Workflow + +- *Routine completions.* The desktop =notify success= covers everything that finishes within a normal session. Signal pages should be the exception, not the default. +- *Periodic status pings.* Long-running-process status updates (per =protocols.org='s 5-minute cadence) go to desktop only. Signal-paging every five minutes is spam. +- *Trivial confirmations.* "Commit landed", "test passed", "file saved" don't earn a Signal page. +- *Outbound to other contacts without explicit instruction.* =--to <+number>= is per-message, not a saved address book. Each outbound page needs Craig's explicit instruction naming the recipient. + +* Mechanics + +** Direct invocation + +#+begin_src bash +# Note-to-self (default): +page-signal "Build finished. 12 min, all tests green." + +# With attachment: +page-signal --file /tmp/report.pdf "Daily prep ready." + +# Outbound (explicit recipient): +page-signal --to +15551234567 "Running 10 minutes late." + +# Quiet mode (suppress stdout success line): +page-signal --quiet "Done." + +# JSON output (for scripted callers): +page-signal --json "Done." +#+end_src + +Exit codes: +- =0= — sent successfully +- =1= — signal-cli reported a send failure (network, rate limit, recipient unreachable) +- =2= — usage error (missing arg, invalid =--to= format) +- =3= — =signal-cli= not installed + +** Composition with =notify= + +If the =notify= script gains a =--signal= flag (currently a separate handoff to the dotfiles project), it can fire desktop notification + Signal page in one call. Until then, run both: + +#+begin_src bash +notify success "Build done" "12 min, all green" --persist +page-signal "Build done — 12 min, all green." +#+end_src + +* Safety Rails + +1. *No outbound without explicit instruction per send.* The Signal protocol doesn't distinguish between "Craig asked me to text Alice" and "I decided Alice should hear from me." The latter is never appropriate. Every =--to <+number>= invocation must trace back to a Craig directive that names the recipient. +2. *No saved address book.* Don't memoize contact numbers in scripts or workflows. The explicit =+number= per call is the rate limiter on accidental sends. +3. *Rate limit awareness.* Signal rate-limits high-volume sends. If a session is firing >5 pages in a few minutes, that's a smell — consolidate into one summary page. +4. *Sensitive content.* Signal is end-to-end encrypted to Craig's devices, but the message body is visible on every device he's logged in on (phone, desktop, web). Don't page secrets, credentials, or anything you wouldn't want shoulder-surfed. +5. *Failure semantics.* A page that didn't land is the failure mode you'll never notice. The wrapper returns non-zero on send failure — callers that depend on delivery should check the exit code, not assume. + +* Common Mistakes + +1. *Signal-paging every notify call.* Defeats the purpose. Signal is the exception for cross-device pages. +2. *Using =--to= with a stored number.* Each outbound needs Craig's instruction. No defaults. +3. *Paging during automated periodic checks.* Use desktop notify for periodic status. Signal is for events Craig wants to react to. +4. *Sending the full task body via Signal.* One sentence, not a wall of text. Signal pages are glanceable; long messages buried on a phone get skimmed past. +5. *Ignoring exit code 1.* The page didn't arrive. Either retry or surface the failure to Craig at the next interactive moment. + +* Living Document + +Tune the "automatic invocation" criteria as the cadence shapes up. If certain long-running task classes consistently warrant Signal pages and others don't, fold the pattern into the heuristic. If a =notify --signal= flag lands in the dotfiles, update the composition section. |
