From f168ad6f4c07ba93b85a49c22c4af74af934d185 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 22 Aug 2026 17:36:51 -0400 Subject: [PATCH] needs-you escalations carry a live @mention (mib007 mention crash fixed) mib007's mention path is fixed (Nirlabinc/mib007 PR #32): mention resolution is now fire-and-forget server-side (a lookup failure can no longer 500 the POST after the insert), and an @handle matching an active workspace-member user's lower(name) creates a comment.mention notification. - update_body: the needs-you escalation line now emits a real @handle instead of the zwsp-neutralised one, so the human actually gets pinged. - neutralize() stays for all ledger-derived text (titles/details/notes): item text containing @aros/@ellie must not accidentally fire an agent reply. - bridge.env: PULSE_BRIDGE_MENTION nir -> rapidnir. 'nir' resolves to nothing (mentions match lower(user.name) over ACTIVE workspace members; the only human members of Nirlab Command Center are Board and RapidNir). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01YECpkAwQUwgu7NVy91R8fW --- bridge.env | 8 ++++++-- bridge.py | 21 ++++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/bridge.env b/bridge.env index 954e918..959eee7 100644 --- a/bridge.env +++ b/bridge.env @@ -4,8 +4,12 @@ PULSE_BRIDGE_MIB_BASE=http://127.0.0.1:5520 # Nirlab Command Center (founder workspace) — where the Pulse/Activity feed lives PULSE_BRIDGE_WORKSPACE_ID=293d29db-4978-4c54-a92e-b24d4c0a7115 PULSE_BRIDGE_CHANNEL=activity -# handle used in "@nir NEEDS YOU:" escalation comments -PULSE_BRIDGE_MENTION=nir +# handle used in "@… NEEDS YOU:" escalation comments. Must be the lower(name) +# of an ACTIVE member of the workspace above — mib007 resolves user mentions by +# lower(u.name) over workspace_memberships. "nir" does not resolve here (the +# only human members are Board/local-board and RapidNir/rapidnir-admin), so we +# mention RapidNir — Nir's account in the Nirlab Command Center workspace. +PULSE_BRIDGE_MENTION=rapidnir PULSE_BRIDGE_POSTER_NAME=Ledger PULSE_BRIDGE_SHRE_ITEMS=/Users/aibot/.local/bin/shre-items PULSE_BRIDGE_STATE=/Users/aibot/.shre/pulse-bridge/state.json diff --git a/bridge.py b/bridge.py index 0746945..e325093 100644 --- a/bridge.py +++ b/bridge.py @@ -136,12 +136,15 @@ def save_state(state: dict) -> None: def neutralize(text: str) -> str: """Insert a zero-width space after '@' in ledger-derived text. - mib007's comms route treats the FIRST '@handle' in a message as an agent - mention: a matching agent fires an AI reply into the thread, and on this - instance ANY mention 500s after the insert (the agent lookup references a - nonexistent url_key column). So no bridge-emitted text may ever contain a - bare '@handle' — including the bridge's own needs-you escalation, which is - emitted zwsp-neutralised and renders identically in the UI. + mib007's comms route treats the FIRST '@handle' in a message as a mention: + a matching agent fires an AI reply into the thread, and a matching + workspace-member user gets a notification. The historical crash (mention + lookup on a nonexistent agents.url_key column 500'd AFTER the insert) is + FIXED — Nirlabinc/mib007 PR #32 — so mentions are safe to send. We still + neutralize ledger-DERIVED text (titles, details, notes) because arbitrary + item text containing "@aros"/"@ellie" must not accidentally fire an agent + reply into the feed. The bridge's own needs-you escalation line is the one + place that deliberately carries a live @handle (see update_body). """ return (text or "").replace("@", "@​") @@ -176,7 +179,11 @@ def update_body(rec: dict) -> str: stage = rec.get("stage") note = neutralize(rec.get("note", "")) if kind == "needs-you": - lines.append(neutralize(f"@{MENTION}") + " NEEDS YOU: this item is now" + # Deliberately a LIVE mention (not neutralized): mib007 resolves + # @ against active workspace members and creates a + # comment.mention notification, so the escalation actually pings the + # human. Everything else in the line stays neutralized. + lines.append(f"@{MENTION} NEEDS YOU: this item is now" " waiting on a human." + (f" — {note}" if note else "")) note = "" # already included elif kind == "failed":