docs(althing): a sixth deploy surface, and it lives outside the repo

Claude Code holds an inbound cross-session message unless the sender's
permission-mode class matches the receiver's, and holds any sender that
asserts no class. The herald is a daemon and asserts none, so on a
default-configured seat every cc poke is held at first contact and the
notice goes to whoever is watching the pane rather than to the session.

The seat still reports declared, reachable and healthy throughout — the
same failure shape as the SessionStart hook that was never deployed, where
every check was green and nothing arrived. That is what makes it worth a
surface of its own rather than a footnote.

deploy-althing.sh now reads crossSessionInbound from ~/.claude/settings.json
and reports it on every run and on --check. It deliberately does NOT set it:
that file is the operator's permission configuration, and a deploy script
that edits it is a deploy script granting itself trust.

Also records surface 5 (the per-seat route declare), which had been implicit,
and why no attestation exists for the herald to send instead — CC reads a
sender's live runtime permission mode from the session registry, which a
daemon does not appear in.
This commit is contained in:
vh
2026-09-02 09:30:48 -07:00
parent 2575242e87
commit af5582c96d
2 changed files with 87 additions and 2 deletions
+37 -1
View File
@@ -6,7 +6,7 @@
# scripts/deploy-althing.sh --check report drift, change nothing
#
# ─────────────────────────────────────────────────────────────────────────────
# WHY FOUR
# WHY FOUR — AND WHY THE COUNT IS NOW SIX
#
# 1. uv tool install --force . the 7 binaries (postbox, althing-listen,
# althing-route, althing-po-herald, ...)
@@ -84,6 +84,33 @@ plugin_content_drift() {
return 1
}
# ── SURFACE 6: ~/.claude/settings.json crossSessionInbound ────────────────────
#
# The only surface that is NOT in the althing repo, so a version check cannot
# reach it. Claude Code holds an inbound cross-session message unless the
# sender's permission-mode class matches yours, and a sender that asserts no
# class is held. The herald is a daemon and asserts none — deliberately — so on
# a default-configured seat a cc poke is HELD and the notice goes to whoever is
# looking at the pane instead of to the session.
#
# The failure shape is the expensive one: the seat is declared, reachable and
# green, and nothing arrives. Same family as the SessionStart hook that was
# never deployed.
#
# ⚠ REPORT ONLY, NEVER SET. This file is the operator's permission
# configuration; a deploy script that edits it is a deploy script that grants
# itself trust. Print what is there and let a human decide.
settings_inbound() {
python3 - <<'EOF' 2>/dev/null || echo "unreadable"
import json, pathlib
p = pathlib.Path.home() / ".claude/settings.json"
try:
print(json.loads(p.read_text()).get("crossSessionInbound", "UNSET"))
except Exception:
print("unreadable")
EOF
}
step "state"
say " repo $(git -C "$REPO" describe --tags --always) $(git -C "$REPO" diff --quiet && echo clean || echo DIRTY)"
say " installed tool $(uv tool list 2>/dev/null | awk '/^althing-core/{print $2}')"
@@ -91,6 +118,14 @@ say " repo plugin $(repo_plugin_version)"
say " marketplace $(market_plugin_version)"
say " CC cache $(cache_versions)"
plugin_content_drift || true
inbound="$(settings_inbound)"
say " cc inbound crossSessionInbound=$inbound (~/.claude/settings.json)"
if [[ "$inbound" != "accept" ]]; then
say " ⚠ cc pokes to a seat on this box are HELD at first contact, not delivered."
say " The seat still looks declared, reachable and healthy. Set"
say " crossSessionInbound: \"accept\" BY HAND — this script will not"
say " edit the operator's permission configuration."
fi
if (( CHECK )); then
say ""
@@ -155,5 +190,6 @@ if ! plugin_content_drift; then
say " bookkeeping. Check the diff above for whether it is load-bearing."
fi
say " herald $(systemctl --user is-active althing-po-herald)"
say " cc inbound crossSessionInbound=$(settings_inbound)"
say ""
say "⚠ RESTART Claude Code to load the new plugin hooks. A running session keeps the old ones."