From e449da89d3035edfa8cffd687e8a4b8f3b977d19 Mon Sep 17 00:00:00 2001 From: garrytan Date: Tue, 3 Nov 2026 19:04:59 +0000 Subject: [PATCH] docs: review key row, review_depth receipt fields, executable and egress classing (GSTA-258 L7 Addendum 2, GST-1177) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- docs/review-policy.md | 8 ++++++-- docs/ship-policy.md | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/review-policy.md b/docs/review-policy.md index 31e24a4b9..335a54795 100644 --- a/docs/review-policy.md +++ b/docs/review-policy.md @@ -210,7 +210,9 @@ content rules: data and config files (JSON, YAML, TOML, CSV and the like) and an scripts under `docs/`, `results/`, `benchmarks/`, `analysis/` or `notebooks/` are judged by their path, so a `lease_usd` value or an `os.path.join(sys.argv[1], …)` in a stats script names no class (HARN-1, harness-evals#231), and binary data such as -`*.sqlite` is data wherever it sits; a docs line that can print a credential (an +`*.sqlite` is data wherever it sits, unless the file has the exec bit or starts with +`#!`: an executable stays code whatever its name or directory (`scripts/logs/prune`, +a runnable `*.out`); a docs line that can print a credential (an `Authorization:` header, a bearer or key-shaped value, an environment key set to a value, a get or show command for auth config such as `mcp get`) is security (gbrain#8417); code that reserves, binds, leases or settles spend against a ledger, budget or cap (`bindCheck(ledger, …)`, @@ -281,7 +283,9 @@ pairs: usage beside a token or cost word, proxy beside billing, and a client beside a cost or charge word, so a CLI's usage text and a plain proxy stay out (GST-850, from gbrain-evals #289, whose metering proxy and billing clients read `required=none`). **security** is a trust-boundary path (trust, redact, sanitize, neutralize, -consent, escape) or line (`shell: true`, `exec(` and `execSync(`, `eval`, `new Function(`, +consent, escape, and sealed custody or egress: seal, sealed, custody, egress) or line (a +redaction call, an import of a redaction or outside-voice module, a `SECRET` or `CREDENTIAL` +constant set to a regex, since that code decides what reaches an outside model, GST-1177; `shell: true`, `exec(` and `execSync(`, `eval`, `new Function(`, raw HTML sinks, a shell run through argv, recursive deletes), any call to an outbound HTTP client (`fetch`, `http(s).get` or `.request`, axios, got, undici, `requests`, `httpx`, urllib, with no exemption for a literal URL), `new URL` from diff --git a/docs/ship-policy.md b/docs/ship-policy.md index f611346eb..e89310487 100644 --- a/docs/ship-policy.md +++ b/docs/ship-policy.md @@ -60,6 +60,7 @@ refuses the file (`POLICY_GSTACK_TOO_OLD`). `validate` ends with | `full_e2e` | `true` \| `false` | `false` | `true`: every merge needs a passing full-gate result bound to a tree equal to the merging one modulo stamps; `gstack-ship-queue ready`, `stamp` and `verify` refuse without one (`QUEUE_GATE_MISSING`): a gate-ahead record, or the lane's `--gate-exit 0 --gate-log ` from its run on the gated head. Needs `min_gstack_version`. | | `review_scope` | `frozen` \| `diff-plus-blocking` \| `all` | `frozen` | The finding scope of `/ship`'s review loop; see [review_scope](#review-scope). `frozen` fixes the diff on pass 1, files blocking findings in unchanged code as issues, and later passes read only the range since the previous pass. `diff-plus-blocking` is the same but fixes a blocking finding in unchanged code in this PR instead of filing it. `all` is the earlier loop: every finding is fixed on every pass. Needs `min_gstack_version` when not `frozen`. | | `review_exclude_paths` | git glob pathspecs | `[]` | Content files `/ship`'s reviewers leave out: data, docs, `.log`, and binaries under a content extension (images, fonts, archives and the like) that do not start with executable magic. Read from the base only. Code (native libraries and every other binary outside the content extensions included), gate paths, agent prose, config, executables, links, `.gstack/` and `.github/` files, gate-tagged, secret-line and named-by-code files stay in review. See [review_exclude_paths](#review-exclude-paths). Needs `min_gstack_version`. | +| `review` | `{ panel?, reader_model?, platform?, risk_paths? }` | `{ all, lane, off, [] }` | Who does `/ship`'s review, read from the base only; see [Who reads](review-policy.md#who-reads-r65-the-base-policys-review-key). `panel`: `all` (today's panel on every class) \| `risk` \| `off` (the opt-in one-reader shapes); `reader_model`: `lane`, `cross-family` or a model id; `platform`: `off` \| `on` (a docs or tests diff with no numeric, results or prereg claims whose PR carries capy-ai[bot]'s review at the exact head skips the readers); `risk_paths`: globs of code paths that count as risk class `policy`. Introduced at 1.94.30.0; needs `min_gstack_version` when set to a non-default value. | | `min_gstack_version` | version or `null` | `null` | The oldest gstack that may read the file; see the compatibility rule above. | | `docs` | `{ caps: [{ path, max_bytes }] }` or `null` | `null` | Documentation files with a byte cap. `/ship` Step 14.5 runs `gstack-ship-receipt docs-caps --base ` (the caps come from `origin/`'s policy, never the branch's copy; `--policy ` is for a repository bootstrapping its policy) before the verification gate and prints one `DOCS_CAP: / ok\|over` line per cap; any `over` (an absent file counts) exits 1 and blocks the ship until the file is trimmed or the cap raised on the base branch (`DOCS_AUDIT_BLOCKED`). At most 64 caps, each path contained. See [the ship receipt](#ship-receipt). Needs `min_gstack_version`. | | `train` | `{ gate_workflow, free_workflow, full_gate_check, record_artifact, max_size, fill_hours, screen_selection, trial_reservation_usd, land? }`, `{ gates, land, max_size, fill_hours }` or `null` | `null` | Turns on [merge trains](#run-a-merge-train), read from the base revision only. Every field is required and an unknown field is `POLICY_INVALID`: `max_size` 1 to 6, `fill_hours` above 0 and at most 24, `screen_selection` `gstack-paid` \| `none`, `trial_reservation_usd` above 0 and at most 100. A block with `gates` ([any repository](#train-gates)) takes `max_size` 1 to 5 and needs `min_gstack_version` at least `TRAIN_GATES_KEY_VERSION`. `null` keeps the per-PR queue exactly as it is. Needs `min_gstack_version`. | @@ -1188,7 +1189,8 @@ repair is trimming the file, never raising the cap in the same PR. **`review_depth` and `gstack_version`.** `write` records the gstack that wrote the receipt and the review depth at the checked-out head ([review-policy.md#review-depth](review-policy.md#review-depth)): -`{ depth, class, runtime_lines, rules, base, registry, gate_scan: { tagged, head }, reasons }`, +`{ depth, class, runtime_lines, rules, base, registry, gate_scan: { tagged, head }, reasons, risk, mode }` +(`mode` is lean, panel or platform; `declared` and `detected` appear with `write --declare-risk`, and the platform depth adds `platform_review`, see [review-policy.md](review-policy.md#review-depth)), computed from git objects for the range against `origin/` (`gstack-diff-scope --head ` for the scope signals), with the gate scan run on that head. `--head` must be the checked-out HEAD