Skip to content

Commit ec00b53

Browse files
os-teslaclaude
andauthored
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

File tree

0 commit comments

Comments
 (0)