Safe Rollout Checklist

Check privacy-sensitive settings before distributing assignments to a real cohort.

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 groupId and 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 --count option 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_MEMBERS can 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 --yes for 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:

  1. Start from a copy that does not contain real member data or student work.
  2. Replace names, UUIDs, repository names, comments, commit metadata, reports, logs, and screenshots with synthetic values.
  3. Use divekit snapshot if 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.
  4. Review the complete demonstration repository as an unauthenticated visitor would see it.
  5. 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.