mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-09 18:28:15 +01:00
docs(pregate): CHANGELOG entry for #3286 and the link-chain and dangling-parent rules
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
393b60cae9
commit
0ade4b5f5a
3 files changed
+31
-7
No files matched your search
@@ -22,6 +22,25 @@
|
||||
- No threshold, budget, timeout, trial count or case kind changed. Pregate's lanes now map and run tests for `.rs` files that previously failed closed with "no test lane", and nested vitest/jest packages run under their own runner instead of `bun test`. A `.rs` file outside any crate, a crate with no tests, and a missing cargo or package manager still fail closed or stay incomplete; the tests above cover each.
|
||||
- No new dependency (Cargo.toml is parsed with Bun's built-in TOML parser), no network call in pregate itself, no workflow change. As with the root runner detection on main (`npx vitest run`), a nested package's detected runner (`npx`, `bun x`) may fetch a missing tool when it runs under `--allow-repo-commands`.
|
||||
|
||||
**A repo that keeps `.gstack/` out of git can give pregate a policy, and name the CI lanes a local run satisfies (#3286).** On a shared repo where gstack is one contributor's tool, pregate fell back to defaults, so every platform lane the machine could not run (an `ubuntu-latest` suite on a Mac, say) became a `requires-remote` obligation that never cleared, even when that suite runs the same here. Ported from #3286 by arlophoenix, whose 13 commits carry the feature (merged with their history kept); our commits on top close two findings from a security-focused review of the port.
|
||||
|
||||
### Added
|
||||
- **`lib/pregate/context.ts`, `lib/pregate/config.ts`** (arlophoenix): when the base branch carries no `.gstack/pregate.json`, `gstack-pregate run` reads `<state root>/projects/<slug>/pregate.json`. Never under `--policy-from head`, never a relative path or one inside the checkout, and never chosen by a checkout's `.env` (the bin ignores it, and a bare `bun gstack-pregate` beside one refuses). An unreadable file, a dangling link on its path, `sealed` or `price_file` refuses with `PREGATE_CONFIG_INVALID`; a base copy git cannot read refuses with `POLICY_SOURCE_UNAVAILABLE` unless `git ls-tree` confirms it is absent.
|
||||
- **`local`** (arlophoenix): `<workflow.yml>/<job>` lanes a local run satisfies run here instead of becoming `requires-remote`. Under 8 cores with a `remote_gate` or remote `test_backend`, the small-machine obligation still stands.
|
||||
- **`lib/pregate/index.ts`** (arlophoenix): the record names the user file and its digest, and `verify` goes `PREGATE_STALE` when it is edited, deleted, or appears after a run under the defaults. Fix texts for missing lanes, strays, stalls and `remote_gate` name the active policy file.
|
||||
|
||||
### Fixed
|
||||
- **`lib/pregate/context.ts`**: a user policy whose path reaches the checkout through any symlink is ignored. Before, only the lexical path and the final target were checked, so a state root linked into the checkout, holding a link back out to another existing policy, let a branch choose a more permissive file without changing its bytes.
|
||||
- **`lib/pregate/index.ts`**: `verify` goes `PREGATE_STALE` when a link on the way to the absent user path starts pointing nowhere. A fresh run refuses that state, but verify looked only at the leaf, so an old defaults pass stayed publishable. The loader and verify now share one absence check.
|
||||
|
||||
### Tests
|
||||
- `test/pregate-user-policy.test.ts` (new, arlophoenix) covers the user file, `local`, the refusals, `.env` isolation and stale receipts. New cases: a link chain through the checkout is refused for both a linked state root and a single in-repo hop, while a direct outside link is still read; and verify goes stale on a dangling parent, with the plain-absent path as the control.
|
||||
- `test/pregate-rust.test.ts`: the two cargo-lane cases skipped on Windows carry a `TODO(#3380)` naming the gap.
|
||||
|
||||
### Gate integrity
|
||||
- No threshold, budget, timeout, trial count, case kind or skip changed. The user file can relax lanes only where the base has no policy at all, and only from outside the repository; the two fixes make that containment stricter.
|
||||
- No new dependency, no network call, no workflow change.
|
||||
|
||||
## [1.91.186.0] - 2026-10-24
|
||||
|
||||
**Approving an autoplan run no longer fails one time in ten because its run id looks like a card number.** Today's daily flaky-fix pass found `test/capy-captain-flow.test.ts` failing once and passing on the serial retry in 7 of the 57 Free Tests runs from 2026-10-21 to 2026-10-23, one of them a push to main (39878113535). Every failure had the same assertion: `gstack-approvals import` refused the approval row with "field ask: pii.cc". The default autoplan run id is `run-YYYYMMDDHHMMSS`, the import writes it into the row's ask and source, and the credit-card rule saw those 14 digits as a card number whenever they passed the Luhn check, which a timestamp does about one time in ten. A real user's approval import failed the same way.
|
||||
|
||||
+6
-3
@@ -85,9 +85,12 @@ else a gstack plugin's data directory, else `~/.gstack` ([docs/state-root.md](st
|
||||
(never under `--policy-from head`), it lives outside the repository so a PR still
|
||||
cannot reach it, and the record names it (`policy user <path>`) and fingerprints
|
||||
its bytes (`policy_digest`, and each check's `inputs.policy`); `verify` and the
|
||||
ship receipt treat an edited or deleted user file, or one that appears after a
|
||||
run under the defaults, as `PREGATE_STALE`. A path that is relative or resolves
|
||||
inside the repository is ignored, since a PR could commit it; `--explain` says
|
||||
ship receipt treat an edited or deleted user file, or one that appears (or a
|
||||
link on its path that starts pointing nowhere) after a run under the defaults,
|
||||
as `PREGATE_STALE`. A path that is relative, resolves inside the repository, or
|
||||
reaches it through any symlink on the way (a state root linked into the
|
||||
checkout, or a link hop inside it, even when the last hop points back outside)
|
||||
is ignored, since a PR could commit it or choose the file; `--explain` says
|
||||
so, or says `(absent)` when no file is there. The slug and state root come from
|
||||
the caller's environment, never the checkout's `.env`: the bin's shebang passes
|
||||
`--no-env-file`, and a bare `bun gstack-pregate` launched beside any `.env` file
|
||||
|
||||
@@ -2947,8 +2947,9 @@ or exists but cannot be read (a dangling symlink on its path counts).
|
||||
**Fix.** `gstack-pregate validate`. `secrets` and required-lane obligations
|
||||
cannot be downgraded; every other check id in `warn` is honoured only from the
|
||||
base branch's copy or the user-owned file. For the user-owned file, edit it
|
||||
directly at the path the message names. A user file inside the repository is
|
||||
ignored rather than read (`--explain` names it).
|
||||
directly at the path the message names. A user file inside the repository, or
|
||||
reached through a symlink into it, is ignored rather than read (`--explain`
|
||||
names it).
|
||||
|
||||
<a id="pregate-secrets"></a>
|
||||
### `PREGATE_SECRETS`
|
||||
@@ -3061,8 +3062,9 @@ file with `--receipt`, or let `gstack-pregate --stage tests --remote --spend-cap
|
||||
|
||||
**Meaning.** `pregate.json` was recorded against a different working-tree
|
||||
fingerprint than the one being published (the final stamp, a regen, any edit),
|
||||
or the user-owned policy it ran under was edited or deleted (or one appeared
|
||||
after a run under the defaults).
|
||||
or the user-owned policy it ran under was edited or deleted (or one appeared,
|
||||
or a symlink on its path started pointing nowhere, after a run under the
|
||||
defaults).
|
||||
|
||||
**Fix.** Rerun `gstack-pregate` after the final generation and stamp; Step 18
|
||||
refuses to write the ship receipt otherwise.
|
||||
|
||||
Reference in new issue
Block a user