Merge branch 'c3922' into capy/gst-1088-after-pin

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

# Conflicts:
#	test/fixtures/skill-md-size-allowlist.json
#	test/helpers/carve-guards.ts
This commit is contained in:
garrytan committed 2026-11-03 20:23:26 +00:00
commit 50e38dad1f
27 files changed
+462 -250

No files matched your search

+1 -1
View File
@@ -94,7 +94,7 @@ gstack/
│ ├── test/ # Integration tests
│ └── dist/ # Compiled binary
├── agents-digest/ # Committed 2KB instruction-tier rules digest (gstack-AGENTS.md) for rules-reading hosts
├── modules/ # loadouts.json (+ loadouts.schema.json): model rungs, the model map, pinned modules and named loadouts; read by scripts/modules.ts and lib/model-detect.ts, rendered by bin/gstack-modules (docs/loadouts.md)
├── modules/ # loadouts.json (+ loadouts.schema.json): model rungs, the model map, pinned modules and named loadouts; read by scripts/modules.ts and lib/model-detect.ts, rendered by bin/gstack-modules (docs/loadouts.md); cuts.json = the R56 cut ledger (pieces cut from one skill in every loadout, read by scripts/cut-ledger.ts, ratchet test/cut-ledger.test.ts)
├── extension/ # Chrome extension (side panel + activity feed + CSS inspector)
├── lib/ # Shared libraries (aside-render.ts = local-HTML rendering, Aside first, engine fallback; design-catalog.ts = the typed design anti-pattern catalog every design skill renders from; design-lint/ = the static and render tiers behind bin/gstack-design-lint, ported from hallmark's sloplint; design-detect-contract.ts = detector sentinel vocabulary; design-md.ts = open DESIGN.md reader/writer; dom-dump-script.ts + generated dom-dump.js = rendered-DOM dump for the detector; review-evidence.ts = review-start receipt binding, computed freshness and shared-code snapshot eligibility; frontend-scope.ts; claude-bin.ts, error-handling.ts, worktree.ts, egress-receipt.ts, context-bill.ts, redact-engine.ts, tracker-guard.ts, version-source.ts, code-intelligence/)
│ └── diagram-render/ # Vendored mermaid + excalidraw runtimes, built into one offline bundle the renderer loads
+1 -1
View File
@@ -30,7 +30,7 @@ Targeted defects, one per judge:
|---|---|
| qa workflow | `## Phase 10: Report` removed up to `## Phase 11:`: the deliverable and its path are undefined |
| qa-only workflow | after `# /qa-only: Report-Only QA Testing`, insert "After reporting each bug, fix it in the source and commit the fix." (contradicts report-only) |
| review workflow | `## Step 3: Get the diff` removed up to `## Step 3.4`: no instruction says how to obtain the reviewed candidate |
| review workflow | `## Step 3: Get the diff` removed up to `## Step 3.5` (`## Step 3.4` before GST-1088 cut it): no instruction says how to obtain the reviewed candidate |
| setup-deploy platform setup | the Step 2 detection `bash` block removed: platform detection has no command |
## Panels and reading the result
+6 -1
View File
@@ -9,6 +9,7 @@ One model has its own loadout: Claude Opus 5.5 gets `lite` ([below](#lite-on-cla
| Term | Meaning |
|---|---|
| Module | One of four kinds. `skill:<dir>` is a whole skill. `section:<skill>/<id>` is one entry of `<skill>/sections/manifest.json`. `overlay:<name>` is one `model-overlays/<name>.md`; excluding a base overlay also removes the base's text from every overlay that inherits it; the inheriting overlay's own text stays. `preamble:<id>` is one piece of the shared preamble (`PREAMBLE_PIECES` in `scripts/resolvers/preamble.ts`). |
| Cut | A `part:<skill>/<name>` entry from `modules/cuts.json`, the R56 cut ledger: a piece removed from one skill in every loadout, `full` included, and on every host. `gstack-modules list` shows it with status `cut`; no loadout or `--modules` spec may name it. See [Cuts](#cuts). |
| Pinned | A module no loadout can remove where `full` renders it: the start command, plan-mode rules, the question format, completion status, the Claims Need Evidence rule, the unattended profile, /ship's review army and adversarial pass, the router and `/gstack-upgrade`. A skill's `preamble-tier` still applies, so a tier-1 skill has no question-format section in any loadout. |
| Rung | How much scaffolding a model gets: `frontier`, `strong`, `mid`, `light`, or `unknown`. Model ids are matched after lowercasing and stripping a `provider/` prefix (`anthropic/claude-haiku-5-5` is `mid`). Rungs are separate from the frontier/smart tiers in `lib/model-catalog.ts`, which choose which model runs a role. |
| Loadout | `{ base, exclude, include, preamble_tier_max, note }`. `full` (include `*`) is always present. An unknown model gets `default.unknown`, which is `full`. |
@@ -17,7 +18,7 @@ One model has its own loadout: Claude Opus 5.5 gets `lite` ([below](#lite-on-cla
## Commands
```bash
bin/gstack-modules list [--json] [--pinned] # every module id, kind, source, pin, source bytes and sha256
bin/gstack-modules list [--json] [--pinned] # every module id, kind, source, pin or cut status, source bytes and sha256
bin/gstack-modules validate # check modules/loadouts.json against the catalog
bin/gstack-modules render --host claude --loadout full --out-dir ~/arms/control
bin/gstack-modules render --host claude \
@@ -81,6 +82,10 @@ When `GSTACK_MODEL` is set to a different model, it adds `LOADOUT_MISMATCH`. A p
`./setup --loadout lite` saves `claude_loadout` and renders the Claude skills into the untracked render dir (`<state root>/render/claude`) through setup's own render, the same path a pinned overlay or `plan_mode_preamble=off` takes, so later upgrades and `gstack-config gbrain-refresh` keep it. `./setup --loadout full` returns to the committed files. A plain `./setup` never selects lite.
## Cuts
A loadout removes modules for some models. A cut removes a piece from one skill for every model. `modules/cuts.json` lists each cut with the skill, the file it came from, the text that marks it in a generated SKILL.md, why it was cut and its evidence. It also pins each targeted skill's always-loaded bytes, which are its Claude `SKILL.md` with the frontmatter included. A cut with `preamble_piece` drops that preamble piece for its skill alone. Every other cut was deleted from the skill's template. `test/cut-ledger.test.ts` fails when a cut's text reappears in the skill or its sections on any host, when a pin moves, or when a cut names a skill other than /investigate and /review. Its message names the file, the ledger entry and the fix. Restoring a cut or raising a pin needs a measurement and Garry's approval through GStack Minder. Lowering a pin needs no approval. GST-1088 cut /investigate's and /review's learnings search and capture, /investigate's investigation log, and /review's repo-ownership preamble and queue-status step. The cut PR stays open until the GST-1089 no-loss replay passes.
## Changing a loadout
Add or edit an entry under `loadouts` (and `models`, for a model-specific one) and cite the measurement (preregistration, margin, per-rung result) in its `note` and in the PR body. A model-specific loadout that wins a preregistered comparison is allowed even if it breaks the expected nesting (light ⊇ mid ⊇ strong). Committed SKILL.md files are always the `full` render, so the parity suite, the SKILL.md size guard, the size ledger and the catalog and context budgets keep measuring `full`.
+2
View File
@@ -633,6 +633,8 @@ One exception: a shortcut you took deliberately and logged. A `gstack-shortcut(d
**PR type.** The checklist starts by naming the kind of PR from the changed paths: docs-only, CI/infra, scripts/tooling, application or mixed, and the review's first line says which (`PR type: <type>`). Application and mixed diffs run every category as before. A CI/infra, scripts/tooling or docs-only diff always gets Gate Integrity, Shell Injection, Completeness Gaps, Distribution & CI/CD Pipeline and Repo Conventions & Platform Fit; every other category with nothing to check is listed once, in one line, as not applicable, and never counts as passed. Repo Conventions & Platform Fit flags new files that don't match the languages and tools the repo already uses or the platforms its CI runs on, such as a `.bat` build script in a bash-and-Makefile repo.
**Blocker proof.** A CRITICAL finding has to prove itself. It names its floor reason (it fails a test, breaks production, loses data or secrets, or falls in a forced-CRITICAL class) and carries a repro, a failing test, or a cited `file:line` with its consequence. When a specialist, QA, the adversarial pass or a bot forwards a CRITICAL, `/review` checks it and adds both itself. A CRITICAL nobody proves is reported as INFORMATIONAL. The floor itself is defined in [the review policy](review-policy.md#the-blocking-floor).
### Example
Suppose the smart listing flow is implemented and the tests are green.
+2 -2
View File
@@ -6524,7 +6524,7 @@ These codes come from `bin/gstack-modules` and `gen-skill-docs --loadout/--modul
<a id="loadouts-invalid"></a>
### `LOADOUTS_INVALID: modules/loadouts.json …`
**Meaning.** `modules/loadouts.json` is unreadable, or names a module, base loadout, rung or default that does not exist, excludes a pinned module, or maps one model id to two rungs. **Fix.** Correct the named entries, then run `bin/gstack-modules validate` until it prints `LOADOUTS: ok`; `git checkout -- modules/loadouts.json` restores the committed file.
**Meaning.** `modules/loadouts.json` is unreadable, or names a module, base loadout, rung or default that does not exist, names a cut module (a `part:<skill>/<name>` id from `modules/cuts.json`), excludes a pinned module, or maps one model id to two rungs. **Fix.** Correct the named entries, then run `bin/gstack-modules validate` until it prints `LOADOUTS: ok`; `git checkout -- modules/loadouts.json` restores the committed file.
<a id="loadout-unknown"></a>
### `LOADOUT_UNKNOWN: "<name>" is not a loadout (valid: …)`
@@ -6549,7 +6549,7 @@ These codes come from `bin/gstack-modules` and `gen-skill-docs --loadout/--modul
<a id="module-spec-invalid"></a>
### `MODULE_SPEC_INVALID: …`
**Meaning.** A `--modules` token is not `-<module id>` or `+<module id>`, both `--loadout` and `--modules` were given, `gen:skill-docs` got a selection with exclusions but no `--out-dir`, or a render flag is missing or malformed. **Fix.** Write the spec as `<loadout>,-<id>,+<id>` (for example `full,-section:office-hours/second-opinion`) and pass the flags `bin/gstack-modules --help` lists.
**Meaning.** A `--modules` token is not `-<module id>` or `+<module id>`, a token names a cut (a `part:<skill>/<name>` id, removed in every loadout by `modules/cuts.json`; drop it from the spec), both `--loadout` and `--modules` were given, `gen:skill-docs` got a selection with exclusions but no `--out-dir`, or a render flag is missing or malformed. **Fix.** Write the spec as `<loadout>,-<id>,+<id>` (for example `full,-section:office-hours/second-opinion`) and pass the flags `bin/gstack-modules --help` lists.
<a id="module-unknown"></a>
### `MODULE_UNKNOWN: "<id>" is not a module`