diff --git a/docs/pregate.md b/docs/pregate.md
index 6e9e4f0e0..42a336c8c 100644
--- a/docs/pregate.md
+++ b/docs/pregate.md
@@ -63,6 +63,7 @@ the byte-pinned `/ship` renders in `test/fixtures/golden/`).
| `selection` | `workflow.yml/job` → a command printing the lane's file list, for matrices a planner computes (gstack: `scripts/test-free-shards.ts --list`) |
| `warn` | check ids downgraded to warn; `secrets` and required lanes never |
| `strays.allow` | intentional root files or new top-level directories |
+| `local` | `workflow.yml/job` lanes a local run satisfies: a platform-agnostic toolchain (an `ubuntu-latest` suite that runs the same on a Mac), or a repo whose CI is off. Their tests run here instead of becoming `requires-remote` |
| `guards` | `[{ id, when: [globs], command, fix?, timeout_s? }]`: repo commands a lane must pass when a touched file matches `when` (manifest checks, subprocess goldens the import graph cannot see); see [guards](#guards) |
| `serial_patterns` | test-file globs the `lanes` check runs one process per file, apart from the unit files (default `**/*.serial.test.*`) |
| `sealed` | sealed or eval output that must never reach a public destination; read by the pre-push hook and `gstack-pregate sealed` (see [sealed output](#sealed)) |
@@ -71,7 +72,16 @@ the byte-pinned `/ship` renders in `test/fixtures/golden/`).
| `remote_gate` | the repo's remote test gate command; under 8 cores the local test tier becomes a `requires-remote` obligation naming it, and `--remote` runs it (see [remote gate](#remote-gate)) |
Only the `origin/` copy is honoured, so a downgrade is reviewed before it
-takes effect. `gstack-pregate validate` / `init` cover the working-tree file.
+takes effect. A repo that keeps `.gstack/` out of git (a shared repo where gstack
+is one contributor's tool) can hold the same file at
+`/projects//pregate.json`. It is read only when the base
+carries none (never under `--policy-from head`), it lives outside the repository
+so a PR still cannot reach it, and the record names it (`policy user `).
+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.
+`gstack-pregate validate` / `init` cover the working-tree file.
## `gstack-pregate`
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index d802e845b..269efc2a6 100644
--- a/docs/troubleshooting.md
+++ b/docs/troubleshooting.md
@@ -2751,7 +2751,10 @@ or `REALITY: surface-check finding bun upgrade --version absent on 1.3.14 bin/gs
Both tools read their pin file (`.gstack/generated.json`, `.gstack/pregate.json`)
from `origin/`, never the working tree, and run repo-declared commands only
-under `--allow-repo-commands` or inside `/ship`. Details: docs/pregate.md.
+under `--allow-repo-commands` or inside `/ship`. When the base carries no
+`.gstack/pregate.json`, `gstack-pregate run` reads
+`/projects//pregate.json` instead (outside the repository).
+Details: docs/pregate.md.
### `REGEN_REGISTRY_INVALID`
@@ -2794,10 +2797,14 @@ reference the repository's (gstack's entries do through `bun run`).
**Meaning.** `.gstack/pregate.json` has an unknown key, a wrong type, a glob
that escapes the repository, a runner without `{files}`, or `secrets` in `warn`.
+The user-owned `/projects//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.
**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.
+base branch's copy. For the user-owned file, edit it directly at the path the
+message names.
### `PREGATE_SECRETS`