mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-09 02:08:19 +01:00
Merge origin/main into gsta133-write-skill; stamp v1.91.287.0
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
commit
872ed2188b
31 files changed
+820
-60
No files matched your search
+44
-1
@@ -1,6 +1,6 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
## [1.91.287.0] - 2026-10-28
|
||||
|
||||
**Write, change and slim skills with `/write-skill`; the first diet halves /learn's template with the same results.** Garry asked, 2026-10-27: "Can we incorporate skill writing and improvement into gstack? https://github.com/nicobailon/skill-diet". gstack now has one skill for writing a new skill, changing an existing one, and putting one on a diet, plus a size bill, a static check that skills only call flags their bins accept, and a contract for the shared before/after skill eval the gstack-evals crew is building. /learn is the pilot: its template drops from 5,797 to 2,955 bytes and its rendered SKILL.md from 11,217 to 8,375. An A/B of 30 sessions per version on claude-opus-5-5 passed 30/30 before and 30/30 after (29/30 with no skill), with 10% fewer tokens per session. Adapted from nicobailon/skill-diet at 5f41df1 (MIT; NOTICE.md). Plan approved by Garry, 2026-10-27: "A1, B1, C1 D1 E1" and "Rec".
|
||||
|
||||
@@ -19,6 +19,49 @@
|
||||
- **`gstack-learnings-search --cross-project`** no longer drops every project when the state root path contains the current project's slug.
|
||||
- **The learnings bins refuse bad input.** An unknown flag, a flag without its value, or a `--limit` that is not a positive integer exits 2 with the valid flags named, before any state is read or written; before, unknown flags were silently skipped. No gstack caller passes one.
|
||||
|
||||
## [1.91.286.0] - 2026-10-28
|
||||
|
||||
**Two ship-touching PRs in one merge train no longer overshoot ship's size cap together, and verify stops freezing the queue on a train whose PRs all landed long ago.** Train 26's free run failed twice ("size ratio 1.753 > maxSizeRatio 1.7528", then "1.752 > 1.7524") because each PR re-pinned the same ratio on its own tree. Ship's cap is now a byte ledger. Each branch records its own signed delta, and the deltas add up exactly in any train order. Train 24's leftover record froze the queue on a main train 28 had already verified (#3519); verify now calls that record stale instead.
|
||||
|
||||
### Changed
|
||||
- **Ship's parity size cap** (`test/helpers/carve-guards.ts`, `test/helpers/parity-harness.ts`, `test/helpers/size-ledger.ts`): ship's `maxSizeRatio: 1.7529` is replaced by `sizeLedger: 'test/size-ledger/ship'`. The parity suite requires ship's union bytes to equal `base.json` (329,024 bytes, measured on main 10b77de merged with this PR) plus one `<branch>.json` entry (`{ bytes, why }`) per branch that changed them. A missing base, a malformed entry, an under-declared growth and an undeclared shrink all fail with the exact byte gap and the command that fixes it. Other skills keep their ratio caps. The ratio's history moved verbatim to `test/size-ledger/ship/HISTORY.md`.
|
||||
|
||||
### Added
|
||||
- **`scripts/size-ledger.ts`**: `record <skill> --why "<what changed>"` writes this branch's entry from the measured difference (and deletes it when the difference is zero), `check <skill>` prints measured, expected and every entry, and `fold <skill> --measured-at "<tree>"` moves the entries into `base.json` in a tidy-up PR. `record` refuses on main, master or a detached HEAD.
|
||||
- **`QUEUE_TRAIN_STALE`** (`gstack-ship-queue verify --train`): when every slot of the train already merged on GitHub and main's sha is a prefix another train's verify confirmed (read after the notes ref), verify refuses with `NEXT: gstack-ship-queue train prune --stale --train <nonce>`, freezes nothing and dispatches no backstop. A train with a slot still open, a main no train verified, or a `--no-fetch` run freezes as before.
|
||||
|
||||
### Fixed
|
||||
- **Freeze records keep unreadable slots** (`lib/ship-queue-train-record.ts`, `lib/ship-queue-train.ts`): a slot GitHub could not answer for beside a merged one is stored under an optional `unreadable` field, printed on an `unreadable:` line, and named after the repair as `gh pr view <n> --json state,headRefOid` so the operator checks it before seating it. Records written before the field read unchanged.
|
||||
|
||||
### Tests
|
||||
- `test/size-ledger.test.ts`: the train-26 shape fails under ratio pins and passes under the ledger in both merge orders through the real `buildChain`; missing, under-declared, shrinking, duplicate-edit and malformed ledgers fail. The fixture repo checks out with `core.autocrlf false`, so Windows counts the same bytes.
|
||||
- `test/ship-queue-train.test.ts`: an all-merged train on a main another train verified refuses as stale; the same train with a slot still open freezes; unreadable slots land in the field, the freeze lines and the post-repair NEXT.
|
||||
|
||||
### Docs
|
||||
- docs/ship-policy.md § Run a merge train: size caps compose through the ledger, and the stale-train and unreadable-slot rules. docs/troubleshooting.md: `QUEUE_TRAIN_STALE`.
|
||||
|
||||
### Gate integrity
|
||||
- Ship's union-size gate changes from a ceiling (`maxSizeRatio`) to an equality ledger at the same value (329,024 bytes, 1.7529 × 187,706, measured on main 10b77de merged with this PR); no skill prose changed, so ship's bytes did not move. No other threshold, timeout, trial count or case kind changed.
|
||||
|
||||
## [1.91.285.0] - 2026-10-27
|
||||
|
||||
**A lane plans before it builds, and the /captain skill says so.** Until now a crew thread told to build something started editing, and the first chance for the controller or the owner to say "smaller" or "not that way" was a finished PR with a paid gate behind it; the rule that a sized /autoplan comes first lived only in one crew's rules file, which a crew set up from gstack's templates would never read. The /captain skill, `docs/captain.md` and the crew templates now carry it: a building lane's first act is an /autoplan run sized to the work, the plan and its gate go up to the controller in plain language, the controller relays one ask with the recommended reply as the one-word default and a "do it" reply, and the lane builds only after the owner's word is answered into the run and it reports `APPROVED`.
|
||||
|
||||
### Added
|
||||
- **`docs/captain.md` § Plan before build**: who plans (any lane that builds; any new scope taken on part-way), the first act (`/autoplan` sized to the work, with the short-run flags for a one-file fix), what the lane sends (`gstack-owner-brief render --captain`, the cost lines, a needs-you report), what the controller relays (shape B, `rec` as the default, "do it"), the build gate (the answer in the run, amendments incorporated, reopened phases finished, `APPROVED`; an imported approval row alone is not completion), the record (`gstack-approvals import --autoplan`, rendered into the report and PR body), and the exemptions (read-only lanes, the daily flaky pass's repairs, slot stamps, CHANGELOG-only resolves, cap re-pins under a written grant; a crew may add, never remove). The rule is row 24 of the "Where each rule lives" table; the READY contract and merge trains are unchanged, and a plan approval is not a READY field.
|
||||
- **`captain/templates/brief.md`**: the controller's brief to a lane. A header with the lane, controller, rules file, owned files, the files other lanes own, a `Plan: required | approved: <run> | exempt: <reason>` line and the spend cap; step 1 the plan and the plan ask, step 2 the build after the word, step 3 /ship to READY; a done line that names the approval row or the exemption. A brief marked `approved` starts at step 2, one marked `exempt` at step 3.
|
||||
- **`captain/templates/CREW.md` rule 24** (Plan before build) with its home, and a row for the owner's words in the standing-approvals table. Crew-specific rules now number from 25; a crew whose own rules already took 24 keeps its numbering and cites the section by name.
|
||||
|
||||
### Changed
|
||||
- **`captain/SKILL.md.tmpl`**: the approvals part carries a "Plan before build" paragraph pointing at the section and the brief, and the rules enumeration names the rule.
|
||||
- **`capy/skill/gstack/SKILL.md` § Plan, approve, ship**: the short form every Capy thread follows, under a Captain or on its own (the owner, 2026-10-27: "Also incorporate the autoplan and eli5 and ship instructions for Capy-specific gstack usage"): /autoplan sized to the work before new functionality, the ELI5 with `rec` as the one-word default and a "do it" reply, the build only after the word and an `APPROVED` run, /ship at the final pushed head before a PR is called ready with the receipt naming that head, no merge without the owner's word, the review inside /ship and the autoplan sized to the change, and the exempt work. References are plain text, since the folder is copied to a Drive without the repository; the owner copies `capy/skill/gstack/` over the Drive skill folder to pick it up.
|
||||
- **`capy/skill/gstack/captain.md` § 3**: the lane-side pointer, so a thread launched on Capy sees the first-act rule where it reads the plan-ask shape, pointing at the SKILL.md section.
|
||||
- **`captain/templates/plan-ask.md`**: the record line names the autoplan path (`gstack-autoplan answer … --owner-reply`, then `gstack-approvals import --autoplan`) and keeps `gstack-approvals add` for plans that are not autoplan gates.
|
||||
- **`docs/captain.md` Setting it up, step 5**: lanes start with the brief.
|
||||
|
||||
### Tests
|
||||
- `test/captain-skill.test.ts` ships `brief.md` in the template set (existence, reference, generic prose), pins the CREW template at 24 rules and `docs/captain.md` at 24 mapped rows, and asserts the new section, the brief's `Plan:` line and step order, and the skill's paragraph.
|
||||
|
||||
## [1.91.284.0] - 2026-10-27
|
||||
|
||||
**Five small takes from tstack, in gstack's words.** Theo Browne's tstack (MIT, 2026-10-24) is nine short PR-landing skills; its best ideas that gstack lacked were a verb for an aging pull request, a Codex picker that says what each skill is for, a written grant for unattended sessions, a repo-level rule for porting a contributor's PR, and a visible author line on agent-posted comments. Each lands here as gstack prose and gstack code; no sentence is copied (NOTICE.md). Approved by Garry, 2026-10-26: "Do it, send" (yes to the opt-in attribution callout, off by default).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# gstack digest v1.91.284.0 — regenerate/re-copy after upgrading gstack
|
||||
# gstack digest v1.91.287.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,
|
||||
|
||||
@@ -282,6 +282,7 @@ gstack_result_anchor() {
|
||||
QUEUE_TRAIN_PREFIX_INVALID) printf '%s' 'queue-train-prefix-invalid' ;;
|
||||
QUEUE_TRAIN_REBUILD_REFUSED) printf '%s' 'queue-train-rebuild-refused' ;;
|
||||
QUEUE_TRAIN_TREE_MISMATCH) printf '%s' 'queue-train-tree-mismatch' ;;
|
||||
QUEUE_TRAIN_STALE) printf '%s' 'queue-train-stale' ;;
|
||||
QUEUE_TRAIN_FROZEN) printf '%s' 'queue-train-frozen' ;;
|
||||
QUEUE_RECEIPT_MISSING) printf '%s' 'queue-receipt-missing' ;;
|
||||
QUEUE_RECEIPT_STALE) printf '%s' 'queue-receipt-stale' ;;
|
||||
|
||||
+9
-1
@@ -161,7 +161,7 @@ carries its own copy of how to do things. The rules: session-start install check
|
||||
validation discipline, untrusted external diffs, file ownership, pre-approved spend, the
|
||||
READY contract, reports, one routing path (everything through the controller), no merging
|
||||
base into a READY branch, the CHANGELOG entry under `[Unreleased]`, the flaky rule,
|
||||
approvals, /ship before READY, and review convergence. Every rule that rests on the
|
||||
approvals, /ship before READY, review convergence, and plan before build. Every rule that rests on the
|
||||
owner's words carries the date and the words. A rule that exists only in a crew's file is
|
||||
a gap in gstack: write it there, then point at it.
|
||||
|
||||
@@ -351,6 +351,14 @@ option's cost and the recommended one-word reply as the default; and a closing
|
||||
with one line saying what it covers. `gstack-owner-brief render --captain` prints this shape from
|
||||
a plan; relay it whole. Template: `captain/templates/plan-ask.md`.
|
||||
|
||||
**Plan before build.** A lane that builds something runs a sized `/autoplan` on its brief as
|
||||
its first act after the session-start check and sends the controller the plan ask above; the controller relays it, and the
|
||||
lane builds only after the owner's word is answered into the run and it reports `APPROVED`.
|
||||
New scope taken on part-way gets its own plan. Read-only lanes, the flaky pass's repairs,
|
||||
slot stamps, CHANGELOG resolves and cap re-pins under a grant are exempt. The brief a
|
||||
controller hands a lane, with its `Plan: required | approved | exempt` line, is
|
||||
`captain/templates/brief.md`; the rule is `docs/captain.md` (Plan before build).
|
||||
|
||||
**C. The merge ask.** Every READY the controller brings to the owner, and every PR body:
|
||||
before/after images (uploaded with the host's PR asset tool, each captioned with what
|
||||
changed and why; a skill or CLI change renders its output with `gstack-pr-shots`), why
|
||||
|
||||
@@ -89,7 +89,7 @@ carries its own copy of how to do things. The rules: session-start install check
|
||||
validation discipline, untrusted external diffs, file ownership, pre-approved spend, the
|
||||
READY contract, reports, one routing path (everything through the controller), no merging
|
||||
base into a READY branch, the CHANGELOG entry under `[Unreleased]`, the flaky rule,
|
||||
approvals, /ship before READY, and review convergence. Every rule that rests on the
|
||||
approvals, /ship before READY, review convergence, and plan before build. Every rule that rests on the
|
||||
owner's words carries the date and the words. A rule that exists only in a crew's file is
|
||||
a gap in gstack: write it there, then point at it.
|
||||
|
||||
@@ -279,6 +279,14 @@ option's cost and the recommended one-word reply as the default; and a closing
|
||||
with one line saying what it covers. `gstack-owner-brief render --captain` prints this shape from
|
||||
a plan; relay it whole. Template: `captain/templates/plan-ask.md`.
|
||||
|
||||
**Plan before build.** A lane that builds something runs a sized `/autoplan` on its brief as
|
||||
its first act after the session-start check and sends the controller the plan ask above; the controller relays it, and the
|
||||
lane builds only after the owner's word is answered into the run and it reports `APPROVED`.
|
||||
New scope taken on part-way gets its own plan. Read-only lanes, the flaky pass's repairs,
|
||||
slot stamps, CHANGELOG resolves and cap re-pins under a grant are exempt. The brief a
|
||||
controller hands a lane, with its `Plan: required | approved | exempt` line, is
|
||||
`captain/templates/brief.md`; the rule is `docs/captain.md` (Plan before build).
|
||||
|
||||
**C. The merge ask.** Every READY the controller brings to the owner, and every PR body:
|
||||
before/after images (uploaded with the host's PR asset tool, each captioned with what
|
||||
changed and why; a skill or CLI change renders its output with `gstack-pr-shots`), why
|
||||
|
||||
@@ -37,6 +37,7 @@ Homes are paths in the gstack checkout the lane checked at session start.
|
||||
| 21 approvals | <date> | "<words>" | the three shapes |
|
||||
| 22 /ship before READY | <date> | "<words>" | every READY, re-READYs included |
|
||||
| 23 blocking floor | <date> | "<words>" | what blocks another review pass |
|
||||
| 24 plan before build | <date> | "<words>" | a sized /autoplan first, the owner's word before the build |
|
||||
|
||||
## Rules
|
||||
|
||||
@@ -125,8 +126,18 @@ Homes are paths in the gstack checkout the lane checked at session start.
|
||||
skills, scope knob `REVIEW_SCOPE`; record the pass count in your READY. Home: the
|
||||
`/ship` and `/review` skills.
|
||||
|
||||
24. **Plan before build.** If you build something, a `/autoplan` run on your brief, sized
|
||||
to the work, is your first act after the session-start check; send `CONTROLLER` the plan and its gate in plain
|
||||
language with the recommended reply named; build only after the owner's word is
|
||||
answered into the run and it reports `APPROVED`; record it with `gstack-approvals
|
||||
import --autoplan`. New scope taken on part-way gets the same. Exempt: read-only
|
||||
lanes, the daily flaky pass's repairs, slot stamps, CHANGELOG-only resolves, cap
|
||||
re-pins under a written grant. Home: `docs/captain.md` (Plan before build),
|
||||
`captain/templates/brief.md`.
|
||||
|
||||
## Crew-specific rules
|
||||
|
||||
Add rules here, numbered from 24, each with the date, the owner's words where there are
|
||||
any, and the thread that produced it. A rule that stays here for long is a gap in gstack:
|
||||
file it.
|
||||
Add rules here, numbered from 25, each with the date, the owner's words where there are
|
||||
any, and the thread that produced it. A crew whose own rules already took 24 before rule
|
||||
24 shipped keeps its numbering and cites `docs/captain.md` (Plan before build) by section
|
||||
name. A rule that stays here for long is a gap in gstack: file it.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Brief
|
||||
|
||||
Sent by the controller when a lane starts, and again when a lane takes on scope its brief
|
||||
did not name. The lane reads the rules file first, then this. Everything in angle brackets
|
||||
is filled by the controller; `Plan:` says whether the lane plans first
|
||||
(`docs/captain.md`, Plan before build).
|
||||
|
||||
```text
|
||||
Lane: <thread code> · Controller: <CONTROLLER> · Rules: <drive>/CREW.md · Base: <BASE>
|
||||
Owns: <the files and directories this lane may edit; everything else is routed through the controller>
|
||||
Do not touch: <files other live lanes own, each with its lane>
|
||||
Plan: required | approved: <autoplan run dir, or its checkpoint dir> | exempt: <reason from the exemption list>
|
||||
Spend cap: <focused paid runs per PR, from SPEND>
|
||||
|
||||
1. Plan (when Plan: required). After the session-start install check, install for autoplan
|
||||
and follow autoplan/DRIVER.md "On Capy" (launch file sourced, GSTACK_AUTOPLAN_CHECKPOINT_DIR
|
||||
set, run dir under ~/.capy/work). Write the plan with its ## Before → after,
|
||||
## Why it matters, ## What caused this work, ## Big decisions and ## Implementation plan
|
||||
sections, then run gstack-autoplan next --out <run dir> --plan <plan.md> <scope flags>
|
||||
sized to this brief (a one-file fix: --no-ui --no-dx --max-rounds 1 --estimate-usd <n>
|
||||
--spend-cap <small>). At the gate send me the output of
|
||||
gstack-owner-brief render --captain --out <run dir> whole, as a needs-you report.
|
||||
Build nothing yet.
|
||||
2. Build after the word. I bring the owner's exact words back. Answer them into the run
|
||||
(gstack-autoplan answer --out <run dir> --gate-rev <n> --reply <tokens> --rec-hash <h>
|
||||
--by agent:<your thread> --owner-reply "<their words>"), incorporate every accepted plan
|
||||
change (revise), finish every reopened phase, and start product edits only when the run
|
||||
reports APPROVED. Then gstack-approvals import --autoplan <run dir> --by "<owner>".
|
||||
New scope you take on part-way goes back to step 1 with its own plan.
|
||||
3. Ship. CHANGELOG entry under [Unreleased]; GUARD_CHECKS, pregate and /ship at the final
|
||||
head; one unstamped READY block (captain/templates/READY.md) to me; the PR body carries
|
||||
gstack-approvals render. Never merge; stamp only on my slot call.
|
||||
|
||||
Done when: the READY block is sent at a frozen head, reports/<thread code>.md is written,
|
||||
and its Approvals table carries the plan approval row (the owner's words, the date) or the
|
||||
Plan: exempt reason.
|
||||
```
|
||||
|
||||
A lane whose brief says `approved: <dir>` starts at step 2 with that run (restore it with
|
||||
`gstack-autoplan resume --out <new dir> --from <its checkpoint dir>` when it lives on another machine); a
|
||||
lane whose brief says `exempt:` starts at step 3. A brief with no `Plan:` line reads as
|
||||
`Plan: required`.
|
||||
@@ -28,5 +28,7 @@ output, a screen, a cost or time number>
|
||||
named: docs, trains, cleanups>, and carry them through to done with no further ask.
|
||||
```
|
||||
|
||||
When the answer comes back, record it before the work starts:
|
||||
`gstack-approvals add --ask "<what>" --words "<exact words>" --by "<owner> (via <controller>)" --scope "<what it covers>"`.
|
||||
When the answer comes back, record it before the work starts. For an autoplan gate:
|
||||
`gstack-autoplan answer --out <run dir> --gate-rev <n> --reply <tokens> --rec-hash <h> --by agent:<thread> --owner-reply "<exact words>"`,
|
||||
then `gstack-approvals import --autoplan <run dir> --by "<owner>"` (the tool records the relayer). For any
|
||||
other plan: `gstack-approvals add --ask "<what>" --words "<exact words>" --by "<owner> (via <controller>)" --scope "<what it covers>"`.
|
||||
@@ -42,6 +42,17 @@ Run directories and scratch on Capy live under `~/.capy/work/<name>` (`--out ~/.
|
||||
|
||||
Capy checklist for `/autoplan`: drive `gstack-autoplan`, never a hand adaptation presented as a run. Relay `gstack-gate render <dir>/gate.json --all` with `rec` (every recommendation, plan changes included) as the one-word default; answer with `--by agent:<id> --owner-reply "<their words>"`. Set `GSTACK_AUTOPLAN_CHECKPOINT_DIR` to a private project-user Drive folder; after machine replacement, `gstack-autoplan resume --out <new dir> --from <that dir>` restores the newest valid checkpoint.
|
||||
|
||||
## Plan, approve, ship
|
||||
|
||||
Every Capy thread that uses gstack follows these for new work, under a Captain or on its own. The rule in full is `docs/captain.md`, "Plan before build"; the lane side is section 3 of captain.md in this folder.
|
||||
|
||||
- **Plan first.** Before building new functionality, run `/autoplan` on it as the first act after the install check, sized to the work (scope flags and `--max-rounds`; a one-file fix gets `--no-ui --no-dx --max-rounds 1` with `--estimate-usd` and a small `--spend-cap`, never no run).
|
||||
- **ELI5, then the word.** Send the plan and gate to the person, or the Captain, in plain language: `gstack-owner-brief render --captain --out <run dir>`, with `rec` as the one-word default and a "do it" reply that takes every recommendation at full scope. Build only after their word is answered into the run and it reports `APPROVED`; then `gstack-approvals import --autoplan <run dir> --by "<owner>"`.
|
||||
- **/ship before ready.** Run /ship at the final pushed head before a PR is called ready; `SHIP_RECEIPT: pr=<n> head=<head>` must name that head, and a later push needs a new /ship. The review inside /ship, like the autoplan, is sized to the change.
|
||||
- **No merge without the owner's word.** A thread never merges on its own; under a Captain the controller merges on a recorded standing approval, and a thread with no Captain asks the person.
|
||||
|
||||
Exempt from the plan step: read-only work, the daily flaky pass's repairs, slot stamps, CHANGELOG-only resolves and cap re-pins under a written grant.
|
||||
|
||||
## Working under a Captain
|
||||
|
||||
When you work for a Capy Captain (a crew thread) or straight for a person, gstack's decisions reach them through you. Every workflow started with the `GSTACK_LAUNCH` line prints `CAPY: on` and a `capy-asks` block that repeats these rules. The full guide, with worked examples and copy-paste templates, is [captain.md](captain.md) in this folder.
|
||||
|
||||
@@ -70,6 +70,13 @@ gstack-approvals render # the ## Approvals se
|
||||
|
||||
## 3. Plan approvals: the shape
|
||||
|
||||
Under a Captain, a thread that builds something plans before any product code. A `/autoplan` run on its
|
||||
brief, sized to the work, is its first act, the gate goes up in the shape below, and the build starts only
|
||||
when the answer is in the run and it reports `APPROVED`. The short form every Capy thread follows, with the
|
||||
exempt work (read-only threads, flaky-pass repairs, slot stamps, CHANGELOG resolves, cap re-pins under a
|
||||
grant), is the "Plan, approve, ship" section of SKILL.md in this folder; the rule in full is `docs/captain.md`,
|
||||
Plan before build.
|
||||
|
||||
Every plan or gate you bring for approval has these parts, in this order, written so someone outside the
|
||||
project can follow it:
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ gstack/
|
||||
├── write-skill/ # /write-skill skill (edit ladder, levels, gstack-skill-bill, full diet in references/diet.md)
|
||||
├── test-audit/ # Report-first sweep for low-value tests (test value bar, audit mode)
|
||||
├── eval-plan/ # Preregistered paid evals: prereg, arms, $0 dry run, priced pilot (bin/gstack-eval-plan)
|
||||
├── captain/ # /captain (also /crew): one controller, many lanes; templates/ holds CREW.md, AGENTS.md, NOTES.md, DIGEST.md, the flaky ledger, the lane report, the READY block, slot call, asks and the daily automation prompt
|
||||
├── captain/ # /captain (also /crew): one controller, many lanes; templates/ holds CREW.md, AGENTS.md, NOTES.md, DIGEST.md, the flaky ledger, the lane report, the READY block, slot call, the lane brief, asks and the daily automation prompt
|
||||
├── plan-ceo-review/ # /plan-ceo-review skill
|
||||
├── plan-eng-review/ # /plan-eng-review skill
|
||||
├── autoplan/ # /autoplan skill (auto-review pipeline: CEO → design → DX → eng, eng always last)
|
||||
|
||||
+59
-2
@@ -97,6 +97,7 @@ Where each rule lives:
|
||||
| 21 | Approvals, plan asks and merge asks in the three shapes | [Approvals](#approvals-three-shapes); [capy/skill/gstack/captain.md](../capy/skill/gstack/captain.md) |
|
||||
| 22 | /ship before every READY; the block carries `SHIP_RECEIPT`; stamp commits hold only tool output | [ship-policy.md](ship-policy.md#ship-before-ready); [the lane's /ship sequence](#the-lanes-ship-sequence-before-ready) |
|
||||
| 23 | Review loops converge: scope frozen after pass 1, later passes on the delta, a pass cap, a blocking floor | the `/ship` and `/review` skills' own convergence policy ([skills.md](skills.md#ship)); a crew names it in one line and sets only the scope knob (`REVIEW_SCOPE`) |
|
||||
| 24 | Plan before build: a sized `/autoplan` is a building lane's first act; the plan ask goes up, the build starts after the owner's word is in the run and it reports `APPROVED` | [Plan before build](#plan-before-build); the [brief template](../captain/templates/brief.md) |
|
||||
|
||||
## Lane discipline
|
||||
|
||||
@@ -121,6 +122,61 @@ such decision with a plain-language explanation of every option: what it is, why
|
||||
matters, what each answer does, and what it costs. A gate code or a tool's result line
|
||||
alone is not an ask.
|
||||
|
||||
## Plan before build
|
||||
|
||||
A lane that builds something plans first. Its first act after the session-start install
|
||||
check, before any product code, is a `/autoplan` run on its brief, sized to the work. The
|
||||
phases run in order, CEO, then design, then DX, then eng, with design and DX only when the
|
||||
scope has them, and a one-file fix gets a short run (`--no-ui --no-dx --max-rounds 1`, with
|
||||
`--estimate-usd` set so a small `--spend-cap` still seats its attempts), not no run. On Capy the
|
||||
unattended loop is `autoplan/DRIVER.md` in the gstack checkout. New functionality a lane
|
||||
takes on part-way, scope its brief did not name, gets its own plan and its own ask before
|
||||
the lane builds it. In the rules file this is rule 24 of the
|
||||
[template](../captain/templates/CREW.md); a crew whose own rules already took 24 before
|
||||
this rule shipped cites this section by name.
|
||||
|
||||
**What the lane sends.** The plan and its gate in plain language a person outside the
|
||||
project can follow: what changes, why now, what the change does, what it costs, the lane's
|
||||
pick, and the recommended one-word reply. `gstack-owner-brief render --captain --out <run dir>`
|
||||
prints that from the plan's `## Before → after`, `## Why it matters`,
|
||||
`## What caused this work` and `## Big decisions` sections, with the cost lines
|
||||
(`GATE_SPEND:`, `GATE_REC_COST:`) and a last line for the controller; a plan missing a
|
||||
section exits `CAPTAIN_BRIEF_INCOMPLETE`, so the lane adds the section and renders again
|
||||
([capy/skill/gstack/captain.md](../capy/skill/gstack/captain.md) § 3 lists them). The lane
|
||||
sends it whole, as a needs-you report, and builds nothing yet.
|
||||
|
||||
**What the controller relays.** One ask to the owner in shape B below: the recommended
|
||||
reply (every recommendation, plan changes included) as the one-word default and a "do it"
|
||||
reply that takes every recommendation at full scope, follow-ons included. The plan as
|
||||
first written is never the default.
|
||||
|
||||
**The build gate.** The lane builds only after the owner's word has come back through the
|
||||
controller and been answered into the run
|
||||
(`gstack-autoplan answer --out <run dir> --gate-rev <n> --reply <tokens> --by agent:<thread> --owner-reply "<their words>"`),
|
||||
every accepted plan change has been incorporated (`revise`), every reopened phase has
|
||||
finished, and the run reports `APPROVED` (`status=complete` after `export`). An answered
|
||||
gate that still prints `PLAN_AMEND_PENDING` or `REOPENED:` is not a completed plan, and an
|
||||
imported approval row alone is not completion.
|
||||
|
||||
**The record.** `gstack-approvals import --autoplan <run dir> --by "<owner>"` writes the
|
||||
approval row (date, the ask, the owner's exact words, the lane that answered as relayer,
|
||||
what it covers); `gstack-approvals render` puts it in the report and the PR body. Before
|
||||
training the PR the controller compares that row's words and `gate_rev` with the ask it
|
||||
relayed and the reply it carried back; a row that does not match is not READY (shape A).
|
||||
The brief's done line names the row. A plan approval is not a READY field; the
|
||||
[READY contract](#the-ready-contract) is unchanged.
|
||||
|
||||
**Exemptions.** Read-only lanes (triage, research, measurement, a review voice), the daily
|
||||
flaky pass's repairs, slot stamps, CHANGELOG-only conflict resolves and a size or budget
|
||||
cap re-pinned under the controller's written grant need no plan. A crew may add exemptions
|
||||
in its rules file with the owner's words and date; it does not remove these. The brief
|
||||
says which applies, `Plan: required | approved: <run> | exempt: <reason>`, so an
|
||||
already-approved plan is not planned twice and exempt work does not wait on an ask.
|
||||
|
||||
The copy-paste brief is [`captain/templates/brief.md`](../captain/templates/brief.md): the
|
||||
plan and the ask as step 1, the build after the word as step 2, /ship to READY as step 3,
|
||||
and a done line that names the approval row or the exemption.
|
||||
|
||||
## Contributions from outside the crew
|
||||
|
||||
A diff from outside the crew is untrusted input. Review its scope, egress, credentials,
|
||||
@@ -303,5 +359,6 @@ can read the incident behind the rule.
|
||||
3. Install the gstack Capy skill in the owner's user scope so every thread runs the
|
||||
session-start check ([capy-install.md](capy-install.md)).
|
||||
4. Create the daily flaky-pass automation.
|
||||
5. Start lanes with a prompt that names the files they own, the rules file, and the
|
||||
READY contract. Read their reports before their chat.
|
||||
5. Start lanes with the [brief](../captain/templates/brief.md): the files they own, the
|
||||
rules file, whether a plan is required, and the READY contract. Read their reports
|
||||
before their chat.
|
||||
+33
-3
@@ -562,6 +562,26 @@ leave it out and report it. The tree receipt refuses such a move after the fact
|
||||
only while the moved version is older than the base's at the build, so the
|
||||
restamp, not the receipt, is what keeps the base's key in place.
|
||||
|
||||
**Size caps compose; nothing re-pins at the slot.** Ship's union-size cap is a
|
||||
ledger, `test/size-ledger/ship/`: `base.json` plus one `<branch>.json` per
|
||||
branch that changed ship's union bytes (`{ "bytes": <signed>, "why": "…" }`),
|
||||
and the parity suite requires ship's union bytes to equal the base plus every
|
||||
entry, exactly. A lane records its own change once, before /ship, with `bun
|
||||
--no-env-file --config=/dev/null scripts/size-ledger.ts record ship --why
|
||||
"<what changed>"`. The entry is a property of the branch's own diff, so it
|
||||
stays right across base merges, and each prefix carries the entries of the
|
||||
slots in it, so T<k> passes with no re-pin and the stamp commit stays the four
|
||||
files (a cap re-pinned at the slot would be a fifth file on a tree the gate
|
||||
never ran). A clean merge adds byte deltas exactly; overlapping hunks are a
|
||||
train conflict anyway, and two branches making an identical edit (git keeps
|
||||
one copy, both entries count) fail closed with the same record command as the
|
||||
fix. A branch that grows ship beyond its entry, or shrinks it without a
|
||||
negative one, fails on its own tree and on every prefix that includes it.
|
||||
`scripts/size-ledger.ts check ship` prints the ledger; `fold ship
|
||||
--measured-at <tree>` moves the entries into `base.json` in a tidy-up PR,
|
||||
never in a stamp commit. Other skills keep their `maxSizeRatio` caps in
|
||||
`test/helpers/carve-guards.ts`.
|
||||
|
||||
**A stacked child whose parent merged earlier.** When the pin was stacked on a
|
||||
PR that squash-merged in an earlier slot or train, the base merge conflicts
|
||||
beyond the CHANGELOG wherever the parent's squash and the pin touched the same
|
||||
@@ -624,9 +644,19 @@ freezes the same way, since main already holds the unverified squash. The
|
||||
record comes from the one GitHub read that decided to freeze, never a second
|
||||
one: a slot that read MERGED stays merged even when GitHub stops answering
|
||||
before the record is written, and a slot unreadable beside a merged one is
|
||||
left out of `unmerged` and named in the reason; nothing reads it again, so
|
||||
the `NEXT:` after the repair omits it and the operator seats it in a train by
|
||||
hand once `gh pr view` answers. When
|
||||
left out of `unmerged`, recorded under `unreadable` and printed on an
|
||||
`unreadable:` line; the `NEXT:` after the repair names it (`gh pr view <n>
|
||||
--json state,headRefOid (unreadable at the freeze: #<n>@<sha>); seat each
|
||||
that is OPEN in a train`).
|
||||
When every slot of the train already merged on GitHub and main's SHA is a
|
||||
prefix another train's verify confirmed (read after the notes ref, so a
|
||||
machine that never ran that train still sees it), the mismatch says nothing
|
||||
about this train: verify refuses with `QUEUE_TRAIN_STALE` and `NEXT:
|
||||
gstack-ship-queue train prune --stale --train <nonce>`, freezing nothing and
|
||||
dispatching no backstop (train 24's record froze the queue that way on a main
|
||||
train 28 had verified, #3519). Only a verify that fetched main takes this
|
||||
exit: under `--no-fetch` the local main may be older than GitHub's, so the
|
||||
mismatch freezes as before. When
|
||||
whether a slot merged on GitHub cannot be read, verify refuses
|
||||
(`QUEUE_PROOF_MISSING`, "whether #<n> merged on GitHub could not be read")
|
||||
and asks to be rerun once `gh pr view` answers; an unreadable state is never
|
||||
|
||||
+1
-1
@@ -1473,7 +1473,7 @@ this model disagree (squash or merge, who stamps, gate-ahead, the severe race, a
|
||||
id in the READY), the skill ships both as options for the crew rules file.
|
||||
|
||||
Templates (CREW.md, AGENTS.md, NOTES.md, DIGEST.md, the flaky ledger, the lane report,
|
||||
the READY block, the slot call, the plan and merge asks, the daily automation prompt)
|
||||
the READY block, the slot call, the lane brief, the plan and merge asks, the daily automation prompt)
|
||||
live in `captain/templates/`; the team setup guide for Capy is [docs/captain.md](captain.md).
|
||||
|
||||
## `/gstack-upgrade`
|
||||
|
||||
+20
-2
@@ -4346,6 +4346,23 @@ current main. When whether a slot merged on GitHub cannot be read, verify
|
||||
refuses with `QUEUE_PROOF_MISSING` instead of either answer; rerun it once
|
||||
`gh pr view` answers.
|
||||
|
||||
<a id="queue-train-stale"></a>
|
||||
### `QUEUE_TRAIN_STALE`
|
||||
|
||||
**Meaning.** Verify found main's tree outside this train's prefixes, but every
|
||||
slot of the train already merged on GitHub and main's SHA is a prefix another
|
||||
train's verify confirmed, so the record is stale: its PRs landed and later
|
||||
trains moved main on. Comparing today's main with its prefixes proves nothing,
|
||||
so the queue is not frozen and no backstop is dispatched (train 24's record
|
||||
did both on a main train 28 had verified, #3519). Other trains are read after
|
||||
the notes ref, so a machine that never ran the later train still sees it.
|
||||
|
||||
**Fix.** `gstack-ship-queue train prune --stale --train <nonce>` settles the
|
||||
record. When some slot is not merged, no train verified main's SHA, or verify
|
||||
ran with `--no-fetch`, verify freezes as before (`QUEUE_TRAIN_FROZEN`). A queue
|
||||
another machine already froze stays frozen; the refusal prints its freeze
|
||||
lines.
|
||||
|
||||
<a id="queue-train-frozen"></a>
|
||||
### `QUEUE_TRAIN_FROZEN`
|
||||
|
||||
@@ -4360,8 +4377,9 @@ stops answering a moment later, and a slot whose state could not be read when
|
||||
another slot had merged is left out of `unmerged` and named in the reason
|
||||
(`#<n> unreadable on GitHub, left out of unmerged; seat it in a train by hand
|
||||
once gh pr view answers`), so the rebuild after the repair never seats a PR
|
||||
that may already be in; nothing reads that slot again, so the `NEXT:` after
|
||||
the repair omits it and the operator seats it by hand. The
|
||||
that may already be in; the record keeps it under `unreadable`, an
|
||||
`unreadable:` line prints it, and the `NEXT:` after the repair names it for a
|
||||
`gh pr view` check. The
|
||||
freeze lives in local state and on `refs/notes/gstack-trains`. Ordinary
|
||||
trains and other trains' merges are refused until a repair lands.
|
||||
|
||||
|
||||
@@ -127,6 +127,11 @@ export const RELEASE_RESULT_CODES = {
|
||||
summary: 'main’s tree is neither the train’s prefix before this PR nor after it (modulo stamps), so the merge does not publish what the gate tested',
|
||||
fix: 'stop merging; if earlier PRs of the train merged, the queue is frozen (QUEUE_TRAIN_FROZEN); otherwise rebuild the train on current main',
|
||||
},
|
||||
QUEUE_TRAIN_STALE: {
|
||||
anchor: 'queue-train-stale',
|
||||
summary: 'every slot of this train already merged on GitHub and main is a prefix another train verified, so the record is stale; comparing today’s main to its prefixes proves nothing and does not freeze the queue',
|
||||
fix: 'settle the record with train prune --stale --train <nonce>; no backstop is needed',
|
||||
},
|
||||
QUEUE_TRAIN_FROZEN: {
|
||||
anchor: 'queue-train-frozen',
|
||||
summary: 'a train stopped partway through publication, so main holds a prefix no gate covered on its own; ordinary trains are refused until a repair lands',
|
||||
|
||||
@@ -64,6 +64,8 @@ export interface BisectRecord {
|
||||
}
|
||||
export interface FreezeRecord {
|
||||
schema: 1; kind: 'freeze'; repo_key: string; train: string; merged: string[]; unmerged: Array<{ pr: string; head: string }>;
|
||||
/** Slots GitHub could not answer for beside a merged one: neither merged nor unmerged (#3519); absent on records written before the field. */
|
||||
unreadable?: Array<{ pr: string; head: string }>;
|
||||
main: { sha: string; tree: string }; reason: string; backstop: { nonce: string; run: number | null; state: string } | null;
|
||||
repair: { pr: string; head: string; train: string | null } | null; created_at: string; cleared_at: string | null; cleared_by: string | null; updated_at: string;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import type { QueueContext } from './ship-queue';
|
||||
import { git } from './ship-queue-gate';
|
||||
import { bindReceipt } from './ship-receipt';
|
||||
import { checkRun, execFor, prInfo, repoSlug } from './ship-queue-train-github';
|
||||
import { activeFreeze, attemptsOf, nowIso, persist, trainFile, type FreezeRecord, type TrainRecord } from './ship-queue-train-record';
|
||||
import { activeFreeze, attemptsOf, listTrains, nowIso, persist, rebuildFromNotes, trainFile, type FreezeRecord, type TrainRecord } from './ship-queue-train-record';
|
||||
import {
|
||||
effect, fetchBase, fetchTrainBranch, findTrain, frozenLines, nextFor, outFailed, outOk, outRefused, pinList, prState, prsArgs, save, trainEnv, type TrainEnv, type TrainOut,
|
||||
} from './ship-queue-train';
|
||||
@@ -114,9 +114,10 @@ function published(env: TrainEnv, t: TrainRecord, i: number, main: string): { sa
|
||||
* anything remote, then the backstop gate is dispatched on main's sha.
|
||||
* `states` is the one GitHub read of every unverified slot, made by the
|
||||
* caller: a slot that read MERGED is merged, verified tree or not, and a slot
|
||||
* that could not be read is left out of `unmerged` and named in the reason
|
||||
* (nothing reads it again; the operator seats it by hand once gh answers), so
|
||||
* the rebuild after the repair never seats a PR that may already be in.
|
||||
* that could not be read is left out of `unmerged`, recorded under
|
||||
* `unreadable` and named in the reason and in the NEXT after the repair (the
|
||||
* operator seats it by hand once gh answers), so the rebuild after the repair
|
||||
* never seats a PR that may already be in.
|
||||
*/
|
||||
async function freezeQueue(env: TrainEnv, t: TrainRecord, reason: string, mainSha: string, states: ReadonlyMap<string, string>): Promise<FreezeRecord> {
|
||||
const now = nowIso();
|
||||
@@ -127,6 +128,7 @@ async function freezeQueue(env: TrainEnv, t: TrainRecord, reason: string, mainSh
|
||||
const f: FreezeRecord = {
|
||||
schema: 1, kind: 'freeze', repo_key: env.repo.key, train: t.nonce, merged: [...t.merged.map(m => m.pr), ...landed],
|
||||
unmerged: unverified.filter(s => !landed.includes(s.pr) && !unreadable.includes(s.pr)).map(s => ({ pr: s.pr, head: s.head })),
|
||||
unreadable: unverified.filter(s => unreadable.includes(s.pr)).map(s => ({ pr: s.pr, head: s.head })),
|
||||
main: { sha: mainSha, tree: git(env.ctx.repoRoot, ['rev-parse', `${mainSha}^{tree}`]).out },
|
||||
reason: [reason, landed.length ? `${prs(landed)} merged on GitHub without a verified tree` : '', unreadable.length ? `${prs(unreadable)} unreadable on GitHub, left out of unmerged; seat it in a train by hand once gh pr view answers` : ''].filter(Boolean).join('; '),
|
||||
backstop: null, repair: null,
|
||||
@@ -146,6 +148,21 @@ async function freezeQueue(env: TrainEnv, t: TrainRecord, reason: string, mainSh
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Where another train's verify confirmed main's exact sha as one of its merged
|
||||
* prefixes, read from local records after the notes ref (a machine that never
|
||||
* ran that train still sees it). Null when none did.
|
||||
*/
|
||||
function verifiedElsewhere(env: TrainEnv, t: TrainRecord, mainSha: string): string | null {
|
||||
rebuildFromNotes(env.ctx.repoRoot, env.remote);
|
||||
for (const other of listTrains(env.repo.keys)) {
|
||||
if (other.nonce === t.nonce) continue;
|
||||
const m = other.merged.find(x => x.sha === mainSha);
|
||||
if (m) return `T${other.prefixes.find(p => p.pr === m.pr)?.index ?? '?'} of train ${other.nonce} (#${m.pr}, verified at ${m.at})`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupted publication: freeze when a slot merged, verified or merged on
|
||||
* GitHub without a verified tree (slot 1's own squash failing the post-merge
|
||||
@@ -153,7 +170,7 @@ async function freezeQueue(env: TrainEnv, t: TrainRecord, reason: string, mainSh
|
||||
* plain refusal (nothing was published). A GitHub state that cannot be read
|
||||
* is neither: the verify refuses and asks to be rerun, never "nothing merged".
|
||||
*/
|
||||
async function stopped(env: TrainEnv, t: TrainRecord, code: 'QUEUE_TRAIN_TREE_MISMATCH' | 'QUEUE_TRAIN_MOVED', message: string, mainSha: string, lines: string[]): Promise<TrainOut> {
|
||||
async function stopped(env: TrainEnv, t: TrainRecord, code: 'QUEUE_TRAIN_TREE_MISMATCH' | 'QUEUE_TRAIN_MOVED', message: string, mainSha: string, lines: string[], fetched: boolean): Promise<TrainOut> {
|
||||
const run = trainFile(t.nonce);
|
||||
// One GitHub read per unverified slot decides both the freeze and its record.
|
||||
const states = new Map(t.slots.filter(s => !t.merged.some(m => m.pr === s.pr)).map(s => [s.pr, prState(env.ctx, s.pr)] as const));
|
||||
@@ -161,6 +178,11 @@ async function stopped(env: TrainEnv, t: TrainRecord, code: 'QUEUE_TRAIN_TREE_MI
|
||||
const unreadable = landed ? [] : [...states].filter(([, state]) => state === 'unreadable').map(([pr]) => `#${pr}`);
|
||||
if (unreadable.length) return outRefused({ code: 'QUEUE_PROOF_MISSING', message: `${message}; whether ${unreadable.join(', ')} merged on GitHub could not be read, so whether the queue must freeze is unknown` }, lines, `${Q} verify --pr ${t.slots[0]!.pr} --train ${t.nonce} (once gh pr view answers)`, run);
|
||||
if (!landed) return outFailed({ code, message: `${message}; nothing of train ${t.nonce} merged, so the queue is not frozen` }, lines, `${Q} train build ${prsArgs(t.slots, t.explicit_order)} (a new train on current main)`, run);
|
||||
const later = fetched && t.slots.every(s => t.merged.some(m => m.pr === s.pr) || states.get(s.pr) === 'MERGED') ? verifiedElsewhere(env, t, mainSha) : null;
|
||||
if (later) {
|
||||
const held = activeFreeze(env.repo.keys);
|
||||
return outRefused({ code: 'QUEUE_TRAIN_STALE', message: `${message}; every slot of train ${t.nonce} merged on GitHub and main ${mainSha.slice(0, 12)} is ${later}, so this record is stale and ${held ? `freezes nothing (the queue is already frozen by train ${held.train})` : 'the queue is not frozen'}` }, held ? [...lines, ...frozenLines(held)] : lines, `${Q} train prune --stale --train ${t.nonce}`, run);
|
||||
}
|
||||
const f = activeFreeze(env.repo.keys) ?? await freezeQueue(env, t, message, mainSha, states);
|
||||
return outFailed({ code, message: `${message}; the queue is frozen` }, [...lines, ...frozenLines(f)], `${Q} train build --repair --prs <repair-pr>@<sha>`, run);
|
||||
}
|
||||
@@ -192,13 +214,13 @@ export async function verifyTrain(ctx: QueueContext, o: { pr: string; train: str
|
||||
if (post.same) return confirmMerged(env, t, o.pr, main, after.index, [...lines, `main: ${main} = T${after.index} (${post.detail})`]);
|
||||
const pre = sameModuloStamps(env, before.commit, main);
|
||||
if (!pre.same) {
|
||||
return stopped(env, t, 'QUEUE_TRAIN_TREE_MISMATCH', `main ${main.slice(0, 12)} is neither T${before.index} nor T${after.index} modulo stamps (vs T${after.index}: ${post.detail})`, main, lines);
|
||||
return stopped(env, t, 'QUEUE_TRAIN_TREE_MISMATCH', `main ${main.slice(0, 12)} is neither T${before.index} nor T${after.index} modulo stamps (vs T${after.index}: ${post.detail})`, main, lines, !o.noFetch);
|
||||
}
|
||||
const headRef = o.noFetch ? '' : (git(ctx.repoRoot, ['fetch', '--no-tags', '-q', env.remote, `+refs/pull/${o.pr}/head:refs/gstack/queue/pr-${o.pr}`]).ok ? `refs/gstack/queue/pr-${o.pr}` : '');
|
||||
const head = headRef ? git(ctx.repoRoot, ['rev-parse', headRef]).out : t.slots[i]!.head;
|
||||
const pinned = head === t.slots[i]!.head ? { same: true, detail: 'the pinned head' } : sameModuloStamps(env, t.slots[i]!.head, head);
|
||||
const stampOnly = pinned.same ? pinned : mergedIn(env, t, i, head, main);
|
||||
if (!stampOnly.same) return stopped(env, t, 'QUEUE_TRAIN_MOVED', `#${o.pr} moved past its pinned head ${t.slots[i]!.head.slice(0, 12)} and is not T${after.index} modulo stamps (${head.slice(0, 12)}: ${stampOnly.detail}; against the pin it ${pinned.detail})`, main, lines);
|
||||
if (!stampOnly.same) return stopped(env, t, 'QUEUE_TRAIN_MOVED', `#${o.pr} moved past its pinned head ${t.slots[i]!.head.slice(0, 12)} and is not T${after.index} modulo stamps (${head.slice(0, 12)}: ${stampOnly.detail}; against the pin it ${pinned.detail})`, main, lines, !o.noFetch);
|
||||
const info = prInfo(ctx, o.pr);
|
||||
if ('error' in info) return outRefused({ code: 'QUEUE_PROOF_MISSING', message: info.error }, lines, `${Q} verify --pr ${o.pr} --train ${t.nonce}`, run);
|
||||
const shipped = bindReceipt(info.body, o.pr, [t.slots[i]!.head, head]);
|
||||
@@ -222,7 +244,10 @@ function confirmMerged(env: TrainEnv, t: TrainRecord, pr: string, main: string,
|
||||
freeze.updated_at = freeze.cleared_at;
|
||||
persist(env.ctx.repoRoot, [freeze], { remote: env.remote });
|
||||
lines.push(`FREEZE: cleared (${freeze.cleared_by})`);
|
||||
return outOk(lines, freeze.unmerged.length ? `${Q} train build --prs ${pinList(freeze.unmerged)}` : 'none', run);
|
||||
const rebuild = freeze.unmerged.length ? `${Q} train build --prs ${pinList(freeze.unmerged)}` : '';
|
||||
const unread = freeze.unreadable ?? [];
|
||||
const check = unread.length ? `${unread.map(u => `gh pr view ${u.pr} --json state,headRefOid`).join(' && ')} (unreadable at the freeze: ${unread.map(u => `#${u.pr}@${u.head.slice(0, 12)}`).join(', ')}); seat each that is OPEN in a train` : '';
|
||||
return outOk(lines, [rebuild, check].filter(Boolean).join('; then ') || 'none', run);
|
||||
}
|
||||
return outOk(lines, nextFor(t), run);
|
||||
}
|
||||
@@ -427,6 +427,7 @@ export function frozenLines(f: NonNullable<ReturnType<typeof activeFreeze>>): st
|
||||
return [
|
||||
`QUEUE_TRAIN_FROZEN: train ${f.train} merged ${f.merged.map(p => '#' + p).join(',') || '(none)'}; main ${f.main.sha.slice(0, 12)} tree ${f.main.tree.slice(0, 12)}; backstop ${f.backstop ? `${f.backstop.state} run ${f.backstop.run ?? 'unknown'} (nonce ${f.backstop.nonce})` : 'not dispatched'}`,
|
||||
`freeze: ${f.reason}; unmerged ${f.unmerged.map(u => '#' + u.pr).join(',') || '(none)'}; repair ${f.repair ? `#${f.repair.pr}@${f.repair.head.slice(0, 12)}` : 'none admitted'}`,
|
||||
...(f.unreadable?.length ? [`unreadable: ${f.unreadable.map(u => `#${u.pr}@${u.head.slice(0, 12)}`).join(', ')} (GitHub did not answer at the freeze; neither merged nor unmerged)`] : []),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gstack",
|
||||
"version": "1.91.284",
|
||||
"version": "1.91.287",
|
||||
"description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env -S bun --no-env-file --config=/dev/null
|
||||
/**
|
||||
* Size ledger for a carved skill's union bytes (GSTA-132; format in
|
||||
* test/helpers/size-ledger.ts).
|
||||
*
|
||||
* size-ledger.ts record <skill> --why <text> [--branch <name>]
|
||||
* set this branch's entry to what this tree's union bytes differ from the
|
||||
* base plus every other entry; a zero difference deletes the entry
|
||||
* size-ledger.ts check <skill>
|
||||
* print measured, expected and each entry; exit 1 on a mismatch
|
||||
* size-ledger.ts fold <skill> --measured-at <text>
|
||||
* move the entries' sum into base.json and delete them (a tidy-up PR,
|
||||
* never a stamp commit); refuses on a mismatch
|
||||
*/
|
||||
import { spawnSync } from 'child_process';
|
||||
import { CARVE_GUARDS } from '../test/helpers/carve-guards';
|
||||
import { readSkillForParity } from '../test/helpers/parity-harness';
|
||||
import { foldLedger, ledgerExpected, ledgerFailure, readSizeLedger, recordEntry } from '../test/helpers/size-ledger';
|
||||
|
||||
const USAGE = 'usage: size-ledger.ts record <skill> --why <text> [--branch <name>] | check <skill> | fold <skill> --measured-at <text>';
|
||||
|
||||
function fail(msg: string, code = 2): never {
|
||||
console.error(`size-ledger: ${msg}`);
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
function flag(args: string[], name: string): string | undefined {
|
||||
const i = args.indexOf(name);
|
||||
if (i < 0) return undefined;
|
||||
const v = args[i + 1];
|
||||
if (!v || v.startsWith('--')) fail(`${name} needs a value`);
|
||||
return v;
|
||||
}
|
||||
|
||||
const [cmd, skill, ...rest] = process.argv.slice(2);
|
||||
if (!cmd || !skill || !['record', 'check', 'fold'].includes(cmd)) fail(USAGE);
|
||||
const root = spawnSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf-8', timeout: 10_000 }).stdout?.trim() || process.cwd();
|
||||
const dir = CARVE_GUARDS[skill]?.sizeLedger;
|
||||
if (!dir) fail(`${skill} has no sizeLedger in test/helpers/carve-guards.ts`);
|
||||
const measured = readSkillForParity(root, skill, true).unionBytes;
|
||||
const ledger = readSizeLedger(root, dir);
|
||||
if ('error' in ledger) fail(ledger.error, 1);
|
||||
|
||||
if (cmd === 'check') {
|
||||
console.log(`base ${ledger.base.union_bytes} (${ledger.base.measured_at})`);
|
||||
for (const e of ledger.entries) console.log(`${e.bytes > 0 ? '+' : ''}${e.bytes} ${e.file}: ${e.why}`);
|
||||
console.log(`expected ${ledgerExpected(ledger)} measured ${measured}`);
|
||||
const failure = ledgerFailure(skill, measured, ledger);
|
||||
if (failure) fail(failure, 1);
|
||||
console.log('SIZE_LEDGER: ok');
|
||||
} else if (cmd === 'record') {
|
||||
const why = flag(rest, '--why');
|
||||
if (!why?.trim()) fail('record needs --why "<what changed>"');
|
||||
const branch = flag(rest, '--branch') ?? spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: root, encoding: 'utf-8', timeout: 10_000 }).stdout?.trim();
|
||||
if (!branch || branch === 'HEAD') fail('detached HEAD: pass --branch <name>');
|
||||
if (branch === 'main' || branch === 'master') fail(`refusing to record on ${branch}; record on the branch that made the change`);
|
||||
let r: { file: string; bytes: number };
|
||||
try { r = recordEntry(root, ledger, measured, branch, why); } catch (err) { fail((err as Error).message); }
|
||||
console.log(r.bytes === 0
|
||||
? `SIZE_LEDGER: ${dir}/${r.file} not needed (this tree matches the ledger without it); expected ${measured}`
|
||||
: `SIZE_LEDGER: ${dir}/${r.file} ${r.bytes > 0 ? '+' : ''}${r.bytes}; expected ${measured}`);
|
||||
} else {
|
||||
const at = flag(rest, '--measured-at');
|
||||
if (!at?.trim()) fail('fold needs --measured-at "<tree it was measured on>"');
|
||||
const failure = ledgerFailure(skill, measured, ledger);
|
||||
if (failure) fail(`fold refused: ${failure}`, 1);
|
||||
foldLedger(root, ledger, at);
|
||||
console.log(`SIZE_LEDGER: folded ${ledger.entries.length} entries into ${dir}/base.json = ${measured}`);
|
||||
}
|
||||
@@ -15,7 +15,7 @@ const read = (rel: string) => fs.readFileSync(path.join(ROOT, rel), 'utf8');
|
||||
const skill = read('captain/SKILL.md');
|
||||
const tmpl = read('captain/SKILL.md.tmpl');
|
||||
const flat = skill.replace(/\s+/g, ' ');
|
||||
const TEMPLATES = ['CREW.md', 'AGENTS.md', 'NOTES.md', 'DIGEST.md', 'flaky-ledger.md', 'report.md', 'READY.md', 'slot-call.md', 'plan-ask.md', 'merge-ask.md', 'automation-flaky-pass.md'];
|
||||
const TEMPLATES = ['CREW.md', 'AGENTS.md', 'NOTES.md', 'DIGEST.md', 'flaky-ledger.md', 'report.md', 'READY.md', 'slot-call.md', 'plan-ask.md', 'merge-ask.md', 'automation-flaky-pass.md', 'brief.md'];
|
||||
|
||||
describe('/captain skill', () => {
|
||||
test('frontmatter names the skill and its /crew alias trigger', () => {
|
||||
@@ -59,12 +59,25 @@ describe('/captain skill', () => {
|
||||
expect(read('captain/templates/slot-call.md')).toContain('STAMP_VERSION=<X>');
|
||||
expect(read('captain/templates/flaky-ledger.md')).toMatch(/## Open[\s\S]*## Fixed[\s\S]*## Won't fix/);
|
||||
const crew = read('captain/templates/CREW.md');
|
||||
expect(crew).toMatch(/^23\. /m);
|
||||
expect(crew).not.toMatch(/^24\. /m);
|
||||
for (let n = 1; n <= 23; n++) expect(crew, 'rule ' + n + ' names its home').toMatch(new RegExp('^' + n + '\\. \\*\\*[^]*?Home:', 'm'));
|
||||
for (let n = 1; n <= 23; n++) expect(doc, 'docs/captain.md maps rule ' + n).toMatch(new RegExp('^\\| ' + n + ' \\| ', 'm'));
|
||||
for (const h of ['## Lane discipline', '## Contributions from outside the crew']) expect(doc).toContain(h);
|
||||
expect(crew).toMatch(/^24\. /m);
|
||||
expect(crew).not.toMatch(/^25\. /m);
|
||||
for (let n = 1; n <= 24; n++) expect(crew, 'rule ' + n + ' names its home').toMatch(new RegExp('^' + n + '\\. \\*\\*[^]*?Home:', 'm'));
|
||||
for (let n = 1; n <= 24; n++) expect(doc, 'docs/captain.md maps rule ' + n).toMatch(new RegExp('^\\| ' + n + ' \\| ', 'm'));
|
||||
for (const h of ['## Lane discipline', '## Plan before build', '## Contributions from outside the crew']) expect(doc).toContain(h);
|
||||
expect(doc).toMatch(/## Plan before build[^]*?reports `APPROVED`[^]*?## Contributions from outside the crew/);
|
||||
const brief = read('captain/templates/brief.md');
|
||||
expect(brief).toContain('Plan: required | approved: <autoplan run dir, or its checkpoint dir> | exempt: <reason');
|
||||
expect(brief).toContain('gstack-autoplan answer --out <run dir> --gate-rev <n> --reply <tokens>');
|
||||
expect(brief).toMatch(/^1\. Plan[^]*?^2\. Build after the word[^]*?^3\. Ship[^]*?^Done when:/m);
|
||||
expect(brief).toContain('gstack-approvals import --autoplan');
|
||||
expect(flat).toContain('**Plan before build.**');
|
||||
const capySkill = read('capy/skill/gstack/SKILL.md');
|
||||
expect(capySkill).toMatch(/^## Plan, approve, ship$/m);
|
||||
expect(capySkill).toMatch(/## Plan, approve, ship[^]*?reports `APPROVED`[^]*?Exempt from the plan step[^]*?## Working under a Captain/);
|
||||
expect(capySkill).not.toMatch(/## Plan, approve, ship[^]*?\]\((?:\.\.\/)?docs\//);
|
||||
expect(read('capy/skill/gstack/captain.md')).toContain('"Plan, approve, ship" section of SKILL.md');
|
||||
expect(read('captain/templates/plan-ask.md')).toContain('**do it**');
|
||||
expect(read('captain/templates/plan-ask.md')).toContain('gstack-approvals import --autoplan');
|
||||
expect(read('captain/templates/automation-flaky-pass.md')).toContain('never merge');
|
||||
});
|
||||
|
||||
|
||||
@@ -88,6 +88,12 @@ export interface CarveGuard {
|
||||
minUnionBytes: number;
|
||||
/** Parity: content phrases the union must preserve. */
|
||||
mustContain: string[];
|
||||
/**
|
||||
* Parity: the skill's union bytes must equal this ledger directory's
|
||||
* base.json plus its per-branch entries (see the size-ledger helper). A
|
||||
* guard carries sizeLedger or maxSizeRatio, never both.
|
||||
*/
|
||||
sizeLedger?: string;
|
||||
/**
|
||||
* Parity: optional per-skill override for the union size-growth ceiling vs the
|
||||
* v1.53.0.0 baseline (default 1.05). Bumped only when a deliberate cross-cutting
|
||||
@@ -168,7 +174,7 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
|
||||
// wave's headline capability) grows the union to 1.195x. Deliberate:
|
||||
// the section is on-demand (loads only for Apple store targets), so
|
||||
// per-invocation cost for non-iOS ships is one manifest line.
|
||||
maxSizeRatio: 1.7529, // GSTA-128 flaky pass (#3516, 2026-10-27, GStack Minder's rule 19 grant): the review-army section's small-diff clause names State Machines as item 9's call and a State Machines-only specialist list, +5 union bytes on a main (703b0049, v1.91.280.0) that sat 4 bytes under the 1.7524 cap after #3515 and #3517; measured 328,937 / 187,706 = 1.7524 (before: 328,932 = 1.7524) on the merged tree, pinned one in the last place above. Before that: GSTA-96 hoist merged with v1.91.273.0 (#3501, 2026-10-27): main's 1.7500 plus the hoist's own raise, no trim; measured 328,918 / 187,706 = 1.7523 on the merged tree. Before: Shared advisory identity/dedup + critical-severity validation: 248,065 union bytes / 187,706 baseline = 1.3216 (2026-09-17). + test value bar in the lazy Step 7 section (value cards, weak paths, gate table, base control, machine checks; ~13.6KB): measured 1.396 (2026-09-29). + W1 guarded state-root resolution (`eval gstack-paths; : "${GSTACK_STATE_ROOT:?…}"`) in the Context Recovery preamble, the eureka log and each state-writing bash block; measured 1.401 (2026-09-30). + the shared QA review step's plan-check timing rule (plan checks and their revalidation run on --timeout-ms after smoke expiry); measured 1.4022 (2026-09-30). + the shared TEST_BOOTSTRAP owned-change undo rules (s03 H1-H3, M1) and the value-bar coverage wording (s03 M2/M3); measured 1.4044 (2026-10-02). + severe fix wave ship-review lane: G1 NO_VERSION dispatch, title and CHANGELOG arms (versionless repos ship without inventing a version), F1 parent-side plan binding before the audit dispatch (binding, docs/designs candidates, exact not-run line) and D3's data-not-instructions line; +2,126 union bytes, measured 1.4135 (2026-10-03). + INV-1 consumer lines (outside review `unverified`/`unavailable` is missing coverage in the readiness note and PR body); measured 1.4148 (2026-10-03). + v1.91.19.0 severe fix wave: verdict-form outside-review callers with sandbox preflight and first-use notice (INV-1/B1/Q2), P0/P1 gate and unverified wording, bound-plan discovery (F1), visible LEARNINGS failures (B5), carved external pointers; measured 267,752 / 187,706 = 1.4264 (2026-10-03). + v1.91.18.0 (#3023) merged into the v1.91.19.0 wave; measured 267,874 / 187,706 = 1.4271 (2026-10-04). + Oct 6 fix wave: quota_exhausted preflight branch (#3051) and quoted-heredoc issue template (#3046); measured 268,199 / 187,706 = 1.4288 (2026-10-06). + Step 10's inline no-PR check before the Greptile dispatch (#3020); measured 268,655 / 187,706 = 1.4313 (2026-10-06). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 275,422 / 187,706 = 1.4673 (2026-10-06). Combined Oct 6 wave head (B free-text files + D measure loop + A rework): measured 280,363 / 187,706 = 1.4936 (2026-10-06). + gate-once push rule (no second paid gate after a CI push); measured 280,573 / 187,706 = 1.4947 (2026-10-06). + the measurement bar's decision step (exit-code branches for MEETS, MEETS-qualified, needs-classify with the qualifying and fix-round classes, EXTEND once; the measure prose was tightened to offset most of it); measured 281,058 / 187,706 = 1.4973 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 281,438 / 187,706 = 1.4994 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 281,556 / 187,706 = 1.5000 (2026-10-07). + Oct 7 wave B4: /ship publishes through gstack-post (title prepared in a file in the pr-body section, compose block plus gstack-post exit-code branches replacing the two scans); measured 281,894 / 187,706 = 1.5018 (2026-10-07). + B2 early Greptile PR (lazy Step 6.5 section: detect, public-repo consent, push, provisional title file, open; Step 10's bounded wait; the stop-leaves-the-draft rule); measured 286,626 / 187,706 = 1.5270 (2026-10-07). B3, the classifier, B4 and B2 merged: measured 287,128 / 187,706 = 1.5297 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 281,370 / 187,706 = 1.4990 (2026-10-07). Merged with the guard area: measured 287,440 / 187,706 = 1.5313 (2026-10-07). + Oct 8 wave: the defensive-security framing and fixture summary mode reach the security specialist and the Red Team (stated once in the dispatch, referenced by the Red Team); measured 288,783 / 187,706 = 1.5385 (2026-10-08). + gate integrity (HONEST_WORK_GATE_INTEGRITY W3): the shared GATE_SCAN_BLOCK in the core checklist (2.5) and after Step 7's child, the four-option gate question and record fields in 9.4, tests_ran states in Step 5, Gate edits and per-lane counts in the PR body with draft-whil
Line truncated
|
||||
sizeLedger: 'test/size-ledger/ship', // union bytes = base.json + one entry per branch that changed them (GSTA-132); the maxSizeRatio history is in HISTORY.md there
|
||||
},
|
||||
'plan-ceo-review': {
|
||||
skill: 'plan-ceo-review',
|
||||
|
||||
@@ -23,6 +23,7 @@ import * as path from 'path';
|
||||
import type { ParityBaseline, SkillBaselineEntry } from './capture-parity-baseline';
|
||||
import { captureBaseline } from './capture-parity-baseline';
|
||||
import { CARVE_GUARDS } from './carve-guards';
|
||||
import { ledgerFailure, readSizeLedger } from './size-ledger';
|
||||
|
||||
export interface ParityInvariant {
|
||||
skill: string;
|
||||
@@ -50,6 +51,8 @@ export interface ParityInvariant {
|
||||
sectioned?: boolean;
|
||||
/** Max bytes for the always-loaded skeleton SKILL.md (carved skills only). */
|
||||
maxSkeletonBytes?: number;
|
||||
/** Size ledger directory (test/helpers/size-ledger.ts): union bytes must equal its total; replaces maxSizeRatio. */
|
||||
sizeLedger?: string;
|
||||
}
|
||||
|
||||
export interface ParityCheckResult {
|
||||
@@ -121,7 +124,10 @@ export function checkSkillParity(
|
||||
}
|
||||
|
||||
// SIZE checks (union bytes for carved skills, skeleton bytes for monoliths)
|
||||
if (invariant.maxSizeRatio !== undefined && baseline) {
|
||||
if (invariant.sizeLedger !== undefined) {
|
||||
const failure = ledgerFailure(invariant.skill, checkBytes, readSizeLedger(repoRoot, invariant.sizeLedger), baseline?.skillMdBytes);
|
||||
if (failure) failures.push(failure);
|
||||
} else if (invariant.maxSizeRatio !== undefined && baseline) {
|
||||
const ratio = checkBytes / baseline.skillMdBytes;
|
||||
if (ratio > invariant.maxSizeRatio) {
|
||||
failures.push(`size ratio ${ratio.toFixed(3)} > maxSizeRatio ${invariant.maxSizeRatio}`);
|
||||
@@ -230,7 +236,7 @@ const CARVED_INVARIANTS: ParityInvariant[] = Object.values(CARVE_GUARDS).map((g)
|
||||
// CSO's helper trust boundary requires its private startup; demanding the
|
||||
// shared Preamble here would silently reintroduce conflicting policy.
|
||||
mustHaveHeadings: g.skill === 'cso' ? [] : ['## Preamble'],
|
||||
maxSizeRatio: g.maxSizeRatio ?? 1.05,
|
||||
...(g.sizeLedger ? { sizeLedger: g.sizeLedger } : { maxSizeRatio: g.maxSizeRatio ?? 1.05 }),
|
||||
}));
|
||||
|
||||
export const PARITY_INVARIANTS: ParityInvariant[] = [
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Size ledger for a carved skill's union bytes (GSTA-132).
|
||||
*
|
||||
* A guard with `sizeLedger` replaces the one-tree `maxSizeRatio` pin: the
|
||||
* skill's union bytes must equal `base.json`'s `union_bytes` plus the sum of
|
||||
* one entry per branch that changed them (`<branch>.json`: `{ bytes, why }`).
|
||||
* An entry is a property of its branch's own diff, so it survives base merges
|
||||
* and composes across a merge train: a clean three-way merge adds byte deltas
|
||||
* exactly, and overlapping hunks are a train conflict. Equality, not a ceiling:
|
||||
* an undeclared shrink would leave headroom a later branch could spend without
|
||||
* declaring it. Record an entry with
|
||||
* `bun --no-env-file --config=/dev/null scripts/size-ledger.ts record <skill> --why "<what changed>"`.
|
||||
*/
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
export interface SizeLedger {
|
||||
dir: string;
|
||||
base: { union_bytes: number; measured_at: string };
|
||||
entries: Array<{ file: string; bytes: number; why: string }>;
|
||||
}
|
||||
|
||||
export const LEDGER_ENTRY = /^[a-z0-9][a-z0-9._-]*\.json$/;
|
||||
|
||||
export function recordCommand(skill: string): string {
|
||||
return `bun --no-env-file --config=/dev/null scripts/size-ledger.ts record ${skill} --why "<what changed>"`;
|
||||
}
|
||||
|
||||
/** Branch name to entry filename: lowercase, [a-z0-9._-] only. */
|
||||
export function entryFile(branch: string): string {
|
||||
const slug = branch.toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^[^a-z0-9]+|-+$/g, '');
|
||||
if (!slug || slug === 'base') throw new Error(`branch ${JSON.stringify(branch)} gives no usable ledger entry name; pass --branch <name>`);
|
||||
return `${slug}.json`;
|
||||
}
|
||||
|
||||
export function readSizeLedger(repoRoot: string, dir: string): SizeLedger | { error: string } {
|
||||
const abs = path.join(repoRoot, dir);
|
||||
let base: unknown;
|
||||
try { base = JSON.parse(fs.readFileSync(path.join(abs, 'base.json'), 'utf-8')); } catch (err) { return { error: `${dir}/base.json unreadable: ${(err as Error).message}` }; }
|
||||
const b = base as { union_bytes?: unknown; measured_at?: unknown };
|
||||
if (!Number.isSafeInteger(b.union_bytes) || (b.union_bytes as number) <= 0 || typeof b.measured_at !== 'string' || !b.measured_at.trim()) {
|
||||
return { error: `${dir}/base.json needs a positive integer union_bytes and a measured_at` };
|
||||
}
|
||||
const entries: SizeLedger['entries'] = [];
|
||||
for (const file of fs.readdirSync(abs).sort()) {
|
||||
if (!file.endsWith('.json') || file === 'base.json') continue;
|
||||
if (!LEDGER_ENTRY.test(file)) return { error: `${dir}/${file}: entry names are [a-z0-9._-] ending in .json` };
|
||||
let e: { bytes?: unknown; why?: unknown };
|
||||
try { e = JSON.parse(fs.readFileSync(path.join(abs, file), 'utf-8')); } catch (err) { return { error: `${dir}/${file} unreadable: ${(err as Error).message}` }; }
|
||||
if (!Number.isSafeInteger(e.bytes) || e.bytes === 0 || typeof e.why !== 'string' || !e.why.trim()) {
|
||||
return { error: `${dir}/${file} needs a non-zero integer bytes and a why` };
|
||||
}
|
||||
entries.push({ file, bytes: e.bytes as number, why: e.why });
|
||||
}
|
||||
return { dir, base: { union_bytes: b.union_bytes as number, measured_at: b.measured_at }, entries };
|
||||
}
|
||||
|
||||
export const ledgerExpected = (l: SizeLedger) => l.base.union_bytes + l.entries.reduce((n, e) => n + e.bytes, 0);
|
||||
|
||||
/** Set `branch`'s entry to what `measured` differs from the base plus every other entry; zero deletes it. */
|
||||
export function recordEntry(repoRoot: string, ledger: SizeLedger, measured: number, branch: string, why: string): { file: string; bytes: number } {
|
||||
const file = entryFile(branch);
|
||||
const bytes = measured - ledger.base.union_bytes - ledger.entries.filter(e => e.file !== file).reduce((n, e) => n + e.bytes, 0);
|
||||
const target = path.join(repoRoot, ledger.dir, file);
|
||||
if (bytes === 0) fs.rmSync(target, { force: true });
|
||||
else fs.writeFileSync(target, JSON.stringify({ bytes, why: why.trim() }, null, 2) + '\n');
|
||||
return { file, bytes };
|
||||
}
|
||||
|
||||
/** Move the entries' sum into base.json and delete them; the caller checks the ledger holds first. */
|
||||
export function foldLedger(repoRoot: string, ledger: SizeLedger, measuredAt: string): number {
|
||||
const total = ledgerExpected(ledger);
|
||||
const abs = path.join(repoRoot, ledger.dir);
|
||||
fs.writeFileSync(path.join(abs, 'base.json'), JSON.stringify({ union_bytes: total, measured_at: measuredAt.trim() }, null, 2) + '\n');
|
||||
for (const e of ledger.entries) fs.rmSync(path.join(abs, e.file));
|
||||
return total;
|
||||
}
|
||||
|
||||
/** Null when `measured` is what the ledger accounts for, else the failure line. */
|
||||
export function ledgerFailure(skill: string, measured: number, ledger: SizeLedger | { error: string }, baselineBytes?: number): string | null {
|
||||
if ('error' in ledger) return `size ledger: ${ledger.error}`;
|
||||
const expected = ledgerExpected(ledger);
|
||||
if (measured === expected) return null;
|
||||
const ratio = baselineBytes ? ` (${(measured / baselineBytes).toFixed(4)}x baseline)` : '';
|
||||
const d = measured - expected;
|
||||
return `size union ${measured} bytes${ratio} != ledger ${ledger.base.union_bytes} + ${expected - ledger.base.union_bytes} (${ledger.entries.length} entries in ${ledger.dir}) = ${expected}; this tree is ${d > 0 ? '+' : ''}${d} bytes off: ${recordCommand(skill)}`;
|
||||
}
|
||||
@@ -428,24 +428,24 @@ export const E2E_TOUCHFILES: Record<string, string[]> = {
|
||||
// skill in test/carve-section-loading.test.ts (case-sharded, W5a). Each case
|
||||
// selects on its own skill directory; the registry, helper, harness and
|
||||
// sections.ts select every case.
|
||||
'carve-section-loading-browse': ['browse/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-codex': ['codex/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-design-consultation': ['design-consultation/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-design-html': ['design-html/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-design-shotgun': ['design-shotgun/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-document-release': ['document-release/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-benchmark': ['benchmark/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-context-restore': ['context-restore/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-investigate': ['investigate/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-land-and-deploy': ['land-and-deploy/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-plan-design-review': ['plan-design-review/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-plan-devex-review': ['plan-devex-review/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-plan-eng-review': ['plan-eng-review/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'scripts/resolvers/learnings.ts', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'scripts/resolvers/testing.ts', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-qa': ['qa/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-retro': ['retro/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-review': ['review/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-setup-gbrain': ['setup-gbrain/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-spec': ['spec/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-browse': ['browse/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-codex': ['codex/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-design-consultation': ['design-consultation/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-design-html': ['design-html/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-design-shotgun': ['design-shotgun/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-document-release': ['document-release/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-benchmark': ['benchmark/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-context-restore': ['context-restore/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-investigate': ['investigate/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-land-and-deploy': ['land-and-deploy/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-plan-design-review': ['plan-design-review/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-plan-devex-review': ['plan-devex-review/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-plan-eng-review': ['plan-eng-review/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'scripts/resolvers/learnings.ts', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'scripts/resolvers/testing.ts', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-qa': ['qa/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-retro': ['retro/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-review': ['review/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-setup-gbrain': ['setup-gbrain/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'carve-section-loading-spec': ['spec/**', 'setup', 'bin/gstack-bun-version.sh', 'bin/gstack-state-root.sh', 'lib/state-root.ts', 'bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts', 'bin/gstack-slug', 'bin/gstack-remote-identity.sh', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue', 'test/fixtures/autoplan-amend-input-77.json', 'test/fixtures/autoplan-phase-handoff-6714.json', 'test/fixtures/plan-scope-recovery-av.json', 'test/fixtures/design-scope-checkpoint-at.json', 'scripts/resolvers/composition.ts', 'autoplan/**', 'test/helpers/carve-guards.ts', 'scripts/resolvers/sections.ts', 'scripts/resolvers/redact-doc.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/session-runner.ts', 'bin/gstack-autoplan-snapshot.ts', 'test/fixtures/autoplan/t-ceo-omitted-obligations.json', 'test/fixtures/autoplan/u-ceo-original-loss.json', 'test/fixtures/autoplan/v-ceo-dangling-references.json', 'scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts', 'test/carve-section-loading.test.ts', 'test/helpers/carve-section-case.ts', 'test/fixtures/design-html-section-complete.md', 'test/helpers/carve-plan-fixture.ts', 'test/fixtures/carve-existing-repository/**', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/preamble/generate-ask-user-format.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/llm-judge.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
|
||||
// Per-finding AskUserQuestion count + review-report-at-bottom assertion.
|
||||
// Each test drives its skill end-to-end; touchfiles include preamble +
|
||||
@@ -1121,8 +1121,8 @@ export const E2E_TOUCHFILES: Record<string, string[]> = {
|
||||
'test/skill-e2e-arm-benchmark.test.ts',
|
||||
'ship/SKILL.md', 'test/helpers/e2e-gate.ts'],
|
||||
|
||||
'office-hours-section-loading': [ 'ETHOS.md', 'office-hours/**', 'bin/gstack-office-hours-review', 'lib/office-hours-review.ts', 'lib/fs-atomic.ts', 'lib/spec-review-cap.ts', 'test/helpers/office-hours-formatter-fixture.ts', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/sections.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/carve-guards.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/office-hours-completion.ts', 'test/helpers/llm-judge.ts', 'test/helpers/session-runner.ts', 'test/skill-e2e-office-hours-section-loading.test.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'office-hours-design-draft': [ 'ETHOS.md', 'office-hours/**', 'lib/office-hours-review.ts', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/sections.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/carve-guards.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/office-hours-completion.ts', 'test/helpers/llm-judge.ts', 'test/helpers/session-runner.ts', 'test/skill-e2e-office-hours-design-draft.test.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'office-hours-section-loading': [ 'ETHOS.md', 'office-hours/**', 'bin/gstack-office-hours-review', 'lib/office-hours-review.ts', 'lib/fs-atomic.ts', 'lib/spec-review-cap.ts', 'test/helpers/office-hours-formatter-fixture.ts', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/sections.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/carve-guards.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/office-hours-completion.ts', 'test/helpers/llm-judge.ts', 'test/helpers/session-runner.ts', 'test/skill-e2e-office-hours-section-loading.test.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'office-hours-design-draft': [ 'ETHOS.md', 'office-hours/**', 'lib/office-hours-review.ts', 'scripts/resolvers/review-dashboard.ts', 'scripts/resolvers/plan-gates.ts', 'scripts/resolvers/spec-review.ts', 'scripts/resolvers/outside-voice-steps.ts', 'scripts/resolvers/review-scope.ts', 'scripts/resolvers/outside-voice.ts', 'scripts/resolvers/sections.ts', 'scripts/gen-skill-docs.ts', 'test/helpers/carve-guards.ts', 'test/helpers/auq-sdk-capture.ts', 'test/helpers/office-hours-completion.ts', 'test/helpers/llm-judge.ts', 'test/helpers/session-runner.ts', 'test/skill-e2e-office-hours-design-draft.test.ts', 'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts', 'test/helpers/auto-decision-state.ts', 'test/helpers/autoplan-artifact-digest.ts', 'test/helpers/autoplan-artifact-permission.ts', 'test/helpers/autoplan-artifact-recorder.ts', 'test/helpers/capture-parity-baseline.ts', 'test/helpers/claude-pty-runner.ts', 'test/helpers/pty/**', 'test/helpers/dx-selected-navigation.ts', 'test/helpers/e2e-gate.ts', 'test/helpers/eng-cache-writer-decision.ts', 'test/helpers/hermetic-skill-runtime.ts', 'test/helpers/native-auto-decide.ts', 'test/helpers/owned-claude-transcript.ts', 'test/helpers/parity-harness.ts', 'test/helpers/size-ledger.ts', 'test/helpers/plan-count-artifacts.ts', 'test/helpers/plan-count-file-permission.ts', 'test/helpers/plan-count-fixture.ts', 'test/helpers/plan-count-pending-exit.ts', 'test/helpers/plan-count-pending-question.ts', 'test/helpers/plan-count-transcript.ts', 'test/helpers/plan-floor-review.ts', 'test/helpers/plan-floor-target.ts', 'test/helpers/plan-scope-selection.ts', 'test/helpers/plan-seed-submission.ts', 'test/helpers/plan-skill-question-events.ts', 'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/plan-skill-questions.ts', 'test/helpers/pty-screen.ts', 'test/helpers/pty-trust-dialog.ts', 'test/helpers/skill-census.ts'],
|
||||
'dx-error-contract-review': ['test/skill-e2e-dx-error-contract.test.ts', 'test/fixtures/dx-error-contract-case.ts', 'lib/dx-error-contract.ts', 'scripts/resolvers/dx.ts', 'scripts/resolvers/index.ts', 'scripts/gen-skill-docs.ts', 'plan-devex-review/**', 'bin/gstack-autoplan-snapshot.ts', 'lib/autoplan-prompts.ts', 'lib/autoplan-reconcile.ts', 'lib/coordinator-contract.ts', 'test/helpers/session-runner.ts', 'test/helpers/eval-store.ts', 'test/helpers/eval-budgets.ts', 'lib/claude-bin.ts', 'lib/eval-model.ts'],
|
||||
'plan-devex-peer-comparison-classification': [
|
||||
|
||||
|
||||
@@ -1070,9 +1070,9 @@ describe('verify, freeze, repair and clear', () => {
|
||||
}, 300_000);
|
||||
|
||||
// Value: protects=a slot unreadable on GitHub beside a merged one is left out of unmerged and named in the reason, so the rebuild after the repair never seats a PR that may already be in; fails_when=freezeQueue files an unreadable slot under unmerged, or drops it without naming it; why_new=the test above keeps slot 2 readable; seam=the fixture's gh pr view vanishing for slot 2; no_claim=the backstop's outcome
|
||||
test("a slot unreadable on GitHub beside a merged one is left out of unmerged and named in the freeze reason", () => {
|
||||
test("a slot unreadable on GitHub beside a merged one is left out of unmerged, recorded as unreadable and named by the NEXT after the repair", () => {
|
||||
const fx = make();
|
||||
const { nonce } = twoPrTrain(fx);
|
||||
const { h2, nonce } = twoPrTrain(fx);
|
||||
expect(queue(fx, ['train', 'verdict', '--train', nonce]).status).toBe(EXIT.ok);
|
||||
const t = trainJson(fx, nonce);
|
||||
const coord = coordinatorClone(fx.repo);
|
||||
@@ -1082,7 +1082,72 @@ describe('verify, freeze, repair and clear', () => {
|
||||
const frozen = queue(fx, ['verify', '--pr', '1', '--train', nonce], {}, coord);
|
||||
expect(frozen.status).toBe(EXIT.fail);
|
||||
expect(line(frozen.out, 'freeze:')).toMatch(/; #1 merged on GitHub without a verified tree; #2 unreadable on GitHub, left out of unmerged; seat it in a train by hand once gh pr view answers; unmerged \(none\); repair none admitted$/);
|
||||
expect(JSON.parse(fs.readFileSync(path.join(fx.state, 'ship-queue', 'freeze', `${repoKey(fx)}.json`), 'utf8'))).toMatchObject({ merged: ['1'], unmerged: [] });
|
||||
expect(JSON.parse(fs.readFileSync(path.join(fx.state, 'ship-queue', 'freeze', `${repoKey(fx)}.json`), 'utf8'))).toMatchObject({ merged: ['1'], unmerged: [], unreadable: [{ pr: '2', head: h2 }] });
|
||||
expect(line(frozen.out, 'unreadable:')).toBe(`unreadable: #2@${h2.slice(0, 12)} (GitHub did not answer at the freeze; neither merged nor unmerged)`);
|
||||
// The repair clears the freeze, and the NEXT names the unreadable slot instead of omitting it (#3519 b).
|
||||
const h3 = openPr(fx, '3');
|
||||
readyReceipt(fx, '3', h3);
|
||||
const rn = nonceOf(queue(fx, ['train', 'build', '--repair', '--prs', `3@${h3}`]).out);
|
||||
expect(queue(fx, ['train', 'verdict', '--train', rn]).status).toBe(EXIT.ok);
|
||||
publishMain(fx, trainJson(fx, rn).prefixes[1].commit, '1.2.6.0');
|
||||
const cleared = queue(fx, ['verify', '--pr', '3', '--train', rn], {}, coord);
|
||||
expect(cleared.out).toMatch(/^FREEZE: cleared /m);
|
||||
expect(next(cleared.out)).toBe(`NEXT: gh pr view 2 --json state,headRefOid (unreadable at the freeze: #2@${h2.slice(0, 12)}); seat each that is OPEN in a train`);
|
||||
}, 300_000);
|
||||
|
||||
// Value: protects=verify on a train whose every slot already merged, against a main another train verified, refuses as stale instead of freezing the queue and dispatching a backstop (#3519 c: train 24's record froze the queue at 9ccb5233, T1 of verified train 28, run 40586582766); fails_when=stopped() freezes when every slot merged and main's sha is another train's verified prefix, or refuses without that proof; why_new=every freeze test above has an unmerged or unverified main; seam=a second train record written into the state root; no_claim=what prune --stale then does (covered by the prune tests)
|
||||
test("verify on a train whose every slot merged, against a main another train verified, refuses as stale and freezes nothing", () => {
|
||||
const fx = make();
|
||||
const { nonce } = twoPrTrain(fx);
|
||||
expect(queue(fx, ['train', 'verdict', '--train', nonce]).status).toBe(EXIT.ok);
|
||||
const t = trainJson(fx, nonce);
|
||||
const coord = coordinatorClone(fx.repo);
|
||||
const v = (pr: string) => queue(fx, ['verify', '--pr', pr, '--train', nonce], {}, coord);
|
||||
publishMain(fx, t.prefixes[1].commit, '1.2.4.0');
|
||||
expect(v('1').status).toBe(EXIT.ok);
|
||||
const later = publishMain(fx, t.prefixes[2].commit, '1.2.5.0', { file: 'stray.txt', text: 'a later train\n' });
|
||||
fx.write(d => { (d.prs['2'] as any).state = 'MERGED'; });
|
||||
const freezeFile = path.join(fx.state, 'ship-queue', 'freeze', `${repoKey(fx)}.json`);
|
||||
const tree = fx.repo.git('rev-parse', `${later}^{tree}`);
|
||||
const otherNonce = `${nonce}-later`;
|
||||
const other = { ...t, nonce: otherNonce, state: 'merging', prefixes: [t.prefixes[0], { index: 1, commit: later, tree, pr: '9' }], merged: [{ pr: '9', sha: later, tree, at: '2026-10-18T13:00:00.000Z' }] };
|
||||
fs.mkdirSync(path.join(fx.state, 'ship-queue', 'trains', otherNonce), { recursive: true });
|
||||
fs.writeFileSync(path.join(fx.state, 'ship-queue', 'trains', otherNonce, 'train.json'), JSON.stringify(other));
|
||||
const stale = v('2');
|
||||
expect(stale.status).toBe(EXIT.refused);
|
||||
expect(stale.err).toContain(`every slot of train ${nonce} merged on GitHub and main ${later.slice(0, 12)} is T1 of train ${otherNonce} (#9, verified at 2026-10-18T13:00:00.000Z), so this record is stale and the queue is not frozen`);
|
||||
expect(stale.err).toContain('(QUEUE_TRAIN_STALE)');
|
||||
expect(next(stale.out)).toBe(`NEXT: gstack-ship-queue train prune --stale --train ${nonce}`);
|
||||
expect(fs.existsSync(freezeFile)).toBe(false);
|
||||
expect(dispatches(fx, 'evals.yml').filter(d => d.ref === 'main').length).toBe(0);
|
||||
// Without another train's verified record for this main, the same mismatch still freezes.
|
||||
fs.rmSync(path.join(fx.state, 'ship-queue', 'trains', otherNonce), { recursive: true });
|
||||
const frozen = v('2');
|
||||
expect(frozen.status).toBe(EXIT.fail);
|
||||
expect(line(frozen.out, 'QUEUE_TRAIN_FROZEN:')).toMatch(/^QUEUE_TRAIN_FROZEN: train \S+ merged #1,#2; main /);
|
||||
}, 300_000);
|
||||
|
||||
// Value: protects=a train with a slot still OPEN on GitHub freezes on a mismatch even when main's sha is another train's verified prefix; fails_when=the every-slot-merged guard before verifiedElsewhere is dropped or weakened, so a live train refuses as stale and skips the freeze; why_new=the test above only covers an all-merged train; seam=none; no_claim=prune behavior
|
||||
test("a train with a slot still open freezes on the mismatch even when another train verified main's sha", () => {
|
||||
const fx = make();
|
||||
const { nonce } = twoPrTrain(fx);
|
||||
expect(queue(fx, ['train', 'verdict', '--train', nonce]).status).toBe(EXIT.ok);
|
||||
const t = trainJson(fx, nonce);
|
||||
const coord = coordinatorClone(fx.repo);
|
||||
const v = (pr: string) => queue(fx, ['verify', '--pr', pr, '--train', nonce], {}, coord);
|
||||
publishMain(fx, t.prefixes[1].commit, '1.2.4.0');
|
||||
expect(v('1').status).toBe(EXIT.ok);
|
||||
const later = publishMain(fx, t.prefixes[2].commit, '1.2.5.0', { file: 'stray.txt', text: 'a later train\n' });
|
||||
const tree = fx.repo.git('rev-parse', `${later}^{tree}`);
|
||||
const otherNonce = `${nonce}-later`;
|
||||
const other = { ...t, nonce: otherNonce, state: 'merging', prefixes: [t.prefixes[0], { index: 1, commit: later, tree, pr: '9' }], merged: [{ pr: '9', sha: later, tree, at: '2026-10-18T13:00:00.000Z' }] };
|
||||
fs.mkdirSync(path.join(fx.state, 'ship-queue', 'trains', otherNonce), { recursive: true });
|
||||
fs.writeFileSync(path.join(fx.state, 'ship-queue', 'trains', otherNonce, 'train.json'), JSON.stringify(other));
|
||||
const partial = v('2');
|
||||
expect(partial.status).toBe(EXIT.fail);
|
||||
expect(partial.err).not.toContain('(QUEUE_TRAIN_STALE)');
|
||||
expect(line(partial.out, 'QUEUE_TRAIN_FROZEN:')).toMatch(/^QUEUE_TRAIN_FROZEN: train \S+ merged #1; main /);
|
||||
expect(fs.existsSync(path.join(fx.state, 'ship-queue', 'freeze', `${repoKey(fx)}.json`))).toBe(true);
|
||||
}, 300_000);
|
||||
|
||||
// Value: protects=a post-merge CHANGELOG difference is excused only when main's parent is T<i-1> modulo stamps, so a foreign commit between the verified head and the squash freezes; fails_when=published() skips or inverts the parent check; why_new=the two tests above reach the CHANGELOG rule only with a parent that is T1 modulo stamps; seam=none; no_claim=a parent differing from T1 in the CHANGELOG alone
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
* Size ledger (GSTA-132): ship's union cap composes across a merge train.
|
||||
*
|
||||
* The train-26 shape: two branches off one main both grow a carved skill. Under
|
||||
* one-tree ratio pins, branch A re-pins on its own tree and branch B fits under
|
||||
* main's rounding slack without a pin; each passes alone and the train's own
|
||||
* merge of both (buildChain, the code train build runs) fails the parity
|
||||
* check. Under the ledger each branch records its own delta and the same train
|
||||
* passes, while a branch that grows beyond what it recorded still fails.
|
||||
*/
|
||||
import { afterAll, describe, expect, test } from 'bun:test';
|
||||
import { spawnSync } from 'child_process';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { bunIsolationArgs } from '../lib/bun-isolation';
|
||||
import { buildChain } from '../lib/ship-queue-train';
|
||||
import { DEFAULT_POLICY } from '../lib/ship-policy';
|
||||
import { CARVE_GUARDS } from './helpers/carve-guards';
|
||||
import { PARITY_INVARIANTS, checkSkillParity, readSkillForParity } from './helpers/parity-harness';
|
||||
import type { SkillBaselineEntry } from './helpers/capture-parity-baseline';
|
||||
import { entryFile, foldLedger, ledgerExpected, ledgerFailure, readSizeLedger, recordEntry } from './helpers/size-ledger';
|
||||
|
||||
const BASELINE = { skillMdBytes: 187_706 } as SkillBaselineEntry;
|
||||
const MAIN_UNION = 328_937;
|
||||
const LEDGER = 'test/size-ledger/demo';
|
||||
const roots: string[] = [];
|
||||
afterAll(() => { for (const r of roots) fs.rmSync(r, { recursive: true, force: true }); });
|
||||
|
||||
function git(cwd: string, ...args: string[]): string {
|
||||
const r = spawnSync('git', args, { cwd, encoding: 'utf-8', timeout: 30_000, env: { ...process.env, GIT_AUTHOR_NAME: 't', GIT_AUTHOR_EMAIL: 't@t', GIT_COMMITTER_NAME: 't', GIT_COMMITTER_EMAIL: 't@t' } });
|
||||
if (r.status !== 0) throw new Error(`git ${args.join(' ')}: ${r.stderr}`);
|
||||
return r.stdout.trim();
|
||||
}
|
||||
|
||||
const write = (root: string, rel: string, text: string) => { fs.mkdirSync(path.dirname(path.join(root, rel)), { recursive: true }); fs.writeFileSync(path.join(root, rel), text); };
|
||||
const append = (root: string, rel: string, bytes: number) => fs.appendFileSync(path.join(root, rel), 'y'.repeat(bytes - 1) + '\n');
|
||||
const union = (root: string) => readSkillForParity(root, 'demo', true).unionBytes;
|
||||
const pinFor = (root: string) => Math.ceil((union(root) / BASELINE.skillMdBytes) * 1e4) / 1e4;
|
||||
const ratioCheck = (root: string) => checkSkillParity({ skill: 'demo', sectioned: true, maxSizeRatio: JSON.parse(fs.readFileSync(path.join(root, 'cap.json'), 'utf-8')).ratio }, BASELINE, BASELINE, root);
|
||||
const ledgerCheck = (root: string) => checkSkillParity({ skill: 'demo', sectioned: true, sizeLedger: LEDGER }, BASELINE, BASELINE, root);
|
||||
const ledger = (root: string) => { const l = readSizeLedger(root, LEDGER); if ('error' in l) throw new Error(l.error); return l; };
|
||||
|
||||
/** main: a carved skill at 328,937 union bytes, a ratio pin one in the last place above, and an empty ledger. */
|
||||
function mainRepo(): { root: string; main: string } {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'size-ledger-'));
|
||||
roots.push(root);
|
||||
git(root, 'init', '-q', '-b', 'main');
|
||||
git(root, 'config', 'core.autocrlf', 'false');
|
||||
write(root, 'demo/sections/a.md', '# A\n');
|
||||
write(root, 'demo/sections/b.md', '# B\n');
|
||||
write(root, 'demo/SKILL.md', '## Preamble\n' + 'x'.repeat(MAIN_UNION - 8 - 13) + '\n');
|
||||
expect(union(root)).toBe(MAIN_UNION);
|
||||
write(root, 'cap.json', JSON.stringify({ ratio: pinFor(root) }) + '\n');
|
||||
write(root, `${LEDGER}/base.json`, JSON.stringify({ union_bytes: MAIN_UNION, measured_at: 'fixture main' }) + '\n');
|
||||
git(root, 'add', '-A');
|
||||
git(root, 'commit', '-q', '-m', 'main');
|
||||
return { root, main: git(root, 'rev-parse', 'HEAD') };
|
||||
}
|
||||
|
||||
/** A branch off main that grows section `file` by `bytes`, then lets `mark` record the change its way. */
|
||||
function branch(root: string, main: string, name: string, file: string, bytes: number, mark: (root: string) => void): string {
|
||||
git(root, 'checkout', '-q', '-b', name, main);
|
||||
append(root, `demo/sections/${file}`, bytes);
|
||||
mark(root);
|
||||
git(root, 'add', '-A');
|
||||
git(root, 'commit', '-q', '-m', name);
|
||||
return git(root, 'rev-parse', 'HEAD');
|
||||
}
|
||||
|
||||
function train(root: string, main: string, heads: string[]): string {
|
||||
const chain = buildChain(root, main, heads.map((head, i) => ({ pr: String(i + 1), head, ready_at: '', screen: 'none' as never })), DEFAULT_POLICY);
|
||||
if (!('prefixes' in chain)) throw new Error(`train stopped at #${chain.stoppedAt}: ${chain.conflicts.join(', ')}`);
|
||||
const tip = chain.prefixes.at(-1)!.commit;
|
||||
git(root, 'checkout', '-q', '--detach', tip);
|
||||
return tip;
|
||||
}
|
||||
|
||||
function atHead(root: string, head: string) { git(root, 'checkout', '-q', '--detach', head); }
|
||||
|
||||
describe('train-26 shape under one-tree ratio pins (before)', () => {
|
||||
test('each branch passes alone and the train merge of both fails the ratio cap', () => {
|
||||
const { root, main } = mainRepo();
|
||||
const a = branch(root, main, 'a', 'a.md', 55, r => write(r, 'cap.json', JSON.stringify({ ratio: pinFor(r) }) + '\n'));
|
||||
const b = branch(root, main, 'b', 'b.md', 12, () => {});
|
||||
atHead(root, a); expect(ratioCheck(root).passed).toBe(true);
|
||||
atHead(root, b); expect(ratioCheck(root).passed).toBe(true);
|
||||
train(root, main, [a, b]);
|
||||
const res = ratioCheck(root);
|
||||
expect(res.passed).toBe(false);
|
||||
expect(res.failures.join('\n')).toMatch(/size ratio 1\.753 > maxSizeRatio 1\.7527/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the same train under the size ledger (after)', () => {
|
||||
const recorded = (name: string, why: string) => (r: string) => { recordEntry(r, ledger(r), union(r), name, why); };
|
||||
|
||||
test('each branch records its own delta; both orders of the train pass', () => {
|
||||
const { root, main } = mainRepo();
|
||||
const a = branch(root, main, 'a', 'a.md', 55, recorded('a', 'grew a'));
|
||||
const b = branch(root, main, 'b', 'b.md', 12, recorded('b', 'grew b'));
|
||||
for (const head of [a, b]) { atHead(root, head); expect(ledgerCheck(root).failures).toEqual([]); }
|
||||
for (const order of [[a, b], [b, a]]) {
|
||||
train(root, main, order);
|
||||
expect(ledgerCheck(root).failures).toEqual([]);
|
||||
expect(ledger(root).entries.map(e => [e.file, e.bytes])).toEqual([['a.json', 55], ['b.json', 12]]);
|
||||
}
|
||||
});
|
||||
|
||||
test('a branch that grows without recording fails on its own tree and in the train', () => {
|
||||
const { root, main } = mainRepo();
|
||||
const a = branch(root, main, 'a', 'a.md', 55, recorded('a', 'grew a'));
|
||||
const b = branch(root, main, 'b', 'b.md', 12, () => {});
|
||||
atHead(root, b);
|
||||
expect(ledgerCheck(root).failures.join('\n')).toContain('this tree is +12 bytes off: bun --no-env-file --config=/dev/null scripts/size-ledger.ts record demo');
|
||||
train(root, main, [a, b]);
|
||||
expect(ledgerCheck(root).failures.join('\n')).toContain('this tree is +12 bytes off');
|
||||
});
|
||||
|
||||
test('a branch that records less than it grew fails the train by the difference', () => {
|
||||
const { root, main } = mainRepo();
|
||||
const a = branch(root, main, 'a', 'a.md', 55, recorded('a', 'grew a'));
|
||||
const b = branch(root, main, 'b', 'b.md', 12, r => write(r, `${LEDGER}/b.json`, JSON.stringify({ bytes: 11, why: 'under-declared' }) + '\n'));
|
||||
train(root, main, [a, b]);
|
||||
expect(ledgerCheck(root).failures.join('\n')).toContain('this tree is +1 bytes off');
|
||||
});
|
||||
|
||||
test('an undeclared shrink fails: it would leave headroom a later branch spends silently', () => {
|
||||
const { root, main } = mainRepo();
|
||||
atHead(root, main);
|
||||
write(root, 'demo/sections/a.md', '#\n');
|
||||
expect(ledgerCheck(root).failures.join('\n')).toContain('this tree is -2 bytes off');
|
||||
recordEntry(root, ledger(root), union(root), 'trim', 'trimmed a');
|
||||
expect(ledgerCheck(root).failures).toEqual([]);
|
||||
});
|
||||
|
||||
test('two branches making the identical edit fail closed (git keeps one copy, both entries count)', () => {
|
||||
const { root, main } = mainRepo();
|
||||
const a = branch(root, main, 'a', 'a.md', 20, recorded('a', 'same line'));
|
||||
const b = branch(root, main, 'b', 'a.md', 20, recorded('b', 'same line'));
|
||||
train(root, main, [a, b]);
|
||||
expect(ledgerCheck(root).failures.join('\n')).toContain('this tree is -20 bytes off');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ledger records', () => {
|
||||
test('record is idempotent, deletes a zero entry, and fold keeps the total', () => {
|
||||
const { root, main } = mainRepo();
|
||||
atHead(root, main);
|
||||
append(root, 'demo/sections/a.md', 30);
|
||||
expect(recordEntry(root, ledger(root), union(root), 'feat/x', 'grew')).toEqual({ file: 'feat-x.json', bytes: 30 });
|
||||
expect(recordEntry(root, ledger(root), union(root), 'feat/x', 'grew')).toEqual({ file: 'feat-x.json', bytes: 30 });
|
||||
write(root, `${LEDGER}/other.json`, JSON.stringify({ bytes: 5, why: 'other branch' }) + '\n');
|
||||
append(root, 'demo/sections/b.md', 5);
|
||||
expect(ledgerCheck(root).failures).toEqual([]);
|
||||
const total = foldLedger(root, ledger(root), 'fixture fold');
|
||||
expect(total).toBe(MAIN_UNION + 35);
|
||||
expect(ledger(root)).toMatchObject({ base: { union_bytes: MAIN_UNION + 35 }, entries: [] });
|
||||
expect(ledgerCheck(root).failures).toEqual([]);
|
||||
write(root, 'demo/sections/a.md', '# A\n');
|
||||
expect(recordEntry(root, ledger(root), union(root), 'feat/x', 'undo')).toEqual({ file: 'feat-x.json', bytes: -30 });
|
||||
expect(recordEntry(root, ledger(root), union(root) + 30, 'feat/x', 'undo')).toEqual({ file: 'feat-x.json', bytes: 0 });
|
||||
expect(fs.existsSync(path.join(root, LEDGER, 'feat-x.json'))).toBe(false);
|
||||
});
|
||||
|
||||
test('malformed ledgers fail instead of skipping', () => {
|
||||
const { root, main } = mainRepo();
|
||||
atHead(root, main);
|
||||
const bad = (rel: string, text: string, msg: RegExp) => {
|
||||
write(root, rel, text);
|
||||
expect(ledgerFailure('demo', union(root), readSizeLedger(root, LEDGER))).toMatch(msg);
|
||||
fs.rmSync(path.join(root, rel));
|
||||
};
|
||||
bad(`${LEDGER}/x.json`, '{"bytes":1.5,"why":"a"}', /non-zero integer bytes and a why/);
|
||||
bad(`${LEDGER}/x.json`, '{"bytes":3,"why":" "}', /non-zero integer bytes and a why/);
|
||||
bad(`${LEDGER}/x.json`, '{"bytes":0,"why":"a"}', /non-zero integer bytes and a why/);
|
||||
bad(`${LEDGER}/x.json`, 'not json', /unreadable/);
|
||||
bad(`${LEDGER}/Upper.json`, '{"bytes":1,"why":"a"}', /entry names/);
|
||||
fs.rmSync(path.join(root, LEDGER, 'base.json'));
|
||||
expect(ledgerFailure('demo', union(root), readSizeLedger(root, LEDGER))).toMatch(/base\.json unreadable/);
|
||||
});
|
||||
|
||||
test('entry names come from the branch', () => {
|
||||
expect(entryFile('GSTA-132/Size Ledger')).toBe('gsta-132-size-ledger.json');
|
||||
expect(() => entryFile('///')).toThrow(/no usable ledger entry name/);
|
||||
expect(() => entryFile('base')).toThrow(/no usable ledger entry name/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ship is on the ledger', () => {
|
||||
const repo = path.resolve(import.meta.dir, '..');
|
||||
test('a guard carries sizeLedger or maxSizeRatio, never both', () => {
|
||||
expect(Object.values(CARVE_GUARDS).filter(g => g.sizeLedger && g.maxSizeRatio !== undefined).map(g => g.skill)).toEqual([]);
|
||||
expect(CARVE_GUARDS.ship!.sizeLedger).toBe('test/size-ledger/ship');
|
||||
});
|
||||
test('the parity invariant takes the ledger, not the 1.05 default', () => {
|
||||
const inv = PARITY_INVARIANTS.find(i => i.skill === 'ship')!;
|
||||
expect(inv.sizeLedger).toBe('test/size-ledger/ship');
|
||||
expect(inv.maxSizeRatio).toBeUndefined();
|
||||
expect(PARITY_INVARIANTS.find(i => i.skill === 'plan-eng-review')!.maxSizeRatio).toBe(CARVE_GUARDS['plan-eng-review']!.maxSizeRatio!);
|
||||
});
|
||||
test('the ship ledger accounts for this tree', () => {
|
||||
const l = readSizeLedger(repo, 'test/size-ledger/ship');
|
||||
expect(ledgerFailure('ship', readSkillForParity(repo, 'ship', true).unionBytes, l)).toBeNull();
|
||||
expect('error' in l ? 0 : ledgerExpected(l)).toBeGreaterThan(0);
|
||||
});
|
||||
// Value: protects=the scripts/size-ledger.ts CLI contract lanes run (check exits 0 with SIZE_LEDGER: ok on a tree the ledger accounts for; record refuses on main or without --why, fold without --measured-at, a skill with no ledger; none of them writes); fails_when=a refusal is dropped, an exit code changes or a refused call writes an entry; why_new=the tests above call the helpers, never the script; seam=none; no_claim=the exit-1 mismatch path (needs a ship tree off the ledger)
|
||||
test('scripts/size-ledger.ts checks this tree and refuses unsafe calls without writing', () => {
|
||||
const run = (...args: string[]) => spawnSync(process.execPath, [...bunIsolationArgs(), path.join(repo, 'scripts/size-ledger.ts'), ...args], { cwd: repo, encoding: 'utf-8', timeout: 60_000 });
|
||||
const dir = path.join(repo, 'test/size-ledger/ship');
|
||||
const before = fs.readdirSync(dir).sort();
|
||||
const check = run('check', 'ship');
|
||||
expect([check.status, check.stdout.trim().split('\n').at(-1)]).toEqual([0, 'SIZE_LEDGER: ok']);
|
||||
const refusals: Array<[string[], string]> = [
|
||||
[['record', 'ship', '--why', 'probe', '--branch', 'main'], 'refusing to record on main'],
|
||||
[['record', 'ship'], 'record needs --why'],
|
||||
[['fold', 'ship'], 'fold needs --measured-at'],
|
||||
[['check', 'plan-eng-review'], 'plan-eng-review has no sizeLedger'],
|
||||
];
|
||||
for (const [args, message] of refusals) {
|
||||
const r = run(...args);
|
||||
expect([r.status, r.stderr.includes(message)]).toEqual([2, true]);
|
||||
}
|
||||
expect(fs.readdirSync(dir).sort()).toEqual(before);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
# ship union-size cap history
|
||||
|
||||
## Superseded at the cut-over
|
||||
|
||||
Main re-pinned ship to `maxSizeRatio: 1.7529` (#3497, v1.91.284.0) while GSTA-132 was in review. The cut-over merge of main 10b77de into #3522 replaced that literal with this ledger and measured `base.json` on the merged tree. The 1.7529 comment, verbatim:
|
||||
|
||||
GSTA-128 flaky pass (#3516, 2026-10-27, GStack Minder's rule 19 grant): the review-army section's small-diff clause names State Machines as item 9's call and a State Machines-only specialist list, +5 union bytes on a main (703b0049, v1.91.280.0) that sat 4 bytes under the 1.7524 cap after #3515 and #3517; measured 328,937 / 187,706 = 1.7524 (before: 328,932 = 1.7524) on the merged tree, pinned one in the last place above. Before that: GSTA-96 hoist merged with v1.91.273.0 (#3501, 2026-10-27): main's 1.7500 plus the hoist's own raise, no trim; measured 328,918 / 187,706 = 1.7523 on the merged tree. Before: Shared advisory identity/dedup + critical-severity validation: 248,065 union bytes / 187,706 baseline = 1.3216 (2026-09-17). + test value bar in the lazy Step 7 section (value cards, weak paths, gate table, base control, machine checks; ~13.6KB): measured 1.396 (2026-09-29). + W1 guarded state-root resolution (`eval gstack-paths; : "${GSTACK_STATE_ROOT:?…}"`) in the Context Recovery preamble, the eureka log and each state-writing bash block; measured 1.401 (2026-09-30). + the shared QA review step's plan-check timing rule (plan checks and their revalidation run on --timeout-ms after smoke expiry); measured 1.4022 (2026-09-30). + the shared TEST_BOOTSTRAP owned-change undo rules (s03 H1-H3, M1) and the value-bar coverage wording (s03 M2/M3); measured 1.4044 (2026-10-02). + severe fix wave ship-review lane: G1 NO_VERSION dispatch, title and CHANGELOG arms (versionless repos ship without inventing a version), F1 parent-side plan binding before the audit dispatch (binding, docs/designs candidates, exact not-run line) and D3's data-not-instructions line; +2,126 union bytes, measured 1.4135 (2026-10-03). + INV-1 consumer lines (outside review `unverified`/`unavailable` is missing coverage in the readiness note and PR body); measured 1.4148 (2026-10-03). + v1.91.19.0 severe fix wave: verdict-form outside-review callers with sandbox preflight and first-use notice (INV-1/B1/Q2), P0/P1 gate and unverified wording, bound-plan discovery (F1), visible LEARNINGS failures (B5), carved external pointers; measured 267,752 / 187,706 = 1.4264 (2026-10-03). + v1.91.18.0 (#3023) merged into the v1.91.19.0 wave; measured 267,874 / 187,706 = 1.4271 (2026-10-04). + Oct 6 fix wave: quota_exhausted preflight branch (#3051) and quoted-heredoc issue template (#3046); measured 268,199 / 187,706 = 1.4288 (2026-10-06). + Step 10's inline no-PR check before the Greptile dispatch (#3020); measured 268,655 / 187,706 = 1.4313 (2026-10-06). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 275,422 / 187,706 = 1.4673 (2026-10-06). Combined Oct 6 wave head (B free-text files + D measure loop + A rework): measured 280,363 / 187,706 = 1.4936 (2026-10-06). + gate-once push rule (no second paid gate after a CI push); measured 280,573 / 187,706 = 1.4947 (2026-10-06). + the measurement bar's decision step (exit-code branches for MEETS, MEETS-qualified, needs-classify with the qualifying and fix-round classes, EXTEND once; the measure prose was tightened to offset most of it); measured 281,058 / 187,706 = 1.4973 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 281,438 / 187,706 = 1.4994 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 281,556 / 187,706 = 1.5000 (2026-10-07). + Oct 7 wave B4: /ship publishes through gstack-post (title prepared in a file in the pr-body section, compose block plus gstack-post exit-code branches replacing the two scans); measured 281,894 / 187,706 = 1.5018 (2026-10-07). + B2 early Greptile PR (lazy Step 6.5 section: detect, public-repo consent, push, provisional title file, open; Step 10's bounded wait; the stop-leaves-the-draft rule); measured 286,626 / 187,706 = 1.5270 (2026-10-07). B3, the classifier, B4 and B2 merged: measured 287,128 / 187,706 = 1.5297 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 281,370 / 187,706 = 1.4990 (2026-10-07). Merged with the guard area: measured 287,440 / 187,706 = 1.5313 (2026-10-07). + Oct 8 wave: the defensive-security framing and fixture summary mode reach the security specialist and the Red Team (stated once in the dispatch, referenced by the Red Team); measured 288,783 / 187,706 = 1.5385 (2026-10-08). + gate integrity (HONEST_WORK_GATE_INTEGRITY W3): the shared GATE_SCAN_BLOCK in the core checklist (2.5) and after Step 7's child, the four-option gate question and record fields in 9.4, tests_ran states in Step 5, Gate edits and per-lane counts in the PR body with draft-while-open; measured 300,143 / 18Line truncated
|
||||
|
||||
## Before the cut-over
|
||||
|
||||
Ship's union cap was a `maxSizeRatio` literal in `test/helpers/carve-guards.ts`, re-pinned by each PR on its own merged tree, until GSTA-132 moved it to this ledger (`base.json` plus one `<branch>.json` per branch that changed ship's union bytes; see `test/helpers/size-ledger.ts`). The last literal was `maxSizeRatio: 1.7525` against the 187,706-byte v1.64.1.0 baseline (328,937 union bytes). Its comment, verbatim:
|
||||
|
||||
GSTA-128 flaky pass (#3516, 2026-10-27, GStack Minder's rule 19 grant): the review-army section's small-diff clause names State Machines as item 9's call and a State Machines-only specialist list, +5 union bytes on a main (703b0049, v1.91.280.0) that sat 4 bytes under the 1.7524 cap after #3515 and #3517; measured 328,937 / 187,706 = 1.7524 (before: 328,932 = 1.7524) on the merged tree, pinned one in the last place above. Before that: GSTA-96 hoist merged with v1.91.273.0 (#3501, 2026-10-27): main's 1.7500 plus the hoist's own raise, no trim; measured 328,918 / 187,706 = 1.7523 on the merged tree. Before: Shared advisory identity/dedup + critical-severity validation: 248,065 union bytes / 187,706 baseline = 1.3216 (2026-09-17). + test value bar in the lazy Step 7 section (value cards, weak paths, gate table, base control, machine checks; ~13.6KB): measured 1.396 (2026-09-29). + W1 guarded state-root resolution (`eval gstack-paths; : "${GSTACK_STATE_ROOT:?…}"`) in the Context Recovery preamble, the eureka log and each state-writing bash block; measured 1.401 (2026-09-30). + the shared QA review step's plan-check timing rule (plan checks and their revalidation run on --timeout-ms after smoke expiry); measured 1.4022 (2026-09-30). + the shared TEST_BOOTSTRAP owned-change undo rules (s03 H1-H3, M1) and the value-bar coverage wording (s03 M2/M3); measured 1.4044 (2026-10-02). + severe fix wave ship-review lane: G1 NO_VERSION dispatch, title and CHANGELOG arms (versionless repos ship without inventing a version), F1 parent-side plan binding before the audit dispatch (binding, docs/designs candidates, exact not-run line) and D3's data-not-instructions line; +2,126 union bytes, measured 1.4135 (2026-10-03). + INV-1 consumer lines (outside review `unverified`/`unavailable` is missing coverage in the readiness note and PR body); measured 1.4148 (2026-10-03). + v1.91.19.0 severe fix wave: verdict-form outside-review callers with sandbox preflight and first-use notice (INV-1/B1/Q2), P0/P1 gate and unverified wording, bound-plan discovery (F1), visible LEARNINGS failures (B5), carved external pointers; measured 267,752 / 187,706 = 1.4264 (2026-10-03). + v1.91.18.0 (#3023) merged into the v1.91.19.0 wave; measured 267,874 / 187,706 = 1.4271 (2026-10-04). + Oct 6 fix wave: quota_exhausted preflight branch (#3051) and quoted-heredoc issue template (#3046); measured 268,199 / 187,706 = 1.4288 (2026-10-06). + Step 10's inline no-PR check before the Greptile dispatch (#3020); measured 268,655 / 187,706 = 1.4313 (2026-10-06). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 275,422 / 187,706 = 1.4673 (2026-10-06). Combined Oct 6 wave head (B free-text files + D measure loop + A rework): measured 280,363 / 187,706 = 1.4936 (2026-10-06). + gate-once push rule (no second paid gate after a CI push); measured 280,573 / 187,706 = 1.4947 (2026-10-06). + the measurement bar's decision step (exit-code branches for MEETS, MEETS-qualified, needs-classify with the qualifying and fix-round classes, EXTEND once; the measure prose was tightened to offset most of it); measured 281,058 / 187,706 = 1.4973 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 281,438 / 187,706 = 1.4994 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 281,556 / 187,706 = 1.5000 (2026-10-07). + Oct 7 wave B4: /ship publishes through gstack-post (title prepared in a file in the pr-body section, compose block plus gstack-post exit-code branches replacing the two scans); measured 281,894 / 187,706 = 1.5018 (2026-10-07). + B2 early Greptile PR (lazy Step 6.5 section: detect, public-repo consent, push, provisional title file, open; Step 10's bounded wait; the stop-leaves-the-draft rule); measured 286,626 / 187,706 = 1.5270 (2026-10-07). B3, the classifier, B4 and B2 merged: measured 287,128 / 187,706 = 1.5297 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 281,370 / 187,706 = 1.4990 (2026-10-07). Merged with the guard area: measured 287,440 / 187,706 = 1.5313 (2026-10-07). + Oct 8 wave: the defensive-security framing and fixture summary mode reach the security specialist and the Red Team (stated once in the dispatch, referenced by the Red Team); measured 288,783 / 187,706 = 1.5385 (2026-10-08). + gate integrity (HONEST_WORK_GATE_INTEGRITY W3): the shared GATE_SCAN_BLOCK in the core checklist (2.5) and after Step 7's child, the four-option gate question and record fields in 9.4, tests_ran states in Step 5, Gate edits and per-lane counts in the PR body with draft-while-open; measured 300,143 / 18Line truncated
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"union_bytes": 329024,
|
||||
"measured_at": "merged tree: main 10b77de (v1.91.284.0) + #3522"
|
||||
}
|
||||
Reference in new issue
Block a user