- 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>
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>
* 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>
* feat(review): variant G part 4: data files no code names are docs in classifyDiff, untested state-matrix cells map below the floor per cell (GSTA-167 PR-a)
Part 4a: lib/review-depth.ts owns DATA_PATH (JSON, JSONL, NDJSON, CSV, TSV, raster
images; YAML, TOML and SVG stay code) and applies the data rule only in classifyDiff,
to candidates lib/review-collect.ts finds no non-docs consumer for (git grep of
basenames at head, merge base and, live, the working tree; data-to-data chains four
deep; over 2,000 candidates keeps all code; a grep failure fails closed). classifyPath
and every path-only caller are unchanged; the receipt gate scan decides through
gateScanNeeded (path-only), so it cannot be skipped. gstack-ship-preflight computes
RUNTIME_LINES with classifyDiff over gstack-review-plan --json (now with consumed).
Part 4b: lib/review-scope.ts mapStateMatrixOutput maps an "untested cell" finding to
INFORMATIONAL when its cell has test null in the same output's matrix and it is the
only finding on that cell; gstack-state-matrix findings prints it for Step 9.2 before
the merge. state-machines.md is byte-identical; check still reads the raw output.
Reviewer-brief pins repinned under no-loss replay PR-a (Arm 4: plan identity at the 14
cohort heads; free exact re-score of saved C, D and A' findings).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(review): variant G parts 1 and 3: blocking floor in both prose voices, specialists at medium (GSTA-167)
Part 1: the native adversarial and outside-voice prompts end with the blocking
floor ("would fail a test, break production, or lose data or secrets") and ask
each finding for Severity and Blocks: yes|no. Additive rule: a finding is
CRITICAL when its label rule says so or it says Blocks: yes; Blocks: no never
lowers one (proseVoiceSeverity, BLOCKING_FLOOR in lib/review-scope.ts).
Part 3: ROLE_EFFORT puts specialists at medium; Red Team, native adversarial
and fix-check stay full; light's batched specialist (carries the Red Team
prompt) stays full; --no-tiers sends specialists to host.
Repinned reviewer briefs with no-loss replay G1 (live Arm G1, not yet run):
ship/sections/review-army.md, ship/sections/adversarial.md,
review/sections/adversarial.md, lib/review-depth.ts. Merge only on G1's pass.
Review-skill parity ratio 1.3136 -> 1.3180 and the gstack-review size pins
+537 for the approved +0.3k tokens per voice.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(review): variant G part 2: lean ensemble, one batched specialist at every depth (GSTA-167)
planReview dispatches one 'specialist batched' at standard and full depth (and
light, which adds the Red Team checklist): Testing and Security always on code
and gate class, plus State-machines, Data-migration, API-contract and Design
when scope asks; a forced checklist always joins. Maintainability, Performance
and Simplification are read only when forced (SKIP names them). LIGHT_FIXED is
[testing, security]; BATCH_SCOPED joins DEPTH_RULES so old receipts re-plan.
The Red Team rule and prompt are unchanged; it reads the batched reader's
merged findings. specialistsFor stays as the legacy selection the dispatch
compare script models.
Repinned reviewer briefs with no-loss replay L (live Arm L, scored L∘G1 vs G1;
not yet run): ship/sections/review-army.md, lib/review-depth.ts. Merge only on
L's pass.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(review): variant G on #3648's dispatch: Blocks: yes collects as CRITICAL, batched checklists by name (GSTA-167)
Integrates parts 1 and 2 with gstack-review-dispatch (#3648):
- lib/review-ledger.ts parseFindings: a prose voice's "Blocks: yes" makes its
own line, or the finding on the line just before it, CRITICAL in
merged.jsonl (normalizer v2, certified by round 5's G1), so judge refuses a
lead that keeps it below the floor; with no finding before it the Blocks
line is its own CRITICAL finding. "Blocks: no" never lowers a label.
- lib/review-brief.ts: the outside-voice brief no longer appends "Give each
finding a severity"; the section's prompt now asks for Severity and Blocks,
so the brief is the certified section prompt plus the branch diff.
- bin/gstack-review-dispatch render --checklists takes the plan's
checklists= names (review/specialists/<name>.md) as well as paths and
refuses an unknown one, since the batched reader is now every depth's
specialist dispatch.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore(changelog): GSTA-167 variant G reviewer stack fragment
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review): consumer scan survives grep.lineNumber/grep.column; collect reads separate-line Severity/Blocks
/ship pass 1 (PR #3660): the Red Team CRITICAL at lib/review-collect.ts:120 and the
informational findings in the same batch. proseVoiceSeverity had no caller and is
removed; the normalizer v2 table now runs through parseFindings, the path collect uses.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review): collect keeps every prose blocker and one id per finding
/ship pass 2 (PR #3660): an unlabeled line carrying an inline Blocks: yes collects as
CRITICAL again; Severity/Blocks continuation needs a colon, stops at a list item, heading,
bold paragraph opener or a repeated field, and never swallows a top-level bullet or its
section label; the native voice's FIXABLE collects as CRITICAL under its role with or
without a dispatch name; the consumer scan adds --no-color.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review): a later finding's fields never land on the one before it; explicit Severity wins its line
/ship pass 2 Red Team (PR #3660): prose after a finding's Severity/Blocks field, a
post-blank paragraph or a line in an indented block starts the next finding, and a
line's explicit Severity: label decides it over other label words on the line.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review): FIXABLE outranks a Severity label on its line; a blocker keeps its own id and subject
/ship fix-check (PR #3660): labels are named before the strongest is taken, so a one-line
native FIXABLE ... Severity: Medium collects as CRITICAL; a later finding starts at a
file:line after the open finding's fields, field bullets stay on their finding, a field
line may omit the colon, and continuation prose never replaces a list item's subject.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): GSTA-167 fragment adds round 6 and the collect and consumer-scan fixes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* pregate: map tests to dotfiles named in quoted literals
The quoted-literal pattern required [A-Za-z0-9_@] after the relative prefix, so "../.gitleaks.toml" never matched, and a dot-led literal resolved beside the test instead of from the repo root. A branch touching only the dotfile ended in PREGATE_NO_LANE (GST-246, garrytan/truther#956).
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* pregate: dotfile literals as their own pass; dot-led literals also resolve from the naming file's folder
Review fixes for #3661: the optional dot in QUOTED let a closing quote followed
by .method( consume the next literal's opening quote, dropping an edge main
found; and join(__dirname, '.github', ...) lost its fixture edge. Regression
test fails at acd2274.
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(sealed): local_path flags a home path after a shell default (${VAR:-/home/...})
Fixes#3568
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (array, indirect and special parameter defaults; docs limit; changelog example)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: bound the array subscript in LOCAL_PATH_RE so a hostile line stays linear
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): end the two colon sentences the prose lint flags
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship): GSTA-167 turn levers on the restored reviewers: ship preflight/release bins, own-jam meter, dispatch-pair metering, ship/DRIVER.md
Ports the non-reviewer parts of #3633 (gsta-167-pr34) and #3637 (gsta-167-pr5 @2914400)
onto main ae3d58c (v1.91.331.0). Reviewer briefs, checklists, the fix-check prompt and
the depth rules are byte-identical to main and now pinned in
test/review-packets-removed.test.ts.
Left out: gstack-review-packet and its libs, parallel/batched fanout, --like, collect,
the audit prompt split, the docs-audit packet, review-army/adversarial/outside-voice
edits, the gate-scan summary-only block and the review-depth scope-error change.
Packet-bytes reader pricing is dropped from gstack-ship-budget; handoff READ ranges
send each section whole; the driver runs the audit, review, adversarial and
documentation sections as written.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(context-budget): raise the capy/skill/gstack eager ceiling to its captured value after the main merge (own-jam meter, driver and reviewer-batch prose, GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(ship-driver): name ship/DRIVER.md.tmpl so the pregate maps the template to its test lane (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-driver): keep the skill generator off lib/ship-budget so a minimal setup checkout still renders (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(windows): keep test/ship-release.test.ts off the Windows subset; it launches the shebang bin and sh stubs directly (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship): variant E orchestration: one program per review pass and Step 14.5 audit, the review child starts at Step 9, a metered dispatch:docs role, and the driver's record headings (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship): variant G orchestration: one call per driver phase (9 for a clean pass, at most 12), gstack-ship-preflight --audit for single reads and deterministic audits, an observe-mode ledger with note and credits, 240 s wait pings, and small-model audit readers (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-budget): a Capy handoff child needs no jam id: verify-handoff with no reading makes it parent-metered (METER: parent), it never delegates on an unknown charge, and reconcile charges the parent's counter delta (GSTA-167 replay 7e)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship): a poll settles a reader only at done, failed or a final summary, never a fresh idle; return settles the child's open step reservation (GSTA-167 replay 7e)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-budget): return releases an open step reservation under the estimate meter instead of booking its projection; measured meters still settle it (GSTA-167 replay 7e)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review): a clean fix-check after below-floor fixes is done; Step 11 and fix-check below-floor findings are notes at pass 1
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship): verbatim reviewer briefs and loss-free collection (gstack-review-dispatch render/sent/collect/judge/verify)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes
- verify requires each output's brief rendered and sent verbatim, reruns judge
against the recorded judged.jsonl hash, and flags outputs collected after judge
- judge drops self-folds, fold cycles and chains
- prose findings parse a leading label or a label heading, not any severity word
- releasePaths: manifests count as release metadata only for version-only edits,
lockfiles never; TODOS.md stays out of lane-evidence exemptions
- push stops when the sealed-output guard did not run
- ship-audit reads the test tree once instead of one git grep per file
- drop the uncalled --delegate measured mode; doc/help step-number fixes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (pass 2)
- collect keeps a finding wherever its label stands (headings, table rows,
mid-line, Informational and upper-case labels); only top-level list items
inherit a label heading, and any heading or bold-only line ends it
- judge treats a merged file missing any collected id as a drop; verify flags
merged_ids_missing and a sent reader never collected (NOT_COLLECTED)
- finish computes release paths after --build, so a build that rewrites
package.json is a build-input change
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review-dispatch): verify per render, voided superseded mismatches
- verify treats each render as one dispatch of its reader, so a two-pass
ledger compares pass-1 sends with pass-1 briefs (later renders print as
<reader>@2); outputs bind to the latest send of their own render
- a mismatched send re-sent byte-exact before anything was collected is void
and counted (voided=N on the verdict line); one that produced an output
stays MISMATCH
- an indented bold sub-line no longer ends a label section (fix-check)
- docs: a failed reader is collected from its failure text
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(review-dispatch): only the newest render of a path checks its file; absolute ledger paths
- a later render into the same briefs directory overwrites the earlier brief by
design, so verify checks a brief file only for the newest render of that path
- collect and judge record absolute output, merged and judged paths, so verify
reads them from any directory
- docs: a failed reader's failure text is parsed like any output
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore: changelog and TODOS
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-release): the changelog_fragments fragment is release metadata
Fix-check 4 (CRITICAL) after the main merge: releasePaths omitted
<changelog_fragments.dir>/<branch-slug>.md, so finish stopped on the
fragment Step 13 writes under gstack's policy, or routed it to re-review.
version now names the fragment in its Step 13 NEXT line instead of
[Unreleased], DRIVER.md Step 13 writes and lints where NEXT says, and the
preflight POLICY line says Steps 12-16.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore: changelog and TODOS
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(captain): every ask to the owner uses the lettered ask format (R41)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(captain-brief): render the named heading through the brief helper (typecheck:test)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore(changelog): add the R41 ask-format fragment
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(captain-brief): tell the relaying agent how a named option answers (rec except <token>)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore(changelog): name the rec except form in the R41 fragment
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(captain): an ask that needs the owner to act carries the exact link and simple steps (R43)
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>
* captain: train land per slot under changelog_fragments (skill and skills.md)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* ship-policy: turn changelog_fragments on for gstack (required checks, key version 1.91.336.0); mergeChangelogs keeps a stacked child's only line inside its released parent's list
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* review fixes: a carried child entry never repeats a released parent line; min_gstack_version 1.91.340.0; required-check names as GitHub reports 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>
* feat(ship-policy): changelog_fragments key; restamp folds fragments; tree receipt accepts the fold
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): land, the per-PR merge step; Version Gate enforces fragments
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): land --repair after drift; hook base sha; docs and CHANGELOG
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: timeout on the land gh shim's git spawn
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship): /ship writes a CHANGELOG fragment under changelog_fragments; land checks the depth-checked receipt (#3567)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(land): keeps the base's four-part package.json (#3557)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-queue): land waits for CI through runScriptSync (script-invocation tripwire)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: land, fragment and Version Gate cases from /ship's coverage audit
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(windows): leave test/ship-queue-land.test.ts out of the Windows-safe subset (gh shim cannot launch there)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(ship-policy): rollback lands open fragment PRs first; restamp folds only with the key on
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(land): close pre-landing review findings
land without --no-wait now compares the pushed branch head and polls the
stamp commit's checks, refuses a PR whose base is not the stamped base,
releases the lock on a pre-push failure, keeps --break-lock off drift
locks, resumes from a lost journal via the stamp commit's pin, honours
history merge-only, and refuses a fragment whose text is already released
on the base. Version Gate stops applying open claims to a fragments stamp.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(land): close adversarial and outside-voice findings
land reconciles a merge GitHub completed behind an error reply, refuses
--break-lock against a holder that just entered a push or a merge, keeps
a repair takeover on the lock itself (any checkout can land the repair
PR), resumes --repair after a failed PR create, releases the lock on
QUEUE_LAND_BASE_BUSY, never writes through a symlinked release file,
keeps a package.json version source's other edits, and refuses an empty
object id instead of pushing a deletion. A carried-back fragment is
matched on whole released lines. Under changelog_fragments Version Gate
accepts a stamped head only as a [pin, base] merge-step commit with valid
fragments.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(land): refuse a pin without a READY receipt; symlinked release files refuse before restamp
Under changelog_fragments, gstack-ship-queue ready records a READY receipt
(refs/notes/gstack-trains) once its pregate, full_e2e and /ship receipt
checks pass, and land refuses a pin without one (fix: run
gstack-ship-queue ready --pr N), --dry-run included (GStack Minder ruling,
2026-10-29). The merged tree's release files may not be symlinks, so
restamp never writes outside the scratch worktree. --repair adopts an
existing branch only when it holds land's repair commit.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): clear's stamp-only substitution applies the changelog_fragments fold; docs match land and ready
gstack-pregate clear and gstack-tree-receipt now classify through one
classifyFiles, so under changelog_fragments a receipt for the fragment head
clears the stamped head when the stamp is exactly the fold. The ship-policy
reference names ready's receipt push, land's own check polling, the key-off
refusal and the /ship changelog_fragments line.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(pregate, ship-policy): the fragment fold's two receipt rules, and clear applies them too
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): stamped train prefixes S_i with the self-check (PR B)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): train build stamps S_i under fragments; train land publishes S_i exactly; backstop covers exact trees (PR B)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: stamped trains and train land; QUEUE_TRAIN_STAMP_MISMATCH anchor
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* captain templates: fragments instead of [Unreleased]; no slot call for stamped trains
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: timeouts on the train-land gh wrapper's sync spawns
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): train land checks the depth-checked receipt (#3567); regenerate the doctor anchors
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(train-stamp): S_i keeps the base's four-part package.json (#3557)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(windows): leave test/ship-queue-train-land.test.ts out of the Windows-safe subset (same gh shim as the train tests)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): close pre-landing review and outside-voice findings
- train land checks commit-tree and stamps with a fixed identity and date, journals before the push, and
adopts its own stamp head on a rerun; a failed commit-tree never pushes a branch deletion
- a symlinked release file in the merged tree refuses before the train stamp writes
- mergeStep merges a conflicted manifest three-way with the predecessor's version (mergeManifest, shared with land)
- train land refuses a PR retargeted off the base and a failed base refresh
- Version Gate skips a released fragment carried in by a stacked pin instead of counting its bump
- bisect of a stamped train tests T0 and S_1..S_k
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): a rerun whose head is still the pin re-enters the stamp step after a journaled, unpushed stamp
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): prove the record's S_i is on the gated chain before stamping; a merge main does not show yet pends
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): pin S_i to the gated head's exact prefix; an out-of-order slot refuses without freezing; stamps never sign
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): pin S_i to slot position; a failed push or unreadable PR never reads as a move; reruns of landed slots confirm; T0 in the out-of-order refusal
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(train-land): verify the whole stamped chain from git before landing; require changelog_fragments.required_checks green on the stamp commit
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(ship-policy, troubleshooting, harness): train land refusals, resume and required checks; stamped bisect; three-way manifest merges
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): count a slot as merged only when GitHub reports its PR MERGED (#3603)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* ship: write the Steps 12-16 range with an ASCII hyphen so the skeleton fits maxSkeletonBytes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-policy): changelog_fragments key; restamp folds fragments; tree receipt accepts the fold
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): land, the per-PR merge step; Version Gate enforces fragments
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): land --repair after drift; hook base sha; docs and CHANGELOG
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: timeout on the land gh shim's git spawn
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship): /ship writes a CHANGELOG fragment under changelog_fragments; land checks the depth-checked receipt (#3567)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(land): keeps the base's four-part package.json (#3557)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-queue): land waits for CI through runScriptSync (script-invocation tripwire)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: land, fragment and Version Gate cases from /ship's coverage audit
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(windows): leave test/ship-queue-land.test.ts out of the Windows-safe subset (gh shim cannot launch there)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(ship-policy): rollback lands open fragment PRs first; restamp folds only with the key on
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(land): close pre-landing review findings
land without --no-wait now compares the pushed branch head and polls the
stamp commit's checks, refuses a PR whose base is not the stamped base,
releases the lock on a pre-push failure, keeps --break-lock off drift
locks, resumes from a lost journal via the stamp commit's pin, honours
history merge-only, and refuses a fragment whose text is already released
on the base. Version Gate stops applying open claims to a fragments stamp.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(land): close adversarial and outside-voice findings
land reconciles a merge GitHub completed behind an error reply, refuses
--break-lock against a holder that just entered a push or a merge, keeps
a repair takeover on the lock itself (any checkout can land the repair
PR), resumes --repair after a failed PR create, releases the lock on
QUEUE_LAND_BASE_BUSY, never writes through a symlinked release file,
keeps a package.json version source's other edits, and refuses an empty
object id instead of pushing a deletion. A carried-back fragment is
matched on whole released lines. Under changelog_fragments Version Gate
accepts a stamped head only as a [pin, base] merge-step commit with valid
fragments.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(land): refuse a pin without a READY receipt; symlinked release files refuse before restamp
Under changelog_fragments, gstack-ship-queue ready records a READY receipt
(refs/notes/gstack-trains) once its pregate, full_e2e and /ship receipt
checks pass, and land refuses a pin without one (fix: run
gstack-ship-queue ready --pr N), --dry-run included (GStack Minder ruling,
2026-10-29). The merged tree's release files may not be symlinks, so
restamp never writes outside the scratch worktree. --repair adopts an
existing branch only when it holds land's repair commit.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): clear's stamp-only substitution applies the changelog_fragments fold; docs match land and ready
gstack-pregate clear and gstack-tree-receipt now classify through one
classifyFiles, so under changelog_fragments a receipt for the fragment head
clears the stamped head when the stamp is exactly the fold. The ship-policy
reference names ready's receipt push, land's own check polling, the key-off
refusal and the /ship changelog_fragments line.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(pregate, ship-policy): the fragment fold's two receipt rules, and clear applies them too
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): stamped train prefixes S_i with the self-check (PR B)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): train build stamps S_i under fragments; train land publishes S_i exactly; backstop covers exact trees (PR B)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: stamped trains and train land; QUEUE_TRAIN_STAMP_MISMATCH anchor
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* captain templates: fragments instead of [Unreleased]; no slot call for stamped trains
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: timeouts on the train-land gh wrapper's sync spawns
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): train land checks the depth-checked receipt (#3567); regenerate the doctor anchors
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(train-stamp): S_i keeps the base's four-part package.json (#3557)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(windows): leave test/ship-queue-train-land.test.ts out of the Windows-safe subset (same gh shim as the train tests)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): close pre-landing review and outside-voice findings
- train land checks commit-tree and stamps with a fixed identity and date, journals before the push, and
adopts its own stamp head on a rerun; a failed commit-tree never pushes a branch deletion
- a symlinked release file in the merged tree refuses before the train stamp writes
- mergeStep merges a conflicted manifest three-way with the predecessor's version (mergeManifest, shared with land)
- train land refuses a PR retargeted off the base and a failed base refresh
- Version Gate skips a released fragment carried in by a stacked pin instead of counting its bump
- bisect of a stamped train tests T0 and S_1..S_k
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): a rerun whose head is still the pin re-enters the stamp step after a journaled, unpushed stamp
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): prove the record's S_i is on the gated chain before stamping; a merge main does not show yet pends
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): pin S_i to the gated head's exact prefix; an out-of-order slot refuses without freezing; stamps never sign
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(train-land): pin S_i to slot position; a failed push or unreadable PR never reads as a move; reruns of landed slots confirm; T0 in the out-of-order refusal
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(train-land): verify the whole stamped chain from git before landing; require changelog_fragments.required_checks green on the stamp commit
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(ship-policy, troubleshooting, harness): train land refusals, resume and required checks; stamped bisect; three-way manifest merges
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* ship: write the Steps 12-16 range with an ASCII hyphen so the skeleton fits maxSkeletonBytes
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(sealed): waivers must name the full commit sha (GST-268)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(sealed): one ignored-waiver note per line and commit; split the waiver loops into cases
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(pregate): quote the ignored-waiver stderr line as printed
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(sealed): create SHA-256 scratch repos with --object-format, not the init config
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(sealed): ignored-waiver hint names the finding's commit to review, not a sha to write
Choose the shortened-vs-another-commit wording by prefix against the
finding's commit (fixes the SHA-256 40-hex mislabel and non-prefix short
waivers), and check applied waivers with a Set instead of rescanning.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-policy): changelog_fragments key; restamp folds fragments; tree receipt accepts the fold
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): land, the per-PR merge step; Version Gate enforces fragments
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship-queue): land --repair after drift; hook base sha; docs and CHANGELOG
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: timeout on the land gh shim's git spawn
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(ship): /ship writes a CHANGELOG fragment under changelog_fragments; land checks the depth-checked receipt (#3567)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(land): keeps the base's four-part package.json (#3557)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(ship-queue): land waits for CI through runScriptSync (script-invocation tripwire)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: land, fragment and Version Gate cases from /ship's coverage audit
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(windows): leave test/ship-queue-land.test.ts out of the Windows-safe subset (gh shim cannot launch there)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(ship-policy): rollback lands open fragment PRs first; restamp folds only with the key on
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(land): close pre-landing review findings
land without --no-wait now compares the pushed branch head and polls the
stamp commit's checks, refuses a PR whose base is not the stamped base,
releases the lock on a pre-push failure, keeps --break-lock off drift
locks, resumes from a lost journal via the stamp commit's pin, honours
history merge-only, and refuses a fragment whose text is already released
on the base. Version Gate stops applying open claims to a fragments stamp.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(land): close adversarial and outside-voice findings
land reconciles a merge GitHub completed behind an error reply, refuses
--break-lock against a holder that just entered a push or a merge, keeps
a repair takeover on the lock itself (any checkout can land the repair
PR), resumes --repair after a failed PR create, releases the lock on
QUEUE_LAND_BASE_BUSY, never writes through a symlinked release file,
keeps a package.json version source's other edits, and refuses an empty
object id instead of pushing a deletion. A carried-back fragment is
matched on whole released lines. Under changelog_fragments Version Gate
accepts a stamped head only as a [pin, base] merge-step commit with valid
fragments.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* feat(land): refuse a pin without a READY receipt; symlinked release files refuse before restamp
Under changelog_fragments, gstack-ship-queue ready records a READY receipt
(refs/notes/gstack-trains) once its pregate, full_e2e and /ship receipt
checks pass, and land refuses a pin without one (fix: run
gstack-ship-queue ready --pr N), --dry-run included (GStack Minder ruling,
2026-10-29). The merged tree's release files may not be symlinks, so
restamp never writes outside the scratch worktree. --repair adopts an
existing branch only when it holds land's repair commit.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(pregate): clear's stamp-only substitution applies the changelog_fragments fold; docs match land and ready
gstack-pregate clear and gstack-tree-receipt now classify through one
classifyFiles, so under changelog_fragments a receipt for the fragment head
clears the stamped head when the stamp is exactly the fold. The ship-policy
reference names ready's receipt push, land's own check polling, the key-off
refusal and the /ship changelog_fragments line.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(pregate, ship-policy): the fragment fold's two receipt rules, and clear applies them too
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* ship: write the Steps 12-16 range with an ASCII hyphen so the skeleton fits maxSkeletonBytes
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(harness): register OpenClaw skills over its 32 KB whole-read limit as entries pointing at SKILL.full.md (GST-110)
#3555's hybrid layout registered review, investigate, ship and plan-eng-review
as OpenClaw skills; OpenClaw serves a registered SKILL.md whole or refuses it,
at 32,768 bytes when the model's context window is unknown.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(harness): OpenClaw entry skills and the whole-read limit; CHANGELOG (GST-110)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (GST-110)
Entries point at a full SKILL.md in a plain copy of every skill (the router's
gstack/skills/ in hybrid, .gstack-skills/ under --skills all), so autoplan's
../gstack-plan-eng-review/SKILL.md and other sibling paths reach full texts;
test the #3555 upgrade path.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: remove .gstack-skills in the manual OpenClaw uninstall (GST-110)
Step 14.5 audit gst110-docs-1: the gstack* glob never matched the dot folder that --skills all registrations now write.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(harness): OpenClaw entry threshold 32,000 bytes so served skills also fit a 100K-200K-token tool-result budget (GST-110)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* v1.91.334.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>
* fix(scorecard): --now bounds every windowed line; recommended-harness week is 83 PRs (GST-135)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(scorecard): page-capped reads report unavailable, releases page to the window, one instant comparison for runs
Pre-landing review fixes for GST-135: readMergedPrs, readGateRuns and readReleases throw past MAX_PAGES
instead of returning a partial count; readReleases pages until it reaches the window start;
listWorkflowRuns compares both bounds with Date.parse and skips unparsable timestamps; tests for a
sub-second window, releases behind a full page and the PR page cap; doc wording on the red-train row
and the unverified 142-PR baseline removed.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(harness): document the scorecard's --now window end
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test(scorecard): a numeric timestamp in the inWindow control is a parsed date, not a bare epoch literal
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(scorecard): releases read every page; flaky row counts records across cases
GitHub lists releases by creation, so stopping on a page's oldest
publication could miss a draft published inside the window. Read every
page (the page cap still marks the line unavailable). Pin the gate-run
and release page caps with a test. The harness doc's flaky row now says
17 paid flake records across 11 cases instead of 17 cases.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* v1.91.333.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>
* feat(capy): agent_model preference via gstack-models resolve --role agent; capy/skill/gstack/factory.md
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(agent-model): pre-landing review fixes
- a broken preferences.yaml no longer blocks --request or config.yaml
- CRLF, a byte-order mark and a trailing comment still read the value
- never echo raw control or bidi bytes from an unvalidated source
- cap the bytes actually read, not only the stat size
- family names and host are case-insensitive in gstack-config too
- list passes the platform through to the agent block
- a wrapper inside the checkout names no preferences file
- docs: --check never writes the skill folder
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix(changelog): restore CHANGELOG.md history that 1bec403 truncated
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: agent_model and factory.md in capy-install, model-policy, troubleshooting and capy/README
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(capy): the Captain archives its own child threads by its plan for each (GST-211, R39)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* v1.91.332.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>
* revert(review): restore pre-#3621 reviewer briefs (GSTA-167 no-loss round 3)
Reverts the reviewer-packet parts of 5358a3b3 (#3621, v1.91.326.0) and
ce3a093a (#3636, v1.91.330.0). No-loss round 3
(handoffs/GSTA-167/noloss3-results.md) found the packet reviewers caught 10 of
the 19 blockers the dcd62c3 reviewers find.
Every non-stamp file is back to dcd62c389d73's bytes; the later main commits
959c8a6, 9184ffd and de53aef touch none of these files and are kept. Stamp
files (VERSION, package.json, agents-digest) stay at main; CHANGELOG gains an
[Unreleased] entry.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: keep the reverted reviewer-packet files gone and unreferenced (GSTA-167)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): name the reviewer-packet guard test
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>
* chore: stamp 1.91.331.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>
* pregate: always run the whole-tree tests listed in .gstack/always-run.json
A diff-selected run never maps a touched file to a scanner that reads the whole tree, so tripwires, ratchets and conformance tests passed the selected gate and failed CI after review (#3592, #3593). The lanes selection now adds every tracked test the list's globs name whenever the branch selects a test, owes a lane or edits the list.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(pregate): restore the truncated pregate.md tail; cite seeded durations for the always-run list
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs(changelog): [Unreleased] entry for the pregate always-run list
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>
* Narrow screens leave hub files to the train gate; map size-ledger baselines and the careful mask awk
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* fix: pre-landing review fixes (pull_request runs stay broad, deleted hubs, READY and summary previews)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: CHANGELOG for narrow screens (Unreleased)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: TESTING_INTERNALS describes narrow and broad PR screen policy
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* chore: record test-pr-profile.ts as non-behavioral at HARNESS_VERSION 6
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* ship-queue: screen only when the selector restores every case; unscreened PRs fill train seats (GSTA-165 1a)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* test: pin the diffs that still screen (unselectable, skill template + bun.lock)
Two assertions in test/ship-queue-train-logic.test.ts: a diff the paid
selector cannot select recommends --screen with the full gate selection,
and a diff that mixes a skill template with bun.lock recommends --screen.
GSTA-165 1a, from /ship Steps 7-8.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* docs: CHANGELOG tests and deferrals; P1 TODOs for GSTA-165 follow-ups
CHANGELOG [Unreleased]: name the two added tests and list the deferred
CREW.md rule 22 text and train-record attribution field. TODOS.md: both
deferrals as P1 under Ship.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
* 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>