Skip to content

Commit a5cb8ea

Browse files
Bordaclaude
andcommitted
refine(oss): action-item change/severity fields; replace sentinel commit gate with in-context auth.
- Add `change` (code/test/docs/config/ci/style/refactor) and `severity` (1–5) to ACTION_ITEMS schema - Update action item table format to include Change and Severity columns - Route by `change` field when Codex unavailable (code/refactor→sw-engineer, test→qa-specialist, docs→doc-scribe, style→linting-expert) - Add `--agent` override to bypass routing table unconditionally - Update TaskCreate description to carry change+severity for agent context - git-commit.md: replace Path A/B/C + sentinel files with 3-signal in-context model (in-message, in-workflow, in-confirmation); rename to Commit Authorization + Push Authorization; no filesystem state or touch/rm needed - foundry/.claude-plugin/plugin.json: bump to 0.20.0 - oss/resolve/SKILL.md: fix Step 4 skip condition — checkout runs unconditionally in pr mode; Step 8 skip when SELECTED_ITEMS empty - oss/.claude-plugin/plugin.json: bump to 0.9.4 --- Co-authored-by: Claude Code <noreply@anthropic.com>
1 parent 3c27603 commit a5cb8ea

5 files changed

Lines changed: 63 additions & 48 deletions

File tree

plugins/foundry/.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
"license": "MIT",
1616
"name": "foundry",
1717
"repository": "https://github.com/Borda/AI-Rig",
18-
"version": "0.19.1"
18+
"version": "0.20.0"
1919
}

plugins/foundry/rules/git-commit.md

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -108,64 +108,61 @@ Never skip trailers because skill template omits them.
108108

109109
## Branch Safety
110110

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`.
112112

113113
Before any `git commit`, check current branch:
114114

115115
```bash
116116
CURRENT_BRANCH=$(git branch --show-current)
117117
```
118118

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.
120120

121-
## Commit Gate (two gates)
121+
## Commit Authorization
122122

123-
**Gate 1 — commit authorization** (all branches):
123+
Authorization determined in-context at the moment of committing — no sentinel files, no filesystem state.
124124

125-
Sentinel path: `/tmp/claude-commit-auth-<repo-slug>-<branch-slug>` · TTL: 15 min
125+
**Feature branch — authorized when any signal present**:
126126

127-
**Gate 2 — default-branch protection** (default branch only):
128-
129-
Sentinel path: `/tmp/claude-commit-default-<repo-slug>-<branch-slug>` · TTL: 5 min (must touch immediately before commit)
130-
131-
Slug algorithm: all non-alphanumeric → `-`, lowercased, consecutive dashes squeezed, trailing dashes stripped.
127+
| Signal | What it looks like |
128+
| --- | --- |
129+
| **In-message** | Current user message contains unambiguous commit instruction: "commit", "commit this", "make a commit" |
130+
| **In-workflow** | Running skill that names commit as documented step AND user invoked that skill — skill invocation = implicit authorization |
131+
| **In-confirmation** | User confirmed via `AskUserQuestion` in the current response turn |
132132

133-
```bash
134-
# Compute both sentinel paths
135-
REPO_SLUG=$(git rev-parse --show-toplevel | xargs basename | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | tr -s '-' | sed 's/-$//')
136-
BRANCH_SLUG=$(git branch --show-current | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | tr -s '-' | sed 's/-$//')
137-
SENTINEL="/tmp/claude-commit-auth-${REPO_SLUG}-${BRANCH_SLUG}"
138-
DEFAULT_SENTINEL="/tmp/claude-commit-default-${REPO_SLUG}-${BRANCH_SLUG}"
139-
```
133+
**Default branch — always AskUserQuestion**: none of the above signals override default-branch protection. Always invoke `AskUserQuestion` before committing to default branch.
140134

141-
**Path A — skill pre-auth** (skills committing as part of workflow, e.g. `/oss:resolve`):
142-
- `touch $SENTINEL` at start of commit phase; `rm -f $SENTINEL` on finish or abort (use `trap` to guarantee cleanup)
143-
- If committing to default branch: also `touch $DEFAULT_SENTINEL`; `rm -f $DEFAULT_SENTINEL` in same `trap`
144-
- Gate 1 sentinel exists and <15 min old (Gate 2 valid if on default branch) → hook allows commit
145-
- Sentinel absent, expired, or branch mismatch → hook blocks → fall through to Path B
135+
**When no signal present (feature branch)**: invoke `AskUserQuestion` before `git commit`. Question must show: target branch, whether default branch, diff size (`N files, +A −B lines` from `git diff --stat HEAD`), draft commit message subject line.
146136

147-
**Path B — user ad-hoc request**:
148-
- No Gate 1 sentinel → invoke `AskUserQuestion` before `git commit`
149-
- Question must show: target branch, whether default branch, diff size (`N files, +A −B lines` from `git diff --stat HEAD`), draft commit message subject line
150-
- On user confirmation:
151-
- Feature branch: `touch $SENTINEL``git commit``rm -f $SENTINEL`
152-
- Default branch: `touch $SENTINEL && touch $DEFAULT_SENTINEL``git commit``rm -f $SENTINEL $DEFAULT_SENTINEL`
153-
- 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.
154138

155139
## Staging and Hooks
156140

157141
- Never `git add -A` or `git add .` — always stage specific files by name
158142
- Never `--no-verify` — if pre-commit blocks, fix underlying issue
159143
- Never `--no-gpg-sign` unless user explicitly requests it
160144

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.
162162

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"
169166

170167
## History Safety
171168

plugins/oss/.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
"license": "MIT",
1616
"name": "oss",
1717
"repository": "https://github.com/Borda/AI-Rig",
18-
"version": "0.9.2"
18+
"version": "0.9.3"
1919
}

plugins/oss/skills/resolve/SKILL.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,10 @@ Read every comment, review, inline code comment. Per inline code comment: if its
260260
| `[info]` | Praise, acknowledgement, emoji-only — skip |
261261
| `[self-review]` | Finding from `/oss:review` report — not a GitHub commenter; author = agent name |
262262

263-
Build `ACTION_ITEMS`: `[{id, type, author, summary, file, line, url, full_comment_text}]``url`: `html_url` from GitHub API response; blank for report items
263+
Build `ACTION_ITEMS`: `[{id, type, change, severity, author, summary, file, line, url, full_comment_text}]``url`: `html_url` from GitHub API response; blank for report items
264+
265+
- **`change`** — type of change required: `code` · `test` · `docs` · `config` · `ci` · `style` · `refactor`; infer from finding text and affected file path; default `code` when ambiguous
266+
- **`severity`** — estimated impact severity 1–5 (5 = highest): 5 = blocks merge / data loss / security; 4 = user-visible regression; 3 = correctness/important quality gap; 2 = improvement, non-blocking; 1 = nit / style; map from comment urgency and `type` (`[req]` → floor 3)
264267

265268
### Sources confirmation
266269

@@ -270,17 +273,19 @@ Print action item table — **MUST render as markdown table; never use key-value
270273

271274
- **Summary**: ≤60 chars — truncate at word boundary, append ``
272275
- **Notes**: ≤45 chars — truncate; full text preserved in `full_comment_text`; use `` when empty
276+
- **Change**: one of `code` · `test` · `docs` · `config` · `ci` · `style` · `refactor`
277+
- **Severity**: integer 1–5; `[req]` floor = 3
273278

274279
Status codes: `pending` · `✓ resolved` · `⊘ skipped` · `⊘ no action`. Verbose reason → Notes column:
275280

276281
```markdown
277282
### Action Items — PR #<number>
278283

279-
| # | Type | Author | Status | Summary | Notes |
280-
|---|------|--------|--------|---------|-------|
281-
| 1 | [gh][req] | @reviewer | pending | rename param `x` to `count` ||
282-
| 2 | [gh][suggest] | @maintainer | pending | add docstring ||
283-
| 3 | [gh][question] | @reviewer | pending | why not use X instead? ||
284+
| # | Type | Change | Severity | Author | Status | Summary | Notes |
285+
|---|------|--------|----------|--------|--------|---------|-------|
286+
| 1 | [gh][req] | code | 4 | @reviewer | pending | rename param `x` to `count` ||
287+
| 2 | [gh][suggest] | docs | 2 | @maintainer | pending | add docstring ||
288+
| 3 | [gh][question] | code | 3 | @reviewer | pending | why not use X instead? ||
284289
```
285290

286291
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
335340
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).
336341

337342
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)
339344
- "Apply all [req]" → all `[req]` IDs
340345
- "Apply all" → all pending IDs
341346
- "Apply selected" → checked IDs from item questions
@@ -369,7 +374,7 @@ Create tasks **only for `SELECTED_ITEMS`** — not all pending items; avoids con
369374
```text
370375
TaskCreate(
371376
subject="<type> <summary> — PR #<number>", # <type> = full string with brackets
372-
description="Author: @<author> | File: <file:line or '—'> | <full_comment_text>",
377+
description="Author: @<author> | Change: <change> | Severity: <severity> | File: <file:line or '—'> | <full_comment_text>",
373378
activeForm="Implementing: <summary>" # <summary> truncated to 80 chars
374379
)
375380
```
@@ -378,7 +383,7 @@ Store returned task ID in each `SELECTED_ITEMS` entry as `task_id`.
378383

379384
## Step 4: Checkout PR branch
380385

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.*
382387

383388
**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:
384389

@@ -423,6 +428,8 @@ Read and execute `$_OSS_RESOLVE/modes/conflict-resolution.md`.
423428

424429
## Step 8: Implement action items
425430

431+
*Skip when `SELECTED_ITEMS` is empty — jump to Step 9.*
432+
426433
**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).
427434

428435
<!-- Step 8 defined in action-item-dispatch.md — see that file for phase/sub-step detail -->

plugins/oss/skills/resolve/modes/action-item-dispatch.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,18 @@ trap 'rm -f "$SENTINEL"; rm -rf "$IMPL_DIR"' EXIT INT TERM
2323
CHALLENGE_LOG=() # per-item records: id|evidence|suggestion|resolution
2424
```
2525

26-
`CODEX_AVAILABLE=false`: apply degradation rules from Step 1 (simple items → foundry:sw-engineer; complex items → skip with notice). Never blanket-skip all items.
26+
`CODEX_AVAILABLE=false`: use `change` field to route to internal agent; never blanket-skip all items.
27+
28+
| `change` value | `IMPL_AGENT` |
29+
| --- | --- |
30+
| `code` · `refactor` · `config` · `ci` | `foundry:sw-engineer` |
31+
| `test` | `foundry:qa-specialist` |
32+
| `docs` | `foundry:doc-scribe` |
33+
| `style` | `foundry:linting-expert` |
34+
35+
Complex items (effort `xhigh`, multi-file) with `CODEX_AVAILABLE=false` → skip with `⚠ codex not found — skipping item #<id> (xhigh effort). Install: /plugin marketplace add openai/codex-plugin-cc`.
36+
37+
`--agent <name>` overrides this routing table unconditionally.
2738

2839
> **Conflict gate**: verify all Step 5a conflict tasks `completed` before any action item. Still `pending`/`in_progress` → stop, surface list, wait. Items on unresolved conflicts compound diff.
2940

0 commit comments

Comments
 (0)