38 Commits
Author SHA1 Message Date
Garry Tanandcapy-ai[bot] 807aaa8da5 v1.91.363.0 Evidence ignores Bun's .bun/ cache, --check-prose skips the Approvals table, pr-body drops stale intros (GST-421, GST-412) (#3675)
* fix(evidence): leave an untracked root .bun/ out of the fingerprint and name mid-run changes (GST-421)

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

* fix(ship-receipt): --check-prose skips the rendered Approvals block (GST-412)

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

* fix(gstack-post): pr-body with sections replaces stale text above the first heading (GST-412)

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

* fix(review): withhold flagged dropped-preamble excerpts, keep forged Approvals rows checked, sanitize wtree_changed (GST-412, GST-421)

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

* docs: GST-421/GST-412 review follow-ups in TODOS, fragment and troubleshooting

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>
2026-10-31 11:15:23 +00:00
Garry Tanandcapy-ai[bot] e744bfe994 v1.91.353.0 fix(ship): Step 12 keeps VERSION on --keep-current, adds bump never, and waits for the owner's answer before an unattended bump (GST-380) (#3666)
* test(ship): failing-first Step 12 keep-current refusal and unattended early bump write (GST-380)

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

* fix(ship): Step 12 keeps VERSION on --keep-current, adds bump never, and waits for the owner's answer before an unattended bump (GST-380)

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

* test: regenerate ship SKILL goldens (GST-380)

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

* fix: pre-landing review fixes (answer gate covers ALREADY_BUMPED --version writes; typed session rows; never drift and --answer rejection cases)

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

* fix: pre-landing review fixes (the answer gate names every flag that decides the write; Version Gate and validate understand bump never)

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

* fix: under bump never a release PR that moves VERSION takes the Version Gate's ordinary rules

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

* docs(changelog): fragment for GST-380 Step 12 keep-current and bump never

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>
2026-10-31 06:07:36 +00:00
Garry Tanandcapy-ai[bot] 21277291c8 v1.91.345.0 feat(ship): compact driver plus preflight/release bins over the restored reviewers (GSTA-167) (#3648)
* 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>
2026-10-31 01:09:31 +00:00
Garry Tanandcapy-ai[bot] c6e781f4a9 ship-receipt: carry counts changelog_fragments fragments as release metadata (GST-343) (#3656)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-31 00:56:31 +00:00
Garry Tanandcapy-ai[bot] 53522b1bbc v1.91.342.0 ship-policy: gstack versions its own PRs at merge time (changelog_fragments on; GSTA-154 P) (#3654)
* captain: train land per slot under changelog_fragments (skill and skills.md)

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

* ship-policy: turn changelog_fragments on for gstack (required checks, key version 1.91.336.0); mergeChangelogs keeps a stacked child's only line inside its released parent's list

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

* review fixes: a carried child entry never repeats a released parent line; min_gstack_version 1.91.340.0; required-check names as GitHub reports them

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>
2026-10-30 21:28:02 +00:00
Garry Tanandcapy-ai[bot] 7bc2034724 v1.91.340.0 ship-queue: train land counts a slot as merged only when GitHub reports it MERGED (#3603) (#3613)
* feat(ship-policy): changelog_fragments key; restamp folds fragments; tree receipt accepts the fold

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

* feat(ship-queue): land, the per-PR merge step; Version Gate enforces fragments

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

* feat(ship-queue): land --repair after drift; hook base sha; docs and CHANGELOG

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

* test: timeout on the land gh shim's git spawn

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

* feat(ship): /ship writes a CHANGELOG fragment under changelog_fragments; land checks the depth-checked receipt (#3567)

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

* test(land): keeps the base's four-part package.json (#3557)

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

* fix(ship-queue): land waits for CI through runScriptSync (script-invocation tripwire)

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

* test: land, fragment and Version Gate cases from /ship's coverage audit

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

* test(windows): leave test/ship-queue-land.test.ts out of the Windows-safe subset (gh shim cannot launch there)

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

* docs(ship-policy): rollback lands open fragment PRs first; restamp folds only with the key on

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

* fix(land): close pre-landing review findings

land without --no-wait now compares the pushed branch head and polls the
stamp commit's checks, refuses a PR whose base is not the stamped base,
releases the lock on a pre-push failure, keeps --break-lock off drift
locks, resumes from a lost journal via the stamp commit's pin, honours
history merge-only, and refuses a fragment whose text is already released
on the base. Version Gate stops applying open claims to a fragments stamp.

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

* fix(land): close adversarial and outside-voice findings

land reconciles a merge GitHub completed behind an error reply, refuses
--break-lock against a holder that just entered a push or a merge, keeps
a repair takeover on the lock itself (any checkout can land the repair
PR), resumes --repair after a failed PR create, releases the lock on
QUEUE_LAND_BASE_BUSY, never writes through a symlinked release file,
keeps a package.json version source's other edits, and refuses an empty
object id instead of pushing a deletion. A carried-back fragment is
matched on whole released lines. Under changelog_fragments Version Gate
accepts a stamped head only as a [pin, base] merge-step commit with valid
fragments.

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

* feat(land): refuse a pin without a READY receipt; symlinked release files refuse before restamp

Under changelog_fragments, gstack-ship-queue ready records a READY receipt
(refs/notes/gstack-trains) once its pregate, full_e2e and /ship receipt
checks pass, and land refuses a pin without one (fix: run
gstack-ship-queue ready --pr N), --dry-run included (GStack Minder ruling,
2026-10-29). The merged tree's release files may not be symlinks, so
restamp never writes outside the scratch worktree. --repair adopts an
existing branch only when it holds land's repair commit.

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

* fix(pregate): clear's stamp-only substitution applies the changelog_fragments fold; docs match land and ready

gstack-pregate clear and gstack-tree-receipt now classify through one
classifyFiles, so under changelog_fragments a receipt for the fragment head
clears the stamped head when the stamp is exactly the fold. The ship-policy
reference names ready's receipt push, land's own check polling, the key-off
refusal and the /ship changelog_fragments line.

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

* docs(pregate, ship-policy): the fragment fold's two receipt rules, and clear applies them too

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

* feat(ship-queue): stamped train prefixes S_i with the self-check (PR B)

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

* feat(ship-queue): train build stamps S_i under fragments; train land publishes S_i exactly; backstop covers exact trees (PR B)

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

* docs: stamped trains and train land; QUEUE_TRAIN_STAMP_MISMATCH anchor

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

* captain templates: fragments instead of [Unreleased]; no slot call for stamped trains

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

* test: timeouts on the train-land gh wrapper's sync spawns

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

* feat(ship-queue): train land checks the depth-checked receipt (#3567); regenerate the doctor anchors

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

* test(train-stamp): S_i keeps the base's four-part package.json (#3557)

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

* test(windows): leave test/ship-queue-train-land.test.ts out of the Windows-safe subset (same gh shim as the train tests)

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

* fix(train-land): close pre-landing review and outside-voice findings

- train land checks commit-tree and stamps with a fixed identity and date, journals before the push, and
  adopts its own stamp head on a rerun; a failed commit-tree never pushes a branch deletion
- a symlinked release file in the merged tree refuses before the train stamp writes
- mergeStep merges a conflicted manifest three-way with the predecessor's version (mergeManifest, shared with land)
- train land refuses a PR retargeted off the base and a failed base refresh
- Version Gate skips a released fragment carried in by a stacked pin instead of counting its bump
- bisect of a stamped train tests T0 and S_1..S_k

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

* fix(train-land): a rerun whose head is still the pin re-enters the stamp step after a journaled, unpushed stamp

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

* fix(train-land): prove the record's S_i is on the gated chain before stamping; a merge main does not show yet pends

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

* fix(train-land): pin S_i to the gated head's exact prefix; an out-of-order slot refuses without freezing; stamps never sign

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

* fix(train-land): pin S_i to slot position; a failed push or unreadable PR never reads as a move; reruns of landed slots confirm; T0 in the out-of-order refusal

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

* feat(train-land): verify the whole stamped chain from git before landing; require changelog_fragments.required_checks green on the stamp commit

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

* docs(ship-policy, troubleshooting, harness): train land refusals, resume and required checks; stamped bisect; three-way manifest merges

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

* fix(train-land): count a slot as merged only when GitHub reports its PR MERGED (#3603)

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

* ship: write the Steps 12-16 range with an ASCII hyphen so the skeleton fits maxSkeletonBytes

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>
2026-10-30 19:39:14 +00:00
Garry Tanandcapy-ai[bot] 3df7484bc7 v1.91.339.0 ship-queue: stamped merge-train prefixes and train land (GSTA-154 PR B) (#3595)
* feat(ship-policy): changelog_fragments key; restamp folds fragments; tree receipt accepts the fold

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

* feat(ship-queue): land, the per-PR merge step; Version Gate enforces fragments

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

* feat(ship-queue): land --repair after drift; hook base sha; docs and CHANGELOG

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

* test: timeout on the land gh shim's git spawn

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

* feat(ship): /ship writes a CHANGELOG fragment under changelog_fragments; land checks the depth-checked receipt (#3567)

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

* test(land): keeps the base's four-part package.json (#3557)

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

* fix(ship-queue): land waits for CI through runScriptSync (script-invocation tripwire)

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

* test: land, fragment and Version Gate cases from /ship's coverage audit

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

* test(windows): leave test/ship-queue-land.test.ts out of the Windows-safe subset (gh shim cannot launch there)

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

* docs(ship-policy): rollback lands open fragment PRs first; restamp folds only with the key on

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

* fix(land): close pre-landing review findings

land without --no-wait now compares the pushed branch head and polls the
stamp commit's checks, refuses a PR whose base is not the stamped base,
releases the lock on a pre-push failure, keeps --break-lock off drift
locks, resumes from a lost journal via the stamp commit's pin, honours
history merge-only, and refuses a fragment whose text is already released
on the base. Version Gate stops applying open claims to a fragments stamp.

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

* fix(land): close adversarial and outside-voice findings

land reconciles a merge GitHub completed behind an error reply, refuses
--break-lock against a holder that just entered a push or a merge, keeps
a repair takeover on the lock itself (any checkout can land the repair
PR), resumes --repair after a failed PR create, releases the lock on
QUEUE_LAND_BASE_BUSY, never writes through a symlinked release file,
keeps a package.json version source's other edits, and refuses an empty
object id instead of pushing a deletion. A carried-back fragment is
matched on whole released lines. Under changelog_fragments Version Gate
accepts a stamped head only as a [pin, base] merge-step commit with valid
fragments.

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

* feat(land): refuse a pin without a READY receipt; symlinked release files refuse before restamp

Under changelog_fragments, gstack-ship-queue ready records a READY receipt
(refs/notes/gstack-trains) once its pregate, full_e2e and /ship receipt
checks pass, and land refuses a pin without one (fix: run
gstack-ship-queue ready --pr N), --dry-run included (GStack Minder ruling,
2026-10-29). The merged tree's release files may not be symlinks, so
restamp never writes outside the scratch worktree. --repair adopts an
existing branch only when it holds land's repair commit.

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

* fix(pregate): clear's stamp-only substitution applies the changelog_fragments fold; docs match land and ready

gstack-pregate clear and gstack-tree-receipt now classify through one
classifyFiles, so under changelog_fragments a receipt for the fragment head
clears the stamped head when the stamp is exactly the fold. The ship-policy
reference names ready's receipt push, land's own check polling, the key-off
refusal and the /ship changelog_fragments line.

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

* docs(pregate, ship-policy): the fragment fold's two receipt rules, and clear applies them too

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

* feat(ship-queue): stamped train prefixes S_i with the self-check (PR B)

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

* feat(ship-queue): train build stamps S_i under fragments; train land publishes S_i exactly; backstop covers exact trees (PR B)

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

* docs: stamped trains and train land; QUEUE_TRAIN_STAMP_MISMATCH anchor

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

* captain templates: fragments instead of [Unreleased]; no slot call for stamped trains

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

* test: timeouts on the train-land gh wrapper's sync spawns

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

* feat(ship-queue): train land checks the depth-checked receipt (#3567); regenerate the doctor anchors

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

* test(train-stamp): S_i keeps the base's four-part package.json (#3557)

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

* test(windows): leave test/ship-queue-train-land.test.ts out of the Windows-safe subset (same gh shim as the train tests)

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

* fix(train-land): close pre-landing review and outside-voice findings

- train land checks commit-tree and stamps with a fixed identity and date, journals before the push, and
  adopts its own stamp head on a rerun; a failed commit-tree never pushes a branch deletion
- a symlinked release file in the merged tree refuses before the train stamp writes
- mergeStep merges a conflicted manifest three-way with the predecessor's version (mergeManifest, shared with land)
- train land refuses a PR retargeted off the base and a failed base refresh
- Version Gate skips a released fragment carried in by a stacked pin instead of counting its bump
- bisect of a stamped train tests T0 and S_1..S_k

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

* fix(train-land): a rerun whose head is still the pin re-enters the stamp step after a journaled, unpushed stamp

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

* fix(train-land): prove the record's S_i is on the gated chain before stamping; a merge main does not show yet pends

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

* fix(train-land): pin S_i to the gated head's exact prefix; an out-of-order slot refuses without freezing; stamps never sign

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

* fix(train-land): pin S_i to slot position; a failed push or unreadable PR never reads as a move; reruns of landed slots confirm; T0 in the out-of-order refusal

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

* feat(train-land): verify the whole stamped chain from git before landing; require changelog_fragments.required_checks green on the stamp commit

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

* docs(ship-policy, troubleshooting, harness): train land refusals, resume and required checks; stamped bisect; three-way manifest merges

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

* ship: write the Steps 12-16 range with an ASCII hyphen so the skeleton fits maxSkeletonBytes

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>
2026-10-30 19:23:01 +00:00
Garry Tanandcapy-ai[bot] e474a4fb53 v1.91.336.0 ship-queue: assign VERSION/CHANGELOG at merge time (changelog fragments + gstack-ship-queue land) (#3594)
* feat(ship-policy): changelog_fragments key; restamp folds fragments; tree receipt accepts the fold

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

* feat(ship-queue): land, the per-PR merge step; Version Gate enforces fragments

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

* feat(ship-queue): land --repair after drift; hook base sha; docs and CHANGELOG

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

* test: timeout on the land gh shim's git spawn

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

* feat(ship): /ship writes a CHANGELOG fragment under changelog_fragments; land checks the depth-checked receipt (#3567)

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

* test(land): keeps the base's four-part package.json (#3557)

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

* fix(ship-queue): land waits for CI through runScriptSync (script-invocation tripwire)

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

* test: land, fragment and Version Gate cases from /ship's coverage audit

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

* test(windows): leave test/ship-queue-land.test.ts out of the Windows-safe subset (gh shim cannot launch there)

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

* docs(ship-policy): rollback lands open fragment PRs first; restamp folds only with the key on

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

* fix(land): close pre-landing review findings

land without --no-wait now compares the pushed branch head and polls the
stamp commit's checks, refuses a PR whose base is not the stamped base,
releases the lock on a pre-push failure, keeps --break-lock off drift
locks, resumes from a lost journal via the stamp commit's pin, honours
history merge-only, and refuses a fragment whose text is already released
on the base. Version Gate stops applying open claims to a fragments stamp.

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

* fix(land): close adversarial and outside-voice findings

land reconciles a merge GitHub completed behind an error reply, refuses
--break-lock against a holder that just entered a push or a merge, keeps
a repair takeover on the lock itself (any checkout can land the repair
PR), resumes --repair after a failed PR create, releases the lock on
QUEUE_LAND_BASE_BUSY, never writes through a symlinked release file,
keeps a package.json version source's other edits, and refuses an empty
object id instead of pushing a deletion. A carried-back fragment is
matched on whole released lines. Under changelog_fragments Version Gate
accepts a stamped head only as a [pin, base] merge-step commit with valid
fragments.

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

* feat(land): refuse a pin without a READY receipt; symlinked release files refuse before restamp

Under changelog_fragments, gstack-ship-queue ready records a READY receipt
(refs/notes/gstack-trains) once its pregate, full_e2e and /ship receipt
checks pass, and land refuses a pin without one (fix: run
gstack-ship-queue ready --pr N), --dry-run included (GStack Minder ruling,
2026-10-29). The merged tree's release files may not be symlinks, so
restamp never writes outside the scratch worktree. --repair adopts an
existing branch only when it holds land's repair commit.

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

* fix(pregate): clear's stamp-only substitution applies the changelog_fragments fold; docs match land and ready

gstack-pregate clear and gstack-tree-receipt now classify through one
classifyFiles, so under changelog_fragments a receipt for the fragment head
clears the stamped head when the stamp is exactly the fold. The ship-policy
reference names ready's receipt push, land's own check polling, the key-off
refusal and the /ship changelog_fragments line.

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

* docs(pregate, ship-policy): the fragment fold's two receipt rules, and clear applies them too

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

* ship: write the Steps 12-16 range with an ASCII hyphen so the skeleton fits maxSkeletonBytes

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>
2026-10-30 16:54:58 +00:00
Garry Tanandcapy-ai[bot] 9184ffd16c v1.91.328.0 ship-queue: screen only when the selector restores every case; unscreened PRs fill train seats (GSTA-165 1a) (#3619)
* Narrow screens leave hub files to the train gate; map size-ledger baselines and the careful mask awk

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

* fix: pre-landing review fixes (pull_request runs stay broad, deleted hubs, READY and summary previews)

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

* docs: CHANGELOG for narrow screens (Unreleased)

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

* docs: TESTING_INTERNALS describes narrow and broad PR screen policy

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

* chore: record test-pr-profile.ts as non-behavioral at HARNESS_VERSION 6

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

* ship-queue: screen only when the selector restores every case; unscreened PRs fill train seats (GSTA-165 1a)

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

* test: pin the diffs that still screen (unselectable, skill template + bun.lock)

Two assertions in test/ship-queue-train-logic.test.ts: a diff the paid
selector cannot select recommends --screen with the full gate selection,
and a diff that mixes a skill template with bun.lock recommends --screen.
GSTA-165 1a, from /ship Steps 7-8.

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

* docs: CHANGELOG tests and deferrals; P1 TODOs for GSTA-165 follow-ups

CHANGELOG [Unreleased]: name the two added tests and list the deferred
CREW.md rule 22 text and train-record attribution field. TODOS.md: both
deferrals as P1 under Ship.

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>
2026-10-30 03:14:00 +00:00
Garry Tanandcapy-ai[bot] 0732890091 v1.91.323.0 ship: proportional (scoped) second review pass after a blocking fix (GSTA-152 PR B) (#3596)
* ship: token cap with real meters and fresh-context delegation (GSTA-152 PR A)

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

* ship: scoped second review pass after a blocking fix (GSTA-152 PR B)

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

* fix: pre-landing review fixes (stopped or lost capped run no longer blocks uncapped review starts; short child return reconciles incomplete)

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

* fix: carry estimate spend across a meter epoch change; calibration docs match their evidence

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

* test: load the committed calibration file by its repo path so pregate maps it to a lane

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

* ship: fix fence placeholders and register claude-usage fixture (GSTA-152 PR A)

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

* test: run ship-budget and review-log bins through their interpreters so Windows can launch them

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

* fix: plan the full pass 2 when the fix range touches a gate path or is empty (GSTA-152 PR B review)

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

* fix: classify the fix range and the diff at the range base with their own scope and gate scan (GSTA-152 PR B pass 2)

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

* fix: a full pass 1 always gets a full pass 2; drop the at-base reconstruction (GSTA-152 PR B pass 3)

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>
2026-10-29 19:53:29 +00:00
Garry Tanandcapy-ai[bot] a8d60be09f v1.91.322.0 feat: narrow PR screens leave hub files to the train gate (#3587)
* Narrow screens leave hub files to the train gate; map size-ledger baselines and the careful mask awk

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

* fix: pre-landing review fixes (pull_request runs stay broad, deleted hubs, READY and summary previews)

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

* docs: CHANGELOG for narrow screens (Unreleased)

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

* docs: TESTING_INTERNALS describes narrow and broad PR screen policy

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

* chore: record test-pr-profile.ts as non-behavioral at HARNESS_VERSION 6

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>
2026-10-29 19:38:32 +00:00
Garry Tanandcapy-ai[bot] f59b3435d5 v1.91.315.0 ship-receipt: carry a stacked child after its parent lands (#3572)
* feat(ship-receipt): carry across regenerated outputs and onto a reviewed tree after a rebase

A base merge whose only product-side change is a registered output the
pregate regen check proved fresh now carries the receipt. A rebased head
carries when its tree is one the receipt covers and its product patch-id
against the current base matches (RECEIPT_CARRY_TREE_MISMATCH otherwise).
Docs: merge main into a reviewed branch, never rebase it.

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

* fix: regenerate doctor anchors; type the head_tree assert

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

* feat(review): proportional /ship review depth (light, standard, full)

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

* fix: carry sets aside only outputs the regen check proved it recreates

The regen check deletes each touched output in its scratch worktree before
the command runs and records the ones recreated byte-identically as proven.
gstack-ship-receipt carry exempts only those paths, and only when the check
ran origin/<base>'s registry at the commit the carry reads. A file under an
output glob that the generator never writes stays product (pre-landing
review, #3564 pass 1).

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

* feat(ship-receipt): record review depth, check it in the queue, structured review-loop exception (#3559)

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

* fix: prove generated outputs in a second regen run; literal names only

The regen verdict comes from the unmodified run again, so a generator that
reads its own registered output (gen-skill-docs and
qa/templates/functional-report-template.md) passes as before; the proof is a
second run with the touched outputs deleted, and its failure only means not
proven. The carry ignores a proven path with glob syntax, since it uses the
paths as pathspec globs (pre-landing review, #3564 pass 2).

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

* docs: receipt evidence keys and carry record fields; carry refusal fix line

Documentation audit for #3564 (/document-release, audit ship3564-docs-1).

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

* fix: pre-landing review fixes (depth scan binding, queue scope, carry checks)

- carry refuses a --head other than the checked-out HEAD, a receipt with
  gstack_version but no review_depth, and an owner exception that no longer
  stands; a dirty or foreign checkout makes the write-time gate scan
  unavailable (full)
- the queue binds a gate scan only to the full bound commit and recomputes
  the scope signals with gstack-diff-scope <base> --head <sha>, the same
  range the writer uses
- the queue checks the review-loop exception's fix-check ancestry
- a package.json version line counts as stamp-only only when it is a bare
  version key
- docs and help name what review_depth is and which registry the queue reads

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

* docs: CHANGELOG for the review fixes; defer two plan items to TODOS

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

* feat(ship-receipt): carry a stacked child after its parent lands (#3570)

When the carry base differs from the receipt's (a stack parent landed and
the PR was retargeted), the receipt carries only when HEAD's product diff
against the base equals the range reviewed against the parent branch.

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

* docs: queue and carry refusal lists name the depth and exception codes

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

* fix: pre-landing review fixes

A retargeted carry compared the reviewed range with a patch-id whose pathspec
came from the reviewed head..HEAD range, so a parent's package.json change
that never reached the base dropped out and the receipt carried. Compare with
HEAD's whole product patch-id against the base (the one write records), rebind
the receipt's base on a retarget carry, and cover the parent-metadata, landed-
with-changes and test-only-child cases.

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

* test: approval-classes summary-line regexes allow the receipt's depth field

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

* docs: troubleshooting names the stacked-retarget carry refusals

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

* fix(ship-receipt): summary line prints depth before approval

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

* Revert "test: approval-classes summary-line regexes allow the receipt's depth field"

This reverts commit e9ec264358.

* test: assert a retarget carry rebinds review_depth to the new base and binds at the queue; docs: split the --head carry advice

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>
2026-10-29 10:12:18 +00:00
Garry Tanandcapy-ai[bot] 256874a109 v1.91.308.0 fix(restamp): keep a four-part package.json version in repos that declare it (#3557)
* fix(restamp): keep a four-part package.json version in repos that declare it

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

* docs(changelog): restamp keeps a declared four-part manifest

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

* fix: pre-landing review fixes (base manifest sets the form, flag validated first, stamp_paths test)

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>
2026-10-29 05:35:56 +00:00
Garry Tanandcapy-ai[bot] edf4c2e581 v1.91.307.0 ship: proportional review depth (light, standard, full) with depth-checked receipts (#3567)
* feat(ship-receipt): carry across regenerated outputs and onto a reviewed tree after a rebase

A base merge whose only product-side change is a registered output the
pregate regen check proved fresh now carries the receipt. A rebased head
carries when its tree is one the receipt covers and its product patch-id
against the current base matches (RECEIPT_CARRY_TREE_MISMATCH otherwise).
Docs: merge main into a reviewed branch, never rebase it.

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

* fix: regenerate doctor anchors; type the head_tree assert

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

* feat(review): proportional /ship review depth (light, standard, full)

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

* fix: carry sets aside only outputs the regen check proved it recreates

The regen check deletes each touched output in its scratch worktree before
the command runs and records the ones recreated byte-identically as proven.
gstack-ship-receipt carry exempts only those paths, and only when the check
ran origin/<base>'s registry at the commit the carry reads. A file under an
output glob that the generator never writes stays product (pre-landing
review, #3564 pass 1).

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

* feat(ship-receipt): record review depth, check it in the queue, structured review-loop exception (#3559)

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

* fix: prove generated outputs in a second regen run; literal names only

The regen verdict comes from the unmodified run again, so a generator that
reads its own registered output (gen-skill-docs and
qa/templates/functional-report-template.md) passes as before; the proof is a
second run with the touched outputs deleted, and its failure only means not
proven. The carry ignores a proven path with glob syntax, since it uses the
paths as pathspec globs (pre-landing review, #3564 pass 2).

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

* docs: receipt evidence keys and carry record fields; carry refusal fix line

Documentation audit for #3564 (/document-release, audit ship3564-docs-1).

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

* fix: pre-landing review fixes (depth scan binding, queue scope, carry checks)

- carry refuses a --head other than the checked-out HEAD, a receipt with
  gstack_version but no review_depth, and an owner exception that no longer
  stands; a dirty or foreign checkout makes the write-time gate scan
  unavailable (full)
- the queue binds a gate scan only to the full bound commit and recomputes
  the scope signals with gstack-diff-scope <base> --head <sha>, the same
  range the writer uses
- the queue checks the review-loop exception's fix-check ancestry
- a package.json version line counts as stamp-only only when it is a bare
  version key
- docs and help name what review_depth is and which registry the queue reads

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

* docs: CHANGELOG for the review fixes; defer two plan items to TODOS

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

* docs: queue and carry refusal lists name the depth and exception codes

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

* test: approval-classes summary-line regexes allow the receipt's depth field

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

* fix(ship-receipt): summary line prints depth before approval

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

* Revert "test: approval-classes summary-line regexes allow the receipt's depth field"

This reverts commit e9ec264358.

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-29 04:55:01 +00:00
Garry Tanandcapy-ai[bot] de4c694d91 v1.91.306.0 ship-receipt: carry across regenerated outputs and onto a reviewed tree after a rebase (#3564)
* feat(ship-receipt): carry across regenerated outputs and onto a reviewed tree after a rebase

A base merge whose only product-side change is a registered output the
pregate regen check proved fresh now carries the receipt. A rebased head
carries when its tree is one the receipt covers and its product patch-id
against the current base matches (RECEIPT_CARRY_TREE_MISMATCH otherwise).
Docs: merge main into a reviewed branch, never rebase it.

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

* fix: regenerate doctor anchors; type the head_tree assert

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

* fix: carry sets aside only outputs the regen check proved it recreates

The regen check deletes each touched output in its scratch worktree before
the command runs and records the ones recreated byte-identically as proven.
gstack-ship-receipt carry exempts only those paths, and only when the check
ran origin/<base>'s registry at the commit the carry reads. A file under an
output glob that the generator never writes stays product (pre-landing
review, #3564 pass 1).

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

* fix: prove generated outputs in a second regen run; literal names only

The regen verdict comes from the unmodified run again, so a generator that
reads its own registered output (gen-skill-docs and
qa/templates/functional-report-template.md) passes as before; the proof is a
second run with the touched outputs deleted, and its failure only means not
proven. The carry ignores a proven path with glob syntax, since it uses the
paths as pathspec globs (pre-landing review, #3564 pass 2).

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

* docs: receipt evidence keys and carry record fields; carry refusal fix line

Documentation audit for #3564 (/document-release, audit ship3564-docs-1).

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>
2026-10-29 04:37:43 +00:00
Garry Tanandcapy-ai[bot] 148d28ea81 feat(ship): /ship and /autoplan size their review to the diff (GSTA-131) (#3527)
* wip(GSTA-131): review depth, fix-check transitions, dispatch counters, carry pregate, autoplan round policy

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

* wip(GSTA-131): reviewers stay at full effort; audits light

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

* feat(ship): Step 9 dispatches what gstack-review-plan plans; fix-check after below-floor fixes; cap two full passes plus one fix-check

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

* test: review-dispatch-compare has a free lane; review-depth fixtures registered free; resumed max_rounds case off the old default

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

* fix(GSTA-131): ship review pass-1 repairs: fix-check binds under its own skill, Step 11.5 accepts a fix-check or a planned adversarial skip, delta carry with a pregate, carry --pregate pinned to the checkout, quiet-after-cap revise regates, skill-dir markdown and rule docs classed code, gate signals from tests class up, plan fails closed on git errors, per-class compare ratios

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

* fix(GSTA-131): ship review pass-2 repairs: Step 11 follows the last full-pass plan, Important Rules restored, ship goldens regenerated, true per-class medians, review-policy transitions and once-per-invocation voices, docs/** assets stay docs-class, CLI and fix-check binding tests

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

* docs(changelog): GSTA-131 review depth, fix-check, delta /ship and autoplan rounds

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

* docs: ship-policy cap and counters, review-policy /review cycle cap, unattended passes (docs audit)

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

* fix(review): 400-word findings cap fits the /review size pins (five host pins lowered by 2); CHANGELOG max_rounds wording

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

* docs(changelog): gate integrity names the size-ledger entry and the lowered /review pins

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

* test: the round-budget case asserts the default through ROUNDS output only (pregate literals heuristic)

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

* test: curate ship-receipt-carry-pregate out of the Windows lane like its --pregate siblings

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

* docs(changelog): end the Windows curation sentence instead of a mid-sentence colon

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

* fix(ship): one decision each for the review-loop exits, the planned adversarial skip and Step 16's TODOS rerun (screen judge repair)

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

* fix(ship): fix-check repairs: pin the renamed Step 11 heading, keep the below-floor exit at the cap, name the plan run a repeat reuses, print the native skip on outside-only plans

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>
2026-10-28 05:45:54 +00:00
Garry Tanandcapy-ai[bot] 398618259d v1.91.286.0 feat(ship-queue): the ship size cap composes across a merge train; verify refuses a stale all-merged train (#3519) (#3522)
* feat(ship-queue): the ship size cap composes across a merge train; verify refuses a stale all-merged train (#3519 b, c)

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

* fix: pre-landing review fixes (runnable clear-time NEXT, stale exit only on a fetched main, open-slot freeze control, LF size-ledger fixture)

- verify's clear-time NEXT names gh pr view <n> --json state,headRefOid per unreadable slot instead of a pasteable #n@sha that views the current branch's PR
- QUEUE_TRAIN_STALE needs a fetched main (never under --no-fetch) and reports a freeze restored from the notes ref instead of saying the queue is not frozen
- freezeQueue docstring matches the unreadable field
- new test: a train with a slot still OPEN freezes even when another train verified main's sha
- test/size-ledger.test.ts fixture repo sets core.autocrlf false (Windows Free Tests shard 4 counted CRLF bytes)

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

* docs: CHANGELOG [Unreleased] entry for the ship size ledger and QUEUE_TRAIN_STALE

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

* test: run scripts/size-ledger.ts (check on this tree, refusals write nothing)

The remote pregate refused 82f160c with PREGATE_NO_LANE: no test named scripts/size-ledger.ts. The new case runs the CLI itself.

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

* test: spawn scripts/size-ledger.ts with bunIsolationArgs() so native Windows Bun starts it

The CLI test passed --config=/dev/null, which native Bun on Windows cannot open
(#3415); Windows Free Tests shard 6 failed at 4143373 with exit 1 and empty stdout.

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

* FILES: CHANGELOG.md VERSION agents-digest/gstack-AGENTS.md package.json
MERGE_CONDITION: sha=1b7c8b3af32a093924205f4894cba6c5d224630a
next: NEW_VERSION=1.91.286.0; commit and push only the stamp diff above (FILES), with no edit of your own: the train's verify accepts the CHANGELOG only as the base's plus this PR's entry re-headed; merge with the expected head 1b7c8b3af3 and recompute on a stale queue.
GSTACK_RESULT: skill=restamp status=complete run=/workspace/gstack/.gstack/tmp/restamp-journal.json

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>
2026-10-28 00:27:22 +00:00
Garry Tanandcapy-ai[bot] 9ccb5233f3 v1.91.282.0 fix(ship-queue): one CHANGELOG rule before and after the merge, base keys stay in slot stamps, a stacked child carries past its released parent (#3518)
* Ship-queue train tooling: one CHANGELOG rule, base keys stay, stacked-child carry (GSTA-129)

Four train-24 (GSTA-96) defects in one change.

verify --train applies the same CHANGELOG rule before and after the merge:
main's CHANGELOG plus the PR's own lines (its authored diff plus what
mergeChangelogs writes for it). A head the pre-merge verify accepted no longer
freezes the queue after its squash merge, and a freeze record lists a slot
GitHub reports MERGED as merged.

restamp's stamp_paths stage leaves a *_KEY_VERSION line the base introduced
after the fork point alone, base merge committed or staged, and says so.

mergeChangelogs with a base carries a stacked child's edits to its released
parent entry as "Correction to the <version> entry below" bullets under the
child's own Gate integrity section instead of returning null; the slot
one-liner prints each carried correction. #3453's two 1.91.276.0 corrections
are restored that way here.

The digest-freshness defect is already closed by #3451 (regeneratedAtBase);
docs/ship-policy.md now says how an unstamped generator change ships.

Docs: ship-policy § Run a merge train, captain.md § Merge trains and the
slot-call template carry the stamp-files and stacked-child rules.

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

* Review fixes: carried union from slot 2, GitHub-merged slot-1 freeze, no-own-entry refusal, fail-closed base diff (GSTA-129)

Pre-landing review pass 1 (six specialists and the Red Team, all INFORMATIONAL):
- mergeStep unions the carried child from slot 2 on, so a stacked child behind
  another slot never repeats its released parent's text under a second
  [Unreleased] (Red Team, lib/ship-queue-train.ts).
- stopped() freezes the queue when any slot is MERGED on GitHub, so a slot-1
  squash that fails the post-merge check no longer answers "nothing merged"
  (Red Team, lib/ship-queue-train-verify.ts).
- ownEntryAboveMain refuses a CHANGELOG equal to main's: no entry of the PR's own
  (state-machines, lib/changelog-check.ts).
- branchAddedLines refuses when the base diff cannot run instead of reading it as
  "nothing added" (Red Team, lib/restamp.ts).
- slot-call.md and docs/captain.md name the stamp files as the ones the slot
  call names, STAMP_FILES plus a *_KEY_VERSION file the PR introduced, matching
  docs/ship-policy.md (maintainability).

Also: the coverage tests Step 7 added (post-merge parent check, carry shapes),
and two dependency-map rows (test/helpers/free-fixtures-data.ts for the
merge-train-3453 fixtures, scripts/test-pr-profile.ts for captain/templates/**)
so the paid-gate selector and the FREE_FIXTURES inventory accept the new files.

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

* Review pass 2: an unreadable GitHub state at a failed slot refuses, never "nothing merged" (GSTA-129)

stopped() read prState's 'unreadable' as "not merged": with nothing in
t.merged, a slot-1 squash already on main while gh pr view failed answered
"nothing of the train merged, so the queue is not frozen". It now refuses with
QUEUE_PROOF_MISSING ("whether #<n> merged on GitHub could not be read, so
whether the queue must freeze is unknown") and asks for the verify to be rerun;
no freeze, no backstop. Raised independently by five pass-2 reviewers.

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

* Docs audit: troubleshooting codes and ship-policy sections match the shipped train rules (GSTA-129)

The /document-release audit (edit mode) corrected two docs the PR had not
reached: docs/troubleshooting.md's QUEUE_TRAIN_TREE_MISMATCH, QUEUE_PROOF_MISSING,
QUEUE_TRAIN_FROZEN and POLICY_SOURCE_UNAVAILABLE entries, and docs/ship-policy.md's
train build conflict rule (the carried stacked child is the exception), the
verify freeze paragraph (slot-1 GitHub-MERGED freeze, unreadable-state refusal)
and the restamp stamp_paths stage (base-added lines stay; an unrunnable base diff
refuses). Five mid-sentence colons in the PR's own paragraphs are rewritten for
the prose lint, and the CHANGELOG Docs bullet names docs/troubleshooting.md.

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

* HARNESS_VERSION: scripts/test-pr-profile.ts row recorded non-behavioral at version 6 (GSTA-129)

The remote free tier's only red was the HARNESS_VERSION guard: scripts/test-pr-profile.ts is a pinned shared-harness file and gained the captain/templates/** FREE_ONLY_PR_FILES row. Recorded with bump-harness-version.ts --non-behavioral: no paid case reads the crew templates, so no selection, input or verdict changes and no pass-rate series resets.

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

* test: type the saved fixture PR row for the test-code ratchet (GSTA-129)

CI's typecheck:test ratchet refused one new TS2698 (spread of a loosely typed fixture row) in the slot-1 freeze test; the row is read as any, as the neighbouring state writes already do.

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

* ship-queue verify: build the freeze record from the one GitHub read that decided to freeze

freezeQueue took a second prState read per unverified slot and filed anything
but an exact MERGED under unmerged, so a slot that read MERGED at stopped()
and was unreadable a moment later was recorded as unmerged (the record half of
train 24's #3453 misfile). stopped() now reads each unverified slot once and
passes those states in; a MERGED slot stays merged, and a slot unreadable
beside a merged one is kept out of unmerged and named in the reason. The
fixture's gh shim gains a per-PR vanish count so a test can change GitHub's
answer between two reads.

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

* ship-queue verify: say what happens to a slot unreadable beside a merged one

The freeze reason, docs and CHANGELOG said the slot was kept out of unmerged
'until read', but nothing reads it again: the NEXT after the repair is built
from unmerged alone. Say so (the operator seats it in a train by hand once gh
answers) and pin the record shape with a test.

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

* v1.91.282.0 stamp

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>
2026-10-27 21:21:50 +00:00
Garry Tanandcapy-ai[bot] 1f246e3505 v1.91.278.0 fix(ship-queue): readiness takes dispatched Free Tests, stamp paths accept tentative key versions, ready and train build read the base overlap, pr-wait --exclude, restamp prints the corrected order (#3514)
* fix(ship-queue): readiness takes dispatched Free Tests, prose check reads key=value pairs, stamp paths accept tentative key versions, ready and train build read the base overlap, pr-wait --exclude, restamp prints the corrected order

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

* fix: pre-landing review fixes

Pass 1 of /ship's review on #3514: the prose check skips a key: value pair's value
whatever the whitespace, the restamp recompute keeps a merged-not-in-base
predecessor and says to fetch, stampOnlyLine applies the version-width bound,
pr-wait --exclude excludes nothing while the required checks are unreadable,
baseOverlap reports a failed git read as unknown and gives no verdict at train
build, readiness lets a pull_request run outrank a dispatched one, and the READY
conflict refusal follows the crew template's rule 14 instead of a crew-local rule.

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

* docs: stamp rule for tentative key versions, key=value prose claims, QUEUE_STALE merged-not-in-base fix

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>
2026-10-27 15:11:13 +00:00
Garry Tanandcapy-ai[bot] f8d0ab0339 v1.91.275.0 fix(ship-policy): DOCS_CAPS_KEY_VERSION is 1.91.270.0; key versions move through stamp_paths at the slot stamp (#3511)
* fix(ship-policy): DOCS_CAPS_KEY_VERSION is 1.91.270.0; key versions move through stamp_paths at the slot stamp

#3487 was written naming 1.91.258.0 for docs.caps and main stamped that
number for another PR first; the slot call cannot edit anything beyond the
four stamp files, so the constant shipped stale. lib/ship-policy.ts now sits
in .gstack/ship-policy.json stamp_paths with the _KEY_VERSION = '{version}'
template, so a new key written as a tentative future version is moved by
gstack-restamp's stamp_paths stage at the slot (read from the base policy,
so live from the next PR on). test/gstack-ship-policy.test.ts gains the
check the incident lacked: a released key's version must be a heading whose
entry names the key. Dry-run proof: a tentative 1.91.272.0 on a branch line
moved to the allocated 1.91.271.0 with --policy-from head.

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

* docs(ship-policy): tentative key versions are clear of main's pace; the receipt accepts the move only at the base version until #3512

Pass-1 review notes: the next patch above the fork point is the number main
takes first, so the convention names the next minor; and the tree receipt's
stamp-only check (lib/tree-receipt.ts stampOnlyHunks, with stampOnlyText and
stampFreeTree) rewrites only base VERSION -> new VERSION, so a tentative move
passes the train only when the tentative value equals the base version at the
slot. Filed as #3512 (outside this diff, deferred under the frozen scope).

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

* test(ship-policy): read origin/main's CHANGELOG with a 64 MiB maxBuffer; say plainly that a new-key PR cannot clear the train until #3512

Pass-2 Red Team: CHANGELOG.md is past spawnSync's default 1 MiB maxBuffer,
so both CHANGELOG-reading tests dropped origin/main's file silently and the
incident shape passed at the pin. With the buffer the released-key test sees
main's headings on a full clone. The comment and CHANGELOG now state the
practical consequence of the receipt limit.

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

* docs(ship-policy): gstack's own policy excerpt names lib/ship-policy.ts under stamp_paths

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>
2026-10-27 11:18:53 +00:00
Garry Tanandcapy-ai[bot] f27a7605d4 v1.91.270.0 feat(ship): version-less repos, docs-audit record and caps, the frozen-scope paid case, and the review-loop follow-ups (#3487)
* feat(ship): version-less repos, docs-audit record and caps, the frozen-scope paid case, and the review-loop follow-ups

Follow-up to the review-loop convergence PR: Step 12 and the CHANGELOG step skip cleanly in a repository with no version source (receipt version "none"); the receipt records the docs audit outcome and the owner exception (DOCS_AUDIT_BLOCKED without one) and a policy may declare doc caps (gstack-ship-receipt docs-caps); docs/unattended.md names the READY evidence and the cross-family outside voice; the ship-frozen-scope-convergence behaviour case runs the generated Step 9.4 under review_scope frozen through the real binaries; carry probes git >= 2.39 (RECEIPT_GIT_TOO_OLD); defer passes the repository to gh repo view positionally and names its search limit; late defers count without being passes; reviewers diff from RANGE_BASE on pass 2+; the cap check runs before edits; --review-fanout batches specialists by free slots; read --check-prose compares quoted counters with the receipt (RECEIPT_PROSE_MISMATCH); checklist rule ids prereg-with-results and test-keyboard-count-loop; gstack-coauthor-trailers.

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

* test: repair the CI reds the retarget onto main surfaced (test-only)

Seven test files, no product change. The pull_request run at 2d73fadd
failed 5 Linux shards and 4 Windows shards:

- test/ship-frozen-scope-actor.test.ts imported only test code, so the
  test-of-test ratchet refused it; the first case now recomputes the loop
  summary with summarizeReviewLoop/reviewLoopLine from lib/review-scope and
  asserts the exact REVIEW_LOOP line. Its three cases replay the bash
  workflow through bash -c and the shebang bins, so they are POSIX-only.
- test/codex-host.test.ts: the new gate case is Claude-specific (33 -> 34).
- test/paid-retry-supervision.test.ts: the gate census fixture now carries a
  trial record for the one planned behavior-kind gate case, the way
  test/ci-paid-coordination.test.ts already does.
- test/review-fix-range.test.ts asserted the pre-#3487 DIFF_BASE sentence;
  it now asserts the ${RANGE_BASE:-merge-base} clause that carries the same
  contract (every reviewer reads the range from pass 2 on).
- test/gstack-coauthor-trailers.test.ts: the fixture sets its own git
  identity; a CI runner has none to auto-detect ("Committer identity
  unknown").
- test/review-scope-followups.test.ts and test/gstack-ship-receipt-docs.test.ts:
  the gh and old-git stand-ins are sh scripts on a colon-joined PATH, which
  CreateProcess cannot run, so those three cases skip on win32.

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

* fix: pre-landing review fixes (pass 1)

Twelve informational findings from the /ship pass-1 review, all below the
blocking floor, fixed in place:

- docs-caps reads docs.caps from origin/<base>'s policy (--base <ref>), never
  the branch's copy; an unavailable base policy refuses with
  POLICY_SOURCE_UNAVAILABLE instead of substituting DEFAULT_POLICY
- receiptVersion returns "none" only when the stamp file is absent; other
  errors surface as undefined
- checkReceiptProse groups counters by leaf key and uses word boundaries that
  cover hyphenated names, so shared leaf keys and hyphenated words no longer
  report RECEIPT_PROSE_MISMATCH
- gstack-coauthor-trailers refuses a --range/--base starting with "-",
  prefixes origin/ when origin/<ref> resolves (slash-named branches), and
  passes --end-of-options to git log
- REVIEW_SCOPE_KEY_VERSION and DOCS_CAPS_KEY_VERSION name the releases that
  first read their keys
- the Step 11 late-defer row logs under skill review-late-defer so a tokenless
  review row never reads UNVERIFIED; summarizeReviewLoop counts both
- the "already filed" literal is one constant shared by bin and renderer
- receiptDocs (dead) removed
- Step 14.5 clears .gstack/tmp/docs-audit.json on first entry
- dispatched review prompts carry a literal diff-base sha (<diff-base>) instead
  of a shell variable the reviewer process never sees
- the coauthor-trailers tests launch the bin through runScriptSync so the
  Windows lane can run them

Tests extended for each change; SKILL.md, sections and goldens regenerated.

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

* test: cover the carry patch-id refusal (Step 7 coverage gap)

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

* test: derive the too-old review_scope minimum from the constant

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

* fix: keep co-author trailers in one trailer block

gstack-coauthor-trailers --message appended the new Co-authored-by lines as a
separate paragraph after existing trailers, so git interpret-trailers (and
GitHub attribution) read only the last paragraph and the existing co-author
lost credit. The new lines now join the existing trailer block; the test
checks the result with git interpret-trailers --parse.

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

* fix: let git place co-author trailers; name the docs key release

gstack-coauthor-trailers --message now runs git interpret-trailers --in-place,
so the appended lines join the existing trailer block whatever its shape
(CRLF, comment lines, folded continuations) and the existing co-author keeps
attribution; the interpret-trailers check in the test carries a timeout for
the spawnSync tripwire. DOCS_CAPS_KEY_VERSION names the release after the
newest CHANGELOG heading on main (1.91.258.0), and a test ties every
unreleased policy key to that next release so a stamp elsewhere fails loudly.

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

* fix: hold unreleased policy keys newer than any visible heading; pin trailer placement

The CHANGELOG-heading test asked for the exact next release after the newest
heading, which a depth-1 CI clone (no origin/main) computes from the branch
alone, so it went red there. It now requires an unreleased key's version to be
newer than every heading the checkout can see, which holds at depth 1, on the
stamped train tree and on main; the ship-policy comment says who moves the
constant when the stamp lands under another number.

gstack-coauthor-trailers pins git interpret-trailers' placement on the command
line (--no-divider so a --- body line is not a divider, --where end,
--if-exists addIfDifferentNeighbor, trailer.separators=:, -- before the path)
so a user's trailer.* config cannot replace or drop the existing co-author.

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

* docs: describe the shipped contracts (Step 13 and 14.5)

CHANGELOG [Unreleased]: docs-caps --base <base> reading origin/<base>'s
policy, the review-late-defer row, the literal <diff-base> prompt rule, the
coauthor-trailers placement and refusals, the policy key versions (review_scope
1.91.256.0 re-pin, docs.caps at the stamping release), the version-less
conditions split between Step 12 and the receipt, and the carry refusal wording.
docs/ship-policy.md, docs/review-policy.md and docs/unattended.md follow the
code: docs-caps --base, the literal diff-base sha, the trailer block, the
gstack-outside-voice run binding and the Step 11 row fields.

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

* docs: scope the literal diff-base claim to the review-army prompts; name where the outside-voice cause lives

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

* fix(docsync): declare Step 14.5's own-tree commands to the fixture; exclude .gstack/tmp at the Entry

The ship-docsync-completion and ship-docsync-current paid cases failed twice at
775d9804: Step 14.5's continue path now runs gstack-ship-receipt docs-caps and
writes .gstack/tmp/docs-audit.json, and the docsync fixture's closed interface
declared neither, while its repository had no origin/main for docs-caps to read.
The actor stopped correctly (blocked, no exception) and never reached the
publication stand-in.

- test/helpers/docsync-interface.ts: the three housekeeping commands (the shared
  exclude line, rm -f of the record, docs-caps --base main) and the record write
  are declared, byte for byte with the generated section; DOCS_AUDIT_RECORD_PATHS
  names what the kernel observer may see.
- test/helpers/docsync-observer.ts: accepts exactly those commands and the record
  write; every neighbour (another base, --json, write --docs, another .gstack file)
  stays outside the interface.
- test/helpers/docsync-fixture.ts: every scenario pushes main to the fixture
  remote, as Steps 0-14 would have.
- ship/sections/documentation.md.tmpl: the Entry runs the shared .gstack/tmp
  exclude line before rm -f, so the record never surfaces as an untracked file
  when no earlier step added it; the caps paragraph tightened to hold the ship
  parity ratio at 1.7400.
- test/docsync-command-grammar.test.ts: pins the literals against the generated
  section and the refusals around them.

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

* fix(docsync): the receipt record is housekeeping for read-only audits and the fault cases too

Pass 9's outside voice found two gaps in the fixture change (2524ec4): a
read-only audit (ship-docsync-current) must still write .gstack/tmp/docs-audit.json,
but docsToolFailures flagged every product write under readOnly before the
record allowance; and the unseeded fault cases (missing-asset, legacy-completion)
run the Entry too, so their kernel-write check saw .git/info/exclude as a
forbidden write because only the lifecycle test named the housekeeping paths.

- docsToolFailures: the record write is permitted under readOnly; the document
  and every other product file stay refused.
- docsWriteFailures: DOCS_AUDIT_RECORD_PATHS are permitted for every caller, so
  the fault evaluator needs no per-scenario list; anything else under .git or
  .gstack stays forbidden.
- test/docsync-command-grammar.test.ts pins both: the record under readOnly, the
  document refused there, the observed housekeeping paths accepted with an empty
  allowance and two neighbours refused.

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

* test(docsync): accept the cap gate's ~/.claude/skills/gstack form the section prints (pass 9 Red Team note)

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

* test(docsync): name the admitted composed line precisely (pass 9 maintainability note)

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

* fix(docsync): install lib/ beside bin/ in the fixture so the declared cap gate can load (2524ec4 rerun: module error, not a verdict)

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

* fix(docsync): admit the Write tool's temp sibling of the receipt record (0230fc2 rerun: both lifecycle cases red on it)

The paid rerun at 0230fc2 cleared every earlier refusal and both cases then
failed on one path: forbidden docs write: .gstack/tmp/docs-audit.json.tmp.<pid>.<12 hex>.
Claude Code's Write and Edit tools land every file, new ones included, through
that sibling plus fsync and rename, and the fixture's kernel observer proved
such a landing for the document only (atomicTargets: [DOC_PATH]).

The observer now treats the record's sibling as a transient file too, and
docsWriteFailures admits it only as the cookie-paired MOVED_FROM source of a
MOVED_TO on the record whose other events are create/modify/attrib/close_write
and which is left in neither snapshot nor in changed. A lingering sibling, an
unpaired move, a move onto another path or a sibling of the document moved onto
the record stay forbidden (grammar test). A live check on this machine saw the
second landing's create/modify/close_write/moved_from events admitted and a
stray sibling refused.

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>
2026-10-27 08:16:11 +00:00
Garry Tanandcapy-ai[bot] f375b873de v1.91.263.0 feat(ship-queue): screens read from the run, train watch/forget/prune --stale, verify --post-merge, ready --dispatch-ci, --stack-tests (#3484)
* feat(ship-queue): screens read from the run, train watch/forget/prune --stale, verify --post-merge, ready --dispatch-ci, --stack-tests

Operating merge trains on 2026-10-26 showed the gaps this closes. A dispatched
screen's verdict is read from the run's gate-binding and report-verdict artifacts
(lib/ship-queue-screen.ts) and recorded in the READY receipt: a RED screen refuses
ready under either choice and is never re-dispatched at the same merge SHA
(QUEUE_SCREEN_RED); a run that concluded success with no slice is NOT-RUN
(QUEUE_SCREEN_NOT_RUN), never followed, and counted as unscreened by train build.
When refs/pull/<n>/merge lags or is missing the screen is planned on a scratch merge
pushed as screen/<pr>-<head12> (#3465); QUEUE_SCREEN_STALE_REF means a real
conflict only. train watch --train is the resumable follow command; train prune
--stale settles a merging/green train whose PRs all merged or closed elsewhere;
train forget removes one record with an exact lease on refs/notes/gstack-trains;
verify --post-merge <sha> watches main's push workflows until they settle;
ready --dispatch-ci <wf,…> dispatches the free workflows on a conflicting PR,
waits, and clears the matching requires-remote pregate lanes with the run URLs;
train build --dry-run --stack-tests runs each PR's new test files on its integrated
prefix before anything is dispatched (QUEUE_TRAIN_STACK_RED).

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

* Regenerate gstack-doctor-components.sh for the four new QUEUE_* result codes

The committed Bash render was four case lines behind its generator, so
test/doctor-components.test.ts failed at c75ec3a. Output of
bun run gen:skill-docs; no hand edits.

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

* Restore the exact stderr line count in the POLICY_SOURCE_UNAVAILABLE test

RH-15: toBeGreaterThan(0) after a toMatch is vacuous; the refusal is one
deterministic line, so toBe(1) holds and is restored.

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

* docs(ship-policy): a lagging merge ref is a scratch merge, not QUEUE_SCREEN_STALE_REF

Three passages still described the pre-scratch-merge refusal; they now
match screenMerge: a missing or lagging refs/pull/<n>/merge gets a
screen/<pr>-<head12> scratch merge, and QUEUE_SCREEN_STALE_REF is a real
conflict with the base only.

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

* stack-tests: drop the dead detail clause and assert the worktree is gone

r.detail === 'pass' can never hold when r.ok is false; the dry-run test
now checks git worktree list instead of a state-dir name that was never
written.

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

* ready --dispatch-ci: fail closed on fork or unreadable PRs, surface gh errors, keep screen: after READY

dispatchCi now uses prInfo (a fork head or an unreadable PR is refused
instead of dispatched), reads gh's error text when the workflow run call
fails, and calls runsAt once. The screen: line is inserted after the
READY line instead of at index 1, which with --dispatch-ci put it before
READY and after the first CI_DISPATCH line.

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

* verify --post-merge: honour commit statuses in the settled and red verdicts

settled and red were computed from check runs only while ci.green also
counted commit statuses, so a pending status was called settled and a
failed status was reported as 'red: ' with no name. Pending statuses now
keep the verdict pending; a red status with no failed check run is named
as such. The fixture gains a statuses knob to drive both.

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

* train watch: reject a malformed --free-timeout as usage instead of taking the default

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

* train forget: restore the local notes ref on a rejected lease and refuse every in-flight state

forgetNotes removed the note locally before the leased push, so a
rejected lease left a local notes ref without the note that the next
plain persist pushed without a lease. It now snapshots the ref and
restores it on rejection, reporting failed removals separately. forget
refused only merging/gate-pending/free-pending; built, pushed,
free-green, dispatch-unknown and dispatch-absent are in flight too and
are refused the same way. CHANGELOG and ship-policy say so.

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

* train build --dry-run: never persist or push the read screen verdict

admitSlots recorded a verdict that differed from the receipt and pushed
refs/notes/gstack-trains before the dryRun branch printed 'nothing
written, pushed or dispatched'. It now takes dryRun and skips the
persist, matching trainReady's guard.

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

* stack-tests: only bun test files count as new tests, passed as paths

TEST_FILE matched every .ts under test/, so a PR whose only added file
was a helper or fixture ran 'bun test test/helpers/x.ts', which exits 1
(the filter matches no test file) and was reported QUEUE_TRAIN_STACK_RED.
A bare positional is also a substring filter that picks up unrelated
files. The rule is now bun's own (.test, _test_, .spec, _spec_ in the
name) and each file is passed as ./<path>, which bun treats as the exact
file. The fixture PR 3 now adds a helper and is still 'no new test
files'.

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

* screen: page the run's artifact list before picking the newest binding

One page of 100 artifacts can miss gate-binding/report-verdict on a
broad or rerun screen (three artifacts per slice plus reruns), which
read as 'bound no verdict' and bought a fresh screen. newestArtifact now
follows page= until a short page.

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

* stack-tests: match bun's _test and _spec suffixes too

Bun discovers a file whose name ends in .test, _test, .spec or _spec
before the extension. The previous rule missed the underscore forms
(b_test.ts, e_spec.ts), so a PR adding only such files got no stack
check, and it matched names bun ignores. PR 1 in the fixture now adds
test/pr-1_test.ts to prove the underscore form is run.

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

* docs: ship-policy and troubleshooting match the shipped train commands

Step 14.5 documentation audit: the stack-tests naming rule is bun's own
(.test, _test, .spec, _spec); prune --stale deletes every merged or
closed PR's screen/<pr>-* branch; verify --post-merge takes the full SHA
and counts commit statuses; train watch --free-timeout and
ready --dispatch-ci --timeout defaults; PENDING/UNKNOWN/INCOMPLETE screen
verdicts; QUEUE_SCREEN_STALE_REF's Meaning no longer contradicts its Fix;
one sentence each for the new QUEUE_NOT_READY, QUEUE_TRAIN_UNTRUSTED and
QUEUE_TRAIN_PENDING triggers.

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

* changelog: prune --stale scope, post-merge commit statuses, STALE_REF vs POLICY_SOURCE_UNAVAILABLE

Three details the documentation audit found wrong against the code; the
entry stays under [Unreleased] (stamp-at-merge).

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

* docs: RED screens are not seated; QUEUE_PROOF_MISSING and POLICY_SOURCE_UNAVAILABLE name the train-command causes

Step 14.5 re-audit: ship-policy.md says train build does not seat a RED
screen and its NEXT names the build without that PR; troubleshooting.md
lists train forget, train watch, verify --screen and the scratch-branch
push under QUEUE_PROOF_MISSING, and the origin/<base> fetch under
POLICY_SOURCE_UNAVAILABLE.

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

* test(host-conformance): delete the named scope.md in the C3 broken-link case

A test repair the remote gate requires, not a review finding. The case
deleted the first .md readdirSync listed under gstack-qa/sections, and
on the remote-gate VM's ext4 that was a file setup --status does not
count, so the case was deterministically red there (#3479) while green
locally and on Actions. The same one-line change ships in #3471
(fd468eb); this copy carries no CHANGELOG line so the two merge cleanly.

Refs #3479

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

* v1.91.263.0 stamp

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>
2026-10-27 02:48:59 +00:00
Garry Tanandcapy-ai[bot] 51a2b19b75 v1.91.261.0 fix(restamp): quoted since: rows and stale base-version mentions on branch-added lines when VERSION equals the base (gbrain #7640) (#3491)
* fix(restamp): quoted since: rows and stale base-version mentions on branch-added lines when VERSION equals the base (gbrain #7640)

A PR that stamped X, lost its slot and merged a base that had reached X on
its own had no branch stamp, and the mention scanner could not pass the
opening quote of a quoted row, so gstack-restamp --next left the PR's
{ since: 'X' } rows at X while the release shipped as X+1.

- tentativeMentions and rewriteStamps accept since: 'X' / since: "X" /
  (was 'X') / (was "X") and keep the quote style; the scanner also reads
  the policy's stamp_patterns templates.
- With no branch stamp and no --was, a stamp-form mention of the base
  version on a line the branch added moves; the same version on a base
  line stays. The stamp_paths stage detail names both counts per file.
- test/restamp-mentions.test.ts (pure forms + the reporter's state rebuilt
  with the real bin), stamp-templates pin updated, docs/ship-policy.md,
  --was help line, CHANGELOG [Unreleased].

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

* fix(restamp): review pass 1 — closing quotes, positional provenance, retry after a partial apply

- since: 'X' and (was 'X') require the quote to close right after X in the
  scanner and the rewrite table, so a quoted prerelease or a mismatched pair
  is never a stamp (the tree receipt shares the table).
- branchAddedLines records positions from the unified=0 hunk headers; the
  stamp_paths stage rewrites by position, so a base line with the same text
  stays and a CRLF checkout still finds the branch's row.
- Journal recovery restores the equal-base provenance (no branch stamp) so a
  stamp interrupted after VERSION was written retries as a stamp, not noop.
- Skipped detail names the explicit version it searched for; --was help line
  names the CHANGELOG re-heading; docs and CHANGELOG state the boundaries,
  the fork-point attribution and the rule's false-positive class.

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

* fix(restamp): review pass 2 — positions counted through joined-hunk context

parseUnifiedDiff records each added line's new-side position (addedAt),
counting context lines a hunk carries, and branchAddedLines pins
--inter-hunk-context=0, so a diff.interHunkContext setting that joins two
hunks around a base row no longer shifts the branch's second row onto the
base row. Test with interHunkContext=1 (red on the pass-1 tree).

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

* docs(restamp): correct the red-case count, the --was sentence and the help default

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>
2026-10-27 01:30:23 +00:00
Garry Tanandcapy-ai[bot] 576839cb8c v1.91.256.0 feat(ship): review loop converges (frozen scope, 3-pass cap, NO FINDINGS) and receipts carry across conflict-only merges (#3481)
* feat(ship): review loop converges (frozen finding scope, 3-pass cap, NO FINDINGS first-class) and receipts carry across conflict-only merges

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

* test(ship): keep the Step 9 first-entry and Fix-First phrasing the skip/requeue contract asserts; fill the review record's pass, review_scope and range_base placeholders in the caller template test; narrow a test type

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

* fix: pre-landing review fixes (pass 1) and the review-loop budget wording

Two blocking findings from /ship's own pass 1, both reproduced in the QA smoke before the fix:
gstack-ship-receipt carry hashed the product diff with git patch-id --stable, which strips
whitespace, so a space moved in a reviewed shell line carried as "no product change"; and it
classed package.json and every lockfile as release metadata, so a dependency swap carried too.
The patch-id is now --verbatim, package.json and VERSION are metadata only while the change is a
version stamp (lib/pregate/stamp-only.ts), lockfiles are product unless the policy names them,
the test globs name code extensions, a dirty working tree refuses before anything is compared,
and a receipt carried twice keeps the reviewed head as carry.from.

gstack-review-scope: an unresolvable base is POLICY_SOURCE_UNAVAILABLE instead of a silent
working-tree read; --range-base is validated; git runs with core.quotePath=false; range_base is
null on pass 1; a blocking finding with no path is fix; category "testing" is a test finding
below the floor; defer searches once, files nothing on a failed search and exits 0 unfiled;
summary refuses zero matching passes and the receipt write is chained to it with &&; a finding
the diff causes elsewhere names the changed line in `cause` and classify follows it.

Review-loop budget wording (ideas from tstack's sol-loop and pstack's interrogate, rewritten;
NOTICE.md): the blocker / should / nit glossary and two stop rules in Step 9.4, the checklist
and docs/review-policy.md; a lead-judgment stage in the finding merge both /review and /ship
render. The core read diffs $RANGE_BASE from pass 2 on. Caps and pins re-measured with reasons.

Step 7 coverage audit: four tests added in existing files, the --review-loop case moved to its
own test (the shared test tripped bun's 5 s default).

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

* fix: pin the renumbered review-army stages and point the wording test at product code

CI at c3e27fc failed three free-tier tests, all this branch's own: the
workflow-required-steps fixture and shared-libs-rendering still pinned the
pre-Lead-judgment stage numbers, and test-of-test-ratchet counted
review-loop-budget-wording.test.ts as test-only code because it read only
generated markdown. The fixture and rendering test now pin stages 1-8, and the
wording test renders both armies through generateReviewArmy and reads the
authored ship template as well as the generated sections.

Pass-2 maintainability notes folded in: docs/troubleshooting.md names the two
new RECEIPT_CARRY_REFUSED causes (dirty tree, unreadable status) and the two new
REVIEW_SCOPE_INPUT causes (non-hex --range-base, summary with no matching
pass); gstack-review-scope's help states that classify reads the base branch's
policy and refuses an unresolvable base unless --policy is passed.

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

* fix: date a review-log row from its binding start when it has no timestamp

The Step 9.4 template asks the writer to fill `timestamp`; the logger stamps
`review_binding.started_at` but never `timestamp`. `gstack-review-scope
summary` dropped such a row silently, so this PR's own pass 2 was missing from
REVIEW_LOOP (passes=1 for a two-pass loop). A row now dates from `timestamp`,
else from its binding start; a row with neither is still not counted.

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

* fix: pass-4 review fixes (carry stamp rule, deleted-file locus, scanned defer, diff prefixes, row time)

Five findings at the blocking floor from the Step 11 outside voice (gpt-6.1-sol)
and the native adversarial pass, fixed as a fourth pass approved by GStack
Minder under the three-pass policy:

- carry: a path the policy names under stamp_files, stamp_paths or
  release_outputs is metadata only while its change is a stamp (versionStampOnly
  for a manifest kind, stampOnlyText otherwise), the rule the tree receipt
  applies; a logic change in a stamped source file is product. Every
  metadata-listed path is read at both heads and a non-stamp change drops its
  globs from the product exclusion.
- review-scope: parseHunks keeps a deleted file as a whole changed location, so
  a cause anchored in a removed export is the diff's to fix, not deferred.
- defer: issues are filed through lib/gstack-post's publication scan; a HIGH
  finding in the title or body refuses and a MEDIUM one needs a human, both
  recorded as unfiled with the reason; --repo names the destination.
- classify: both diffs pin --src-prefix=a/ --dst-prefix=b/ --no-textconv, so
  diff.mnemonicPrefix cannot send every finding outside.
- summary: a row dates from review_binding.started_at before the writer-typed
  timestamp, so a date-only value cannot drop a real pass.

Docs: ship-policy.md#receipt-carry, review-policy.md, the Step 9.4 template
and the CHANGELOG gate-integrity note record the rule and the pass.

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

* test(review-army): assert the Red Team branch the run took in the N+1 case

Under the blocking floor the Performance specialist rates a 12-line N+1
INFORMATIONAL, so the conditional Red Team does not activate; the case
encoded the old severity (N+1 is CRITICAL, a Red Team always follows). It
now asserts the branch the run took: a Red Team that ran must follow the
Performance specialist; no Red Team is correct only when the report's own
count says 0 critical and its Red Team line names that reason. The N+1
detection assertion is unchanged. The free contract test gains the
informational-not-activated and informational-claimed controls and the
budget test's synthetic report carries the count line.

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

* v1.91.256.0 stamp

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>
2026-10-26 20:48:01 +00:00
Garry Tanandcapy-ai[bot] b004c06dbc v1.91.255.0 fix(ship-queue): fill trains at 3 READY PRs or one hour, and price every case shard's trial (#3478)
* fix(ship-queue): fill trains at 3 READY PRs or one hour, and price every case shard's trial

The 5-PR / 3-hour fill left READY PRs waiting most of a day; .gstack/ship-policy.json
now fills at max_size 3 or fill_hours 1, whichever comes first (fillDue already
dispatches at either bound). train verdict printed cost=$24.41 for a train whose slice
report said cost $32.92 known + 54 of 136 trial(s) cost unknown: E2E records named by a
display label ("/benchmark workflow") were never attributed to their case id, so the
per-case sum was short. A case shard's records now belong to its one case; a multi-case
shard with display-labelled records keeps those trials unknown. The ATTEMPT: line names
how many cases have no cost instead of printing a partial sum as the total.

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

* fix(ci): record the paid-report.ts harness decision and keep ship-queue-train-cost.test.ts off the Windows subset

scripts/lib/paid-report.ts is a pinned shared-harness file, so test/harness-version.test.ts wants a HARNESS_VERSION decision for its edit: non-behavioral, because a case shard's records are attributed to its one case for the trial's cost, class and error fields while no case's outcome, panel verdict or selection changes.

test/ship-queue-train-cost.test.ts drives bin/gstack-ship-queue against the #!/bin/sh gh shim, which windows-latest cannot run (windows-free-shard 2 on #3478 at d5e6a7d), so it joins test/ship-queue-train.test.ts in the Windows exclusion list.

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

* test: pin a failed display-labelled trial's fields and the $0.00 cost line; say so in the CHANGELOG

The widened record filter also feeds failedRecord, so a failed display-labelled trial in a case shard now takes failure_class, exit_reason and error from its record (train-gate classes a red infra record INFRA instead of VERDICT). The CHANGELOG entry said only the cost fields changed; it now says both. A train priced at zero prints cost=$0.00.

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

* chore(harness): say which panel class the paid-report decision moves

The non-behavioral note now names the one verdict-side effect of attributing a case shard's records to its case: a red whose own record says infra or timeout is classed INFRA instead of VERDICT, which changes rerun and bisect eligibility and not a pass rate.

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

* docs: document one-case-shard cost attribution and the train verdict cost line; put the undercounted train costs on record

/document-release (ship-owned audit) added the attribution rule and the ATTEMPT: cost-line form to docs/TESTING_INTERNALS.md, docs/troubleshooting.md#cost-unknown and docs/evals/census-red.md. The CHANGELOG headline now says every train cost the coordinator reported until this fix was the undercounted verdict figure (about $24 per train against about $33 real).

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

* docs: the train verdict prints the known+unknown cost form only when some but not every case is priced

The second /document-release audit tightened docs/TESTING_INTERNALS.md and docs/troubleshooting.md#cost-unknown: a train record with no priced case prints no cost at all (classifyGate's cost is null). The CHANGELOG bullet says the same.

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

* v1.91.255.0 stamp

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>
2026-10-26 20:33:32 +00:00
Garry Tanandcapy-ai[bot] 6154b6ea1d v1.91.245.0 fix(ship-queue): ready counts the latest run per check name and hints the dispatch route on a conflicting PR (#3460)
* fix(version-gate): a release output regenerated at the base VERSION is not a stamp

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

* fix(version-gate): run the head release tool with a bare env, drop outputs it must rewrite, prune the staging worktree

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

* fix(version-gate): regenerate at the merge base VERSION, read tool output from a file, never follow a VERSION symlink

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

* fix(version-gate): kill a release tool that ignores TERM at the limit, read a bounded log

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

* fix(ship-queue): ready counts the latest run per check name and hints the dispatch route on a conflicting PR; ship-policy follows #3439

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

* fix(ship-queue): key the latest run on app and name, keep undated runs standalone, quote the hint branch; restore the full CHANGELOG

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

* fix(ship-queue): refuse a dash-led branch in the hint, soften the green hint, restore the CHANGELOG tests bullet

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

* docs(ship-policy): name the refusal this branch prints for --screen on a conflicting PR

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>
2026-10-26 12:29:07 +00:00
Garry Tanandcapy-ai[bot] fa9d4b637c v1.91.237.0 fix(version-gate): a release output regenerated at the base VERSION is not a stamp (#3451)
* fix(version-gate): a release output regenerated at the base VERSION is not a stamp

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

* fix(version-gate): run the head release tool with a bare env, drop outputs it must rewrite, prune the staging worktree

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

* fix(version-gate): regenerate at the merge base VERSION, read tool output from a file, never follow a VERSION symlink

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

* fix(version-gate): kill a release tool that ignores TERM at the limit, read a bounded log

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>
2026-10-26 09:17:09 +00:00
Garry Tanandcapy-ai[bot] 6665e20d56 v1.91.236.0 feat(ship-queue): require a current /ship receipt before READY, train build and train merge (#3438)
* feat(ship-queue): require a current /ship receipt before READY, train build and train merge

Garry, 2026-10-25: use the gstack ship skill before merging PRs. ready printed
SHIP_RECEIPT: none as information and returned ok, so the pool was READY'd without
/ship. Now ready, train build (dry run included) and verify --train refuse with
QUEUE_RECEIPT_MISSING or QUEUE_RECEIPT_STALE from the PR body alone; verify accepts
the receipt written for the pinned head when the current head is its stamp commit.

gstack-ship-receipt result is /ship's terminal step (GSTACK_RESULT: skill=ship,
run dir with the head and receipt), unattended /ship may update an existing PR's
body, and INSTALL_UNVERIFIED with no verdict names the project directory to
install from (GSTA-85).

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

* test(ship): pin Step 22 in workflow-required-steps and tighten the ship skeleton

Gate edit: test/fixtures/workflow-required-steps.json pins the new
"## Step 22: Terminal line (every run)" heading (strengthens: a later
edit that drops the terminal line turns the required-steps test red).
Steps 14, 16, 18, 20 and 22 prose tightened so the carve-guards raise
shrinks to 81,600 / 1.6740 (measured skeleton 81,535, union 314,027).

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

* fix: pre-landing review fixes (ready at the stamp commit, screen on a stale merge ref, ship-run.json)

- ready accepts the pin's receipt at a slot's stamp commit (plus the slot-2
  merge of main), as verify --train already did; a real edit stays STALE
- ready --screen refuses QUEUE_SCREEN_STALE_REF when refs/pull/<n>/merge is
  missing or merges an older head; a finished screen that planned 0 cases is
  never followed, and train build seats that slot unscreened (GSTA-95 on #3431)
- gstack-ship-receipt result writes ship-run.json (a /ship record, not a run
  v1 manifest), validates --head, and prints status=incomplete on gh failures
- bindReceipt takes an optional pr and renders one-line SHIP_RECEIPT lines
- tests for every state-matrix cell the review named; the train fixture's
  merge ref is a real merge commit

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

* fix: cycle-2 review fixes (private screen scratch, no bare-merge receipt reuse, 12-hex --head, one receipt scrub) and align the unattended hook text with the GSTACK_RESULT writers (GSTA-91)

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

* fix: adversarial-review fixes (result refuses an unpushed HEAD, resolves --out and reports unwritable records; ready names a failed merge-ref fetch; unattended /ship never runs gh pr ready)

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

* fix: close review-cycle gaps (a stamp must change a stamp file, result requires a full --head and fails closed without headRefOid, digits-only --pr) with tests for every cycle-3 branch

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

* test: give the fsck-rejected merge-ref spawns a timeout (spawnsync tripwire)

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

* fix: detect a hollow screen from the plan it uploads (no paid-plan artifact or nothing planned), correct two troubleshooting facts, and normalise result --pr

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

* fix(hollow-screen): read manifest.json by name, list artifacts by name, say when the plan is unreadable; lowercase result --head

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

* test(hollow-screen): expired and unreadable run rows, uppercase --head; docs name every SCREEN: literal

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

* fix(train build): say when the repository slug is unreadable instead of counting the screen silently

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

* fix: name an ls-remote failure in ready --screen, refuse result --pr with --body, cap echoed receipt errors, tell an unreadable install verdict from a missing one

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

* test: ls-remote refusal, --pr with --body, capped receipt errors, unreadable slug and verdict (both twins); docs name the new literals

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

* fix: scrub Unicode line separators from receipt text, report an unreadable --body as incomplete, refuse unsupported verdict schemas in the bash twin

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>
2026-10-26 09:03:59 +00:00
Garry Tanandcapy-ai[bot] 080b752140 v1.91.196.0 fix(land-and-deploy): Step 3.4 reads the ship policy and stops only on a real VERSION collision (#3318) (#3379)
* fix(land-and-deploy): Step 3.4 reads the ship policy and stops only on a real VERSION collision (#3318)

Under stamp-at-merge, verify the exact head stamp (base + one bump, changelog
headings bound to it) and ignore claims. Under claim-at-open, stop only when
another open PR holds the same VERSION or the base is at or above it. MICRO
bumps and versions below a sibling's claim pass.

Reported-by: Evgenii Lopatin (@exGeni)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(ship-policy): what /land-and-deploy Step 3.4 reads from the policy (#3318)

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

* docs(changelog): Unreleased entry for #3318 /land-and-deploy Step 3.4

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

* test(size): raise land-and-deploy size pins and parity cap for #3318 Step 3.4 (owner-approved)

Garry, 2026-10-24: "do it". Pins set to the measured sizes on 11 hosts
(+1,084 to +1,111 chars); maxSizeRatio 1.112 -> 1.125 (measured 1.1201).

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>
2026-10-25 05:49:11 +00:00
Garry Tanandcapy-ai[bot] 910ee700e5 v1.91.192.0 fix(ship-queue): merge-train hardening — repo key, CHANGELOG damage, 1 MiB fail-open, merged-in verify, --order (GSTA-67) (#3374)
* fix(ship-queue): merge-train hardening — repo key, CHANGELOG damage, 1 MiB fail-open, merged-in verify, --order (GSTA-67)

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

* test(ship-queue): register the #3345 CHANGELOG fixtures; placeholder credential URLs (GSTA-67)

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

* v1.91.192.0 stamp: fix(ship-queue): merge-train hardening (GSTA-67) (#3374)

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>
2026-10-25 03:56:50 +00:00
Garry Tanandcapy-ai[bot] b616d6c53d v1.91.173.0 fix(ship-queue): train verify accepts a slot head with main merged in (GSTA-49) (#3327)
* fix(ship-queue): train verify accepts a slot head with main merged in (GSTA-49)

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

* v1.91.173.0 stamp

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>
2026-10-21 00:10:39 +00:00
Garry Tanandcapy-ai[bot] c580561e8a v1.91.164.0 feat(ship-policy): turn merge trains on for gstack (GSTA-49 go-live) (#3317)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-20 06:40:13 +00:00
Garry Tanandcapy-ai[bot] 6a4ab69dcd v1.91.146.0 feat(ship-queue): merge trains with pattern bisect and train-record verify (GSTA-49 T1) (#3272)
* feat(ship-queue): merge trains with pattern bisect and train-record verify (GSTA-49 T1)

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

* test(windows): curate ship-queue-train.test.ts out of the Windows subset (gh shim not resolved on windows-latest)

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

* v1.91.145.0 feat(ship-queue): merge trains with pattern bisect and train-record verify (GSTA-49 T1)

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

* v1.91.146.0 restamp: #3295 takes v1.91.145.0

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>
2026-10-19 10:29:44 +00:00
cadbd0af15 v1.91.116.0 feat: field list 2 wave B: gstack-ship-queue, approval classes, state-machine review, pregate timing check, update-check main moves (#3235)
* fix(capy): the install trailer says behind=<n> and its fix, so a stale install shows in every relayed trailer (field list 2 item 13, #2378)

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

* fix(capy): a lease records its holder's start identity, so a pid reused after a wake is reclaimed; a skipped session-start upgrade ends fail behind, never ok (GBRA-105, GBRA-106)

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

* fix(lease): stale needs proof (unreadable or malformed identities keep the lease), ps identity is timezone-independent, and reclaim never deletes a concurrent renewal

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

* feat(autoplan): enforced round cap and spend budget, deferred close, public export without machine paths, opt-in durable checkpoints (field list 2 W5-W7)

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

* fix(lease): one directory lock for publish, prune and reclaim; reclaim rereads the record judged stale, so a renewal is never deleted or hidden

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

* fix(lease): the directory lock names its holder; broken only when the holder is dead or its pid reused, unlock removes only its own lock, touch exits 3 under a live holder

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

* fix(lease): breakers serialize on .lock.break and reread the lock before removing it; gstack-skill-start reports a lease the held lock kept out

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

* docs(lease): name the double-crash limit of breaking a dead lock

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

* feat(capy): --for review-voice install profile, no-Drive bootstrap command, reviewer prompt trailer (field list 2 W11)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 89bf556c11)

* test: pin review-voice row, helpers row and the no-Drive fallback in existing install tests

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 7f6c70459a)

* test: the DRIVER template names the reviewer trailer relay (pregate lane)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 2545d9a6d2)

* test(context-budget): capy skill eager ceiling for the review-voice subagent paragraph (W11; ratchet protocol, capture value)

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

* feat(eval-plan): prereg diagnostics dry run (W8) and .gstack/eval-models.json lint (W9), WIP

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit b509096218)

* feat(eval-plan): W8/W9 tests, docs/eval-models.md, troubleshooting anchors, /eval-plan steps

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 9335e45de2)

* test(eval-plan): eval-plan/SKILL.md names only defined codes and accepted flags

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit a7a974d268)

* test(review-voice): the launch line points at the verdict's bun-only directory (#3233's launch contract)

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

* test(third-party-actions): the Aside drive-offer detector matches the product name, not the English idiom (paid run 38988927989 tpa-absent-linux false positive)

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

* fix(autoplan): export refuses artifact paths outside the run before writing; a deferred close keeps earlier undecided findings; reopening CEO grants Eng its rerun (review of #3234)

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

* fix(restamp): gate-ahead keeps the lane CHANGELOG entry when both PRs took the same tentative stamp (GBRA-102 diagnosis fixture)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 43c75a6bb6)

* test(tree-receipt): a real gbrain stamp pair is same-modulo-stamps under gbrain committed policy (W1 acceptance)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 6cf53f9fed)

* feat(ship-policy): gate_command, full_e2e and min_gstack_version; unknown keys stay fail-closed; validate prints introducing versions

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 878a7123d7)

* feat(ship-queue): gstack-ship-queue ready, stamp, verify and gate-ahead (WIP, tests next)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 409a5957ad)

* test(ship-queue): stamp journal and resume, verify from a separate clone, gate-ahead attempts, ready

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit ade554087b)

* docs(ship-policy): Run a shared merge queue; new keys and compatibility rule; troubleshooting anchors; /ship pointer

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 7fc73e8892)

* 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)

* test(windows): curate the shared-queue tests out of the Windows subset (shebang spawns)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 8deee14728)

* test(fixtures): register the gbrain stamp-pair fixture as free-only

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 563a07aa03)

* test(ship-queue): receipt digest contract names lib/ship-queue.ts for its pregate lane

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 501637c258)

* feat(pregate): timing check flags elapsed-time bounds and sleep-then-assert in added test lines (W4)

lib/pregate/checks/timing.ts prints TIMING_ASSERTION: <file>:<line> <pattern>
and a TIMING_ASSERTIONS summary; gstack-timing-ok: <reason> in any comment
syntax on the line or the line above escapes one. It warns
(PREGATE_TIMING_ASSERTION): measured on gstack (9 of 47 test-touching
commits, 263 hits in the tree) and gbrain (37 of 95 commits; 31 of 38 sites
of the five timing-flake fixes), blocking would stop a fifth to two fifths
of test changes. Adds the /review checklist rule and the /investigate
timing-flake playbook.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit a3b86b10b2)

* feat(update-check): an equal VERSION with a moved main is an upgrade, via the compare API (W12)

When VERSION matches but ls-remote's main SHA differs from this checkout's
HEAD, bin/gstack-update-check asks the GitHub compare API (status, ahead_by)
through the existing receipted curl and prints
UPGRADE_AVAILABLE <ver> <ver>+<n> <sha>; a diverged or unreadable compare is
CHECK_FAILED (unknown), and behind/identical is up to date. Never fetches.

The cache gains an IDENTITY line (head, compared remote SHA, upstream): an
outcome replays only for the same HEAD and upstream, a same-remote refresh
reuses it without another compare, and a git checkout ignores a legacy
one-line cache (non-git installs keep the one-line format). The snooze is
keyed by the SHA. gstack-upgrade's question, snooze note and What's New step
handle the four-field line; gstack-skill-end reports it.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 421e66d2a4)

* fix(pregate): treat planning and evidence markdown as an empty lane

A docs-only diff with no .gstack/pregate.json failed lanes as
PREGATE_NO_LANE. Planning and evidence Markdown is now a docs/no-tests
empty lane. Unmapped source files still fail closed.

Co-authored-by: Nick <surlymo@apache.org>
(cherry picked from commit e8793e59e8)

* fix(pregate): keep test-read markdown on its test lane

Unmarked Markdown that no test depends on is a docs/no-tests empty lane.
A file a test reads, including a fixture, still selects that test through
the import graph. Unmapped source and unreferenced test-tree files still
fail closed.

Co-authored-by: Nick <surlymo@apache.org>
(cherry picked from commit 7aabbddf3d)

* test(pregate): reviewer edges for the docs/no-tests empty lane (#3215)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 2fb3fa8613)

* test(pregate): requires-remote on a gbrain-shaped repo (ci:ubicloud, UBI_OWNER) (W10)

A base pregate.json with gbrain's dependencies and remote_gate
"bun run ci:ubicloud" (a package script whose stub needs UBICLOUD_API_KEY,
names VMs from UBI_OWNER and prints PREGATE_REMOTE). Under 8 cores the test
tier is one obligation naming the command; --remote passes the caller's
UBI_OWNER and key through and clears it on the report; without the key the
gate's own error shows and the obligation stays uncleared. #3190's path
needed no change.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 4d69ff02df)

* test(pregate): the ship receipt counts the timing check (7 checks)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit cb03ef67e7)

* test(context-budget): gstack-upgrade eager ceiling for the W12 equal-version upgrade question (ratchet protocol, capture value)

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

* feat(approval-classes): gstack-approval-classes and ship-receipt citation enforcement (W2, WIP)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 847c7dae3d)

* feat(approval-classes): tests, docs, /review and /ship wiring (W2)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 269bd5b8b5)

* feat(review): state-machines specialist and gstack-state-matrix round-trip check with a captured #6792 regression (W3)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 1a634979c6)

* fix(review-army): keep the --simplification force flag pinned; approval test timeouts

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 789d392bce)

* test(free-fixtures): register the state-matrix-6792 fixture

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 1bacef296d)

* test(state-matrix): cover state-machines NEVER_GATE in gstack-specialist-stats

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
(cherry picked from commit 859063d56f)

* test(fixtures): register the pregate-timing fixtures as free-only (W4)

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

* fix(ship-queue): full_e2e needs bound gate evidence in ready and verify, CI reads every check-run page and commit status, next: quotes its paths (review #3235 P1-1, P1-5, P2-1)

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

* fix(pregate): timing reads a native diff and never passes an unread one

The timing check's git diff honored diff.external, textconv and
diff.noprefix, so a configured driver hid every added line and the check
passed. Run it with --no-ext-diff --no-textconv and explicit a/ b/
prefixes, and report a git diff that fails or does not finish as
incomplete (PREGATE_INCOMPLETE), which a warn downgrade does not soften.

Review of #3235, sibling of P1-4 (lib/pregate/checks/timing.ts:189).

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

* fix(approval-classes): only affirmative APPROVED evidence counts, explicit tokens are authoritative, native diffs fail closed (review #3235 P1-2, P1-3, P1-4)

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

* fix(state-matrix): detect reads the native diff, ignoring diff.external and textconv (review #3235 P1-4)

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

* test(e2e): review-army-state-matrix behavior case on the #6792 fixture (field list 2, W3)

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

* fix(review-army): tighten the State Machines dispatch line so /ship stays under its parity size ratio with main's #3231 review-army text

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

* fix(approval-classes): only top-level approval lines count; quoted, fenced, indented-code and commented text never does (review #3235 r2)

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

* fix(approval-classes): approval evidence is the first non-blank line only, at column 0 (review #3235 r3)

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

* test(autoplan-budget): bind the reservation expectation to lib/autoplan-budget's default estimate (test-of-test ratchet)

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

* fix: keep gstack-upgrade under its size budget, exempt state-matrix's fetch hint, fit the periodic plan's 37 slices

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

* fix(evals): the docs observer accepts the spawned-prefixed gstack-skill-start --help read

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

* fix(windows): curate capy-review-voice out of the Windows subset (POSIX launcher contract)

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

* docs: changelog entry for field list 2 wave A

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

* chore: stamp v1.91.115.0

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

* test: the scope-signal clarity check follows helper-printed signals; the hermetic update-check fixture writes the identity cache

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

* refactor: move the release-path result codes to lib/result-codes-release.ts (module-size ratchet); fit the periodic plan's 38 slices

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

* docs: changelog entry for field list 2 wave B

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

* chore: stamp v1.91.116.0

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

* test: copy lib/result-codes-release.ts wherever a fixture copies lib/result-codes.ts; the scope-signal check requires the helper's computed emission

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

* test: state-matrix stats test resolves its slug under its own state root (home containment)

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

* fix(windows): curate pregate-docs-lane-review out of the Windows subset (runBin shebang, like the other pregate fixtures)

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

* fix(windows): curate pregate-remote-gbrain out of the Windows subset (runBin shebang, like pregate-remote)

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>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Nick <surlymo@apache.org>
2026-10-17 03:32:16 +00:00
Garry Tanandcapy-ai[bot] 7edaf4f50a v1.91.98.0 fix: plan obligations meet repo gates; priced paid gates; machine-proved restamps (field wave C, items 14-17) (#3166)
* docs(designs): gstack field wave plan (2026-10-12) and the shared simulated Capy host fixture

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

* feat(pregate): price_command config key for the non-executing call plan a paid gate is priced from

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

* feat(pregate): repo guards a lane must pass, verified launch Bun and per-file serial runs in lanes, unknown flags exit 2

The guards check runs each .gstack/pregate.json guard whose globs match a
touched file in its own process with its own timeout (PREGATE_GUARD_FAILED,
never downgradable, incomplete without --allow-repo-commands). The lanes
runner and guards get the first Bun in $BUN_INSTALL/bin or ~/.bun/bin that
satisfies gstack's and the project's engines.bun; serial_patterns files run
one process each. price_file replaces the unreleased price_command key: a
paid gate is priced from a call-plan data file, never by running a command.

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

* fix(pricing): Sonnet 5.5, Gemini 3.x and gbrain embedding rows from fetched pages; Opus 4.7 at its current list price

Each new row carries its source URL and fetch date (2026-10-12). Embedding
models bill input only, so they live in EMBEDDING_PRICING beside PRICING
(eval arms never resolve to them); pricingRow also accepts gbrain's
provider:model ids (voyage:voyage-4). claude-opus-4-7 moves from 15/75 to the
5/25 the Anthropic pricing page lists; benchmark-runner's expected costs follow.

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

* feat(eval-plan): price-gate prices a paid gate from a call-plan data file, never executing it

gstack-eval-plan price-gate --gate "<exact command>" reads a GSTACK_EVAL_CALLS
v1 file (--plan-file, else the base policy's price_file at HEAD), checks its
binding (gate command string equality, head with only the plan file changed
since, every input's sha256 at HEAD), prices each call purpose (aggregate
totals) and each one-call reservation, and writes a receipt binding the price
to the gate, head, inputs and plan bytes. Unpriced models print unknown, never
zero (EVAL_PRICE_MISSING); a missing plan or no call lines is
EVAL_GATE_UNPRICED unless --allow-unpriced records an owner override; over
--cap-usd / --smoke-cap-usd is EVAL_GATE_OVER_CAP; malformed or partial files
refuse EVAL_DRY_RUN_FAILED and stale ones EVAL_PLAN_STALE. dry-run --cap adds
the same reservation-fits-cap check. Wire format, receipt and the reference
emitter (formatEvalCalls): docs/eval-calls.md.

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

* feat(eval-plan): the approval step prices every paid gate with price-gate

Step 4 runs gstack-eval-plan price-gate for each paid gate the plan names and
puts its GATE_PRICE line in the ask; the dry-run checklist documents
reservation-fits-cap under --cap.

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

* feat(sealed): sealed-output guard over every published commit, in the pre-push hook and gstack-pregate sealed

A repo with a sealed key in .gstack/pregate.json (base branch union the
pushed commit, so a push can tighten but never relax) refuses publishing
sealed paths, transcripts, quoted answers, seeds or local home paths to a
public or unknown destination (SEALED_OUTPUT_REFUSED); private warns.
Path rules see every added, renamed or copied path in each published
commit (git rev-list <local> --not --remotes=<remote>), text rules each
commit's added lines; waivers only from the base branch allow file; a
malformed policy fails closed; visibility caches public 24 h, private 1 h.

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

* fix(eval-plan): only an undeclared plan is unpriced; a missing price_file is stale, a bad base policy refuses

price-gate's EVAL_GATE_UNPRICED (and --allow-unpriced) now covers only no
plan declared at all or a plan with zero call lines. A declared price_file
missing from the HEAD commit is EVAL_PLAN_STALE (exit 1, not overridable); an
unresolvable origin/<base> is POLICY_SOURCE_UNAVAILABLE and an invalid
.gstack/pregate.json is PREGATE_CONFIG_INVALID (both exit 3).

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

* feat(restamp): the repo's stamp rule (stamp_files, literal stamp_patterns) and restamp_command in the staging worktree

stamp_files is an allowlist applied before every stamp rule; stamp_patterns
are bounded literal {version} templates shared by the restamp writer and the
tree receipt. restamp_command runs first in the staging worktree with the
target version (argument and GSTACK_RESTAMP_VERSION), needs a clean caller
tree, skips gstack's version writer and keeps output confinement; a failure
or a wrong version writes nothing. migrations { dir, id } is the policy key
gstack-pregate regate reads.

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

* feat(pregate): gstack-pregate regate --against <gated-head> with per-lane reuse and migration collisions

Reuse comes only from a tree receipt evaluated now, with a bundle produced
on the gated tree, the current execution identity and an unmoved, known
predecessor head. Each lane prints reusable/rerun/not-reusable; REGATE:
not-needed needs stamp-only, every bundle and --require lane reusable (a
stamp-sensitive lane reruns) and a finished migration lookup. Migration
numbers the branch adds are checked against the base tree and every other
open PR (gh pr list --limit 1000; 100-file lists refetched with gh api
--paginate); any lookup that cannot finish is unknown and blocks
not-needed (MIGRATION_COLLISION). Bare --against routes to the verb.
docs/pregate.md gains the regate section and the gbrain worked configs.

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

* feat(contract): lanes run gstack-pregate (and the sealed guard where configured) before done; handoff carries the gstack trailer and PREGATE: line

The coordinator contract gains a 'Before done' paragraph and the handoff
order GSTACK_RESULT, gstack: ok|fail <rev>, PREGATE:, gate summary; the
spec section is regenerated and docs/unattended.md states the same rule.
A new test pins the terms and their order; the byte-identity pins stay.

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

* v1.91.98.0: pregate guards, priced paid gates, regate and the sealed-output guard

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

* test: drop the helper-only Capy host fixture test (test-of-test ratchet); lane tests exercise the helper

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

* fix: price-gate --gate-file keeps free text out of the /eval-plan fence; shortest dependency traces; bounded test spawns

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

* ci(windows): curate out the new pregate/restamp tests that spawn bin/ shebang scripts through runBin

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>
2026-10-13 15:38:41 +00:00
Garry Tanandcapy-ai[bot] 5cb5e1cfc1 v1.91.83.0 feat(ship): gstack ships itself under stamp-at-merge, bump patch, explicit maintainers (#3125)
* v1.91.81.0 feat(ship): gstack ships itself under stamp-at-merge, bump patch, explicit maintainers

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

* docs(ship-policy): queue-side procedure in the tentative-stamp form

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

* test(selection): .gstack/ship-policy.json is free-only for PR eval selection (harness v4 non-behavioral record)

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>
2026-10-11 06:06:12 +00:00
Garry Tanandcapy-ai[bot] 5d647455f2 v1.91.79.0 feat(eval-plan): /eval-plan tier 1, lane-check, evidence verify, coordinator contract, owner brief, contributor-PR mode, banned terms (multi-agent wave PR E) (#3123)
* v1.91.79.0 feat(eval-plan): /eval-plan tier 1, lane-check, evidence verify, coordinator contract, owner brief, contributor-PR mode, banned terms (multi-agent wave PR E)

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

* fix(spec,review): fail closed when the coordinator contract cannot be read; restore the omitted-Army sentence

The spec --execute spawn captures `gstack-autoplan contract` before piping
the archive, so a lane never starts without the contract; the C9 fixture
installs its gstack-like checkout (bin, lib, a contract stub) at every
host's global root. Review Step 5.8 keeps the pinned
'without claiming specialist coverage' wording.

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>
2026-10-11 03:10:06 +00:00
Garry Tanandcapy-ai[bot] 7552362196 v1.91.73.0 feat(ship): repo ship policy, gstack-restamp stamp-at-merge, tree receipt, evidence bundle, ship receipt (multi-agent wave C-stamp) (#3118)
* v1.91.70.0 feat(unattended): artifact contract, unattended session kind, findings-derived review log, gate list

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

* v1.91.73.0 feat(ship): repo ship policy, gstack-restamp stamp-at-merge, tree receipt, evidence bundle, ship receipt

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

* fix(ci): result-codes is selection data, receipt counts come from files, C-stamp tests leave the Windows subset

- scripts/pr-dependencies.ts: lib/result-codes.ts joins SELECTION_DATA_MODULES; its fix: prose names commands a person reruns, not files the module consumes (test/pr-dependencies.test.ts traced review cases through it to bin/gstack-next-version)
- ship/sections/pr-body.md.tmpl: gstack-ship-receipt write reads --gate/--ci from agent-written .gstack/tmp/ship-*.json files and --spend-usd from the allowlisted <spend-usd> placeholder (generated-bash lint: no free text in commands)
- scripts/lib/windows-curation.ts: the five C-stamp test files spawn bin/ shebang scripts through test/helpers/restamp-fixture.ts, which the source scan misses

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

* fix(ship): the receipt step names where each input comes from

The workflow judge (eval-slices 3, median 3/4) found pr-body's gstack-ship-receipt command demanding a tree receipt, CI counts and a spend figure no earlier step produces, with RECEIPT_INVALID halting publication. The command now takes only Step 16 stage 4's lane counts (file-written JSON); --receipt is added only when Step 16 wrote .gstack/tmp/tree-receipt.json; RECEIPT_INVALID says to fix the named input file and rerun. The unused <spend-usd> allowlist entry is removed.

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>
2026-10-11 01:01:42 +00:00