1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
#+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.
- *Every commit.* Most commits are project-internal hygiene (audit, intake, TODO updates) that the other projects don't care about. Even cross-project workflow updates rsync into every project's =.ai/= at next startup, so the capability lands without a broadcast. Broadcast only when projects need to *act* on the change (use a new tool, migrate before a deprecation, change their behavior per a new rule). Resist the urge to fan out a "here's what shipped today" digest. The startup rsync already carries the bits; the broadcast carries the *attention*, and attention is the costly resource.
* Cadence Guideline
Broadcasts are capability-and-rule-level events, not commit-level events. A reasonable cadence is one to four broadcasts per month, depending on what landed. Five reasons for the restraint:
1. Each broadcast costs N inbox processings across the fleet (currently ~23 targets). Daily broadcasts mean daily noise.
2. Most commits are project-internal. Other projects do not need to read about another project's TODO sweeps, audit passes, or hygiene work.
3. The startup rsync already does the capability work. Broadcasts add awareness, not availability.
4. Aggregation wins. One weekly "here's what shipped" digest beats ten per-commit pings on every dimension. Fewer inbox files, easier to skim, easier to defer reading.
5. Per-commit broadcasts train projects to ignore inbox. Then a real handoff gets missed.
If a session ships several broadcastable changes, bundle them into one broadcast at session end rather than firing one per commit.
* 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."
|