fix(signal): stop relaying the expected PNI/ACI cross-check as a WARNING - #125
Merged
juniperbevensee merged 2 commits intoJul 29, 2026
Merged
Conversation
`_resolve_own_uuid` resolves the account ACI from `listIdentities`, then cross-checks it against `getUserStatus`. Its own docstring states that signal-cli (verified on 0.14.5) ALWAYS returns the account PNI for a self `getUserStatus` — so the two values always differ and the mismatch branch is the expected steady state on every gateway start, not a fault. It logged at WARNING. Because `gateway.platforms.signal` is in home_log_router's DEFAULT_LOGGERS and that router forwards WARNING to the operator's home channel, every agent on the fleet relayed this line to the operator on each restart — the exact lifecycle spam home_log_router's module docstring forbids. It also reads as a recurring failure when in fact it is the code working correctly. Downgraded to DEBUG, so the diagnostic remains available when actually investigating identity issues. Behavior is unchanged: the ACI from `listIdentities` was already the only value cached, and still is. Verified benign across a 7-agent fleet before changing the level: 2-4 occurrences per container per 24h, a stable PNI/ACI pair per account, zero Signal auth errors and zero own-ACI resolution failures. Tests: 4 new (no WARNING emitted, DEBUG retained, ACI still wins, silent when the values agree). 380 signal tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
An independent review found DEBUG overshot the goal. home_log_router's policy floors at WARNING (policy.py:19, WARNING default), so INFO already stops the home-channel relay completely. DEBUG additionally dropped the line from gateway.log, whose handler is pinned to INFO+ (hermes_logging.py:345) — so the claim that the diagnostic "remains available" was false in practice: the branch only runs inside connect(), meaning you would need a DEBUG-enabled restart to ever see it. It fires once per connect, so INFO carries no spam risk. Also softened "the account PNI, as expected" back to "presumed the account PNI". Nothing in this code verifies that status_sid IS the PNI — the docstring notes signal-cli strips the PNI: prefix on self-lookup, so it is unknowable from these two RPCs. The original hedge was more accurate. Trimmed the comment block, which had grown longer than the statement it annotated and duplicated the commit message and test docstring. Re-verified non-vacuous at the new level: flipping INFO back to WARNING fails 2 of 4 tests. 380 signal tests + 42 home_log_router tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
juniperbevensee
deleted the
dev/juniperbevensee/signal-pni-crosscheck-noise
branch
July 29, 2026 23:36
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The noise
Every agent on the fleet emits this on each gateway start, and
home_log_routerrelays it to the operator's Signal home channel:Why it's wrong at WARNING
_resolve_own_uuid's own docstring already documents the cause:So the two values always differ. The mismatch branch is the expected steady state, not an anomaly — the line fires precisely when the code is working correctly. And the ACI from
listIdentitiesis already the only value cached (if candidate: self._own_uuid = candidate), so the warning never signalled a behavioural problem.It compounds:
gateway.platforms.signalis inhome_log_router'sDEFAULT_LOGGERS, which forwards at WARNING. That module's docstring explicitly warns against routing loggers that emit "lifecycle noise (violates the no-lifecycle-spam rule)" — this is exactly that, and it reaches the operator on every restart of every agent.Verified benign before changing it
Measured across a 7-agent fleet over 24h rather than assuming:
The PNI/ACI pair is stable per account, and the resolved
_own_uuidis the ACI everywhere. Nothing downstream is affected.The change
logger.warning→logger.debug, with a comment recording why DEBUG is the correct level so it doesn't get "fixed" back. The cross-check is still worth having — at DEBUG it's there when you're actually diagnosing identity issues. Message reworded from "likely the account PNI" to "the account PNI, as expected".Behavior is unchanged.
Tests
4 new in
tests/gateway/test_signal_pni_crosscheck_level.py:listIdentitiesstill wins (the Signal groups: agent executes tasks @-mentioned to a different agent (own-ACI mismatch + addressing-blind auto-resume + observe_only self-attribution) #112 invariant — never cache the PNI)380 passed, 1 skippedacross the signal gateway suite.Note for reviewers
home_log_routerhasHERMES_HOME_LOG_LOGGERSand_LEVELbut no message-pattern denylist, so this could not be filtered without silencing all Signal warnings — including the reconnect/auth ones that genuinely should reach home. Fixing the level is the right layer. If benign-WARNING spam recurs elsewhere, a denylist knob may be worth adding, but correcting levels should be preferred over masking them.🤖 Generated with Claude Code