Repository navigation
fix(release): judge a .objectstack-sha console bundle against objectui's own build of that commit - #24532
Conversation
…i's own build of that commit On a pin carrying .objectstack-sha, build-console.sh stands this tree in for objectui's pinned objectstack commit, so the spec objectui's install holds is this tree's own. Handed to assert-console-spec-injection.mjs as --vendored it equalled --injected: the assertion reported no skew, stamped null witnesses, and passed any bundle; check:console-injection --require-stamp then replayed "nothing assertable". build-console.sh now builds objectui's own @objectstack/* at its .objectstack-sha first (the pin script without OBJECTSTACK_ROOT), keeps a copy with the pin's cache stamp outside the cache the stand-in replaces, and passes that spec as --vendored. The assertion refuses, as cannot-judge, any other reference on such a pin (the stand-in, the install's copy, a build of another commit), and the stamp records vendoredFrom and vendoredPin. Self-test battery 15 pins the refusal, the real witness, the red on a bundle carrying the pinned spec (build and replay), and the honest no-skew case. Claude-Session: https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp Co-authored-by: Claude <noreply@anthropic.com>
…e assertion's verdicts Wording only: on a .objectstack-sha pin the vendored side is objectui's own build of that commit, not a published spec, so its unique descriptions are reported as pin-only. Claude-Session: https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp Co-authored-by: Claude <noreply@anthropic.com>
… text in a restored dist Wording only: a stamp with vendoredPin was judged against objectui's own build of that commit, so the replay's red verdict says so instead of "the PUBLISHED". Claude-Session: https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp Co-authored-by: Claude <noreply@anthropic.com>
…ck-sha pin The branch test now expects objectui's own pin build (no OBJECTSTACK_ROOT, no OS_SKIP_DTS) before the stand-in, the reference cache with its pin stamp to survive the stand-in, and a rerun to reuse it only while its stamp names the pin. Claude-Session: https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
|
ACCEPT ·
Landing: ready → auto-merge → merge queue. Generated by Claude Code |
Fixes #24510
Clause-②: no
What this changes
On a console pin whose objectui commit carries
.objectstack-sha,scripts/build-console.shstands THIS tree in for objectui's pinned objectstack commit (OBJECTSTACK_ROOT). So the spec in objectui's install is this tree's own. The script handed exactly that spec toassert-console-spec-injection.mjsas--vendored. It equalled--injected, so the assertion printed "no observable skew", stampedskew: falsewith null witnesses, and exited 0 before it looked at the bundle at all.check:console-injection --require-stampthen replayed "Nothing assertable". Both release paths passed any bundle.scripts/build-console.sh: on the.objectstack-shabranch, before the stand-in, it now builds objectui's OWN@objectstack/*at its.objectstack-sha, by objectui's own recipe (node scripts/objectstack-pin.mjs buildwithOBJECTSTACK_ROOTandOS_SKIP_DTSunset). It keeps a copy of that cache, the pin script's.stamp.jsonincluded, atnode_modules/.cache/objectstack-pin-referencein the objectui build tree, outside the cache the stand-in replaces. That copy'sspecis passed as--vendored. A rerun in the same build tree reuses it while its stamp sayssource: pinat this pin. A pin without.objectstack-shais unchanged:--vendoredis still objectui's install.scripts/assert-console-spec-injection.mjs: when the--objectuitree carries.objectstack-sha,--vendoredmust sit beside a pin-script stamp withsource: pinandshaequal to that pin. Anything else is refused as cannot-judge (exit 2), never read as "no skew": the stand-in (source: external), the install's own copy (no stamp), or a build of another commit. The stamp entry now recordsvendoredFromandvendoredPin. The verdict text names the pinned reference (pin-only, notpublished-only). The probe derivation inconsole-spec-probes.mjsis unchanged.scripts/check-console-injection.mjs: the replay names the pinned reference in its no-skew line and in its red verdict. Self-test battery 15 (17 cases, floor 17; roster floor 12 → 13) covers four things. It refuses the three wrong references. It stamps a real witness against the right one. It goes red on a bundle carrying the pinned spec, at build time and on replay. It passes the honest no-skew case and names the reference in it.packages/spec/scripts/build-console-objectstack-root.test.ts: the existing branch test (it pins this exact branch ofbuild-console.sh) now expects three things. The native pin build runs before the stand-in, withoutOBJECTSTACK_ROOTand withoutOS_SKIP_DTS. The reference cache and its pin stamp survive the stand-in. A rerun reuses the reference only while its stamp names the pin.The producer of the vacuity was the wiring in
build-console.sh, so the fix is there. The assertion's new refusal keeps that wiring from coming back silently..github/workflows/release.ymlis untouched: itscheck:console-injection --require-stampcall did not need to change, so this PR touches no governed surface.The card's "Wanted", item by item
.objectstack-sha": done.--vendoredis objectui's own build of2c9bf9430a11, and the assertion refuses any other reference on such a pin.Measurements
All readings are from objectstack
a5a781bc7(BASE) and this branch, at.objectui-sha4016370af3c9, where objectui's.objectstack-shais2c9bf9430a11(spec 18.0.0-next.3). This tree's spec is 18.0.0-next.5. The objectui source was the sibling checkout,build-console.shmode 2.Stamp, real build (
bash scripts/build-console.shunderos-verify-lock):--require-stampa5a781bc7(VERDICT 0, 862 s)falsenullnull91dc1bab6(VERDICT 0, 672 s)true2c9bf9430a11…Build-time verdict on this branch: "Console bundle carries THIS tree's @objectstack/spec, and only it (vendored: @objectstack/spec of objectui's own build of objectstack 2c9bf94)". 16 of 16 injected-only descriptions are present and all 2 pin-only ones are absent. This is the same count os-dev-report 6263864885 measured by hand.
Reference build cost, from the pin script's own step timings on this shared box: fetch 14.8 s, install 5.0 s, build of the 7 packages 144.7 s, pack 16.5 s, so about 181 s. The rerun in the same tree skipped it: the log has 0 "Building objectui's own" lines, against 1 on the first run.
The negative proof (hypothesis 5). The red bundle is a scratch
build-console.shrun with both halves deliberately broken:OBJECTUI_DEPS_BUILD_CMDputs objectui's own pin build back into its install after the stand-in, andOBJECTUI_BUILD_CMDdropsOBJECTSTACK_SPEC_DISTandOBJECTSTACK_CLIENT_DIST. That is what ships if pack and inject both regress. The run ended with build-time exit 1: "✗ Built console still carries the @objectstack/spec of objectui's own build of objectstack 2c9bf94 … (1 of 2 pin-only descriptions) … Binds the element to one same-origin API endpoint instead of an object". Lock VERDICT command-exit 1. Theimport/jobscanary passed on that same bundle.A first sabotage aimed only
OBJECTSTACK_SPEC_DISTat the pinned spec while the install stayed this tree. It never produced a bundle: rolldown's MISSING_EXPORT error said this tree's@objectstack/lintneedsvirtualFieldAggregateRemedy, which the pinned spec lacks. So the coherent leak is the whole pin, and that is the bundle used here.Then every leg was re-run at the final head, against the saved bundles. These are direct node runs, assertion blob
26acfe988c3b, BASE blob4fd59042a9eb:--vendoredPM mechanism hypotheses
--vendoredresolved to this tree's packed spec, and the stamp and replay matched the card exactly.OBJECTSTACK_ROOT, and the pin script at this pin has no machine-store code at all: its 2 "machine" hits are about npm network settings, against 7 hits in objectui#12972'sf9401e6.git showof this repo's history gives source, while the probes read built.describe()text. An npm version is exact only when the pin is a version commit, and objectui'sbump-objectstack.shpins any main HEAD. The reference stays a built spec, needs no secret, and fetches objectstack from GitHub like the pin script does by default (OBJECTSTACK_REPO_URLoverrides it). The cache-HIT replay still reads only the stamp, which now carries real probes. On a HIT nothing is built, and the replay's expiry check still reads only this tree's built spec..objectstack-shapin, that reference is objectui's own build of the pinned commit, proven by its pin stamp. When that build declares the same descriptions as this tree, the bundle carries the same text either way, so it stays an honest exit 0. The stamp then recordsvendoredPin, and the replay prints "no observable skew between the injected and objectui's own build of objectstack SHA". The vacuous case can no longer be produced: a reference that is the stand-in or the install is refused with exit 2 before the bundle is read. Battery 15 pins both.import/jobsclient canary passed on the pin-native bundle too, so it does not tell an injected client from objectui's own. That is measured above and agrees with 6263864885. No client witness was added: per 6263864885, the two trees' client differs only in a type signature and comments, so a witness would have nothing to tell apart today. See the Acceptance notes.Route choice on the four axes
.objectstack-shamoves. The cost is about 3 minutes per console build that misses its cache.Tests and gates
The gate union was run after the final commit, at
14d4124e8.dispatch-gates.mjs --commandsderived 86 families. 84 exited 0 on the first pass. Two answered exit 3, PREREQUISITE NOT MET, which is not a measurement:check-plugin-teardown-shape --self-testcould not reach its fixture commit in a shallow clone. Aftergit fetch --unshallow origin mainit exited 0.check:dual-build-cjs-loadsneeds every package's dist. Afterturbo run build --filter=!@objectstack/docs --concurrency=2(76 of 76, 75 cached, VERDICT 0) it exited 0.dispatch-gates.mjs --ranthen reported "86 derived, 86 run, 0 NOT-MEASURED, 0 UNRUN" (exit 0). This PR's check-runs belong to CI and were not re-run here.node scripts/check-console-injection.mjs --self-test: exit 0, "84 assertions over real fixture trees".pnpm --filter @objectstack/spec exec vitest run --project repo --maxWorkers=2 scripts/build-console-objectstack-root.test.ts: 6 of 6 pass. The same file at24e7c5cab, before its update, failed 2 of 5. Ablation throughscripts/ablation-replace.mjs: the reference guard was replaced byif false, the anchor went 1 → 0 and the blob changed, and 3 of 6 failed. The restore was proven: blob equal to HEAD,git diff HEADempty. Re-run after the restore: 6 of 6.pnpm --filter @objectstack/spec typecheck: VERDICT 0.tsc -p tsconfig.scripts.json --listFilesincludes the edited test.check:console-injectionexit 0 andcheck:console-shaexit 0 on the real dist.Acceptance notes
.objectstack-shapin now pays the reference build once, about 181 s on this box. Both workflows hashscripts/build-console.shinto their dist-cache key, so every entry stamped by the old script stops being restored. The first run of each workflow after this lands rebuilds cold.build-console.shruns underset -e.@objectstack/client, which is where a derived client witness would come from if one is ever wanted. Owner: none. Not filed: this is an observation with nothing to witness today.localvitest project, wholetest:repo,pnpm lintand the rest of the farm belong to CI.Generated by Claude Code