* Let an owner recorded approval close a gate finding in unattended ship (GST-2491)
An unattended /ship logs every gate finding open and nothing could close it, so a PR with an owner-approved gate change could never finish. gstack-approvals gate records the owner disposition outside the run; it closes only that fingerprint on a review row whose range holds the head, and finish, the receipt, the PR body and READY all carry it.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the pinned review brief unchanged; document the resume steps for a dispositioned gate finding (GST-2491)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Bind a gate disposition to its gate change and show it as kept to the rest of /ship (GST-2491)
A disposition now names the finding's gate_id as well as its fingerprint, so a later loosening of the same line stays open. gstack-review-read shows a closed gate finding as kept with the disposition's approval id, so the existing --blocking-open, --gate-open, draft and Gate edits rules carry it without prose changes, and an unreadable approval record applies no disposition instead of failing the reader.
Review-Finding: p1/red-team#1 reader=red-team
Review-Finding: s11/outside-voice#1 reader=outside-voice
Review-Finding: s11/outside-voice#2 reader=outside-voice
Review-Finding: s11/adversarial-native#1 reader=adversarial-native
Review-Finding: s11/adversarial-native#2 reader=adversarial-native
Review-Finding: s11/adversarial-native#4 reader=adversarial-native
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* List the Gate disposition line in the receipt and prose troubleshooting entries (GST-2491)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Require the lander to accept each owner gate disposition before merging (GST-2491)
Land and a new read-only verify --pin re-derive the dispositions the approval store applies at the pin and merge only with --accept-gate-disposition for each one. The gate writer refuses while any worktree holds an open /ship run on the branch, under a lock; a row counts only in the writer's full shape with its digest; receipt write needs --body when a disposition applies; ready and land cross-check the receipt and body against the store. Supersedes #4299.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Regenerate the result-code anchors for the gate-disposition refusal (GST-2491)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Always record the receipt's gate dispositions and refuse a store that disagrees at merge (GST-2491)
The receipt always carries gate_dispositions (an empty list when none apply) and write refuses on an unreadable store or a git error. Land, verify and ready refuse a receipt id the merge-time store lacks, naming the likely wrong state root or mirror, and a field-less receipt beside an applied row. A git ancestry error while deriving dispositions refuses instead of reading as not applied.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Count a disposition whose head a rewrite removed as not applied, and expect the receipt to end with gate_dispositions (GST-2491)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Trim and check the gate disposition recorder name, and let a parked run's ended lease stop blocking it (GST-2491)
Review-Finding: s11/outside-voice#3 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>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Let the sealed-output guard read pull requests larger than 256 MiB (GST-2494)
The guard's text check and landed-patch check buffered git diff-tree's whole output under spawnSync's 256 MiB maxBuffer, so a PR with millions of generated lines always refused with an empty-stderr error. Both now spool git's stdout to a private temp file and read it a line at a time after git exits 0; failures name the exit code, signal or timeout.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Accept the platform spawn error text in the missing-git test (Windows says Executable not found)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Reword the sealed guard changelog entry to pass the prose 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>
* Stop the stable cut counting its own check runs against the commit it cuts (GST-2463)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Match the stable cut's own check runs by job, not by check suite (GST-2463)
GitHub files a check run another workflow creates through the API (main-backstop from release-gate.yml and evals-main-backstop.yml) under any github-actions check suite on the commit, so suite membership could hide a red main-backstop. The cut now lists the jobs of its own workflow runs and sets aside only check runs whose id is one of those job ids.
Review-Finding: p1/red-team#1 reader=red-team
Review-Finding: p1/adversarial-native#1 reader=adversarial-native
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say that the stable cut's own-run lookup needs actions: read and fails safe (GST-2463)
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>
* Stop gstack-uninstall deleting unpushed or kept work under any folder it removes (GST-2303)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep repos behind a symlinked .gstack-worktrees, remove stable-channel installs, and read worktrees on git before 2.36 in gstack-uninstall (GST-2303)
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#1 reader=testing
Review-Finding: p1/specialist-batched#2 reader=testing
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Count a FETCH_HEAD commit as pushed only when it came from one of the checkout's remotes in gstack-uninstall (GST-2303)
Review-Finding: p2/specialist-batched#1 reader=security
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Read remote URLs with git remote get-url so url.insteadOf rewrites match FETCH_HEAD in gstack-uninstall (GST-2303)
Review-Finding: fc/fix-check#1 reader=fix-check
Review-Finding: fc/fix-check#2 reader=fix-check
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Refuse to uninstall on git older than 2.36 instead of reading worktrees without -z (GST-2303)
Review-Finding: v11/outside-voice#1 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* List the git 2.36 uninstall refusal in troubleshooting (GST-2303)
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>
* Drop the review skill from the QM edition
A benchmark of the QM edition found gstack-review flagged too many problems
without making the reviewed work better, so the edition now ships only
gstack-plan. Regenerated qm/ and removed the review-only first-step script.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Regenerate the QM edition without the review skill and update its docs and tests
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Give the deleted QM review script an empty test lane so the pre-merge check accepts its removal
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Point the deleted QM review script at the QM edition test instead of no test lane
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>
* Stop gstack-uninstall deleting nested worktrees, locked worktrees and a .gstack repo (GST-2268)
The worktree check now walks every checkout under .gstack-worktrees/,
nested ones included, and keeps a submodule of a clean lane covered by
that lane's status. A locked worktree stops the uninstall even with
--force-worktrees. A .gstack/ that holds its own git repository is kept
with a message. The check runs again right before .gstack-worktrees/ is
deleted, so work saved while the prompt waited is kept (exit 2). The
manual steps in docs/uninstall.md no longer rm -rf the per-project
folders.
test/uninstall.test.ts is already excluded from the Windows subset by
scripts/lib/windows-curation.ts (it spawns a bin/ shebang script).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep a lane's submodule when it holds commits no remote-tracking branch has (GST-2268)
The submodule exemption trusted the lane's status, which only compares the submodule's HEAD to the recorded gitlink. Commits on the submodule's own branches or stash live in the lane's git dir and were deleted with exit 0. Uninstall now refuses such a submodule, and matches the gitlink by exact path instead of a prefix or glob pathspec.
Review-Finding: s11/outside-voice#1 reader=outside-voice
Review-Finding: s11/adversarial-native#1 reader=adversarial-native
Review-Finding: p1/specialist-batched#1 reader=testing
Review-Finding: p1/red-team#3 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Explain the submodule rule in the uninstall docs (GST-2268)
docs/uninstall.md now says a submodule inside a clean lane goes only when its commits are on a remote-tracking branch, and the changelog entry drops a mid-sentence colon.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Make every gstack-uninstall keep check run before anything is deleted (GST-2268)
The post-prompt worktree check now runs right after confirmation, before
the install root or anything else is removed, so running uninstall from
inside the gstack install no longer deletes a worktree edited during the
prompt. A .gstack/ holding its own git repository inside the install being
removed now stops the uninstall. A failing git worktree list stops it too,
even with --force-worktrees. The manual cleanup in docs/uninstall.md now
matches worktree paths by prefix, so it never removes a worktree outside
the project whose path merely contains it.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Also stop gstack-uninstall when a .gstack repo sits inside a Cursor, OpenCode, Copilot, Antigravity or Gemini install (GST-2268)
Review-Finding: p1/specialist-batched#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Split a run-on sentence in the uninstall release note (GST-2268)
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>
* Warn when a red check is replaced by a run from another suite, and refuse a plain ready whose note never reached origin (GST-2205)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Fetch the base before ready picks the train or plain path (GST-2205)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Let the train path report its own fetch failure when ready cannot refresh the base (GST-2205)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Give the no-origin/main routing test a complete pregate record (GST-2205)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Give the unpushed ready-note test a complete pregate record (GST-2205)
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>
* Brain sync scans binary files and split authorization values for secrets (GST-2292)
Git showed a file with a NUL byte or UTF-16 text as "Binary files differ",
so the push-time secret scan never saw an AWS key inside it. The sync and the
pre-commit hook now diff with --text --no-textconv, the scanner also reads
NUL-bearing lines as UTF-16 and with NULs removed, and a section git still
did not diff as text is held as binary-not-scanned.
A Bearer value added under an unchanged "authorization": line was missed
because the + marker broke the match; each hunk's new text is now scanned as
one block too. The docs say plainly that an already-committed secret stays
held after deletion and only --skip-file clears it.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Secret scan catches split auth values in UTF-16 files and under diff.context=0
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>
* Sync docs say a secret already committed in ~/.gstack stays held until you skip the file
Approved docs-audit repair: approval a-029ea2b533be (GStack Minder GSTA-36, lane brief item 3).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Secret scan keeps the plain git diff as one reading beside the text reading
The sync and the pre-commit hooks had replaced git's plain staged diff with
a --text --no-textconv -U3 diff. That lost two things the old scan held: an
unchanged line that the user's diff.context showed (5 lines away from an
edit), and a secret that only a configured textconv driver decodes. The
scanner now takes both diffs and holds a file when either reading matches;
binary-not-scanned applies to the text reading only.
Review-Finding: sol-audit-201c6a0#1 reader=cross-family-audit
Review-Finding: sol-audit-201c6a0#2 reader=cross-family-audit
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Secret scan decodes JSON escapes in UTF-16 text and keeps its diff files private
A \u-escaped AWS key inside a UTF-16 JSON file passed both scans, because
the UTF-16 and NUL-stripped readings skipped the JSON decoding every other
reading gets. The sync's two scan diffs, which now carry binary bytes, were
written with the user's umask (0644 under /tmp); they are created 0600.
Review-Finding: p3/outside-voice#1 reader=outside-voice
Review-Finding: p3/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>
* Count a fix-check whose range starts after a docs-only commit (GST-2294)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Name the follow-up review rule in plain words in the changelog (GST-2294)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Bridge a docs-only gap only through paths the router itself treats as release metadata (GST-2294)
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>
* Add failing tests: escaped secrets pass brain sync, unchanged lines hold edits, hooks miss new families (GST-2263)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Brain sync scans only added lines, decodes JSON strings, and its pre-commit hook uses the same scanner (GST-2263)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Use a placeholder password in the brain sync docs example so the credential scan passes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Test that the brain repo pre-commit hook refuses a commit when its scanner is missing or fails
Review-Finding: p1/specialist-batched#2 reader=testing
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Brain repo hook keeps its own copy of the secret scanner, and the scan catches auth headers with escaped keys
Review-Finding: v1/adversarial-native#1 reader=adversarial-native
Review-Finding: v1/outside-voice#1 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Name the brain sync changelog fragment after its branch
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Brain sync scans the whole staged diff again, so renamed keys and secret file names are still held (GST-2263)
Review-Finding: bin/gstack-brain-secret-scan.py:111:outside-voice reader=outside-voice
Review-Finding: bin/gstack-brain-secret-scan.py:104:outside-voice 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>
* Let the CI carry accept a run where only an unrelated job was rerun (GST-2284)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Check artifact ids only when a run holds several same-named artifacts (GST-2284)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Date a carried CI run by its own test jobs so an unrelated rerun cannot refresh old results (GST-2284)
Freshness now reads the newest completed_at among the profile's jobs, not every job in the run, so rerunning a job outside the profile no longer makes days-old test results look fresh. The no-dependencies hint now matches only a missing package or module error.
Review-Finding: p1/red-team#1 reader=red-team
Review-Finding: p1/specialist-batched#1 reader=testing
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say in the changelog and pregate docs that a carried run is dated by its own test jobs (GST-2284)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Fix the test type error in the new freshness test (GST-2284)
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>
* Catch secrets split across lines in UTF-16 files and skip deleted files in the push scan (GST-2261)
Each reading of a file git calls binary is now scanned as its own text with the file's line numbers, so a keyword and its value on the next line stay neighbours. The pre-push hook diffs with --irreversible-delete, so a deleted binary's old bytes no longer fill its 64 MiB buffer.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Leave the landed binary-scan changelog fragment unchanged (GST-2261)
Review-Finding: changelog.d/scan-binary-files-for-secrets.md:1:release reader=core
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* List a token once when several readings of a binary file find it (GST-2261)
Review-Finding: p1/specialist-batched#1 reader=specialist-batched
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Report a repeated token once only within one binary file, so an allowlisted token never hides another (GST-2261)
Review-Finding: p2/specialist-batched#1 reader=security
Review-Finding: p2/red-team#2 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Name the changelog fragment after the branch (GST-2261)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the side-by-side reading of binary files so a key and its keyword in different readings still fail (GST-2261)
Review-Finding: audit/cross-family#1 reader=gpt-6.1-sol
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>
* Let an owner's ruling clear the new blockers a granted fix-check found (GST-2251)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Name every finding that still holds a fix-check open, with the full rule command (GST-2251)
Review-Finding: p1/adversarial-native#1 reader=adversarial-native
Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Describe the wider FIX_CHECK_OPEN list in the release note (GST-2251)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep a skipped blocking finding open until the owner rules it, even beside a ruled CRITICAL (GST-2251)
A ruled open CRITICAL could clear a fix-check row while an unruled non-CRITICAL finding logged skipped with blocking:true stayed unruled. Rulings now clear a row only when one covers every unresolved or blocking finding, and FIX_CHECK_OPEN names the rest.
Review-Finding: captain-audit/Q1 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>
* Make pregate verify refuse a record from a partial run (GST-2194)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Update pregate and queue test fixtures to complete records
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Document that verify needs every check and that a staged rerun keeps the rest
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Skip the partial-record pregate tests on Windows, where the fixture lane is a remote obligation
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Give the crew queue tests complete pregate records
The train, train-ops and wave tests wrote one-check pregate records, which verify now refuses as a partial run. They now write every registered check, as test/gstack-ship-queue.test.ts already does (CI free-suite run 42718782737).
Review-Finding: lib/pregate/index.ts:251:functional-contract reader=core
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Explain the missing-checks pregate refusal in troubleshooting
Documents that verify refuses a record missing registered checks, and that a fix commit needs a full gstack-pregate run (Step 14.5 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>
* Make ship-queue ready fetch the base before it checks the receipt (GST-2232)
ready read origin/<base> as the clone last fetched it, so a lane a few landings behind measured the PR from an older merge base and refused a good receipt with a false RECEIPT_INVALID field=review_exclude. ready now fetches the base first and refuses QUEUE_BASE_UNFETCHED when it cannot; the stamp path of land refuses the same way instead of ignoring a failed fetch.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Regenerate the doctor component list for the new queue refusal code (GST-2232)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the new ready test off the Windows-safe set and say which land path uses the new refusal (GST-2232)
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>
* Make ship-queue ready refuse when its READY note doesn't reach origin (GST-2242)
ready exited 0 and printed "notes pushed" even when the READY note never reached origin, so land refused the pin with QUEUE_NOT_READY (#4245). The notes writer now reads origin's ref back after each push, and train ready refuses with QUEUE_READY_NOTE_UNPUSHED when origin still lacks the note after three tries.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Name the changelog fragment for the branch (GST-2242)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Regenerate the doctor component list for the new ready result code (GST-2242)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say that ready's notes check covers train policies, and how to rerun it with its gate flags (GST-2242)
Review-Finding: p1/red-team#2 reader=red-team
Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Skip the ready notes-push test on Windows, where the gh shim can't run (GST-2242)
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>
* Stop the runaway scan from telling Captains to rotate crew threads that hold a PR (GST-2226)
Only a thread marked standing rotates, and never while it holds an open PR or its PR list is missing; a crew thread gets one CHECK_IN past 1B own tokens (R70 as amended, R91).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Trim the runaway-stopper wording so it fits the skill context budget with #4244
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Reword the runaway-scan changelog entry so it passes the prose 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>
* Stop gstack-uninstall deleting a repo's committed .gstack files and unsaved worktrees (GST-2197)
--keep-state now keeps the repo's .gstack/ and .gstack-worktrees/. A plain
uninstall keeps git-tracked .gstack files, removes only ignored state, and
stops before removing anything when a worktree has uncommitted changes
unless --force-worktrees is given.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep moved, config-hidden and committed worktree work from gstack-uninstall (GST-2197)
The dirty-worktree guard now checks every checkout on disk under .gstack-worktrees/, pins git status flags so config cannot hide new files, refuses a checkout whose commits no branch or tag holds, and keeps .gstack/ when git cannot list its tracked files.
Review-Finding: p1/red-team#2 reader=red-team
Review-Finding: p1/red-team#3 reader=red-team
Review-Finding: p1/specialist-batched#1 reader=security
Review-Finding: p1/red-team#4 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Make gstack-uninstall list worktree checkouts safely and never run their config (GST-2197)
Checkouts are listed NUL-separated and through a symlinked .gstack-worktrees, only worktrees this repository registered are opened with git, and those git calls turn off fsmonitor, hooks and optional index writes.
Review-Finding: v1/adversarial-native#1 reader=adversarial-native
Review-Finding: v1/adversarial-native#5 reader=adversarial-native
Review-Finding: v1/adversarial-native#2 reader=adversarial-native
Review-Loop-Grant: a-f3b2ff8e662e
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Check a .gstack-worktrees that is itself a git repo before gstack-uninstall deletes it (GST-2197)
Review-Finding: fc1/fix-check#1 reader=fix-check
Review-Loop-Grant: a-3b80e7929588
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Document what gstack-uninstall keeps and refuses, and the new --force-worktrees flag (GST-2197)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Stop gstack-uninstall dropping the registration of worktrees it did not delete (GST-2197)
Uninstall ran a repo-wide git worktree prune, which unregistered every worktree whose folder was missing at that moment, including ones outside .gstack-worktrees on an unmounted drive, and left their detached commits unreachable. It now unregisters only the gstack checkouts it just removed.
Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say that gstack-uninstall does not yet check worktrees nested inside another checkout (GST-2197)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Stop gstack-uninstall deleting checkouts through a .gstack-worktrees symlink that points outside the repo (GST-2197)
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>
* Make gstack-uninstall remove only the link when .gstack-worktrees is a symlink, as before (GST-2197)
Review-Finding: p2/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Drop release-note wording from the gstack-uninstall docs (GST-2197)
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>
The receipt carry and finish scoped-review packet counted context lines, hunk headers and the base's change toward the 200-line section cap (founderstar#802). gstack-review-plan measured the fix range as --range-base..HEAD, so files a main merge brought counted as the PR's fix (harness-evals#354).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Make the archive check refuse unknown PR states, cut-short issue rows and a missing title policy (GST-2241)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Regenerate the doctor result-code table for the two new archive codes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Document that the archive check refuses unknown PR states and needs the title policy on land
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>
* Scan files git calls binary for secrets before push and in pregate (GST-2195)
A NUL byte, UTF-16 text or a -diff attribute made git print 'Binary files differ', so a token in that file passed pregate's secrets check and the pre-push hook. Both diffs now use --text and read such files through scannableText, keeping only credential findings; pregate's secrets check also fails closed when its merge-base diff does not finish.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Find tokens in UTF-16 text that is mostly Cyrillic or CJK, and note the size limit for binaries
Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Read each line of a binary file both plainly and as UTF-16, so a nearby byte cannot hide a token
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>
* Keep tokens beside CJK characters in UTF-16 files whole, and parse large added diffs in linear time
Review-Finding: p2v/outside-voice#1 reader=outside-voice
Review-Finding: p2v/targeted#1 reader=targeted
Review-Finding: p2v/outside-voice#2 reader=outside-voice
Review-Finding: p2v/adversarial-native#1 reader=adversarial-native
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Split two long sentences in the changelog entry for binary-file scanning
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Describe how the secret check reads binary files, its size limits and its new pass line
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say which UTF-16 layouts the binary-file secret scan does not catch yet
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>
* Stop the merge queue from calling a head green while a check on it failed (GST-2167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Don't count a workflow run cancelled before any job as a failed check, and keep a jobless failure counted until its replacement starts (GST-2167)
A concurrency group cancels a pending run when a newer one at another SHA arrives, so the main backstop at 526f604f91 and 5fdfa14904 would have read red forever. A replacing run that is still queued with no jobs no longer hides the failure before it. Adds a test that an unreadable workflow-runs list is unknown.
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=testing
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Judge each check suite by its latest attempt that ran jobs, so a rerun clears a dropped matrix failure and an empty failed rerun stays red (GST-2167)
ciAtHead now reads check runs with the default filter and with filter=all. A suite the default list names is judged by that list alone; a suite only filter=all names is judged by its earlier attempts, and its workflow run counts as a failed check with no jobs when it failed and nothing in the suite already counts the failure.
Review-Finding: v1/outside-voice#1 reader=outside-voice
Review-Finding: v1/outside-voice#2 reader=outside-voice
Review-Finding: v1/adversarial-native#1 reader=adversarial-native
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Name the changelog fragment after the branch and split a run-on sentence in it (GST-2167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Describe how the merge queue now counts CI in the ship policy doc (GST-2167)
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 that a Captain cannot archive a thread still holding open work (GST-2188)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Refuse to archive a thread that holds an open PR and close a landed PR's issue (GST-2188)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Clear the archive check's handoff file on a failed read and say plainly that long PR lists cannot be checked
Review-Finding: p1/specialist-batched#2 reader=testing
Review-Finding: p1/specialist-batched#3 reader=state-machines
Review-Finding: p1/red-team#1 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>
* Refuse to archive on an issue list with no rows, and match tracker codes in any case when closing a landed PR's issues
Review-Finding: p3/outside-voice#1 reader=outside-voice
Review-Finding: p3/outside-voice#2 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say in the skills guide that a rotated thread is archived only once none of its PRs is open
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Shorten the runaway-stopper archive step so the skill fits its context budget after the rebase
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>
* Keep a numbered review finding's closing paragraph on that finding after a nested list (GST-2174)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the nested-list join from lowering a separate finding or a CRITICAL item
The join that keeps a numbered native finding's closing paragraph now ends after that first paragraph, skips bold-led margin paragraphs and verdict lines, applies only to the native voice's items, and never lowers an item that names CRITICAL or P0. Each of these let a separate finding's Severity and Blocks: no lower a FIXABLE blocker to Low (GST-2174).
Review-Finding: review/specialist-batched#1 reader=testing
Review-Finding: review/red-team#2 reader=red-team
Review-Finding: review/red-team#3 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Describe the numbered-finding nested-list rule and add its changelog entry
docs/review-policy.md now says how the collector keeps a native numbered finding's first closing paragraph after a nested list (GST-2174).
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>
* Add failing tests: ready and land accept a stacked child's receipt reviewed against its open parent branch
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Refuse a receipt reviewed against another branch than the queue base at ready, land and train build (GST-2153)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Regenerate the doctor result anchors for the new receipt base mismatch code
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
Train build now has a test that refuses a receipt reviewed against a parent branch.
Review-Finding: p1/specialist-batched#1 reader=specialist-batched
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
Keep the base-contains-head diagnostic ahead of the receipt base check, normalize any remote's refs, and tell callers to merge the base in before the carry.
Review-Finding: v1/outside-voice#3 reader=outside-voice
Review-Finding: v1/outside-voice#1 reader=outside-voice
Review-Finding: v1/outside-voice#2 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say in the changelog entry that the base is merged into the child before the carry
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* List the receipt base mismatch refusal in the land refusal tables
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Leave the crew captain refusal table for a follow-up so this PR changes no agent instructions after 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>
* Keep /autoplan working after a Claude Code 2.1.317 compaction (#4200)
On 2.1.317 a compact boundary's logicalParentUuid names a record the
session file never receives, and the preserved list ends with the last
record kept in place. The journal reader required that tail to equal the
logical parent, so the boundary became an orphan, every later record was
dropped, and each phase entry was refused on every retry.
The reader now accepts a preserved list whose last entry is the segment's
tail, and continues a boundary whose logical parent is absent from the
file from that tail. The 2.1.300 path is unchanged: when the tail is the
logical parent it still needs the boundary cycle, so an unflushed tail
supplies no ownership. A boundary that opens the file stays a resumed
fork's root, and lists naming no node of this session still continue
nothing.
Co-authored-by: vilano93 <244097767+vilano93@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say the troubleshooting guide's compaction note covers Claude Code 2.1.317
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: vilano93 <244097767+vilano93@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Rebuild the decision snapshot from the merged log when two machines' syncs conflict (#4174)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep redacted decisions out of a rebuilt decision snapshot
The jsonl-append merge driver takes the union of base, ours and theirs, so a
log that lost lines on one side (--compact expunging a redacted decision)
would get them back. The snapshot rebuild now runs only when every base line
of the log is still on both sides; otherwise the merge aborts as before.
A conflicted snapshot when local edits are put back after the merge is now
rebuilt from the working-tree log instead of left at the merged version.
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>
* Put the stash recovery path back to how main handles it
Rebuilding a conflicted decision snapshot after stash pop made a decision
that another machine redacted and compacted away consistent and publishable,
because stash pop merges the log as a union. Without the rebuild the
mismatched log and snapshot stay held, as on main. The redaction guard on
the merge-retry rebuild stays. A new test shows the brought-back decision
stays held and never reaches the remote.
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>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Make the behind= trailer and rebase rules agree across gstack docs (GST-2136)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the Capy skill inside its context budget after the behind= rewrite (GST-2136)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Skip the unset fix for a pin with a recorded reason, and add the changelog fragment (GST-2136)
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>
* Teach crews to keep work owned and treat outside PRs as bug reports (GST-2077)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Name the credit range and who posts a verdict in the outside-PR docs (GST-2077)
Review-Finding: p1/red-team#2 reader=red-team
Review-Finding: p1/red-team#3 reader=red-team
Review-Finding: p1/red-team#4 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Name the changelog fragment after the branch and mention the credit range (GST-2077)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Check fork authors before adding contributor credit (GST-2077)
Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Describe contributor PRs as rewritten fixes in the harness options table (GST-2077)
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>
* Keep quoted file names with secrets in review (GST-1451)
The review collector now decodes git's C-quoted patch headers, so the secret-line keep rule reads the added lines of a file whose name holds a quote, backslash or control byte. reviewExclude also keeps a matched file the collector holds no lines for, as unread.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Type the expected kept reasons in the quoted-name test
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Skip the quoted-name tests on Windows, which cannot create those names
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>
* Keep deferred review findings on the PR instead of filing issues
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Repin the ship review section after the deferred-findings lead edit
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the deferred record's severity as the plain label
The reviewer's stated severity and Blocks text now sit in their own field, so a review-log row built from a deferred record keeps a severity the ledger can rank. The PR body renders the same line as before.
Review-Finding: p1/adversarial-native#2 reader=adversarial-native
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say deferred findings stay on the PR in the unattended docs
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>
* Let the docs audit repair a badly shaped final line without using an attempt
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the audit id and outcome out of docs audit format repairs
A missing audit id or a missing or unknown status is now a content failure, a --repair-of that names a non-repairable output no longer uses up the audit's one repair, and the re-ask goes to a fresh agent with no tools instead of the writer child.
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
Review-Finding: p1/red-team#2 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Treat repeated identity keys and malformed outcome lists as failed docs audits
A repeated audit_id or status key, and a files_updated or blockers list that is present but malformed, are now content failures, so a format repair can no longer erase a reported blocker or choose the outcome. A missing list stays repairable.
Review-Finding: v1/outside-voice#1 reader=outside-voice
Review-Finding: v1/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>
* Stop flagging test run numbers in PR descriptions as phone numbers (GST-2047)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Let approval import record autoplan run ids that look like phone or card numbers (GST-2047)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Read versions beside a VERSION file or a semver as versions, not public IPs (GST-2047)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say pre-merge checks in the changelog entry (GST-2047)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the phone-number check on run-id fields that hold other text and on run id names (GST-2047)
Review-Finding: p1/red-team#1 reader=red-team
Review-Finding: p1/specialist-batched#1 reader=security
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Exempt only 11 to 20 digit run numbers in a ship summary block from the phone-number check (GST-2047)
Review-Finding: v1/adversarial-native#2 reader=adversarial-native
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>
* Keep local paths out of the approvals table and add render --redacted
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Label local paths in the Asked and Still pending columns too
pathLabels now covers file:// URIs, ~user, $HOME, %USERPROFILE%, UNC and Drive-relative paths, and the approvals table runs it on Asked and Still pending as well as Covers. Exact words stays verbatim.
Review-Finding: p1/red-team#1 reader=red-team
Review-Finding: p1/specialist-batched#1 reader=security
Review-Finding: p1/specialist-batched#2 reader=testing
Review-Finding: p1/red-team#2 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Label paths glued onto a colon or dash, and file: in any case
Only a :// scheme prefix now keeps a slash path unlabelled, so ledger:/home/..., user@host:/home/... and run-/home/... get file-name labels, and file:/ and FILE:/// paths match. Granted fix-check a-5b68cd273658.
Review-Finding: p2/adversarial-native#1 reader=adversarial-native
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>
* Stop the focused-test tag from keeping run data in review (GST-2006)
RH-1's skip, focus and removed-declaration checks now read only files a test runner can execute: source files by extension, extensionless scripts, test-folder or project-glob files that are not data, and files renamed from one of those. English like "don't fit (" in a results .jsonl no longer tags the file and keeps it in the reviewers' diff under review_exclude_paths (harness-evals#333).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep RH-1 on every file except data and logs
Review found that the code-extension allowlist dropped RH-1 from an HTML browser suite, unlisted languages, and a test-floor file renamed to data. RH-1 now skips only .json, .jsonl, .ndjson, .csv, .tsv, .log and .out files that were not renamed from another kind of file.
Review-Finding: p1v/outside-voice#1 reader=outside-voice
Review-Finding: p1v/outside-voice#2 reader=outside-voice
Review-Finding: p1v/targeted#1 reader=targeted
Review-Finding: p1v/adversarial-native#2.1 reader=adversarial-native
Review-Finding: p1v/adversarial-native#2.2 reader=adversarial-native
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>
* Keep the scroll selector when --wait is absent
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Skip a PATH browse that links to another program such as xdg-open
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Give each project its own browse slug on installs without ~/.claude
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep a question marker when its signal hint is malformed
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Read the lowercased question id in the never-ask preference hook
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep a marker's tail in the one-way door check
Review-Finding: p1/targeted#1 reader=targeted
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep a marker's tail apart from the next word in the one-way door check
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>
* Say where old domain skills live and narrow the marker note in the changelog
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say how the browse daemon picks a project's domain skill file
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>
* Add failing tests for fix-check chains whose earlier links found issues (GST-1973)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Count fix-check chains whose earlier links found issues a later clean link read (GST-1973)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* List the new follow-up review test with the other release-script tests in the test-only ratchet (GST-1973)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Match finding paths written with a leading ./ and test the remaining refusal guards (GST-1973)
Review-Finding: p1b/specialist-batched#1 reader=testing
Review-Finding: p1b/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Name the changelog entry after the branch and say it in plain words (GST-1973)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Reword the changelog entry in plain words without tracker codes (GST-1973)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Refuse a follow-up review chain when no later clean review read an earlier finding's file (GST-1973)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say in the changelog entry that a finding no later clean review read now refuses the chain (GST-1973)
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>
* Report free-suite results to Trunk Flaky Tests for detection only (GST-1859)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say that test files that time out or crash do not reach Trunk
Review-Finding: p1/red-team#2 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep a failed JUnit upload from failing a free-suite shard, and correct what the docs say about timed-out children
Review-Finding: p11/outside-voice#1 reader=outside-voice
Review-Finding: p1fc/fix-check#1 reader=fix-check
Review-Finding: p1fc/fix-check#2 reader=fix-check
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say the Trunk uploader job also sees a secret in Free Tests
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>
* Add failing tests for repo-declared docs-only paths (GST-1974)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Let a repository name its own docs-only paths in its base ship policy (GST-1974)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Catch relative directory readers, missing docs tests and readers the base gained in the docs-only class
Review-Finding: review/specialist-batched#1 reader=security
Review-Finding: review/red-team#1 reader=red-team
Review-Finding: review/red-team#2 reader=red-team
Review-Finding: voices/adversarial-native#1 reader=adversarial-native
Review-Finding: voices/adversarial-native#3 reader=adversarial-native
Review-Finding: voices/adversarial-native#5 reader=adversarial-native
Review-Finding: voices/outside-voice#1 reader=outside-voice
Review-Finding: voices/outside-voice#2 reader=outside-voice
Review-Finding: voices/outside-voice#3 reader=outside-voice
Review-Finding: voices/outside-voice#4 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Say in the changelog that a missing docs test or a new base reader keeps the full checks
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Describe the new directory-reader forms, the missing docs test refusal and land's base-reader 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>
* Make the autoplan docs say what lean and full runs actually load (GST-1985)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the autoplan description at its size pin and say when the eng checklist is sent
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>
* Let review exclusions handle big results PRs (GST-1967)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the value rule in review-exclude so the pinned review-risk rules stay at their replayed bytes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Reword the changelog entry so its credential sentence reads plainly
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>
* Let pull requests that only change human-facing docs skip the test suites (GST-1951)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Quote the docs test list in the docs lane so shellcheck passes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the Windows smoke check green on docs-only pull requests and update the workflow contract tests
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the merged test check when the base gained a reader of a changed doc, hold the land policy key until a release reads it, and register two more docs reader tests
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Check links in untracked docs and docs with quoted or spaced names, and report an undecodable anchor instead of crashing
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Point the flaky-exception anchor back at its section and test the link checker's exit codes
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>
* Stop pregate flagging real files whose names start with tmp or scratch (GST-1944)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Make the stray-name test safe on case-insensitive disks and record the tmp-word tradeoff
Review-Finding: p1/specialist-batched#1 reader=testing
Review-Finding: p1/red-team#2 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Describe the new scratch-name rule in the PREGATE_STRAYS troubleshooting entry
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>
* Stop macOS EPERM marking a finished QA capture as incomplete
On macOS the cleanup kill of an exited command's process group can get
EPERM while the group is being torn down, and the capture then recorded a
successful command as incomplete with exit code 2. On EPERM, check the group
directly (kill with signal 0, then a ps listing that ignores zombie and
exiting entries) and treat it as gone only when no live member remains.
A live member or a failed check keeps the fail-closed result.
Co-authored-by: vilano93 <244097767+vilano93@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep the EPERM group check to macOS so Linux still fails closed
Review-Finding: p1/red-team#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Count exiting macOS group members as gone after a refused group kill
On macOS, ps shows a process that is exiting with a trailing E flag
(for example RE or UE), so a check on the leading letter alone read a
mid-exit member as live and kept the capture incomplete. Count a member
as gone when its state starts with Z or carries E; X means traced on
macOS, so it stays live. Linux is unchanged and still fails closed.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Document the macOS EPERM exception in QA deadline cleanup
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: vilano93 <244097767+vilano93@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Load the Capy crew skills only on Capy machines (GST-1833)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Add changelog entry for Capy-only crew skills (GST-1833)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Move the Capy-only crew tooling into crew/ and run its tests only when needed (GST-1833)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Test that the Capy launch file puts crew/bin on PATH
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Count any ~/.capy as a Capy machine, so a Mac running Capy keeps /captain
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Fix the tests and fixtures that broke when crew tooling moved into crew/
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Plan every crew test when a pull request's merge-base can't be read
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Add a test that checks each crew-only module left the root tree for crew/
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Run crew tests on pull requests that change bin/ commands or workflows they drive
Review-Finding: p1/specialist-batched#1 reader=testing
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep running every crew test on every pull request; the skip comes in a later change
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Keep copied installs and older release bisects working after the crew/ move
Setup now copies crew/lib into every host's runtime root beside bin and lib, so Windows installs (which copy instead of linking) can still start gstack-ship-receipt, gstack-pregate and the other commands that import it. The release bisect runs the train-gate script from wherever the checked-out commit has it, so a bisect over commits from before the move still gets a verdict.
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>
* Say in the changelog that Windows installs keep working after the crew/ move
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Point the harness guide's merge-queue rows at crew/lib/ where those modules moved
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Point the plain-title test at the wave module's new home in crew/ (GST-1833)
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>
* Give a clear error when Chromium's sandbox can't start, and make design-build preflight launch the browser (GST-1906)
On Linux hosts that deny unprivileged user namespaces (stock Ubuntu 23.10+ under AppArmor, non-root Docker), Chromium aborts with "No usable sandbox!". browse now fails with one error naming both fixes (allow user namespaces, or GSTACK_CHROMIUM_NO_SANDBOX=1 for trusted pages only) with Chromium's line below it, and never turns the sandbox off on its own. Docker's /.dockerenv now counts as a container, like CONTAINER. gstack-design-build preflight opens and closes one tab in the browser it found and stops with code=BROWSER_SANDBOX and the same error when that launch fails.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Reword the Chromium sandbox changelog entry (GST-1906)
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>