mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-31 22:14:25 +01:00
* feat(ship): GSTA-167 turn levers on the restored reviewers: ship preflight/release bins, own-jam meter, dispatch-pair metering, ship/DRIVER.md
Ports the non-reviewer parts of #3633 (gsta-167-pr34) and #3637 (gsta-167-pr5 @2914400)
onto main ae3d58c (v1.91.331.0). Reviewer briefs, checklists, the fix-check prompt and
the depth rules are byte-identical to main and now pinned in
test/review-packets-removed.test.ts.
Left out: gstack-review-packet and its libs, parallel/batched fanout, --like, collect,
the audit prompt split, the docs-audit packet, review-army/adversarial/outside-voice
edits, the gate-scan summary-only block and the review-depth scope-error change.
Packet-bytes reader pricing is dropped from gstack-ship-budget; handoff READ ranges
send each section whole; the driver runs the audit, review, adversarial and
documentation sections as written.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(context-budget): raise the capy/skill/gstack eager ceiling to its captured value after the main merge (own-jam meter, driver and reviewer-batch prose, GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(ship-driver): name ship/DRIVER.md.tmpl so the pregate maps the template to its test lane (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-driver): keep the skill generator off lib/ship-budget so a minimal setup checkout still renders (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(windows): keep test/ship-release.test.ts off the Windows subset; it launches the shebang bin and sh stubs directly (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship): variant E orchestration: one program per review pass and Step 14.5 audit, the review child starts at Step 9, a metered dispatch:docs role, and the driver's record headings (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship): variant G orchestration: one call per driver phase (9 for a clean pass, at most 12), gstack-ship-preflight --audit for single reads and deterministic audits, an observe-mode ledger with note and credits, 240 s wait pings, and small-model audit readers (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-budget): a Capy handoff child needs no jam id: verify-handoff with no reading makes it parent-metered (METER: parent), it never delegates on an unknown charge, and reconcile charges the parent's counter delta (GSTA-167 replay 7e)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): a poll settles a reader only at done, failed or a final summary, never a fresh idle; return settles the child's open step reservation (GSTA-167 replay 7e)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-budget): return releases an open step reservation under the estimate meter instead of booking its projection; measured meters still settle it (GSTA-167 replay 7e)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review): a clean fix-check after below-floor fixes is done; Step 11 and fix-check below-floor findings are notes at pass 1
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship): verbatim reviewer briefs and loss-free collection (gstack-review-dispatch render/sent/collect/judge/verify)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
- verify requires each output's brief rendered and sent verbatim, reruns judge
against the recorded judged.jsonl hash, and flags outputs collected after judge
- judge drops self-folds, fold cycles and chains
- prose findings parse a leading label or a label heading, not any severity word
- releasePaths: manifests count as release metadata only for version-only edits,
lockfiles never; TODOS.md stays out of lane-evidence exemptions
- push stops when the sealed-output guard did not run
- ship-audit reads the test tree once instead of one git grep per file
- drop the uncalled --delegate measured mode; doc/help step-number fixes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (pass 2)
- collect keeps a finding wherever its label stands (headings, table rows,
mid-line, Informational and upper-case labels); only top-level list items
inherit a label heading, and any heading or bold-only line ends it
- judge treats a merged file missing any collected id as a drop; verify flags
merged_ids_missing and a sent reader never collected (NOT_COLLECTED)
- finish computes release paths after --build, so a build that rewrites
package.json is a build-input change
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review-dispatch): verify per render, voided superseded mismatches
- verify treats each render as one dispatch of its reader, so a two-pass
ledger compares pass-1 sends with pass-1 briefs (later renders print as
<reader>@2); outputs bind to the latest send of their own render
- a mismatched send re-sent byte-exact before anything was collected is void
and counted (voided=N on the verdict line); one that produced an output
stays MISMATCH
- an indented bold sub-line no longer ends a label section (fix-check)
- docs: a failed reader is collected from its failure text
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review-dispatch): only the newest render of a path checks its file; absolute ledger paths
- a later render into the same briefs directory overwrites the earlier brief by
design, so verify checks a brief file only for the newest render of that path
- collect and judge record absolute output, merged and judged paths, so verify
reads them from any directory
- docs: a failed reader's failure text is parsed like any output
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore: changelog and TODOS
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-release): the changelog_fragments fragment is release metadata
Fix-check 4 (CRITICAL) after the main merge: releasePaths omitted
<changelog_fragments.dir>/<branch-slug>.md, so finish stopped on the
fragment Step 13 writes under gstack's policy, or routed it to re-review.
version now names the fragment in its Step 13 NEXT line instead of
[Unreleased], DRIVER.md Step 13 writes and lints where NEXT says, and the
preflight POLICY line says Steps 12-16.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore: changelog and TODOS
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>
130 lines
6.8 KiB
Cheetah
130 lines
6.8 KiB
Cheetah
## Step 4: Test Framework Bootstrap
|
|
|
|
{{TEST_BOOTSTRAP}}
|
|
|
|
---
|
|
|
|
## Step 5: Run tests (on merged code)
|
|
|
|
**Run it:** `~/.claude/skills/gstack/bin/gstack-ship-preflight --tests-only --base <base> --lane <label>=<command>...`
|
|
(or the Step 1 call with lanes). It runs the free pre-gate first, before any lane, eval or
|
|
remote gate (`gstack-pregate --allow-repo-commands`: stage 1 regen, secrets, strays, literals;
|
|
stage 2 the selected lanes under pipefail), then every lane in parallel inside the evidence
|
|
ledger, and prints `PREGATE:` and one `LANE: <label> <state> exit= tests_ran= log=` line each.
|
|
`fail` or `incomplete` blocks: fix, rerun. `requires-remote` (other platforms; the remote gate under 8 cores) needs
|
|
`gstack-pregate clear` or, under a user cap, `--remote --spend-cap <usd>`. Rerun
|
|
after the final stamp (`gstack-ship-release finish` does); Step 18 refuses a stale one.
|
|
|
|
Use the project's test commands discovered in Step 4 or documented in CLAUDE.md/AGENTS.md. Run every applicable suite; do not assume Rails or Vitest. Pass each as `--lane <label>=<command>`; use the same lane labels and exact commands again in Step 16.
|
|
|
|
**If no applicable test suite exists:** Name the untested scope. AskUserQuestion:
|
|
A) Add tests (recommended), B) Ship with this named testing
|
|
gap, or C) Stop. Reuse an actual prior B answer only for the same scope and
|
|
content; declining bootstrap alone is not that approval. B continues with the
|
|
gap recorded, not passing tests. Independent build, eval, review and QA gates
|
|
still apply. A declared but unavailable suite is a blocker, not an absent suite.
|
|
A runs Step 4 with this new bootstrap choice, then returns here to run the tests.
|
|
C stops this attempt.
|
|
|
|
**For Rails projects using `bin/test-lane`, do NOT run `RAILS_ENV=test bin/rails db:migrate`** — `bin/test-lane` already calls
|
|
`db:test:prepare` internally, which loads the schema into the correct lane database.
|
|
Running bare test migrations without INSTANCE hits an orphan DB and corrupts structure.sql.
|
|
|
|
Each lane runs as `gstack-evidence run --label <label> -- '<command>'`: transparent (exit code passes
|
|
through) and recorded as `{command, exit, working-tree fingerprint, log path}` in
|
|
`$GSTACK_STATE_ROOT/projects/<slug>/<branch>-evidence.jsonl`, which Step 16 cites instead of
|
|
re-running when the content hasn't changed. Each lane has its own log (no shared /tmp
|
|
collisions between concurrent ships); read it for failure detail.
|
|
|
|
**A lane passes on its runner summary line, not on exit 0 alone.** Read each
|
|
lane's `tests_ran` from its `LANE:` line (or from the runner's own summary in the log)
|
|
and keep the three states apart; never merge them:
|
|
|
|
1. `tests_ran: N` (N > 0) with exit 0 — the lane passed; record N for the PR body.
|
|
2. `tests_ran: 0` — **ZERO-RUN**: bun `0 pass 0 fail`, jest "No tests found", pytest
|
|
"no tests ran", rspec "0 examples", `go test` with only `[no test files]`, or an
|
|
empty selection after a filter. Exit 0 here is not a pass, so triage a ZERO-RUN
|
|
lane below as a failed lane: a bad selector, a missing file or a skipped `describe`
|
|
is an in-branch failure until proven otherwise.
|
|
3. `tests_ran: unknown` — the runner's summary was not recognised. Keep today's
|
|
exit-0 pass and record `count unavailable` for that lane in the PR body.
|
|
|
|
**If any test fails:** Do NOT immediately stop. When a free-suite shard failed,
|
|
first Read `~/.claude/skills/gstack/ship/sections/measure.md` and rerun that
|
|
shard's file list as it says (diagnostic, not a verdict). Then apply the Test
|
|
Failure Ownership Triage:
|
|
|
|
{{TEST_FAILURE_TRIAGE}}
|
|
|
|
**After triage:** If any in-branch failures remain unfixed, **STOP**. Do not proceed. If all failures were pre-existing and handled (fixed, TODOed, assigned, or skipped), continue to Step 6.
|
|
|
|
**If all pass:** Report each lane's pass count (or `count unavailable`) in one line and continue to Step 6.
|
|
|
|
---
|
|
|
|
## Step 6: Eval Suites (conditional)
|
|
|
|
Evals are mandatory when prompt-related files change. Select from the full diff,
|
|
including uncommitted changes, before deciding whether to skip.
|
|
|
|
**1. Select affected suites using the project's contract.**
|
|
|
|
**Project-native path:** Read CLAUDE.md/AGENTS.md, package scripts and the eval
|
|
dependency map. Include changed prompts, skill templates, judges and harness
|
|
code. Use the documented selector and pre-merge command. If it reports no
|
|
affected suites, record that result and continue to Step 7. If prompt-related
|
|
files changed but selection or the command is unknown, report the validation
|
|
gap and ask before shipping. A missing Rails-pattern match is not a skip signal
|
|
for another stack.
|
|
|
|
**Rails example only — when this repository provides `bin/test-lane` and
|
|
`test/evals/*_eval_runner.rb`:**
|
|
|
|
- Match the diff against the project's documented prompt paths, such as
|
|
`app/services/*_prompt_builder.rb`, generation/writer/designer services,
|
|
evaluator/scorer/classifier/analyzer services, voice/writing/prompt/token
|
|
concerns, chat tools, `config/system_prompts/*.txt` and `test/evals/**/*`.
|
|
- Match changed files to each runner's `PROMPT_SOURCE_FILES`; follow shared
|
|
judge/support/fixture imports to all affected suites. A runner such as
|
|
`post_generation_eval_runner.rb` maps to `post_generation_eval_test.rb`.
|
|
- Use the project's full pre-merge tier (`EVAL_JUDGE_TIER=full` for this runner).
|
|
Do not substitute a cheaper development tier. If selection remains uncertain,
|
|
include every plausibly affected suite.
|
|
|
|
**2. Run the selected command and preserve its exit status.**
|
|
|
|
For the Rails example:
|
|
|
|
```bash
|
|
set -o pipefail
|
|
EVAL_JUDGE_TIER=full EVAL_VERBOSE=1 bin/test-lane --eval test/evals/<suite>_eval_test.rb 2>&1 | tee /tmp/ship_evals.txt
|
|
```
|
|
|
|
Use the native command for other stacks. Respect the project's concurrency and
|
|
retry policy. Rails suites sharing a test lane run sequentially; stop on the
|
|
first failure before starting another paid suite.
|
|
|
|
**Long eval suites (30+ min): launch detached so a turn boundary can't kill them.**
|
|
Use the detached runner and eval lock; set its outer timeout to cover the
|
|
project's declared suite duration and retries. Do not change individual eval
|
|
limits. For a suite whose full bound fits 5400 seconds:
|
|
|
|
```bash
|
|
~/.claude/skills/gstack/bin/gstack-detach --label ship-evals --lock gstack-evals --timeout 5400 -- <project eval command>
|
|
```
|
|
|
|
Poll the printed log for `### gstack-detach EXIT=<code> ###`. Silence is not
|
|
success. Retain every configured attempt; skipped or unstarted cases do not
|
|
satisfy coverage.
|
|
|
|
**3. Check results and save evidence for Step 19.**
|
|
|
|
- **If any eval fails:** Do not rerun the full gate. Show failures and available
|
|
costs, then Read `~/.claude/skills/gstack/ship/sections/measure.md` and run its
|
|
loop for each red case: classify, measure alone, fix at the cause, re-measure,
|
|
then gate once. **STOP** only at its named-red stop.
|
|
- **If all selected evals pass:** Record actual counts, any reused evidence and
|
|
its source, and available costs. Continue to Step 7.
|
|
|
|
---
|