adventure: give a finished run a report worth sharing
The liveblog answers "what is happening" — it is capped, it scrolls, and six hours after a run ends it is gone, because the adventurer page is about now. Nothing answered the question asked afterwards, usually by somebody who wasn't watching: what WAS that run. So a dispatch announcing a clear or a death was a paragraph about an outcome with no way back to what produced it. The report is that way back. The whole log uncapped, the numbers rolled up, and the single worst hit the party took pulled out of the middle where it otherwise reads as one line among forty. It is stable for a fortnight, which is what makes it a thing worth linking from a dispatch and worth sending to somebody. It is assembled from the same beats through the same renderer as the liveblog. A report that told a different story from the log it was built out of would be the more convincing of the two and the less true. The summary is the exception and the only prose on the channel: gogobee's model reads the finished run back and says what it was about, which is a judgement no template makes. It rides a summary beat rather than its own endpoint, so it inherits the whole channel — idempotent, retried, impossible to attach to a run that doesn't exist — and it passes the same class of guard a dispatch lede does before it reaches a public page. Visibility is the adventurer page's rule exactly, and that matters more here than anywhere: the report outlives the log by a fortnight and is linked from a public dispatch, so it is the surface most likely to still be reachable after somebody opts out. Coming off the board closes it, including through links minted days earlier. Claude-Session: https://claude.ai/code/session_012bxpQQJDjC1mTtLN3VVtBQ
This commit is contained in:
@@ -88,6 +88,13 @@ CREATE TABLE IF NOT EXISTS adventure_events (
|
||||
stakes TEXT, -- free-text noun the fact is about: a bounty, a found treasure's name
|
||||
|
||||
actors TEXT, -- JSON array; the fact-guard allow-list, kept for audit
|
||||
-- The expedition this dispatch is the ending of, when it is the ending of one
|
||||
-- (a clear, a retreat, a death). It is the join from "how it went" to "what
|
||||
-- happened", and it is the reason Pete keeps a finished run's beats for two
|
||||
-- weeks while only *showing* them for six hours: the dispatch outlives the run
|
||||
-- it announced, and a story that can't reach its own log is the whole point
|
||||
-- of the log going missing.
|
||||
run_id TEXT,
|
||||
occurred_at INTEGER NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_adv_events_subject ON adventure_events(subject, occurred_at DESC);
|
||||
@@ -154,6 +161,13 @@ CREATE TABLE IF NOT EXISTS adventure_siege_history (
|
||||
-- That means a run whose start beat never arrived still gets a row (created by
|
||||
-- whatever beat did arrive) and is simply unattributed — the log survives
|
||||
-- nameless instead of being dropped for want of a name.
|
||||
--
|
||||
-- summary is the one piece of PROSE anywhere in the liveblog. Every log line is
|
||||
-- assembled by Pete out of a beat's own nouns and numbers; this is gogobee's LLM
|
||||
-- reading the finished run back and saying what it was *about*, which is a
|
||||
-- judgement no template can make. It arrives late — its own beat, a tick or two
|
||||
-- after the run ends — and it is optional forever: with the model off, the report
|
||||
-- is the log plus the numbers, which is still the report.
|
||||
CREATE TABLE IF NOT EXISTS adventure_run (
|
||||
run_id TEXT PRIMARY KEY,
|
||||
token TEXT NOT NULL DEFAULT '', -- public board token; '' = unattributed
|
||||
@@ -164,7 +178,8 @@ CREATE TABLE IF NOT EXISTS adventure_run (
|
||||
started_at INTEGER NOT NULL DEFAULT 0,
|
||||
updated_at INTEGER NOT NULL DEFAULT 0,
|
||||
ended_at INTEGER NOT NULL DEFAULT 0, -- 0 = still walking
|
||||
outcome TEXT NOT NULL DEFAULT '' -- cleared|died|retreated|abandoned
|
||||
outcome TEXT NOT NULL DEFAULT '', -- cleared|died|retreated|abandoned
|
||||
summary TEXT NOT NULL DEFAULT '' -- LLM run summary, post prose-guard
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_adv_run_token ON adventure_run(token, started_at DESC);
|
||||
|
||||
@@ -189,6 +204,11 @@ CREATE TABLE IF NOT EXISTS adventure_run_beat (
|
||||
crits INTEGER NOT NULL DEFAULT 0,
|
||||
fumbles INTEGER NOT NULL DEFAULT 0,
|
||||
region TEXT NOT NULL DEFAULT '',
|
||||
-- prose is carried by exactly one beat kind ("summary") and is never rendered
|
||||
-- as a log line. It lives on the beat rather than on its own endpoint so the
|
||||
-- summary inherits the whole channel: idempotent on (run_id, seq), retried
|
||||
-- until delivered, and impossible to attach to a run that doesn't exist.
|
||||
prose TEXT NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (run_id, seq)
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user