Skip to content

End an interview when it is over - #33

Merged
jserv merged 3 commits into
mainfrom
dev
Sep 9, 2026
Merged

End an interview when it is over#33
jserv merged 3 commits into
mainfrom
dev

Conversation

@jserv

@jserv jserv commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

A thirty-minute mock interview was reported as taking over ten minutes to produce its evaluation, with no way to tell a slow report from a hung one, so the candidate closed the tab. The report call is not what took that long: it is bounded at 125 seconds and measures about six at the median, with thinking pinned off. The wait was the interview's own clock. Nothing could end a session except the countdown or the candidate's own button, so a conversation that genuinely finished at minute 18 of a 30-minute booking sat idle until the timer caught up, behind a spinner that said nothing about which of the two was happening.

The interviewer can now close a finished session itself, through the same control packet the browser and the server-side deadline already send, and refused until recorded evidence says the rounds actually ran. Alongside that: the ending overlay counts the wait instead of only spinning through it, a report that never lands offers the offline summary beside "leave the room" rather than making leaving the only exit, and a paused interview keeps its deadline instead of freezing until the server's two-minute grace expires.

The second half is the enhancement asked for on the issue: that evaluation happen during the conversation's natural pauses rather than all at the end. Each idle window long enough now spends a short call, off to one side of the room loop, on the stretch of transcript nobody has assessed yet; those notes reach the final report prompt beside the interviewer's own phase evidence. Both are added to the transcript rather than replacing it, because the communication score is read almost entirely from speech. To be plain about the trade: this buys what the report is written from, not when it lands, and session-wide token spend goes up rather than down even though the final call gets cheaper.

Verified with ./scripts/test.sh, the full offline gate: cargo fmt, clippy, the Rust suites, the Python and Node suites, ESLint, the generated-artifact drift checks, cargo-audit and the hook suite. All green. The frozen prompts under tests/golden changed on purpose and were regenerated with UPDATE_PROMPT_GOLDEN=1. Every load-bearing line was checked by reverting it and confirming a test noticed, which is how three fixes that had no coverage were found and given some.

Deliberately left out: the idle-window reviewer ships together with the prompt change that makes the interviewer's own phase evidence richer, so their separate contributions to report quality are not measurable from this branch. If that matters, the two are separable into their own commits.

Closes #31


Summary by cubic

The interviewer can now end a session when the conversation is finished, so candidates no longer wait out a timer after an interview is actually over. The ending overlay counts the wait, a report that never lands offers the offline summary, and paused interviews keep their deadline. Evaluation also gathers during natural pauses: short idle-window reviews send notes to the final report prompt, alongside rather than replacing the transcript.

Key changes

  • Adds end_interview tool, gated on evidence that both coding rounds ran.
  • Shows elapsed time on the ending screen and always offers the offline summary button.
  • Paused interviews no longer lose their deadline.
  • Idle windows over 8 seconds trigger a bounded review of unreviewed transcript, appended to evidence.
  • Session-wide token spend increases, though the final call gets cheaper.

Testing

  • Full test suite passes, including new unit and browser tests; golden prompts regenerated intentionally.

Closes #31

Written for commit 21bcdd2. Summary will update on new commits.

Review in cubic

cubic-dev-ai[bot]

This comment was marked as resolved.

A thirty-minute session was reported as taking over ten minutes to
produce its evaluation. Report generation cannot do that: it is bounded
at 125 seconds and measures six at the median. The wait was the
interview's own clock, because nothing could end a session except the
countdown or the candidate's own button, so a conversation that finished
early sat idle behind a spinner that said nothing about which of the two
was happening. The interviewer can now close a finished session itself,
refused until recorded evidence says the rounds actually ran, and the
report carries the reason it acted on rather than leaving the page to
infer one from its own clock. Around that: the ending overlay counts the
wait, a report that never lands offers the offline summary beside
leaving and releases the room when it does, and a paused interview keeps
its deadline instead of freezing until the server's grace expires.

The reading the final reviewer does is gathered in the pauses as well.
Each idle window long enough spends a call, off to one side, on the
stretch of transcript nobody has assessed yet, and those notes reach the
report prompt beside the interviewer's own phase evidence, delimited as
the untrusted material they are a reading of. Both are added to the
transcript and neither replaces it, because the communication score is
read almost entirely from speech: this buys what the report is written
from, not when it lands, and the frozen prompts change with it. The
evidence cap now gives up a phase's spare observations rather than its
oldest, and never the only one a round gate reads.
The countdown is the browser's and the browser is the candidate's, so
the packet announcing five minutes left is a claim like any other from
that side, and nothing checked it. Accepting one early interrupts the
candidate with a warning that is not true, and now also consumes the
latch that makes the warning fire once, so the real one is refused for
the rest of the interview. The round transition beside it has been held
against this clock all along. The threshold is named on both sides and
the two copies are asserted equal.
The cut in code_head advanced by hand, so a mutation that stops it
advancing does not produce a wrong answer, it produces a hang. The
mutation gate reports that as a timeout, which is neither a pass nor a
finding, and the shard fails on it. A search over a bounded range walks
back to the same byte and cannot be turned into one.
@jserv
jserv requested review from Patriciaath999, alanhc and nosba0957 and removed request for Patriciaath999 and alanhc September 9, 2026 10:05
@jserv
jserv merged commit fcfdfa6 into main Sep 9, 2026
8 checks passed
@jserv
jserv deleted the dev branch September 9, 2026 14:06
@alanhc
alanhc requested review from alanhc and nosba0957 and removed request for alanhc and nosba0957 September 9, 2026 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

面試結束 Evaluation 產生時間過長

1 participant