From a412a923857105fd34c1551a0c2d9157679324c7 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 13 Sep 2026 08:48:16 +0000 Subject: [PATCH] docs(tooling): reserve --rewrite-governed-file by its condition, not by actor `check-upstream-port-parity.mjs`'s usage header reserved the flag for "the human merging it". The reservation's real target is a SILENT rewrite of a governed file from another repository's bytes, and that hazard is decidable before the run: compute each upstream digest independently first and require it to equal what the pin will hold afterwards. Stated as an actor, the rule had to be re-ruled per card; stated as a condition it is falsifiable, and a digest mismatch is loud. Restate it in all four places the file addressed the actor: - the usage header, keeping the comment column; - the `## --resync REFUSES to rewrite governed surface` prose, which repeated the actor framing, plus the worked example the ruling names: on PR #9300 every re-synced file came back byte-identical and every new `upstreamSha256` had been shown to equal the sha256 of `git show origin/main:PATH` taken in the objectstack checkout before the run; - the doc comment on `RESYNC_GOVERNED_FLAG`; - the refusal's own instruction line, which now asks for the proof first and keeps the merging human as the fallback. No behaviour change: the gating predicate (`resyncWriteVerdict`), the governed set it borrows from `check-governed-queue-guard.mjs`, the pin ledger and every pinned copy are untouched. The self-test's assertions on the refusal text (path, flag, matched surface, "drifted governed port reds this gate") all still hold: 58 cases pass, and the live verify still reports 11 ported files at their own refs. Claude-Session: https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8 Co-authored-by: Claude --- scripts/check-upstream-port-parity.mjs | 35 ++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/scripts/check-upstream-port-parity.mjs b/scripts/check-upstream-port-parity.mjs index 81c844a64a..9d3e9a313f 100644 --- a/scripts/check-upstream-port-parity.mjs +++ b/scripts/check-upstream-port-parity.mjs @@ -10,8 +10,10 @@ * node scripts/check-upstream-port-parity.mjs --resync --ref * # the deliberate re-sync act * …the same, plus --rewrite-governed-file # …when the ported file is - * # GOVERNED SURFACE and you are - * # the human merging it + * # GOVERNED SURFACE — for whoever + * # can PROVE the re-sync + * # content-neutral BEFOREHAND, and + * # for the merging human otherwise * * ## What this gate is for * @@ -126,8 +128,23 @@ * So the write path asks `check-governed-queue-guard.mjs` — the repository's own * definition of that surface, reused rather than re-listed, so the two can never * disagree — and refuses, naming the path, its surface and the flag that - * proceeds anyway. `--rewrite-governed-file` is spelled long on purpose: it is - * for the human doing the merge, and it reads as what it does at the call site. + * proceeds anyway. `--rewrite-governed-file` is spelled long on purpose: it + * reads as what it does at the call site, and it is typed by whoever can PROVE + * the re-sync content-neutral beforehand — digests computed independently + * before the run, equal to what the pin holds after it — and by the merging + * human otherwise. + * + * The worked example is PR #9300: six pinned hook entries had drifted, the + * gate's own `--resync` was the required act, and before it ran every new + * `upstreamSha256` was shown to equal the sha256 of `git show origin/main:PATH` + * taken in the objectstack checkout. Every re-synced file then came back + * byte-identical to the committed one, so the rewrite moved no governed byte — + * which is the whole content of the permission. ⛔ The same digests computed + * AFTERWARDS do not qualify: by then the bytes are written, and a rewrite that + * turns out to have been content-neutral is still a rewrite nobody chose. + * What the reservation was always aiming at is a SILENT rewrite from another + * repository's bytes, not the identity of the person at the keyboard + * (objectui#9303, ruled 2026-09-13). * * ⛔ The CHECK path is NOT governed by any of this. A drifted governed port reds * exactly like any other, with no flag and no exemption — the refusal is about @@ -360,8 +377,10 @@ function resyncCommand(pin, entry) { } /** - * The flag that lets `--resync` write a GOVERNED file. Long on purpose: it is - * typed by the human doing the merge, and it has to read as what it does. + * The flag that lets `--resync` write a GOVERNED file. Long on purpose: it has + * to read as what it does at the call site. It is typed by whoever can PROVE + * the re-sync content-neutral beforehand, and by the merging human otherwise — + * that condition, and the worked example behind it, are in this file's header. */ export const RESYNC_GOVERNED_FLAG = '--rewrite-governed-file'; @@ -400,7 +419,9 @@ export function resyncWriteVerdict(portedPath, { allowGoverned = false } = {}) { `A re-sync would replace it with another repository's bytes, which is a governed-surface`, `edit nobody chose. The pin is unchanged and nothing was written.`, ` • To see what a re-sync WOULD do, diff the upstream file against this one by hand.`, - ` • To do it anyway — as the human doing that merge — pass ${RESYNC_GOVERNED_FLAG}.`, + ` • To do it anyway, PROVE it content-neutral FIRST: compute the upstream digest`, + ` independently and require it to equal what the pin will hold afterwards. With`, + ` that proof — or as the merging human — pass ${RESYNC_GOVERNED_FLAG}.`, ` • Registering this file in the pin is NOT affected: checking is not writing, and a`, ` drifted governed port reds this gate with no flag and no exemption.`, ],