fix(imessage): the world model must keep learning on a MUTED channel - #253
Conversation
…— it was dead code for the one incident it was built for Live finding, 24h after deploy: the world-model refresh had not run ONCE. The iMessage bridge is muted, and `maybeRefreshWorldModel` sat below the `proactivePaused()` early return — which is true whenever `this.muted` is set. On a muted channel the whole refresh was unreachable. That is exactly backwards. Mute means "don't SEND to contacts" (#250), not "stop thinking". The refresh messages no one: it reads the owner's own mail, calendar and self-chat notes and updates the OWNER's profile. And the bridge WAS muted on 2026-09-18 — so the refresh that would have corrected the stale grand-opening date never ran, on the very day the stale date made the bot correct a friend twice. The feature shipped switched off by an unrelated flag. - `maybeRefreshWorldModel` moves ABOVE the pause gate, under the killswitch. - Quiet hours and an explicit "quiet Nh" still defer it (its FYI would wake the owner); the next tick after the window picks it up. - The killswitch — the do-nothing-at-all switch — still stops it. - Regression test is structural, because the bug was WHERE the call sat: below that return it is dead code, and no behavioural test of the function itself would have caught it. Verified: imessage-bridge 120/0, tsc clean.
🔎 Codex cross-audit (agent:audit)No Blocking findings. I didn’t find a correctness or security regression in the PR diff. Moving Residual note: the new regression test is structural/source-order based, but that style already exists in this package and is acceptable for this narrow wiring invariant. Verification: targeted test could not be run because |
🛡️ Vuln scan — ❌ vulnerable dependency found |
🔷 Gemini cross-audit (agent:audit-gemini)An audit of the unified diff in Audit Verdict: 🟢 PASS (No Blocking Issues)The patch is sound, secure, and ready to merge. It implements the desired behavior correctly, maintains all existing security boundaries, avoids resource overhead, and includes a precise, well-structured test suite. Detailed Findings1. Correctness & Mute Gating (Verified)
2. Security & Privacy Boundaries (Verified)
3. Performance & Resource Efficiency (Verified)
4. Test Quality & Coverage (Verified)
|
Live finding, 24 hours after the world model deployed: it had not run once.
The iMessage bridge is muted.
maybeRefreshWorldModelsat below theproactivePaused()early return, and that returns true wheneverthis.mutedis set. On a muted channel the entire refresh was unreachable — the feature shipped switched off by an unrelated flag.That is exactly backwards:
Change
maybeRefreshWorldModelmoves above the pause gate, still under the killswitch.quiet Nhstill defer it — its FYI would wake the owner. The next tick after the window picks it up.The regression test is structural on purpose: the bug was where the call sat. Below that return it is dead code, and no behavioural test of
refreshWorldModelitself would ever have caught it.Verification
world-model-mute-scope.test.ts(new, 3 cases)Live behaviour UNVERIFIED until merged and deployed; then the first refresh logs
world model:within ~45 min.