Safe Rollout Checklist
Use this checklist before the first rollout to a real cohort and before a later
patch that sends new content to student repositories. After completing it,
you should have private repositories for the intended students, with only the
required access and without an accidental copy of the cohort member list.
Before distribution
- Confirm that
groupIdand any evaluation target point to the intended GitLab groups. Use a separate non-production group for the rehearsal. - Run the complete workflow once with a small members file containing only
synthetic test accounts controlled by the course team. The
--countoption does not assign users, so it does not test access control. - Confirm that the target namespace permits private projects. For any existing or reused project, check its effective project visibility in GitLab. A private project inside a public group remains private, so inspect the project rather than inferring its visibility from the parent group.
- Store the real members file outside the origin repo. Check that it
is not tracked by Git and is not among the files that distribution can copy.
DIVEKIT_MEMBERScan point Divekit at a dedicated members directory outside the origin repo. - Authenticate with
divekit auth. Keep tokens out of the origin repo, committed configuration, shell history, and ordinary environment files. Prefer Divekit’s credential-store integration or a protected CI secret. Grant the token owner only the GitLab permissions required for this rollout.
The relevant distribution settings are described in the
config.json reference. GitLab documents how
project visibility affects who
can see repository content.
Review the operation
Preview the operation before changing GitLab:
divekit distribute -d <distribution> --dry-run
For a later patch, preview the exact paths and operations:
divekit patch -d <distribution> <paths...> --dry-run
- Read the complete operation plan. Check the remote host, target groups, repository count, members, paths, and destructive actions.
- Inspect outgoing files for student usernames or other cohort data that does not belong in every destination repository. Pay particular attention to CSV, spreadsheet, export, and copied configuration files.
- Inspect existing destination projects in GitLab and confirm that each is private before a patch writes new content.
- Run the real command without
--yesfor the first cohort rollout so that an unexpected prompt cannot be accepted automatically.
See the current command references for
divekit distribute and
divekit patch.
Verify the result
Check the generated state and a representative sample in GitLab before telling students that the repositories are ready:
- Every work and evaluation project is private.
- Only the expected students and course staff can access each project.
- Each person has the least-required role for the workflow. In particular, a student should not receive a higher role merely because the token owner has broad permissions.
- A representative work repository contains the expected individualized assignment and no complete member list, staff export, token, solution, or unrelated course data.
- A representative evaluation repository, if used, contains only the intended evaluation material and has the expected members and role levels.
- Repository names, default branches, pipelines, and Pages links do not expose identifiers that were meant to remain private.
Repeat the sample check after a patch that adds or moves privacy-sensitive files. Increase the sample size when the operation used different target rules or individualization paths for different repositories.
Publish a demonstration intentionally
Do not turn a real student repository public to demonstrate Divekit. Build a separate demonstration from synthetic identities and sanitized content:
- Start from a copy that does not contain real member data or student work.
- Replace names, UUIDs, repository names, comments, commit metadata, reports, logs, and screenshots with synthetic values.
- Use
divekit snapshotif you need a copy without the source Git history. Snapshot removes Git history and commit metadata, but it does not sanitize the current file tree, file paths, UUIDs, or repository names. - Review the complete demonstration repository as an unauthenticated visitor would see it.
- Change visibility in GitLab only after that review. Keep the original cohort repositories private.
Respond to accidental exposure
If sensitive content has already been pushed, stop further distribution and patch operations, make every affected project private in GitLab, and restrict access while you determine the scope. Rotate a token immediately if the exposed content contains one.
Removing a file from the current tree is not the same as removing it from Git history. For example:
divekit patch -d <distribution> --delete <path>
This creates a change that removes the path from the current repository tree. Earlier commits can still contain the file and its contents.
Involve the GitLab administrator and follow the instance-approved history rewrite process. GitLab’s repository history cleanup documentation describes the server-side considerations.
History rewriting is destructive and cannot retract content from existing clones, downloads, artifacts, forks, logs, caches, or backups. It also changes descendant commit and tag IDs, can invalidate signatures and links, and normally requires affected users to clone the repository again. Treat history cleanup as incident containment, not as proof that every copy has disappeared.