Choose the interview language before joining
Jim's coding greeting asked which language the candidate wanted, but answering aloud changed nothing: only the editor's language tabs reach the server, so a spoken answer kept the Python starter and the recovery briefing asked again. This implements placement B from #431, one commit per sub-task in the issue.
- The token request may name the starting language. Only an id the language tabs offer reaches the signed metadata, a whiteboard request drops it, and the agent checks it again. The interview then starts in that language with the choice recorded, so the greeting does not ask, Jim does not announce the first editor packet as a switch, and no recovery briefing asks again. A session without a language keeps today's greeting. Live prompt 33, bundle 43.
- The interview page resolves the starting language as the issue describes: the URL's
language(Try again, #310), else the language the candidate last started an interview in, else Python, whichever the problem can run first. Only C needs the judge: when the preferred language is C and its judge is still loading, Start waits up to five seconds and otherwise starts in the fallback. Every other start goes straight on. The page stores the language once the token request succeeds. - The Before you join dialog has a Programming language menu under Interview preferences, above Jim's voice and accent. It offers what the editor tabs offer by the same rule, so a class problem withholds C and a server without compiled runs withholds C, C++ and Java. A whiteboard interview hides it, and the lobby is unchanged.
- Strict assigns the problem in the token response. Before assignment the menu offers what every problem can run (C waits for a judge, so it is withheld), the token names that language, and the assigned problem opens in it.
One existing behavior changes on purpose. Once the token has named a language, a judge arriving later enables C in the tabs but no longer switches to it, because the token already told the agent which language it is. tests/browser/strict-selection.test.js asserted the old switch for a Strict language=c; that case now asserts the interview stays in Python, and docs/interview-selection.md says so.
| Before | After |
|---|---|
Java chosen before joining: the editor opens on the Java starter and Jim's greeting does not ask for a language.
Validation, on Windows at 8751aa5:
./scripts/test.sh browser: 1832 passed, 2 failed, 12 skipped (nojavac). The two failures are thefloor-capture.test.jsinterruption tests, which fail the same way onmainon this machine (checked ata7b0b22).tests/browser/start-language.test.js(11) andtests/browser/strict-selection.test.js(56) pass. I checked the new tests by breaking the code they cover: an unbounded judge wait, storing before the token succeeds, opening a Strict assignment in the default language, resolving the starting language beforeapplyLanguages, and waiting on the judge for a Python start each make them fail.cargo test: every suite passes except three tests. The twogemini::tests::bounded_http_diagnostic_*failures reproduce onmain(checked at3bb4b11).recording::a_refused_interview_leaves_its_consent_unspentfails while deleting its temporary database, which Windows reports as still open (os error 32), after the test body has run; it does not touch the language path.gen-wire-fixtures.mjs --checkpasses once its imports use file URLs, which Node needs for aC:path; the fixtures have not drifted.
Closes #431