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":