aboutsummaryrefslogtreecommitdiff
path: root/.ai/workflows/cross-project-broadcast.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/cross-project-broadcast.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/cross-project-broadcast.org')
-rw-r--r--.ai/workflows/cross-project-broadcast.org126
1 files changed, 126 insertions, 0 deletions
diff --git a/.ai/workflows/cross-project-broadcast.org b/.ai/workflows/cross-project-broadcast.org
new file mode 100644
index 0000000..3a6294c
--- /dev/null
+++ b/.ai/workflows/cross-project-broadcast.org
@@ -0,0 +1,126 @@
+#+TITLE: Cross-Project Broadcast Workflow
+#+AUTHOR: Craig Jennings & Claude
+#+DATE: 2026-05-29
+
+* Overview
+
+Fan out a single message to every AI project's inbox in one operation. Discovers projects by fingerprint (any directory with =.ai/protocols.org=) and delivers via the existing =inbox-send.py= per-target. The point is announcing a new capability or shared change once, instead of hand-walking 20+ projects.
+
+* When to Use This Workflow
+
+User triggers:
+
+- "broadcast this to every project"
+- "notify every project about <thing>"
+- "fan out this announcement"
+- "let every project know X is available"
+
+Automatic invocation:
+
+- *New machine-global capability landed.* A new script in =~/.local/bin/=, a new MCP server registered, a new tool installed (e.g. =signal-cli=, =page-signal=). Projects need to know it's available so their agents can use it.
+- *Shared rule or protocol change.* When a change to =claude-rules/= or =claude-templates/.ai/= materially affects how every project's agent should behave, broadcast a heads-up so the next session of each project picks it up explicitly rather than discovering it on rsync.
+- *Deprecation notice.* When a script, workflow, or rule is going away, give every project a chance to migrate before the removal lands.
+
+* When NOT to Use This Workflow
+
+- *Project-specific work.* A handoff intended for one project goes through =inbox-send= directly, not broadcast.
+- *Routine status updates.* The session log and todo.org cover routine work. Broadcast is for capability- or rule-level changes.
+- *Bulk noise.* Every broadcast adds N inbox files. Use sparingly; ask whether projects actually need to know.
+
+* The Workflow
+
+** Phase A — Discover targets
+
+Run the discovery helper:
+
+#+begin_src bash
+python3 .ai/scripts/cross-project-broadcast.py --list
+#+end_src
+
+The helper scans =~/code/=, =~/projects/=, =~/.emacs.d= for any directory containing =.ai/protocols.org=. Prints the basename and full path of each, in sender-excluded order (the current project never receives its own broadcast).
+
+** Phase B — Compose the message
+
+Write the broadcast body to =/tmp/broadcast-<topic>.org=. Required structure:
+
+#+begin_example
+,#+TITLE: <one-line summary>
+,#+DATE: YYYY-MM-DD
+,#+SOURCE: <sender project name>
+
+,* What's new
+
+<two to five sentences: the capability, rule, or change being announced.>
+
+,* How to use it
+
+<two to five lines: the concrete invocation, command, or path. Code examples in =#+begin_src= blocks. No prose walls.>
+
+,* Why this matters / when to use
+
+<two to four sentences: the user-facing rationale and the discrimination rule for when the new thing applies vs. when existing alternatives suffice.>
+
+,* Action required
+
+<one of:>
+- =FYI=, no action required (most broadcasts)
+- =Update workflow X= to reference the new capability
+- =Deprecate workflow Y= by date Z
+#+end_example
+
+The structure is rigid on purpose. Every project's next session has to read 20+ broadcasts as efficiently as possible. The standard headings let the agent scan in seconds.
+
+** Phase C — Confirm scope with the user
+
+Surface the discovered project list and the message inline. Ask:
+
+#+begin_example
+Broadcast scope:
+- Target projects: <N> (list)
+- Message: <2-line summary>
+- Action required: <FYI / update workflow / deprecation>
+
+1. Send to all <N> targets (recommended)
+2. Exclude specific projects (name them)
+3. Cancel — message stays at /tmp/broadcast-<topic>.org
+#+end_example
+
+** Phase D — Fan out
+
+Run the broadcast helper with the composed message:
+
+#+begin_src bash
+python3 .ai/scripts/cross-project-broadcast.py \
+ --file /tmp/broadcast-<topic>.org \
+ [--exclude project1 --exclude project2 ...]
+#+end_src
+
+The helper iterates over targets, runs =inbox-send.py <target> --file <broadcast>= per target, captures success/failure per project. The =from-<sender>= prefix in the resulting filename traces provenance.
+
+** Phase E — Report
+
+Summarize the fan-out:
+
+- Total targets discovered
+- Sent successfully (count)
+- Failed (list with reason)
+- Excluded (list with reason)
+
+If any failures, surface them — silent failure on a broadcast means some projects never learn about the change.
+
+** Phase F — Cleanup
+
+Delete =/tmp/broadcast-<topic>.org=. The content lives in each target's inbox now.
+
+* Common Mistakes
+
+1. *Broadcasting project-specific work.* Each broadcast costs N inbox files across the fleet. Routine handoffs go through =inbox-send= directly.
+2. *Skipping Phase B's structure.* Free-form broadcasts force every recipient to parse them differently. Use the rigid headings.
+3. *Sender-includes-itself.* The discovery helper excludes the sender automatically. Don't override it — broadcasting to your own inbox creates a self-reply loop.
+4. *Forgetting Phase E.* A broadcast that partially succeeded is the failure mode you'll never notice. Always check the per-target results.
+5. *Broadcasting without an "Action required" line.* Recipients need to know whether this is FYI or whether their project has to do something. The line is non-optional.
+6. *Using broadcast as a substitute for documentation.* Capability announcements should be paired with a rule or workflow update so the next-next session can rediscover the capability from canonical docs, not from a stale inbox file.
+
+* Living Document
+
+If the discovery roots change (a new top-level directory for AI projects), update =cross-project-broadcast.py='s =SEARCH_ROOTS=. If the per-broadcast structure proves too rigid or too loose, tune Phase B. If the recipient projects start complaining about broadcast noise, the rule is "broadcast less," not "structure broadcasts harder."