fix(ci): the Console Pin Gate never counts text objectui's own source carries as the published spec (#21709) - #21717
Merged
objectstack-fleet[bot] merged 3 commits intoOct 4, 2026
Conversation
…n source carries WIP: self-test battery follows. Claude-Session: https://claude.ai/code/session_01T9u38rswFp5Rw8DswRUReJ Co-authored-by: Claude <noreply@anthropic.com>
…ence, on the build and the replay Battery 14 of check-console-injection's self-test: the injected spec plus an objectui literal beginning with (and one equal to) a published-only description passes and stamps a detector objectui does not write; the published spec itself still fails; the replay agrees on both bundles. Claude-Session: https://claude.ai/code/session_01T9u38rswFp5Rw8DswRUReJ Co-authored-by: Claude <noreply@anthropic.com>
…he good build wrote no stamp Claude-Session: https://claude.ai/code/session_01T9u38rswFp5Rw8DswRUReJ Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Oct 4, 2026
objectstack-fleet
Bot
deleted the
claude/issue-21709-console-probe-collision
branch
October 4, 2026 11:30
This was referenced Oct 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #21709
Clause-②: no
What changes
The
Console Pin Gate's probes no longer treat text that objectui's own source carries as evidence of either spec. A console bundle carries text from objectui's code as well as from the specs. objectui's component registry writesinputsdescriptions that copy spec.describe()text, either verbatim or as a prefix it then extends. When the spec rewords one of those, the old text becomes published-only. objectui's literal still carries it, so a substring search found "the published spec" in a bundle built from this tree's spec. That is what has turned every merge-queue build red since #21699 (16d241a6af): the object-ganttmarkersdescribe and objectui'spackages/plugin-gantt/src/index.tsx:190.scripts/console-spec-probes.mjs:readHostSourceBlob(dir)reads objectui's tracked code files at the pin (git ls-files; test files excluded; a quote's backslash normalised).chooseProbesnow takes that blob ashostBlob, required. It is a TypeError without it.counts.hostCarried), never decides a verdict, and is never returned as a probe, so it is never stamped. A candidate absent from the bundle is still evidence, whoever else carries it. The rule excuses presence, never absence.scripts/assert-console-spec-injection.mjs: a new required--objectuiflag (objectui's build tree, the git checkout at the pin). Its messages report host-carried text separately, so a pass no longer prints "all N published-only descriptions are absent" when one of them is in the bundle.scripts/build-console.sh(declared, and strictly needed by the route): the single assert call site passes--objectui "$BUILD_ROOT", the tree it just built. The only other way to find that tree is to reach two levels up from--vendored, which couples the assert to a path layout. A required flag means a forgotten call site fails loudly (exit 2).scripts/check-console-injection.mjs: the replay logic is unchanged. It needs no objectui tree, because the build never stamps a host-carried probe. Its self-test gains battery 14, and batteries 12 and 13 now pass--objectui.stampVersion1). The stamp now records the filtered choice, so a cache-hit replay agrees with the build.Reproduction (base
7e0066af7a, the head of queue run37187916146)37187916146, job111393796807("Build the Console SPA at the pinned objectui SHA"). Its triage comment on docs(spec): re-anchor the dead tracker citations in packages/spec/src's test surface to the commits that decided them #21700 quotes✗ Built console still carries the PUBLISHED @objectstack/spec.I could not read the raw job log from this container: the log blob host answered 403. So the per-candidate figure comes from the local build below, at the same commit.scripts/build-console.shat7e0066af7a, run underos-verify-lock.sh. It used objectuiab1879721595, and the vendored@objectstack/specresolved to 17.6.0. Lock held 559s. Result: exit 1,(1 of 38 published-only descriptions), the first of them: "Extra vertical reference lines drawn like the Today marker ({ date, label?, color? })".markerstext. objectui's tracked non-test source carries it. The injected-only candidates present are 26 of 26, and none of those is host-carried.Route: (a), by measurement
markerstext is not a whole literal in the real bundle.plugin-gridchunk. Rewording any of those 9 would recreate this red under (b).37 of 38, detector "Actions to execute during transition". Replaying the good build's stamp beside those assets also exits 1.Pins (battery 14,
node scripts/check-console-injection.mjs --self-test)Base: 44 assertions. Head: 67. Every fixture runs the real assert script and replays its stamp through
evaluate(). The mirrored texts sort first, so an unfiltered pick would choose them.staleDetector= a text objectui does not write. The replay passes.Battery 14 also covers:
chooseProbeswithouthostBlob(TypeError).Ablation. Predicted first and saved, then run through
scripts/ablation-replace.mjsin wrap mode. The mutation wasconst hostCarried = new Set();. On disk the anchor went 1 to 0 and the marker 0 to 1. The restore was proven: blob903c3e80cce1equals HEAD, andgit diff HEADis empty.1 of 38with themarkersdetector, and exit 138 of 38.1 of 38with themarkersdetector, and exit 138 of 38with the published chunk added.The real door on this head
scripts/build-console.shon93ea8e7d80reused the built objectui tree, rebuilt the console at the pin, and ran the fixed assert. Exit 0, with37 of 38 published-only descriptions are absent; 1 ... ARE in the bundle, and objectui's own source at the pin carries each of them too. Lock held 278s. The next CI steps then ran on that dist:pnpm check:console-shaexited 0, andpnpm check:console-injection --require-stampexited 0 (self-test 67, replay passed).93ea8e7d80differs from the final head0bcf6a0a95only in a self-test fixture line incheck-console-injection.mjs, and that self-test was re-run on0bcf6a0a95.ci.yml'sconsolefilter, soConsole Pin Gateruns on this PR. Three of them (build-console.sh, the assert, the probes module) are in the dist cache key, so the key moves and the cache misses. The PR head therefore gets a full console build at the pin with this assert, and that is the CI reading of the real door.Console Pin Gateruns this assert.release.yml's key hashesbuild-console.sh, so its next run rebuilds through the new call site too.Gates (on
0bcf6a0a95)node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 32 commands. All 32 exited 0.--ranreconciliation: 32 derived, 32 run, 0 NOT MEASURED, 0 unrun, every one with a recorded exit code. That includespnpm check:console-injection,check:console-sha,check:ci-filter-parity(+ self-test),check:nul-bytes,check:entry-guardandcheck:pm-dispatch-gates(1976 cases, run detached).eslint.config.mjslints all three changed.mjsfiles, so none is ignored.--format jsonreported 3 files, 0 errors and 0 warnings. The config has no type-aware linting, so this diff cannot move any untouched file's verdict.build-console.shis outside eslint's population. The fullpnpm lintis left to CI.Changeset
skip-changeset: nothing published changes. The diff is rootscripts/only, and the root package is private and ships nofiles. I built the console dist (the one published package this build feeds) and grepped it:readHostSourceBlob/hostCarriedhave 0 hits, while the positive control, themarkersliteral, is found in 3 files.Acceptance notes
apps/console/src/__tests__/registry-inputs-spec-parity.test.tsquotes 2 of the 38 published-only describes. Tests are excluded from the host source, so in a real leak those two still count as evidence.7e0066af7a(itshead_sha).origin/mainhas since moved by four commits, and none of them touches this gate's inputs.Generated by Claude Code