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 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YECpkAwQUwgu7NVy91R8fW
This commit is contained in:
Claude
2026-08-22 17:36:51 -04:00
parent 5896d6cab1
commit f168ad6f4c
2 changed files with 20 additions and 9 deletions
+6 -2
View File
@@ -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 # Nirlab Command Center (founder workspace) — where the Pulse/Activity feed lives
PULSE_BRIDGE_WORKSPACE_ID=293d29db-4978-4c54-a92e-b24d4c0a7115 PULSE_BRIDGE_WORKSPACE_ID=293d29db-4978-4c54-a92e-b24d4c0a7115
PULSE_BRIDGE_CHANNEL=activity PULSE_BRIDGE_CHANNEL=activity
# handle used in "@nir NEEDS YOU:" escalation comments # handle used in "@ NEEDS YOU:" escalation comments. Must be the lower(name)
PULSE_BRIDGE_MENTION=nir # 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_POSTER_NAME=Ledger
PULSE_BRIDGE_SHRE_ITEMS=/Users/aibot/.local/bin/shre-items PULSE_BRIDGE_SHRE_ITEMS=/Users/aibot/.local/bin/shre-items
PULSE_BRIDGE_STATE=/Users/aibot/.shre/pulse-bridge/state.json PULSE_BRIDGE_STATE=/Users/aibot/.shre/pulse-bridge/state.json
+14 -7
View File
@@ -136,12 +136,15 @@ def save_state(state: dict) -> None:
def neutralize(text: str) -> str: def neutralize(text: str) -> str:
"""Insert a zero-width space after '@' in ledger-derived text. """Insert a zero-width space after '@' in ledger-derived text.
mib007's comms route treats the FIRST '@handle' in a message as an agent mib007's comms route treats the FIRST '@handle' in a message as a mention:
mention: a matching agent fires an AI reply into the thread, and on this a matching agent fires an AI reply into the thread, and a matching
instance ANY mention 500s after the insert (the agent lookup references a workspace-member user gets a notification. The historical crash (mention
nonexistent url_key column). So no bridge-emitted text may ever contain a lookup on a nonexistent agents.url_key column 500'd AFTER the insert) is
bare '@handle' — including the bridge's own needs-you escalation, which is FIXED — Nirlabinc/mib007 PR #32 — so mentions are safe to send. We still
emitted zwsp-neutralised and renders identically in the UI. 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("@", "@") return (text or "").replace("@", "@")
@@ -176,7 +179,11 @@ def update_body(rec: dict) -> str:
stage = rec.get("stage") stage = rec.get("stage")
note = neutralize(rec.get("note", "")) note = neutralize(rec.get("note", ""))
if kind == "needs-you": if kind == "needs-you":
lines.append(neutralize(f"@{MENTION}") + " NEEDS YOU: this item is now" # Deliberately a LIVE mention (not neutralized): mib007 resolves
# @<lower(user name)> 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 "")) " waiting on a human." + (f"{note}" if note else ""))
note = "" # already included note = "" # already included
elif kind == "failed": elif kind == "failed":