You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: plugins/foundry/rules/git-commit.md
+33-36Lines changed: 33 additions & 36 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -108,64 +108,61 @@ Never skip trailers because skill template omits them.
108
108
109
109
## Branch Safety
110
110
111
-
Default branch is repo-specific — do NOT hardcode `main` or `master`. Hook detects dynamically via `git symbolic-ref refs/remotes/origin/HEAD`, `gh repo view`, or `git remote show origin`. Committing to default branch requires **second sentinel** (Gate 2 below).
111
+
Default branch is repo-specific — do NOT hardcode `main` or `master`. Detect dynamically via `git symbolic-ref refs/remotes/origin/HEAD`, `gh repo view`, or `git remote show origin`.
112
112
113
113
Before any `git commit`, check current branch:
114
114
115
115
```bash
116
116
CURRENT_BRANCH=$(git branch --show-current)
117
117
```
118
118
119
-
On default branch: two sentinels required (Gate 1 + Gate 2). On feature branch: one sentinel required (Gate 1 only).
119
+
Feature branch: commit proceeds when any authorization signal present (§Commit Authorization). Default branch: `AskUserQuestion` always required — no signal overrides this.
120
120
121
-
## Commit Gate (two gates)
121
+
## Commit Authorization
122
122
123
-
**Gate 1 — commit authorization** (all branches):
123
+
Authorization determined in-context at the moment of committing — no sentinel files, no filesystem state.
124
124
125
-
Sentinel path: `/tmp/claude-commit-auth-<repo-slug>-<branch-slug>` · TTL: 15 min
125
+
**Feature branch — authorized when any signal present**:
- Never self-create sentinels without `AskUserQuestion` first — bypasses Gate 2 entirely
137
+
**Never commit autonomously**: authorization must come from one of the three signals — never self-authorize without user signal in the current turn.
154
138
155
139
## Staging and Hooks
156
140
157
141
- Never `git add -A` or `git add .` — always stage specific files by name
158
142
- Never `--no-verify` — if pre-commit blocks, fix underlying issue
159
143
- Never `--no-gpg-sign` unless user explicitly requests it
160
144
161
-
## Push Safety
145
+
## Push Authorization
146
+
147
+
Same signal model as §Commit Authorization — no AskUserQuestion when signal present. Note: `git push` is not pre-allowed in settings; harness will prompt once regardless (by design).
148
+
149
+
**Feature branch — authorized when any signal present**:
150
+
151
+
| Signal | What it looks like |
152
+
| --- | --- |
153
+
|**In-message**| Current user message contains unambiguous push instruction: "push", "push this", "push the branch" |
154
+
|**In-workflow**| Running skill that names push as documented step AND user invoked that skill |
155
+
|**In-confirmation**| User confirmed via `AskUserQuestion` in the current response turn |
156
+
157
+
**When no signal present**: invoke `AskUserQuestion` before `git push`. Show: target branch, remote, whether default branch.
158
+
159
+
**Authorization scoped**: "commit this" does not authorize "push this" — push requires its own signal in the current message or turn.
160
+
161
+
**Default branch**: `AskUserQuestion` always required — no signal overrides this.
162
162
163
-
-**Never push without explicit user confirmation** — always invoke `AskUserQuestion` before any `git push`, including branch pushes, PR pushes, and release tags (prose question alone is not sufficient)
164
-
- Authorization scoped: "commit this" does not authorize "push this"; ask separately for every push
165
-
- Applies inside skill workflows — if skill (e.g. `/resolve`) includes push step, treat as "propose and confirm", not "auto-execute"; stop after committing, report what ready to push, wait for user to say push
166
-
- Never push in autonomous bug fixing or as "final step" without being explicitly asked in that message
167
-
- Never force-push (`--force`, `--force-with-lease`) to main/master — forbidden even with explicit user instruction
168
-
- Never force-push to any other branch without explicit user instruction; prefer regular push with explicit confirmation
163
+
**Force-push**:
164
+
- Main/master: forbidden even with explicit user instruction
165
+
- Other branches: only with explicit user instruction in current message; never as autonomous "final step"
| 3 |[gh][question]|code | 3 |@reviewer| pending | why not use X instead? | — |
284
289
```
285
290
286
291
Long content never justifies switching to key-value or separator-delimited format — truncate, stay in table.
@@ -335,7 +340,7 @@ Options: (a) Apply all [req] (X items) · (b) Apply all (N items) · (c) Skip al
335
340
If per-item control needed: advise re-run after reducing source (e.g. use `report` mode instead of `pr + report`, or `--no-challenge` to cut upstream findings).
336
341
337
342
Resolve `SELECTED_ITEMS`:
338
-
- "Skip all" or no selections → `[]` → skip Steps 4–8, jump to Step 9
343
+
- "Skip all" or no selections → `[]` → skip Step 8, jump to Step 9 (checkout + conflict resolution still run)
339
344
- "Apply all [req]" → all `[req]` IDs
340
345
- "Apply all" → all pending IDs
341
346
- "Apply selected" → checked IDs from item questions
@@ -369,7 +374,7 @@ Create tasks **only for `SELECTED_ITEMS`** — not all pending items; avoids con
369
374
```text
370
375
TaskCreate(
371
376
subject="<type> <summary> — PR #<number>", # <type> = full string with brackets
372
-
description="Author: @<author> | File: <file:line or '—'> | <full_comment_text>",
activeForm="Implementing: <summary>" # <summary> truncated to 80 chars
374
379
)
375
380
```
@@ -378,7 +383,7 @@ Store returned task ID in each `SELECTED_ITEMS` entry as `task_id`.
378
383
379
384
## Step 4: Checkout PR branch
380
385
381
-
*Runs only when `SELECTED_ITEMS` non-empty (set in Step 3e). Empty → skip to Step 9.*
386
+
*Skip only when `MODE = report` with no PR# (`$PR_NUMBER` unset — no remote branch to check out). In pr mode, runs unconditionally regardless of `SELECTED_ITEMS` — conflict resolution must happen even when 0 action items selected.*
382
387
383
388
**Branch-safety pre-check** — must run BEFORE `gh pr checkout` so a wrong-branch commit is impossible (per `git-commit.md` Gate 2). Verify the PR's `headRefName` is not the repo's default branch — `gh pr checkout` of a same-repo PR whose HEAD = default branch would land us on default and any later commit (Step 8) would violate Gate 2:
384
389
@@ -423,6 +428,8 @@ Read and execute `$_OSS_RESOLVE/modes/conflict-resolution.md`.
423
428
424
429
## Step 8: Implement action items
425
430
431
+
*Skip when `SELECTED_ITEMS` is empty — jump to Step 9.*
432
+
426
433
**Soft cap: 8 Codex dispatches per session.** If `SELECTED_ITEMS` has > 8 items, invoke `AskUserQuestion`: "N items selected — Codex cap is 8 per session. Split into batches?" Options: (a) Apply first 8 now, re-run for remainder · (b) Apply all [req] items only (if ≤8) · (c) Proceed anyway (sequential, may be slow).
427
434
428
435
<!-- Step 8 defined in action-item-dispatch.md — see that file for phase/sub-step detail -->
0 commit comments