aboutsummaryrefslogtreecommitdiff
path: root/.ai
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-08-19 15:02:32 -0700
committerCraig Jennings <c@cjennings.net>2026-08-19 15:02:32 -0700
commit62a7fbf695405d8804220c1cf1b280ee8d612082 (patch)
tree66f5c4123b512fcdb2422b335a7e14d5e5446167 /.ai
parent10d4e3b17dddbe8df47a80444688d13be15dc016 (diff)
downloadrulesets-62a7fbf695405d8804220c1cf1b280ee8d612082.tar.gz
rulesets-62a7fbf695405d8804220c1cf1b280ee8d612082.zip
fix(agent-text): relay through a host that holds the account
The relay target was hardcoded to velox, and velox's reinstall wiped its signal-cli registration. A send from velox then relayed to itself, and any machine without a local account relayed into the same dead end. Only ratio still worked, because it holds the account as a linked device and sends directly. The old failure text blamed velox for being down. It was up, just unregistered. The target is now an ordered list, overridable per invocation, and the loop skips any candidate matching this machine's name. The skip is the actual fix. Reaching the relay branch means the account isn't local, so relaying to ourselves can't work whatever the list order. Both sides of that comparison are domain-stripped, or an FQDN nodename would silently disable the guard. A relay host that is reachable but unregistered exits 1, not 0, so the loop advances instead of reporting a delivery that never happened. I checked that rather than assume it. Silent non-delivery is the worst failure this tool has, and a test pins it. The failure message now names which branch failed, so a local send failure no longer sends anyone chasing the tailnet. protocols.org and the pager runbook both asserted the topology the reinstall destroyed. They now say how to derive which machine holds the account instead of naming one. The snapshot form is what rotted. The runbook's linking recipe is marked impossible for now, since the primary's keys are gone and a linked device can't authorize another.
Diffstat (limited to '.ai')
-rw-r--r--.ai/protocols.org10
1 files changed, 7 insertions, 3 deletions
diff --git a/.ai/protocols.org b/.ai/protocols.org
index 3e32074..bf0e6f7 100644
--- a/.ai/protocols.org
+++ b/.ai/protocols.org
@@ -469,13 +469,17 @@ Two channels, two trigger words. "page me" is the desktop, "text me" is the phon
agent-text "Message for Craig's phone"
#+end_src
- =agent-text= (in =~/.local/bin= via the rulesets install) sends from the dedicated Signal identity (+15045173983) to Craig's Signal account UUID, firing a normal mobile push. The account is registered on velox (primary) and ratio (linked device), so either sends directly; a machine without it ssh-relays to velox. Verified end to end 2026-07-13 (velox) and 2026-07-20 (ratio). Never target Craig's phone *number* (it reads as unregistered in Signal's directory); the script targets the UUID.
+ =agent-text= (in =~/.local/bin= via the rulesets install) sends from the dedicated Signal identity (+15045173983) to Craig's Signal account UUID, firing a normal mobile push. Never target Craig's phone *number* (it reads as unregistered in Signal's directory); the script targets the UUID.
- Caveats: a relay from a non-linked machine needs velox up on the tailnet, and each device holding the account wants a periodic =receive= (the signal-receive timer handles that). The full runbook lives in rulesets =docs/design/=.
+ *Which machine holds the account is a runtime fact, not a fixed one — derive it, don't assume it.* Any machine whose local =signal-cli= holds the identity sends directly, whether as the registered primary or as a linked device; a machine without it ssh-relays to the first relay host that does. Check the local half with =signal-cli listAccounts=. I write it this way because the old wording named velox as the permanent primary, and velox's 2026-08-13 reinstall wiped that registration — which broke the doc and the script together, since =agent-text= had the same host hardcoded as its only relay target.
+
+ The relay list lives in =AGENT_TEXT_RELAYS= at the top of the script, tried in order, and is overridable for a one-off (=AGENT_TEXT_RELAYS="host1 host2" agent-text "..."=). It skips any candidate whose short name matches =uname -n=: reaching the relay branch means the account is *not* local, so an ssh round trip to this machine lands on the same empty store and cannot succeed.
+
+ Caveats: a relay needs at least one listed host up on the tailnet *and* holding the account, and each device holding it wants a periodic =receive= (the signal-receive timer handles that). A relay to a host that is reachable but unregistered fails cleanly rather than silently — =signal-cli send= exits 1 with "User <number> is not registered", so the loop moves on to the next candidate (verified 2026-08-19). The full runbook lives in rulesets =docs/design/=.
- *"text and page me" — both.* Fire =agent-text= and =notify= together. The phone reaches him now, the desktop note waits for his return. This is the default when a run can't tell whether he's away.
-On velox, Claude sessions may also have the *signal-mcp* tool (=send_message_to_user=, same identity), fine to use there, but it exists only in velox's local MCP config, so =agent-text= is the portable habit. The tool was named =agent-page= before 2026-07-20; a deprecated =agent-page= shim still delegates to =agent-text=. Do *not* use the old =page-signal= shell script (removed 2026-06-12).
+A *signal-mcp* tool (=send_message_to_user=, same identity) has existed in one machine's local MCP config before now. Treat it as a nicety that may or may not be registered on the machine you're on — it was gone from velox after the 2026-08-13 reinstall — and use =agent-text= as the habit, since that one travels with the rulesets install. The tool was named =agent-page= before 2026-07-20; a deprecated =agent-page= shim still delegates to =agent-text=. Do *not* use the old =page-signal= shell script (removed 2026-06-12).
* Session Protocols