mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-05 00:03:15 +01:00
fix(ship): shared-queue pointer rides the show-effective ship: line (ship skeleton has 2 bytes of parity headroom)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 5b33d4a015)
This commit is contained in:
1 parent
8171f52bbf
commit
da67a3cd2b
5 files changed
+3
-10
No files matched your search
@@ -262,6 +262,7 @@ which carry the workflow consequences the skill prose would otherwise spell out:
|
||||
|---|---|
|
||||
| `ship: history merge-only: …` | never rebase, squash or force-push; `check-history --plan <merge\|squash\|rebase>` refuses a rewrite plan (`HISTORY_POLICY_VIOLATION`, exit 3) |
|
||||
| `ship: queue_mode stamp-at-merge: …` | Step 12 items 1–4 are replaced by `gstack-restamp --next --base <base> --pr <n> --expect-base <sha>` when the PR is next, `--after <predecessor-pr>` when it is not; the restamp's own `next:` line says what follows (NEW_VERSION, CHANGELOG entry text only, the merge's expected head) |
|
||||
| `ship: shared merge queue: …` | in a coordinator-run queue, `gstack-ship-queue ready`, `gate-ahead` and `stamp` replace the restamp calls; see [Run a shared merge queue](#run-a-shared-merge-queue) |
|
||||
| `ship: gate-ahead: …` | with `.gstack/tmp/gate-ahead.json` present, Step 16 reuses only the lanes `gstack-tree-receipt … --json > .gstack/tmp/tree-receipt.json` marks reusable; stamp-sensitive and not-eligible lanes run live; `--force-gate <reason>` is the coordinator's call |
|
||||
| `ship: bump patch: …` | Step 12 never asks for MINOR or MAJOR; PATCH or MICRO by size |
|
||||
| `ship: preregistration: …` | `gstack-evidence ancestor --from-policy --base <base>` must print only `ANCESTOR: ok` before push |
|
||||
|
||||
@@ -458,6 +458,7 @@ export function shipConsequences(policy: ShipPolicy, base: string): string[] {
|
||||
if (policy.history === 'merge-only') out.push('history merge-only: never rebase, squash or force-push this branch; `gstack-ship-policy check-history --plan <merge|squash|rebase>` refuses a rewrite plan (HISTORY_POLICY_VIOLATION)');
|
||||
if (policy.queue_mode === 'stamp-at-merge') {
|
||||
out.push(`queue_mode stamp-at-merge: Step 12 items 1-4 are replaced by \`gstack-restamp --next --base ${base} --pr <pr-number> --expect-base <base-sha>\` when this PR is next in the queue (\`--after <predecessor-pr>\` gates ahead in a throwaway worktree when it is not); follow its next: line; claims are ignored`);
|
||||
out.push(`shared merge queue: when a coordinator runs the queue, \`gstack-ship-queue ready --pr <n>\`, \`gate-ahead --after <pr> --pr <n>\` and \`stamp --pr <n> --version <X> --expect-gated <sha> --expect-base <sha>\` replace the calls above; stamp only when your slot is called, send the READY block and the QUEUE_STAMP: line; the coordinator runs \`gstack-ship-queue verify\` (docs/ship-policy.md#run-a-shared-merge-queue)${policy.gate_command ? `; gate command: \`${policy.gate_command}\`` : ''}`);
|
||||
out.push('gate-ahead: with .gstack/tmp/gate-ahead.json present, Step 16 reuses only the lanes `gstack-tree-receipt --from .gstack/tmp/gate-ahead.json --predecessor-pr <pr> --bundle <bundle> --json > .gstack/tmp/tree-receipt.json` marks reusable; stamp-sensitive and not-eligible lanes run live; `--force-gate <reason>` is the coordinator\'s call');
|
||||
} else out.push('queue_mode claim-at-open: Step 12 runs as written (claims through gstack-next-version)');
|
||||
out.push(policy.bump === 'patch' ? 'bump patch: Step 12 never asks for MINOR or MAJOR; PATCH or MICRO by size' : 'bump ask: Step 12 asks for MINOR and MAJOR as written');
|
||||
|
||||
@@ -770,11 +770,6 @@ chooses it in item 2 and ALREADY_BUMPED derives it in item 1.
|
||||
|
||||
`ship: queue_mode stamp-at-merge` replaces items 1–4.
|
||||
|
||||
**Shared merge queue:** when a coordinator runs the queue, use
|
||||
`~/.claude/skills/gstack/bin/gstack-ship-queue ready | gate-ahead | stamp`
|
||||
(docs/ship-policy.md#run-a-shared-merge-queue): stamp only when your slot is
|
||||
called, and send the printed READY and `QUEUE_STAMP:` lines.
|
||||
|
||||
1. **Classify state** — pure reader, never writes:
|
||||
```bash
|
||||
bun run ~/.claude/skills/gstack/bin/gstack-version-bump classify --base <base>
|
||||
|
||||
@@ -235,11 +235,6 @@ chooses it in item 2 and ALREADY_BUMPED derives it in item 1.
|
||||
|
||||
`ship: queue_mode stamp-at-merge` replaces items 1–4.
|
||||
|
||||
**Shared merge queue:** when a coordinator runs the queue, use
|
||||
`~/.claude/skills/gstack/bin/gstack-ship-queue ready | gate-ahead | stamp`
|
||||
(docs/ship-policy.md#run-a-shared-merge-queue): stamp only when your slot is
|
||||
called, and send the printed READY and `QUEUE_STAMP:` lines.
|
||||
|
||||
1. **Classify state** — pure reader, never writes:
|
||||
```bash
|
||||
bun run ~/.claude/skills/gstack/bin/gstack-version-bump classify --base <base>
|
||||
|
||||
@@ -56,6 +56,7 @@ describe('through the binaries', () => {
|
||||
expect(r.out).toContain(`KEY: gate_command introduced=${SHIP_QUEUE_KEYS_VERSION}\n`);
|
||||
expect(r.out).toContain(`MIN_READER: gstack ${SHIP_QUEUE_KEYS_VERSION} `);
|
||||
expect(JSON.parse(runBin(repo, 'gstack-ship-policy', ['validate', '--json']).out).min_reader).toBe(SHIP_QUEUE_KEYS_VERSION);
|
||||
expect(runBin(repo, 'gstack-ship-policy', ['show-effective', '--base', 'main']).out).toMatch(/^ship: shared merge queue: .*gstack-ship-queue ready --pr <n>.*\(docs\/ship-policy\.md#run-a-shared-merge-queue\); gate command: `bun run test`$/m);
|
||||
const explain = runBin(repo, 'gstack-ship-policy', ['init', '--explain']);
|
||||
expect(explain.out).toMatch(new RegExp(`^full_e2e: .* default: false introduced: ${SHIP_QUEUE_KEYS_VERSION.replace(/\./g, '\\.')}$`, 'm'));
|
||||
}, 60_000);
|
||||
|
||||
Reference in new issue
Block a user