Build lane 4: sessions (SESS-1 to SESS-7) #730
Closed
opened 2026-09-22 00:12:21 +00:00 by claude-bot
·
12 comments
No Branch/Tag specified
main
feat/1328-fill-it-in
feat/1328-fill-frontend
feat/1328-fill-backend
feat/9-foundry-push
fix/9-foundry-live
feat/9-foundry-push-frontend
renovate/celery-5.x
feat/5-foundry-connect
feat/9-foundry-push-backend
feat/9-foundry-push-module
feat/5-foundry-frontend
feat/5-foundry-backend
feat/5-foundry-module
release/v4.8.0-rc1
docs/d341-convert-draft
feat/958-update-to-version
feat/958-convert-sheet
feat/958-pathbuilder-import-frontend
fix/1360-heading-order
feat/958-pathbuilder-import-backend
feat/11-weekly-digest
feat/1341-auto-update
docs/d332-superseded
chore/1345-names-cleanup
feat/1342-mentioned-pages
feat/1328-recipes
fix/1346-pgdg-key
perf/1247-shared-recording-stream
chore/132-gitleaks-allowlist
release/v4.7.1
spike/foundry-module
release/v4.7.1-rc1
docs/decisions-d332-d337
fix/bot-certifi
chore/release-4.7.0
chore/release-4.7.0-rc4
chore/deps-4.7.0
chore/release-4.7.0-rc3
fix/1280-quote-must-say-it
fix/1257-names-row-squeeze
chore/release-4.7.0-rc2
fix/1245-pg-upgrade-count
chore/release-4.7.0-rc1
feat/1257-names-in-prep
feat/1257-be
feat/1257-fe
feat/1257-rating-fixes
design/1328-fill-it-in
feat/1257-name-splits
fix/1326-redis-503
feat/1280-fact-suggestions
feat/1280-be
feat/1280-fe
design/1280-fact-suggestions
feat/1279-infobox
feat/1279-be
feat/1279-fe
feat/1321-shelf-copies
design/1279-infobox
feat/1243-table-find
feat/1257-who-rated
feat/1243-prep-drawer
feat/1243-sheet-pickers
design/1243-browse-in-place
feat/1315-hotwords-default
feat/1242-system-filters
feat/1257-more-name-styles
feat/506-leg3-hotwords
design/1242-system-filters
fix/1302-packs-polish
feat/1241-rules-library
design/1241-rules-library
feat/1245-postgres-18
integ/4.6.2
fix/1263-map-ui-2
fix/1263-map-server
fix/1263-map-ui-1
fix/1261-editor-link-menu
fix/1229-axe-4.14-name-mismatch
renovate/axllent-mailpit-1.x
renovate/eslint-monorepo
renovate/authlib-1.x
chore/release-4.6.0
chore/release-4.6.0-rc2
fix/460-rc2-screens
fix/460-rc2-server
fix/release-prerelease-exit
chore/release-4.6.0-rc1
feat/125-campaign-templates
feat/126-calendar
feat/1181-pictures-and-files
feat/1190-event-people
integ/4.6.0
feat/1191-line-of-the-night
feat/1200-starter-packs
chore/bot-multidict-and-playwright-group
fix/1202-this-week-answered-count
fix/122-124-leftovers
fix/1178-get-routes-that-write
fix/1203-journeys-check-names
design/125-campaign-templates
feat/126-calendar-engine
design/126-in-world-calendar
fix/1189-cited-stamp-in-range
fix/1189-v4-looser-check
fix/1189-richer-beats
fix/1113-export-bind-lists
fix/1154-release-notes-by-file
chore/release-4.5.0
chore/release-4.5.0-rc12
fix/1135-wiki-markup-as-text
fix/demo-usage-cost-in-window
chore/release-4.5.0-rc11
fix/1121-sheet-consistency
fix/1121-sheet-5e-terms-and-card-hp
copy/1122-busiest-pages
fix/1121-relevant-choices
fix/1121-wiki-create-npc-save-sheet-links
fix/1029-menu-stays-on-screen
docs/prototype-transcript-bin-wording
fix/1023-editor-save-row-back-scroll
fix/1020-search-exact-first
fix/1020-table-prep
fix/1020-shell-wordmark-footer-bell
fix/1020-wiki-article-party
fix/872-admin-kept-until-phone-tables
feat/l13-milestone-level-waiting
fix/1000-1001-bell-older-setup-context
fix/999-pronouns-in-prompts
fix/l19-other-class-feats
fix/1010-transcript-window-ordinary-confirm
docs/d254-d269-decisions
fix/702-member-search
fix/680-transcript-bin
fix/993-unidentified-prompts
fix/841-redis-timeouts
fix/990-binned-not-exported
fix/830-export-prep-shelf
fix/deps-audit-2026-10-01
fix/877-title-reads
fix/798-audio-received-at
build/lane11-17-j7
build/lane11-16-levelup
build/lane11-14-seams
build/lane11-14-seed
build/lane11-15-start
build/lane11-13-old-block-out
fix/980-review-r3
build/lane11-12-block
build/lane11-8-packs
fix/demo-seed-canonical-names
build/lane11-11-hot-half
docs/l11-decisions
build/lane11-7-convert
build/lane11-10-editing
fix/npm-audit-brace-expansion
build/lane11-9-sheet-page
fix/bot-pyjwt
build/lane11-6-content
fix/lane11-rank-names
build/lane11-2b-language
build/lane11-4-js-evaluator
build/lane11-3-server
build/lane11-5a-pf2e
build/lane11-5b-5e
feat/design-admin
build/lane11-2-evaluator
build/lane11-1-sheet-pieces
build/lane11-0-drawing
fix/943-quest-objectives-fk
fix/prepsheet-shelf-flake
fix/945-leftovers
build/demo-gm-copy
fix/901-email-landings
build/lane10-8-journeys
build/demo-seed-lanes-8-10
fix/887-gm-own-confirmation
build/lane9-5-j1-admin
fix/918-audience-click
fix/useasync-overtaken
ci/939-critical-path
test/937-backend-suite-speed
chore/claude-orchestration
fix/924-xp-gm-only
fix/session-stale-poll
docs/decisions-d239-d242
fix/930-pypdf
build/lane8-journeys
build/925-quest-editor
fix/894-private-page-pictures
build/lane8-p4-drafts
build/lane8-p7-map
build/lane8-p6-handouts-rules
fix/wiki-fixture-names
build/lane10-d227-test-usage
fix/rsvp-horizon-test-tuesday
fix/media-volume-owner
build/lane8-p3-editor
fix/912-unidentified-rename
build/lane8-p5-party-quests
build/lane8-handout-takeback
build/lane10-pickers
build/lane8-p2-article
build/lane8-6-map
build/lane10-7b-email-pages
build/lane8-5-handouts
build/lane10-7a-test-the-bot-pages
build/lane8-p1-pages
build/lane8-4-quests
build/lane8-2b-feeds
build/lane8-3-parties
build/lane8-2a-links
build/lane10-5-commands
build/lane9-6-seed
build/lane10-4b-reactions
build/lane9-4d-pages
build/lane9-4c-pages
build/lane10-4a-posts
build/lane10-3-email
fix/891-web-fonts
build/lane9-4b-pages
build/lane10-6-test-the-bot
build/lane10-2-notify-out
build/lane8-1-wiki-text
build/lane9-4a-frame
design/lane10-drawings
fix/j6-budget
fix/j5-phone-flake
fix/869-test-leaks
fix/843-record-start-followups
build/lane7-all
build/lane6-all
build/lane9-b2-server
chore/changelog-fragments
docs/decisions-d218
build/lane9-a-owner-overview
fix/rule-card-level-label
fix/834-retention-semantics
fix/o3c-record-without-announcement
docs/decisions-d179
docs/decisions-d131-d170
fix/851-commit-before-response
build/lane6-j3-seed
build/lane9-b1-d67-identity
fix/841-blocking-loop
build/lane9-c-backups-audit
fix/vote-race-and-start-commit
fix/recording-announcement
fix/proposal-read-leak
fix/last-admin-guard
build/lane6-p4c-planning
build/lane6-p4b-margin
build/lane6-p4a-sheet
build/lane5-j4-seed
build/lane6-base
build/lane7-pages-talk
build/lane5-pages
build/lane7-pages-safety
build/lane7-p3-safety
build/lane7-p2-notify
build/lane6-p3-planning
build/lane6-p2-history
build/lane6-p1b-items
build/lane7-p1-threads
build/lane5-p6-faces
build/lane6-p1a-sheet
build/lane5-p5-find
build/lane5-p4a-board
build/lane5-p4b-scenes
build/lane5-p3-live
build/lane5-base
build/lane5-p2-cards
docs/lane5-decisions
build/review-r2-wide
fix/review-r1
build/lane5-p1-scenes
build/demo-seed
build/lane4-journeys-j5
build/lane4-page-review-b
build/lane4-page-review-a
build/lane4-page-read
build/lane4-journeys
build/lane4-page-sess2
build/lane4-page-sess1
build/lane4-notes
build/lane4-discord-on-approval
build/lane4-scheduling
build/lane4-versions
build/760-session-number
build/lane4-decisions
build/797-erase-no-regenerate
build/test-race-audit
build/lane3-completions
build/794-dark-only
build/796-titles-scroll
build/791-retention-anchor
build/a11y-sweep
build/shell-followups
build/retention-preview
build/753-backup-readback
docs/d91-d93
build/lane3-j1
build/ci-harness-paths-selftest
fix/useauth-test-race
build/ci-harness-paths
build/777-ai-settings-read
build/lane3-settings-c
build/lane3-settings-b
build/lane3-j6
build/lane3-sessionform
build/lane3-settings-a
build/lane3-members
build/lane3-thisweek
build/lane3-story
chore/87-align-python-3.12
v4.8.0-rc1
v4.7.1
v4.7.1-rc1
v4.7.0
v4.7.0-rc4
v4.7.0-rc3
v4.7.0-rc2
v4.7.0-rc1
v4.6.2
v4.6.2-rc4
v4.6.2-rc3
v4.6.2-rc2
v4.6.2-rc1
v4.6.1
v4.6.1-rc1
v4.6.0
v4.6.0-rc2
v4.6.0-rc1
v4.5.3
v4.5.3-rc1
v4.5.2
v4.5.2-rc1
v4.5.1
v4.5.1-rc2
v4.5.1-rc1
v4.5.0
v4.5.0-rc12
v4.5.0-rc11
v4.5.0-rc10
v4.5.0-rc9
v4.5.0-rc8
v4.5.0-rc7
v4.5.0-rc6
v4.5.0-rc5
v4.5.0-rc4
v4.5.0-rc3
v4.5.0-rc2
v4.5.0-rc1
v4.4.1
v4.4.0
v4.3.0
v4.2.3
v4.2.2
v4.2.1
v4.2.0
v4.1.2
v4.1.1
v4.1.0
v4.0.1
v4.0.0
v3.11.4
v3.11.3
v3.11.2
v3.11.1
v3.11.0
v3.10.0
v3.9.1
v3.9.0
v3.8.0
v3.7.0
v3.6.1
v3.6.0
v3.5.0
v3.4.1
v3.4.0
v3.3.0
v3.2.0
v3.1.0
v3.0.0
v2.1.0
v2.0.0
v1.1.0
v1.0.0
v0.12.0
v0.11.0
v0.10.0
v0.9.1
v0.3.3
v0.9.0
v0.8.0
v0.3.2
v0.3.1
v0.3.0
v0.7.0
v0.6.0
v0.5.0
v0.4.0
v0.2.1
v0.2.0
v0.1.1
v0.1.0
Labels
Clear labels
backend
Issue related to the backend
bot
Issue related to the bot
bug
Something is not working
duplicate
This issue or pull request already exists
enhancement
New feature
frontend
Issue related to the frontend
help wanted
Need some help
invalid
Something is wrong
question
More information is needed
recording
Issue related to the recording system
security
Security hardening / vulnerability work
wontfix
This won't be fixed
No labels
backend
bot
bug
duplicate
enhancement
frontend
help wanted
invalid
question
recording
security
wontfix
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/Quest-Board#730
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Build lane 4 of the v4.5.0 redesign. The brief is
docs/design/v4.5.0-brief.md(§9, the lanes in order); the build plan isdocs/design/v4.5.0-build-plan.md(the rollout rule, the design-system mapping, the journeys as tests). Umbrella: #366. Goes after lane 3.Scope
Surfaces: SESS-1 to SESS-7: a session before, during and after; voting and Are you in?; the transcript and summary review; the checklist; the recording facts.
The drawing:
/feedback/prototype/lane3— the page the build must match, still by still.Decisions: the brief §7, and each surface's header in
redesign-surfaces/sources/headers.md.Server changes it needs (in this lane or an earlier one)
IS-379); soft answers on pencilled-in sessions (D50); one notes model (D30)Acceptance
coverage/lane3.pyclassifies as drawn or replaced is built as the prototype draws it; the script is the checklist. Rows it marks behaviour are tested, not drawn.vocabulary.js; no page-level error destroys rendered content; every async operation shows progress and a next action on failure; disabled controls say why.redesign-surfaces/sources/headers.md(Decided lines and the owner's review notes) are honoured; a departure is a decision change on #659 first.🤖 Generated with Claude Code
Two things lane 3 is leaving on your doorstep. Neither blocks anything; both are here so this lane starts from a list rather than a surprise.
1.
viewerSecondaryTimeisIS-003, and D17 retires itwebapp/frontend/src/utils/datetime.jshasviewerSecondaryTime— the campaign-zone-plus-viewer-zone pair shown side by side. That is exactly what D17 supersedes:Its only two callers are
SessionDetail.jsxandcomponents/VotingGrid.jsx— both of which this lane replaces (D17's surfaces are CAMP-1 and SESS-1, SESS-2, SESS-3).Lane 3 deliberately did not touch them: converting a page this lane owns, to a rule this lane has to apply anyway when it rebuilds it, would have been churn — and the right end state is that
viewerSecondaryTimeis deleted, not converted.What to use instead:
webapp/frontend/src/utils/when.js, which lane 3 consolidated and #767 corrected.whenText(iso)renders the reader's own zone with its abbreviation and deliberately takes no zone parameter — it had one, every caller passed the campaign's, and a parameter that can reinstate a retired decision is a parameter that will.tableDay(iso, tz)andzoneShift(iso, tz)give you D17's reconciliation sentence, and the offset is computed from the two wall-clock readings of that one instant, so summer time on one side only is handled.Two things that will cost you a cycle otherwise, both learned the hard way in #767:
Europe/Londonrenders as "GMT+1" under en-US CLDR — which is what the CI image runs — and as "BST" under en-GB. Assert that a zone marker is present and is not the table's, not either literal.TZ=…does not reach a headless browser on Windows; it reads the OS zone. Move the table's zone in your fixture instead of the reader's.2.
#760, session numbering, is most naturally yoursD86 (owner, 2026-09-22): a session gets a number, given at creation, frozen, never reused, so a cancelled session leaves a gap. The issue is #760, with the column, the backfill rule and the concurrency point written up.
Lanes 1, 2 and 3 have all shipped the session's title wherever the drawing says "Session 14", because no ordinal exists. That looks right and is not wrong — but this lane owns
SESS-1toSESS-7and rewrites every surface that names a session, so doing the column as this lane's server PR means building against a number rather than retrofitting one afterwards.Not a requirement, just the cheapest moment.
🤖 Generated with Claude Code
A third inheritance from lane 3:
/sessions/:idfails the axe gate on 13 nodesJ6 (#770) walked as far as the session page and CI failed on it. The diagnosis is filed as #775; this is the part that is specifically lane 4's.
SessionDetail.jsxand its children (SessionRsvp.jsx,PostSessionChecklist.jsx) fail WCAG 2.2 AA 1.4.3 on 13 nodes, deterministically — reproduced three times with identical selectors and ratios. Two distinct bugs:bg-amber-900/50 text-amber-300andbg-green-900/50 text-green-300, bare and unconditional, so a translucent dark chip composites over light paper: 1.86:1 and 1.89:1.Ratios run from 1.21:1 to 3.9:1 against a 4.5:1 minimum. The full table is on #775.
J6 no longer walks this page, deliberately:
/sessions/:idwas never in J6's scope (its recap act is This week'sSE-006), the markup is this lane's to delete, and lane 3's acceptance gate should not be blocked on lane 4's debt.a11y-baseline.jsis untouched and still{}— and per #771 it could not have expressed a single-page tolerance anyway.What this lane inherits: the rebuild has to clear all thirteen, and J5 walks this page by name ("after the session: the checklist, transcript and summary review"). Whoever writes J5 will meet them on the first run, so it is worth clearing them before that rather than discovering them as a blocker.
One thing worth stealing from how this was found
J6's scan of this page passed twelve times locally and failed on the runner. It was not flaky markup — the page fails identically every time. The scan was racing the page. Every failing element belonged to a second wave of requests (the roster's chips, the checklist), and the assertions before
axe()were satisfied by the first wave alone, so the chips landed inside axe's own injection window and whether the scan saw them came down to machine speed.The rule is now in the harness README: wait for the slowest thing on the page before you scan it, and pick that thing deliberately — the last request the page makes, not the first. A scan whose target is a race certifies nothing, and it fails in the place least likely to be believed. Worth reading before writing J4 or J5.
🤖 Generated with Claude Code
Picking lane 4 up now that lane 3 and its follow-ups have merged (#799–#802; #803, the test-race audit, is in CI).
Update to the inheritances above: #775's thirteen session-page nodes were fixed by #793 and #801, which cleared every dark-only colour app-wide. The rebuild still has to keep them clear.
First step: a survey covering the coverage checklist (
coverage/lane3.py), the prototype's stills, the SESS headers and D-numbers, and the server state for D30, D31, D50, IS-379 and #760. Per-PR contracts follow from it, in the order lane 3 used: server PRs first, then the pages, then J2 and J5.🤖 Generated with Claude Code
Owner's answers to the lane 4 survey questions (2026-09-24)
Also settled by D94 (#797): old summary versions stay as written after an erase, like the current summary.
🤖 Generated with Claude Code
The four follow-ups, settled (owner, 2026-09-24)
L2, the Discord post waits for approval.
session_summarisedfires. Check whether the bot's approved-repost path assumes a draft message exists. If the bot must change to cope, it's a contract change (bump both sides).L4, notes.
L6, series: #804. Moving a series session moves the later ones where needed, keeping the pattern: each lands on a regular day at least half an interval after the one before. Built in the scheduling server PR.
L9, in-story dates, deferred to #126 (the game calendar, v4.6.0), with the owner's requirements added there:
Lane 4 builds no in-story dates.
lane3.py's IS-092 rows move to deferred (#126), and IS-170 (naming a voice) goes to deferred on #542.These become decision rows D95 onwards when lane 4's first PR lands.
🤖 Generated with Claude Code
Lane 4 progress: three server PRs merged
#807, session numbers (#760, D86). "Session 14" in the breadcrumb, bell, live bar, Home, This week and Sessions list. Migration
f3a4b5c6d7e8.#808, corrections that wait (D31) and every version of a summary (IS-379/D51). GM endpoints for pending corrections and for summary versions with put-back. The version store is generic, for the table note's history (D97). Migration
c5d6e7f8a9b1.#809, scheduling (D99, D100, D101, #804):
recorded_seconds.Migration
d7e8f9a0b1c3.Still to come
🤖 Generated with Claude Code
Two more owner answers (2026-09-24)
/recap,/ask, the reminders' "Previously on" and the session-completed post. Going into the D96 PR.CLAUDE.md's recording-pipeline description (andbot/CLAUDE.md's) for D96. That goes in the D96 PR.🤖 Generated with Claude Code
The first page PR (5a) is built: the session page's frame, and SESS-1
pages/session/SessionPage.jsxrenders a vote (the desktop grid, and D29's phone list) and pencilled in. Every other status still goes to the oldSessionDetail.Campaign › Sessions › Session 14, and the Contents lists the session's sections under Sessions.Departures, accepted:
AudiencePickerwords: "Just you and the GM", "Everyone at the table", "GMs only". These are the app-wide audience model, the same meaning as D97's "Just me and the GM" and "The table", so it reads the same everywhere notes or posts have an audience.🤖 Generated with Claude Code
Lane 4 progress, 2026-09-24
Merged since the last update:
VotingGrid,SessionRsvpandviewerSecondaryTime(IS-003, this issue's first inheritance)./sessions/:id/reviewfor the GM (the legacy page under the new head for now),audio_deleted_at,summary_limits, and D28's stripping.Building: 7a, the GM's Review part one: still to do, the recording, the summary with versions and saved corrections, and the single approval (D95).
Then:
SessionDetail.🤖 Generated with Claude Code
Lane 4 is complete (2026-09-25). Left open for the owner's review.
Every session state now renders the new design, and
SessionDetailis deleted. J2 and J5 pass on desktop, phone and keyboard-only, with axe clean.coverage/lane3.pyis fully classified: every SESS row is built, replaced, behaviour, elsewhere or deferred.What merged
Server
recorded_secondsPages
VotingGrid,SessionRsvpandviewerSecondaryTime(IS-003).Journeys
Decisions: #805 (D94) and #806 (D95–D104). D105 and D106 are in #810 and #811.
Bugs the lane found and fixed
app/.ui/Segmentedcouldn't be reached by keyboard with nothing chosen (fixed in #818).Departures (each recorded in its PR)
Deferred, and where it went
WikiProposalscontrast, and the 60 s lore wait → lane 8 (#734).Worth knowing before a deploy
f3a4b5c6d7e8c5d6e7f8a9b1d7e8f9a0b1c3d6e7f8a9b1c2e9a0b1c2d3f4, the notes data migration: GMs can then read notes that were private (D106).a9b0c1d2e3f5🤖 Generated with Claude Code
The owner's review of lane 4 on dev, 2026-09-25. Looks right: numbers, the vote, confirmed, Manage, cancelled, notes, all three parts of Review, and approving.
Skipped:
Fix in batch R1 (
fix/review-r1):Signed off by the owner on the Redesign Review page, 2026-10-01. Both re-checks for this lane (reading a session; its states) are marked OK. No changes asked for. Closing.