mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-01 06:24:41 +01:00
1bec403bbafaf6edd93345c773ccfd97ca9f4e70
82
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5358a3b384 |
v1.91.326.0 feat(ship): reviewers read one packet; the parent reads a compact findings record (GSTA-167) (#3621)
* feat(ship): reviewers read one packet; the parent reads only a compact findings record (GSTA-167) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(GSTA-167): keep the pinned CODEX_BOUNDARY literal in the resolver; a test holds the packet boundary equal to it Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(GSTA-167): a Step 7/8 audit is one packet, never sharded Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(GSTA-167): packets survive the replay: base as given, budget roles, read= ranges, data summaries, no stale partial manifest - --base origin/main no longer renders origin/origin/main (resolveBaseRef shared by build and audits) - PACKET lines carry budget_role and read= ranges under 30,000 bytes; build prints BUDGET_NEXT for gstack-ship-budget --next - each packet ends with END OF PACKET; the brief reads it with the read tool in parallel ranges, about 3 calls - .json/.jsonl/.ndjson/.csv/.tsv additions past 400 changed lines reach reviewers as a DATA SUMMARY - a partial build keeps other reviewers only at the same head, base and diff content - collect: a matrix counts only from a state-machines reviewer; a CRITICAL line failing validation is invalid Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(GSTA-167): pass-2 review fixes: data summaries read only the diff, a stale Red Team build refuses, any-case CRITICAL lines - topLevelKeys takes keys and columns from the diff's own lines, never the working tree, which a symlink can point at a private file (outside voice CRITICAL) - a --findings build whose head, diff base or content differs from the manifest refuses with STALE_MANIFEST instead of dropping the specialists' coverage (adversarial + Red Team) - collect: a CRITICAL line in any case, or one that fails to parse, makes its reviewer invalid (Red Team) - docs and the misplaced Value header in the review-packet tests Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(GSTA-167): CHANGELOG entry for reviewer packets; ship-budget names BUDGET_NEXT as the --next value 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> |
||
|
|
dcd62c389d |
v1.91.325.0 fix(ship-budget): thresholds above the host call floor; children hand off instead of stopping; batches admit a prefix (GSTA-167) (#3620)
* fix(ship-budget): calibrate projections from the run's own meter, settle dispatch reservations when reviewers return (GST-101) The /ship budget projected every step and dispatch from fixed constants (7.43M per dispatch, 2.25M per default step) plus a fixed 4.48M reserve, so real caps refused work that cost 3-20x less (GSTA-152 PR B, GSTA-2). Each settled reservation is now measured on the next reading, and the run projects with its own factor (max actual/prior of its last three measurements x 1.5), the prior only before the first measurement. The default tail reserve scales with the step factor; the stop overhead keeps its fit. Reservations of reviewers admitted one at a time no longer pile up: check --returned settles named dispatches, --finish settles the pass's dispatches of that step, and a step change settles consumed dispatches. DRIFT and BUDGET_DRIFT lines print projected against actual. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (GST-101) Unseen charges (settle --unknown, a Claude-metered outside voice) are booked at their reservation and never measured, so they cannot shrink the dispatch factor. The handoff holds back the same calibrated reserve as check, so a delegate verdict is one the handoff admits. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(ship-budget): handoff sub-cap subtracts unknown charges and the calibrated reserve Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: changelog (Unreleased) for GST-101 ship-budget calibration Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(ship-budget): give the GSTA-152 PR B replay an explicit 120s timeout It spawns about 100 CLI processes; on windows-latest it ran past the shard runner's 30s per-test timeout (windows-free-shard 5, run 40917695070), and on 2 cores it sat at bare bun test's 5s default. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(ship-budget): thresholds above the host call floor; a child hands off instead of stopping; parallel batches admit a prefix (GSTA-167) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(ship-budget): a child returns incomplete while a grandchild is unreconciled or an ADMIT remainder was never re-checked; join a child's meter only after its handoff succeeds (GSTA-167) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(troubleshooting): BUDGET_CAP_REACHED admits a fitting prefix of a reviewer batch (GSTA-167) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: changelog (Unreleased) for GSTA-167 handoff floor Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: move GSTA-167 changelog entry into [Unreleased] Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.325.0 stamp Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
319ef500ca |
v1.91.320.0 fix(pregate,gstack-post): PREGATE_NO_LANE names the base policy when a branch adds its own lane; pr-body refuses a body holding a title twice (#3579)
* fix(pregate,gstack-post): PREGATE_NO_LANE names the base policy when the branch adds its own lane; pr-body refuses a body holding a title twice Fixes #3574 Fixes #3575 Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(ship): pr-body stops and reports a duplicate-title refusal instead of the by-hand path gstack-post pr-body now exits 64 when the PR's current body holds a title twice. Step 19 read every 64 as 'no usable remote or CLI'; it now stops and names the duplicated titles, and never reposts with --replace itself, since a person picks which copy stays. Size ledger records the +281 bytes. Fixes: #3575 Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: pin the own-policy fix line's guards, its user-policy source and receipt duplicates A head-policy run and a branch deleting pregate.json get the plain fix; under a user-owned policy the line names the user file; a body with two receipt blocks refuses like a doubled title. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): Unreleased entry for the PREGATE_NO_LANE own-policy line and the pr-body duplicate refusal 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> |
||
|
|
9f44f188d1 |
v1.91.317.0 feat(harness): trigger-first skill descriptions, hybrid OpenClaw layout, opt-in --context block (GSTA-135) (#3555)
* test(harness): pin the GSTACK_SESSION_KIND=spawned marker and its readers (GSTA-135) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * feat(harness): trigger-first skill descriptions, hybrid OpenClaw layout, opt-in --context block (GSTA-135) Router lines and Hermes leads open with the skill's triggers; OpenClaw defaults to hybrid (five task skills plus the router); --context writes the routing block only into a named file, refusing SOUL.md and any new Hermes rules file that would outrank one Hermes loads now. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(harness): skill-use layout, --context and HARNESS_CONTEXT_REFUSED (GSTA-135) 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> |
||
|
|
c85dd0a799 |
v1.91.316.0 ship: token cap with real meters and fresh-context delegation (GSTA-152 PR A) (#3593)
* ship: token cap with real meters and fresh-context delegation (GSTA-152 PR A) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (stopped or lost capped run no longer blocks uncapped review starts; short child return reconciles incomplete) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: carry estimate spend across a meter epoch change; calibration docs match their evidence Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: load the committed calibration file by its repo path so pregate maps it to a lane Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * ship: fix fence placeholders and register claude-usage fixture (GSTA-152 PR A) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: run ship-budget and review-log bins through their interpreters so Windows can launch them Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
f59b3435d5 |
v1.91.315.0 ship-receipt: carry a stacked child after its parent lands (#3572)
* feat(ship-receipt): carry across regenerated outputs and onto a reviewed tree after a rebase
A base merge whose only product-side change is a registered output the
pregate regen check proved fresh now carries the receipt. A rebased head
carries when its tree is one the receipt covers and its product patch-id
against the current base matches (RECEIPT_CARRY_TREE_MISMATCH otherwise).
Docs: merge main into a reviewed branch, never rebase it.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: regenerate doctor anchors; type the head_tree assert
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(review): proportional /ship review depth (light, standard, full)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: carry sets aside only outputs the regen check proved it recreates
The regen check deletes each touched output in its scratch worktree before
the command runs and records the ones recreated byte-identically as proven.
gstack-ship-receipt carry exempts only those paths, and only when the check
ran origin/<base>'s registry at the commit the carry reads. A file under an
output glob that the generator never writes stays product (pre-landing
review, #3564 pass 1).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-receipt): record review depth, check it in the queue, structured review-loop exception (#3559)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: prove generated outputs in a second regen run; literal names only
The regen verdict comes from the unmodified run again, so a generator that
reads its own registered output (gen-skill-docs and
qa/templates/functional-report-template.md) passes as before; the proof is a
second run with the touched outputs deleted, and its failure only means not
proven. The carry ignores a proven path with glob syntax, since it uses the
paths as pathspec globs (pre-landing review, #3564 pass 2).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: receipt evidence keys and carry record fields; carry refusal fix line
Documentation audit for #3564 (/document-release, audit ship3564-docs-1).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (depth scan binding, queue scope, carry checks)
- carry refuses a --head other than the checked-out HEAD, a receipt with
gstack_version but no review_depth, and an owner exception that no longer
stands; a dirty or foreign checkout makes the write-time gate scan
unavailable (full)
- the queue binds a gate scan only to the full bound commit and recomputes
the scope signals with gstack-diff-scope <base> --head <sha>, the same
range the writer uses
- the queue checks the review-loop exception's fix-check ancestry
- a package.json version line counts as stamp-only only when it is a bare
version key
- docs and help name what review_depth is and which registry the queue reads
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: CHANGELOG for the review fixes; defer two plan items to TODOS
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-receipt): carry a stacked child after its parent lands (#3570)
When the carry base differs from the receipt's (a stack parent landed and
the PR was retargeted), the receipt carries only when HEAD's product diff
against the base equals the range reviewed against the parent branch.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: queue and carry refusal lists name the depth and exception codes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
A retargeted carry compared the reviewed range with a patch-id whose pathspec
came from the reviewed head..HEAD range, so a parent's package.json change
that never reached the base dropped out and the receipt carried. Compare with
HEAD's whole product patch-id against the base (the one write records), rebind
the receipt's base on a retarget carry, and cover the parent-metadata, landed-
with-changes and test-only-child cases.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: approval-classes summary-line regexes allow the receipt's depth field
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: troubleshooting names the stacked-retarget carry refusals
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-receipt): summary line prints depth before approval
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Revert "test: approval-classes summary-line regexes allow the receipt's depth field"
This reverts commit
|
||
|
|
0cab97447c |
v1.91.314.0 feat(autoplan): carry the owner's answer forward, gate ELI5 field, stacked approvals import (#3583)
* refactor: share the decision-trail append rules (lib/decision-trail.ts) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * feat(autoplan): carry the owner's answer to a later gate that asks nothing new, gate.json eli5, stacked approvals import A later gate revision with nothing new is answered with the owner's recorded words (CARRIED); a 'do it' also covers new auto items that change no scope, cost or direction; an unreviewed post-cap delta gets one cross-family reviewer first (CARRY_CHECK, gstack-autoplan check). gate.json gains eli5 and the Captain brief requires ## ELI5 on runs that carry it. gstack-approvals import --stack writes every branch or none. The first next prints REVIEW_ESTIMATE. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: carry-forward, ELI5 section and stacked approvals import Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(autoplan): carry only fully owner-answered gates; void stale delta checks - a pending delta check is voided (reservation released) when the owner answers, the plan is revised, or a new gate is written; a check bound to an older delta is void - carry refuses a gate with any approval item still pending or answered in item tokens - "do it" never covers an option that changes the plan; isDoIt ignores Captain-relayed prefixes - captain brief rebuilds ELI5 from the current plan and lists items taken under "do it" - gstack-approvals import --stack locates every branch before writing any - DRIVER.md back under its 162-line budget Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: carry-forward conditions, delta-check voiding and import --stack match the final code Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: changelog for autoplan carry-forward (unreleased; stamped at merge) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: stamp v1.91.314.0 Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
81a82727b3 |
v1.91.313.0 fix(redact): pii.phone skips bare numeric constants; pii.email skips package@version filenames (#3578)
* fix(redact): pii.phone skips bare numeric constants; pii.email skips package@version filenames Fixes #3577 Fixes #3576 Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(redact): pii.email reports a file named after an address looksLikeAtFilename exempted any span whose domain ended in a non-TLD extension, so an address inside a filename (an export named after the address plus .json) went unreported. Strip the trailing extension run and exempt only when what precedes it cannot be a domain (one dotless label or a dotted version). The dotted-version branch now requires an extension that doubles as a TLD, so an address at an all-digit subdomain still reports. Regression rows pin both. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: note the constant and @-filename redact exemptions; CHANGELOG under Unreleased 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> |
||
|
|
16fd7a7dbd |
v1.91.312.0 fix(capy-session): an install inside /ship no longer upgrades gstack under it (#3571) (#3573)
* test(capy-session): an install inside a leased run must not upgrade (#3571) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(capy-session): defer the self-upgrade while this session's own run holds the lease (#3571) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): an install inside /ship no longer upgrades gstack under it (#3571) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(capy-session): bound the own-run deferral by the lease's age so Capy machines still upgrade (#3571) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): prose lint, no mid-sentence colon (#3571) 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> |
||
|
|
94165fff39 |
v1.91.311.0 feat(pregate): sealed.allow_paths exceptions and opt-in case_insensitive deny globs (GSTA-145) (#3556)
* feat(pregate): sealed.allow_paths exceptions and opt-in case_insensitive deny globs (GSTA-145) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): sealed allow_paths and case_insensitive (Unreleased) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(pregate): state exactly which allow_paths file names are refused Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(troubleshooting): sealed allow_paths exemption and newer-gstack sealed keys 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> |
||
|
|
edf4c2e581 |
v1.91.307.0 ship: proportional review depth (light, standard, full) with depth-checked receipts (#3567)
* feat(ship-receipt): carry across regenerated outputs and onto a reviewed tree after a rebase
A base merge whose only product-side change is a registered output the
pregate regen check proved fresh now carries the receipt. A rebased head
carries when its tree is one the receipt covers and its product patch-id
against the current base matches (RECEIPT_CARRY_TREE_MISMATCH otherwise).
Docs: merge main into a reviewed branch, never rebase it.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: regenerate doctor anchors; type the head_tree assert
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(review): proportional /ship review depth (light, standard, full)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: carry sets aside only outputs the regen check proved it recreates
The regen check deletes each touched output in its scratch worktree before
the command runs and records the ones recreated byte-identically as proven.
gstack-ship-receipt carry exempts only those paths, and only when the check
ran origin/<base>'s registry at the commit the carry reads. A file under an
output glob that the generator never writes stays product (pre-landing
review, #3564 pass 1).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-receipt): record review depth, check it in the queue, structured review-loop exception (#3559)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: prove generated outputs in a second regen run; literal names only
The regen verdict comes from the unmodified run again, so a generator that
reads its own registered output (gen-skill-docs and
qa/templates/functional-report-template.md) passes as before; the proof is a
second run with the touched outputs deleted, and its failure only means not
proven. The carry ignores a proven path with glob syntax, since it uses the
paths as pathspec globs (pre-landing review, #3564 pass 2).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: receipt evidence keys and carry record fields; carry refusal fix line
Documentation audit for #3564 (/document-release, audit ship3564-docs-1).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (depth scan binding, queue scope, carry checks)
- carry refuses a --head other than the checked-out HEAD, a receipt with
gstack_version but no review_depth, and an owner exception that no longer
stands; a dirty or foreign checkout makes the write-time gate scan
unavailable (full)
- the queue binds a gate scan only to the full bound commit and recomputes
the scope signals with gstack-diff-scope <base> --head <sha>, the same
range the writer uses
- the queue checks the review-loop exception's fix-check ancestry
- a package.json version line counts as stamp-only only when it is a bare
version key
- docs and help name what review_depth is and which registry the queue reads
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: CHANGELOG for the review fixes; defer two plan items to TODOS
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: queue and carry refusal lists name the depth and exception codes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: approval-classes summary-line regexes allow the receipt's depth field
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-receipt): summary line prints depth before approval
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Revert "test: approval-classes summary-line regexes allow the receipt's depth field"
This reverts commit
|
||
|
|
de4c694d91 |
v1.91.306.0 ship-receipt: carry across regenerated outputs and onto a reviewed tree after a rebase (#3564)
* feat(ship-receipt): carry across regenerated outputs and onto a reviewed tree after a rebase A base merge whose only product-side change is a registered output the pregate regen check proved fresh now carries the receipt. A rebased head carries when its tree is one the receipt covers and its product patch-id against the current base matches (RECEIPT_CARRY_TREE_MISMATCH otherwise). Docs: merge main into a reviewed branch, never rebase it. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: regenerate doctor anchors; type the head_tree assert Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: carry sets aside only outputs the regen check proved it recreates The regen check deletes each touched output in its scratch worktree before the command runs and records the ones recreated byte-identically as proven. gstack-ship-receipt carry exempts only those paths, and only when the check ran origin/<base>'s registry at the commit the carry reads. A file under an output glob that the generator never writes stays product (pre-landing review, #3564 pass 1). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: prove generated outputs in a second regen run; literal names only The regen verdict comes from the unmodified run again, so a generator that reads its own registered output (gen-skill-docs and qa/templates/functional-report-template.md) passes as before; the proof is a second run with the touched outputs deleted, and its failure only means not proven. The carry ignores a proven path with glob syntax, since it uses the paths as pathspec globs (pre-landing review, #3564 pass 2). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: receipt evidence keys and carry record fields; carry refusal fix line Documentation audit for #3564 (/document-release, audit ship3564-docs-1). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
f4f16e83e0 |
v1.91.305.0 feat: render gstack per model with modules left out, measured before any model gets less (GSTA-140 PR 1a) (#3554)
* feat(modules): module catalog, per-model loadouts manifest and gstack-modules render (GSTA-140 PR 1a) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(modules): cover bin/gstack-modules and the loadouts schema; allow modules/ in pregate strays Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(modules): gen:skill-docs refuses an exclusion render without --out-dir; render tests set up their own arm Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(modules): skill exclusions honor pinned sections and section references; own-property loadout lookups; llms.txt follows the selection; ownership rechecked before swap Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: bump version and changelog (v1.91.296.0) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: loadout render cost and the modules/ directory in PROJECT_STRUCTURE Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: unstamp #3554 (slot calls stamp); CHANGELOG entry back under [Unreleased] 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> |
||
|
|
61e201ec08 |
v1.91.295.0 fix(pregate): deleting or renaming a test no longer fails lanes (#3534)
* fix(pregate): removed paths owe no lane instead of failing PREGATE_NO_LANE A deleted file or a rename's old name that no remaining test selects now prints 'removed (no lane owed): <path> — <why>' in lanes: a deleted test runs its owning suite or names the files that lost their last test; a modified file whose only test was deleted still fails, and an unreadable deleted test fails closed. Fixes: #3529 Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pregate): pre-landing review fixes for removed paths A removal owes what an edit owes: manifests, lockfiles, config, fixtures, goldens, workflows and files a config still names keep PREGATE_NO_LANE. A test reading a fully deleted directory is selected again, a deleted Rust module selects its crate's tests, a test renamed to a non-test path is accounted as deleted, and the owning suite is the tests that directly exercise the same files. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pregate): a removed file remaining code still imports fails closed Pass-2 red-team: namedBy matched only full repo paths, so a deleted module imported by a relative, extensionless or dotted specifier from untested code was waived. removedPath now refuses when the import graph shows a remaining dependent. Stale headers updated to say other removals owe what an edit owes. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pregate): removals the graph cannot see stay fail-closed Step 11 adversarial and outside-voice findings: the waiver trusted SOURCE_EXT, so Go, Ruby, shell, Rust and bin removals, files loaded by name and files a nested config names relative to itself passed with no test; a rename's old name skipped every check. Now every removed path is refused while a remaining file imports it (directory references included); only JS, TS, Python and Dart code is waived, never a file loaded by name; namedBy also matches paths relative to each ancestor directory; Go and Ruby tests are refused; a rename's old name goes through the same checks unless it is a test renamed to a test. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pregate): basename mentions and Go/Ruby test renames fail closed Fix-check 2 (cycle 4, rule 23 grant from GStack Minder): a deleted file a tested loader reached by path.join(__dirname, 'lib', 'value.js') was waived, and a Go helper test renamed into another directory got the test-rename exemption. namedBy now greps the basename repo-wide (non-Markdown); the Go and Ruby test refusal runs before the rename exemption. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(pregate): align removed-path prose with the waiver rules Ship docs audit (gsta137-docs-1): name the snapshot, baseline and .gstack/ trees the waiver excludes, add usercustomize.py to the loaded-by-name list, and give the unreadable-deleted-test explain line. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: bump version and changelog (v1.91.292.0) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: a removed test runs the tests of files that still name it (pregate lanes) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pregate waives only removed tests; other removals owe what an edit owes (D3 narrowed by the controller) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: a removed test is named by any whole-word mention of its name without the extension (pregate lanes) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: a removed test is named by any mention of its name without the extension (pregate lanes) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: unstamp (VERSION back to 1.91.291.0, CHANGELOG entry under [Unreleased]); the slot call stamps Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: CHANGELOG [Unreleased] entry passes the prose-lint gate Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.295.0 fix(pregate): deleting or renaming a test no longer fails lanes 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> |
||
|
|
9e3308f65a |
v1.91.293.0 fix(harness): error lines print again; register qm stops at QM's pack cap instead of claiming QM works (GSTA-135) (#3532)
* fix(harness): print error lines again; register qm stops before QM's pack cap instead of claiming QM works Bun gives every thrown Error an own numeric 'line' property, which shadowed HarnessError.prototype.line(), so every refused gstack-harness command crashed with 'e.line is not a function'. The printer is now report(). QM imports a skill pack by cloning the whole repository and refuses past 32 MiB / 5,000 files (Harness Evals preflight, HARN-5); gstack's repository is 73 MiB in 4,280 files. register qm now measures first and stops with HARNESS_QM_PACK_TOO_LARGE before any request; QM's own cap refusal maps to the same code. docs/hosts.md lists QM as not available yet. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * s Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(harness): read QM's recorded import error for the cap; refuse to size a non-git checkout; skip symlinks like QM Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: drop a stray a/SKILL.md committed by a scratch experiment Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: no doc implies QM registration works (document-release audit) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(install): stable's 72-hour rule also excepts a regression fix (#3533) 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> |
||
|
|
148d28ea81 |
feat(ship): /ship and /autoplan size their review to the diff (GSTA-131) (#3527)
* wip(GSTA-131): review depth, fix-check transitions, dispatch counters, carry pregate, autoplan round policy Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * wip(GSTA-131): reviewers stay at full effort; audits light Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * feat(ship): Step 9 dispatches what gstack-review-plan plans; fix-check after below-floor fixes; cap two full passes plus one fix-check Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: review-dispatch-compare has a free lane; review-depth fixtures registered free; resumed max_rounds case off the old default Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(GSTA-131): ship review pass-1 repairs: fix-check binds under its own skill, Step 11.5 accepts a fix-check or a planned adversarial skip, delta carry with a pregate, carry --pregate pinned to the checkout, quiet-after-cap revise regates, skill-dir markdown and rule docs classed code, gate signals from tests class up, plan fails closed on git errors, per-class compare ratios Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(GSTA-131): ship review pass-2 repairs: Step 11 follows the last full-pass plan, Important Rules restored, ship goldens regenerated, true per-class medians, review-policy transitions and once-per-invocation voices, docs/** assets stay docs-class, CLI and fix-check binding tests Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): GSTA-131 review depth, fix-check, delta /ship and autoplan rounds Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: ship-policy cap and counters, review-policy /review cycle cap, unattended passes (docs audit) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(review): 400-word findings cap fits the /review size pins (five host pins lowered by 2); CHANGELOG max_rounds wording Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): gate integrity names the size-ledger entry and the lowered /review pins Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: the round-budget case asserts the default through ROUNDS output only (pregate literals heuristic) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: curate ship-receipt-carry-pregate out of the Windows lane like its --pregate siblings Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): end the Windows curation sentence instead of a mid-sentence colon Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(ship): one decision each for the review-loop exits, the planned adversarial skip and Step 16's TODOS rerun (screen judge repair) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(ship): fix-check repairs: pin the renamed Step 11 heading, keep the below-floor exit at the cap, name the plan run a repeat reuses, print the native skip on outside-only plans Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
44f19d0106 |
v1.91.290.0 feat(harness): gstack registers its skills in whatever agent harness it is installed into (GSTA-135) (#3526)
* wip: gstack-harness registrar (GSTA-135) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * wip: harness registration in setup, uninstall, tests Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * wip: harness hosts experimental, troubleshooting codes, kit Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: agent harness registration (GSTA-135) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: harness hosts run in place from the checkout in --status Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: bun-free ledger reader Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: CHANGELOG for harness registration (Unreleased) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(harness): keep edits beside themselves, never follow symlinks, cut only gstack's own context block Review blockers on #3526: uninstall deleted the edit backups under the state root; unregister followed a symlinked folder below the destination; a lone or edited context marker made the cut eat user lines; a re-register adding --context left an unrecorded block. Also: ledger written before the files, --refresh-registered no longer re-runs harness hosts through setup (gstack-harness refresh keeps their mode), bash goes through runBashSync, and setup tests follow openclaw/hermes becoming installs. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(harness): a ledger with no destination row touches nothing (no hang) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: harness registration in README, install and hosts (document-release 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> |
||
|
|
398618259d |
v1.91.286.0 feat(ship-queue): the ship size cap composes across a merge train; verify refuses a stale all-merged train (#3519) (#3522)
* feat(ship-queue): the ship size cap composes across a merge train; verify refuses a stale all-merged train (#3519 b, c) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (runnable clear-time NEXT, stale exit only on a fetched main, open-slot freeze control, LF size-ledger fixture) - verify's clear-time NEXT names gh pr view <n> --json state,headRefOid per unreadable slot instead of a pasteable #n@sha that views the current branch's PR - QUEUE_TRAIN_STALE needs a fetched main (never under --no-fetch) and reports a freeze restored from the notes ref instead of saying the queue is not frozen - freezeQueue docstring matches the unreadable field - new test: a train with a slot still OPEN freezes even when another train verified main's sha - test/size-ledger.test.ts fixture repo sets core.autocrlf false (Windows Free Tests shard 4 counted CRLF bytes) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: CHANGELOG [Unreleased] entry for the ship size ledger and QUEUE_TRAIN_STALE Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: run scripts/size-ledger.ts (check on this tree, refusals write nothing) The remote pregate refused |
||
|
|
9ccb5233f3 |
v1.91.282.0 fix(ship-queue): one CHANGELOG rule before and after the merge, base keys stay in slot stamps, a stacked child carries past its released parent (#3518)
* Ship-queue train tooling: one CHANGELOG rule, base keys stay, stacked-child carry (GSTA-129) Four train-24 (GSTA-96) defects in one change. verify --train applies the same CHANGELOG rule before and after the merge: main's CHANGELOG plus the PR's own lines (its authored diff plus what mergeChangelogs writes for it). A head the pre-merge verify accepted no longer freezes the queue after its squash merge, and a freeze record lists a slot GitHub reports MERGED as merged. restamp's stamp_paths stage leaves a *_KEY_VERSION line the base introduced after the fork point alone, base merge committed or staged, and says so. mergeChangelogs with a base carries a stacked child's edits to its released parent entry as "Correction to the <version> entry below" bullets under the child's own Gate integrity section instead of returning null; the slot one-liner prints each carried correction. #3453's two 1.91.276.0 corrections are restored that way here. The digest-freshness defect is already closed by #3451 (regeneratedAtBase); docs/ship-policy.md now says how an unstamped generator change ships. Docs: ship-policy § Run a merge train, captain.md § Merge trains and the slot-call template carry the stamp-files and stacked-child rules. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Review fixes: carried union from slot 2, GitHub-merged slot-1 freeze, no-own-entry refusal, fail-closed base diff (GSTA-129) Pre-landing review pass 1 (six specialists and the Red Team, all INFORMATIONAL): - mergeStep unions the carried child from slot 2 on, so a stacked child behind another slot never repeats its released parent's text under a second [Unreleased] (Red Team, lib/ship-queue-train.ts). - stopped() freezes the queue when any slot is MERGED on GitHub, so a slot-1 squash that fails the post-merge check no longer answers "nothing merged" (Red Team, lib/ship-queue-train-verify.ts). - ownEntryAboveMain refuses a CHANGELOG equal to main's: no entry of the PR's own (state-machines, lib/changelog-check.ts). - branchAddedLines refuses when the base diff cannot run instead of reading it as "nothing added" (Red Team, lib/restamp.ts). - slot-call.md and docs/captain.md name the stamp files as the ones the slot call names, STAMP_FILES plus a *_KEY_VERSION file the PR introduced, matching docs/ship-policy.md (maintainability). Also: the coverage tests Step 7 added (post-merge parent check, carry shapes), and two dependency-map rows (test/helpers/free-fixtures-data.ts for the merge-train-3453 fixtures, scripts/test-pr-profile.ts for captain/templates/**) so the paid-gate selector and the FREE_FIXTURES inventory accept the new files. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Review pass 2: an unreadable GitHub state at a failed slot refuses, never "nothing merged" (GSTA-129) stopped() read prState's 'unreadable' as "not merged": with nothing in t.merged, a slot-1 squash already on main while gh pr view failed answered "nothing of the train merged, so the queue is not frozen". It now refuses with QUEUE_PROOF_MISSING ("whether #<n> merged on GitHub could not be read, so whether the queue must freeze is unknown") and asks for the verify to be rerun; no freeze, no backstop. Raised independently by five pass-2 reviewers. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Docs audit: troubleshooting codes and ship-policy sections match the shipped train rules (GSTA-129) The /document-release audit (edit mode) corrected two docs the PR had not reached: docs/troubleshooting.md's QUEUE_TRAIN_TREE_MISMATCH, QUEUE_PROOF_MISSING, QUEUE_TRAIN_FROZEN and POLICY_SOURCE_UNAVAILABLE entries, and docs/ship-policy.md's train build conflict rule (the carried stacked child is the exception), the verify freeze paragraph (slot-1 GitHub-MERGED freeze, unreadable-state refusal) and the restamp stamp_paths stage (base-added lines stay; an unrunnable base diff refuses). Five mid-sentence colons in the PR's own paragraphs are rewritten for the prose lint, and the CHANGELOG Docs bullet names docs/troubleshooting.md. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * HARNESS_VERSION: scripts/test-pr-profile.ts row recorded non-behavioral at version 6 (GSTA-129) The remote free tier's only red was the HARNESS_VERSION guard: scripts/test-pr-profile.ts is a pinned shared-harness file and gained the captain/templates/** FREE_ONLY_PR_FILES row. Recorded with bump-harness-version.ts --non-behavioral: no paid case reads the crew templates, so no selection, input or verdict changes and no pass-rate series resets. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: type the saved fixture PR row for the test-code ratchet (GSTA-129) CI's typecheck:test ratchet refused one new TS2698 (spread of a loosely typed fixture row) in the slot-1 freeze test; the row is read as any, as the neighbouring state writes already do. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * ship-queue verify: build the freeze record from the one GitHub read that decided to freeze freezeQueue took a second prState read per unverified slot and filed anything but an exact MERGED under unmerged, so a slot that read MERGED at stopped() and was unreadable a moment later was recorded as unmerged (the record half of train 24's #3453 misfile). stopped() now reads each unverified slot once and passes those states in; a MERGED slot stays merged, and a slot unreadable beside a merged one is kept out of unmerged and named in the reason. The fixture's gh shim gains a per-PR vanish count so a test can change GitHub's answer between two reads. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * ship-queue verify: say what happens to a slot unreadable beside a merged one The freeze reason, docs and CHANGELOG said the slot was kept out of unmerged 'until read', but nothing reads it again: the NEXT after the repair is built from unmerged alone. Say so (the operator seats it in a train by hand once gh answers) and pin the record shape with a test. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.282.0 stamp Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
b3e94a3f8d |
v1.91.279.0 eval:select exemptions and ETHOS.md registration (#3499), below-floor review rulings (#3504, #3485), Windows curation, GSTA-121 follow-ups (#3515)
* Eval selection exemptions, review-floor rulings and the GSTA-121 follow-ups Release metadata (NOTICE.md, LICENSE, licenses/**) no longer restores the full paid gate and ETHOS.md is registered under the two prompts that read it (#3499). docs/review-policy.md records the six finding classes #3485 and #3504 ruled below the floor and the review army's lead judgment applies the table; the floor itself is unchanged. The Windows curation moves test/pregate-remote-stamp-only.test.ts to KNOWN_WINDOWS_INCOMPATIBLE (#3485). From GSTA-121: Blast radius in docs/skills.md and the merge-ask template, the 11-digit run-id exemption from pii.phone.e164 after a run word, relative string literals as import-graph edges, and a ubi-runner pack that never tars the live .git. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes Red Team pass 1 (all below the floor): an 11-digit span with a leading 1 after a run word is a US or Chinese national number, not a run id, and reports again; ubi-runner pack removes its temporary repository when it fails and replays branch.* with remote.* so a branch's upstream resolves on the VM; the conservative-refusal example in docs/review-policy.md reads in the refusing direction; the touchfiles header names why ETHOS.md sits only under the two prompts that quote it. Step 6's selection found captain/templates/merge-ask.md as the one unknown dependency of this PR and registered captain/templates/** in FREE_ONLY_PR_FILES (#3499). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (pass 2) The cmd_pack EXIT trap bakes the temp path in: a set -e failure unwinds the function before the trap runs and a local $tmp is unset there, so the old form leaked the snapshot. The leak test creates TMPDIR where the pack reads it and asserts the failure is the missing index. CHANGELOG examples no longer spell a full national number. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: adversarial review fixes The pack snapshot carries the index's staged blobs as a pack of their own, so a VM write-tree (gstack-wtree) can read a staged file the way the old .git tar allowed; git init runs with --template= and gc.auto=0 and a valueless remote/branch key replays as true. scripts/harness-version.json re-pins scripts/test-pr-profile.ts after the captain/templates/** entry. The run-id exemption reads the same way in the scanner and gstack-post: an 11-digit span after a run word is a run id (the leading-1 exclusion from the Red Team pass contradicted gstack-post's tested contract and the ruling that a run id is not a phone number), with the residual named in the comment, the docs and the CHANGELOG. The #3499 pins move to their own test so the boundary test stays under its default budget. Docs audit: TESTING_INTERNALS names RELEASE_METADATA_FILES and captain/templates/**, docs/captain.md names Blast radius. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (pass 4) The pack's staged-blob list comes from the copied index, holds only blobs staged against HEAD (not every tracked blob), skips gitlinks whose commit the superproject lacks, and dies with its own message when pack-objects fails. The live-checkout test covers a gitlink entry and a valueless remote key replayed as true. CHANGELOG names the staged-blob carry. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (pass 5) The pack's blob list is the copied index's blobs that HEAD's tree lacks, so an intent-to-add entry's empty blob and the stages of an unmerged entry travel too (the HEAD-only diff list dropped both); gitlinks still skip. The live-checkout test adds an intent-to-add entry, which the VM fsck assertion covers. 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> |
||
|
|
1f246e3505 |
v1.91.278.0 fix(ship-queue): readiness takes dispatched Free Tests, stamp paths accept tentative key versions, ready and train build read the base overlap, pr-wait --exclude, restamp prints the corrected order (#3514)
* fix(ship-queue): readiness takes dispatched Free Tests, prose check reads key=value pairs, stamp paths accept tentative key versions, ready and train build read the base overlap, pr-wait --exclude, restamp prints the corrected order Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes Pass 1 of /ship's review on #3514: the prose check skips a key: value pair's value whatever the whitespace, the restamp recompute keeps a merged-not-in-base predecessor and says to fetch, stampOnlyLine applies the version-width bound, pr-wait --exclude excludes nothing while the required checks are unreadable, baseOverlap reports a failed git read as unknown and gives no verdict at train build, readiness lets a pull_request run outrank a dispatched one, and the READY conflict refusal follows the crew template's rule 14 instead of a crew-local rule. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: stamp rule for tentative key versions, key=value prose claims, QUEUE_STALE merged-not-in-base fix Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
a1934a1498 |
v1.91.273.0 feat(ship): PR bodies open with the problem and a Blast radius line, and gstack-prose-lint catches autopilot phrasing before /ship publishes a CHANGELOG entry or PR body (#3501)
* feat(ship): PR bodies lead with the problem and carry a Blast radius line, and gstack-prose-lint checks the CHANGELOG entry and PR body drafts Absorb lane B (Garry, 2026-10-26: "Do it, send" on plans/absorb-tstack.md item 4 and plans/absorb-pstack.md items 2(a) and 11). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: register the prose-lint fixtures and NOTICE.md as free-only PR inputs Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: pin prose-lint gate lines and usage exits, use a gstack-native dropped-article example, keep NOTICE.md unmapped Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: name the CHANGELOG prose-lint gate and the Blast radius body section in the contributor docs Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(ship): name the evidence ladder by skill instead of by a runtime-root path that does not exist yet test/runtime-root-assets.test.ts checks every $GSTACK_ROOT/<path> literal in a host render against the staged root; investigate/sections/blast-radius.md lands with its own lane, so the Blast radius item and the Capy body step now say "the /investigate skill's Blast radius section, when present". Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: name the Blast radius section in the two Capy body-order lists The docs re-audit found capy/skill/gstack/SKILL.md (Merge asks) and docs/capy-install.md still listing the Capy PR body as What changed, Why, Approvals; both now match capy-pr.md.tmpl. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(ship): the compose block's prose-lint trailer goes to stderr, and the publication-gates fixture stages gstack-prose-lint beside gstack-post test/ship-publication-gates.test.ts runs the real compose block under a HOME whose installed bin dir held only gstack-post, so the block's new gstack-prose-lint call failed with "No such file" on every CI free lane; the fixture now stages both bins the blocks call, and the lint's ok line goes to stderr so the composed body is the only stdout. 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> |
||
|
|
f27a7605d4 |
v1.91.270.0 feat(ship): version-less repos, docs-audit record and caps, the frozen-scope paid case, and the review-loop follow-ups (#3487)
* feat(ship): version-less repos, docs-audit record and caps, the frozen-scope paid case, and the review-loop follow-ups Follow-up to the review-loop convergence PR: Step 12 and the CHANGELOG step skip cleanly in a repository with no version source (receipt version "none"); the receipt records the docs audit outcome and the owner exception (DOCS_AUDIT_BLOCKED without one) and a policy may declare doc caps (gstack-ship-receipt docs-caps); docs/unattended.md names the READY evidence and the cross-family outside voice; the ship-frozen-scope-convergence behaviour case runs the generated Step 9.4 under review_scope frozen through the real binaries; carry probes git >= 2.39 (RECEIPT_GIT_TOO_OLD); defer passes the repository to gh repo view positionally and names its search limit; late defers count without being passes; reviewers diff from RANGE_BASE on pass 2+; the cap check runs before edits; --review-fanout batches specialists by free slots; read --check-prose compares quoted counters with the receipt (RECEIPT_PROSE_MISMATCH); checklist rule ids prereg-with-results and test-keyboard-count-loop; gstack-coauthor-trailers. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: repair the CI reds the retarget onto main surfaced (test-only) Seven test files, no product change. The pull_request run at |
||
|
|
295b32e2c4 |
v1.91.269.0 feat(autoplan): gates print their cost, approvals mirror to the Captain's drive, Eng asks for a perf budget (GSTA-114 lane F, PR 3) (#3496)
* feat(autoplan): gates print their cost, --owner-standing rec cites a standing approval, approvals mirror to the Captain's drive
E16: GATE_SPEND and GATE_REC_COST under every GATE line (lib/autoplan-gate-cost.ts), and a
Cost so far sentence in the owner brief; host-subagent attempts stay priced unknown.
E21: gstack-autoplan answer --owner-standing rec --by agent:<id> answers rec by citing the
newest standing approval covering autoplan recommendations from any branch's record; the
id lands on every decision row, in run.json and in the approvals import; refused with
STANDING_APPROVAL_ABSENT or STANDING_APPROVAL_INAPPLICABLE (urgent finding).
E22: the approvals mirror honours the approvals/ directory a Captain created in its drive,
between GSTACK_APPROVALS_DIR and the private project-user folder; gstack-approvals path
names the rule.
E23: the Eng phase asks for a performance budget and a bench step on hot-path changes.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(autoplan): review pass 1 — standing answers bind to the run's project and refuse recommend-edited gates, cost is an upper bound and reaches JSON and the Captain brief
Review pass 1 (6 specialists + red team) on the standing-approval and gate-cost change:
- the standing lookup resolves the approvals record of the repository the run's plan lives in,
never the caller's cwd (red team: project A's row answered project B's gate)
- standingAnswer refuses a gate that `recommend` edited (rec_rev > 0 or recommended_by), a
missing or unreadable findings.jsonl, and an outside-plan finding; the STANDING line flattens
control characters so a crew-writable row cannot forge a protocol line
- coversAutoplanRec matches the recommendation words in the owner's words only and rejects
negations; STANDING_APPROVAL_ABSENT's fix names every required gstack-approvals flag
- recReopens is the upper bound of the answer/revise rules (a plan change counts every phase,
a round grant its phase plus Eng); gate_cost rides the JSON payloads, `run` prints the lines
at its final gate, and `gstack-owner-brief render --captain` appends a ### Cost section
- locate keeps the other mirror roots as read_also so rows mirrored under an earlier rule stay
visible; gstack-approvals path prints READ_ALSO
- the Eng phase edit is size-neutral: five nearby phrases shortened so every host's autoplan
SKILL.md stays at its size-guard pin
- tests: isolated fixtures, the run's plan inside its own git repo, cross-project refusal,
amend_pending vs complete, recommend-then-standing, injection, gate_cost JSON, Captain brief
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (pass 2)
Standing approvals: the newest row about autoplan recommendations decides, so a later refusal
blocks older grants; rows whose id or date is not the recorded shape are never cited; the
project is fixed at init from the plan's physical path (run.json project_root) so a symlinked
plans folder or a checkpoint restore cannot borrow another repository's record. Gate cost:
recReopens counts every phase revise can keep or add and prices answers already recorded at
the gate; run --json emits one payload; the Captain brief's ### Cost sits above the relaying
trailer.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (pass 4, rule-23 exception)
Standing grammar fails closed: the newest standing row mentioning autoplan decides and grants only
with the canonical scope and affirmative owner words; same-id copies keep the newest recorded; id and
date are type-checked before the regexes. Gate cost prices the effective choices exactly as answer
does (p1d, carried overrides, non-recommended options). The run records project_slug beside
project_root so a restored run names its record on another machine, and project_root is a recorded
root for export --public.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* refactor(autoplan): drop --owner-standing rec (E21) from this PR
Pass-4 review (red team + Codex adversarial) still found that the keyword
grammar over the owner's standing words could read a refusal as a grant
("I won't take the recommendations", "Taking the recommendations is
forbidden" granted under the canonical scope) and that gstack-approvals add
deduped a same-day scope revocation as the grant. A free-text negation
parser cannot fail closed, so the standing answer leaves this change and
returns with a structured grant in its own PR.
Kept: GATE_SPEND/GATE_REC_COST cost lines and gate_cost (E16), the
Captain-drive approvals mirror with READ_ALSO (E22), the Eng perf-budget
question (E23). Removed: standingAnswer, standingRecApproval,
coversAutoplanRec, citableRow, project_root/project_slug in run.json,
STANDING_APPROVAL_* result codes and anchors, the standing DRIVER
paragraph and docs, test/autoplan-standing.test.ts (its E16/E22 cases move
to test/autoplan-gate-cost.test.ts).
Focused: 793 pass / 0 fail across 45 files; typecheck, typecheck:test,
format: cso:check clean; renders regenerated with gen:skill-docs --host all.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* RESTAMP: 1.91.268.0 -> 1.91.269.0 (stamped; queue_mode=stamp-at-merge base=origin/main@76aa68fc9e7a policy=base origin/main@76aa68fc9e7a:.gstack/ship-policy.json)
ship, next in queue at 1.91.269.0
STAMP_VERSION: 1.91.269.0
claims: ignored (stamp-at-merge)
stage version: done (wrote 1.91.269.0)
stage release_tool: done (bun scripts/gen-agents-digest.ts)
stage changelog: done (Unreleased -> 1.91.269.0)
stage stamp_paths: skipped (no stamp_paths in policy)
stage mirror: skipped (no mirror in policy)
stage apply: done (4 file(s))
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e4e28308c..566bb525c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
# Changelog
-## [Unreleased]
+## [1.91.269.0] - 2026-10-27
**An autoplan gate now arrives with its price, and the approvals record lands where the whole crew can read it.** Captains reported the same two frictions: review rounds and reviewer subagents had no credit figure at the gate, and the approvals mirror sat in a private project-user folder no sibling thread could read. The Eng phase also gains the performance-budget question, after a correctness pass doubled a consumer's p95 with no bench step to catch it. (The standing "take the recommendations" answer planned beside these, `answer --owner-standing rec`, was cut from this release after review: a keyword grammar over the owner's words could still read a refusal as a grant, so it returns with a structured grant in its own change.)
diff --git a/VERSION b/VERSION
index c31f84688..6437fa3e4 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.91.268.0
+1.91.269.0
diff --git a/agents-digest/gstack-AGENTS.md b/agents-digest/gstack-AGENTS.md
index 3548eb690..4bdc2879f 100644
--- a/agents-digest/gstack-AGENTS.md
+++ b/agents-digest/gstack-AGENTS.md
@@ -1,4 +1,4 @@
-# gstack digest v1.91.268.0 — regenerate/re-copy after upgrading gstack
+# gstack digest v1.91.269.0 — regenerate/re-copy after upgrading gstack
Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed
for agent hosts without a full skill install. The full skills add workflows,
diff --git a/node_modules b/node_modules
new file mode 120000
index 000000000..1de79460f
--- /dev/null
+++ b/node_modules
@@ -0,0 +1 @@
+/workspace/gstack-ap/node_modules
\ No newline at end of file
diff --git a/package.json b/package.json
index 7a672beb5..26a9702da 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "gstack",
- "version": "1.91.268",
+ "version": "1.91.269",
"description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.",
"license": "MIT",
"type": "module",
FILES: CHANGELOG.md VERSION agents-digest/gstack-AGENTS.md package.json
MERGE_CONDITION: sha=624f0eedec7c3aebdd0cecd70be4e4ebd10eb4af
next: NEW_VERSION=1.91.269.0; commit and push only the stamp diff above (FILES), with no edit of your own: the train's verify accepts the CHANGELOG only as the base's plus this PR's entry re-headed; merge with the expected head
|
||
|
|
76aa68fc9e |
v1.91.268.0 feat(bin): gstack-decision-trail and gstack-worktree-audit, ported from pstack (GSTA-123) (#3494)
* feat(bin): gstack-decision-trail and gstack-worktree-audit, ported from pstack (GSTA-123)
Two MIT ports from Lauren Tan's pstack (licenses/MIT-pstack.txt, NOTICE.md):
a TSV decision trail with the header-once append, the formula guard, a start
row per run and a --run admission check; and a read-only worktree audit with
size, merge state, dirty, remote, PR, last chat and a suggested bucket.
Docs: docs/unattended.md (the decision trail and its end-of-run audit),
autoplan/DRIVER.md, docs/CONTRIBUTOR_REFERENCE.md, docs/standalone-binaries.md,
docs/troubleshooting.md, one line in landing-report.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(egress): reasoned scanner exemption for gstack-worktree-audit's base fetch
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review of the pstack ports
bin/gstack-worktree-audit: a worktree path with a space is read whole (sed
on the porcelain 'worktree ' line, not awk's second field); a registered
worktree whose directory is gone prints a 'prunable' row instead of being
skipped; 'safe' now requires a clean tree and either merged into the base
or a closed/merged PR with every commit pushed, so unpushed commits or
untracked files on a merged branch read 'review' (the port's rule called
them safe); fork PRs are dropped and an open PR wins over an older closed
one on a reused branch name; GIT_TERMINAL_PROMPT=0 on the base fetch.
bin/gstack-decision-trail: only a leading -h/--help is help, so a '-h'
cell is appended as data; a trail without a final newline, with CRLF rows
or with a repeated header line is appended to correctly; a run id is
limited to [A-Za-z0-9._:@/-] (exit 2) so a tab or quote cannot break the
start-row idempotence check.
Tests cover each case; the 'without gh' test resolves git from
'git --exec-path' instead of a PATH rebuilt from a tool list. Docs,
CHANGELOG and --help text describe the stricter buckets.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes, pass 2
bin/gstack-worktree-audit: a worktree whose own .git link is gone (git
marks it prunable, or its toplevel is another repository) prints a 'broken'
row in 'review' instead of describing the containing repository as clean
and safe; a locked entry whose directory is gone reads 'review', not
'prunable', since prune would not touch it; a clean tree names its
gitignored entries as 'clean,ignored:<n>' without changing the bucket; the
branch name is read from refs/heads/ by hand so a tag of the same name
cannot hide the PR; porcelain blocks are read with IFS=tab so paths with
leading or trailing spaces survive; a failed git status reads 'unknown',
never 'clean'; the base fetch also sets GIT_ASKPASS=true and ssh BatchMode.
bin/gstack-decision-trail: a file whose first line is not the header (a
blank file, rows written by hand) gets the header appended, and a UTF-8
BOM before the header no longer turns it into a data row.
Tests: the fake gh records its argv and runs the audit's own --jq over
canned JSON with a fork PR when jq is installed; row counts are asserted
before the every() checks; each test starts from the same gh and closed
worktree; the snapshot includes the worktree registry; new fixtures for
locked, broken, tag-shadowed and ignored-only worktrees, a blank trail and
a BOM. Docs and CHANGELOG describe the new DIRTY values and buckets.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes, pass 3
bin/gstack-decision-trail: hasHeader looks for a header line anywhere in
the file, so a blank or hand-written trail gets exactly one header rather
than one per append. bin/gstack-worktree-audit: the broken-worktree check
uses rev-parse --show-cdup and the presence of /.git instead of
comparing two spellings of the same path, which differ on Git for Windows.
Test: the blank-trail case appends twice and asserts a single header.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: adversarial review, pass 5 (rule-23 grant, one finding)
bin/gstack-worktree-audit: git status runs with --untracked-files=normal
--ignore-submodules=none, so a user's status.showUntrackedFiles=no config
cannot hide untracked files and let a worktree holding them read clean and
safe. Test: the fresh worktree under that config via GIT_CONFIG_* still
reads scratch:1 / review (red before the fix).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: documentation audit corrections for the pstack ports
docs/standalone-binaries.md, docs/CONTRIBUTOR_REFERENCE.md,
docs/troubleshooting.md: the audit's safe condition is stated in full
(clean and merged, or PR closed/merged with every commit pushed), the
DIRTY list names missing, broken and unknown, start is a reserved phase
name, and 'read-only' names the base fetch as the one write --no-fetch
skips. CHANGELOG.md says the same (the audit's one decision item).
Audit id gsta123-docs-20261026T221657Z, status updated, no blockers.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* Stamp 1.91.268.0 for #3494 (train slot 1, base
|
||
|
|
6bbd0a536f |
v1.91.266.0 feat(pr-wait): gstack-pr-wait event watcher (tstack pr-wait design port) and /land-and-deploy Step 3 wiring (#3495)
* feat(pr-wait): gstack-pr-wait event watcher (tstack pr-wait design port) and /land-and-deploy Step 3 wiring Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pr-wait): keep the result codes in lib/result-codes-release.ts so fixtures that copy the module list keep working Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(pr-wait): function declarations for the fake-gh helpers so the pregate TSX import scanner maps the lib files Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pr-wait): /ship review pass 1 — every check gates green, --timeout, bot identity, signal disposition Red Team and specialist findings on #3495, all fixed in the diff: - green gates on every check on the head, as gstack-ci-gate does, so land-and-deploy Step 2 and Step 3 can no longer disagree while a non-required check pends; required checks still gate before they appear - --timeout MINUTES (default 60, 0 = none) ends a watch that met nothing as PR_WAIT_BLOCKED naming the still-pending checks; restores Step 3's cap - a bot owns logins that start with its name (greptile-apps[bot]), not any login containing it; a failed gating-bot check is a failed check, never a completed review - ready: green alone when no gating bot is configured (pr_wait_gating_bots none no longer polls forever); held while merge state is UNKNOWN - BEHIND and DIRTY announced once per head, with the short head in the line - the bin installs no signal handlers: the synchronous loop never ran them and they made the process ignore SIGTERM/SIGINT; default disposition kills it at once and the next watcher takes over the dead pid's lock - a gh spawn timeout (ETIMEDOUT) is retried like any transient failure - a local fault (unwritable state root) is PR_WAIT_REFUSED exit 2, so exit 1 always carries a PR_WAIT_BLOCKED line - control characters in GitHub text never start a second event line Tests: 21 new cases including a real SIGTERM against the bin, gstack-config set-time validation and default parity, and the 14 state-matrix cells the state-machines specialist listed (gstack-state-matrix check: ok, 33/33). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pr-wait): /ship review pass 2 — advisory checks gate too, BEHIND keyed on the head, verdict survives a failed save - an advisory bot's review is never waited for, but its check gates like any other, so gstack-ci-gate (Step 2) and gstack-pr-wait --until green (Step 3) read the same check set with no exception - BEHIND and DIRTY are keyed on the head alone; the pass-1 key also held the base oid, so a base that kept moving re-announced BEHIND to a restarted watcher on every commit - finish() keeps the printed verdict's exit code when the state file cannot be written; the save error goes to stderr - PR_WAIT_BLOCKED and PR_WAIT_REFUSED summaries name every exit-1 and exit-2 path (--timeout, a local error); emitBots docstring matches the gating rule - CHANGELOG says what a timeout means at land-and-deploy Step 3: a STOP with the pending checks named, no wait-more question 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> |
||
|
|
f375b873de |
v1.91.263.0 feat(ship-queue): screens read from the run, train watch/forget/prune --stale, verify --post-merge, ready --dispatch-ci, --stack-tests (#3484)
* feat(ship-queue): screens read from the run, train watch/forget/prune --stale, verify --post-merge, ready --dispatch-ci, --stack-tests Operating merge trains on 2026-10-26 showed the gaps this closes. A dispatched screen's verdict is read from the run's gate-binding and report-verdict artifacts (lib/ship-queue-screen.ts) and recorded in the READY receipt: a RED screen refuses ready under either choice and is never re-dispatched at the same merge SHA (QUEUE_SCREEN_RED); a run that concluded success with no slice is NOT-RUN (QUEUE_SCREEN_NOT_RUN), never followed, and counted as unscreened by train build. When refs/pull/<n>/merge lags or is missing the screen is planned on a scratch merge pushed as screen/<pr>-<head12> (#3465); QUEUE_SCREEN_STALE_REF means a real conflict only. train watch --train is the resumable follow command; train prune --stale settles a merging/green train whose PRs all merged or closed elsewhere; train forget removes one record with an exact lease on refs/notes/gstack-trains; verify --post-merge <sha> watches main's push workflows until they settle; ready --dispatch-ci <wf,…> dispatches the free workflows on a conflicting PR, waits, and clears the matching requires-remote pregate lanes with the run URLs; train build --dry-run --stack-tests runs each PR's new test files on its integrated prefix before anything is dispatched (QUEUE_TRAIN_STACK_RED). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Regenerate gstack-doctor-components.sh for the four new QUEUE_* result codes The committed Bash render was four case lines behind its generator, so test/doctor-components.test.ts failed at |
||
|
|
a8decce8ac |
v1.91.262.0 fix(release-cut,ship-queue): the weekly release accepts a train-gated commit; cross-repo refs, run ids, pr-body section merge, pregate by tree (#3483)
* fix(release-cut,ship-queue): the weekly release accepts a train-gated commit, and five lane frictions seen in operation scripts/release-cut.ts gates a main commit either by a successful backstop check run or by a green/merging/merged train record in refs/notes/gstack-trains whose merged[] names its sha or tree (CANDIDATE: ... gated by train <nonce>); a red check, a running run, the required check and the freeze are judged as before. --required-check, --backstop-check and --notes-ref make the names configurable. lib/issue-links.ts reads (name #N[, #M]), (name PR #N) and (name issue #N) as cross-repo references. lib/gstack-post.ts allowlists an 11-digit run id after a run word or chained after one, and pr-body merges by ## section into the PR's current body (--replace overwrites). gstack-pregate mirrors each record under <state root>/pregate/by-tree/<tree>.json and ready reads the mirror for its tree when the checkout's record is missing or for another tree. docs/troubleshooting.md gains #redact-run-id-as-phone, #gate-error-no-base and #gstack-post-pr-body-merge. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (pass 1) Fence-length-aware section splitting in gstack-post pr-body (an unclosed receipt fence or a four-backtick block no longer exposes a heading to the merge), the run-id allowlist drops generic words (id, job, attempt, workflow), ready accepts a by-tree pregate mirror only from a complete run against origin/<base> under a reviewed policy and prints no home path, release-cut skips non-object notes and never substitutes train evidence for the required check when both names are equal, issue-links treats closing/cf./e.g./v1.2 as words rather than repositories. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (pass 2) An unclosed receipt fence makes the body from that line on one section the merge never matches, so posted leading prose cannot replace it and a closed receipt before it stays a receipt; the by-tree pregate mirror must hold the tests stage (what --stage tests --remote writes) rather than every check; empty sha/tree strings in a train note are not evidence; (v1.2.3-rc1 #301) is a version word, not a repository. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: CANDIDATE line names its gate; issue-links reference documents the (name #N) form Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(ship-queue): a PREGATE_ENVIRONMENT local record is final; no mirror stands in for it Merging origin/main |
||
|
|
7dc2f23192 |
v1.91.258.0 feat(capy-install): project floor, --for none, WARN for behind and Node-only pins, in-place review-voice upgrade, /cso env hygiene (GSTA-114 lane F, PR 1) (#3475)
* feat(capy-install): project floor, --for none, WARN for behind and Node-only pins, in-place review-voice upgrade, /cso env hygiene (harness lane F)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* cso: tighten the env-hygiene and tooling-error paragraphs so the controller template stays under the 18,000-byte compactness bound
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* capy skill: name the fail heads once and describe the WARN behind outcome consistently
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* doctor: name the floor field PROJECT_FLOOR_FIELD (it is a JSON field name, not a key)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
Red team (/ship Step 9): a Drive copy at a bootstrapper revision below GSTACK_CAPY_MIN_WRAPPER is a WARN with the owner action in a direct (no-provenance) run too; only a pre-bootstrapper copy fails. A --for none session never self-upgrades. Stale fail-behind comment in gstack-capy-session; SKILL.md says ok not-needed is not an install verdict. Tests: UPGRADE_SKIPPED collapse, silent in-place message, direct-run WARN, wrapper-2 --for none handover.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: adversarial review fixes
Trailer fix after a skipped upgrade is one runnable command (the refusal prose stays on the WARN behind row); the floor reader is whitespace-insensitive and names a non-version value instead of calling it absent. Found by /ship Step 11 (Claude adversarial, Codex adversarial + structured).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: review pass 2 fixes (floor reader bounds, cso start is resumed not retried)
The floor reader reads only the first 64 KiB, takes the first occurrence of the field (the top-level one) and names a non-version string truthfully; /cso resumes a start whose ID never printed instead of retrying it (a run may already exist). Found by /ship pass 2 (Claude adversarial, Codex adversarial + structured).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: the floor evaluation marker lives in the fixture, not /tmp
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: take main's host-conformance C3 fix (#3479) so the remote gate can run on this tree
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* RESTAMP: 1.91.257.0 -> 1.91.258.0 (stamped; queue_mode=stamp-at-merge base=origin/main@7f53ddb1f3cc policy=base origin/main@7f53ddb1f3cc:.gstack/ship-policy.json)
ship, next in queue at 1.91.258.0
STAMP_VERSION: 1.91.258.0
claims: ignored (stamp-at-merge)
stage version: done (wrote 1.91.258.0)
stage release_tool: done (bun scripts/gen-agents-digest.ts)
stage changelog: done (Unreleased -> 1.91.258.0)
stage stamp_paths: skipped (no stamp_paths in policy)
stage mirror: skipped (no mirror in policy)
stage apply: done (4 file(s))
FILES: CHANGELOG.md VERSION agents-digest/gstack-AGENTS.md package.json
MERGE_CONDITION: sha=831ac3c3cb3077f16b2f1a7802297523a2db1349
next: NEW_VERSION=1.91.258.0; commit and push only the stamp diff above (FILES), with no edit of your own: the train's verify accepts the CHANGELOG only as the base's plus this PR's entry re-headed; merge with the expected head
|
||
|
|
7f53ddb1f3 |
v1.91.257.0 feat(pregate): clear --receipt accepts a remote_gate receipt from a stamp-only predecessor tree (gbrain gate-ahead) (#3486)
* feat(pregate): clear --receipt accepts a remote_gate receipt from a stamp-only predecessor tree (gbrain gate-ahead) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (hex object ids, stamp_sensitive_gates and base-branch refusals, one substitution type, docs) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pregate): harden the stamp-only diff read (fixed presentation, diff-tree reconciliation), refuse an unreadable base policy, check the receipt before git work, bind verify to the receipt tree; docs audit corrections Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(pregate): the stamp-only suite expects the Linux-host lanes verdict; skip itself on win32 like test/pregate-remote.test.ts Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
576839cb8c |
v1.91.256.0 feat(ship): review loop converges (frozen scope, 3-pass cap, NO FINDINGS) and receipts carry across conflict-only merges (#3481)
* feat(ship): review loop converges (frozen finding scope, 3-pass cap, NO FINDINGS first-class) and receipts carry across conflict-only merges
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(ship): keep the Step 9 first-entry and Fix-First phrasing the skip/requeue contract asserts; fill the review record's pass, review_scope and range_base placeholders in the caller template test; narrow a test type
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (pass 1) and the review-loop budget wording
Two blocking findings from /ship's own pass 1, both reproduced in the QA smoke before the fix:
gstack-ship-receipt carry hashed the product diff with git patch-id --stable, which strips
whitespace, so a space moved in a reviewed shell line carried as "no product change"; and it
classed package.json and every lockfile as release metadata, so a dependency swap carried too.
The patch-id is now --verbatim, package.json and VERSION are metadata only while the change is a
version stamp (lib/pregate/stamp-only.ts), lockfiles are product unless the policy names them,
the test globs name code extensions, a dirty working tree refuses before anything is compared,
and a receipt carried twice keeps the reviewed head as carry.from.
gstack-review-scope: an unresolvable base is POLICY_SOURCE_UNAVAILABLE instead of a silent
working-tree read; --range-base is validated; git runs with core.quotePath=false; range_base is
null on pass 1; a blocking finding with no path is fix; category "testing" is a test finding
below the floor; defer searches once, files nothing on a failed search and exits 0 unfiled;
summary refuses zero matching passes and the receipt write is chained to it with &&; a finding
the diff causes elsewhere names the changed line in `cause` and classify follows it.
Review-loop budget wording (ideas from tstack's sol-loop and pstack's interrogate, rewritten;
NOTICE.md): the blocker / should / nit glossary and two stop rules in Step 9.4, the checklist
and docs/review-policy.md; a lead-judgment stage in the finding merge both /review and /ship
render. The core read diffs $RANGE_BASE from pass 2 on. Caps and pins re-measured with reasons.
Step 7 coverage audit: four tests added in existing files, the --review-loop case moved to its
own test (the shared test tripped bun's 5 s default).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pin the renumbered review-army stages and point the wording test at product code
CI at
|
||
|
|
b004c06dbc |
v1.91.255.0 fix(ship-queue): fill trains at 3 READY PRs or one hour, and price every case shard's trial (#3478)
* fix(ship-queue): fill trains at 3 READY PRs or one hour, and price every case shard's trial
The 5-PR / 3-hour fill left READY PRs waiting most of a day; .gstack/ship-policy.json
now fills at max_size 3 or fill_hours 1, whichever comes first (fillDue already
dispatches at either bound). train verdict printed cost=$24.41 for a train whose slice
report said cost $32.92 known + 54 of 136 trial(s) cost unknown: E2E records named by a
display label ("/benchmark workflow") were never attributed to their case id, so the
per-case sum was short. A case shard's records now belong to its one case; a multi-case
shard with display-labelled records keeps those trials unknown. The ATTEMPT: line names
how many cases have no cost instead of printing a partial sum as the total.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ci): record the paid-report.ts harness decision and keep ship-queue-train-cost.test.ts off the Windows subset
scripts/lib/paid-report.ts is a pinned shared-harness file, so test/harness-version.test.ts wants a HARNESS_VERSION decision for its edit: non-behavioral, because a case shard's records are attributed to its one case for the trial's cost, class and error fields while no case's outcome, panel verdict or selection changes.
test/ship-queue-train-cost.test.ts drives bin/gstack-ship-queue against the #!/bin/sh gh shim, which windows-latest cannot run (windows-free-shard 2 on #3478 at
|
||
|
|
568cd5aa56 |
v1.91.254.0 pregate: starter policy, benign-finding allowlist, environment vs diff failures, per-run scratch (#3480)
* pregate: starter policy, benign-finding allowlist, environment failures, per-run scratch
A repository with no .gstack/pregate.json now gets a warn (PREGATE_NO_POLICY)
with a starter policy printed, instead of PREGATE_NO_LANE on every touched
file; gstack-pregate init remains the explicit write. The policy gains an
allowlist for benign secrets/pii findings (env.value and secret never
allowlistable). Checks that cannot run because of the machine report
PREGATE_ENVIRONMENT (incomplete, with kind and evidence) apart from diff
failures. Every run writes its scratch under the state root, per run id.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* pregate: rename run-scratch module (strays rule) and map starter.ts to its test
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* pregate literals: match a module as a path fragment, require the constant name for a one-character value
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
guards: an exited guard is the machine's only on exit 127, never from its output;
secrets: clear an interrupted run's added-line copies before scanning;
environment: one fix table per kind, one ANSI strip, hoisted not-found vocabulary;
starter returns its lines; allowlistDigest reuses sha256; stale headers and the
PREGATE_INCOMPLETE fix clause updated; tests for the mixed verify branch, disk
precedence, allowlist boundaries, a positionless finding, head-policy strictness,
run-id edges and the unwritable state root.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* pregate: count a module's full file name without a directory as a consumer
consumersOf anchored both the stem and the full basename on a path
separator, so run('install.sh') or bash install.sh without a directory
stopped counting for a multi-character old value. Only the bare stem
needs the separator; the full file name is specific on its own.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* pregate: a diff cannot clear itself as an environment failure; a taken --run id gets its own directory
Adversarial review of the environment classifier and the scratch layout:
- exit 127 and 'command not found' are missing-binary only when the
command's own binary is off PATH (runner, guard and remote gate alike);
a script the diff controls that exits 127 is the diff's failure
- a local lane with no test summary is classified from its output only
when the runner was not seen starting a test file; a remote gate only
from its first 40 lines, before any test output could stream
- environment.proof records launch (certain) or output (inferred); an
output-inferred cause never says 'the diff is not at fault', its line
says '(inferred from output)', and verify names such checks
- a runner killed by a signal is PREGATE_INCOMPLETE, not missing-binary
- a --run id whose directory exists takes <id>-2 .. -9 instead of
sharing (and truncating) a live run's logs
- engine.* findings are never allowlistable; a pattern entry the scanner
gave no position for is reported as not tested instead of silently inert
- docs: synopsis --run, no-policy lanes wording, verify's code list,
guard exit 127 carve-out, PREGATE_SECRETS allowlist pointer, scratch
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(pregate): PREGATE_INCOMPLETE names a signal-killed runner; CHANGELOG lists every doc edit
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>
|
||
|
|
ab9a854be2 |
v1.91.246.0 docs(readme): cut the README to the first ten minutes; move everything else to docs/ pages verbatim (GSTA-99) (#3428)
* docs(readme): cut the README to the first ten minutes; move everything else to docs/ pages verbatim (GSTA-99) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes Restore the /setup-gbrain code block the README split left open: README.md kept the ```bash opener and docs/gbrain-quick-tour.md got only the closing fence, so both pages rendered their body as one code block. Drop the self-referential 'Full reference' link in docs/domain-skills.md and make the troubleshooting quick-answer link an in-page anchor. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: describe the proactive core-set default in why-gstack The moved 'Proactive skill suggestions' paragraph now documents the four-skill core set, gstack-config set proactive core|all|off and the docs/proactive.md page that #3432 (gsta-99-proactive-core) adds; the CHANGELOG names it as the one non-verbatim paragraph of the move. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (round 2) Promote docs/uninstall.md's moved sections from ### to ## so the page outline matches the other pages the README split created; no inbound link targets those anchors. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: documentation audit fixes The README Docs table no longer claims docs/standalone-binaries.md covers every gstack-* CLI (it documents the standalone ones), and docs/ADDING_A_HOST.md step 6 points at the README host-matrix row and docs/hosts.md, where the per-host notes now live. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: disclose the update check fully and list every setup hook The README privacy summary now names both GitHub requests the update check makes and the version/OS report it adds with telemetry on, as the full text it replaced did. docs/install.md's hooks section lists the team-mode SessionStart hook and the AskUserQuestion PreToolUse/PostToolUse hooks beside the timeline Stop hook. * docs: name the update check's conditional compare-API request bin/gstack-update-check also GETs api.github.com's compare endpoint when the remote VERSION equals the local one but main has moved; the README privacy summary and docs/privacy.md now list it beside the ls-remote and VERSION fetch (documentation audit). * fix: pre-landing review fixes (merge resolution) docs/install.md:21 carried main's stable-channel sentence twice after the merge, the second copy with its backticked spans stripped; the paragraph again matches README.md:41 verbatim with the relative link. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: say outside reviews are on by default in the README privacy summary The one-paragraph summary dropped the default-on disclosure the full text kept; mirror docs/privacy.md's parenthetical so the top-level page says which path sends code off-machine without an opt-in. * v1.91.246.0 stamp Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
d62eb914dc |
fix(pregate): waive version-stamp-only manifests from the lanes check (GBRA-95) (#3461)
gbrain's release:restamp rewrites its plugin manifests and VERSION; its base's .gstack/pregate.json declares no lane for them, and pregate reads policy from the base, so every restamp PR failed lanes with PREGATE_NO_LANE and could not fix itself (gbrain PRs 7625 and 7606). lib/pregate/stamp-only.ts defines version-stamp-only per file kind: a JSON document of the same shape whose every changed leaf is a bare version under a key named for a version; plist <string> versions under a ...Version... key; a VERSION file that is one bare version on both sides. lane-selection applies it only after the import graph, the declarations, the regen registry and both empty lanes found nothing; lanes prints the waived files on their own line and --explain the per-file verdict. Anything else (a changed description, a new key, a dependency pin, an added or deleted manifest) keeps its PREGATE_NO_LANE. Tests: pure rows for every rule, and bin fixtures for a stamp-only PR (passes), a manifest with a changed description (refused), a mixed diff (stamped files waived, the orphan source file still refused, a mapped file still runs its test) and an added/deleted manifest. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
8018ba52fe |
v1.91.243.0 fix(capy): source the launch environment from a 0600 file; no skill fence may print the environment (GSTA-104) (#3449)
* fix(capy): the launch environment is sourced from a 0600 file and no skill fence may print the environment (GSTA-104) During GSTA-96's unattended /ship on #3425, the Step 14.5 docs-audit child re-typed the GSTACK_LAUNCH assignments as `export $(...)`; the substitution came back empty, the bare `export` printed the whole environment, and three API key values landed in its tool output. - bin/gstack-capy-install writes the assignments to <verdict>.env (mode 0600, idempotent PATH prepend) and prints GSTACK_LAUNCH_FILE: <path>. - ship Step 14.5 prompt, document-release's spawned note, autoplan/DRIVER.md and gstack-skill-start's capy-asks block say: source the file; never export $(...), env, printenv or bare set in a tool fence. - test/launch-env-echo-ratchet.test.ts greps every generated SKILL.md, sections, DRIVER.md, the Capy skill and bin/ shell helpers, with negative controls under test/fixtures/launch-env-echo/. - lib/redact-engine.ts: env.value (HIGH) finds the value of any *_KEY, *_TOKEN, *_SECRET, *_PASSWORD variable in the writer's environment, so a leaked value cannot reach a PR body, receipt, report or Drive file. - scripts/lib/shard-engine.ts scrubs the Capy launch markers from shard environments (GSTA-99's finding). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(ci): DRIVER.md back to 159 lines; shard-engine recorded non-behavioral at HARNESS_VERSION 6; verdict-count test lists .json only Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: register test/fixtures/launch-env-echo as a free fixture Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(redact): env-value fixtures stay out of pregate's env.kv net A credential-named assignment with an entropic literal on one line is what the repo's own pregate secrets scan refuses in added lines, so the fixture values move into plainly named constants and the scanned text is built from them. The scan under test still sees the same values through processEnv. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(windows): the late-completion remote-caller case gives its second attempt a 2s budget (run 40263984171) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(redact): env.value trims the value, keeps a prefix value's longer match, hides the preview and skips PUBLIC names /ship Step 9.4 review fixes for the GSTA-104 env-value scan: - a value whose environment copy ends in a newline (a key read from a file) is searched for trimmed, so its leaked form still matches (the length check already trimmed; the search used the raw value); - when one credential value is a prefix of another, the dedup key carries the span length, so the longer value is redacted whole in either order instead of leaving its tail in the text and dropping its finding; - the env.value preview is a fixed mask instead of the first characters of a live credential; - framework-public names (NEXT_PUBLIC_*_KEY, *_PUBLIC_KEY) are not scanned, since those values are committed on purpose; - the header and the processEnv docstring state the name rule (KEY, TOKEN, SECRET, PASSWORD, PASSWD, any case) and that process.env is the engine's one ambient input. Step 7 coverage extensions and a regression test for each fix in test/redact-env-value.test.ts; docs/capy-install.md names the full rule. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * refactor(capy-install): write_launch_file quotes through shq; header names the launch file Review finding: _sq duplicated shq() from the same file. The launch file's assignments now go through shq, and the header comment describes the GSTACK_LAUNCH_PATH and GSTACK_LAUNCH_FILE lines beside GSTACK_LAUNCH. Step 7 coverage: the verdict test sources the launch file and runs --check; the single-quote path test sources the file too; a new case makes the launch-file directory unwritable and checks the run says so, prints no GSTACK_LAUNCH_FILE line, leaves no temp file and keeps its exit code and trailer (linux, non-root). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(preload): strip the Capy launch markers so a direct bun test matches the shard sandbox Red Team finding: the launch-marker scrub lived only in createShardSandbox, so a direct `bun test <file>` run under an unattended Capy session inherited GSTACK_SESSION_KIND, GSTACK_CAPY, GSTACK_EPHEMERAL and GSTACK_INSTALL_VERDICT (GSTA-99's symptom). The preload now deletes the same four names, and test/shard-engine.test.ts imports CAPY_LAUNCH_MARKERS instead of re-typing them. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(ratchet): the launch-env echo scan catches backtick and $VAR exports, typeset -p, env flags and a set in any segment Review findings 11 and 12: export-subst also trips on `export \`...\`` and an unquoted `export $VAR` (both splat a NAME=value file; `export "$name"` is one word and stays allowed); the export rule adds `typeset -p`; env trips with only flags (`env -0`) and as `/usr/bin/env`; set is judged per segment and with redirections, allowed only when piped straight into an anchored grep filter. Quoted strings are blanked offset-preserving so a `#` inside quotes no longer hides the rest of the line. The negative control covers each new form on both sides. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(ship): Step 14.5 names where the launch-file placeholder comes from The /document-release prompt line read `. <file>` with no word on what fills it. It now says the placeholder is the GSTACK_LAUNCH_FILE: path the parent's own install check printed. Worded to stay under the ship skill's pinned parity size (313,279 of 313,281 union bytes). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(redact): env.value admits *_PASS, *_PAT, *_APIKEY and *_PWD, and skips path values and gstack's lock token /ship Step 11 adversarial findings. The name rule also covers DB_PASS, GITHUB_PAT, *_APIKEY and *_PWD (the shell's own PWD and OLDPWD stay out). A credential-named variable whose value is a filesystem path (SSL_KEY=/etc/ssl/ private/x.key) names where the credential lives, so the path is no finding, and GSTACK_BRAIN_LOCK_TOKEN (pid-random-epoch, written to the lock owner file) is not a secret. Without these, an ordinary mention of that path or token in a PR body, receipt or CSO report was a HIGH fail-closed blocker. The adversarial pass also recommended an entropy floor so dev defaults such as DB_PASSWORD=postgres stop matching prose; declined here on purpose, because the scan's promise is to catch a leaked value whatever its shape, and a weak real password is still a credential. Recorded as an open decision in the ship report. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(capy-install): a failed launch-file write removes only its own temp file The failure path ran rm -f "$LAUNCH_FILE".tmp.*, which also deleted the temp file a concurrent installer run (two threads on one machine, same verdict path) was about to mv, so that run lost its launch file too. write_launch_file now cleans up its own $tmp and returns 1; the caller only reports. The file's comment no longer embeds the state-root path (a newline in GSTACK_STATE_ROOT could have ended the comment). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: the launch markers come from one list, and the echo ratchet scans setup and scripts/*.sh The preload imports CAPY_LAUNCH_MARKERS instead of re-typing the four names, and the ratchet asserts the installer exports every name on that list, so a fifth marker cannot be added to one place only. The shell scan also covers ./setup and the scripts/*.sh install scripts callers run first. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): the Unreleased entry states the review-fixed env.value rules, the ratchet forms and the one test-budget change Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(redact): the env.value path exemption asks whether the file exists instead of matching a shape Second review cycle: a path-shaped rule also matched a base64 secret that starts with "/" and holds another "/" (about 1 in 150 AWS-shaped keys), which then went unscanned. The exemption now fires only when the value names a file that exists on the scanning machine (SSL_KEY=/etc/ssl/private/x.key). The module header names that stat as the engine's one filesystem read. NON_SECRET_ENV_NAMES is exported so the test can prove bin/gstack-brain-lock.sh still exports every name in it; the PWD/OLDPWD fixtures hold plain words so only the name rule keeps them out. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: the installer's own-temp-file cleanup is exercised, and the ratchet coverage test names setup and scripts An mv shim first on PATH refuses only the launch-file target, so the temp file exists when the move fails: the run removes that file alone (a sibling from a concurrent run survives), says so, prints no GSTACK_LAUNCH_FILE line and keeps the earlier file, exit code and trailer. The ratchet coverage test asserts setup, scripts/build.sh and scripts/sandbox-doctor.sh are scanned. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(redact): env.value has no path exemption and matches the value in normalized form Second adversarial pass: the existence check let the scanned agent exempt any "/"- or "~/"-prefixed secret by creating a path of that name, a silent bypass of the one guard this branch adds, so the exemption is gone; a path-valued SSL_KEY that must appear in a text goes through the allowlist. The engine is back to no I/O. The value is now normalized the way the text is before indexOf, so a credential NFKC rewrites (fullwidth digits) still finds its leaked ASCII form. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(capy-install): the launch file is written only on a passing run; the ratchet checks the marker list both ways A gstack: fail run no longer writes or announces a sourceable file whose PATH prepend points at an unverified Bun. The ratchet also asserts every variable the launch file exports is a CAPY_LAUNCH_MARKERS entry or GSTACK_STATE_ROOT, so a sixth export cannot reach fixture children unstripped. The Capy skill's prose no longer offers re-typing the assignments as an alternative to sourcing. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(capy-install): the launch file is part of the ok verdict Third adversarial pass: a passing run whose launch file could not be written still said gstack: ok with exit 0 and printed only the GSTACK_LAUNCH line, leaving a shell-evaluating caller with the re-typing path the branch exists to remove. The file is now written before the verdict is recorded; a write failure on a passing run turns the run into "gstack: fail launch-file — could not write the launch file <path>; fix: … (LAUNCH_FILE_UNWRITABLE)" with exit 1 and an ok:false verdict, and every failing run removes the launch file an earlier passing run left beside the verdict. The two failure tests assert the new contract, the doctor-FAIL tests assert no launch file is announced or left, and the docs, Capy skill and CHANGELOG say the same. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(redact): the env.value allowlist and placeholder rules see the normalized value too An allowlisted value in NFC did not suppress a match on its NFKC-composed form, and a value that is a placeholder only after normalization was still searched for. Fixture nits from the third review cycle: fixed directory string instead of process.cwd(), the fullwidth assertion guards its own vacuity, a zero-width-padded value under the floor is pinned, and the ratchet comment names the one kept export and the PATH case line. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(capy-install): LAUNCH_FILE_UNWRITABLE is a registered result code; a kept profile verdict keeps its launch file Fourth review cycle. The new trailer code now has its row in lib/result-codes-capy.ts (the owner module is at its size cap) and its docs/troubleshooting.md anchor, so the install-side code scan resolves it. A failing profile check (--for review-voice) that keeps a fuller ok verdict for this HEAD no longer deletes that verdict's launch file: the fail branch removes the file only when the run rewrites the verdict, and setup_failed removes it too. The docs say "a failing run that rewrites the verdict", and that an unwritable directory keeps both the old file and the old verdict. A new test runs a passing install, then a failing profile check, and asserts the file and the ok verdict both survive. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(redact): the normalized allowlist and placeholder rules each have an assertion that fails without them Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(capy-install): a setup failure after a passing install removes the earlier launch file Fifth review cycle: setup_failed's cleanup had no assertion. The setup failure test now installs once (launch file present), commits a new HEAD so setup runs again, fails that setup, and asserts the launch file is gone and the verdict says ok:false before the next run sets up again and ends ok. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: state-root, contributor reference and capy-install follow the launch-file contract (Step 14.5 audit) The /document-release audit (docs-3449-1792992068) corrected three authored docs: docs/state-root.md shows the GSTACK_LAUNCH_FILE line and says to apply it with ". <that file>" instead of prefixing or exporting the assignments; docs/CONTRIBUTOR_REFERENCE.md names scan()'s one ambient input instead of calling it pure; docs/capy-install.md's bun-shim bullet and exit table name the launch file and the fail launch-file trailer. 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> |
||
|
|
7ee7e8bdd4 |
v1.91.238.0 fix(ship): gate-diff base in single-branch clones, gstack-post release versions and receipt ids, evidence tests_ran, restamp duplicate headings and stamp prompt (GSTA-102) (#3439)
* fix(gate-diff): resolve the base to origin/<base> when no local branch exists; the no_base fix line fetches into the tracking ref Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(post): the repo's release versions and a receipt's tree hash / run ids are not pii.ip_public or pii.phone.e164 Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(evidence): parse the shard runner's and the remote pregate lane's test counts into tests_ran Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(restamp): CHANGELOG_DUPLICATE_HEADING refuses only duplicates the PR introduces checkChangelog takes the base branch's CHANGELOG: a heading the base already carries N times may appear N times on the PR (inherited released history), and only a further copy is a duplicate. gstack-restamp passes origin/<base>'s CHANGELOG at the plan's base sha, so a base like gbrain's master, which heads one version twice, can be stamped; a duplicate the PR adds is still refused with nothing written. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(restamp): the stamp-at-merge next: line no longer asks the lane to edit the CHANGELOG Under a train the stamp commit may hold only restamp's own output: the train's verify accepts the CHANGELOG only as the base's plus the PR's own entry re-headed, and a lane that followed the old "write the CHANGELOG entry text" prompt froze the queue. The claim-at-open wording is unchanged. 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> |
||
|
|
6665e20d56 |
v1.91.236.0 feat(ship-queue): require a current /ship receipt before READY, train build and train merge (#3438)
* feat(ship-queue): require a current /ship receipt before READY, train build and train merge Garry, 2026-10-25: use the gstack ship skill before merging PRs. ready printed SHIP_RECEIPT: none as information and returned ok, so the pool was READY'd without /ship. Now ready, train build (dry run included) and verify --train refuse with QUEUE_RECEIPT_MISSING or QUEUE_RECEIPT_STALE from the PR body alone; verify accepts the receipt written for the pinned head when the current head is its stamp commit. gstack-ship-receipt result is /ship's terminal step (GSTACK_RESULT: skill=ship, run dir with the head and receipt), unattended /ship may update an existing PR's body, and INSTALL_UNVERIFIED with no verdict names the project directory to install from (GSTA-85). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(ship): pin Step 22 in workflow-required-steps and tighten the ship skeleton Gate edit: test/fixtures/workflow-required-steps.json pins the new "## Step 22: Terminal line (every run)" heading (strengthens: a later edit that drops the terminal line turns the required-steps test red). Steps 14, 16, 18, 20 and 22 prose tightened so the carve-guards raise shrinks to 81,600 / 1.6740 (measured skeleton 81,535, union 314,027). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (ready at the stamp commit, screen on a stale merge ref, ship-run.json) - ready accepts the pin's receipt at a slot's stamp commit (plus the slot-2 merge of main), as verify --train already did; a real edit stays STALE - ready --screen refuses QUEUE_SCREEN_STALE_REF when refs/pull/<n>/merge is missing or merges an older head; a finished screen that planned 0 cases is never followed, and train build seats that slot unscreened (GSTA-95 on #3431) - gstack-ship-receipt result writes ship-run.json (a /ship record, not a run v1 manifest), validates --head, and prints status=incomplete on gh failures - bindReceipt takes an optional pr and renders one-line SHIP_RECEIPT lines - tests for every state-matrix cell the review named; the train fixture's merge ref is a real merge commit Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: cycle-2 review fixes (private screen scratch, no bare-merge receipt reuse, 12-hex --head, one receipt scrub) and align the unattended hook text with the GSTACK_RESULT writers (GSTA-91) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: adversarial-review fixes (result refuses an unpushed HEAD, resolves --out and reports unwritable records; ready names a failed merge-ref fetch; unattended /ship never runs gh pr ready) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: close review-cycle gaps (a stamp must change a stamp file, result requires a full --head and fails closed without headRefOid, digits-only --pr) with tests for every cycle-3 branch Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: give the fsck-rejected merge-ref spawns a timeout (spawnsync tripwire) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: detect a hollow screen from the plan it uploads (no paid-plan artifact or nothing planned), correct two troubleshooting facts, and normalise result --pr Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(hollow-screen): read manifest.json by name, list artifacts by name, say when the plan is unreadable; lowercase result --head Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(hollow-screen): expired and unreadable run rows, uppercase --head; docs name every SCREEN: literal Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(train build): say when the repository slug is unreadable instead of counting the screen silently Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: name an ls-remote failure in ready --screen, refuse result --pr with --body, cap echoed receipt errors, tell an unreadable install verdict from a missing one Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: ls-remote refusal, --pr with --body, capped receipt errors, unreadable slug and verdict (both twins); docs name the new literals Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: scrub Unicode line separators from receipt text, report an unreadable --body as incomplete, refuse unsupported verdict schemas in the bash twin Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
669e59d65b |
v1.91.206.0 feat(pregate): user-owned policy file and local lanes (port of #3286) (#3398)
* feat(pregate): user-owned policy file and local lanes
A repo that keeps .gstack/ out of git can hold its pregate policy at
<GSTACK_HOME>/projects/<slug>/pregate.json. gstack-pregate run reads it only
under --policy-from base when the base carries no .gstack/pregate.json, so a
reviewed base copy always wins and a PR still cannot reach the policy. A
missing file falls back; any other read error, and a non-null sealed or
price_file (read only from the git copies), refuse with PREGATE_CONFIG_INVALID
and a fix that names the file.
A new `local` key lists <workflow.yml>/<job> lanes a local run satisfies: a
platform lane named there runs here (tier unit) instead of becoming a
requires-remote obligation. Lane ids share one LANE_ID check with selection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(pregate): the user-owned policy file and local lanes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pregate): policy fixes name the user-owned file when it is the active policy
With no .gstack/pregate.json on the base, an edit to that path is never read,
so the no-lane, runner, stall_timeout_s, remote_gate and strays fixes now name
ctx.configFile: the user-owned path when it is the active policy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(pregate): the remote_gate, strays and stall fixes name the active policy file
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pregate): pre-landing review fixes for the user-owned policy
Ignore a user policy path that is relative or inside the checkout, fingerprint
the active user file into check inputs, name the user file in its JSON errors
and the refusal lead, add --explain lines for an absent user file and an
unknown local id, and document the state-root location and slug lookup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pregate): containment edges and explain wording for the user policy
A state root under an in-repo directory named ..something passed the
inside-the-repo check, and realpath kept the caller's casing on macOS.
The unknown-local explain line now says workflow lane, and the state-root
chain in explain and docs names every source.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pregate): a base copy git cannot read, or a dangling user symlink, refuses
Any git show failure read as no base policy, which now hands the run to
the unreviewed user file; it is absent only when cat-file says so, and a
spawn error (stdout cut at the buffer limit) counts as a failure. A user
pregate.json that is a dangling symlink refuses instead of reading as
absent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pregate): decide a missing base policy from the tree, and catch dangling parent links
cat-file -e checks the blob, so a missing or corrupt object still read as
no base copy; ls-tree reads the tree entry, and any failure refuses. The
dangling-symlink check now covers every path component, not just the file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(result-codes): POLICY_SOURCE_UNAVAILABLE names an unreadable committed pin file
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(pregate): the active policy may be the user-owned file; new refusals
Guards, remote_gate, stall timeouts and lane fixes name the user-owned file
when it is the active policy; the trust boundary says run alone reads it;
the dangling-symlink and unreadable-base-copy refusals are documented, and
state-root lists the bucket's pregate.json.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pregate): a checkout's .env cannot pick the user policy; verify re-checks it
Bun loads .env from the working directory, so a branch could set
GSTACK_PROJECT_SLUG or a state root and choose which pregate.json governs
it. The shebang now passes --no-env-file, scriptInvocation carries that
flag over when it launches the bin as bun <script>, and a bare bun launch
beside any dotenv file refuses (POLICY_SOURCE_UNAVAILABLE).
A recorded pass also outlived its policy: pregate.json now records the
user file's digest (or, under the defaults, the path that was absent), and
verify and the ship receipt treat an edited, deleted or newly present user
file as PREGATE_STALE, reading both paths from the record.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pregate): keep the POLICY_SOURCE_UNAVAILABLE summary's pin-files wording
The added '(or .gstack/pregate.json)' broke describeRefusal's rewrite to
'the reviewed pin files cannot be read', which pregate-wtree-refusal pins.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(pregate): pick the host-foreign lane in the user-policy local-lane test
On a Windows host the windows lane is native, so it never became
requires-remote and the test failed on the Windows shards.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pregate): Rust crate lanes and nested JS package runners
lanes reported PREGATE_NO_LANE for every touched .rs file and ran a nested
pnpm+vitest package's tests as `bun test` from the repo root.
- Rust: a .rs file of a crate (nearest Cargo.toml with [package]) is a test
under <crate>/tests/ or when it holds a #[cfg(test)]; every .rs file of a
crate and its Cargo.toml select the crate's tests and those of every crate
depending on it (lib/pregate/rust.ts). Selected tests run per crate as
`cargo test -p <name>` from the workspace root, judged on the summed
`test result:` lines (doc-tests included); zero tests stays ZERO-RUN and a
missing cargo is incomplete, like a missing Dart SDK.
- JS/TS: a test owned by a nested package.json that declares vitest or jest
runs from that package with package-relative paths, through the package
manager its packageManager field or nearest lockfile names (pnpm exec,
yarn, bun x, else npx). Root detection and a declared runner are unchanged.
- init notes that Rust tests run per crate; docs/pregate.md updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pregate): parse Cargo manifests as TOML; follow workspace membership
The line scan of Cargo.toml missed dependents (a false green) and picked the
wrong workspace:
- an inherited renamed dependency (`base = { workspace = true }` with
`[workspace.dependencies] base = { package = "alpha", path = ... }`);
- dotted keys (`alpha.path = "../a"`), `[dependencies.<name>]` tables and
target-specific tables, matched by key name only;
- a crate the workspace excludes ran `cargo test -p` from the workspace root.
Manifests are now parsed with Bun.TOML. A dependency resolves by path
(relative to the manifest declaring it, or to the workspace root when
inherited), else by package name. A crate runs from the workspace it is a
member of under Cargo's rules (package.workspace, the nearest [workspace],
members globs, exclude, literal members, path dependencies of members),
else from its own directory. Nothing runs cargo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(pregate): the Rust fixture's cargo shim wins PATH on Windows and beside a real cargo
windows-free-shard (5) failed 'a touched src file runs its crate...' and
'zero tests is ZERO-RUN...' deterministically: the shim PATH was joined with
':' so Git Bash never saw the shim dir, and the runner's real cargo ran
against the fixture (exit 1, no test result lines). On POSIX hosts where
Bun and cargo share a directory (/usr/local/bin on Capy's image), the lane
puts Bun's directory first and the real cargo wins the same way.
Join with path.delimiter, add cargo.cmd for Bun.which on Windows, and on
POSIX put the shim first again in the lane's own bash through BASH_ENV.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): quote the crate name in cargoRunner
The crate name is read from the repo's Cargo.toml and was interpolated into
'cargo test -p <name>', which the lane runs through bash. A name like
'evil;touch pwned' ran the second command. Quote it like every file and cwd
the lane already passes; a new end-to-end case checks the name reaches cargo
as one argument and runs nothing.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(pregate): the nested-package pnpm shim wins PATH beside a real pnpm
'a touched file in a nested pnpm+vitest package runs vitest there' ran the
host's real pnpm wherever Bun and pnpm share a directory (/usr/local/bin on
Capy's image): the lane puts Bun's directory first, so pnpm installed vitest
from the network, dirtied the fixture tree and the check came back
incomplete. Put the shim first again in the lane's bash through BASH_ENV,
as the Rust fixture does.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): pregate Rust crate lanes and nested package runners (#3344)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): a crate name Cargo would reject never reaches the lane's shell
Port review (outside voice): quoting alone was not enough, because the lane
expands {files} after the runner string is built, so a crate named
'evil{files}' spliced the quoted file list into the quoted name and a file
name like tests/$(cmd).rs then ran. A name outside Cargo's grammar
(letters, digits, _ and -) now gets no runner: its files are unclaimed and
the lane is incomplete, as Cargo itself would refuse the manifest. A valid
name, Unicode included, still runs quoted.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): match Cargo members globs per path component, without a backtracking regex
Port review (outside voice): members globs went through ship-policy's
matchesAny, which escapes [...] classes (crates/[ab] matched nothing, so the
crate was no member, lost its inherited [workspace.dependencies] path and its
dependents' tests were never selected: a false green) and backtracks
exponentially on a hostile glob such as '*a*a...*ab' (over 5 s for one crate,
before any runner deadline). A small dynamic-programming matcher handles *,
?, [..] with negation and ranges, and ** across components, in
O(pattern x path).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): a plain #[test] in src is a Rust test; bound the cfg attribute scan
Port review (outside voice): only #[cfg(test)] modules and tests/ files
counted, so a dependent crate whose tests are plain #[test] or #[tokio::test]
functions in src never ran when its dependency changed (a false green). The
cfg scan also went quadratic on a run of unclosed '#[cfg(' (about 3 s on
120 KB). Test attributes now count, and the cfg predicate and its strings are
length-bounded so the scan stays linear.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(pregate): Rust test attributes, workspace membership and rejected crate names; changelog for the port review fixes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): match members globs by code point in one pass, and admit every crate past a size cap
Second port review round (outside voice): the matcher counted UTF-16 units, so
'crates/?' missed a crate directory named with a supplementary character and
dropped its inherited dependencies (a false green); and each unmatched '['
rescanned the rest of the glob (5 s for one crate with a million of them).
Tokenize by code point with a precomputed next-']' table, and past 4096
characters of members globs admit every crate under the workspace: a wrong
member fails loudly in cargo, a dropped one is silent. The new supervised
probe kills a super-linear matcher at 30 s instead of hanging the file.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): scan cfg attributes once without truncating them; an unclosable one counts as a test
Second port review round (outside voice): the length bound from the first
round dropped a valid cfg(any(test, feature = "<257 chars>")), so its crate's
tests were no longer selected (a false green). Read each attribute once to
its closing ']' and resume after it, which keeps the scan linear without a
bound; an attribute the scan cannot close (an unterminated string, no ']')
counts as a test, which selects more, never fewer.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): second port review round (code-point member globs, unbounded linear cfg scan)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): past the members size cap, a crate's run root is undecided and its tests unclaimed
Third port review round (outside voice): admitting every crate past the cap
made a non-member run as 'cargo test -p <name>' from the workspace root,
where a same-named member answered and its passing tests stood in for the
orphan's failing one (a false green). Keep the conservative membership for
dependency edges, but leave such a crate's workspace undecided (null):
planRuns leaves its files unclaimed and the lane incomplete.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(pregate): the Rust end-to-end runs put the cargo shim under Windows' own Path key
windows-free-shard (5) still failed both end-to-end cases at
|
||
|
|
db87940e24 |
v1.91.198.0 fix(outside-review): a reviewer's own "not ready" verdict floors advisory-only findings (#3329, port of #3364) (#3376)
* honor not-ready review verdicts with advisory findings The classifier now honors the last recognized not-ready verdict regardless of parsed severity, returning findings and exit code 3 while retaining the highest severity in the summary. Advisory findings with a ready verdict or no verdict keep their existing behavior. Regression coverage and troubleshooting documentation describe this behavior across the execution, structured, and review gates. Fixes #3329 * docs(changelog): outside reviewer not-ready verdict floors advisory findings (#3329, port of #3364) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
225a210378 |
v1.91.189.0 fix(ci): bounded Playwright install with one infra retry, PR runs get main's local branch, Bun install default 1.4.4 (GSTA-68) (#3368)
* fix(ci): bounded Playwright install with one infra retry, PR runs get main's local branch, Bun install default 1.4.4 (GSTA-68) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(runtime-pins): read the install-default job's pin from GSTACK_BUN_DEFAULT (GSTA-68) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.189.0 stamp Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
632bde77de |
v1.91.187.0 docs: unattended contract, gate reply grammar, session-kind override and voice triggers match the code (GSTA-69) (#3367)
* docs: unattended contract, gate reply grammar, session-kind override and voice triggers match the code (GSTA-69) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.187.0 stamp Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
e7a1df9e18 |
v1.91.172.0 feat(capy): approvals per thread, Captain plan briefs and before/after PR images (#3328)
* feat(capy): approvals per thread, Captain plan briefs and before/after PR images (GSTA-61) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(capy): mark whole rewrites in PR images, point the ship guide at the skill folder, refresh ship goldens (GSTA-61) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(context-budget): raise the Capy skill ceiling for "Working under a Captain" (GSTA-61) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * revert(capy): keep wrapper 2; owners copy the skill folder by hand (GSTA-61) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.172.0 stamp (#3328) 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> |
||
|
|
5ebda5999f |
v1.91.161.0 fix(pregate): Django, Dart, asset and tool-config lanes; init drafts from the repo (#3266-#3269) (#3306)
* fix(pregate): Dart import graph and test lanes (#3285) Port of arlophoenix's #3285. The import graph reads Dart import/export/part directives and resolves package: URIs through every tracked pubspec.yaml; _test.dart files under test/ are tests. lanes runs each Dart package's selected tests from its own root with flutter test or dart test (through fvm when the package pins it). flutter/dart/melos/very_good CI jobs are lanes, and run-step test paths resolve against working-directory and literal cd. A missing Dart SDK or a .dart file outside any package leaves the lane incomplete with a fix line; device tests (integration_test/, test_driver/) are not unit lanes. Co-authored-by: arlophoenix <arlo.phoenix@gmail.com> Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pregate): a --base that names a commit gets a branch fix, not an impossible fetch (#3269) gstack-pregate --base <sha> refused with "fix: git fetch origin <sha> --depth=1". That fetch can never create origin/<sha>: a short SHA fails with "couldn't find remote ref", and a full SHA only reaches FETCH_HEAD. A fork clone hits the same wall with --base upstream/main. When origin/<base> does not resolve but <base> names a commit here and no local branch (a SHA, a tag, another remote's ref), the refusal now says --base takes a branch name on origin and suggests origin/HEAD's branch. A local branch, or a name that resolves nowhere, keeps the fetch fix: that is the unfetched or shallow checkout it repairs. Same code, same exit 3, and pin files are still read only from the reviewed origin/<base>. Fixes #3269 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(pregate): Django, asset and tool-config lanes; init drafts from the repo (#3266, #3267, #3268) - Django: settings modules, settings strings, include(), app migrations, admin, templates, static files and project templates get framework edges (lib/pregate/django.ts). - Assets, stylesheets and dotfile tool config take a no-tests empty lane; licence text under any name is documentation. - gstack-pregate init drafts languages, runner notes and nearest-test dependencies; never writes []. - Review fixes on the #3285 port: untracked shell scopes leave a lane unknown; Dart directives read to their semicolon; nested comments. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(pregate): init draft API is exercised directly, so init-draft.ts has a lane Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): restore the history a truncated rewrite dropped Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pregate): outside-voice review fixes for the non-JS lanes - Tool config is an allowlist: unknown dotfiles (.rspec, .husky hooks) and stylesheets still need a lane; snapshot, golden and fixture trees and .gstack/ are never inert. - Django edges need Django evidence (manage.py or code importing django) and settings assignments in code, not strings or comments. - A cd after ||, &, control flow or braces leaves a lane unknown. - Dart directives allow metadata and quoted semicolons. - init drafts at most 256 dependencies (the schema limit); the rest are TODO. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(windows): pregate-dart and pregate-non-js join the POSIX-run pregate fixtures Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore: release v1.91.161.0 Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: arlophoenix <arlo.phoenix@gmail.com> Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> Co-authored-by: y$un_ <forrest.sun527@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
6b57ededeb |
v1.91.153.0 fix(outside-review): no-findings counts only as the review's conclusion; add regressions (#3294) (#3304)
* fix(outside-review): no-findings counts only as the review's conclusion; add regressions/defects (#3294) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(outside-review): a trailing ', and' clause can conclude; elsewhere/otherwise are exceptions; real codex captures Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(outside-review): whitelist the conclusion's qualifier; join wrapped Recommendation clauses; outside-review findings as controls Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(outside-review): join a wrapped line only when it continues in lowercase 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> |
||
|
|
6a4ab69dcd |
v1.91.146.0 feat(ship-queue): merge trains with pattern bisect and train-record verify (GSTA-49 T1) (#3272)
* feat(ship-queue): merge trains with pattern bisect and train-record verify (GSTA-49 T1) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(windows): curate ship-queue-train.test.ts out of the Windows subset (gh shim not resolved on windows-latest) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.145.0 feat(ship-queue): merge trains with pattern bisect and train-record verify (GSTA-49 T1) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.146.0 restamp: #3295 takes v1.91.145.0 Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
8f103baa71 |
v1.91.131.0 feat(pregate): Python import lanes (#3201) and a missing-dependencies regen diagnostic (#3252)
* feat(pregate): lanes follows Python imports and mock.patch targets The import graph only parsed JS/TS imports, so in a Python repo every touched module failed `lanes` with PREGATE_NO_LANE even though SOURCE_EXT, TEST_FILE_RE and the pytest runner/summary already understood Python. Python sources now contribute `import a.b`, `from a.b import c` (c may be a submodule), parenthesised multi-line lists and relative `from ..pkg import x` edges, resolved to `a/b.py` or `a/b/__init__.py` from the repository root. Package `__init__.py` files on the path get edges too, since Python executes them on import. Modules outside the repo resolve to nothing. In test files, dotted string literals such as `'pkg.mod.Class.method'` (mock.patch targets) resolve to the longest dotted prefix that is a repo module. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(regen): report missing dependencies as REGEN_DEPS_MISSING, not REGEN_STALE When package.json declares dependencies and node_modules is missing, the scratch worktree runs the generator without them. A generator that degrades and still exits 0 then looked stale, and the fix line sent people to rerun the generator. gstack-regen check and the pregate regen check now report "dependencies missing; run <install>" with its own result code and troubleshooting anchor; the install command follows the lockfile. The fixture reproduces the shape GSTA-31 saw in gbrain. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pregate): keep Python import scanning linear and conservative Review of #3201 on the integrated tree found two quadratic paths on untrusted Python source and three ways a test could be left unselected: - The from-import module spec let two repetitions share a dot, so a failed match on a long run of dots backtracked quadratically. The spec is now dots followed by an optional word-led name. - Dotted literals and imports resolved every prefix with repeated split/join. Names are capped at 32 segments, deeper than any module path. - A literal that also named a repo file skipped its mock.patch reading; both readings now add edges. - A package and a same-named module both map (Python loads the package). - Imports after `;` or a compound statement's `:` are recognised. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pregate): linear Python string blanking, non-empty from-spec, repo-bounded depth Second review round on the Python import scanner: - An empty from-spec let the whitespace on both sides of it compete, so `from` followed by a long run of spaces backtracked quadratically. The spec now starts with a dot or a word character. - Strings and comments are blanked by a single linear scanner that honours backslash escapes, so an escaped triple quote no longer ends a docstring early and swallows the imports after it. - The fixed 32-segment cap dropped real deep modules. Dotted names are now bounded by the repo's deepest path, which no module can exceed. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): unreleased entry for Python import lanes and REGEN_DEPS_MISSING Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.126.0 stamp Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * release slot 1.91.126.0: back to unstamped (CHANGELOG entry unreleased) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(changelog): resolve the main-merge conflict (Unreleased entry above 1.91.127.0) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.131.0 stamp Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: Scott Gigante <scott@gethubflow.ai> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
4e4f2959cd |
v1.91.126.0 fix(brain-sync): hold case-colliding artifact paths instead of reporting ok (#3220) (#3254)
* fix(brain-sync): verify requested index entries after add Refuse missing or unrelated staged paths and stale indexed content without consuming the queue or resetting the index. * fix(brain-sync): refuse new casefold path collisions Check component prefixes in requested/index and outgoing trees, including retained commits and fetch/merge retries. Preserve historical aliases, local commits, index, and queue on refusal. * fix(brain-sync): hold case-colliding paths instead of halting the sync (#3220) Builds on Kkkkkuro's staged-index and casefold checks (#3245, from #3223). A queued path whose spelling differs only by letter case from another path in the index or the batch is held before staging: it stays queued, every other file keeps syncing, and the status is "collision" rather than "ok". An established spelling keeps syncing; only the new alias waits. Skill start prints one ARTIFACTS_SYNC attention line naming the colliding names and the repair anchor (docs/troubleshooting.md#artifact-case-collision); gstack-doctor warns the same way. The outgoing check is cached by HEAD so the empty-queue drain at every skill boundary stays near main's cost. gstack-slug and skill start's slug path are unchanged. Co-authored-by: Kkkkkuro <180382840+Kkkkkuro@users.noreply.github.com> Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(brain-sync): close review gaps in the case-collision hold - Windows: write the held-path list with LF and strip CR from helper output, so CRLF cannot let a held path through or blank case_names. - --publish-removals runs the outgoing case check before it pushes. - The cached outgoing verdict is keyed by every ref, not HEAD alone, so a moved remote baseline is re-checked. - The repair snippet folds only JSONL logs and lists snapshots and other files for a manual decision. Co-authored-by: Kkkkkuro <180382840+Kkkkkuro@users.noreply.github.com> Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(brain-sync): second review pass on the case-collision hold - The repair loop also folds the dropped spelling's untracked (held) files and says to check for leftovers before removing the folder on Linux. - The cached outgoing verdict also keys on HEAD's symbolic target. - The outgoing check no longer needs a temp file, so a failed mktemp can no longer skip it. Co-authored-by: Kkkkkuro <180382840+Kkkkkuro@users.noreply.github.com> Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(brain-sync): give the retry-merge fixture a git identity The retry merge commits with the ambient identity. CI and Ubicloud runners have none under the test HOME, so the merge failed before the outgoing case check ran and the drain reported push_failed instead of error. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(changelog): unreleased entry for the #3220 case-collision hold Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.126.0 stamp Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: KuroChen <Kkkkkuro@users.noreply.github.com> Co-authored-by: Kkkkkuro <180382840+Kkkkkuro@users.noreply.github.com> Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> |
||
|
|
82530ac143 |
v1.91.117.0 fix: pregate bats lanes, WTREE_UNAVAILABLE, doctor rows, SKILL.md size guard, planMode hosts (fix wave PR 5) (#3236)
* fix(pregate): recognise bats test files so lanes does not fail in bats repos (#3161) gstack-pregate never treated a .bats file as a test, so in a repository whose tests are bats files the lanes check failed every run with PREGATE_NO_LANE: a .gstack/pregate.json dependency pointing at tests/foo.bats selected nothing, a selection manifest printing .bats paths yielded 0 files, and a bats run that executed no tests could not trip the zero-run rule. Recognise .bats in the test-file pattern and in the manifest-output parser, and read the bats TAP plan and pretty summary (as a last resort, after every existing runner's summary) so a run that reports zero tests is a failure. Fixes #3161. Cherry-picked from #3177 ( |
||
|
|
cadbd0af15 |
v1.91.116.0 feat: field list 2 wave B: gstack-ship-queue, approval classes, state-machine review, pregate timing check, update-check main moves (#3235)
* fix(capy): the install trailer says behind=<n> and its fix, so a stale install shows in every relayed trailer (field list 2 item 13, #2378) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(capy): a lease records its holder's start identity, so a pid reused after a wake is reclaimed; a skipped session-start upgrade ends fail behind, never ok (GBRA-105, GBRA-106) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(lease): stale needs proof (unreadable or malformed identities keep the lease), ps identity is timezone-independent, and reclaim never deletes a concurrent renewal Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * feat(autoplan): enforced round cap and spend budget, deferred close, public export without machine paths, opt-in durable checkpoints (field list 2 W5-W7) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(lease): one directory lock for publish, prune and reclaim; reclaim rereads the record judged stale, so a renewal is never deleted or hidden Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(lease): the directory lock names its holder; broken only when the holder is dead or its pid reused, unlock removes only its own lock, touch exits 3 under a live holder Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(lease): breakers serialize on .lock.break and reread the lock before removing it; gstack-skill-start reports a lease the held lock kept out Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs(lease): name the double-crash limit of breaking a dead lock Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * feat(capy): --for review-voice install profile, no-Drive bootstrap command, reviewer prompt trailer (field list 2 W11) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> (cherry picked from commit |