* 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>
* 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>
* fix(redact): a property read in code is not an internal hostname (#3987)
internal.hostname matched any name ending in .local/.prod/.staging/.internal/.corp/.lan,
so server.local('/x'), if (config.prod) and if settings.internal: reported as leaked
hosts, and the pregate secrets stage warned on each. With a code file's path, a span
outside every string and comment on its line, with code syntax on both sides, is now
a property read. Real hosts in strings, comments, URLs, ports, prose and config still
report. Each line is read once, so scan time stays linear.
Co-authored-by: nazarli-shabnam <shabnamnezerli@gmail.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
In JS, a span after a bare key and ':' or '=' (YAML or dotenv text inside a template literal) and any span after a '/' in code on its line (a regex literal can hold a quote) are no longer exempt from internal.hostname.
Review-Finding: p1/specialist-batched#1 reader=security
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: review fix-check fixes
In JS, template literals and block comments come from one pass over the whole input (jsSpans), so a span inside either is never exempt from internal.hostname; in .tsx and .jsx, a span in JSX text is never exempt.
Review-Finding: v2/outside-voice#1 reader=outside-voice
Review-Finding: v2/outside-voice#2 reader=outside-voice
Review-Finding: v2/adversarial-native#1 reader=adversarial-native
Review-Finding: v2/adversarial-native#2 reader=adversarial-native
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(redact): .tsx and .jsx files keep reporting internal hostnames
JSX text can hold a host on any line, so the property-read exemption now applies to TS, Dart and Python only, and the '>' JSX rule is gone. Recorded as the PR's review_loop_exception (a-57e88a238e8b).
Review-Finding: fc/fix-check#1 reader=fix-check
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: nazarli-shabnam <shabnamnezerli@gmail.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* 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>
* 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>
* 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>
* 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>
* fix(land): close land's /proc environment to merged_checks (GST-1421)
A merged check could read land's exec-time environment (GitHub token
included) through /proc/$PPID/environ or a /proc scan. On Linux land now
makes itself non-dumpable before the first check and refuses to run them
when it cannot. macOS (ps -E) is documented as still readable.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): GST-1421 fragment
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(land): kill what a merged check leaves running before land's git and gh calls (GST-1421)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): GST-1421 fragment names the stray kill
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>
* 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>
* fix(ship): finish takes a landed stack parent as the reviewed base, fail-closed on metadata and never bounded (GST-1399)
Ported from #4013 onto #4020's route: the stacked-parent path judges every
shipped path's metadata class against main, counts stamp_paths and
release_outputs only while stamp-only, and never feeds the bounded route.
The receipt carry's landed-parent search finds a squash main edited since.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): a loop exception starts at the landed parent; a conflicted base commit never holds a parent (GST-1399)
Review-Finding: p1/red-team#1 reader=red-team
Review-Finding: v1/outside-voice#1 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): a metadata-only conflict still holds a landed parent; a post-merge loop head starts at its own fork (GST-1399)
heldBy counts a merge as conflicted only when a conflicted path is inside its pathspec, so a train's VERSION restamp
in the squash no longer hides the landed parent. The review-loop exception's atHead uses patchBase, so a fix-check head
after the child merged main starts at its own merge base, not at the parent.
Review-Finding: p2/specialist-batched#1 reader=specialist-batched
Review-Finding: p2/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(ship): stacked-parent loop-exception matrix over merge order, parent state and fix-check head (GST-1399)
28 cells: the child merged main before the parent landed, after, or never; the parent landed by squash, by squash
with a later main edit of its lines, with a release fold, or not at all; the fix-check head is before any merge, the
merge, or after it. Every cell runs the postinstall and stamp_paths probes (parent changes main never took, edited
after the fix-check) and a control run (the child's own file and a main-only file edited after the fix-check).
Red at 3f4c47c (4): merged before or after the landing × parent edited × fix-check head merge or post; the
exception accepts package.json and src/policy.ts. The other 24 cells pass.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): a loop exception's fix-check paths are the head's own patch from both forks; heldBy reads merge-tree with -z (GST-1399)
The "touched at the fix-check head" set is the intersection of the head's patch from its merge base and from the
landed parent, so neither a parent change main never took nor a main-only file counts as reviewed, whatever order
the child merged main in. heldBy reads conflicted names NUL-separated, so a C-quoted name still counts as a conflict.
The stacked-parent matrix (28 cells) is green.
Review-Finding: fc1/fix-check#1 reader=fix-check
Review-Finding: fc1/fix-check#3 reader=fix-check
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>
* docs: on Capy, comment, tag and request reviews only through tools.pr.comment / tools.pr.edit, never gh; unattended /modernize posts nothing (GST-1417 follow-up)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* changelog: own fragment for the GST-1417 follow-up; landed fragments are never edited
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>
* 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>
* 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>
* 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>
* docs(review-policy): verify also checks each merged row's reader (GST-1406 follow-up)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore: changelog fragment for the verify-reader docs line
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>
* fix(review): lead judgment may lower a native finding to the Severity it stated beside Blocks: no (GST-1406)
Collect keeps the FIXABLE raise on a native adversarial finding whose
Severity and Blocks: no follow prose, because it can't tell a finding's
own fields from another subject's. judge() and ledgerBlockers() now let
lead judgment lower such a finding to its one stated positive-rank
Severity, never below it, only with a reason, recorded as dismissed.
Carried from gst-1406-fixable-blocks-no (daf4fc2) without the GST-1409
fence pre-scan.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
verify checks each merged row's reader against the output it came from,
and ledgerBlockers takes the reader from the output event, so a row
relabelled adversarial-native can't take the native lowering and replay
clean. The JUDGMENT_REJECTED hint names the native route; the fragment
says the blocker count is unchanged rather than that it follows.
Review-Finding: v1/outside-voice#1 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>
* chore: name the GST-1406 fragment after its branch
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>
* ci: Trunk Dynamic CI observes free-suite and macos-named-regressions, learning only (GST-1400)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* changelog.d: Trunk Dynamic CI learning-only fragment (GST-1400)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: name the observer check red case and the required-check vote caveat (GST-1400 review)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: a missing Trunk token skips the step, not the job (GST-1400 fix-check)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: secret guards catch lowercase, bracket and toJSON references; docs cite the pinned source (GST-1400 voices)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* changelog.d: name job-start failures as the one red case (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>
* docs: diff-plus-blocking stops at the third fix cycle; carry order matches ship Step 1 (Step 14.5)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): carry NEXT names the push and CI wait; docs give the real diff-plus-blocking cap (GST-1346 follow-up)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): carry route says push before the dry-run and that CI_CARRY: none is not a stop
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>
* docs: agents close or label with no comment; notes to people are drafts for the maintainer (GST-1376)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(modernize): pin the no-comment rule (GST-1376)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(modernize): Step 3 asks before any push or close, never a closing comment (GST-1376)
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>
* fix(doctor): parse the launch probe under macOS /bin/bash 3.2 (#3601)
bash 3.2 ends a $( ) at the ) of a case pattern that has no leading (, so
macOS /bin/bash could not parse bin/gstack-launch-probe.sh and gstack-doctor
reported the probe missing. The pattern takes its POSIX leading (. A static
scanner, which Linux CI runs, fails any tracked shell script with a bare case
pattern inside a substitution, and the probe test parses the file with
/bin/bash.
Co-authored-by: 김보경 <rlaqhrud6263@naver.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* changelog: fragment for the bash 3.2 launch probe fix (#3601)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(launch-probe): say the /bin/bash parse case discriminates only on macOS
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* changelog: the probe parse test catches #3601 only on a Mac
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: move the /bin/bash parse case out of the windows-smoke probe test (#3601)
Main's windows-smoke runs test/gstack-launch-probe.test.ts, and a hardcoded
/bin/bash path takes a file out of the Windows-safe set, so the merged tree
failed windows-native-workflows. The case now lives in
test/bash32-case-in-substitution.test.ts with the Linux scan.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: 김보경 <rlaqhrud6263@naver.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review): Step 11 on its own --out renders only the voices, so verify never sees an unsent specialist brief (GST-1368)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): GST-1368 fragment
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(review-policy): describe pass --voices (GST-1368)
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>
* test-impact: tracer and reuse keys for free tests; pregate keeps main's always-run list
GST-167 PR 2: lib/test-impact/{trace,key}.ts and scripts/test-impact.ts trace a free test file under strace and key it at a tree over its read set, import closure, lockfile, configs, runner and key code and runtime; anything uncertain is ineligible. Nothing in CI changes yet.
GST-233: pregate unions the merge base's .gstack/always-run.json with the branch's, so a branch cannot drop main's whole-tree tests.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (untracked reads ineligible, tool bytes and runner imports in the key)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: adversarial review fixes (creation proof, PATH reads, bound loopback endpoints, unix sockets, env and runtime binding, future traces)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: graph checkout ignores the tree's export attributes; the tracer runs the free runner's own command and sandbox
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: write the graph's tree copy blob by blob so .gitattributes can't rewrite or hide files
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: refuse unsafe tree paths before materializeTree writes; trace the CLI key test on the real runtime
materializeTree now checks every path before writing: a .., . or .git segment, an empty segment, a backslash, a duplicate path or an entry under a symlink entry refuses the tree, and symlinks are written last. Failing-first tests on 89d4728 showed a '..' tree writing into os.tmpdir() and a symlink-then-blob tree writing through the link.
The key --base CLI test traced under a hard-coded bun 1.4.4 while the CLI keys on the real runtime (CI runs bun 1.4.2), so the runtime check added in 6b4e6c5 made it ineligible; it now traces on the real runtime at the current time.
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>
* fix(evals): Codex removed-rule arm strips the rule from the installed skills (GST-840)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(evals): copy linked directories inside a skill before stripping the rule; record the harness decision (GST-840)
/ship review found readdirSync({ recursive: true }) follows linked
subdirectories, so a rule file under a linked directory inside a real
skill directory would have been deleted and rewritten in the checkout.
Every linked directory on the way to a rule file is now copied first,
with a failing-first test row. The harness-version manifest records
codex-host-runner.ts as non-behavioral: only the manual removed arm
on the Codex host changes.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: keep the Codex safety-arm test off Windows, and spawn its probe with bunIsolationArgs (GST-840)
windows-free-shard 3 (run 41336347706) failed every case: native Bun on
Windows cannot open --config=/dev/null, and the test builds a symlinked
~/.codex/skills install that needs Developer Mode the runners lack.
./setup --host codex copies instead of linking on Windows, so the strip
only matters on POSIX. The probe now uses bunIsolationArgs().
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>
* fix(ship-receipt): record the installed gstack VERSION, not the newest policy-key version (GST-1366)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): fragment for GST-1366 receipt gstack_version
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>
* 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>
* 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>
* fix(browse): a touch right after navigation waits for a rendered frame, so it lands where aimed (GSTA-262)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(browse): the frame wait before a touch is capped at 1 s, and touch cancel waits for the frame that delivers it (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>
* fix(review-risk): a token-named file is a secret path only on secret-shaped content (GST-1350)
founderstar scripts/ui/token.gd (Godot design tokens) matched the secret-path
name rule, so a copy-only PR planned gate class at full depth. A token name now
escalates only when the credential scanner finds a secret on its changed lines;
dotenv files, SSH private keys and key-store extensions join the name rule.
Repins lib/review-risk.ts and lib/review-depth.ts with replay GST-1350.
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
Review-Finding: p1/red-team#2 reader=red-team
Review-Finding: p1/specialist-batched#1 reader=security
Review-Finding: p1/specialist-batched#2 reader=security
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
Review-Finding: p2/targeted#1 reader=targeted
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: changelog fragment for GST-1350
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>
* fix(ship): make the five judge-flagged workflow spots match the code (GST-1346)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): carry runs the pregate before its push (review fix)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): carry pushes early, waits for CI, then pregates; restore stage 1 wording (fix-check)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: diff-plus-blocking stops at the third fix cycle; carry order matches ship Step 1 (Step 14.5)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore: changelog and TODOS
Documentation: updated
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Revert "docs: diff-plus-blocking stops at the third fix cycle; carry order matches ship Step 1 (Step 14.5)"
This reverts commit 5151144c04.
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(review): a fetch rule in every reader brief and a base-read readers policy (GST-1322 PR A)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(review-fetch): type the empty policy fixture for the test typecheck ratchet
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(review-fetch): register the #362 fixture as a free fixture
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
Head forbid_paths are ignored (base only), directory-form forbid_paths cover files under them in the scanner and the keep filter, an explicit --base that resolves nowhere refuses, and audit-fetch gains a CLI test.
Review-Finding: p1/specialist-batched#1 reader=security
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
Review-Finding: p1/specialist-batched#2 reader=testing
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
forbid_paths also excludes <pattern>/** so git's diff exclusion covers nested files the way forbiddenPath does; the readersAt refusal no longer names a network command.
Review-Finding: p2/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
forbiddenPath matches a pattern against the path and its parent directories only, the set forbidSpecs makes git exclude; the probe of a made-up child also forbade siblings (lib/x forbade lib/).
Review-Finding: p2/outside-voice#1 reader=outside-voice
Review-Finding: p2/adversarial-native#1 reader=adversarial-native
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): name the PR A fragment for its branch; forbid_paths and the note come from the base
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: fix the readers and review-scope anchors; key versions live in lib/ship-policy-keys.ts (Step 14.5 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>
* test: remove the skill-prose clarity LLM judges (GST-1371)
Removes the 21 eval cases where an LLM scored a skill's instruction text for
clarity, completeness and actionability, with their registrations, input
builders, response cache, calibration corpora, the cookie-workflow manual-review
approval and scripts/judge-controls.ts. The three remaining skill-llm-eval
judges keep their prompts, thresholds and samples; the file's supervision wall
shrinks to fit them. Outcome judges are untouched.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: pin the retired judge-control script and cookie manual-review record as deleted (GST-1371)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: register the manual-review fixture as free (GST-1371)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: keep the orphaned clarity-judge calibration corpora for a follow-up deletion (GST-1371)
Deleting the four corpus directories alone puts the diff over the /ship review
ceiling; they serve no configuration now and go in a follow-up.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(todos): file the clarity-judge removal follow-ups (GST-1371)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: keep skill-bundle section paths POSIX so references dedupe on Windows (GST-1371)
windows-scoped-shard (run 41918796523) failed 'cross-skill references retain
complete bytes once': path.join gave the section entry a backslash path, so a
reference to the same section was not recognized as already bundled.
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>
* fix(ship): one answer per ship-workflow question the judge flagged (GST-1346)
The ship/SKILL.md workflow judge failed twice on main b244e6d (run 41817566885,
actionability 4/3/3 in both panels) on prose no landed PR changed. Every sample
cited the same conflicts; resolve them without growing the skill:
- Step 11: Codex-mode branches keep only the Claude pass the plan dispatched;
both Codex passes run on DISPATCH: outside-voice.
- Steps 12/16: item and stage commands serve only a STOP:.
- CI carry: names the draft-PR command; Step 6.5's question covers only Greptile;
accept runs after Step 17's push.
- Step 19 exit 3 ends Step 22 with status=refused run=-.
Ship union -8 bytes (size ledger), skeleton within its cap.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): drop the Step 11 wording; keep the three no-loss-free repairs (GST-1346)
ship/sections/adversarial.md is pinned to a no-loss replay (GSTA-258-C) and its
headings anchor lib/ship-parts.ts, so its rewording needs a replay first; it moves
to a follow-up. A local single-case judge panel without it passed 3/4/4 on all
three samples. Trims the CI_CARRY reason list (the tool prints the reason) to keep
the ship union under its ledger (-11 bytes).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): stage 1 builds go to finish as --build, stage 5 commits only regenerated outputs, full draft-PR command (GST-1346)
Step 11 review findings: the bare 'gstack-post pr-create --draft' exits 64
without --base/--title-file/--body-file (outside voice), and '1-4's commands are
only STOP recoveries' read as skipping stage 1's build discovery (native).
Folds #3951's stage 5 commit-owner wording. Ship union -39 bytes.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): keep pr-body byte-neutral after the exit-3 status=refused line (GST-1346)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore: changelog and TODOS
Co-Authored-By: Claude <noreply@anthropic.com>
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: Claude <noreply@anthropic.com>
* 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>
* fix(ship): a reader's no-defect closing sentence is not a CRITICAL finding (GST-435)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): fragment for GST-435
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): linear summary grammar, keep a summary line with other prose on record, skip wrapped continuations (GST-435 pass-1 red team)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
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(ship): a summary line under a run-on or exception line in its paragraph keeps its label (GST-435 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>
* docs(ship): closingSummary checks only the line directly above (GST-435 fix-check note)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Revert "docs(ship): closingSummary checks only the line directly above (GST-435 fix-check note)"
This reverts commit daf526b94a.
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* 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>
* fix(ci-carry): a per_file remainder file that skips here too is not owed (GST-1314); anchor per_file paths, --no-env-file, declare gstack's per_file runner
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>
* fix(evidence): a truncated per_file log never counts a remainder file not owed (GST-1314)
Review-Finding: p1b/outside-voice#1 reader=outside-voice
Review-Finding: p1b/red-team#3 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): GST-1314 fragment names the truncated-log refusal
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(pregate): a per_file log cut at 2 MB still refuses (GST-1314)
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>