Repository navigation
Commit 9c8f113
Fixes #20646
Clause-②: no
`Console Pin Gate` is red on `main` since `fbec216e2d` (PR #20695, the
`@objectstack/spec/migrations` entry split). Its build step exits 2:
"Neither spec appears in the built console — no @objectstack/spec
content matched." The injection works. The check was reading text the
console never bundles. This PR makes the build-time probe derivation
choose with the bundle in view. The fresh leg stops reading entries the
console never imports, and the stale leg becomes strictly stronger.
## Root cause, measured
`scripts/console-spec-probes.mjs` builds each spec's blob from every JS
file the package's `exports` map resolves to. The assertion then took
the alphabetically first unique `.describe()` text on each side. A
console bundles only the entries it imports, so either probe could come
from an entry the bundle can never carry.
The readings below compare the published `@objectstack/spec` 17.4.0 that
objectui locks at pin `dd3f7e1be356` with the framework spec.
| leg | framework | fresh witness (carried by) | in bundle | stale
detector (carried by) | in bundle | old check |
| --- | --- | --- | --- | --- | --- | --- |
| dark | `f927864ea0` (main before the split) | "A public export added
or removed by one release." (`.`) | yes | "Accepted developer agreement
version" (`./cloud`) | no | exit 0 |
| lit | `fbec216e2d` (`origin/main`) | the same text, now
(`./migrations`) | no | the same (`./cloud`) | no | exit 2 |
- The witness moved with the split from the root to `./migrations`,
which the console never imports. Meanwhile 102 of the 142 injected-only
descriptions ARE in that bundle; the first sorts from `./ui`.
- The stale leg was already blind. Its detector sits in the published
`./cloud` entry, which objectui's shipped source never imports: 116
`/ui`, 62 `/data`, 17 `/kernel` and so on, and no `/cloud`. A console
built WITHOUT the injection carries 56 of the 160 published-only
descriptions, and not that one.
- The spec side is not the cause. The console never imported the change
manifest, and the injected spec is in the bundle. `packages/spec` is
untouched here.
## The fix (`scripts/console-spec-probes.mjs`, `chooseProbes`)
- **Fresh witness:** the first injected-only description the bundle DOES
carry. With none carried, "neither spec appears" is still exit 2.
- **Stale leg:** judged over EVERY published-only description. It fails
when ANY of them is in the bundle, and reports the first one found with
the count. A bundle the old single pick flagged is still flagged, so
this is strictly stronger.
- **Stamp:** keeps its shape and version. With nothing published in the
bundle, the stamped detector is the same one `pickProbe` chose, so
`check:console-injection`'s cache-hit replay is unchanged.
- **Assertion script:** `scripts/assert-console-spec-injection.mjs`
calls `chooseProbes` and prints the counts. The exit ladder is
unchanged: 0 verified, 1 published spec bundled, 2 unverified.
- **Self-test:** `scripts/check-console-injection.mjs` gains battery 13
(roster floor 10 to 11). It runs the real assertion script on fixtures
whose first unique candidate is not in the bundle:
- a working injection verifies, and its stamp replays green;
- a published-only description the old pick skipped fails the build and
writes no stamp;
- neither side present stays exit 2.
I checked that the battery can fail: reverting `chooseProbes` to
first-pick semantics made it red with 5 failures, and restoring the fix
turned it green again.
## Proof
All legs ran against real `vite build`s of the console, with the old and
the new assertion on the same bundle.
| console build | objectui pin | new check | old check |
| --- | --- | --- | --- |
| injected spec from `fbec216e2d` | `dd3f7e1be356` | exit 0 (witness
from `./ui`; 102/142 present; 0/160 published) | exit 2 |
| NOT injected (published spec) | `dd3f7e1be356` | exit 1 (56/160
published-only descriptions present) | exit 2 |
| a bundle with no spec text | — | exit 2 ("Neither spec appears") | — |
| injected spec from `f927864ea0` (dark) | `dd3f7e1be356` | exit 0
(111/142 present) | exit 0 |
| injected spec from `fbec216e2d` | `db11afd49670` (PR #20706's pin) |
exit 0 (102/142; 0/160) | exit 2 |
| NOT injected (published spec) | `db11afd49670` | exit 1 (56/160) |
exit 2 |
On this branch's head, the Console Pin Gate's steps run locally all
pass: `bash scripts/build-console.sh` with the injected spec exits 0;
the dist presence assert passes; `pnpm check:console-sha` exits 0; and
`pnpm check:console-injection --require-stamp` exits 0 and replays the
new stamp.
## Verification record
- `dispatch-gates --commands` for the 3 changed paths derives 31
families. `--ran` reconciles them as 30 run, all exit 0, and 1 NOT
MEASURED: `check:pm-dispatch-gates`, whose self-test alone outruns the
590-second foreground cap here. It does not read these files' behaviour.
- `node scripts/check-console-injection.mjs --self-test` passes: 44
assertions, battery floor met.
- Lint, narrowed and proven: `eslint --no-inline-config` on the 3
changed files reports 0 errors and 0 warnings. The config enables no
type-aware linting, so untouched files' verdicts cannot move.
- No changeset: the diff touches only root `scripts/`, which ship in no
published package (`@objectstack/spec-monorepo` is private).
## Acceptance notes
- **The cache-hit replay's stale leg is still a single stamped
detector.** At this pin that detector is `./cloud` text no console
bundles, so on a dist-cache HIT the replay cannot catch a published
spec. The build-time leg now can. Fixing the replay needs a
multi-detector stamp (a `stampVersion` bump that invalidates every
cached dist under the unchanged cache key), which is outside this claim.
Carrier: the `domain:spec` seat. Noted, not filed.
- **CI on this head:** `Console Pin Gate` (job 109696257740) concluded
success. The dist cache missed, so step 11 built the console and ran the
changed assertion (105 of 145 injected-only descriptions present, all
160 published-only absent), and steps 12 to 14 passed on that fresh
dist.
---
_Generated by [Claude
Code](https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx)_
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 97005ae commit 9c8f113
3 files changed
Lines changed: 141 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
68 | | - | |
69 | | - | |
| 68 | + | |
70 | 69 | | |
71 | 70 | | |
72 | 71 | | |
| |||
110 | 109 | | |
111 | 110 | | |
112 | 111 | | |
113 | | - | |
114 | | - | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
115 | 121 | | |
116 | 122 | | |
117 | 123 | | |
| |||
140 | 146 | | |
141 | 147 | | |
142 | 148 | | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | 149 | | |
147 | 150 | | |
148 | 151 | | |
149 | 152 | | |
150 | 153 | | |
| 154 | + | |
| 155 | + | |
151 | 156 | | |
152 | 157 | | |
153 | 158 | | |
| |||
157 | 162 | | |
158 | 163 | | |
159 | 164 | | |
160 | | - | |
| 165 | + | |
| 166 | + | |
161 | 167 | | |
162 | 168 | | |
163 | 169 | | |
| |||
178 | 184 | | |
179 | 185 | | |
180 | 186 | | |
181 | | - | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
182 | 192 | | |
183 | 193 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
196 | 196 | | |
197 | 197 | | |
198 | 198 | | |
| 199 | + | |
199 | 200 | | |
200 | 201 | | |
201 | 202 | | |
202 | 203 | | |
203 | | - | |
| 204 | + | |
204 | 205 | | |
205 | 206 | | |
206 | 207 | | |
| |||
850 | 851 | | |
851 | 852 | | |
852 | 853 | | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
853 | 916 | | |
854 | 917 | | |
855 | 918 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
127 | 185 | | |
128 | 186 | | |
129 | 187 | | |
| |||
0 commit comments