Skip to content

Allow guest interviews without GitHub sign-in - #343

Merged
jserv merged 2 commits into
sysprog21:mainfrom
TMQ0717:feat/guest-mode
Oct 21, 2026
Merged

jserv merged 2 commits into
sysprog21:mainfrom
TMQ0717:feat/guest-mode

Conversation

@TMQ0717

@TMQ0717 TMQ0717 commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Allow users to start interviews without GitHub sign-in when recording is disabled and guest access is available.
  • Keep authenticated interview behavior unchanged and enforce separate guest token rate limits.
  • Avoid persisting guest interview reports across sessions and inform guests to download temporary reports before leaving.
  • Add regression tests for guest access, session state, report persistence, and token authorization.

Screenshots

The following screenshots demonstrate the guest-mode interface using a local frontend preview with mocked API responses and sample report data. They illustrate the intended UI behavior and are provided for visual reference; they do not independently verify the complete end-to-end guest interview flow.

Guest interview lobby

The guest interview lobby allows users to start an interview without entering a GitHub username or signing in.

codetrial-guest-home-white

Guest interview report

Guest reports are temporary and are not persisted across sessions. The interface reminds guests to download their reports before leaving.

codetrial-guest-report

Testing

  • Browser tests: 1,234 passed.
  • RustSec dependency audit: passed.
  • Project hooks: 49 checks passed.
  • Formatting check: passed.

Notes

Guest access remains unavailable when recording is enabled or the required account infrastructure is unavailable.


Summary by cubic

Allows starting interviews without GitHub sign-in when recording is disabled and guest mode is enabled, while keeping authenticated interview behavior unchanged. Token responses now flag guests, live-room and guest-capacity bookkeeping share one mutex so concurrent reservations cannot oversubscribe a room, and the server-check script adapts to whether guest mode is available.

  • Guest mode is opt-in via CODETRIAL_GUEST_MODE_ENABLED (default off) and available only when recording is disabled, the account database is reachable, and the dispatcher supports guest admission.
  • Guests and signed-in callers share the IP-based token rate limit so switching auth state can't reset the request budget; guest interviews draw from a separate two-interview capacity cap and cannot share a live room with signed-in interviews.
  • Guest reports skip persistent history entirely, so the "Temporary guest report. Download it before leaving." warning stays, and leaving or report delivery is guarded until the report is safely handled.

Written for commit e511c4f. Summary will update on new commits.

View guided diff

close #316

cubic-dev-ai[bot]

This comment was marked as resolved.

Comment thread src/web/auth.rs Outdated
Comment thread src/web/mod.rs
Comment thread src/web/token.rs
Comment thread src/web/token.rs Outdated
Comment thread web/interview.js
@@ -1113,7 +1113,7 @@ function bindEvents() {
);
});
nodes.report.addEventListener("click", (event) => {
if (event.target.closest("#done")) window.location.assign("/");
if (event.target.closest("#done")) leaveRoom();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leaveRoom() calls beforeUnloadGuard.dispose() before navigating, so Done now leaves without the unload warning. A guest who has not downloaded loses the only copy with no prompt, which contradicts the status line telling them to download first, and signed-in users whose save failed lose the same protection (previously window.location.assign("/") let the guard fire). Keep the guard, or ask for confirmation, on this path when state.reportPersisted is false.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed. I added a confirmation prompt in leaveRoom() when the report has not been persisted, preventing users from accidentally leaving without saving their report.

Comment thread web/interview.js Outdated
Comment thread web/interview.js Outdated
@jserv

jserv commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Without recording, this opens interview dispatch to anonymous callers on every deployment, with no operator switch, and guests share dispatcher capacity and provider budget with signed-in users. One client can hold every slot and lock signed-in candidates out with 503. Detail is on the guest rate-limit check in src/web/token.rs.

@jserv jserv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always rebase onto the latest main branch instead of merging.

@TMQ0717

TMQ0717 commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

Understood. I have rebased my branch onto the latest main branch instead of merging it, and pushed the updated branch.

cubic-dev-ai[bot]

This comment was marked as resolved.

Comment thread scripts/server-check.sh Outdated
Comment thread src/web/mod.rs
Comment on lines +507 to +509
self.config.guest_mode_enabled
&& self.config.recording.is_none()
&& (!self.accounts_required || self.accounts.is_some())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two-guest ceiling exists only in LocalDispatcher::reserve_with_kind. When state.dispatcher is None (the web-only deployment, agents started elsewhere), dispatch_or_release_consent returns before any guest check, and the trait's default ensure_guest_agent just forwards to ensure_agent. So any other dispatcher hands out guest room credentials with no guest cap, limited only by the per-IP token bucket, and that is trivially spread across addresses. Either require a dispatcher that enforces the guest cap here before advertising guest mode, or state that the split deployment has no guest cap and leave that to a follow-up.

@TMQ0717 TMQ0717 Oct 19, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added an explicit supports_guest_admission() capability to RoomDispatcher, with a default value of false. Guest mode is now advertised only when a dispatcher explicitly supports guest admission limits. LocalDispatcher opts in because it enforces the guest-specific capacity limit, while unsupported dispatchers fail closed.

Comment thread web/render.js Outdated
cubic-dev-ai[bot]

This comment was marked as resolved.

cubic-dev-ai[bot]

This comment was marked as resolved.

@jserv
jserv requested review from ColtenOuO and alanhc October 19, 2026 00:50
jserv

This comment was marked as outdated.

@TMQ0717

TMQ0717 commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Done. I rebased the branch onto upstream/main, consolidated the related changes into one functionally minimal commit, and verified that the commit message follows the project’s rules. The test suite passed, and I force-pushed the updated branch to my fork. The PR is ready for review.

@jserv jserv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TMQ0717
TMQ0717 force-pushed the feat/guest-mode branch 2 times, most recently from 271c586 to ac484cb Compare October 19, 2026 01:29
@TMQ0717

TMQ0717 commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor Author

I’ve revised my commit message to better explain the motivation for guest mode, its benefits for first-time users, and the rationale for retaining resource limits and limiting guest report persistence. I’ve also ensured that the message follows the project’s commit message guidelines.

@jserv

This comment has been minimized.

1 similar comment
@jserv

jserv commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Rebase latest main branch and resolve conflicts

@TMQ0717

TMQ0717 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

Done. I rebased feat/guest-mode onto the latest upstream main, confirmed that there were no conflicts, and consolidated the changes into one functionally focused commit. I also checked the commit message against the project's rules and pushed the updated branch to my fork.

Comment thread src/web/token.rs
StatusCode::INTERNAL_SERVER_ERROR,
json!({ "error": "Could not read account session." }),
StatusCode::FORBIDDEN,
json!({ "error": "Guest interviews are disabled." }),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With guest mode off, which is the default, a signed-out caller used to get 401 and "Enter your GitHub username to start an interview."; now it gets 403 "Guest interviews are disabled." That names a feature the operator never turned on and tells the candidate nothing they can act on. The two tests/cli.rs assertions that pinned the old answer were deleted rather than updated, so nothing guards the default path any more. Keep the old 401 and message whenever guest_mode_enabled is false, use this response only for an operator who enabled guests on a deployment that cannot offer them, and restore those tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in e511c4f (Restore guest token admission guarantees).

When guest_mode_enabled is false, anonymous requests now retain the previous 401 Unauthorized response and the message "Enter your GitHub username to start an interview."

I also restored the CLI regression assertions to ensure the default behavior remains unchanged. Thanks for pointing this out.

Comment thread src/web/token.rs Outdated
Users should be able to evaluate the interview experience before
connecting a GitHub account. Requiring sign-in creates an
unnecessary barrier for first-time users who only want to try
the service.

Guest access must remain subject to resource limits to protect
service availability and operating costs. Guest interview
reports should not persist across sessions, while signed-in
users retain their existing experience.
Keep the legacy 401 response when guest mode is disabled.

Separate anonymous token rate limits from signed-in candidates.
Add regression tests for both behaviors.
@jserv

jserv commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

@TMQ0717 #316 now describes the gated guest mode this PR implements, and your answer there settled its scope, so this PR finishes it. Change the last line of the description from Refs #316 to Closes #316, so the merge closes the issue.

@ColtenOuO ColtenOuO left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I have changed description to close the issue.

@jserv
jserv merged commit 5eec193 into sysprog21:main Oct 21, 2026
11 checks passed
@jserv

jserv commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Thank @TMQ0717 for contributing!

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.

Allow users to start an interview without GitHub sign-in

3 participants