The fix-check found that keeping a local base ahead of origin left unpushed
base commits out of the gate scan while review-plan listed them. The tracking
branch now wins whenever it shares history with HEAD, an explicit origin/main
reads refs/remotes/origin/main, the preflight also stops when the diff lists
fewer files than the PR, and the Step 9 exclude line survives a missing
.git/info and an exclude file without a final newline.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Resolve the tracking twin by refs/remotes/<remote>/<ref> and only for a bare
branch name, keep a local base that is ahead or diverged, quote the prSized
stop's base and name the fork case, and have every Step 9 entry create,
exclude and clear .gstack/tmp/targeted.json.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
- isOpenFinding treats action 'open' (the logger's forced-open stamp) as open before a row's status or disposition.
- reviewFreshness flags a claimed clean row only for an 'open' action or a CRITICAL or blocking deferral or note, so
interactive kept and restored gates, skipped advisories and INFORMATIONAL deferrals read CURRENT as before.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
- deriveFromFindings stamps gate rows with the session kind before deriving status, so a findings file cannot
dispose of a gate finding the unattended logger forces open (outside-voice#1).
- reviewFreshness reads a claimed row's findings with isOpenByAction, the rule the notes-only rewrite uses;
noted and deferred clear a finding only when it is marked blocking: false and is not CRITICAL.
- patchId sweeps gstack-patch-id-* directories over an hour old that a killed carry left in TMPDIR.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
- A notes-only pass is recorded clean only when every finding is fixed, or noted or deferred below the
blocking floor (never CRITICAL or blocking), by its logger-stamped action, and the findings account
for the claimed issue and critical counts (GST-430).
- The preflight scoped carry route commits and pushes the base-merge fix before writing the packet (GST-442).
- patchId refuses by name on an unwritable TMPDIR; the tree receipt names why its diff failed (GST-448).
- Step 16 stage 3 spells out --docs-requested with its --docs-result (GST-444).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* ship: poll readers in-program, never wait on wakes; 32 KB returns; gated fix program; unattended push defers the guard offer; calls meter (GSTA-167 calls PR 1)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (inventory lib/ship-release.ts as a GSTACK_SESSION_KIND reader)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(ship-budget): document calls and dotted --step notes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* ship: one call per review pass on Capy; staged dispatch manifest, chunked briefs, intent before create (GSTA-167 calls PR 2)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (pass program reruns a failed review-log start and stops on a failed reader every run)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: Step 11 review fixes (PASS: none read from the last line only, queued readers reconciled and timed out, a budget stop ends the pass)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* ship: judge treats a missing severity as invalid; Capy passes rendered briefs via cat (replay C1-34 breaks)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: the batched reviewer reads its checklists by path, as the render CLI is given them (PR #3665 review)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: keep the Capy skill under its context budget after the main merge
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore: drop PR 1's changelog fragment, which main's v1.91.355.0 stamp already consumed
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): the pass program takes extras as JSON and a cwd, and waits a minute for a done reader's summary (replay C2-34)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(capy): reviewer installs leave the lane's launch environment alone; gstack-upgrade counts capy-server leases (GST-395/396/401/402)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(capy-install): restore the header comment prefixes; borrow the lane's launch file only when it reaches a Bun (GST-401)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(capy-install): gate the store-download borrow test to Linux like its siblings
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>
A scoped-review packet section over 200 lines sends that path to the full loop instead of a truncated packet. The docs-result path match is exact. test_*.py, *Test.java and similar count as test code only under a test directory.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(eval-selector): changelog.d fragments have no eval dependents (GST-400)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(pr-profile): derive the fragment-naming case from touchfile selection, not a hardcoded input
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* harness-version: record scripts/test-pr-profile.ts as non-behavioral (selection only, GST-400)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (fragment exemption only for .md directly in the folder; rename lists keep the old path)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(paid-free-boundary): re-audit test-selection.ts after --no-renames; computed import unchanged, repin its hash
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
The attempt STOP no longer echoes the audit child's fix text. A scoped-review carry now requires the product patch-id without the context paths to match at both heads.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
A test-only edit with no gate tag gets the scoped fix-check of its test hunks instead of a lanes-only rerun. Packet write failures print a STOP or RECEIPT_CARRY_REFUSED. attempt's allowance uses an exclusive create.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
gateEditedPaths reads removed lines only inside hunks; carry refuses when a path listing fails; docs freshness stops on a failed listing; attempt counts an unreadable state file. releasePaths includes stamp_files paths whose edit is a version swap under stamp_patterns.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
A test edit routes as tests= only when it adds lines with no gate tag; a removed or changed line or an unreadable test diff goes through the full loop. Diffs skip textconv. A hunkless patch (binary, empty, mode-only) is same when its patch-id matches. Without --reviewed-base test files route as before. finish's packet path and attempt's state directory have fallbacks.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* review: targeted read-only pass on money, gate, auth and secret diffs (GST-257 part 1, report-only)
lib/review-targeted.ts classifies a diff's added and deleted lines into
money, gate, auth and secret (token-bounded, docs and tests excluded,
fails closed to all four). gstack-review-plan prints TARGETED and
dispatches one read-only targeted reader at full effort when a class
hits; review/specialists/targeted.md is its brief. The receipt records
review_targeted bound to product_patch_id, a carry keeps it, and
gstack-ship-queue ready / train build print a report-only
REVIEW_TARGETED line that refuses nothing.
No-loss evidence: the dispatch-superset test in
test/review-targeted.test.ts runs gstack-review-plan on 18 fixture diffs
and requires every reviewer main dispatched at 8be7f21, unchanged, plus
only the targeted reader. Brief identity: gstack-review-dispatch render
on this tree and origin/main 2356792 gives 13 of 13 existing reviewer
briefs byte-identical (handoffs/GSTA-160/gst257-briefcmp/SUMMARY.txt).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (targeted patch id covers tests, record binds the diff it read, role list pin)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: targeted reader reads the merge base on every pass; dirty-tree record test
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: targeted render takes --base and any spelling of the merge base; Step 11 says the merge base; docs gate-path list
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: type the fail-closed class list (typecheck:test ratchet)
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>
comparePath returns same only when every hunk sits where the base change puts it (patch-ids ignore positions) and treats a file-mode change as changed; the scoped-review packet says when a fence is truncated; --docs-result must be the posted audit's result; the --context-reviewed record goes beside the packet, outside the worktree. Negative controls for each.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): literals skips a version-history row when the branch extended its table (GST-344)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): literals reads the merge base through renames, treats an unreadable base as not extended, and recognizes quoted digit-leading history keys
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): literals exempts only a history row's first field, finds tables in one pass, and matches rows within one line
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): literals checks only the text after a history row's closing bracket; restore digest fixtures
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>
Also: the Captain digest drops an archived thread from In progress in the same turn (GST-371).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(skill-evals): land-and-deploy eval task suite (GSTA-161)
Ten tasks written before any cut: happy path, a red required check with an
--admin push (wrong-behavior control), a conflicting PR, an already-merged
PR, a dirty checkout, the first-run dry run, deploy success, deploy failure
(no revert), a canary URL with no browser, and a Render deploy hook that
needs a dashboard step. seed.sh builds a tiny Bun library with a local bare
remote; gh-stub.sh fakes PR #1, its checks, a real squash merge and the
deploy run; check.sh asserts the end state from the remote and the gh log.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(land-and-deploy): skill diet — canary and browser contracts load on demand (GSTA-161)
Step 7's canary script and health assessment, the Aside browser contract,
the gstack-browser fallback and the Third-Party Web Actions contract move
from the always-loaded SKILL.md into sections/canary.md, read at Step 7 when
a URL is checked or before any browser step or third-party site action. The
routing rules (SKIPPED without a browser, staging and production routes) stay
in the skeleton. Shared resolvers are untouched.
Skill-Diet: land-and-deploy
Skill-Size: 107318→87590 bytes (loaded per session, confirmed run without a canary URL; SKILL.md 51992→32264)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: re-pin land-and-deploy size and carve guards after the diet (GSTA-161)
The canary section drops its duplicated health checklist and long labels so
the parity union stays under its 1.126 cap with the new pointer and index
row. Carve guard: canary.md joins expectedSections and maxSkeletonBytes
drops 52,682 -> 32,216. The codex and factory size pins go away: both hosts
are now under 100,000 chars. The browser tripwire reads land-and-deploy's
Aside contract from sections/canary.md, as it already does for qa.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(skill-evals): widen land-and-deploy canary-no-browser must before the paid verdict (GSTA-161)
The priced pilot (after arm) behaved correctly: it reported MERGED
(UNVERIFIED) and 'URL check skipped' with no browser, but the pattern only
accepted canary/health/browser before 'skipped'. Detector fix, the same for
every arm, made before any before/after cell ran.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(skill-evals): drop private:true from the land-and-deploy deploy fixtures (GSTA-161)
The Deploy workflow runs bun publish, which refuses a private package, so
deploy-ok's 'deploy works' scenario was not actually deployable and a careful
run correctly held the merge. Variant-scoped: other tasks seed identical repos.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* changelog.d: land-and-deploy diet fragment (GSTA-161)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* changelog.d: scope the land-and-deploy saving to Claude Code (GSTA-161)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(ship): failing-first Step 12 keep-current refusal and unattended early bump write (GST-380)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): Step 12 keeps VERSION on --keep-current, adds bump never, and waits for the owner's answer before an unattended bump (GST-380)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: regenerate ship SKILL goldens (GST-380)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (answer gate covers ALREADY_BUMPED --version writes; typed session rows; never drift and --answer rejection cases)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (the answer gate names every flag that decides the write; Version Gate and validate understand bump never)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: under bump never a release PR that moves VERSION takes the Version Gate's ordinary rules
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): fragment for GST-380 Step 12 keep-current and bump never
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(benchmark): particle-1 and DeepSeek V4.1 Flash awareness, gateway provider, preregistered model panel (GSTA-173)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(evals): particle-1 model panel results, run 2026-10-30-0105 (GSTA-173)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(model-panel): name the task field id (credential scanner false positive on key)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: gateway reports a missing OpenRouter key first; register the model panel in the paid count and test-of-test baseline
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: run the fake claude through bun so the gateway provider test passes on Windows
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: gateway benchmark runs load no Claude Code settings
A settings.json env block's ANTHROPIC_API_KEY was sent to the OpenRouter base URL as x-api-key; --setting-sources '' loads no settings source.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: name particle-1 and DeepSeek V4.1 Flash in the /benchmark-models row
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore: changelog fragment and TODOS for the particle-1 model panel
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: name particle-1 and DeepSeek V4.1 Flash in the AGENTS.md /benchmark-models row
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>