Repository navigation
Live tab: refuse an agenda row that needs a role instead of timing it under the default (#91 follow-up) - #140
Merged
Merged
Conversation
…Table Topics' with no timing rules Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…atch The first plan fixed the keyword ladder so "(Table Topics)" landed on Table Topics Speech. The direction changed: a fallback to a built-in can land on a role the user removed, and the closest-match step from #77 gives false positives ("(Table Topics)" became a custom Table Topics Master). Import now takes only an exact role name and highlights the rest on the Agenda tab for a manual pick.
…e rest A line gets a role only when its bracket names one of the roles in the dropdown (same words; case, spacing and punctuation ignored). Any other line keeps its text as written, with no rules. The Agenda tab highlights such rows, with a "Pick a role" list of the saved roles and a banner that counts them; clicking one asks for a role instead of opening the Live tab. The check is derived from the current roles, so rows saved earlier as 'Table Topics' and rows whose role was later removed are highlighted too. Completed rows and breaks never are. matchCustomRole and detectRoleFromText had no callers left and are removed. Add Item now starts on the first listed role when Standard Speech is hidden, so it never saves a role the picker didn't show. agenda-import gains IM-06 and new expectations for IM-02 and IM-05. timer-core is reviewed: importBulkSpeakers is under its Not covered.
The real-client run was blocked: the Mac's screen was locked, so no step ran. The branch is deployed to dev (version 9b18a973) for the rerun. verified_at stays at the last real run.
The Agenda tab already refused to open a row whose role isn't one of the user's. The Live tab had two other ways to load it: its agenda picker (the panel's speaker suggestions, and the Full-Screen Timer's speaker list) and the auto-advance after FINISH. Either loaded the row, and the effect from e876ca8 then moved it to Standard Speech or the first listed role without a word. Now all three refuse the row and show "Pick a role for {name} on the Agenda tab first". After FINISH the name field is cleared and the role stays as it was; the running order stops at that row instead of skipping it. The e876ca8 effect still moves a hand-picked role that leaves the list; for a loaded agenda row whose role leaves the list it lets go of the row (clearActiveSpeaker, new in the web TimerContext) with the same toast, instead of re-roling it. Zoom app and web timer. Tests: both LiveTab.test.jsx files, a Playwright case in zoom.timer-flow.spec.js. timer-core gains TC-13; timer-sounds and club-card-sets reviewed; agenda-import's follow-up line removed.
Passed in the real Zoom client against dev version 5b28ba86. The device ran a club role list without Standard Speech or Ice Breaker, so TC-13 now says how to substitute listed roles. verified_at is unchanged: only TC-13 ran.
Both specs ran green in the real Zoom client against dev a249d5d7: agenda-import IM-01..IM-06 and timer-core TC-01..TC-08, TC-10, TC-11 (TC-09 and TC-12 are human steps). The device hides every built-in role, so the agenda-import needs line now says to use a listed role in its place, and to keep the device's own custom roles unless one clashes with a line in the spec.
INDEX conflict on the timer-core row: kept #140's Covers text and #139's verified column (b029a29, 2026-11-13). timer-core stays `stale` here: its full run on b029a29 predates #140's LiveTab.jsx change, on which only TC-13 ran (5de8185). agenda-import takes #139's `current`; #140 changes none of its covered files. timer-core's #91 note now names the steps that reran on b029a29.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #91. Follow-up to #139, and built on its branch: merge #139 first. Until then this PR's diff also shows #139's commits (now up to
95fbaeb, merged in byc65998a); this PR's own commits are5de8185and73217f4.Why
#139 stopped Simple Format import from guessing roles: a row whose bracket names none of your roles keeps that text as
role, has norules, and the Agenda tab won't open it. The Live tab still had two other ways to load such a row:handleSelectSuggestion) and the Full-Screen Timer's speaker list (StageSpeakerPicker,onSelectSpeaker={loadSpeakerFromAgenda});handleFinish).Either loaded the row, and the effect from e876ca8 ("the selected role left the list") then moved it to Standard Speech or the first listed role without a word. That is the same silent guess #91 removed from the import, one step later.
What changes
clearActiveSpeaker), the field clears, and the same toast shows. The row keeps its role for the Agenda tab to flag, and finishing whatever is timed next neither completes it nor advances past it.TimerContextgainsclearActiveSpeaker(the Zoom app already had it). The check is Simple Format import: ask for a role when the bracket doesn't name one, instead of guessing (#91) #139'sagendaItemNeedsRole, so the Live tab and the Agenda tab agree on which rows need a role.Security
None. Client-side UI only.
Production impact
Ships with or after #139, whose
agendaItemNeedsRoleit uses. With both, master users who import a loosely named role get a toast instead of a speaker timed under the default role, from the Live tab's suggestions, the Full-Screen Timer's list and FINISH. No flags, no migration, no API or sync change. Rollback is a revert.Testing
npm test: 2275 pass (116 files). New: "an agenda row that needs a role (Simple Format import: ask for a role when the bracket doesn't name one, instead of guessing #91)" inapps/zoom-app/src/components/LiveTab.test.jsx(suggestions, stage picker, FINISH, hand-picked role leaving the list, loaded row whose role leaves the list) and the same set minus the stage inapps/web/src/components/LiveTab.test.jsx. Against the pre-changeLiveTab.jsxthe four refusal tests fail in the Zoom app and three in the web app; the e876ca8 test passes on both, as intended.npm run test:e2e: 44 pass. New ine2e/zoom.timer-flow.spec.js: "the Live tab does not time a row that needs a role: suggestions, FINISH, stage picker (Simple Format import: ask for a role when the bracket doesn't name one, instead of guessing #91)".npm run test:specs: valid (8 specs).timer-coregains TC-13;timer-soundsandclub-card-setsreviewed (notes under Not covered); the follow-up line inagenda-import's Not covered is gone, and its intro points to TC-13.Evidence (real Zoom client)
timer-coreTC-13 ✅ on this branch @ 5de8185, deployed to dev as version 5b28ba86 (committed vars:ENTITLEMENT_ENFORCE=1,FLAGS_FORCE=0). Run log:test-runs/2026-11-13-91-live-tab-needs-role/run.md(local).POST /api/club/meetings/20261113/speeches200). PostHog:timer_startedandspeech_finishedfor Bob / 1min Role only.The device runs Claude Test Club's role list (no Standard Speech or Ice Breaker), so the lines used listed roles; TC-13 now says how to substitute.
Not verified
timer-coreTC-01…TC-12 were not rerun on this PR's code. Simple Format import: ask for a role when the bracket doesn't name one, instead of guessing (#91) #139's run passed TC-01…TC-08, TC-10 and TC-11 onb029a29, before this PR'sLiveTab.jsxchange; this PR changes only the agenda paths there, and Bob's START → FINISH → upload in TC-13 went through the same start/finish code. The spec keepsverified_at: b029a29and is markedstalehere until those steps rerun on this code.timer-soundsandclub-card-setswere reviewed, not run: no step loads an agenda row, and both need a second account or computer.loadSpeakerFromAgenda), as before.Look here first
handleSelectSuggestion)🤖 Generated with Claude Code