diff --git a/.changeset/9206-retire-unregistered-rationale.md b/.changeset/9206-retire-unregistered-rationale.md new file mode 100644 index 0000000000..73facda6bd --- /dev/null +++ b/.changeset/9206-retire-unregistered-rationale.md @@ -0,0 +1,31 @@ +--- +--- + +Retire the "not registered in the port pin" rationale for +`scripts/check-bash32-floor.mjs`, in both of the places it was written +(objectui#9206). Prose in a repo-internal gate and in its workflow wiring +comment, plus the two matching divergence pairs in +`scripts/upstream-port-pin.json`; no package source, no published contract and +no gate behaviour is touched, so nothing is released by this change. + +Both copies argued that the file was deliberately unregistered because the +ledger carried ONE repository-wide `upstream.ref` that `--resync` rewrote for +every entry. Neither half is true any more. objectui#8288 retired that field — +`check-upstream-port-parity` now REFUSES a pin that still carries it, and a +re-sync writes only the re-synced entry's own ref and digest — and +objectui#8694 then registered this file at its own ref, with its divergences +declared. So the workflow step a reader consults first, and the port's own +docblock, both explained a decision by naming a mechanism that no longer +exists. + +The workflow comment now states that the file IS registered and where its ref +lives; the docblock's "Why this port is not YET pinned" section is replaced by +a short pointer at the ledger entry, which also records that editing this prose +edits PINNED bytes and must move the matching `ported` side in the same change. + +⛔ No revision is named in either piece of prose, and the previous comment's +revision was dropped rather than refreshed. That is the whole lesson the +section carries: it had already gone stale twice by naming one, and a third +time by arguing from a registration state that had changed underneath it. The +ref lives on the entry in `scripts/upstream-port-pin.json`, beside the digest +it was taken with, where `--resync` keeps it correct. diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4acb42ecde..f8bc8ee2ff 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -303,13 +303,15 @@ jobs: # the other 9 a measurement instead of an assumption, and what stops the # first violation being typed. # - # Ported from objectstack `scripts/check-bash32-floor.mjs` at `6136293` - # and deliberately NOT registered in `scripts/upstream-port-pin.json` — - # that ledger carries ONE global `upstream.ref` (`bf10deb` today) which - # `--resync` rewrites for every entry, so registering this file would mean - # either shipping `bf10deb`'s older, weaker construct table or re-syncing - # three unrelated ported files. The gate's own header carries the full - # argument and names the follow-up. + # Ported from objectstack `scripts/check-bash32-floor.mjs` and REGISTERED + # in `scripts/upstream-port-pin.json` (objectui#8694), so drift from + # upstream reds here instead of arriving as a confident green report. + # ⛔ The ref this copy was taken at is deliberately not named in this + # comment: it lives on that file's ledger entry, beside the digest it was + # taken with, where `--resync` keeps it correct. There is no ledger-wide + # ref to quote instead — objectui#8288 retired that field, and + # `check-upstream-port-parity` now refuses a pin still carrying one. The + # gate's own header carries the full argument. # # Runs before install, next to the three gates above and for the same # reason: node builtins, `scripts/invoked-as.mjs` and `git ls-files` only, diff --git a/scripts/check-bash32-floor.mjs b/scripts/check-bash32-floor.mjs index 32bb5bd886..1c40689187 100644 --- a/scripts/check-bash32-floor.mjs +++ b/scripts/check-bash32-floor.mjs @@ -8,9 +8,10 @@ * commit `6136293`, which is where the class, the construct table and the * exemption rules were worked out. This header states which claims are * upstream's and which were re-measured HERE; ⛔ do not read an inherited - * measurement as a reading about this tree. Deliberately NOT registered in - * `scripts/upstream-port-pin.json` — the reason is at "## Why this port is not - * pinned" below. + * measurement as a reading about this tree. REGISTERED in + * `scripts/upstream-port-pin.json`; that entry carries the ref this copy was + * taken at, its digest and every declared divergence, and the section "## The + * drift gate over this port" below says what follows from it. * * node scripts/check-bash32-floor.mjs * node scripts/check-bash32-floor.mjs --self-test @@ -159,58 +160,31 @@ * closure needed is written at the row itself rather than here, because that is * where a future reader tempted to loosen the pattern will be standing. * - * ## Why this port is not YET pinned in `scripts/upstream-port-pin.json` + * ## The drift gate over this port * + * This file IS registered in `scripts/upstream-port-pin.json`, so + * `check-upstream-port-parity` reverses the divergences declared on its entry + * and compares the reconstruction's bytes against the pinned upstream digest. * That ledger is how this repository stops a ported copy drifting into a * confident-but-stale report — `scripts/pm/check-half-states.mjs` reached a - * 4,637-line diff from upstream while reporting greenly. The same argument - * applies to this file with force: its whole subject is that "an absence from a + * 4,637-line diff from upstream while reporting greenly. The argument applies + * to this file with force: its whole subject is that "an absence from a * denylist reads as an approval", and upstream actively sweeps the table. * - * It is still NOT registered, but the blocker that kept it out was structural - * and is GONE. The pin used to carry ONE ledger-wide `upstream.ref` beside - * per-file digests, and `--resync` rewrote that global field on every run. So - * registering this port at the revision it was actually taken from meant one of - * two bad trades: port from the older revision the ledger happened to name — - * deliberately shipping a WEAKER construct table so a provenance field stayed - * true, which inverts the point of the gate — or drag every other pinned file - * to a new ref, an unrelated rewrite of other ported tooling. A third route, - * pinning this file's digest while the global ref named a different revision, - * was the one that must never be taken: the digest would verify and the - * provenance line would be false. - * - * objectui#8288 retired the field and all three trades with it. Read off - * `check-upstream-port-parity.mjs`: `ref` is now a REQUIRED key on each - * `files[]` entry beside the digest it was taken with, `validatePin` REFUSES a - * pin that still carries `upstream.ref`, and `resyncedPin` writes only the - * re-synced entry's own `ref` and digest while returning every other entry - * untouched. `upstream` keeps `repo` alone. Entries at different refs now - * coexist by design, so this file can be registered at its own revision without - * disturbing anything already pinned. + * ⚠️ So these bytes are PINNED, and this prose pays that cost too. An edit + * anywhere inside a declared region — this paragraph included — has to move + * that divergence's `ported` side in the SAME change, or the gate reds with + * `expected its ported text exactly once, found 0`. That is the intended + * failure direction: loud, and naming the divergence it could not reverse. * * ⛔ Do not write a revision into this prose. A port's ref lives on that port's - * entry in `scripts/upstream-port-pin.json`; read it from there, where - * `--resync` keeps it correct. This section has already gone stale TWICE by - * naming one: objectui#7749 moved the global ref out from under the sentence - * describing it, and objectui#8288 then deleted the field that sentence named. - * Both times the prose stayed confident and wrong — which is this file's own - * subject, aimed at itself. - * - * What registration still costs is per-file work rather than a schema change, - * which is why it did not ride along with objectui#8288 and is a card of its - * own: read the upstream blob at a named ref, compute its SHA-256, and declare - * every divergence as an exact `upstream`/`ported` text pair with a stated - * `why`. The same unblocking reaches the ported `.claude/hooks/**` files that - * objectui#7953 recorded from the other direction — a per-file ref can name a - * revision where each of them exists — with one extra cost there and not here: - * those are GOVERNED surface, so `--resync` refuses to write them without - * `--rewrite-governed-file`. - * - * Consequence, stated so it is inherited rather than rediscovered: until that - * registration lands, this file has NO drift gate. Upstream improvements to - * `CONSTRUCTS` arrive here only if someone carries them by hand. That cost was - * once accepted because paying it meant weakening a gate; it is now simply - * unpaid, and the work to pay it is ordinary. + * entry in the ledger, beside the digest it was taken with, where `--resync` + * keeps it correct. This section has gone stale THREE times for want of that + * rule: objectui#7749 moved a then-ledger-wide ref out from under the sentence + * describing it, objectui#8288 deleted the field that sentence named, and + * objectui#8694 registered this file while the section went on arguing it was + * unregistered. Each time the prose stayed confident and wrong — which is this + * file's own subject, aimed at itself. * * ## Population * diff --git a/scripts/upstream-port-pin.json b/scripts/upstream-port-pin.json index 7f5bc33eb6..050f62fa85 100644 --- a/scripts/upstream-port-pin.json +++ b/scripts/upstream-port-pin.json @@ -167,9 +167,9 @@ "divergences": [ { "id": "header-card-and-ported-banner", - "why": "The header names this repository's card and carries the PORTED provenance banner; upstream's names upstream's. ⚠️ Its \"Deliberately NOT registered\" clause is stale the moment this entry lands — correcting it edits the ported file and is a follow-up card, not a silent fix here.", + "why": "The header names this repository's card and carries the PORTED provenance banner; upstream's names upstream's. It also points at this ledger entry as the place the ref, the digest and these divergences are read from — a pointer upstream, being the original, has nothing to make.", "upstream": "/**\n * The bash-3.2 floor, repo-wide (#12221).\n *\n", - "ported": "/**\n * The bash-3.2 floor, repo-wide (objectui#7692).\n *\n * ⚠️ PORTED from objectstack-ai/objectstack `scripts/check-bash32-floor.mjs` at\n * commit `6136293`, which is where the class, the construct table and the\n * exemption rules were worked out. This header states which claims are\n * upstream's and which were re-measured HERE; ⛔ do not read an inherited\n * measurement as a reading about this tree. Deliberately NOT registered in\n * `scripts/upstream-port-pin.json` — the reason is at \"## Why this port is not\n * pinned\" below.\n *\n" + "ported": "/**\n * The bash-3.2 floor, repo-wide (objectui#7692).\n *\n * ⚠️ PORTED from objectstack-ai/objectstack `scripts/check-bash32-floor.mjs` at\n * commit `6136293`, which is where the class, the construct table and the\n * exemption rules were worked out. This header states which claims are\n * upstream's and which were re-measured HERE; ⛔ do not read an inherited\n * measurement as a reading about this tree. REGISTERED in\n * `scripts/upstream-port-pin.json`; that entry carries the ref this copy was\n * taken at, its digest and every declared divergence, and the section \"## The\n * drift gate over this port\" below says what follows from it.\n *\n" }, { "id": "incidents-are-upstreams-and-local-coverage-census", @@ -197,9 +197,9 @@ }, { "id": "why-this-port-is-not-yet-pinned-section", - "why": "A port-local rationale section with no upstream counterpart. ⚠️ This entry is what makes it false; rewriting it would edit the ported file and change this divergence, so it is tracked as a follow-up card rather than folded in.", + "why": "A port-local section with no upstream counterpart: what this ledger entry means for the ported copy, and the standing ⛔ against restating its ref in prose. ⚠️ It is prose INSIDE a declared region, so editing it moves this pair — which is why the correction and the pair travel in one change.", "upstream": " *\n * ## Population\n", - "ported": " *\n * ## Why this port is not YET pinned in `scripts/upstream-port-pin.json`\n *\n * That ledger is how this repository stops a ported copy drifting into a\n * confident-but-stale report — `scripts/pm/check-half-states.mjs` reached a\n * 4,637-line diff from upstream while reporting greenly. The same argument\n * applies to this file with force: its whole subject is that \"an absence from a\n * denylist reads as an approval\", and upstream actively sweeps the table.\n *\n * It is still NOT registered, but the blocker that kept it out was structural\n * and is GONE. The pin used to carry ONE ledger-wide `upstream.ref` beside\n * per-file digests, and `--resync` rewrote that global field on every run. So\n * registering this port at the revision it was actually taken from meant one of\n * two bad trades: port from the older revision the ledger happened to name —\n * deliberately shipping a WEAKER construct table so a provenance field stayed\n * true, which inverts the point of the gate — or drag every other pinned file\n * to a new ref, an unrelated rewrite of other ported tooling. A third route,\n * pinning this file's digest while the global ref named a different revision,\n * was the one that must never be taken: the digest would verify and the\n * provenance line would be false.\n *\n * objectui#8288 retired the field and all three trades with it. Read off\n * `check-upstream-port-parity.mjs`: `ref` is now a REQUIRED key on each\n * `files[]` entry beside the digest it was taken with, `validatePin` REFUSES a\n * pin that still carries `upstream.ref`, and `resyncedPin` writes only the\n * re-synced entry's own `ref` and digest while returning every other entry\n * untouched. `upstream` keeps `repo` alone. Entries at different refs now\n * coexist by design, so this file can be registered at its own revision without\n * disturbing anything already pinned.\n *\n * ⛔ Do not write a revision into this prose. A port's ref lives on that port's\n * entry in `scripts/upstream-port-pin.json`; read it from there, where\n * `--resync` keeps it correct. This section has already gone stale TWICE by\n * naming one: objectui#7749 moved the global ref out from under the sentence\n * describing it, and objectui#8288 then deleted the field that sentence named.\n * Both times the prose stayed confident and wrong — which is this file's own\n * subject, aimed at itself.\n *\n * What registration still costs is per-file work rather than a schema change,\n * which is why it did not ride along with objectui#8288 and is a card of its\n * own: read the upstream blob at a named ref, compute its SHA-256, and declare\n * every divergence as an exact `upstream`/`ported` text pair with a stated\n * `why`. The same unblocking reaches the ported `.claude/hooks/**` files that\n * objectui#7953 recorded from the other direction — a per-file ref can name a\n * revision where each of them exists — with one extra cost there and not here:\n * those are GOVERNED surface, so `--resync` refuses to write them without\n * `--rewrite-governed-file`.\n *\n * Consequence, stated so it is inherited rather than rediscovered: until that\n * registration lands, this file has NO drift gate. Upstream improvements to\n * `CONSTRUCTS` arrive here only if someone carries them by hand. That cost was\n * once accepted because paying it meant weakening a gate; it is now simply\n * unpaid, and the work to pay it is ordinary.\n *\n * ## Population\n" + "ported": " *\n * ## The drift gate over this port\n *\n * This file IS registered in `scripts/upstream-port-pin.json`, so\n * `check-upstream-port-parity` reverses the divergences declared on its entry\n * and compares the reconstruction's bytes against the pinned upstream digest.\n * That ledger is how this repository stops a ported copy drifting into a\n * confident-but-stale report — `scripts/pm/check-half-states.mjs` reached a\n * 4,637-line diff from upstream while reporting greenly. The argument applies\n * to this file with force: its whole subject is that \"an absence from a\n * denylist reads as an approval\", and upstream actively sweeps the table.\n *\n * ⚠️ So these bytes are PINNED, and this prose pays that cost too. An edit\n * anywhere inside a declared region — this paragraph included — has to move\n * that divergence's `ported` side in the SAME change, or the gate reds with\n * `expected its ported text exactly once, found 0`. That is the intended\n * failure direction: loud, and naming the divergence it could not reverse.\n *\n * ⛔ Do not write a revision into this prose. A port's ref lives on that port's\n * entry in the ledger, beside the digest it was taken with, where `--resync`\n * keeps it correct. This section has gone stale THREE times for want of that\n * rule: objectui#7749 moved a then-ledger-wide ref out from under the sentence\n * describing it, objectui#8288 deleted the field that sentence named, and\n * objectui#8694 registered this file while the section went on arguing it was\n * unregistered. Each time the prose stayed confident and wrong — which is this\n * file's own subject, aimed at itself.\n *\n * ## Population\n" }, { "id": "population-shebang-census-is-zero-here",