Repository navigation
Commit ec00b53
fix(pm): the proxy re-exec guard is the caller's name, and it speaks when it suppresses (#19170)
Fixes #18989
Clause-②: no
`scripts/pm/check-governed-merges.mjs` carries its own `proxyRearmPlan`
and that plan read ONE
hard-coded guard name — this file's. `scripts/pm/ci-failure.mjs` imports
that plan and set the
same variable on the child it re-execs. So either tool's guard, once
inherited by the other,
answered "already re-armed" for a run that had never re-armed; the
suppressed run then took the
bypassed route and answered 401 Bad credentials on every endpoint, with
no line printed anywhere
to say why. That is the #18939 mechanism in a second plan — the one PR
#18980 does not touch —
and, for the plan itself, one route with two owners.
## What changed, per file
**`scripts/pm/check-governed-merges.mjs`**
- `proxyRearmPlan({ …, guard = PROXY_REARM_GUARD } = {})` — the guard is
the CALLER's name, and
the default stays this file's own, so its own re-exec is unchanged.
- The guarded branch SPEAKS: `hint: true`, `guarded` naming the
suppressor, and a reason naming
the variable to unset, the proxy the request was supposed to take, and
the 401 the silence
would otherwise be read as. It can only fire on the anomaly — a real
re-exec's child carries
the flag in `execArgv` and is answered by the branch above.
- Both live call sites (`rearmProxyOrNull`, and the INCOMPLETE banner's
plan) hand it
`guard: PROXY_REARM_GUARD` explicitly: for a plan another tool imports,
the default is not the
contract.
- `rearmProxyOrNull` now PRINTS the hint instead of returning through
the silent `!rearm.rearm`
line. Both hint branches — an older node, and a guard already set —
previously reached a reader
only through the sweep's INCOMPLETE banner, and only when the
incompleteness was about
attribution; every other mode bypassed the proxy in silence.
**`scripts/pm/ci-failure.mjs`**
- Declares and sets its OWN `OS_CI_FAILURE_PROXY_REARMED`, spelled once,
and hands it to the plan
per call. The re-exec already spawned under that identifier, so the
child now inherits this
tool's name and nobody else's.
- Imports the sibling's spelling as `GOVERNED_MERGES_GUARD`, so the
self-test pins the two apart
against the real constant rather than a hand-copied string: a rename on
either side reds.
## The arm taken: the copy STAYS, and the reason is measured rather than
assumed
The card asks the taker to keep the copy only if the header's stated
verbatim-copy reason still
holds, and to delete it and import the patrol's plan otherwise. Both
halves were measured.
1. **The premise as written is false.** `check-governed-merges.mjs`'s
header states no
verbatim-copy reason, and the plan's own docblock said only "Pure, so
every branch is
offline-testable". The copy-verbatim argument lives in
`check-half-states.mjs` — it is about
copying THAT file into a sibling repo, and it bars the reverse edge, not
this one.
2. **The import is refused by something stronger: it deadlocks the
process.** Measured
2026-09-19 on a throwaway copy of `scripts/` outside the repo (nothing
in the tree under test
was mutated):
| leg | invocation | exit |
|:---|:---|:---|
| control, unmodified | `check-governed-merges.mjs --test AGENTS.md` |
**3** — the GOVERNED verdict |
| plus `import { proxyRearmPlan } from './check-half-states.mjs'` at
module scope | same argv | **13** — "Detected unsettled top-level await
at check-half-states.mjs:10044" |
| plus `const patrol = await import('./check-half-states.mjs')` inside
`selfTest()` | `--self-test` | **13** — unsettled top-level await at
this file's own `await selfTest()` |
The cycle is short and live: `check-half-states.mjs:10044` resolves its
H43 register at module
scope with `await loadGovernedRegister()`, which awaits
`import('./check-governed-queue-guard.mjs')`, which imports THIS file at
module scope. The lazy
door that `check-governed-queue-guard.mjs`'s `CONTRACT_REVIEW_LABEL`
describes is shut here too,
because this file's `--self-test` dispatch is itself a module-scope
await. Importing would
therefore not tidy the duplication, it would take
`check:pm-governed-merges` — the governed-surface
instrument in most derived unions — down with it, plus the patrol and
the queue guard.
So the copy stays, and the triage's 「修法若只统一守卫名而不处理副本,下一次分叉照旧发生」 is
answered by
DECLARING it: the plan's docblock names its owner, states both measured
exits, and the self-test
pins the mirror to that owner the way `CONTRACT_REVIEW_LABEL` is pinned
— by reading the owner's
SOURCE off disk (a constant asserting against itself proves nothing),
and by pinning the REASON,
so when the patrol's module-scope await goes away the failing case says
to make this a real import.
Escalation condition re-measured in the worktree: `grep -rn 'function
proxyRearmPlan' scripts/`
returns exactly **2** definitions (`check-governed-merges.mjs`,
`check-half-states.mjs`). No third
copy, so the deliverable stayed as graded.
## The A/B — the card's own repro, read-only and offline
`proxyRearmFor(['--pr','9774'], { env: { HTTPS_PROXY, GUARD: '1' } })`
through a harness that
imports the module (no dispatch, no socket, no argv). Leg A is the base
files restored with
`git checkout HEAD~1 --`, leg B this branch; the restore was verified
byte-identical
(`git hash-object` equals the HEAD blob for both files, `git diff HEAD`
empty).
| guard set in the environment | base (leg A) | this branch (leg B) |
|:---|:---|:---|
| none | `rearm: true` | `rearm: true` |
| `OS_GOVERNED_MERGES_PROXY_REARMED=1` | **`rearm: false, hint:
false`**, reason "already re-armed once this run" — the silent
cross-suppression | **`rearm: true`** — the sibling's guard no longer
silences this tool |
| `OS_CI_FAILURE_PROXY_REARMED=1` | (did not exist) | `rearm: false,
hint: true, guarded: OS_CI_FAILURE_PROXY_REARMED`, reason naming the
variable, the proxy and the 401 |
| `OS_HALF_STATES_PROXY_REARMED=1` | — | `rearm: true` — the patrol's
name is inert here too |
Leg A is the defect exactly as filed: a tool that never re-armed, told
it had, printing nothing.
## Self-tests: both directions, both sides
| reading | before | after |
|:---|:---|:---|
| `check-governed-merges.mjs --self-test` | 392 assertions, exit 0 |
**410** assertions, exit 0 |
| its battery roster / pinned roster size | 28 batteries | **29** (new:
the #18989 guard set, floor 18) |
| `ci-failure.mjs --self-test` | exit 0 | exit 0 |
| its `proxyRearmFor: the transport trap` battery | floor 7 | **floor
17** |
The ci-failure count is measured, not asserted: with that floor mutated
17 to 18 through
`scripts/ablation-replace.mjs`, the run reds with "registered 17
case(s), below its pinned floor
of 18" (exit 1), and the tool restored the file to a blob equal to HEAD
with `git diff HEAD`
empty. A first attempt at that probe passed the wrong flags, printed
usage and exited 0 without
mutating anything — a no-op reading, discarded and re-run rather than
believed.
## Gates
Derived in the worktree with `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack
--commands` (the script takes the change set itself; the derivation
names the repo and commit
`d904ab5`) — 32 families, all 32 run, every exit code captured before
any pipe. Reconciled with
`--ran`: "32 derived famil(ies) accounted for — 32 run, 0 NOT-MEASURED
(a DERIVED zero — all 32
recorded an exit code and none of them is 3)". **Every one exited 0**,
including
`pnpm check:pm-governed-merges` (this file's own self-test, 410
assertions), `ci-failure.mjs
--self-test`, `check-self-test-wired`,
`check-self-test-workflow-commands`,
`check-scripts-symbol-anchors`, `check-declaration-mirrors` and
`check:nul-bytes`.
`pnpm check:pm-dispatch-gates` took **1025.1s** on this box (1866 cases
pass) — well past the
430-450s the dispatch estimated, worth knowing for anyone budgeting a
foreground run while other
agents share the container.
Repo-wide sweeps (`pnpm lint` and the rest of the farm) are CI's run,
not this branch's. A scan
for control bytes over both files (`grep -naP` over the C0 set plus DEL)
exits 1 with no hits.
## Acceptance notes
- Noted, not filed: the mirror's route check accepts only the flag in
`execArgv` / `NODE_OPTIONS`,
while its owner also accepts `NODE_USE_ENV_PROXY=1`. A run already
routed by the env spelling
therefore re-execs once needlessly here — a spent process, never a wrong
verdict — so it is a
mirror divergence rather than a defect class. Whoever next edits either
plan meets it: the new
battery names the owner and reads its source, which is where the
divergence is now visible.
- Not touched, by dispatch: `testVerdict`, `landsByHumanMerge`, the size
limb and the post-merge
default-mode listing of `check-governed-merges.mjs` are #19036's region.
Every hunk here is in
the proxy plan, its constants, its two call sites and the self-test
batteries.
- `skip-changeset`: `scripts/pm/**` is published by no package's
`files[]`.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01W5y9kRg1YtYaMQYExVLRc2)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent fe36a40 commit ec00b53
2 files changed
Lines changed: 254 additions & 8 deletions
0 commit comments