feat: enforce main branch protection in pre-push hook#104
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new “Gate 0” to the repo’s pre-push hook to block direct pushes to protected branches (main/master), and documents the enforcement decision and workflow guidance in Squad docs.
Changes:
- Added Gate 0 (main/master push guard) to
scripts/hooks/pre-pushso it runs before existing gates. - Recorded the enforcement decision in
.squad/decisions.md. - Updated
.squad/ceremonies.mdto note workflow enforcement and reformatted the Standard Task Workflow section.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| scripts/hooks/pre-push | Adds Gate 0 branch protection ahead of existing pre-push gates. |
| .squad/decisions.md | Documents the decision to enforce main/master push protection via pre-push. |
| .squad/ceremonies.md | Updates workflow docs to mention enforcement and adjusts formatting/structure. |
You can also share your feedback on Copilot code review. Take the survey.
.squad/ceremonies.md
Outdated
| ## Phase 3: Implementation | ||
|
|
There was a problem hiding this comment.
Heading levels under “Standard Task Workflow” become inconsistent: Phase 1/2 are #####, but Phase 3–5 are ##, which jumps back up to the same level as “Defined Ceremonies”. This breaks the document hierarchy/TOC; make Phase 3–5 the same level as Phase 1/2 (and nested under #### Phases).
.squad/ceremonies.md
Outdated
| @@ -76,27 +92,35 @@ | |||
| - Architecture.Tests + AppHost.Tests.Unit | |||
| 5. If pre-push fails, fix issues and retry | |||
There was a problem hiding this comment.
This section says “all 6 pre-push gates must pass” and lists items like AppHost.Tests.Unit, but scripts/hooks/pre-push currently documents/runs 4 gates and does not run AppHost.Tests.Unit. Update this list/count so it matches what the hook actually enforces (including Gate 0 if intended).
.squad/decisions.md
Outdated
| ### 2026-03-10: Main branch push protection enforced | ||
| **By:** Matthew Paulosky (via Copilot) | ||
| **What:** Pre-push hook now blocks direct pushes to `main` or `master`. All work must go through `squad/{issue}-{slug}` feature branches and PRs. | ||
| **Why:** Ceremonies.md documents the Standard Task Workflow but it was not enforced. Direct push to main (commit 889d6cb) bypassed the PR process. Gate 0 now reads the remote ref and exits with error if target is main/master. |
There was a problem hiding this comment.
In the “Why” line, Ceremonies.md is referenced without the actual path used in this repo (.squad/ceremonies.md). Consider updating the reference so it’s easy to locate.
| **Why:** Ceremonies.md documents the Standard Task Workflow but it was not enforced. Direct push to main (commit 889d6cb) bypassed the PR process. Gate 0 now reads the remote ref and exits with error if target is main/master. | |
| **Why:** `.squad/ceremonies.md` documents the Standard Task Workflow but it was not enforced. Direct push to main (commit 889d6cb) bypassed the PR process. Gate 0 now reads the remote ref and exits with error if target is main/master. |
scripts/hooks/pre-push
Outdated
| check_main_branch_protection() { | ||
| echo "🔒 pre-push: checking branch protection…" | ||
|
|
||
| while read local_ref local_sha remote_ref remote_sha; do |
There was a problem hiding this comment.
while read local_ref local_sha remote_ref remote_sha; do should use IFS= and read -r for consistent, robust parsing (the rest of this script already uses IFS= read -r). This avoids backslash-escape handling surprises and makes the style consistent.
| while read local_ref local_sha remote_ref remote_sha; do | |
| while IFS=' ' read -r local_ref local_sha remote_ref remote_sha; do |
scripts/hooks/pre-push
Outdated
| echo " 1. Create a feature branch: git checkout -b squad/{issue}-{slug}" | ||
| echo " 2. Make your changes and commit" | ||
| echo " 3. Push the branch: git push -u origin squad/{issue}-{slug}" | ||
| echo " 4. Create a PR: gh pr create --base main" |
There was a problem hiding this comment.
The branch name placeholder in this guidance (squad/{issue}-{slug}) doesn’t match the pattern documented in .squad/ceremonies.md (squad/{issue-number}-{kebab-slug}). Consider aligning the placeholders to reduce confusion.
| #!/usr/bin/env bash | ||
| # pre-push hook — runs three gate checks before allowing any push: | ||
| # pre-push hook — runs four gate checks before allowing any push: | ||
| # | ||
| # Gate 0: Main Branch Protection | ||
| # - Blocks direct pushes to main/master branches | ||
| # - Enforces squad feature branch workflow (squad/{issue}-{slug}) |
There was a problem hiding this comment.
PR description claims .git/hooks/pre-push was updated, but this repo appears to keep the hook under scripts/hooks/pre-push and install it into .git/hooks/ via scripts/hooks/install-hooks.sh. Consider updating the PR description (or adding .git/hooks/pre-push if you intend to track it) so the stated changed files match what’s actually included.
2b22ad4 to
2b8a721
Compare
Add Gate 0 to pre-push hook that blocks direct pushes to main/master.
All work must go through squad/{issue}-{slug} feature branches and PRs.
- Added main branch guard as Gate 0 (runs first, reads stdin)
- Updated scripts/hooks/pre-push template to match
- Documented decision in .squad/decisions.md
- Added enforcement note to ceremonies.md Standard Task Workflow
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2b8a721 to
bcdfb60
Compare
Create handlers now call ObjectId.GenerateNewId() instead of using ObjectId.Empty, which was being rejected by repository validation. Fixes 10 failing integration tests: - CreateCommentHandler, CreateStatusHandler, CreateCategoryHandler, CreateIssueHandler Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rge decision inbox - Orchestration logs for Gimli (ObjectId generation fix) and Aragorn (PR #104 review) - Session log summarizing integration test fixes and workflow enforcement - Merge gimli-handler-generates-objectid.md decision into decisions.md - Delete merged inbox file - Deduplicated — no duplicate entries Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #104 +/- ##
==========================================
+ Coverage 58.87% 58.89% +0.01%
==========================================
Files 110 110
Lines 2495 2496 +1
Branches 254 254
==========================================
+ Hits 1469 1470 +1
Misses 844 844
Partials 182 182
🚀 New features to boost your workflow:
|
Summary
Adds Gate 0 to the pre-push hook that blocks direct pushes to
mainormasterbranches. This enforces the squad workflow documented inceremonies.md.Changes
.git/hooks/pre-push— Added Gate 0 (main branch guard) that runs first and blocks pushes to protected branchesscripts/hooks/pre-push— Synced template to match.squad/decisions.md— Documented the enforcement decision.squad/ceremonies.md— Added enforcement note to Standard Task WorkflowBefore
After
Testing
mainpush with clear error messagesquad/*branch push