--- name: scheduled-peer-review description: Set up and validate the opt-in GitHub Actions scheduler for deterministic Canvas group peer-review pairing. --- # Scheduled peer-review pairing This is an advanced-user deployment. It installs a course-owned GitHub Actions workflow that periodically runs `peer_review_schedule.py`, which gates the configured local-time window and delegates Canvas work to the existing, idempotent `peer_review_assign.py` tool. ## Ownership boundary - Canonical tools, examples, and this skill live in `canvas-toolbox`. - The concrete workflow belongs in the course repository at `.github/workflows/peer-review-sync.yml`. - The course schedule belongs at `.canvas/peer-review-schedule.yml`. - Do not install either automatically through `cb_flatten` or `cb_update`. - Canvas credentials belong in GitHub Actions secrets. The course ID may be a repository variable; never commit a token. ## Setup 1. Confirm the course repository is a flattened toolkit install and that `lib/tools/peer_review_assign.py` is present. 2. Copy `scaffold/peer-review-schedule.yml.example` to `.canvas/peer-review-schedule.yml` and set the assignment/group set, term window, lock time, and `America/Denver` (or the course's actual IANA zone). 3. Copy `scaffold/peer-review-sync.yml.example` to `.github/workflows/peer-review-sync.yml`. 4. Authenticate the GitHub CLI for the course repository, then use the secret-safe helper from the course repo: ```text uv run python lib/tools/github_actions_setup.py --repo OWNER/COURSE uv run python lib/tools/github_actions_setup.py --repo OWNER/COURSE --apply --yes ``` The helper reads only `CANVAS_API_TOKEN`, `CANVAS_BASE_URL`, and `CANVAS_COURSE_ID` from `.env`; it writes the first two as repository secrets and the course ID as a repository variable. It never prints secret values. Without `--apply --yes`, it is a dry run. 5. Run the workflow manually with `apply` unchecked and verify the counts. 6. Validate against a real Canvas sandbox. Only then set `allow_enrolled: true` for an enrolled production course and enable the schedule. ## Safety properties - The schedule is dry-run by default. - The local lock time is evaluated with `zoneinfo`; the GitHub cron is only a polling cadence, so DST changes do not require editing the workflow. - Runs outside the configured window or before the lock time are no-ops. - Pairing writes remain idempotent and read-back verified through `peer_review_assign.py`. - The scheduler prints counts/status only; it does not print student names or submission contents. - A non-zero tool result fails the GitHub job and surfaces through GitHub's normal notification/history mechanisms. - The setup helper never uses `gh secret set --env-file .env`; it allowlists the three expected keys so unrelated `.env` values cannot be uploaded.