VC policy hardening — diagnostic prompt¶
Use this prompt when running a version-control policy audit. Read ../SKILL.md first for orientation questions and guardrails.
Inputs¶
Collect from the user before scanning:
| Input | Required | Default |
|---|---|---|
host |
No | github |
org |
Yes (GitHub/Bitbucket) or project (ADO) |
— |
repo |
If single-repo scope | — |
scope |
Yes | single-repo or all-org-repos |
policy_level_preference |
Ask | repo-first or org-wide |
target_branch |
No | main (or repo default branch) |
large_file_limit_mb |
No | 3 |
Metadata block (top of every report)¶
Last updated by: <agent or reviewer name>
Run date: <ISO date>
Host: GitHub | Azure DevOps | Bitbucket
Scope: <OWNER/REPO | org ORG — N repos>
Policy level assessed: repo | org | both
Target branch: main
Evidence source: gh CLI | UI screenshots | mixed
Phase 0 — Tooling gate¶
- Confirm
ghavailability (gh --version,gh auth status) for GitHub. - If unavailable, direct the user to gh-cli-install.md (Windows/winget, Git Bash PATH, macOS, Linux) or switch to UI audit mode.
- Ask user to paste or screenshot:
- Rules / rulesets list
- Pull request merge settings
- Default branch name
Do not proceed to remediation commands until tooling path is clear.
Phase 1 — Scope question (mandatory)¶
Ask exactly one of:
Should I audit a single repository (you'll name OWNER/REPO) or scan all
repositories in the org/project and summarise gaps across them?
If all-org-repos, warn that runtime grows with repo count; offer to filter by team, naming prefix, or "active in last 90 days" if the list is large.
Phase 2 — Policy level question (mandatory)¶
Ask:
Do you want recommendations for repo-specific policies first (pilot on one
repo), or org/project-wide rules that apply to every repository?
Record the answer. Tailor remediation steps accordingly.
Phase 3 — GitHub scan (single repo)¶
Run and capture output for each:
# Identity and default branch
gh repo view OWNER/REPO --json name,defaultBranchRef,mergeCommitAllowed,squashMergeAllowed,rebaseMergeAllowed,deleteBranchOnMerge
# Rulesets (org + repo)
gh api repos/OWNER/REPO/rulesets --jq '.[] | {id, name, source_type, enforcement, target}'
# Ruleset detail (for each active ruleset affecting main)
gh api repos/OWNER/REPO/rulesets/RULESET_ID --jq '{name, rules, conditions}'
# Legacy branch protection (may 404 if rulesets-only)
gh api repos/OWNER/REPO/branches/main/protection 2>&1 || true
Checklist — map evidence to controls¶
| Control | What to look for | Golden path |
|---|---|---|
| Main protected | Ruleset targets main / default branch |
Active ruleset |
| No force-push | non_fast_forward rule |
Present |
| No branch deletion | deletion rule |
Present |
| Linear history | required_linear_history |
Present (blocks merge commits) |
| Rebase-only merges | Repo flags + optional pull_request merge method rule |
squash=false, merge=false, rebase=true |
| Auto-delete head branches | deleteBranchOnMerge |
true |
| Update branch button | allow_update_branch on repo |
true (recommended) |
| Large file block | Push ruleset with max file size | e.g. 3 MB active |
| CI on main | Required status checks in ruleset or workflow runs on PR/push | Validate workflow exists |
Ghost-branch diagnostic (optional)¶
If user reports "branch still 1 commit ahead after merge":
git fetch origin
git log --oneline origin/main..origin/FEATURE_BRANCH | head -5
git log --oneline origin/FEATURE_BRANCH..origin/main | head -5
Explain: squash merge creates a new commit on main; branch tip is not an ancestor → GitHub shows "ahead". Not missing work if PR merged. Fix: rebase merge + auto-delete branches.
Large-file diagnostic (optional)¶
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| awk '/^blob/ && $3 > LIMIT_BYTES {printf "%.2f MB %s\n", $3/1024/1024, $4}' | sort -rn | head -20
Replace LIMIT_BYTES with e.g. 3145728 for 3 MiB.
Phase 4 — GitHub scan (all org repos)¶
ORG=wiresuncrossed # example
gh repo list "$ORG" --limit 200 --json name,defaultBranchRef,isArchived,updatedAt \
--jq '.[] | select(.isArchived == false) | .name'
# Per repo (script or loop) — collect merge flags + ruleset names only
for repo in $(gh repo list "$ORG" --limit 200 --json name -q '.[].name'); do
echo "=== $repo ==="
gh repo view "$ORG/$repo" --json mergeCommitAllowed,squashMergeAllowed,rebaseMergeAllowed,deleteBranchOnMerge
gh api "repos/$ORG/$repo/rulesets" --jq '.[].name' 2>/dev/null || echo "(no rulesets or no access)"
done
Produce a summary table plus drill-down on repos that fail golden path.
Phase 5 — Gap analysis¶
For each control: ✅ Present | ⚠️ Partial | ❌ Missing | 🔶 Org-only (not repo)
Prioritise:
- P0 — main unprotected, direct push allowed, or merge commits allowed
- P1 — squash enabled (ghost branches), no large-file push rule
- P2 — no auto-delete branches, no update-branch, no local dev guidance
- P3 — documentation, commitlint, pre-commit alignment
Phase 6 — Recommendations (do not apply without approval)¶
Present repo-first and org-wide variants where relevant.
GitHub repo-first golden path (reference only):
gh repo edit OWNER/REPO \
--enable-merge-commit=false \
--enable-squash-merge=false \
--enable-rebase-merge=true \
--delete-branch-on-merge=true \
--allow-update-branch
Rulesets (UI or API) — see github-controls.md.
Ask: "Shall I apply these changes, or do you want the report only?"
Phase 7 — Local dev recommendations¶
Always include a short local dev section in the report:
git-hygieneskill — branch from freshmain, never commit tomain.- New branch per PR — avoid reusing merged branch names without reset.
- Large artifacts — R2 / Git LFS / release assets; never commit >limit MB.
- History scrub — if large file was pushed:
git filter-repoon feature branch, force-push with lease; coordinate before rewriting shared branches. - Pre-commit — optional local gates; server push rules remain authoritative.
Phase 8 — Non-GitHub hosts¶
If host is Azure DevOps or Bitbucket, follow
other-platforms.md. Do not invent policy names or API
commands — use documented UI paths and ask for screenshots.
Output¶
Write the report using gap-report-template.md. Attach raw command output or screenshot references as an appendix when helpful.