- create_post: on HTTPError, look for an existing post tagged ledger:<id> (insert-then-error recovery) and adopt it before retrying - save_state: fsync tmp file before rename - load_state: corrupt state is fatal (auto-reseed would duplicate every open item's post) - comment: drop only on 500/404/410; 401/403/429/502/503 retry next poll Accepted as-is (with rationale): same-second ordering relies on the feed replaying the JSONL in append order + Python's stable sort; seed-window add+close races reduce to the documented 'predates bridge' skip. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YECpkAwQUwgu7NVy91R8fW
pulse-bridge v0
Mirrors the estate's shared work ledger (~/.local/bin/shre-items,
JSONL store at ~/.shre/open-items/items.jsonl) into Pulse — the
social-feed surface of the local mib007 instance (http://127.0.0.1:5520,
launchd ai.shre.mib007). Ledger items become posts, stage changes become
threaded comments, needs-you escalations mention the user.
Where Pulse actually lives (as discovered 2026-08-22)
The Pulse UI is mib007's Activity app (/activity, PULSE_ROUTE in
ui/src/platform/lib/app-routes.ts). Its feed is backed by the comms
tables, not the unified message envelope: the envelope work (feed_items
view, migrations 0101-0111) is in shreai PR #163 and is not merged into
the running mib007 (local checkout is at migration 0100). The
/api/workspaces/:id/feed route proxies to shre-feed (:5436), which is
down locally. So the write path Pulse really uses is:
- create post:
POST /api/workspaces/:wid/comms/channels/:cid/messages{content, type: "text", userName}→ returns the row (id= post id) - comment/reply: same endpoint with
threadId: <post message id> - channel: the Activity app reads/writes the channel named
activity(creates it if missing) — same behaviour here.
Auth: mib007 service token (~/.shre/service-tokens.json, key mib007),
board-level, valid from loopback. mib007 runs in authenticated mode, so
requests without it are rejected.
Mapping
| ledger op | Pulse action |
|---|---|
add |
new post: emoji by kind + title, detail, tag line (#kind #stage #tags surface: project: ledger:<id>) |
update |
comment on the mapped post: stage → review, ⛔ failed at verify, attempt 2 — <note>, kind → … |
update to kind: needs-you |
comment @nir NEEDS YOU: … |
close |
comment ✅ done — <why> or 🗑 dropped — <why> |
First run seeds posts for currently-open items only
(shre-items list --json); history before the bridge is not replayed.
State & config
- State:
~/.shre/pulse-bridge/state.json— checkpoint (max atseen), boundary-second(id,op,at)dedupe set (the feed window is inclusive), ledger-id → post-id map, resolved channel id. Written atomically (tmp +os.replace). - Config:
bridge.envnext to the script (orPULSE_BRIDGE_ENV); environment variables override. See the file for keys (poll interval, mib base URL, workspace, channel, mention handle, token file). - Poll cadence: every 30 s the daemon runs
shre-items feed --since <checkpoint>and processes new records inatorder. A failed record stops the batch before the checkpoint advances past it, so it is retried next cycle.
launchd
ai.shre.pulse-bridge — KeepAlive daemon, logs to
~/.shre/pulse-bridge/bridge.log:
cp ai.shre.pulse-bridge.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.shre.pulse-bridge.plist
v0 limitations
- No real user-mention primitive. mib007 comms has agent @mentions
only (the first
@handlein a message that matches a workspace agent triggers an AI reply). There is no user mention/notification hook, so needs-you escalations are the literal text@nir NEEDS YOU: …. - Mention path is broken on this instance (found during smoke): ANY
@handlein a message makesPOST …/messages500 after the row is inserted — the mention agent-lookup queries a nonexistenturl_keycolumn onagents(comms.ts~line 226; error in mib007 stderr log). Retrying such a failure duplicates the message. The bridge therefore (a) zwsp-neutralises every@it emits, including its own@nirescalation (renders identically in the UI), and (b) treats an HTTP error on a comment as non-retryable (DROP … comment not retriedin the log) — comments are best-effort; posts still retry. - Updates for items that pre-date the bridge and were never seeded (closed before first run) are skipped with a log line — there is no post to comment on.
- One workspace, one channel. Multi-workspace fan-out is v1.
- Fork-links (post → ledger deep link and back) and reverse intake (posting in Pulse creating/annotating ledger items) are v1.
- Reactions on posts are not mirrored back to the ledger.
- If the envelope migration (shreai #163) lands and Pulse moves to
feed_items, the write path here must be revisited.