mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-05 00:03:15 +01:00
docs(pregate): the active policy may be the user-owned file; new refusals
Guards, remote_gate, stall timeouts and lane fixes name the user-owned file when it is the active policy; the trust boundary says run alone reads it; the dangling-symlink and unreadable-base-copy refusals are documented, and state-root lists the bucket's pregate.json. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4cfe49fd94
commit
dfb7092e7b
3 files changed
+27
-14
No files matched your search
+14
-8
@@ -19,7 +19,8 @@ Three bins, all over `lib/`:
|
||||
|
||||
A pin file names commands. Its presence never authorizes execution: both tools
|
||||
read the committed copy on `origin/<base>` (a PR cannot smuggle a command into
|
||||
its own gate) and run commands only with `--allow-repo-commands`, which `/ship`
|
||||
its own gate; `gstack-pregate run` alone also reads a user-owned file outside
|
||||
the repository when the base has none, see [pregate v1](#pregate-v1)) and run commands only with `--allow-repo-commands`, which `/ship`
|
||||
passes. Standalone, `gstack-regen check` lists the commands and exits 3
|
||||
(`REPO_COMMANDS_NOT_ALLOWED`); `gstack-pregate` marks `regen` and `lanes`
|
||||
`incomplete`, never `pass`. `--policy-from head` (a PR that introduces or
|
||||
@@ -89,7 +90,10 @@ so, or says `(absent)` when no file is there.
|
||||
It covers `gstack-pregate run` only: `sealed` and `price_file` are read from the
|
||||
base branch's copy, so the user file refuses them (`PREGATE_CONFIG_INVALID`)
|
||||
rather than holding a policy nothing reads. A user file that exists but cannot
|
||||
be read refuses the same way instead of falling back to defaults.
|
||||
be read, or a symlink on its path that points nowhere, refuses the same way
|
||||
instead of falling back to defaults. A base copy git cannot read (and
|
||||
`git ls-tree` cannot confirm is absent) refuses with `POLICY_SOURCE_UNAVAILABLE`
|
||||
instead of handing the run to the user file.
|
||||
`gstack-pregate validate` / `init` cover the working-tree file.
|
||||
|
||||
## `gstack-pregate`
|
||||
@@ -123,13 +127,15 @@ Two stages with separate clocks, both printed:
|
||||
`TIMING_ASSERTIONS: found=<n> escaped=<n> files=<n>` summary. It warns
|
||||
(`PREGATE_TIMING_ASSERTION`); it does not block. See [timing](#timing).
|
||||
|
||||
- `guards`: each guard in `.gstack/pregate.json` whose `when` globs match a
|
||||
- `guards`: each guard in the active policy (`.gstack/pregate.json`, or the
|
||||
user-owned file) whose `when` globs match a
|
||||
touched file (renames included) runs its `command` in its own process, under
|
||||
the verified launch Bun, with its own `timeout_s` (default `--timeout`). A
|
||||
non-zero exit fails pregate naming the guard and its `fix`
|
||||
(`PREGATE_GUARD_FAILED`); a timeout is `incomplete`; without
|
||||
`--allow-repo-commands` the selected guards are listed and the check is
|
||||
`incomplete`. Guards are read from the base branch's copy and cannot be
|
||||
`incomplete`. Guards are read from the base branch's copy (or the
|
||||
user-owned file when the base carries none) and cannot be
|
||||
downgraded to warn. See [guards](#guards).
|
||||
|
||||
**Stage 2, test execution:**
|
||||
@@ -150,7 +156,7 @@ Two stages with separate clocks, both printed:
|
||||
`set -o pipefail`, judged on the runner's summary line (zero tests ran is a
|
||||
failure, a `| tail`-hidden exit is still an exit); a platform lane this
|
||||
machine cannot run becomes a `requires-remote` obligation naming
|
||||
`workflow.yml/job`. `--explain` prints each test's provenance and every
|
||||
`workflow.yml/job`, unless `local` names that lane. `--explain` prints each test's provenance and every
|
||||
uncertain mapping (a planner-computed matrix without a `selection` manifest
|
||||
selects conservatively). Test files matching `serial_patterns` (default
|
||||
`**/*.serial.test.*`) run one process per file after the unit files. The
|
||||
@@ -163,7 +169,7 @@ Two stages with separate clocks, both printed:
|
||||
runner process (the unit-file group, each serial file, each guard without
|
||||
its own `timeout_s`), not their total; the stall timeout catches a hung or
|
||||
silent one sooner.
|
||||
- Under 8 cores, a base-branch `remote_gate` or a remote `test_backend`
|
||||
- Under 8 cores, a `remote_gate` in the active policy or a remote `test_backend`
|
||||
(`gstack-config set test_backend ubicloud`) records the local test tier as a
|
||||
`requires-remote` obligation instead of running it: see [remote gate](#remote-gate).
|
||||
|
||||
@@ -229,8 +235,8 @@ misses a descendant that was reparented or started detached.
|
||||
<a id="remote-gate"></a>
|
||||
## Small machines and the remote gate
|
||||
|
||||
Under 8 cores (`os.availableParallelism()`), when the base branch's
|
||||
`.gstack/pregate.json` declares `remote_gate` or `gstack-config get
|
||||
Under 8 cores (`os.availableParallelism()`), when the active policy (the
|
||||
base branch's `.gstack/pregate.json`, or the user-owned file) declares `remote_gate` or `gstack-config get
|
||||
test_backend` is not `local`, the lanes check runs nothing locally: it records
|
||||
the selected local files as a `requires-remote` obligation with the command to
|
||||
run, `pregate.json/remote_gate` (the declared command) or
|
||||
|
||||
@@ -104,6 +104,9 @@ lives in `projects/<slug>/`. `bin/gstack-slug` picks the slug from the git
|
||||
and the ssh, https and ssh-with-port spellings of one repository share one.
|
||||
- Without a remote, the project root's directory name is used.
|
||||
|
||||
A bucket can also hold a user-owned `pregate.json` policy, for a repo that keeps
|
||||
`.gstack/` out of git (see [pregate v1](pregate.md#pregate-v1)).
|
||||
|
||||
The first slug gstack resolves in a directory sticks (it is cached under
|
||||
`slug-cache/`), so a project keeps its bucket when it adds a remote later.
|
||||
|
||||
|
||||
+10
-6
@@ -2354,7 +2354,10 @@ file is described in [docs/ship-policy.md](ship-policy.md); the queue flow in
|
||||
**Meaning.** The policy is read from the committed copy on `origin/<base>`,
|
||||
and that ref does not resolve here (a shallow or detached gate checkout, or a
|
||||
fetch that never happened). The tool exits 3 and never falls back to the
|
||||
working-tree file silently.
|
||||
working-tree file silently. For `gstack-pregate` the same refusal covers a base
|
||||
`.gstack/pregate.json` git cannot read (a timeout, an oversized blob, a missing
|
||||
or corrupt object) that `git ls-tree` cannot confirm is absent; it never falls
|
||||
through to the user-owned file.
|
||||
|
||||
**Fix.** `git fetch origin <base> --depth=1`, then rerun. To run against the
|
||||
branch's own file deliberately, pass `--policy-from head --allow-repo-commands`;
|
||||
@@ -2812,7 +2815,7 @@ repository's lockfile), then rerun `gstack-regen check` or the pre-gate.
|
||||
that escapes the repository, a runner without `{files}`, or `secrets` in `warn`.
|
||||
The user-owned `<state root>/projects/<slug>/pregate.json` also refuses when it
|
||||
sets `sealed` or `price_file` (both are read only from the base branch's copy)
|
||||
or exists but cannot be read.
|
||||
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
|
||||
@@ -2859,7 +2862,7 @@ test. An unmapped source or code file still fails. A file under a test
|
||||
directory is not this empty lane.
|
||||
|
||||
**Fix.** Add a test that names the file, or declare its lane (an explicit `[]`
|
||||
for files with no behaviour) under `dependencies` in `.gstack/pregate.json`.
|
||||
for files with no behaviour) under `dependencies` in `.gstack/pregate.json` (or the user-owned file the message names).
|
||||
Other non-Markdown documentation goes in `empty_lanes` on the base branch.
|
||||
`--explain` prints every mapping and why. For a file with no lane it also prints the import
|
||||
specifiers in test files that resolved to no repo file (for example a
|
||||
@@ -2892,7 +2895,7 @@ keep the tree still, then rerun.
|
||||
|
||||
**Meaning.** A test command the lanes check (or a guard, or the `--remote`
|
||||
gate) launched wrote nothing to its log for the stall timeout (default 300 s,
|
||||
`stall_timeout_s` in the base branch's `.gstack/pregate.json`, or
|
||||
`stall_timeout_s` in the base branch's `.gstack/pregate.json` or the user-owned file, or
|
||||
`--stall-timeout`). pregate killed its process group and names the last test
|
||||
file started. The check is incomplete, never pass.
|
||||
|
||||
@@ -3149,8 +3152,9 @@ next `./setup` prints no CRLF warning.
|
||||
<a id="pregate-guard-failed"></a>
|
||||
### `PREGATE_GUARD_FAILED`
|
||||
|
||||
**Meaning.** A guard from the base branch's `.gstack/pregate.json` (a repo
|
||||
command such as a serial-test manifest check or a CLI golden test) matched a
|
||||
**Meaning.** A guard (a repo command such as a serial-test manifest check or a
|
||||
CLI golden test) from the base branch's `.gstack/pregate.json`, or from the
|
||||
user-owned file when the base carries none, matched a
|
||||
file the branch touched and exited non-zero. Guards cover what the import graph
|
||||
cannot see: manifests, subprocess goldens, registries. They cannot be
|
||||
downgraded to warn.
|
||||
|
||||
Reference in new issue
Block a user