Repository settings¶
What is enforced on github.com/coltonbearden/carrel, why, and how to
reproduce it. Applied and verified by scripts/github-harden.sh (idempotent;
re-run it any time to re-assert this state).
Branch ruleset main (active)¶
| rule | effect |
|---|---|
| Restrict deletions | main cannot be deleted |
| Block force pushes | history on main is append-only |
| Require linear history | squash or rebase merges only, no merge commits |
| Require a pull request | direct pushes are rejected; 0 approvals required (solo maintainer), stale approvals dismissed, review threads must be resolved |
| Require status checks | lint, test (py3.12), test (py3.13), test (py3.14), test-minimal, test-minimal (macos) must pass on the PR head, and the branch must be up to date with main. Pending: promote test-minimal (windows) once it has been green on main for two consecutive weeks (D-028 in docs/DECISIONS.md has the rule, where the count starts and the earliest date) — drop continue-on-error in .github/workflows/test.yml, add the check to REQUIRED_CHECKS, re-run the script |
| Bypass | repository admin role, through a pull request only — the admin can merge a PR past failing or pending checks, never push directly; every other actor (bots, collaborators, tokens) is blocked |
Tag ruleset release tags (active, v*)¶
Release tags cannot be deleted, moved, or force-updated. No bypass — nobody, including the admin, can move a published tag.
Security & analysis¶
- Dependabot alerts + security updates: on (
.github/dependabot.ymlalso schedules weekly grouped updates foruvandgithub-actions). - Secret scanning + push protection: on. (Non-provider patterns: the API accepts but ignores the toggle on user-owned repos — flip it under Settings → Advanced Security if wanted.)
- Private vulnerability reporting: on (
SECURITY.mdlinks the form). - CodeQL default setup: on, extended query suite, languages
python+actions.
Actions¶
- Allowed actions: GitHub-owned, verified-creator, plus
astral-sh/setup-uv@*andpypa/gh-action-pypi-publish@*. - SHA pinning required (all workflows pin to commit SHAs with a version comment).
- Default
GITHUB_TOKENpermissions: read-only; Actions cannot approve PRs. - Environment
pypi: deployments only fromv*tags. - Environment
github-pages: deployments only frommain.docs.ymldeploys on every event butpull_request, so this keeps a dispatched branch from deploying through it. A workflow that names another environment is not covered (D-029).
Secrets¶
Actions secrets carrel's workflows read. Publishing needs none — PyPI is Trusted Publishing (OIDC), so no long-lived token exists anywhere.
| Secret | Set? | Used by | If absent |
|---|---|---|---|
CONTEXT7_API_KEY |
not set | .github/workflows/context7-refresh.yml |
The job is green and skipped: HAS_KEY is decided at job level and the request step is gated on it. Nothing to disable and no red runs. Context7 re-indexes on its own schedule regardless; the key only buys a nudge and higher refresh limits. Generate one at https://context7.com/dashboard. |
Merge behaviour¶
- Squash merge (PR title + body) and rebase allowed; merge commits disabled.
- Auto-merge enabled, head branch auto-deleted, "update branch" button on.
- Wiki disabled (docs live in
docs/, published to GitHub Pages).
Verified state (2026-09-04)¶
scripts/github-harden.sh applied and read back every setting above after PR #7
merged: both rulesets active, secret scanning + push protection enabled, private
vulnerability reporting on, CodeQL default setup configured (extended), Actions
restricted to the allow-list with SHA pinning required, pypi environment
limited to v* tags. PR #7 itself was the first change to land under the
required checks (lint, test (py3.12/3.13/3.14), test-minimal, test-minimal (macos)).
2026-10-09: scripts/github-harden.sh --verify-only read every setting above back again,
the github-pages policy included. That policy was already main only; the script had
not set or checked it before. For both environments it now checks that custom policies are
in force as well as which patterns exist, and applying it deletes any other pattern.
Not enforced (deliberately)¶
- Signed commits — would block unsigned commits from automation; enable once every committer signs.
- Required reviewers on
pypi— one maintainer; the ruleset + tag protection + version check already gate releases.