aboutsummaryrefslogtreecommitdiff
path: root/.ai/workflows/page-signal.org
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-29 14:51:53 -0500
committerCraig Jennings <c@cjennings.net>2026-05-29 14:51:53 -0500
commit664bf01ceaccf730cb636463cc8587cd1d966192 (patch)
treee964f6c88d986454c5a2acfc99dfb55964fbba2b /.ai/workflows/page-signal.org
parentc3cf9a592ea6779ad59f0d79577e29777fce49f6 (diff)
downloadrulesets-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.org87
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.