Every dispatch Pete publishes is an accomplishment — a death, a clear, a
milestone — and an accomplishment is a newspaper clipping the moment it lands.
No refresh interval fixes that. So the page never felt alive, and it never was
going to.
The board is the other kind of thing: state that is currently true. gogobee
pushes the whole roster, we replace ours with it, and it renders above the
clippings. An open tab re-polls so it keeps telling the truth.
Replace, never merge: anyone gogobee omits (opted out, no character) drops off
the public page. That omission IS the opt-out — a standing row showing class,
level and zone names the player anyway, so "an adventurer" would have been a fig
leaf.
The snapshot time lives in its own row, because an empty board is ambiguous:
nobody playing, or gogobee stopped talking to us. The page has to tell those
apart — one is a quiet realm, the other is a board that lies confidently, which
is worse than one that admits it lost the wire.
Also teaches Pete "departure", so a bored adventurer letting itself out is news.
The source tag credits an outlet Pete is relaying (`ars technica`). On
his own reporting it rendered as a trailing `pete` under a message he
already sent - him signing his own name. Drop Source on adventure posts
and omit the tag line entirely when there's nothing to credit; RSS posts
keep theirs.
gogobee has started filing a `retreat` bulletin — an expedition that ended with
the player walking out alive. Pete had no case for it, and handleAdventureIngest
answers an unrecognized event_type with 400.
That failure is silent and total. gogobee's sender treats any non-2xx as a
failure, retries eight times over roughly two hours, and then parks the row for
good. A gogobee emitting `retreat` at a Pete who doesn't know the word would not
log an error anyone reads — it would just quietly drop every retreat the realm
ever files.
So Pete has to learn it BEFORE gogobee starts saying it. Deploy order matters
here, and it is Pete first.
The copy leads with everyone coming home, because that is the true and the kind
part: a retreat is a bad day, not a funeral. Bulletin tier — it rides the daily
digest and does not interrupt the room. Announcing every failed run live would
be a firehose, and an unkind one.
https://claude.ai/code/session_01B2MwktU4RgfWkar8HM3zZn
- Don't post adventure beats when posting.enabled=false (PostNow ignores the flag)
- Keep the adventure channel out of the round-robin rotation so it can't steal bulletins from the digest
- no_push now retires a fact against the digest, not just the live post
- Default a missing occurred_at to now instead of the Unix epoch
- Keep protocol-relative image URLs on the guarded thumbnailer
- Make digest_hour=0 (midnight UTC) settable
- Quote the true window total in the digest, not the truncated slice
- Hide the Adventure section entirely when it's disabled
gogobee now splits the realm's first-ever clear (zone_first, priority)
from a later repeat (zone_clear, bulletin) so a repeat is never filed as
a first-ever. Handle both:
- renderAdventure: zone_first keeps the "cleared for the very first
time" headline; zone_clear gets the personal "{subject} clears {zone}"
headline, sharing the lede. A tier fallback still handles a legacy
zone_first that predates the split.
- advEventMeta: zone_clear -> "Zone cleared" (distinct from zone_first's
"First clear"), so a repeat's permalink page and emblem aren't stamped
"First clear".
The GUID contract is otherwise unchanged: prefix == event_type, so the
permalink label derives correctly. Test: TestRenderZoneTaxonomy.
Deploy this before the matching gogobee change — a zone_clear fact hits
an un-updated Pete as an unknown event_type (400).
Pete's side of the Adventure news feed. Receives structured game-event
facts from gogobee, templates them in Pete's warm-reporter voice, and
publishes to a new /adventure section + live Matrix posts.
- adventure.go: bearer ingest + fact-guard + 13 event templates;
/adventure/{guid} permalink (story.html); per-event SVG emblems at
/adventure/art/{type}.svg (card image + og:image); NoPush suppresses
the live Matrix post (cold-start backfill).
- adventure_digest.go: daily BULLETIN roundup at DigestHour (UTC);
unposted-in-48h = bulletins; marks them digested; per-day ?digest= URL
avoids canonical dedup.
- config AdventureConfig (enabled/ingest_token/channel/digest_hour);
web.New takes the seam + a priority poster; started in main.
- adventure theme colors; thumbURL passes through local emblem paths;
adventure pages are noindex (player-named; gap #5).
Claude-Session: https://claude.ai/code/session_017mEwUmmS7aQTP2NQXj6rUa