Welcome back! In the previous chapter, Remote Session Model, we learned about the "Digital Receipt" (the Session object) that tracks a remote task.
But before we can hand out that receipt, we need to make sure the user is actually allowed to run the task. This brings us to the Session Eligibility Gatekeeper.
Imagine a "Start Remote Session" button in your application.
We don't want to write messy if/else statements directly inside our UI code. Instead, we use a central Gatekeeper function. Its job is to run a checklist and return a list of reasons why the button might be blocked.
The Gatekeeper doesn't return true or false. It returns an Array of Errors.
[]: Everything is perfect! The gate is open.['not_logged_in']: Stop! You cannot pass because you are not logged in.
First, let's look at the specific blocking problems we might encounter. These are defined in BackgroundRemoteSessionPrecondition.
// File: remote/remoteSession.ts
export type BackgroundRemoteSessionPrecondition =
| { type: 'not_logged_in' } // User needs to sign in
| { type: 'no_remote_environment' } // No server connection
| { type: 'not_in_git_repo' } // Not inside a project
| { type: 'no_git_remote' } // Project isn't on GitHub
| { type: 'github_app_not_installed' } // Missing permissions
| { type: 'policy_blocked' } // Admin disabled this feature
By defining these types clearly, the UI knows exactly which error message to show the user.
The main function is checkBackgroundRemoteSessionEligibility. It acts like a security guard performing a sequence of checks.
Before looking at the code, let's trace the decision-making process.
Now, let's break down the actual code implementation into small, manageable chunks.
The very first thing we check is the global policy. If the administrator has turned off remote sessions entirely, we stop immediately. We don't care if you are logged in or not; the feature is off.
// File: remote/remoteSession.ts
export async function checkBackgroundRemoteSessionEligibility() {
const errors: BackgroundRemoteSessionPrecondition[] = []
// 1. Check the "Master Switch"
if (!isPolicyAllowed('allow_remote_sessions')) {
errors.push({ type: 'policy_blocked' })
return errors // STOP HERE. Do not pass go.
}
// ... continue to next checks
}
If the policy allows it, we gather three pieces of information at the same time (in parallel) to be fast:
// 2. Run independent checks in parallel
const [needsLogin, hasRemoteEnv, repository] = await Promise.all([
checkNeedsClaudeAiLogin(),
checkHasRemoteEnvironment(),
detectCurrentRepositoryWithHost(),
])
if (needsLogin) errors.push({ type: 'not_logged_in' })
if (!hasRemoteEnv) errors.push({ type: 'no_remote_environment' })
Note: We will dive deep into how these individual verification functions work in Precondition Verification.
This part is slightly complex. Usually, to run a remote session, we need a GitHub Remote and the GitHub App installed.
However, there is a "Fast Lane" called Bundle Seeding. If this feature is on, the requirements are looserβwe only need to be inside any Git folder, even if it's not on GitHub yet.
// 3. Determine if we are in the "Fast Lane" (Bundle Seeding)
// ... (logic to check env vars for bundle seeding) ...
if (!checkIsInGitRepo()) {
// If not in a git folder at all, block it.
errors.push({ type: 'not_in_git_repo' })
} else if (bundleSeedGateOn) {
// "Fast Lane": We are in a git repo, so we are good!
// We skip the stricter GitHub checks below.
} else if (repository === null) {
// Standard Lane: Must have a remote origin
errors.push({ type: 'no_git_remote' })
}
Finally, if we are in the "Standard Lane" (not using Bundle Seeding), and the repository is hosted on GitHub, we must ensure the GitHub App is installed.
// 4. If using standard GitHub, check for the App
else if (repository.host === 'github.com') {
const hasGithubApp = await checkGithubAppInstalled(
repository.owner,
repository.name,
)
if (!hasGithubApp) {
errors.push({ type: 'github_app_not_installed' })
}
}
return errors // Return the final list
The Session Eligibility Gatekeeper is the bouncer of our system.
If the list is empty, the UI lights up the "Start" button!
But how exactly do we check if the user is logged in? And how do we know if there is a remote environment? In the next chapter, we will look at the specific functions that power these checks.
Next Chapter: Precondition Verification
Generated by Code IQ