The product is a local-first browser application backed by a public GitHub learning record and a private controller. The lab operates no permanent learner login service, analytics service, or database of student answers.
Repository Boundaries#
IDEALLab/onboarding-IT handbook, curriculum, site, exporters
soheylm-passport-sandbox/passport-exercises public fictional exercises and records
soheylm-passport-sandbox/gh-passport public launcher releases
soheylm-passport-sandbox/onboarding-control private authority and operations
username/passport-exercises learner-owned public fork
The active deployment profile is platform/deployment.json. Students are not
members of either organization.
Three Separate Surfaces#
| Surface | Location | Learner experience |
|---|---|---|
| Visible learning | Local browser on 127.0.0.1 |
One current mission, action, check, feedback, submit, continue |
| Real practice | Separate local folder or named remote system | Git, Python, Euler, NAS, Blade, or AI only when taught |
| Transport and authority | .transport, central draft PR, Worker, controller |
Hidden until Git is understood; technical details thereafter |
The launcher never mixes a learner's staged practice changes with a Passport submission. It copies only mission-declared synthetic artifacts into the managed transport clone and stages an exact allowlist.
First Contact And Consent#
public static first-contact page
-> install Git and GitHub CLI
-> gh auth login
-> install gh-passport
-> gh passport start
-> local pre-provisioning wizard
-> choose platform and responsibilities
-> read and accept the public-content boundary
-> create/reuse fork, .transport clone, route, branch, and draft PR
-> open first mission
No fork, branch, PR, or public answer exists before explicit consent. The browser wizard accepts only platform, known responsibility IDs, and the consent boolean.
Resume And Authority#
| State | Location | Authority |
|---|---|---|
| Last page, drafts, attempt counters | OS-local registry and gitignored state | Convenience only |
| Practice files | Separate local folder | Draft work only |
| Generated submission at a fork SHA | Public learning record | Assessment input |
| Trusted Check Run at that exact SHA | Central public repository | Training status |
| Operational approval at that exact SHA | Private assignment plus authorized review | Real access/ownership decision only |
| Completion record | Private append-only registry | Minimal final training record |
gh passport open works from any folder because the OS-specific registry stores
only the absolute managed transport path. If local state disappears, the
launcher reconstructs official progress from the central PR and Check Run. A
completed closed, unmerged PR remains resumable.
Event And Assessment Path#
launcher pushes one generated mission submission
-> public App sends signed pull_request webhook
-> Cloudflare Worker checks signature, installation, repository, action,
draft state, branch, base, body size, and SHA
-> dispatch App starts private assess.yml with PR number + exact SHA
-> private assignment freezes immutable GitHub IDs and route
-> isolated container reads exact checkout with no token and no network
-> controller revalidates the PR SHA
-> trusted App writes one Check Run and upserts sanitized feedback
A sparse cron scans for dropped events four times daily. It is recovery, not the normal path. Duplicate dispatches are harmless because assignment state, attempt counts, and Check Runs are keyed by exact head SHA.
Trust Checks#
Registration and each assessment validate:
- active private enrollment and immutable learner/reviewer IDs;
- official central repository and base branch;
- PR author, fork ID, direct parent ID, source branch, and draft/open state;
- canonical route resolved from platform and responsibilities;
- immutable protected-file hashes and exact submitted SHA;
- secret scan before parsing or execution;
- editable-path, size, suffix, and symlink boundaries;
- exact remote Git-practice PR identity where that competency is assessed.
Untrusted code runs under resource limits in a network-disabled container. No App key, organization token, or learner token enters the checkout.
GitHub Apps#
Use separate least-privilege identities:
- Controller App: installed only on
passport-exercises; reads contents and PRs, writes Checks, issues/comments, and PR state. - Dispatch App: installed only on
onboarding-control; writes Actions workflow dispatches and reads metadata.
The dispatch private key exists only as a Cloudflare Worker secret. The
controller private key exists only in private onboarding-control. Neither App
is installed on unrelated repositories or personal forks.
Completion And Human Work#
automatic and exception_only missions pass from deterministic criteria.
exception_only creates attention only when the bounded verifier cannot decide.
operational_approval can finish its training check while a real access,
classification, or ownership decision remains assigned asynchronously.
On complete training, the controller writes the minimal private record and closes the transport PR without merging. Human review is not a routine Passport bottleneck.
Privacy#
The public record contains GitHub identity, structured choices, booleans, one-way challenge digests, scores, and declared synthetic artifacts. It excludes ETH identifiers, local/NAS paths, job IDs, logs, screenshots, AI transcripts, credentials, and research content. Private control stores identity and status metadata, not answer bodies.