feat: the line of the night, picked by the GM or voted by the table (#1191) #1209

Merged
claude-bot merged 10 commits from feat/1191-line-of-the-night into main 2026-10-17 10:59:41 +00:00
Collaborator

Fixes #1191: the line of the night.

Owner's decisions (comments on #1191):

  • The GM picks, or the table votes, set per campaign in Settings → General; the GM picks by default.
  • Voting opens when the GM approves the summary and closes three days later. The GM can close it early, and a tie or no votes falls to the GM.

Server:

  • Migration a1191b0e5701:
    • sessions.best_highlight_id and line_vote_closed_at;
    • campaigns.line_of_the_night_mode;
    • the line_of_the_night_votes table, unique per session and voter.
  • GET/PUT /api/sessions/{id}/line-of-the-night, PUT/DELETE …/vote, and POST …/close.
  • Highlights carry is_best, and the campaign highlights list takes ?best_only=true.
  • A Beat sweep stores the winner after the three days. A GET works it out without writing.
  • Counts are hidden from everyone, the GM included, until the vote closes, and the GM can pick only after it closes, so a GM can't override the table mid-vote.
  • Export carries the mode and each session's line, additively.
  • The bot labels the approved post's quote "Line of the night" when extra.top_quote.is_best. This is additive, with no contract bump.

Screens:

  • the Settings radio;
  • the Review tab's mark and move, the vote state and "Close voting now";
  • the Read view's line shown first, the vote toggles, and the winner's count after close;
  • the Highlights page's "Lines of the night" filter.

Tests:

  • Backend on docker-test: test_line_of_the_night (25 new), export, highlights and bounds, 1031 passed, plus 147 on the rerun of the fixed pins.
  • Bot faces: 583 passed.
  • Vitest: 546 of 548 passed, then the fixed files reran clean (85 of 85).
  • ruff and checks clean.
  • Journey J6 timed out at a load average of about 35 on docker-test, so this PR's CI run is its real check.

Merge note: this is the first of four 4.6.0 migrations, all based on f1187a1b2c3d. The others are re-pointed after this merges.

🤖 Generated with Claude Code

Fixes #1191: the line of the night. **Owner's decisions** (comments on #1191): - The GM picks, or the table votes, set per campaign in Settings → General; the GM picks by default. - Voting opens when the GM approves the summary and closes three days later. The GM can close it early, and a tie or no votes falls to the GM. **Server:** - Migration `a1191b0e5701`: - `sessions.best_highlight_id` and `line_vote_closed_at`; - `campaigns.line_of_the_night_mode`; - the `line_of_the_night_votes` table, unique per session and voter. - `GET`/`PUT /api/sessions/{id}/line-of-the-night`, `PUT`/`DELETE …/vote`, and `POST …/close`. - Highlights carry `is_best`, and the campaign highlights list takes `?best_only=true`. - A Beat sweep stores the winner after the three days. A GET works it out without writing. - Counts are hidden from everyone, the GM included, until the vote closes, and the GM can pick only after it closes, so a GM can't override the table mid-vote. - Export carries the mode and each session's line, additively. - The bot labels the approved post's quote "Line of the night" when `extra.top_quote.is_best`. This is additive, with no contract bump. **Screens:** - the Settings radio; - the Review tab's mark and move, the vote state and "Close voting now"; - the Read view's line shown first, the vote toggles, and the winner's count after close; - the Highlights page's "Lines of the night" filter. **Tests:** - Backend on docker-test: `test_line_of_the_night` (25 new), export, highlights and bounds, 1031 passed, plus 147 on the rerun of the fixed pins. - Bot faces: 583 passed. - Vitest: 546 of 548 passed, then the fixed files reran clean (85 of 85). - ruff and checks clean. - Journey J6 timed out at a load average of about 35 on docker-test, so this PR's CI run is its real check. **Merge note:** this is the first of four 4.6.0 migrations, all based on `f1187a1b2c3d`. The others are re-pointed after this merges. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
fix: no best_only when it is off (#1191)
Some checks failed
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 59s
CI / Backend lint (ruff) (pull_request) Successful in 31s
CI / Bot/backend version sync (pull_request) Successful in 26s
CI / Feedback site tests (pull_request) Successful in 45s
CI / Does this change touch the recording path? (pull_request) Successful in 10s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Which journeys does this change need? (pull_request) Successful in 12s
CI / Bot tests and audit (pull_request) Successful in 2m39s
CI / Docker image build (pull_request) Successful in 2m54s
CI / Frontend (shard 1/2) (pull_request) Successful in 10m36s
CI / Frontend (shard 2/2) (pull_request) Successful in 14m35s
CI / End-to-end journeys (desktop) (desktop) (pull_request) Successful in 14m10s
CI / Backend migration, tests, and audit (pull_request) Failing after 31m58s
510b31b627
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
claude-bot scheduled this pull request to auto merge when all checks succeed 2026-10-17 07:48:40 +00:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge main into feat/1191-line-of-the-night
Some checks failed
CI / Backend lint (ruff) (pull_request) Successful in 26s
CI / Does this change touch the recording path? (pull_request) Successful in 26s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 1m5s
CI / Feedback site tests (pull_request) Successful in 42s
CI / Which journeys does this change need? (pull_request) Successful in 24s
CI / Bot/backend version sync (pull_request) Successful in 1m9s
CI / Docker image build (pull_request) Successful in 1m17s
CI / Bot tests and audit (pull_request) Successful in 2m6s
CI / Frontend (shard 2/2) (pull_request) Successful in 7m7s
CI / Frontend (shard 1/2) (pull_request) Successful in 8m26s
CI / End-to-end journeys (desktop) (pull_request) Successful in 16m43s
CI / Backend migration, tests, and audit (pull_request) Failing after 25m56s
749f6a7e8e
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test: drop the stale Session row from the title-reader list (#1191)
All checks were successful
CI / Which journeys does this change need? (pull_request) Successful in 13s
CI / Does this change touch the recording path? (pull_request) Successful in 14s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Bot/backend version sync (pull_request) Successful in 1m1s
CI / Backend lint (ruff) (pull_request) Successful in 1m9s
CI / Feedback site tests (pull_request) Successful in 1m16s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 1m27s
CI / Docker image build (pull_request) Successful in 2m16s
CI / Bot tests and audit (pull_request) Successful in 2m33s
CI / Frontend (shard 2/2) (pull_request) Successful in 16m20s
CI / Frontend (shard 1/2) (pull_request) Successful in 19m21s
CI / End-to-end journeys (desktop) (pull_request) Successful in 21m2s
CI / Backend migration, tests, and audit (pull_request) Successful in 27m26s
1b3993c931
list_campaign_quotes now reads sess.title, so the Session row was a row nobody checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No description provided.