v1.93.24.0 GSTA-253 ship judge flake: one owner for the release commit, defined skipped/kept result (#3881)

* fix(ship): one owner for the release commit and a defined result for a skipped or kept version (ship judge flake, GSTA-253)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (Step 12 names the no-write kept line exactly)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(ship): Step 15 states the no-tag rule outright (ship-workflow-clarity)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
Garry Tanandcapy-ai[bot] authored and GitHub committed 2026-11-02 23:15:57 +00:00
1 parent 8965b915ae
commit f1cbdbb483
12 files changed
+60 -81

No files matched your search

+7
View File
@@ -1,5 +1,12 @@
# Changelog
## [1.93.24.0] - 2026-11-02
**The /ship workflow judge loses the contradiction it cited in every recorded red sample.**
### Fixed
- **`ship/SKILL.md` Steps 12 and 15**: Step 15 no longer tells the agent to make the VERSION/CHANGELOG commit by hand while Step 16's `gstack-ship-release finish` makes the same commit. Feature work is committed in Step 15, and `finish` commits the release files last with the co-author trailer. Step 12 now says what a `VERSION: skipped` (stamp-at-merge or changelog fragments) or `VERSION: <v> kept` result leaves for Steps 13, 18 and 20. All six judge samples in the two recorded reds (E2E Evals 41429095451, 41445571955) named the commit conflict, and three named the undefined skipped/kept result. Three focused judge runs on the fix passed (actionability median 4 each), and none of their nine samples cited either one.
## [1.93.23.0] - 2026-11-02
**Four tests from the 2026-11-02 flaky pass stop failing correct runs, and one more names its cause when it fails.**
+1 -1
View File
@@ -1 +1 @@
1.93.23.0
1.93.24.0
+1 -1
View File
@@ -1,4 +1,4 @@
# gstack digest v1.93.23.0 — regenerate/re-copy after upgrading gstack
# gstack digest v1.93.24.0 — regenerate/re-copy after upgrading gstack
Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed
for agent hosts without a full skill install. The full skills add workflows,
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "gstack",
"version": "1.93.23",
"version": "1.93.24",
"description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.",
"license": "MIT",
"type": "module",
+5 -13
View File
@@ -520,7 +520,8 @@ chooses it in item 2 and ALREADY_BUMPED derives it in item 1.
runs items 1 and 3–5; each decision left to you is a `STOP:` naming its rerun flag
(`--bump`, `--accept-incomplete`, `--version <v>`, `--keep-current`, `--answer`).
`ship: queue_mode stamp-at-merge` replaces items 1–4.
`VERSION: skipped` or `VERSION: <v> kept (…; no write)` ends Step 12 with
`NEW_VERSION` unset: Step 13 follows its `NEXT:`; Steps 18 and 20 take NO_VERSION's branch.
1. **Classify state** — pure reader, never writes:
```bash
@@ -641,19 +642,10 @@ Make bisectable commits; if already committed, continue to Step 16. Never create
migrations may stand alone. Under 50 lines across fewer than 4 files may be one commit.
2. Order dependencies first: infrastructure → models/services → controllers/views.
Each commit works alone (no broken imports or missing code).
Group VERSION + CHANGELOG + TODOS.md after the feature commits.
3. Use `<type>: <summary>` (feat/fix/chore/refactor/docs) and a brief body; fixing a
user-named issue adds a `Fixes: #<n>` trailer. Only the final
VERSION/CHANGELOG commit gets the release version and co-author trailer. No Git tag:
```bash
git commit -m "$(cat <<'EOF'
chore: bump version and changelog (vX.Y.Z.W)
Co-Authored-By: Claude <noreply@anthropic.com>
EOF
)"
```
user-named issue adds a `Fixes: #<n>` trailer. Leave VERSION, CHANGELOG/fragment, TODOS.md
and the digest uncommitted: Step 16's `finish` commits them last with
`--trailer 'Co-Authored-By: Claude <noreply@anthropic.com>'`. Do not add a Git tag.
---
+5 -13
View File
@@ -243,7 +243,8 @@ chooses it in item 2 and ALREADY_BUMPED derives it in item 1.
runs items 1 and 3–5; each decision left to you is a `STOP:` naming its rerun flag
(`--bump`, `--accept-incomplete`, `--version <v>`, `--keep-current`, `--answer`).
`ship: queue_mode stamp-at-merge` replaces items 1–4.
`VERSION: skipped` or `VERSION: <v> kept (…; no write)` ends Step 12 with
`NEW_VERSION` unset: Step 13 follows its `NEXT:`; Steps 18 and 20 take NO_VERSION's branch.
1. **Classify state** — pure reader, never writes:
```bash
@@ -362,19 +363,10 @@ Make bisectable commits; if already committed, continue to Step 16. Never create
migrations may stand alone. Under 50 lines across fewer than 4 files may be one commit.
2. Order dependencies first: infrastructure → models/services → controllers/views.
Each commit works alone (no broken imports or missing code).
Group VERSION + CHANGELOG + TODOS.md after the feature commits.
3. Use `<type>: <summary>` (feat/fix/chore/refactor/docs) and a brief body; fixing a
user-named issue adds a `Fixes: #<n>` trailer. Only the final
VERSION/CHANGELOG commit gets the release version and co-author trailer. No Git tag:
```bash
git commit -m "$(cat <<'EOF'
chore: bump version and changelog (vX.Y.Z.W)
{{CO_AUTHOR_TRAILER}}
EOF
)"
```
user-named issue adds a `Fixes: #<n>` trailer. Leave VERSION, CHANGELOG/fragment, TODOS.md
and the digest uncommitted: Step 16's `finish` commits them last with
`--trailer '{{CO_AUTHOR_TRAILER}}'`. Do not add a Git tag.
---
+5 -13
View File
@@ -521,7 +521,8 @@ chooses it in item 2 and ALREADY_BUMPED derives it in item 1.
runs items 1 and 3–5; each decision left to you is a `STOP:` naming its rerun flag
(`--bump`, `--accept-incomplete`, `--version <v>`, `--keep-current`, `--answer`).
`ship: queue_mode stamp-at-merge` replaces items 1–4.
`VERSION: skipped` or `VERSION: <v> kept (…; no write)` ends Step 12 with
`NEW_VERSION` unset: Step 13 follows its `NEXT:`; Steps 18 and 20 take NO_VERSION's branch.
1. **Classify state** — pure reader, never writes:
```bash
@@ -642,19 +643,10 @@ Make bisectable commits; if already committed, continue to Step 16. Never create
migrations may stand alone. Under 50 lines across fewer than 4 files may be one commit.
2. Order dependencies first: infrastructure → models/services → controllers/views.
Each commit works alone (no broken imports or missing code).
Group VERSION + CHANGELOG + TODOS.md after the feature commits.
3. Use `<type>: <summary>` (feat/fix/chore/refactor/docs) and a brief body; fixing a
user-named issue adds a `Fixes: #<n>` trailer. Only the final
VERSION/CHANGELOG commit gets the release version and co-author trailer. No Git tag:
```bash
git commit -m "$(cat <<'EOF'
chore: bump version and changelog (vX.Y.Z.W)
Co-Authored-By: Claude <noreply@anthropic.com>
EOF
)"
```
user-named issue adds a `Fixes: #<n>` trailer. Leave VERSION, CHANGELOG/fragment, TODOS.md
and the digest uncommitted: Step 16's `finish` commits them last with
`--trailer 'Co-Authored-By: Claude <noreply@anthropic.com>'`. Do not add a Git tag.
---
+5 -13
View File
@@ -520,7 +520,8 @@ chooses it in item 2 and ALREADY_BUMPED derives it in item 1.
runs items 1 and 3–5; each decision left to you is a `STOP:` naming its rerun flag
(`--bump`, `--accept-incomplete`, `--version <v>`, `--keep-current`, `--answer`).
`ship: queue_mode stamp-at-merge` replaces items 1–4.
`VERSION: skipped` or `VERSION: <v> kept (…; no write)` ends Step 12 with
`NEW_VERSION` unset: Step 13 follows its `NEXT:`; Steps 18 and 20 take NO_VERSION's branch.
1. **Classify state** — pure reader, never writes:
```bash
@@ -641,19 +642,10 @@ Make bisectable commits; if already committed, continue to Step 16. Never create
migrations may stand alone. Under 50 lines across fewer than 4 files may be one commit.
2. Order dependencies first: infrastructure → models/services → controllers/views.
Each commit works alone (no broken imports or missing code).
Group VERSION + CHANGELOG + TODOS.md after the feature commits.
3. Use `<type>: <summary>` (feat/fix/chore/refactor/docs) and a brief body; fixing a
user-named issue adds a `Fixes: #<n>` trailer. Only the final
VERSION/CHANGELOG commit gets the release version and co-author trailer. No Git tag:
```bash
git commit -m "$(cat <<'EOF'
chore: bump version and changelog (vX.Y.Z.W)
Co-Authored-By: Claude <noreply@anthropic.com>
EOF
)"
```
user-named issue adds a `Fixes: #<n>` trailer. Leave VERSION, CHANGELOG/fragment, TODOS.md
and the digest uncommitted: Step 16's `finish` commits them last with
`--trailer 'Co-Authored-By: Claude <noreply@anthropic.com>'`. Do not add a Git tag.
---
+5 -13
View File
@@ -520,7 +520,8 @@ chooses it in item 2 and ALREADY_BUMPED derives it in item 1.
runs items 1 and 3–5; each decision left to you is a `STOP:` naming its rerun flag
(`--bump`, `--accept-incomplete`, `--version <v>`, `--keep-current`, `--answer`).
`ship: queue_mode stamp-at-merge` replaces items 1–4.
`VERSION: skipped` or `VERSION: <v> kept (…; no write)` ends Step 12 with
`NEW_VERSION` unset: Step 13 follows its `NEXT:`; Steps 18 and 20 take NO_VERSION's branch.
1. **Classify state** — pure reader, never writes:
```bash
@@ -644,19 +645,10 @@ Make bisectable commits; if already committed, continue to Step 16. Never create
migrations may stand alone. Under 50 lines across fewer than 4 files may be one commit.
2. Order dependencies first: infrastructure → models/services → controllers/views.
Each commit works alone (no broken imports or missing code).
Group VERSION + CHANGELOG + TODOS.md after the feature commits.
3. Use `<type>: <summary>` (feat/fix/chore/refactor/docs) and a brief body; fixing a
user-named issue adds a `Fixes: #<n>` trailer. Only the final
VERSION/CHANGELOG commit gets the release version and co-author trailer. No Git tag:
```bash
git commit -m "$(cat <<'EOF'
chore: bump version and changelog (vX.Y.Z.W)
Co-Authored-By: OpenAI Codex <noreply@openai.com>
EOF
)"
```
user-named issue adds a `Fixes: #<n>` trailer. Leave VERSION, CHANGELOG/fragment, TODOS.md
and the digest uncommitted: Step 16's `finish` commits them last with
`--trailer 'Co-Authored-By: OpenAI Codex <noreply@openai.com>'`. Do not add a Git tag.
---
+5 -13
View File
@@ -522,7 +522,8 @@ chooses it in item 2 and ALREADY_BUMPED derives it in item 1.
runs items 1 and 3–5; each decision left to you is a `STOP:` naming its rerun flag
(`--bump`, `--accept-incomplete`, `--version <v>`, `--keep-current`, `--answer`).
`ship: queue_mode stamp-at-merge` replaces items 1–4.
`VERSION: skipped` or `VERSION: <v> kept (…; no write)` ends Step 12 with
`NEW_VERSION` unset: Step 13 follows its `NEXT:`; Steps 18 and 20 take NO_VERSION's branch.
1. **Classify state** — pure reader, never writes:
```bash
@@ -646,19 +647,10 @@ Make bisectable commits; if already committed, continue to Step 16. Never create
migrations may stand alone. Under 50 lines across fewer than 4 files may be one commit.
2. Order dependencies first: infrastructure → models/services → controllers/views.
Each commit works alone (no broken imports or missing code).
Group VERSION + CHANGELOG + TODOS.md after the feature commits.
3. Use `<type>: <summary>` (feat/fix/chore/refactor/docs) and a brief body; fixing a
user-named issue adds a `Fixes: #<n>` trailer. Only the final
VERSION/CHANGELOG commit gets the release version and co-author trailer. No Git tag:
```bash
git commit -m "$(cat <<'EOF'
chore: bump version and changelog (vX.Y.Z.W)
Co-Authored-By: Factory Droid <droid@users.noreply.github.com>
EOF
)"
```
user-named issue adds a `Fixes: #<n>` trailer. Leave VERSION, CHANGELOG/fragment, TODOS.md
and the digest uncommitted: Step 16's `finish` commits them last with
`--trailer 'Co-Authored-By: Factory Droid <droid@users.noreply.github.com>'`. Do not add a Git tag.
---
@@ -185,6 +185,22 @@ describe('ship/SKILL.md — Plan Completion gate invariants', () => {
expect(entry).not.toMatch(/Step 15\.[012]/);
});
test('one owner per release commit and a defined result for a version Step 12 does not write', () => {
// Value: protects=the ship workflow judge's 6/6 cited conflict (Step 15 committed release metadata by hand while Step 16 finish also commits it) and its 3/6 undefined stamp-at-merge/kept result; fails_when=Step 15 regains a manual release commit or Step 12 drops the skipped/kept route; why_new=no pin covered commit ownership; seam=none; no_claim=judge scores
const entry = fs.readFileSync(path.join(SHIP_DIR, 'SKILL.md'), 'utf8');
const commit = entry.slice(entry.indexOf('## Step 15:'), entry.indexOf('## Step 16:'));
expect(commit).not.toContain('git commit');
expect(commit.replace(/\s+/g, ' ')).toMatch(/TODOS\.md and the digest uncommitted: Step 16's `finish` commits them last/);
const finish = entry.slice(entry.indexOf('## Step 16:'), entry.indexOf('### 1. Finish writers'));
expect(finish).toContain("makes Step 15's item-3 commit");
const version = entry.slice(entry.indexOf('## Step 12:'), entry.indexOf('1. **Classify state**')).replace(/\s+/g, ' ');
expect(version).not.toContain('replaces items 1–4');
expect(version).toContain('`VERSION: skipped`');
expect(version).toContain('`VERSION: <v> kept (…; no write)` ends Step 12 with `NEW_VERSION` unset');
expect(version).toContain('ALREADY_BUMPED derives it in item 1');
expect(version).toContain("Steps 18 and 20 take NO_VERSION's branch");
});
test('a rejected push stops publication and routes changed content back through verification', () => {
const entry = fs.readFileSync(path.join(SHIP_DIR, 'SKILL.md'), 'utf8');
const push = entry.slice(entry.indexOf('## Step 17:'), entry.indexOf('## Step 20:'));
@@ -0,0 +1,4 @@
{
"bytes": 4,
"why": "Steps 12 and 15 name who makes the release commit and what a skipped or kept version leaves for Steps 13, 18 and 20 (ship workflow judge flake, GSTA-253)"
}