v1.89.1.0 fix: remove continuous checkpoint commits (#2970)

* v1.89.1.0 fix: remove continuous checkpoint commits and repair validation blockers

* fix: clarify shipping and engineering review recovery

* fix: interpret native no-change review descriptions

* test: separate descendant readiness from timeout delivery
This commit is contained in:
Garry Tan
2026-09-24 17:27:14 -04:00
committed by GitHub
parent 06ed920a97
commit 730a1017d1
103 changed files with 1819 additions and 2279 deletions
+19 -98
View File
@@ -295,31 +295,6 @@ For high-stakes ambiguity (architecture, data model, destructive scope, missing
A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked.
## Continuous Checkpoint Mode
If `CHECKPOINT_MODE` is `"continuous"`: auto-commit completed logical units with `WIP:` prefix.
Commit after new intentional files, completed functions/modules, verified bug fixes, and before long-running install/build/test commands.
Commit format:
```
WIP: <concise description of what changed>
[gstack-context]
Decisions: <key choices made this step>
Remaining: <what's left in the logical unit>
Tried: <failed approaches worth recording> (omit if none)
Skill: </skill-name-if-running>
[/gstack-context]
```
Rules: stage only intentional files, NEVER `git add -A`, do not commit broken tests or mid-edit state, and push only if `CHECKPOINT_PUSH` is `"true"`. Do not announce each WIP commit.
`/context-restore` reads `[gstack-context]`; `/ship` squashes WIP commits into clean commits.
If `CHECKPOINT_MODE` is `"explicit"`: ignore this section unless a skill or user asks to commit.
## Context Health (soft directive)
During long-running skill sessions, periodically write a brief `[PROGRESS]` summary: done, next, surprises.
@@ -670,14 +645,15 @@ service with existing deployment — verify that a distribution pipeline exists.
- B) Defer — add a P1 distribution TODO in Step 14
- C) Not needed — this is internal/web-only, existing deployment covers it
4. **If release pipeline exists:** Continue silently.
5. **If no new artifact detected:** Skip silently.
4. **If the user chooses A:** Add packaging and publish configuration using this repository's CI conventions. Ask for the intended distribution target if it is unknown; do not invent a registry or credentials. Include the new workflow in the tests and review below. Do not publish a release during `/ship`.
5. **If release pipeline exists:** Continue silently.
6. **If no new artifact detected:** Skip silently.
---
## Step 3: Merge the base branch (BEFORE tests)
Merge the base ref fetched in Step 1 so tests cover the same state used by Step 2:
Merge the base ref fetched in Step 1 so tests and reviews cover the integrated code:
```bash
git merge origin/<base> --no-edit
@@ -718,7 +694,7 @@ for slot selection. Bump level and queue collisions remain agent decisions.
```
Save the JSON `baseVersion` as `BASE_VERSION`, then read `state` and dispatch:
- **FRESH** → do the bump (steps 2-4).
- **ALREADY_BUMPED** → keep `NEW_VERSION` at `currentVersion`; recover the prior `BUMP_LEVEL` from the release decision (or base/current version difference), then run step 3's queue check. Do not bump again without approval.
- **ALREADY_BUMPED** → keep `NEW_VERSION` at `currentVersion`. Use the recorded level for this release; if absent, compare `baseVersion` and `currentVersion` left to right: the first changed major/minor/patch/micro component supplies `BUMP_LEVEL` (a missing fourth component is zero). Then run step 3's queue check. This recovers the level, not permission to bump again.
- **DRIFT_STALE_PKG** → run `gstack-version-bump repair`, then reclassify. On success, follow **ALREADY_BUMPED**, including its queue check; on failure, STOP. Repair alone never re-bumps.
- **DRIFT_UNEXPECTED** → **STOP**. package.json disagrees with VERSION while VERSION matches base — a manual edit bypassed /ship. Reconcile manually, then re-run.
@@ -776,25 +752,7 @@ Never turn dropped scope into TODOs or invent unapproved follow-ups. Reuse match
## Step 15: Commit (bisectable chunks)
### Step 15.0: Preserve checkpoint context
Run `~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode`. `continuous` means automatic `WIP:`
checkpoint commits; any other value skips WIP consolidation. In continuous mode,
count `WIP:` commits in `origin/<base>..HEAD`. If none exist, skip Step 15.2.
Otherwise preserve their context before committing or rewriting history:
```bash
mkdir -p "$(git rev-parse --show-toplevel)/.gstack"
git log origin/<base>..HEAD --grep="^WIP:" --format="%H%n%B%n---END---" > \
"$(git rev-parse --show-toplevel)/.gstack/wip-context-before-squash.md"
```
If export fails, do not rewrite history. Step 13 already read these bodies for
CHANGELOG; retain this PR context locally, outside commits.
### Step 15.1: Bisectable Commits
Create small, logical commits for `git bisect`. If all changes are already committed, continue to Step 15.2; never create an empty commit.
Create small, logical commits for `git bisect`. If all changes are already committed, continue to Step 16; never create an empty commit.
1. Group by coherent change. Keep each model/service/controller with its tests;
keep controller views together. Migrations may stand alone or accompany their
@@ -815,48 +773,6 @@ EOF
)"
```
### Step 15.2: Consolidate WIP commits when safe
After Step 15.1, run only for continuous-mode WIP commits. Require a clean working
tree except the context export. Run `git fetch origin`; failure means STOP.
Inspect `WIP_BASE..HEAD`, where `WIP_BASE` is `git merge-base HEAD origin/<base>`:
- **merge commits:** do not replay or flatten Step 3's integration merge.
- **published commits** (`git branch -r --contains <sha>` returns a ref): never rewrite.
- For either, ask to preserve WIP history and continue to Step 16 (recommended),
or stop for manual consolidation. Never rebase or force-push these paths.
For a linear, unpublished range, prepare and inspect an oldest-first todo.
Keep non-WIP commits as `pick` in relative order; put each WIP after its verified
logical target as `fixup`. Include every commit exactly once. An ambiguous or
out-of-range target needs a preserve-history/stop decision. First entry stays
`pick` or `reword`; all-WIP ranges retain a logical `reword` anchor. Rewording
requires a noninteractive `WIP_EDITOR` script that writes descriptive messages;
picks/fixups alone use `true`. Set the reviewed todo's absolute path below:
```bash
export WIP_TODO="<absolute path to prepared todo>"
test -s "$WIP_TODO" || exit 1
WIP_BASE=$(git merge-base HEAD origin/<base>) || exit 1
test -z "$(git status --porcelain -- . ':(exclude).gstack/wip-context-before-squash.md')" || exit 1
test -z "$(git rev-list --merges "$WIP_BASE"..HEAD)" || exit 1
for sha in $(git rev-list "$WIP_BASE"..HEAD); do
test -z "$(git branch -r --contains "$sha")" || exit 1
done
ORIGINAL_TREE=$(git rev-parse 'HEAD^{tree}')
GIT_EDITOR="${WIP_EDITOR:-true}" GIT_SEQUENCE_EDITOR='cp "$WIP_TODO"' git rebase -i "$WIP_BASE" || {
git rebase --abort
echo "STATUS: BLOCKED — WIP consolidation conflicted; original history restored"
exit 1
}
test "$ORIGINAL_TREE" = "$(git rev-parse 'HEAD^{tree}')" || {
echo "STATUS: BLOCKED — consolidation changed contents; inspect before continuing"
exit 1
}
```
Only an unchanged tree after successful consolidation may proceed to Step 16.
---
## Step 16: Verification Gate
@@ -885,14 +801,19 @@ Step 7 tests, review fixes, and Step 14 TODO edits intentionally make evidence S
- **Every line FRESH (exit 0):** recorded runs passed on identical content except
the listed release files. Cite label, exit, timestamp, and log path; continue.
- **Any STALE/MISSING (exit non-zero):** rerun the stale/missing lanes on final
content, wrapped as `~/.claude/skills/gstack/bin/gstack-evidence run --label <lane> -- '<command>'`.
Read results and recheck once. A content, command, or age mismatch requires
relevant fresh verification. If the ledger alone cannot record or verify a
successful live run, confirm unchanged final content and cite the exact command,
exit, and log; report ledger unavailable and continue, but never label the ledger FRESH.
If unchanged content cannot be confirmed, STOP. Do not rerun green suites solely for bookkeeping.
A failed CHECK selects live verification: a failed CHECK never blocks; a failed RUN does, except for the explicit triage waiver below.
- **Any STALE/MISSING (exit non-zero):** inspect the reason before choosing recovery:
- **Content, command or age mismatch, or no passing live evidence:** rerun the
affected lanes on final content, wrapped as `~/.claude/skills/gstack/bin/gstack-evidence run --label <lane> -- '<command>'`.
Read results and recheck once. TODO edits and generated tests are content
changes, not ledger-only bookkeeping.
- **Ledger read/write failure only:** if a successful live run already covers
the unchanged final content, exact command and permitted age, cite its exit,
timestamp and log directly. Report ledger unavailable and continue, never
ledger FRESH. Do not rerun green suites solely because the ledger cannot save
or read its record. If unchanged content cannot be confirmed, STOP.
A failed CHECK identifies evidence to repair; it is not a test failure. The
required live RUN must pass, except for the explicit triage waiver below.
Paste build and rerun results. Later code, test, or build-input changes return
through this gate before pushing. Step 18 owns validation of its post-push