lib/unfurl.py, plumbing in run_room.py (sidecars under
rooms/<rid>/links/, one digest per lid per room, transcript mirror). The
T2 deep-read (<read> below) is the recorded follow-up, not yet built —
the sidecar already freezes every section for it. This page's demo still runs the whole pipeline standalone.Live mock, real pipeline. Paste a real URL into the composer below.
Before send — the server fetches the page and a preview chip appears above the input (✕ to dismiss).
After send — the message carries the frozen card, and the right panel shows the model context as an
append-only timeline: the T1 skeleton digest goes in at send; click an outline pill to play a persona
ordering a full section via the in-band <read> tag (T2, appended next turn).
python docs\unfurl_server.py
then open http://127.0.0.1:8013/.the room — composer + bubble
what the persona sees — real extraction
<read link="L3" section="…"> in its output — the same in-band trick as
<speak>/<confer>; our code validates the id + heading against the
frozen extract and appends the section next turn (no second model call; a one-beat delay is natural
in a chat room). The T1 outline is the menu it can order from. Guardrails: max 2 fulfilments per turn,
dedup, ids anchored — never re-matched from names./api/rooms/…/linkimg/Ln, never the origin (a hotlinked og:image leaks every reader's IP/UA — the
reason Slack ships Slack-ImgProxy) · utm_*/click-id params stripped before fetch · a generic
failed-extract detector (250-char floor, halved for CJK; <15% of the page's visible text = boilerplate)
driving a ladder: recall retry → the JS-hidden-body recovery → wall verdict (paywall/bot-wall fingerprints
→ the digest honestly says「behind a wall」and carries only the card's own words, never the wall's boilerplate).
Declined, knowingly: oEmbed (rich embeds we don't render — og + title is our ladder) · headless rendering
(production unfurlers don't; cost/latency without proof of need) · robots.txt (Slack's stated position: an unfurl
acts for a human, it isn't crawling) · AMP-alternate retries (a declining asset). One place our evidence beat
the field's recipe: ftr-site-config's WeChat rule (un-hide the styles, re-extract) does NOT transplant to
trafilatura — measured; the leaf-block subtree recovery is ours and it works.docs/unfurl_server.py (port 8013, a thin harness) ·
production: lib/unfurl.py + lib/run_room.py (shipped v1032)