Commit Graph
177 Commits
Author SHA1 Message Date
garrytanandcapy-ai[bot] b5898e6854 fix(ship-receipt): write honors every docs audit in one /ship run (GST-1616)
When Step 14.5 audits twice in one /ship run (an audit, then a base merge and
restamp, then the re-audit), receipt write reset only the last audit's files,
so a file the first audit edited and committed stayed in the review_exclude
selection and write refused the reviewed digest (gbrain #8678).

gstack-docs-candidate snapshot now takes --run (the invocation record), --pre
on a post snapshot (records the files the audit edited, before and after) and
--carry (the run's earlier post snapshot, refused from another run). Write
resets every file the run's audits edited to its content before them when HEAD
holds what the last of them left; a file no audit edited, an edit after an
audit and a carried audit of another run still refuse.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-11-06 12:38:26 +00:00
Garry Tanandcapy-ai[bot] f7015fa72c ship-receipt write: the targeted record survives a main merge (GST-1593) (#4058)
* ship-receipt write: the targeted record survives a main merge; classes since the read cover the PR's own change (GST-1593)

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

* docs: the targeted record's change since the read is the PR's own (GST-1593)

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

* ship-receipt depth: a branch edit to a path whose base did not move always voids the targeted record; isolate the GST-1593 tests' gate scan from the real home (GST-1593)

ownChangeSince compared the PR's per-path hunks with line numbers stripped even when main had not moved the
path's base content, so a branch commit after the targeted read that relocated the PR's money line to an
identical-context block read as unchanged and the record bound (red-team, /ship #4058 pass 1). Hunk
comparison now applies only when the base blob moved. The four direct targetedClassesSince calls in the
GST-1593 tests now run with the fixture's env, so gstack-gate-diff no longer writes under the real
~/.gstack (CI run 42179129702, free-suite (4): FREE_SUBSHARD_REJECTED real home changed).

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

* fix: pre-landing review fixes (GST-1593)

ownChangeSince: a path whose base content main also changed now moves unless replaying main's change onto
the read's content (git merge-file) gives HEAD's content exactly, so relocating the PR's money hunk to an
identical context after a main merge voids the targeted record; position-free hunk comparison is gone. The
built commit carries the branch's first-parent messages since the read, so a [skip ci] commit stays RH-14
gate class. Two red-first tests cover both.

Review-Finding: v1/outside-voice#1 reader=outside-voice
Review-Finding: v1/adversarial-native#1 reader=adversarial-native
Review-Finding: v1/outside-voice#2 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* ci: run the checks at the review-fix head (GST-1593)

The previous commit's message quoted a CI skip marker, so no workflow ran at c462483. This commit changes
no file; the tree is c462483's.

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

* fix: pre-landing review fixes, fix-check round (GST-1593)

The built commit now carries the message of every commit since the read that origin/main does not hold,
so a CI-skip marker on a side-branch commit merged with --no-ff still tags RH-14. A path whose mode at
HEAD is not the replayed mode now moves, so a mode-only change after a main merge to the PR's own file
voids the record. Two red-first tests cover both.

Review-Finding: fc1/fix-check#1 reader=fix-check
Review-Finding: fc1/fix-check#2 reader=fix-check
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* changelog.d: plain-sentence wording for the GST-1593 fragment (prose lint)

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-11-06 10:34:41 +00:00
Garry Tanandcapy-ai[bot] 05114c8049 ship accept: a lanes-only head policy gates the final tree; owner-granted test-lane exception (GST-1595) (#4061)
* ship accept: a lanes-only head policy gates the final tree; name bun-hidden JUnit suites; owner-granted test-lane exception (GST-1595)

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

* fix: pre-landing review fixes

Each excepted file is preflighted on its own and must run a counted test; the preflighted files count toward the lane's tests_ran; grants are kept per head and file set; lanesOnlyHeadPolicy compares .gstack/generated.json with the fork copy.

Review-Finding: v1/outside-voice#1 reader=outside-voice
Review-Finding: v1/outside-voice#2 reader=outside-voice
Review-Finding: v1/outside-voice#3 reader=outside-voice
Review-Finding: v1/adversarial-native#2 reader=adversarial-native
Review-Finding: v1/adversarial-native#4 reader=adversarial-native
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: lanesOnlyHeadPolicy compares generated.json with the base tip again

A --policy-from head run loads the regen registry from the branch (lib/pregate/context.ts), so a branch whose .gstack/generated.json differs from main's tip keeps the base policy; comparing with the fork copy would gate under a stale registry.

Review-Finding: p2/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: troubleshooting entries for the accept head policy and test-lane exceptions (GST-1595)

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-11-06 10:16:00 +00:00
Garry Tanandcapy-ai[bot] 4b1a115284 ship-receipt carry: changed and moved-context paths compose into one bounded re-check (GST-1561) (#4054)
* test: failing-first repro for the changed+context carry deadlock (GST-1561)

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

* ship-receipt carry: a changed path plus moved base context compose into one bounded re-check, and a base-side removed line joins the scoped review (GST-1561)

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

* fix: pre-landing review fixes

baseEditOnly refuses a hunk whose range holds a line the base inserted without replacing any, so a merge that drops base code stays changed. Curates the new test out of the Windows scoped shard like ship-mechanical-retake.

Review-Finding: p1/specialist-batched#1 reader=testing
Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes

baseEditOnly refuses any base hunk at the reviewed range that adds more lines than it removes, so a merge that drops a line the base added beside its own edit stays changed.

Review-Finding: p2/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: ship-policy names the base-added-line case that stays a changed path (GST-1561)

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-11-06 07:02:54 +00:00
Garry Tanandcapy-ai[bot] 8d712d63dd ship finish: a declared mechanical version retake after a base merge binds without a new review (GST-1560) (#4053)
* test: failing-first founderstar#563 retake shape, refusals and planner agreement at the cap (GST-1560)

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

* feat(ship): finish routes a declared mechanical retake with no review; --post-review plans the inserted Step 9 (GST-1560)

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

* docs(ship): mechanical_retake, ROUTE_MECHANICAL_REFUSED and the Step 16 planner line (GST-1560)

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

* test: keep ship-mechanical-retake.test.ts off the Windows scoped lane (bin shebang spawns) (GST-1560)

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

* fix: pre-landing review fixes

finish dropped a post-review path named like an Object.prototype key (constructor, toString, __proto__) from behavior through 'p in proven' on a plain object; proven is now a null-prototype map read with Object.hasOwn, with a regression test.

Review-Finding: v1/outside-voice#1 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: changelog fragment prose lint (GST-1560)

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-11-06 04:33:54 +00:00
Garry Tanandcapy-ai[bot] c454496143 fix(review-exclude): files kept only for a secret line go to readers as excerpts (GST-1447) (#4044)
* fix(review-exclude): files kept only for a secret line go to pass readers as excerpts (GST-1447)

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

* fix(review-exclude): keep the pinned depth rules untouched; the plan adds each dispatch's excerpt (GST-1447)

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

* fix(review-exclude): split secret-excerpt sections only at real line starts (GST-1447)

A CR, U+2028 or U+2029 followed by 'diff --git ' inside a changed line cut the
file's section short, so the secret lines after it left the excerpt while the
file stayed excluded from the reader's own diff.

Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(review-exclude): scan secret-excerpt lines with their context and overlapping chunks (GST-1447)

The scanner read changed lines alone, in chunks with no overlap, so a secret it
detects only beside its label (an AWS secret key under an unchanged
aws_secret_access_key line, or a label at the end of one 512 KiB chunk) left
every excerpt. Scan every hunk line, repeat 1 KiB between chunks, and count
findings on changed lines only.

Review-Finding: p11/outside-voice#1 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(changelog): split the excerpt sentence (GST-1447)

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-11-05 19:27:19 +00:00
Garry Tanandcapy-ai[bot] 065afdfdcf fix(ubi-runner): an ambiguous create arms teardown only once this call's ssh key opens the VM (GST-1463) (#4046)
* fix(ubi-runner): an ambiguous create arms teardown only once this call's ssh key opens the VM (GST-1463)

With an explicit -n name a second caller can take the name between the 404
name check and the create; if our create's 409 was lost (000), the by-name
lookup adopted that caller's VM and teardown destroyed it. Teardown is now
off from an ambiguous create answer on and armed only when this call's key
opens the VM within UBI_SSH_WAIT; otherwise up keeps the record and bundle,
exits UBI_CREATE_UNKNOWN and leaves the VM to its TTL, and run reports
left=unknown.

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

* fix: ubi-runner ssh proof offers only this call's key (IdentitiesOnly=yes)

The ownership proof after an ambiguous create counted any ssh success, and ssh also offered agent and default ~/.ssh keys beside -i, so a holder VM that accepted one of them was armed and destroyed. Failing-first test: the fake agent holds the holder's key.

Review-Finding: p1/specialist-batched#1 reader=specialist-batched
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: ubi-runner ownership proof ignores ssh config identities (-F /dev/null)

IdentitiesOnly=yes still offers IdentityFile and CertificateFile entries from ssh config, so the proof after an ambiguous create could pass on a holder VM that accepts a configured key. The unproven proof now runs with -F /dev/null; the normal path keeps the user's config. Failing-first: the fake ssh config holds the holder's key.

Review-Finding: p2/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: ubicloud skill says to list before down after UBI_CREATE_UNKNOWN

left=unknown can now mean another caller's VM; the runner prints list, not down, for that case. The changelog fragment notes that agent and config keys don't count for the proof.

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-11-05 19:24:58 +00:00
Garry Tanandcapy-ai[bot] 4c400661d9 fix(review-exclude): write, ready and carry bind a digest whose policy gives the PR's files the same selection (GST-1446) (#4041)
* fix(review-exclude): write, ready and carry bind a digest whose policy gives the PR's files the same selection (GST-1446)

harness-evals #222's reviewers read 7cf39a7e1150, which excludes 1,260 of its files under #272's
three globs. After #278 added six globs that match none of them, main's digest became
dde43b124877 and gstack-ship-receipt write refused the reviewed digest: write compared digests
only, and the shared carryExcludeBinds rule bound a moved digest only when both selections
were empty.

carryExcludeBinds now binds when the recorded selection and HEAD's give the PR's files the same
list hash (applied patterns, excluded files, kept files with their reasons); the empty-selection
rule is the case where both lists are empty. ready, train build, land and carry pick it up
through the same predicate. Write gets only the reviewed digest, so it rebuilds the record from
the review_exclude_paths the base held at each commit that changed the policy file, and binds
when one of them with HEAD's list builds the digest (REVIEW_EXCLUDE_POLICY_MOVED:). A digest no
such policy builds, an omitted --review-exclude, a selection that differs and an unreadable base
policy still refuse; --docs-post keeps its path.

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

* fix: pre-landing review fixes

reviewedRecord walks the policy file's full history, so a merge that restores an earlier policy no longer hides the reviewed one (GST-1446).

Review-Finding: p1/outside-voice#1 reader=outside-voice
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-11-05 18:06:47 +00:00
Garry Tanandcapy-ai[bot] 3374c5838d fix(ubi-runner): an API error is never read as success on the money path (GST-1441) (#4039)
* fix(ubi-runner): an API error is never read as success on the money path (GST-1441)

A refused create disarms teardown, a 5xx/unanswered create is looked up by
name, down counts a VM gone only on a readable list, pull fails on ssh
failure, gc reports failed destroys, an unanswerable run record refuses
instead of starting a second VM, and the API key leaves curl's argv.

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

* fix: pre-landing review fixes

A 5xx or unanswered create no longer adopts a VM another caller already holds under that name: up refuses a name that already answers show before any create is sent, and adopts after an ambiguous create only when the name was free just before it. Regression test reproduces the adopt-then-destroy on 6a61206.

Review-Finding: v1/outside-voice#1 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(troubleshooting): UBI_CREATE_UNKNOWN and UBI_ATTACH_UNKNOWN (GST-1441)

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

* fix(ubi-runner): create only after the name check answers 404 (GST-1441 fix-check)

An unanswered name check let the create go out; a 5xx create whose lookup
then stayed unanswered left teardown armed on a VM whose owner was never
established, and one whose lookup answered 200 was disarmed and left to its
TTL. up now refuses before any request unless the check answers 404, so a
VM found after an ambiguous create is always this call's. The 409 test
again lists the holder (landing between check and create) and proves it is
not destroyed.

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-11-05 17:56:15 +00:00
Garry Tanandcapy-ai[bot] 713c672d28 fix(review-exclude): fixed git calls for the name scan and binary read; dispatch names a plan timeout (GST-1442) (#4040)
* fix(review-exclude): one git grep per tree through a scratch index, batched blob reads; dispatch prints REVIEW_PLAN_STOPPED (GST-1442)

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

* fix(review-dispatch): the plan limit lives beside the scan deadline it must stay a minute above (GST-1442)

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

* fix: pre-landing review fixes

Batched blob prefixes are copied, so each 64 MB cat-file --batch buffer is released after its group instead of staying alive until every blob is read.

Review-Finding: v1/outside-voice#1 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(review-policy): a plan past the pass limit stops with REVIEW_PLAN_STOPPED (GST-1442)

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-11-05 17:40:15 +00:00
Garry Tanandcapy-ai[bot] 6278ee4fb7 fix(review-exclude): ready binds an older digest when no selection holds a PR file; name scan greps consumers only (GST-1434, GST-1435) (#4036)
* fix(review-exclude): ready binds an older digest when no selection holds a PR file; the name scan greps consumers only (GST-1434, GST-1435)

GST-1434: gstack-ship-queue ready (and train build, land) refused any receipt whose
recorded review_exclude digest differed from the base policy's, so a policy edit on
main voided every receipted PR even when no PR file fell under a pattern
(harness-evals #274, #276 after #278). excludeMismatch now uses carryExcludeBinds,
the predicate carry uses since #4030: a digest change binds when neither the recorded
selection nor HEAD's holds a file the PR changed; anything else still refuses.

GST-1435: the named-by-code scan ran git grep over the whole tree, so on
harness-evals #269 it searched 30 MB of receipts for 4,354 candidate paths, ran
278 s past its 120 s limit and kept every file. It now lists each tree, keeps the
consumer files (code and tests outside the candidates) and greps only those through
literal pathspecs in 24 KB chunks. A git failure or timeout still keeps every
candidate.

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

* fix: pre-landing review fixes

grepFixed keeps every candidate when a consumer's name does not survive UTF-8 decoding, since its literal pathspec would match nothing.

Review-Finding: p1/outside-voice#1 reader=outside-voice
Review-Finding: p1/adversarial-native#1 reader=adversarial-native
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: the queue's review_exclude check follows carry's rule (GST-1434)

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-11-05 15:38:48 +00:00
Garry Tanandcapy-ai[bot] 467be16ab2 fix(ship-receipt): a docs audit after the review no longer forces another review (GST-1429) (#4034)
* fix(ship-receipt): a docs audit after the review no longer voids the review_exclude binding (GST-1429)

Step 14.5's docs audit runs after the review. When it edits, adds or removes a
file under review_exclude_paths, HEAD's selection digest moves and receipt
write refused the reviewed digest. write --docs-post <audit-id>-post.json now
binds the reviewed digest when it is HEAD's selection with the files under a
pattern that changed since the snapshot's HEAD reset to it, each named by the
snapshot with the content HEAD holds and excluded or kept only because code
names it, and every other file selected alike. Anything else still refuses.

The ship driver's Step 19 write omitted --review-exclude, so gbrain #8627
wrote recorded=none; it now passes it, and the refusal says when the flag was
left out.

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

* test(review-exclude): keep the GST-1429 in-process receipt read off the real state root

The #8627-shape test called receiptReviewAtHead in-process with the runner's
GSTACK_STATE_ROOT, so its gate scan wrote gate-diff and slug-cache entries
under the real ~/.gstack and CI rejected free-suite shard 9
(FREE_SUBSHARD_REJECTED, run 42017628509). It now points GSTACK_STATE_ROOT at
the fixture like the docs-only gate-tagged test does.

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

* fix: pre-landing review fixes

The docs-audit exception reset every changed file under review_exclude_paths
to the post snapshot's HEAD, so a docs edit the review read while it was still
uncommitted was reverted and write refused a normal /ship run. --docs-pre
<Prepare snapshot> now narrows the reset to the files the audit changed, back
to their Prepare content. Snapshot hashes of working-tree bytes also compare
against HEAD's content as it checks out, so autocrlf or a clean filter no
longer reads as an edit after the audit.

Review-Finding: s11/outside-voice#1 reader=outside-voice
Review-Finding: s11/outside-voice#2 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* chore: changelog and TODOS

gstack: ok 1.96.0.0 for=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-11-05 12:25:45 +00:00
Garry Tanandcapy-ai[bot] 6666b72967 feat(ship-policy): gstack adopts the release gate; a pre-adoption backstop freeze only warns (GST-1133) (#4031)
* feat(ship-policy): adopt the release gate; a backstop freeze only warns land once release_gate is set (GST-1133)

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

* fix: pre-landing review fixes

Review-Finding: p1/specialist-batched#1 reader=state-machines
Review-Finding: p1/red-team#2.1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: bisect follows the current policy cap and resumes when it is raised; docs say the cap prices trials at the reservation

Review-Finding: p2/outside-voice#1 reader=outside-voice
Review-Finding: p2/outside-voice#2 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(changelog): GST-1133 fragment covers release-cut and the bisect cap

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

* docs: land table and QUEUE_TRAIN_FROZEN note the release_gate stand-down (Step 14.5 audit g2a1)

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-11-05 07:33:37 +00:00
Garry Tanandcapy-ai[bot] e4f2930812 fix(ship): a required edit after review takes one scoped reader, not another review round (GST-1276, GST-1311) (#4020)
* feat(ship): bounded post-review edits take one scoped reader, not a third review round (GST-1276, GST-1311)

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

* docs(ship): a scoped-review STOP takes one reader, not a fix-check round (GST-1276)

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

* test: bound the diff-scope spawn and record the ship size ledger (GST-1276)

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

* test: repin lib/review-depth.ts on the GST-1276 no-loss replay

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

* fix: pre-landing review fixes

Review-Finding: p1/specialist-batched#1 reader=specialist-batched
Review-Finding: p1/specialist-batched#2 reader=specialist-batched
Review-Finding: p1/specialist-batched#3 reader=specialist-batched
Review-Finding: p1/red-team#2 reader=red-team
Review-Finding: p1/red-team#3 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: a blank line or a template literal no longer hides a changed expected value (review fix-check)

Review-Finding: p2/outside-voice#1 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(ship): a bounded lanes edit changes only dependencies; any other pregate key stops (GST-1276)

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

* ship: take the receipt-write targeted rebind out of GST-1276 (follow-up); document the lanes key check

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

* docs: list always-run.json as a gate path and finish's bounded=N stop

Step 14.5 audit da1-gst1276 corrections.

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

* docs: keep review-policy.md at its reviewed bytes

main's finish reads docs/review-policy.md as agent prose (behavior); the gate-path list omission of .gstack/always-run.json is recorded as doc debt in the PR body.

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-11-05 04:16:06 +00:00
Garry Tanandcapy-ai[bot] a4d058b078 feat(review): enforce the reader fetch rule with a per-stage sweep (GST-1322 B) (#4011)
* feat(review): enforce the reader fetch rule with a per-stage sweep (GST-1322 B)

Split of #4008 onto current main: the squashed product diff at cf34a43.

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

* fix: pre-landing review fixes (GST-1322 B, ship-c-p1)

A start sweep that hit its bounds is a partial note, never a violation
(sweepResult). The sweep tests remove their fixture repos. A stage's rerun
dispatches no reader while a path its first attempt found still exists
(FETCH_RERUN_BLOCKED, the Captain's ruling C on #4011).

Review-Finding: p1/specialist-batched#1 reader=state-machines
Review-Finding: p1/red-team#1 reader=red-team
Review-Finding: p1/red-team#2 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: sweep strips remote userinfo; a spent or blocked rerun stops every later stage (GST-1322 B, grant a-7b63e4cad37c)

outside-voice#1: remote URLs are recorded and printed without user:token@.
outside-voice#2: resuming after FETCH_RERUN_SPENT stops before any later stage
and returns no reader output; while a kept path blocks one stage's rerun, no
stage's start (Step 11's voices included) dispatches a reader.

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

* fix: sweep reads remotes through git config and redacts fail-closed (GST-1322 B, GSTA-297)

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

* fix: pre-landing review fixes

Review-Finding: p1/specialist-batched#1 reader=security
Review-Finding: p1/red-team#2 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: quarantine every collection of a dispatch; classify remotes on the raw value (GST-1322 B, GSTA-297)

Review-Finding: p1/outside-voice#1 reader=outside-voice
Review-Finding: p1/outside-voice#2 reader=outside-voice
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-11-05 04:13:13 +00:00
Garry Tanandcapy-ai[bot] 3b66745ce5 fix: queued PRs keep their ship receipts when main starts excluding paths they never touched (GST-1408) (#4018)
* fix(ship-queue): a receipt with no review_exclude digest binds when the PR touches no new pattern (GST-1408)

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

* test(review-exclude): type the touched-file cases for the test typecheck ratchet

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

* docs(changelog): name the GST-1408 fragment by branch slug

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

* docs(troubleshooting): the queue accepts a recorded=none receipt when no pattern matches (GST-1408)

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-11-05 04:10:02 +00:00
ef6425036e fix(outside-review): a ## Recommendation heading counts as the completion marker (#4000)
* fix(outside-review): a ## Recommendation heading counts as the completion marker (#3980)

A completed Codex review whose model wrote its recommendation as a Markdown
heading with the prose underneath was classified unavailable/missing_markers,
because only an inline "Recommendation: <action> because <reason>" line passed.
The fence-blanked views now fold the heading and its next prose line into the
inline marker. Empty sections, no because-rationale, list or quote lines under
the heading, and fenced examples still report missing.

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

* fix(outside-review): keep labels and verdicts under the heading visible to the severity parsers

Review p1 (specialist + adversarial) found that folding the heading into the
fence-blanked views moved a P1:, Critical: or Verdict: line under the heading
off line start, so a blocking review read clean. The folded view now feeds only
the completion check and the no-findings conclusion.

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

* fix(outside-review): fold only a heading line that carries a because-clause

Pass 2's fix-check found that a structured reply ending '## Recommendation' over
'No issues found.' read clean at base and unverified after the fold. A line with
no because can never meet the completion marker, so it is left as prose.

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

* docs(changelog): fragment for the Recommendation heading fix

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

* docs(troubleshooting): missing-markers entry names the Recommendation heading form

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

---------

Co-authored-by: nfitzsimmons <2198211+nfitzsimmons@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-11-05 00:04:35 +00:00
Garry Tanandcapy-ai[bot] ec1f2aa6a4 fix(redact): a short sha is not a phone number or a bc1 wallet; plan-reality receipt and pregate fixture flakes (#3998)
* fix(redact): a short sha is not a phone number or a bc1 wallet; plan-reality receipt and pregate fixture flakes (GSTA-279)

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

* docs: the review_loop_grant sha exemption and the fixture origin's maintenance setting (GSTA-279)

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

* docs(changelog): name the fragment for the branch and narrow its claim to the review_loop_grant position (GSTA-279)

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-11-05 00:01:33 +00:00
Garry Tanandcapy-ai[bot] dbd9288399 fix(ship-queue): a lock push GitHub applied but answered 502 no longer leaks the land lock (GST-1344) (#3994)
* fix(ship-queue): a lock push GitHub applied but answered 502 no longer leaks the land lock (GST-1344)

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

* fix: pre-landing review fixes

Review-Finding: p1/specialist-batched#1 reader=testing
Review-Finding: p1/specialist-batched#2 reader=testing
Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes

Review-Finding: p2/outside-voice#1 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: troubleshooting covers a land lock push GitHub applied but answered 502 (GST-1344)

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-11-04 23:35:57 +00:00
Garry Tanandcapy-ai[bot] 4debdba226 fix(ship-queue): under merge: direct, land --pin --repair admits one repair while frozen and a green backstop on its main clears the freeze (GST-1354) (#4001)
* fix(ship-queue): under merge: direct, land --pin --repair admits one repair while frozen and a green backstop on its main clears the freeze (GST-1354)

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

* fix(ship-queue): direct freeze review fixes: unjudged gates keep the repair slot, a repair merged at another head gives way, leftover train freezes, notes re-read after red cases (GST-1354)

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

* fix(ship-queue): a standing direct freeze names the backstop rerun that gates main again; pin the leftover train freeze green clear (GST-1354)

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

* fix(ship-queue): backstop freeze rewrites by compare-and-swap, an active freeze always gates, land repairs only backstop freezes and never a release (GST-1354)

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

* test(ship-queue): the backstop helper clears GITHUB_RUN_ID; rewriteFreeze fails on a local notes write failure (GST-1354)

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

* chore: name the changelog fragment after the branch (GST-1354)

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

* fix(ship-queue): the backstop takes its run id from the CLI, not the environment, so its tests hold under Actions (GST-1354)

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-11-04 17:07:28 +00:00
Garry Tanandcapy-ai[bot] 7ba250ba60 fix(ship-queue): land --pin tests the merged tree on a stale base, with consent and a scrubbed env (GST-1316) (#3984)
* fix(ship-queue): land --pin refuses a stale base with QUEUE_LAND_STALE_BASE (GST-1316)

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

* fix: pre-landing review fixes

Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(captain): QUEUE_LAND_UNVERIFIED row names the main-moved-during-merge cause

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

* chore: name the changelog fragment after the branch

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>

* Revert "docs(captain): QUEUE_LAND_UNVERIFIED row names the main-moved-during-merge cause"

This reverts commit 343dd2bf16.

* feat(ship-queue): land --pin tests the merged tree on a stale base with land.merged_checks (GST-1316)

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

* fix(ship-queue): merged checks on a merged commit fail on a timeout or a tracked-file rewrite; no land key warns and lands

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

* fix(ship-queue): land.merged_checks need --allow-repo-commands and a scrubbed env; a no-key rerun checks the tree only; lock before merge

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

* fix(ship-queue): land --pin recovers its own leaked lock, takes --break-lock, refreshes the lock before merging; dry rerun verifies nothing

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

* fix(ship-queue): merged checks run git with hooks off and log to a file, so a lingering child cannot stall a passing check

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

* fix(ship-queue): merged checks stop at the timeout with SIGKILL, refuse a dependency change or a moved HEAD, and land re-reads the base policy under the lock

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

* docs(captain): land refusal rows cover a stale-base conflict and a main that moved after land's check

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

* test(ship-queue): a placeholder GH_TOKEN value the secrets scan does not flag

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-11-04 09:18:11 +00:00
Garry Tanandcapy-ai[bot] a66d2f460d fix(ship): keep review credit across base merges and docs commits; grant after a fix-check; second-pass loop exception (GST-1195) (#3970)
* fix(ship): a fix-checked path keeps its credit across a base merge that edits it; the docs audit carries a path whose branch patch is unchanged (GST-1195)

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

* fix(review): a recorded grant gets its one fix-check after a round-2 fix-check (GEVA-223, GST-1130)

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

* fix(ship): a targeted record carries across a plain docs commit; review_loop_exception.second_pass for a stop after the second full pass (GST-1195, TRUT-26, TRUT-7)

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

* test: type the docs-commit cases (typecheck:test ratchet)

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

* fix(ship): the docs-audit carry compares the checked tree, not HEAD; repin lib/review-depth.ts (replay GEVA-223)

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

* fix(ship): a binary or auth/security-worded docs commit does not carry a targeted record (review_loop_exception, #3970 round 2)

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

* docs: describe the GST-1195 bundle's shipped behavior (ship docs audit gst1195-da1)

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-11-04 04:35:24 +00:00
Garry Tanandcapy-ai[bot] e5366a52b7 fix(autoplan): export --public drops owner replies and redacts quoted owner words (GST-1243) (#3967)
* fix(autoplan): export --public drops owner replies and redacts quoted owner words, refusing what it can't redact (GST-1243)

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

* fix(autoplan): owner words in every deferral rendering, superseded replies, glued punctuation, short replies, echoed plan text (GST-1243 review)

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

* fix(autoplan): normalize markup, entities, escapes and format characters before matching owner words; each new run in an echoing reply is its own needle (GST-1243 review)

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

* fix: pre-landing review fixes

Review-Finding: p1/outside-voice#1 reader=outside-voice
Review-Finding: p1/outside-voice#2 reader=outside-voice
Review-Finding: p1/outside-voice#3 reader=outside-voice
Review-Finding: p1/outside-voice#4 reader=outside-voice
Review-Finding: p1/outside-voice#5 reader=outside-voice
Review-Finding: p1/outside-voice#6 reader=outside-voice
Review-Finding: p1/adversarial-native#1 reader=adversarial-native
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes

Review-Finding: p2/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* changelog: GST-1243 fragment names the review fixes

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-11-04 03:42:16 +00:00
Garry Tanandcapy-ai[bot] 9e826b2994 feat(release): versions at release under merge: direct (GSTA-258 L2 PR 2) (#3978)
* feat(release): versions at release under merge: direct (gstack-release-stamp open, restamp --release, land --pin on release/<version>; GSTA-258 L2 PR 2)

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

* fix(release): commit only the stamped files, leave no local release branch, reopen replaces the branch; regenerate doctor anchors

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

* fix(release): land a release head only on the main it was stamped on

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

* fix(release): review round — refresh notes before the release freeze check, check manifest/lockfile/CHANGELOG headings and every release output, branch names the stamped version, reuse an open release PR; restamp stays under 800 lines

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

* fix(release): round 2 — a deleted release output is refused, a release that merged onto a moved main is reported, branch-name test

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

* fix(release): released CHANGELOG sections must stay byte-identical, rerun land checks the stamped base, --bump refused with --release, open ignores fork PRs

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

* docs(release): name the release PR where docs said versions are set at every merge

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

* fix(release): a release that deletes a release output is refused by name, before the release tool runs

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

* fix(land): the release rerun reads the pin's parent after fetching the pin; tests for the rerun, the released-section guard and the fork filter

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

* docs(release): a release may not delete a release output; the release land rerun reads the pin's parent after fetching

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

* docs(release): drop the ship-policy.md re-audit sentences (docs risk accepted by GSTA-258; they go into the follow-up)

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-11-04 03:38:56 +00:00
Garry Tanandcapy-ai[bot] 56a800da98 feat: /runaway-stopper — detect, stop and prevent runaway threads and subagents (GST-1279) (#3975)
* feat(runaway-stopper): detect, stop and prevent runaway threads and subagents (GST-1279)

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

* fix(runaway-stopper): autoplan review fixes: input validation, exact /ship task-row meter at 100M, rotation hand-off of subagents and PR watches, bounded fetch program

Skill-Size: 0→6747 bytes (SKILL.md.tmpl)
Evidence: plan docs/evals/runaway-stopper-prereg.md measure_by 2026-11-24
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(ship-budget): describe the task-row reading without a literal thread_id this

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

* fix(runaway-stopper): ship review pass 1: DEFER holds rotation and a self-stop only, working-only defer, subagents file validation, scan exit kept, DRIVER and factory.md within their size budgets

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

* fix(runaway-stopper): ship voices: list limit clamp, allSettled fetch, waiting /ship and shipping descendants defer, unknown flags refused, GSTACK_SHIP_TASK_TITLE implies the task-row meter

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

* fix(ship): leave DRIVER.md unchanged; main left 21 bytes under its 12 KB cap

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-11-04 02:59:50 +00:00
Garry Tanandcapy-ai[bot] e09ea409f0 fix(ship): a second full preflight stops while this checkout's /ship run is open (GST-1204) (#3950)
* fix(ship-preflight): forward --timeout to Step 5's pregate (GST-1196)

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

* fix(ship): a second full preflight stops while this checkout's /ship run is open (GST-1204)

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

* fix(ship): a new /ship from the same harness replaces a stopped run's marker; a run the lease can't record stops (GST-1204 review)

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-11-04 01:32:57 +00:00
Garry Tanandcapy-ai[bot] 4ed1711d7e fix(outside-review): an unrecognized Verdict is unverified, numbered findings are counted (#3925) (#3946)
* fix(outside-review): an unrecognized Verdict is unverified, numbered findings are counted (#3925)

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

* fix(outside-review): read approvals and verdict spellings, skip steps in a no-findings reply, share the FINDINGS label (#3925 review)

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

* fix(outside-review): read a verdict line's inline code and reject caveated approvals (#3925 round-2 floor findings)

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

* fix(outside-review): the exact NO_FINDINGS verdict is clean; document consult verdicts as unverified (#3925)

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

* fix(outside-review): read verdicts from a view that unwraps inline code, reject a verdict with a question mark (#3925 fix-check)

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

* fix(outside-review): find the verdict line as main does; keep the recognized-verdict rule (#3925, narrowed)

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

* docs(changelog): plain sentence for the #3925 entry

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

* docs(codex): review-mode maps VERDICT: clean with FINDINGS: unspecified to check 4 (#3925 docs audit)

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

* Revert "docs(codex): review-mode maps VERDICT: clean with FINDINGS: unspecified to check 4 (#3925 docs audit)"

This reverts commit 48b817233d.

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-11-04 01:32:24 +00:00
Garry Tanandcapy-ai[bot] 0b19a366ca fix: version strings gstack names aren't public IPs; renderers install Chromium on first use; outside-voice role hint (GST-1204) (#3941)
* fix: version strings gstack names aren't public IPs; renderers install Chromium on first use; outside-voice role hint (GST-1204)

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

* fix: gstack-named exemption needs a release-shaped quad and a same-major range end; Chromium install time doesn't eat the render deadline (GST-1204 review)

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

* docs: changelog fragment and troubleshooting entry name the tightened gstack-version exemption (GST-1204)

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-11-04 01:31:37 +00:00
Garry Tanandcapy-ai[bot] a73184629f ubi-runner: recovery bundles, recover, and a dormant results sink (GST-1220) (#3961)
* test: failing-first recovery bundle and results sink tests (GST-1220)

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

* ubi-runner: encrypted recovery bundles, recover, --counted, and a dormant VM-side results sink (GST-1220)

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

* ubi-runner: bind bundles to their VM and owner, stretch the bundle secret, keep the last good sink snapshot, stop the pusher before the final push (GST-1220 review)

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

* ubi-runner: keep command words after -- in the run record; tests for the run record, counted reattach and input guards (GST-1220)

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

* docs: ubi-runner recovery troubleshooting covers counted reattach and tiered-verify reruns after SINK_FLUSH_FAILED (GST-1220)

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

* test: failing-first tests for the cross-family findings: runner-owned --pass names, a --sink-spelled option value, a corrupt bundle on counted reattach (GST-1220)

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

* ubi-runner: forward only caller-exported --pass names, copy run-record words while parsing, open the bundle before a counted reattach (GST-1220 cross-family read)

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

* test: --pass forwards the caller-exported value, not a same-named runner local (opt, src, sink) (GST-1220 fix-check)

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

* ubi-runner: --pass forwards the value captured from the caller environment at startup, never a live variable (GST-1220 fix-check)

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

* docs: ubicloud skill says --pass forwards the exported value from runner start and never the recovery key or sink URL (GST-1220 docs audit 2)

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-11-04 01:27:04 +00:00
Garry Tanandcapy-ai[bot] 5fdfa14904 fix(post): keep the PR's opening text and Capy badge; run ids in runs= lists aren't phone numbers (GST-1227) (#3949)
* fix(post): a full pr-body post keeps the opening text and badge byte for byte; run ids in runs= lists and actions/runs/ paths aren't phone numbers (GST-1227)

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

* fix(post): only a trailing Capy badge splits off; other marker blocks stay in their section; tighter run-id exemptions (GST-1227 review)

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-11-04 01:26:11 +00:00
Garry Tanandcapy-ai[bot] 26a4e59165 v1.95.0.0 feat(ship-queue): land --pin merges a READY PR at its own green head (merge: direct, GSTA-258 L2 PR 1) (#3973)
* feat(ship-queue): land --pin merges a READY PR at its own green head under merge: direct (GSTA-258 L2 PR 1)

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

* fix(ship-policy): keep gstack's policy on train until the merge key's release exists; regenerate doctor components; floor test

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

* fix(ship-queue): direct land fails closed without a merge base; stamping land refuses under merge: direct; Windows curation for the gh shim test

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

* fix(ship-queue): land --pin reads policy after fetching the base, fetches the pin before verifying, and tells cannot-verify apart from a mismatch

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

* docs(ship-policy): land --pin STAMPED row names .gstack/version-path

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

* test(ship-queue): the merge-key floor test simulates its restamp on a tentative constant, so it holds after the 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-11-04 00:03:30 +00:00
Garry Tanandcapy-ai[bot] 2a368135de v1.94.41.0 fix(ship): receipt counts bind by finding id, scoped re-check, lighter READY, head= on the result line (GSTA-258 L4) (#3926)
* fix(ship): receipt counts bind by finding id, every run kept, scoped re-check after a refused carry, READY tail, head= on the result line (GSTA-258 L4; GST-1136, GST-1168, GST-1179)

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

* fix(ship): goldens, head= in the base-red line test, Severity field after a closing quote (ggstack#71); repin ship/sections/review-army.md under GST-508+GST-464+GST-967+GSTA-258-L4 (brief-identity no-loss check: every cut brief unchanged)

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

* fix: pre-landing review fixes (J1 never re-checks a legacy receipt, a cut path walk or moved base context; legacy READY asks for the cross-family read)

Review-Finding: p1/specialist-batched#1 reader=security
Review-Finding: p1/specialist-batched#2 reader=testing
Review-Finding: p1/red-team#1 reader=red-team
Review-Finding: p1/red-team#2 reader=red-team
Review-Finding: p1/red-team#3 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (Step 11: re-check refuses binary paths and packets over 64 KB; fingerprint trailers bind findings with a ledger_id; the runs fence closes only on its own line)

Review-Finding: v/outside-voice#1 reader=outside-voice
Review-Finding: v/outside-voice#2 reader=outside-voice
Review-Finding: v/adversarial-native#1 reader=adversarial-native
Review-Finding: v/targeted#1 reader=targeted
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs: J1 re-check eligibility names every refusal (review fixes)

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

* test: explicit timeouts on the re-check and result-head CLI tests (each spawns several git and bun runs; the carry tests ran past bun's 5 s default locally)

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

* ship: trim 11 skeleton bytes so the merged tree fits the 61,420 cap (GSTA-258 L4)

The rule 19 merge of main 1ccab0d8 put #3929's push-guards wording (61,418 on
main) together with J1's head=<sha> in the GSTACK_RESULT line, measuring 61,429.
Three rewordings beside that line bring the skeleton back to 61,418; the branch
ledger entry drops by 11 and the ship goldens are regenerated.

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-11-03 22:35:15 +00:00
Garry Tanandcapy-ai[bot] f8085aa0e4 v1.94.39.0 fix(ship): base-side lines don't count toward the scoped-review section limit (GST-1226) (#3955)
* fix(ship-patch): only the branch's own lines count toward the scoped-review section cap (GST-1226)

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

* fix(ship-patch): a base change past 2,000 lines counts in full; drop the text-matched context predicate (GST-1226 review round 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-11-03 20:21:34 +00:00
Garry Tanandcapy-ai[bot] 95806d002f v1.94.38.0 fix(ship-receipt): carry a stamp file back at the base after a changelog-fragment conversion (GST-1210) (#3937)
* fix(ship-receipt): carry a stacked PR's receipt after its parent squash-merges into main (GST-1199)

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

* fix(ship-receipt): a commit with no product change is no landed stack parent (review fix, GST-1199)

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

* changelog: name the fragment by the branch slug (GST-1199)

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

* docs: troubleshooting names the base-written stacked carry (Step 14.5 audit, GST-1199)

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

* test: failing-first carry cases for stamp-file reverts and ported harness pins (GST-1210)

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

* fix(ship-receipt): carry a stamp file back at the base and a byte-for-byte ported pin entry (GST-1210)

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

* fix(ship-receipt): review fixes: a pin needs exactly one naming map key; stamp-file sides compare object ids (GST-1210)

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

* fix(ship-receipt): drop the pin-entry guess; stamp-file sides compare ls-tree entries (GST-1210, GSTA-36 ruling A)

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

* test: stage the mode flip with update-index so the control holds on Windows (GST-1210, run 41626229324)

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-11-03 20:09:15 +00:00
Garry Tanandcapy-ai[bot] 72761513d3 v1.94.32.0 fix(ship-queue): a RED screen names its rule-case reds, not just panel reds (GSTA-258 L8) (#3958)
* fix(ship-queue): a RED screen names its rule-case reds, not just panel reds (GSTA-258 L8, run 41662815506)

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

* test: register the run 41662815506 screen-verdict fixture as free

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

* docs(changelog): split a sentence in the L8 fragment

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

* docs(troubleshooting): QUEUE_SCREEN_RED names rule cases from the report's failure lines

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-11-03 18:44:36 +00:00
87801b6da7 v1.94.31.0 fix(browse): Playwright 1.64.1 (Chromium 156) for the macOS sandbox-escape CVE; handoff honors GSTACK_CHROMIUM_PATH (#3947)
* test(browse): failing tests for #3907 (handoff ignores GSTACK_CHROMIUM_PATH; bundled Chromium predates CVE-2026-106378 fix)

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

* fix(browse): handoff honors GSTACK_CHROMIUM_PATH (#3907)

handoff() always launched Playwright's bundled Chromium, so a GSTACK_CHROMIUM_PATH browser dropped back to the bundle at handoff. It now passes executablePath like launch() and launchHeaded(), skips the poisoned-bundle probe and XProtect heal for a custom path, and never loads the extension into a build that bakes it in.

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

* fix(deps): Playwright 1.64.1 (Chromium 156) for CVE-2026-106378 (#3907)

Playwright 1.62.1 bundled Chromium 151.0.7922.34, which lacks the macOS GPU-process TCC fix (Chromium 0c2f3e54b265, crbug.com/507596239). 1.64.1 bundles 156.0.8078.4, which has it. The playwright-core patch is regenerated from our 1.62.1 patch: the launch windowsHide and TcpPortRandomizationWin hunks carry over unchanged; the taskkill hunk is dropped because 1.64 passes windowsHide there upstream.

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

* chore(pregate): map patches/** to the playwright-core patch test

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

* test(browse): name the 1.64.1 patch file in the TcpPortRandomizationWin check

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

* docs(changelog): fragment for Playwright 1.64.1 and handoff GSTACK_CHROMIUM_PATH (#3907)

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

* docs(troubleshooting): GSTACK_CHROMIUM_PATH covers headed browse and handoff

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

* test(browse): the retired 1.62.1 patch stays deleted

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: merit-blake <265362871+merit-blake@users.noreply.github.com>
2026-11-03 18:34:14 +00:00
Garry Tanandcapy-ai[bot] ade35bc813 v1.94.29.0 R56: everything in gstack earns its place (principle, evidence gates, inventory) (#3837)
* eval-plan: a no-gstack arm needs masking, install and audit lines

prereg --check now refuses a loaded comparison whose ## No-gstack arm
section lacks masking:, install: or audit:, or says none for one of them
(PREREG_NO_GSTACK_ARM). On Capy, run agents inherit the instruction to load
the user-drive gstack skill, so the arm hides both Capy drives, checks that
no gstack is installed, and audits drive reads; an arm that read a gstack
skill file is contaminated and gets zero credit (TESTING_INTERNALS.md
#no-gstack-arm). The prereg template, /eval-plan, troubleshooting and the
two passing prereg fixtures carry the new lines. eval-plan's paragraph was
dieted to hold its context-budget ceiling.

Evidence: safety: keeps the no-gstack control uncontaminated (Captain order, FOUN-32 via GGST-6)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* inventory: the R56 evidence ledger, gstack-inventory and skill-bill EVIDENCE

docs/inventory/evidence.json holds one row per inventory key: the skill
folders discoverTemplates() finds (root skill as gstack, symlinked folders
excluded) plus seven shared parts, 71 keys. lib/inventory.ts validates each
row by its status's own fields, with named codes (LEDGER_*), and joins the
ledger with lib/context-bill.ts buildBill. bin/gstack-inventory writes
docs/inventory.md, --check validates (exit 1 with codes), --json prints.
Paid dispatches per run for /ship and /autoplan are quoted from their own
docs and found by line, so a moved citation fails --check
(INVENTORY_SOURCE_MISSING). Every current row is grandfathered and seeded
from GEVA-2's table (org-gstack-gbrain/research/gstack-part-evidence.json):
in-flight fair tests and proposed registry rows as plans, earlier unfair
results under prior with why (stub, unmasked, ceiling, ...), five safety
rows. gstack-skill-bill prints the skill's EVIDENCE line.

Evidence: plan none (owner ruling R56, GST-914); the ledger itself is the measurement record
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* ETHOS 9, Earn Its Place: factory, /write-skill and /autoplan carry it

Garry, 2026-11-02: "Also work this principle of only include it if it is
beneficial and good into gstack". ETHOS.md principle 9 states the rule, the
fair test (claude_code preset, frontier models per R54, masked no-gstack
arm), the R48 Why-null cycle, the safety exception, and measure biggest
first, linking docs/inventory.md. factory.md item 8 cites it, trimmed
elsewhere to 3,298 of 3,300 bytes with no rule dropped. /write-skill's edit
ladder step 2 is the evidence rule and section 4 adds the Evidence: commit
line. /autoplan's CEO phase lists each part a plan adds to gstack with its
evidence or owned, dated plan; two redundant lines went to keep autoplan
under its size pins (pins lowered by 17). CONTRIBUTING.md "Adding a new
skill" and docs/skills.md point at the ledger.

Skill-Size: 3273→3666 bytes (write-skill/SKILL.md.tmpl)
Skill-Size: 12738→12721 bytes (autoplan/sections/ceo-phase.md)
Evidence: plan none (owner ruling R56, GST-914); write-skill and autoplan rows stay grandfathered untested
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fixup! inventory: the R56 evidence ledger, gstack-inventory and skill-bill EVIDENCE

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

* inventory: list the evidence table's other names and its unmapped rows

Ledger rows carry aliases (the name GEVA-2's table uses where it differs from the key, such as upgrade for gstack-upgrade), and docs/inventory.md lists them beside the installed-name rule. Unmapped rows are labeled as evidence-table rows, and the ranking notes that a skill's on-demand files can also be a shared row's.

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

* docs: the first inventory snapshot and the R56 changelog fragment

docs/inventory.md is generated by bin/gstack-inventory at the previous commit: 71 parts ranked by load per run, 0 helps, 0 no-effect, 0 hurts, 16 untested with a plan (4 fair tests under way, 12 proposed), 50 untested with plan none, 5 safety.

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

* inventory: investigate's step procedure is a fair-test CUT-CANDIDATE (GST-814)

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

* docs: the inventory snapshot after investigate's no-effect row

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

* inventory: only the seeded backlog may be grandfathered, so a new part's row is checked (review fix)

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

* inventory: devex-review and retro name their GEVA-2 registry rows (R56-11, R56-12)

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

* docs: the inventory snapshot after the review fixes

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

* inventory: a concrete plan is a path, gstack-inventory never writes into a gstack install, and the ledger checks aliases, r48 and prior.why (review fixes)

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

* inventory: investigate's no-effect row notes that only Opus 5.5 was measured

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

* docs: the inventory snapshot after the review fixes

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

* changelog: R56 counts after investigate's row; grandfathering and the install guard

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

* test: register inventory-grandfathered.json as a free fixture

free-suite (1) at e56d3312c failed FREE_FIXTURES inventory: the pinned grandfather fixture from d0b3028b5 had no paid touchfile and no FREE_FIXTURES entry. Its only reader is test/inventory.test.ts.

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-11-03 17:08:30 +00:00
Garry Tanandcapy-ai[bot] 1ccab0d8bc v1.94.24.0 fix(harness): start hook leaves a fresh harness config alone, keeps the profile's own OPENCLAW_CONFIG_PATH, reads status off PATH (GST-778) (#3794)
* fix(harness): start hook waits for the harness config, keeps the profile's own OPENCLAW_CONFIG_PATH, reads status from config off PATH (GST-778)

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

* fix: pre-landing review fixes

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

* fix: pre-landing review fixes

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

* docs(changelog): recovery note covers every release before this fix

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

* docs(hosts): turning the hook off in a profile with no harness config runs no harness command

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-11-03 15:41:57 +00:00
Garry Tanandcapy-ai[bot] b3e9e5d32c v1.94.23.0 fix(pregate): strays matches only documented scratch names; literals ignores a named literal the branch only adds (GST-1211) (#3944)
* fix(pregate): strays matches only the documented scratch names; literals ignores a named literal the branch only adds (GST-1211)

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

* fix(pregate): literals reports every removed value when the name still has one, so a delete-plus-edit keeps the edited site's old value (GST-1211 review)

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-11-03 15:32:05 +00:00
Garry Tanandcapy-ai[bot] 2f9d11a59d v1.94.19.0 fix: a finished /ship's workflow lease no longer blocks gstack-upgrade (GST-1205) (#3932)
* fix: gstack-skill-end releases its run on the workflow lease, so a finished /ship stops blocking gstack-upgrade (GST-1205)

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

* fix: a hold without --run survives a sibling's release, and an orphaned run ages out on its own (GST-1205 review)

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

* fix: a touch whose identity read comes back empty keeps the recorded identity and its runs (GST-1205 review)

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

* fix: keep an unreadable identity unknown, keep a converted hold's age, and document each run's 120-minute bound (GST-1205 review round 2)

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

* fix: a SESSION_ID without urandom falls back to the start's pid, so two same-second runs keep separate lease entries (GST-1205 review round 2)

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-11-03 14:30:58 +00:00
Garry Tanandcapy-ai[bot] d2e63181d7 v1.94.17.0 ci-carry: guard carry, jobs-mapped lanes, aliases, per-file carry of runner-skipped files, path-skipped jobs (GST-1186, GST-1189, GST-1190) (#3929)
* feat(pregate): a guard that already passed at this tree carries from CI or the ledger (GST-1186)

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

* feat(ci-carry): jobs-mapped lanes, aliases, narrow-lane counts, --simulate proof, policy-base check on carried (GST-1189, GST-1190)

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

* fix(ci-carry): a file whose every test skipped on CI is not carried; tree.json records skipped_files (GST-1190)

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

* feat(ci-carry): path-skipped jobs count only under an unchanged gate; find --policy-from head --simulate (GST-1190)

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

* ship: name the pre-push guards in Step 17 and the early push (moved from #3923 per GSTA-258)

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

* ci-carry: per-file lane carry for runner-skipped files; review fixes (gate inputs, passed ignores CI rows, simulate consent, pull_request-only skips, guard not-owed)

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

* ship: Step 17 names the pre-push guards without a code this branch cannot print

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

* pregate: gstack's bun run test lane runs its runner-skipped files with per_file

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

* ci-carry: a per_file remainder must run tests here and the carried runs must still stand (l6c-p2)

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

* ci-carry: read record-ci from its own last record line; the remainder's count must come from this run's row (l6c-p2 red-team)

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

* test(ci-tree-reuse): type the skipped_files fixture for the test typecheck ratchet

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

* Revert "pregate: gstack's bun run test lane runs its runner-skipped files with per_file"

This reverts commit fafbae5b9b.

* ci-carry: ship the skipped_files reader inert; gstack's writer and per_file move to the adoption PR; Step 17 keeps its refs/heads marker

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

* docs: guard carry, per_file and the too-old message in pregate and troubleshooting (docs audit l6cdocs2)

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

* gstack-evidence record-ci: recheck the working tree after the post-remainder run recheck (#3929 second fix-check)

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

* windows-curation: exclude test/ship-ci-carry.test.ts like its ship-bin-fixture siblings (the path-scoped Windows check runs it at its first spawn)

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-11-03 14:14:50 +00:00
Garry Tanandcapy-ai[bot] bf2bcf14b0 v1.94.15.0 fix(ship-receipt): carry a stacked PR's receipt after its parent squash-merges into main (GST-1199) (#3928)
* fix(ship-receipt): carry a stacked PR's receipt after its parent squash-merges into main (GST-1199)

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

* fix(ship-receipt): a commit with no product change is no landed stack parent (review fix, GST-1199)

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

* changelog: name the fragment by the branch slug (GST-1199)

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

* docs: troubleshooting names the base-written stacked carry (Step 14.5 audit, GST-1199)

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-11-03 11:11:25 +00:00
Garry Tanandcapy-ai[bot] 8d276f9e31 v1.94.14.0 fix(review): review_exclude_paths keeps native binaries, NUL-bearing code and attribute-binary secret lines; exact --review-exclude docs (GST-972) (#3902)
* fix(review): review_exclude_paths keeps native binaries, NUL-bearing code and attribute-binary secret lines; exact --review-exclude docs (GST-972)

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

* test(review): GST-972 key-file fixture holds no key header the credential scan flags

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

* fix: pre-landing review fixes

attributeBinaryLines reads attribute-binary files in one git diff per argument-byte chunk instead of one per file (red-team#2). The changelog and ship-policy row say readers' own diffs still show such a kept file as binary (red-team#1, deferred as #3905).

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

* docs: the native-magic check covers files git reports as binary; attribute-text files are #3910

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

* chore: changelog fragment named for the branch

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

* docs: ship-policy config row names content binaries and keeps native ones (Step 14.5 audit)

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

* docs: drop the post-review ship-policy sentence; #3910 stays in the changelog and PR notes

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

* test(review): kept reasons typed as literals for the test typecheck ratchet

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

* fix(review): sniff executable magic on every file git's own bytes call binary, whatever .gitattributes says; exact review_exclude docs (GST-972 round 2)

bytesBinary reads git diff --numstat with attributes from the empty tree, so a branch's '*.png diff -binary' cannot make an ELF read as text and skip the magic check (#3910). Adds 64-bit universal Mach-O magic. ship-policy's key row lists every kept class; troubleshooting and the write/queue refusal lines say a review_exclude mismatch compares the --review-exclude argument, not the review ledger.

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

* fix(ship-receipt): carry refusal names the --review-exclude digest, not what reviewers read

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-11-03 11:01:13 +00:00
Garry Tanandcapy-ai[bot] b42ad1e300 v1.93.42.0 fix(stamp): name branch lines by position; carry and finish accept a kept VERSION claim (GST-979, GST-980) (#3889)
* fix(stamp): name branch lines by position; carry and finish accept a kept VERSION claim (GST-979, GST-980)

BranchSide carries the positions of the branch-added lines and stampOnlyLine takes the removed line position, so a base line whose text duplicates a branch line keeps the old-version floor. At equal versions only the branch own lines may move. stampOnlyText and stampedFiles accept a kept claim for those lines, and the carry leaves a stamp file out of the product comparison when its only change since the reviewed head is a stamp on the branch own rows and the base did not touch it. Failing-first: all five new tests fail on main fc292e22f.

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

* fix: pre-landing review fixes (GST-980 carry reads the stamp file line by line at the branch's positions, and keeps its mode)

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

* docs(changelog): GST-979/980 entry counts the seven tests

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

* docs: the receipt carry follows a stamp on the branch's own rows (GST-980)

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

* docs: keep docs/ship-policy.md at the reviewed text; its GST-980 sentence already states the carry rule

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

* Revert "docs: keep docs/ship-policy.md at the reviewed text; its GST-980 sentence already states the carry rule"

This reverts commit f926ccb0c2.

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-11-03 03:34:35 +00:00
Garry Tanandcapy-ai[bot] 106fd39446 v1.93.41.0 Codex outside reviews report their token usage (#2948) (#3729)
* outside-review-result: one Codex usage parser and an OUTSIDE_USAGE line (#2948)

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

* docs: troubleshooting names the OUTSIDE_USAGE line (#2948)

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

* test: the generated Codex plan-review invocation prints OUTSIDE_USAGE (#2948)

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-11-03 03:24:35 +00:00
Garry Tanandcapy-ai[bot] f47d19dd21 v1.93.35.0 fix: pregate no longer kills a quiet test suite that is busy working (GST-1095) (#3899)
* fix(pregate): a quiet suite that is busy on CPU is not stalled (GST-1095)

The stall timer looked only at log growth, so a parallel check.sh that
prints nothing for 9 minutes while working ended PREGATE_STALLED (FOUN-63).
supervise now samples the process group's CPU time each second and treats
growth of at least a tenth of wall time as liveness. An idle hang still
stalls; a hang that burns CPU is left to --timeout.

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

* fix(pregate): stall wording says what was measured; a failed CPU read skips one sample; ps -S on BSDs (review pass 1)

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

* fix(pregate): a failed CPU read waits for the next sample; docs wording (fix-check)

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

* changelog: GST-1095 fragment

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-11-03 01:59:44 +00:00
Garry Tanandcapy-ai[bot] 14d7414af3 v1.93.33.0 wave(review): #3705 #3744 #3745 #3764 #3765 #3795 (#3852)
* fix(ship): base merges, adjacent base edits, test-only and audit-requested fixes no longer force a second review loop (GST-407, GST-384, GST-391)

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

* ship driver: trim two phrases for headroom with #3662

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

* ship driver: keep the Next steps heading phrase the handoff check reads; trim elsewhere

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

* test: regenerate ship goldens

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

* fix: pre-landing review fixes

comparePath returns same only when every hunk sits where the base change puts it (patch-ids ignore positions) and treats a file-mode change as changed; the scoped-review packet says when a fence is truncated; --docs-result must be the posted audit's result; the --context-reviewed record goes beside the packet, outside the worktree. Negative controls for each.

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

* fix: pass-2 review fixes

A test edit routes as tests= only when it adds lines with no gate tag; a removed or changed line or an unreadable test diff goes through the full loop. Diffs skip textconv. A hunkless patch (binary, empty, mode-only) is same when its patch-id matches. Without --reviewed-base test files route as before. finish's packet path and attempt's state directory have fallbacks.

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

* fix: Step 11 review fixes; a version-only stamp_files edit after review is release metadata (GBRA-251)

gateEditedPaths reads removed lines only inside hunks; carry refuses when a path listing fails; docs freshness stops on a failed listing; attempt counts an unreadable state file. releasePaths includes stamp_files paths whose edit is a version swap under stamp_patterns.

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

* fix: no test edit skips review; guard packet writes; exclusive attempt state

A test-only edit with no gate tag gets the scoped fix-check of its test hunks instead of a lanes-only rerun. Packet write failures print a STOP or RECEIPT_CARRY_REFUSED. attempt's allowance uses an exclusive create.

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

* fix: attempt prints gstack's install command; carry checks the product diff outside context paths

The attempt STOP no longer echoes the audit child's fix text. A scoped-review carry now requires the product patch-id without the context paths to match at both heads.

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

* fix: oversized packets take the full loop; exact --docs-requested match; name-only test globs only in test dirs

A scoped-review packet section over 200 lines sends that path to the full loop instead of a truncated packet. The docs-result path match is exact. test_*.py, *Test.java and similar count as test code only under a test directory.

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

* docs(unattended): carry's scoped-review refusal and what it keeps

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

* docs: carry's scoped-review route in ship-policy, review-policy and troubleshooting (docs-a-1)

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

* test(windows): curate ship-rereview-triggers out of the Windows lane like ship-release (run 41193336209)

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

* fix(review-log): record a notes-only /ship pass clean; name the cause and repair when a pass's tree moved (GST-430)

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

* fix(receipt): carry and write handle PRs with thousands of files; tree receipt fails closed on a failed diff (GST-448)

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

* fix(ship): preflight routes RECEIPT_CARRY_SCOPED_REVIEW to the scoped review; carry --dry-run writes no packet (GST-442)

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

* docs(ship): Step 1.4 and Step 16 route the scoped-review refusal and the --docs-requested fix; trims keep the cap (GST-442, GST-444)

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

* fix: /ship review pass 1: notes-only floor, scoped carry order, named temp and diff refusals

- A notes-only pass is recorded clean only when every finding is fixed, or noted or deferred below the
  blocking floor (never CRITICAL or blocking), by its logger-stamped action, and the findings account
  for the claimed issue and critical counts (GST-430).
- The preflight scoped carry route commits and pushes the base-merge fix before writing the packet (GST-442).
- patchId refuses by name on an unwritable TMPDIR; the tree receipt names why its diff failed (GST-448).
- Step 16 stage 3 spells out --docs-requested with its --docs-result (GST-444).

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

* test: pin the Step 16 --docs-requested route with its --docs-result

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

* fix: a claimed clean review row with a logger-stamped open gate finding reads UNVERIFIED (red-team, pass 1)

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

* fix: Step 11 findings: gate rows from --findings are stamped, one open rule, stale patch-id dirs swept

- deriveFromFindings stamps gate rows with the session kind before deriving status, so a findings file cannot
  dispose of a gate finding the unattended logger forces open (outside-voice#1).
- reviewFreshness reads a claimed row's findings with isOpenByAction, the rule the notes-only rewrite uses;
  noted and deferred clear a finding only when it is marked blocking: false and is not CRITICAL.
- patchId sweeps gstack-patch-id-* directories over an hour old that a killed carry left in TMPDIR.

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

* fix: Step 11 round 2: stamped-open gates win over status and disposition; resolved gate, skipped and below-floor actions stay CURRENT

- isOpenFinding treats action 'open' (the logger's forced-open stamp) as open before a row's status or disposition.
- reviewFreshness flags a claimed clean row only for an 'open' action or a CRITICAL or blocking deferral or note, so
  interactive kept and restored gates, skipped advisories and INFORMATIONAL deferrals read CURRENT as before.

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

* fix: carry dry run offers the scoped route last; patch-id diff under the git dir; changelog matches the review-log floor

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

* fix: a claimed clean review row with any unresolved non-gate CRITICAL finding reads UNVERIFIED (pass 2 red-team)

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

* docs: carry dry-run scoped route, patch-id directory, tree-receipt refusal (docs-d-1 audit)

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

* fix(ship): Step 3 names merge conflicts in its STOP sentence again (ship-workflow-clarity pin)

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

* fix(tree-receipt): keep the gated-to-current diff at the file helper timeout (60 s); pregate literals check

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

* test(carry): large-diff fixture sets core.longpaths so Git for Windows can add its long receipt paths (windows-free-shard 1, run 41210080055)

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

* fix(review): a stale local base branch yields to its origin twin in gate-diff and diff-scope (GST-462)

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

* fix(ship): Step 11 saves the targeted record and the receipt writes carry it; Step 9 clears it (GST-464)

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

* changelog: GST-464 and GST-462

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

* fix(review): pass 1: ahead and diverged labels, diff-scope needs shared history; preflight refreshes origin/<base> and stops on a diff far beyond the PR (GST-462, HARN-15)

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

* fix: pass-2 review fixes for base twin, prSized stop and targeted record

Resolve the tracking twin by refs/remotes/<remote>/<ref> and only for a bare
branch name, keep a local base that is ahead or diverged, quote the prSized
stop's base and name the fork case, and have every Step 9 entry create,
exclude and clear .gstack/tmp/targeted.json.

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

* fix: origin's tracking base wins whenever related; prSized lower bound

The fix-check found that keeping a local base ahead of origin left unpushed
base commits out of the gate scan while review-plan listed them. The tracking
branch now wins whenever it shares history with HEAD, an explicit origin/main
reads refs/remotes/origin/main, the preflight also stops when the diff lists
fewer files than the PR, and the Step 9 exclude line survives a missing
.git/info and an exclude file without a final newline.

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

* changelog: the tracking-ref claim holds while the tracking branch exists

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

* test: repin the two ship section briefs under no-loss replay GST-464

GST-464 brief-identity check: every reviewer brief lib/review-brief.ts cuts
from ship/sections/review-army.md and adversarial.md stays byte-identical to
the bodies the L and GST-257 replays admitted; only lead instructions outside
the cut spans changed. The check is a test CI runs.

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

* ship: keep Step 9's PASS_HEAD sentence whole; repin review-army under GST-464

The targeted-record line follows the PASS_HEAD/RANGE_BASE sentence instead of
splitting it (test/review-fix-range.test.ts pins that sentence). The brief-body
check still holds: every reviewer brief is byte-identical.

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

* fix: restore bin/gstack-ship-receipt after the main merge

The merge commit b10e2db wrote a truncated copy of the file. This is the
three-way merge of both sides with the refused() union: main's codes plus
RECEIPT_CARRY_SCOPED_REVIEW.

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

* review-collect: narrow the consumer scan and give it one 300 s deadline (GST-544)

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

* review-collect: keep the consumer scan deadline under the 180 s plan timeout (review fix)

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

* review-collect: plain paths under --literal-pathspecs; whole-millisecond timeout override (review fix)

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

* review-collect: whole-tree grep for non-UTF-8 names, no argument spread, name spawn errors (review fix)

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

* review-collect: cap the consumer grep output at 256 MB across calls; per-scan deadline wording (review fix, cycle 4)

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

* review-collect: read a missing spawn status as null (Bun 1.4.2 returns undefined on ENOENT)

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

* test: review-collect whole-tree helper reads a null status as -1 (typecheck:test ratchet)

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

* review-bots: /review and /ship triage every configured review bot, not only Greptile (#3122)

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

* fix: pre-landing review fixes (gh before 2.48 pages without --slurp; driver routes Step 10; tests for guards, review-bot fence, REMOTE_SLUG owner)

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

* fix: drop the review-bot fence test that could not fail (the tool-fence WARN degrade is unreachable: placeholder spans are skipped first)

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

* fix: Step 11 review fixes (record by comment id so a filename never reaches a shell; lookup failures are errors; tojson pages; longest bot prefix wins)

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

* fix: pass-2 review fixes (record refuses * paths, colliding ids and a missing fetch dir; parent requires id and dir; botOwning doc)

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

* review: classify the PR type and always check repo conventions (#356)

The checklist now opens with a PR-type line (application, CI/infra,
scripts/tooling, docs-only or mixed). Application and mixed diffs run
every category; other types always run five categories, including the
new Repo Conventions & Platform Fit, and report the rest as not
applicable in one line instead of skipping silently.

No-loss replay: GSTA-224 H1 preregistered no-loss run (run id
gsta224-h1-20261031, Opus 5.5, 81 calls, $9.53) against main's checklist
with a no-gstack arm; every preregistered bar passed. The
review/checklist.md pin in test/review-packets-removed.test.ts moves to
a32963ef with replay 'GSTA-224 H1'.

Refs GSTA-224

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

* review-bots: allowlist the record placeholders and match Step 10's id rule in tests

The record fence uses <comment-id>, <fix|fp|already-fixed> and <category>,
each with an enum or numeric grammar; <greptile-dir> becomes <bot-dir>.
review/greptile-triage.md also lists every REVIEW_BOTS skip reason.

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

* docs: review-bot triage covers every configured bot (#3122)

README, CONTRIBUTING, the contributor reference and standalone-binaries
name gstack-review-bots and the review-bot fence; TODOS drops the #3122
item; the changelog fragment covers record-by-id and lookup errors.

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

* test: the PR-type test also pins the compose, Terraform and README/CHANGELOG phrases

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

* test: follow the review-bot rename in the remote free tier's three reds

The cross-skill consistency judge describes review-bot-history.md and its
record helper; the tracker-guard exemption for the removed raw Greptile
fetch in review/greptile-triage.md is dropped (the fetch now lives in
gstack-review-bots, whose bodies still reach context only through
gstack-issue-guard); the Step 10 PR-check test expects 'Review bots: not
run'. HARNESS_VERSION stays 6: skill-fixture.ts and llm-judge.ts are
recorded non-behavioral for every other case.

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

* test: keep the cross-skill judge's rubric to one renamed bullet

Name review-bot-history.md beside the older greptile-history.md so the
calibration corpus still matches, and keep the REMOTE_SLUG bullet. One
live 3-sample panel at this tree: consistent 3/3, scores 4/4/4.

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

* changelog: H1 fragment passes prose lint

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

* changelog: name the H1 fragment after its branch; TODOS drops #356

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

* docs: /review's PR type step in docs/skills.md (#356)

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

* ship-policy: review_exclude_paths key and loadPolicyAt (GST-508)

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

* review: apply the base policy's review_exclude_paths and the reviewer diff ceiling (GST-508)

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

* receipt: bind review_exclude in write, carry and the queue (GST-508)

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

* docs, tests and changelog for review_exclude_paths (GST-508)

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

* fix: pre-landing review fixes (binary by bytes, links kept, untracked files out of the selection)

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

* fix: keep binary files at code paths under review_exclude_paths

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

* docs: name the reasons that keep a binary file under review_exclude_paths

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

* fix: keep every review_exclude_paths candidate when the gate scan is unknown; docs example names its version

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

* test: keep the NUL fixture clear of the sync-spawn tripwire

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

* changelog: split the ceiling sentence

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

* fix: keep a live binary file whose bytes cannot be read; tests render outside voices from a clean checkout and read the ship fixture text

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

* test(review-exclude): explicit +x for the census script; skip the chmod-000 read case on Windows and root

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

* refactor: move loadPolicyAt to lib/ship-policy-at.ts so lib/ship-policy.ts stays under the 800-line module cap

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

* fix: refuse a base that contains HEAD; skip a self-pointing origin/HEAD (GST-774)

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

* chore: regenerate gstack-doctor-components.sh for BASE_CONTAINS_HEAD

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

* fix: land resumes a merged merge-only PR instead of refusing BASE_CONTAINS_HEAD (GST-774 review)

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

* docs: changelog fragment for GST-774

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

* docs: troubleshooting names diff-scope base_contains_head and the self-pointing no_base case (GST-774 docs audit)

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

* test: repin the reviewer briefs to GST-508's no-loss-tested bytes

ship/sections/review-army.md, ship/sections/adversarial.md and lib/review-depth.ts now pin
the bytes the GST-508 preregistered no-loss replay ran at ef2760f (handoffs/GSTA-202/noloss-results.md
in the GStack Minder drive): Arm V 33/41 vs R 33/41, delta 4, exact sign flip, p_NI 0.0279 (pass).
The merge of main 83ae96e leaves these three files byte-identical to ef2760f, and an Arm P unit
(3593) renders byte-identical briefs at ef2760f and at the merge.

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

* fix: GST-774 review round 1 — merged resume depth, aliased and detached PR checkouts, develop/trunk defaults

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

* ship: Step 20 says a metrics row, keeping DRIVER.md at 12 KB after the main merge

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

* test: ship-parts resend case leaves room for the first phase-3 part after the Step 9 targeted-record sentence

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

* fix: /ship delivers review/checklist.md in two parts so checklist v1 fits the 24576-byte part cap (#3670)

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

* changelog: drop the GST-407 and GST-430 fragments, already released on main (stacked history)

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

* wave review-53cfb5bfe011: lib/ship-policy.ts back to 800 lines (module-size ratchet after merging #3744 and #3795)

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

* wave review-53cfb5bfe011: /ship pass 1 fixes

- lib/ship-receipt-depth.ts: a merged resume (land after a true merge) no longer recomputes the review_exclude digest over the emptied range, so it lands instead of RECEIPT_INVALID (failing-first land test with review_exclude_paths active).
- bin/gstack-review-dispatch render: a standalone targeted render under an active review_exclude_paths refuses and points at the pass manifest voices stage, instead of writing a brief with no selection that leaves verify dirty (failing-first test).
- test/default-base.test.ts: #3795 expectations follow main R51 depth (light for an 80-line code diff; runtime_lines=80 still proves the real base).
- test/review-dispatch.test.ts: the GST-897 fingerprint test renders from the clean checkout, like its neighbor, because CI rebuilds the tracked lib/diagram-render/dist/diagram-render.html and the reviewer diff ceiling refused the ROOT render.

* wave review-53cfb5bfe011: /ship pass 2 fixes

- lib/review-exclude.ts: binaryContent reads each blob's first 8,000 bytes (git cat-file blob, 8 KB buffer) instead of one --batch read capped at 256 MB, so head mode (receipt, carry, queue) and the plan agree past 256 MB of blobs; an unreadable blob is kept, as in live mode. Failing-first test with two 270 MB blobs.
- lib/review-bots.ts: a file-level bot review comment (subject_type file, no line position) is triaged instead of read as outdated. Failing-first test.
- test/ship-queue-land.test.ts: the merged-resume exclusion test runs its gate scan under the fixture state root, not the real home (CI free-suite 6 home containment).

* fix: merge follow-ups for main 3d99c22: origin/* stays qualified in diff-scope's twin step, retro skeleton back under its cap, combined no-loss pin GST-508+R51+GST-911

* fix(review): receipt write gate-scans whenever the base declares review_exclude_paths; collectLive never re-qualifies origin/<base> (#3852 /ship red-team#1, outside-voice#1)

* test: the docs-only receipt digest test keeps its gate scan out of the real home (free-suite shard 5 FREE_SUBSHARD_REJECTED)

* fix(merge fc292e22f): tentative REVIEW_EXCLUDE_KEY_VERSION, classify targeted.json, render main's new outside-voice test from a clean checkout

- lib/ship-policy.ts: REVIEW_EXCLUDE_KEY_VERSION 1.93.0.0 -> 1.94.0.0, the next-minor tentative form stamp_paths moves (docs/ship-policy.md, #3512); 1.93.0.0 is a released heading that never names the key.
- test/gstack-clean-producers.test.ts (new from main): KEPT gains targeted.json, the wave's --review-targeted input.
- test/review-dispatch.test.ts: main's wrong-tree test rendered the outside voice from ROOT; a CI build that dirties ROOT pushes that diff past the wave's REVIEW_DIFF_MAX_BYTES ceiling, so render refused and verify saw no brief (exit 3). It now runs in cleanCheckout like the wave's other outside-voice tests.

* test(merge 68410828f): GST-967's brief-body pin carries the wave's GST-508 placeholders

The merged sectionTexts differ from main's by exactly the wave's GST-508 exclude-pathspec lines (merged minus main equals wave minus fc292e22f); the 1,440-case plan grid still hashes to main's MAIN_PLANS. Checks: GStack Minder drive handoffs/GSTA-202/merge-6841-checks.md.

* fix(merge e85005482): targeted classes since the read accept an empty range; the wave's receipt tests pass main's targeted record

- lib/ship-receipt-depth.ts targetedClassesSince (main, GST-986) reads the range from the commit the targeted reader read to HEAD through headInputs, which since #3795 runs gstack-diff-scope's BASE_CONTAINS_HEAD check. When the reader read HEAD itself the range is empty, diff-scope reported base_contains_head, and every write with --review-targeted was refused (the product patch matched). It now passes merged=true (--merged), which skips only that check; an ancestor check already guards the range.
- test/review-exclude.test.ts and test/review-targeted.test.ts: since #3887 write refuses a money head with no targeted record and requires the record's head, so the wave's two writes that must succeed pass one, as main's own tests do (targetedAtHead in test/ship-receipt-depth.test.ts).

* test(merge e85005482): drop the wave's duplicate targeted.json KEPT entry

Main (#3887) classified .gstack/tmp/targeted.json in KEPT too; the auto-merge kept both keys, which typecheck:test rejects (TS1117). Main's entry stays.

* test(merge e85005482): ship size ledger entry for the merged tree (-232 B)

Main's ship size ledger plus the wave's entries summed to 345,334 B; the merged tree measures 345,102 B because DRIVER.md takes main's shorter Step 19 line. Recorded with scripts/size-ledger.ts record ship.

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-11-03 01:40:07 +00:00
Garry Tanandcapy-ai[bot] e85005482a v1.93.27.0 feat(pregate): pregate-literal markers waive one deliberate old-value line (#3490) (#3891)
* feat(pregate): pregate-literal markers waive one deliberate old-value line (#3490)

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

* chore(changelog): fragment named after the branch

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

* fix: pre-landing review fixes (GST-634: a bare */ is not a reason; every marker on and above the line counts)

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

* fix: a reason may not start with * (GST-634: **/ and * */ closers are not reasons)

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

* docs: a pregate-literal reason cannot start with * (GST-634 docs audit)

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-11-02 23:44:52 +00:00
Garry Tanandcapy-ai[bot] 82db89ab3e v1.93.22.0 fix(ship): targeted record binds to the commit it read; write/carry run the targeted verdict; fix-check ledgers count (GST-986) (#3887)
* test: GST-986 failing-first cases for the targeted record, receipt write/carry and fix-check counters

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

* fix(ship): GST-986 targeted record binds to the read commit; write/carry run the targeted verdict; fix-check ledgers count

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

* fix(ship): GST-986 write/carry report fail-closed targeted classes; docs, changelog, adversarial repin (brief bodies unchanged)

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

* test: GST-986 review round 1 failing-first: a docs/TODOS commit after the targeted read binds; verify clears a stale --targeted-out

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

* fix(ship): GST-986 review round 1: a record binds across class-free commits after the read; verify removes a stale targeted record

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

* test: GST-986 fix-check failing-first: test skip after the read, re-raised blocker, verify early-return cleanup, carry wording

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

* fix(ship): GST-986 scoped fix-check batch: record binds only when nothing after the read carries a class (gate scan run), a re-raised blocker is not fixed, verify always clears the stale record, carry names #3859

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

* test: GST-986 carry case runs receiptDepthAtHead under the fixture's private HOME (pregate real-HOME tripwire)

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

* test: GST-986 classify .gstack/tmp/targeted.json as a /ship producer (gstack-clean, from the main merge)

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

* fix: GST-986 bind a targeted record only to the product patch the reader read

The targeted gate reader at 0715327 found that the classifier-only binding
rule kept a stale record bound when a post-read edit removed an enforcing
line with no money token. Restore main's equal-product-patch check and keep
the gate-scan refusal on top of it. Docs-only binding moves to GST-1031.

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-11-02 21:53:30 +00:00
Garry Tanandcapy-ai[bot] cb72cc13b1 v1.93.19.0 fix(receipt): --check-prose skips the Documentation exception line and closed code fences (GST-983, GST-984) (#3884)
* fix(receipt): --check-prose skips the Documentation exception line and closed code fences (GST-983, GST-984)

write --docs with an owner exception requires the PR body to carry the Documentation exception line word for word, and read --check-prose read the owner reason in it as counter claims, the deadlock GST-977 fixed for the Review-loop exception line. Pasted test output and quoted code in fenced blocks were read as receipt counts too (gstack-evals #142). The prose check now skips the exact docs exception line and every closed code fence; a fence that never closes stays prose. Failing-first: the three new cases fail on main d45c3501e.

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

* fix(receipt): inline triple backticks open no fence, and nothing after an unclosed fence is skipped (GST-984 review)

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-11-02 21:17:24 +00:00