Repository navigation
Let the candidate mark unclear interviewer lines - #433
April-ying wants to merge 1 commit into
Conversation
|
|
||
| function showUnclearButton(visible) { | ||
| if (!nodes.captionUnclear) return; | ||
| nodes.captionUnclear.hidden = !visible; |
There was a problem hiding this comment.
Hiding captionUnclear while it has focus drops keyboard focus to <body>: tab to Unclear, press Space, start speaking, and the next updateCaptions("you", ...) hides the focused button. The cap does the same with disabled when the next Jim turn arrives. Before hiding or disabling, check document.activeElement === nodes.captionUnclear and move focus to a stable control (the editor or the captions bar).
There was a problem hiding this comment.
Fixed: before the button is hidden or disabled while it has focus, focus moves to the captions bar, which now has tabindex="-1". Two caption tests cover candidate speech and the cap.
2346a2d to
4f27374
Compare
4f27374 to
070d623
Compare
| // Above the longest interviewer turn measured (548 bytes), so a real turn is | ||
| // kept whole, while ten lines of four-byte characters stay under 24 KB of the | ||
| // 64 KB report body. | ||
| const MAX_UNCLEAR_LINE_CHARS = 600; |
There was a problem hiding this comment.
boundedText cuts at 600 code points without any marker, and Past attempts keep no transcript, so the end of a long marked turn (often the actual question) is gone for good with nothing on screen saying so. 548 bytes was the longest of 93 sampled lines, and a long hint can exceed it. Append an ellipsis when a line is clipped so the report shows the cut.
There was a problem hiding this comment.
Fixed: a line longer than 600 code points is cut to 599 and ends in an ellipsis, so the report shows the cut. A lib test covers it.
| <button | ||
| id="caption-unclear" | ||
| type="button" | ||
| class="caption-unclear" | ||
| aria-pressed="false" | ||
| hidden | ||
| > | ||
| Unclear | ||
| </button> |
There was a problem hiding this comment.
The button now sits inside #captions-bar, which is aria-live="polite", and showUnclearButton flips its hidden at every switch between candidate and Jim captions. Unhiding it is an addition to the live region, so a screen reader announces "Unclear" before Jim lines, and the aria-pressed change is read out as caption content too. Keep the control out of the announced content: move aria-live and aria-label from the bar onto #captions-text, so only the caption text is live.
There was a problem hiding this comment.
Fixed: aria-live and aria-label moved from #captions-bar onto #captions-text, so only the caption text is announced.
Non-native candidates often miss a word or two of what Jim says and answer anyway, and nothing let them note the line to review later. An Unclear button beside the live caption marks the Jim turn on screen. Marks never reach Jim or the report request: they are resolved to transcript text when the report is saved and stored as unclearLines in the history entry, since saved history keeps no transcript, while the live export tags turns by id so a repeated line is not tagged twice. The cap of 10 keeps a marked interview within one average report of the 164 KB local history budget, and marks are dropped before they would push the 64 KB report body past the server limit, so they never cost the report. Past attempts and replay accept the field only as an array of strings, so older or hand-edited entries render as before.
070d623 to
7387d2f
Compare
| export const MAX_UNCLEAR_LINES = 10; | ||
| // Above the longest interviewer turn measured (548 bytes), so a typical turn is | ||
| // kept whole; a longer one is cut with an ellipsis that says so. | ||
| const MAX_UNCLEAR_LINE_CHARS = 600; |
There was a problem hiding this comment.
MAX_UNCLEAR_LINE_CHARS caps code points, but the history budget that decides eviction is serialized UTF-8 bytes, and the cap of 10 was justified with byte measurements (548 bytes longest, about 5.5 KB worst case). A turn of 600 non-ASCII characters passes clipUnclearLine at up to 2,400 bytes, so ten marks can reach about 24 KB and push out three or four older reports instead of one. Clipping by TextEncoder byte length (with the ellipsis inside the budget) would make the guarantee in the description hold for any script, not only English.
jserv
left a comment
There was a problem hiding this comment.
Rebase latest main branch to apply security updates.
What
During the interview, an "Unclear" button beside the "Live CC:" label marks the Jim turn on screen; pressing it again unmarks it. The button shows only while a Jim turn is on screen, and it is disabled on unmarked turns once 10 are marked. Jim is not told about a mark.
When the report is saved, the marked turns are resolved to their transcript text and stored as
unclearLinesin the history entry, after the report returns, so they are never part of the report request. The report shows a "Lines you marked as unclear" section after "Practice next", in the web card and the Markdown export, and the export also tags the marked turns in its transcript as "Jim (marked unclear)". A report reopened from Past attempts shows the section too; its export has no transcript to tag, as before.One difference from the issue body: the web report card has no transcript, so tagging inside the transcript happens only in the Markdown export downloaded at the end of the interview.
Measurements
Local history in this browser held 21 reports: 594 to 12,109 bytes each, 6,933 on average, 145,600 bytes in total against the 167,936-byte budget, so the budget fits about 24 average reports, not 500.
Interviewer lines from three downloaded reports (93 lines): median 172 bytes, 90th percentile 333 bytes, longest 548 bytes.
With about 3 bytes of JSON per string, 10 marks add about 1.8 KB at the median line length and at most about 5.5 KB if every mark were as long as the longest line seen, about 25% and 79% of an average report. An interview at the cap therefore pushes out at most one older report, so the cap is 10. A cap of 20 could cost more than one.
Tests
tests/browser/progress.test.js: an entry at the cap keeps all 10 lines, an entry past the cap or with an oversized line is bounded on read, andunclearLinesthat is missing, null, a string, a number, an object, or an array holding a non-string is read as no marks.tests/browser/captions.test.js: the button marks and unmarks the current turn, hides during candidate speech, starts unmarked on a new Jim turn, and stops marking at the cap; hiding or disabling the focused button, or hiding the bar through the idle timeout or a code edit, moves focus to the editor.tests/browser/render.test.js: the Markdown export lists and tags marked lines, and a report without marks has no section in either view.saveHistorynow passunclearLines, and the replay vocabulary test lists the new section's words../scripts/test.shpasses locally, including the Playwright browser tests. One lobby layout test, "problem cards span desktop panels and return home on narrow screens", passes on some runs and fails on others here, also on an unmodified checkout.Contract version
No version bump: no prompt, rubric, or report schema changed, and
unclearLineslives in the history entry outside the report.Screenshots
Before: the caption bar.

After: the Unclear button, unmarked and marked.

After: the report section.

Closes #391
Summary by cubic
Lets the candidate mark Jim's lines as unclear during the interview so they can review them later; pressing the new Unclear button again unmarks the line. Jim never sees the marks.
unclearLinesin the history entry, outside the report and its request, so no prompt, rubric, or report schema changes; marks that would push the report body past the server's size limit are dropped rather than costing the report.Written for commit 7387d2f. Summary will update on new commits.