mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-03 15:27:56 +01:00
docs(sealed): hex lists count as identifiers; a \u escape always parses (Step 14.5 audit)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
cd1b600969
commit
d5cf2a1c40
2 files changed
+8
-5
No files matched your search
@@ -1,8 +1,8 @@
|
||||
**The sealed guard can now refuse a published record that puts a label next to an identifier.** gstack-evals hides which test units are decoys. Its /ship on garrytan/gstack-evals#99 published a panel where each unit's `stratum`, `tags` and `decoy_set` sat next to its `head`, `tree_sha256`, `plan_bytes` and `files`, values a model under test can compute from its own copy of the work. A model could look itself up and learn it was the decoy. No answer leaked, so `gstack-pregate sealed` said `clear` (GSTA-2, GST-620). The new rule is opt-in. A repo that sets `sealed.label_keys` gets it, and every other repo sees the same output as before, byte for byte.
|
||||
|
||||
### Added
|
||||
- **`sealed.label_keys` and `sealed.identifier_keys` in `.gstack/pregate.json`.** With `label_keys` set, `sealed.label_join` checks every .json, .jsonl, .ndjson, .csv, .tsv and Markdown pipe table a published commit adds, modifies, renames or copies. A record that holds a label field and an identifier (a field matching an `identifier_keys` glob, by default `head`, `*_sha256`, `*_bytes`, `files` and similar names, or any 7 to 64 character hex string, as a value or as the key of an object) is a join. The guard fingerprints each join in memory and compares it with the parent's version of the file, so unchanged rows and reformatting stay clear while a replaced, added or widened row refuses even when the row count stays the same. Findings name the file, the commit and the field names (`keys=stratum,tags,head,plan_bytes`), never the values, on stderr, in `--json` and in the pre-push hook.
|
||||
- **`sealed.label_join_unchecked`.** A file whose text never names a label key, ignoring double quotes, cannot hold a join and is skipped without parsing, so a commented `tsconfig.json` passes. A supported file over 4 MiB, one that names a label key and does not parse, one nested deeper than 64 levels, or a blob git cannot read refuses instead of passing unread. The `SEALED:` line counts these as `unchecked=<n>`. Like every sealed finding, it can be waived through the base branch's `.gstack/sealed-allow.tsv`; `allow_paths` never exempt either rule.
|
||||
- **`sealed.label_keys` and `sealed.identifier_keys` in `.gstack/pregate.json`.** With `label_keys` set, `sealed.label_join` checks every .json, .jsonl, .ndjson, .csv, .tsv and Markdown pipe table a published commit adds, modifies, renames or copies. A record that holds a label field and an identifier (a field matching an `identifier_keys` glob, by default `head`, `*_sha256`, `*_bytes`, `files` and similar names, or any 7 to 64 character hex string, as a value, in a list, or as the key of an object) is a join. The guard fingerprints each join in memory and compares it with the parent's version of the file, so unchanged rows and reformatting stay clear while a replaced, added or widened row refuses even when the row count stays the same. Findings name the file, the commit and the field names (`keys=stratum,tags,head,plan_bytes`), never the values, on stderr, in `--json` and in the pre-push hook.
|
||||
- **`sealed.label_join_unchecked`.** A file whose text never names a label key, ignoring double quotes, cannot hold a join and is skipped without parsing, so a commented `tsconfig.json` passes. A file with a `\u` escape is always parsed. A supported file over 4 MiB, one that names a label key and does not parse, one nested deeper than 64 levels, or a blob git cannot read refuses instead of passing unread. The `SEALED:` line counts these as `unchecked=<n>`. Like every sealed finding, it can be waived through the base branch's `.gstack/sealed-allow.tsv`; `allow_paths` never exempt either rule.
|
||||
- **The policy only tightens.** A field can count as both a label and an identifier, so adding identifier names to `label_keys` never hides a join. Both lists are the union of the base branch's and the pushed policy's, each resolved to its default first, so a pushed config can turn the rule on or widen it but cannot turn it off or narrow it.
|
||||
|
||||
### Changed
|
||||
|
||||
+6
-3
@@ -1006,8 +1006,9 @@ gstack-pregate sealed [--range <a..b>] [--remote origin] [--base <branch>] [--js
|
||||
matches an `identifier_keys` glob (`*` is the only wildcard; the default
|
||||
is `head`, `head_sha`, `sha`, `commit`, `tree`, `tree_sha*`, `*_sha`,
|
||||
`*_sha256`, `sha256`, `digest`, `*_digest`, `hash`, `*_hash`,
|
||||
`*_bytes`, `bytes`, `size`, `files`, `lines`), or any string value of 7
|
||||
to 64 hex characters with at least one digit and one letter a to f. An
|
||||
`*_bytes`, `bytes`, `size`, `files`, `lines`), or any string value (or a
|
||||
list holding one) of 7 to 64 hex characters with at least one digit and
|
||||
one letter a to f. An
|
||||
object key of that shape counts as an identifier of the object it holds
|
||||
(shown as `(key)`), so a map keyed by sha joins too. Numbers count only
|
||||
through the field name. A field can be both a label and an identifier, and
|
||||
@@ -1022,7 +1023,9 @@ gstack-pregate sealed [--range <a..b>] [--remote origin] [--base <branch>] [--js
|
||||
and a replaced, added or widened record refuses even when the count stays
|
||||
the same. A file whose text never names a label key, ignoring double
|
||||
quotes (so `"Strat"um` still names `stratum`), cannot hold a join, so
|
||||
it is skipped without parsing (a commented `tsconfig.json` passes). A
|
||||
it is skipped without parsing (a commented `tsconfig.json` passes). A file
|
||||
with a `\u` escape, which could spell a label key, is always parsed, so a
|
||||
commented one is `sealed.label_join_unchecked`. A
|
||||
supported file over 4 MiB, one that names a label key and does not parse (one bad
|
||||
JSONL line is enough), one nested deeper than 64 levels, or a blob git
|
||||
cannot read is `sealed.label_join_unchecked`. It refuses too, and the
|
||||
|
||||
Reference in new issue
Block a user