Skip to content

Commit 2a61f08

Browse files
release(ui-merge): one release lane for both scopes — @object-ui joins the fixed group, @objectstack/console builds from ui/apps/console, the objectui pin is deleted (#25711) (#25745)
<!-- claude-projects-attribution: {"github_login":"os-tesla"} --> _Requested by **Tesla** · [project thread](https://claude.ai/code/project/chan_01AXsQkLFKRdQCqQ3RTr6JaoKAHLK79xmvJyPStopRpPQ2)_ Part of objectstack#25677 Fixes #25711 Blocked-by: sub-issue 5 of #25677 (the subtree PR that adds `ui/`; not filed yet) Clause-②: no Metadata-protocol: none **Maintainer rulings (Tesla, 2026-10-25 09:06Z, director thread):** 17a — the release npm token has publish rights on `@object-ui`. 17b, ruling B — the private VS Code extension `object-ui` stays in the one fixed group. 17c, ruling B — the QUICK_REFERENCE release-sync rows retire; decision B (17c) carried here. > ⛔ **Tier H, cutover sitting.** The cutover #25825 is on `main` (`fd40831416`, with #25833). This PR merged `main` and applies its `ui/` half as tree edits on that tree. Local verdict on `fb110c2323`: comment 6404553650, every step and gate exit 0. It merges per ruling 30 = B once that sweep is clean and the four fast lanes are green. > Body refreshed 2026-10-25T22:55Z on head `fb110c2323` (the merge of `main` `fd40831416` is `e2db258a24`). Comments read through 6404553650. ## What changes **1. One fixed group** (`.changeset/config.json`). The 38 public `@object-ui/*` packages and the private VS Code extension `object-ui` (17b) join the `@objectstack/*` fixed group; `@object-ui/example-*`, `@object-ui/site`, `@object-ui/runner` and `@object-ui/test-support` are ignored, as in objectui. (objectui#13506 made `@object-ui/runner` private before the freeze at `9e1fe03286`.) `ui/.changeset/config.json` is deleted by the ui-side patch (changesets reads one config per repository), and objectui's 65 pending `ui/.changeset/*.md` stay under `ui/` for aftercare #25831. Measured on cutover head `c04b36dcb9`, moving them as they stand reds `check-empty-changeset` (3 empty frontmatters) and `check-adr-0087-registration` (41 breaking changesets with no disposition). Root `check-changeset-fixed` accepts a private name in the group only when `PRIVATE_FIXED_MEMBERS` declares it (`object-ui` alone, with its reason), the package is private, and `privatePackages.version` is true; it reds if that member leaves the group. `check:lockstep-package-count` subtracts the declared private members, so the published count is 111. `check-changeset-no-major` now reads `packages/console/build-dist.sh` as the Console's packed-copy build script, and `check-empty-changeset`'s frontmatter-parser family loses the deleted objectui digest. **2. `@objectstack/console` builds in this workspace.** `packages/console/build-dist.sh` copies `ui/apps/console/dist` (built by turbo through `@object-ui/console#build`) into `packages/console/dist`, ships the tracked `sdui.manifest.json` (ADR-0080), and runs the single-zod canary over the bytes it ships. Root task `@objectstack/console#build:dist` (`turbo.json`) depends on `@object-ui/console#build`; `pnpm console:build` runs it, and `pnpm release` / `cut-rc.yml` run it after `pnpm run build`. `files` and `prepublishOnly` are unchanged. `scripts/build-console.sh` is deleted. The CLI's remedy for a missing Console dist names `pnpm console:build`. **3. The objectstack-side pin is deleted.** `.objectui-sha`, `scripts/bump-objectui.sh` (+ selftest), `scripts/objectui-changeset-digest.mjs`, `scripts/objectui-range.mjs`, `scripts/check-prerelease-pin-watch.mjs`, `scripts/check-console-sha.mjs`, `scripts/check-console-injection.mjs`, `scripts/assert-console-spec-injection.mjs`, `scripts/console-spec-probes.mjs`, `packages/spec/scripts/build-console-objectstack-root.test.ts`; the pin reads in `cut-rc.yml` ("THE objectui PIN IS AN INPUT HERE" and `Read the committed objectui pin`), `release.yml`, `lint.yml`, `showcase-smoke.yml` and the root `package.json` scripts (`objectui:*`, `check:console-sha`, `check:console-injection`, `check:objectui-*`, `check:prerelease-pins`; `pnpm dev*` no longer runs `check:console-sha`). `scripts/check-console-intercept-disarm.mjs` stays. Release notes (`collect-release-notes.sh`) say "no objectui pin" when the new ref has none. Gate self-tests and rosters that named the deleted scripts follow (`dispatch-gates`, `pnpm-filter-targets`, `check-pnpm-filter-targets` (tree-aware: foreign `@object-ui/` targets must be 0 without `ui/`, >0 with it), `bare-root-worklist`, `check-type-check-coverage`). The lockstep count in `content/docs/protocol/backward-compatibility.mdx` and `scripts/publish-smoke-pack.mjs` reads 112, both scopes (`check:lockstep-package-count --fix`), and `packages/spec/vitest.repo-tests.json` drops the deleted test. **4. The objectui-side pin is deleted, in `ui/`.** Until `ui/` was on `main`, this half was carried as `scripts/ui-import/4a-ui-side.patch`. After the cutover landed, `fb110c2323` applied it under `ui/` with README step 2's deletions, then deleted the patch file. `scripts/ui-import/README.md` now records what was applied. It deletes `.objectstack-sha`, `.objectstack-pin/`, `bump-objectstack.sh`, `objectstack-pin.mjs`, `objectstack-floor.mjs`, `check-spec-range-floors.mjs`, `check-installed-spec-pin-claims.mjs`, the dist-pin Vite probes `vite-objectstack-spec-dist.ts` / `vite-objectstack-client-dist.ts`, `changeset-release.yml`, `spec-range-floors.yml`, `release-github-releases.mjs` and their tests, plus (17c) `sync-quick-reference-release.mjs`, its test and the `quick-reference-current-release-4143` pin, with `QUICK_REFERENCE.md`'s version rows. The single-zod guard moves to `ui/scripts/vite-single-zod.ts` (it runs in every console build); `apps/console/vite.config.ts` drops both injections. Every reader of the Changesets config goes through a new `changesetConfigPath()` (own root standalone, monorepo root when nested); objectui's `check-changeset-fixed` and `check-unused-dependencies` otherwise keep their extension rules (17b). The patch was written against verify head `9e37acd126` and checked with `git apply --check` on cutover heads `1c0d02eda4` and `c04b36dcb9` and on `main` at `fd40831416`. It also deletes the nested `ui/.github/pull_request_template.md`, which never renders and whose only markdown-test-inputs reader was the claims test. **6. SDUI manifest.** Carries the sdui manifest regeneration for the merged tree (107 → 106 components; objectui#13449 retired html): `sdui.manifest.json` and `scripts/sdui-manifest.record.json`, regenerated from `ui/` now that `.objectui-sha` is gone and the dual-mode gates (#25833) read the in-tree oracle. **5. One release lane.** objectui's `changeset-release.yml` is gone; root `release.yml` publishes both scopes in one `pnpm -r publish`, and the root `scripts/release-github-releases.mjs` cuts one GitHub Release per package tag across both scopes. ## The four deleted Console checks, and what proves the same thing now | Deleted | What it proved | Now | |---|---|---| | `assert-console-spec-injection.mjs` | the built Console bundles THIS tree's `@objectstack/spec`, not the copy objectui's lockfile installed | Can no longer be false. Every `@objectstack/*` dependency under `ui/` is `workspace:^` (33 spec, 2 client, 2 lint, 2 formula rows measured), which pnpm links and never resolves from the registry; the merged lockfile has 0 registry entries for `@objectstack/spec` or `@objectstack/client` and 37 `link:` rows to `packages/spec`. The single-zod guard (Vite, `ui/scripts/vite-single-zod.ts`) and canary (`build-dist.sh`, on the shipped bytes) still run in every build. | | `check-console-injection.mjs` | a Console dist restored from the pin-keyed cache was built against the current spec | Can no longer be false. The cache keyed on `.objectui-sha` is gone; turbo's hash for `@object-ui/console#build` includes `@objectstack/spec#build`, `@objectstack/client#build` and `@objectstack/lint#build` (measured with `turbo run build:dist --filter=@objectstack/console --dry=json`), so a spec change misses the cache. | | `check-console-sha.mjs` | the local `packages/console/dist` was built from the pinned objectui commit | The pin it compared against is gone, so that drift cannot occur. A local dist can still be older than `ui/` after a pull; `pnpm console:build` rebuilds it (a turbo cache hit when nothing changed). Nothing checks this on `pnpm dev` any more: reported to the dispatcher. | | `console-spec-probes.mjs` | the shared probe derivation for the two injection checks above | Left with them; nothing else imported it. | ## Verification (merged tree at objectui@cd70b7818; the 17b/17c items re-measured on verify head `9e37acd126`) - `pnpm changeset version` on the cutover head `1c0d02eda4` (objectstack#25825, objectui frozen at `9e1fe03286`) + this PR + the ui patch: exit 0, and all 112 members move 18.1.0 → 18.2.0 together (111 public: 73 `@objectstack/*` and 38 `@object-ui/*`, plus `object-ui`). The private, ignored `@object-ui/runner` stays at 18.1.0. On that tree root and objectui `check-changeset-fixed` and `check:lockstep-package-count` exit 0. - Earlier, on verify head `9e37acd126` (when `@object-ui/runner` was still public): all 113 members move 18.1.0 → 18.2.0 in one bump: 112 public (73 `@objectstack/*`, 39 `@object-ui/*`) and the private extension `object-ui`. The other private `@objectstack/*` packages move as they do on `main`. `pnpm -r publish` and `release-verify-npm` skip `object-ui` (private), so nothing it owes the registry changes. - `pnpm -r publish --dry-run` after the version (at `9e37acd126`): 112 packages, 39 `@object-ui/*` + 72 `@objectstack/*` + `create-objectstack`, all 18.2.0. `pnpm pack` of `@object-ui/core`: `@objectstack/spec` `workspace:^` → `^18.2.0`, `@object-ui/types` `workspace:*` → `18.2.0`. - `pnpm console:build` (CI=true): exit 0, single-zod canary green. The packed `@objectstack/console` has the same top-level `dist/` entries as the published 18.1.0 tarball, minus `dist/.objectstack-injection.json` and `dist/.objectui-sha`; assets 2,268 → 2,381 (newer objectui), tarball 9,260K → 9,140K. - Console eager-closure budget (`ui/scripts/check-eager-closure-budget.mjs`, ceiling 3,496.0 KB): this build 3,054.2 KB gzipped, `vendor-objectstack` 1,605.2 KB; the published 18.1.0 dist measured by the same ceilings: 3,522.3 KB, `vendor-objectstack` 1,851.5 KB. The membership half is red identically on both (`packages/core`: 1 of 89 modules in `vendor-objectstack`), so it predates this PR. - The ui-side patch on verify head `9e37acd126`: `git apply --check` passes after README steps 1–2 and reproduces the edited `ui/` tree byte for byte (60 files). With this PR's root half, install and `pnpm run build`: `type-check:scripts`, `type-check:vitest-config`, `lint:root` exit 0; root and objectui `check-changeset-fixed` pass; `vitest run scripts/__tests__` 17 failed / 5,573 passed, where 2 are 15 s load timeouts that pass alone, 2 fail the same way without the patch (`check-lockfile-integrity`; `quick-reference-commands-4149` on the root scripts the adaptation drops, cutover bill), and 14 read objectui's nested `ui/.github/`, which 4b PR 2 deletes. - actionlint 1.7.7 over `release.yml`, `cut-rc.yml`, `lint.yml`, `showcase-smoke.yml`: exit 0. No step reads a pin file. ## Gates (this branch, no `ui/`) `dispatch-gates --commands` derives 166 families for this diff; all 166 ran, and `dispatch-gates --ran` reconciles: 164 run, 2 NOT-MEASURED. All were run on head `4ac569dc00` (after merging `main` at `f0cf338330`, which had moved `.objectui-sha` and the root `build` script), after a full `pnpm run build`. 156 exit 0, including `check:required-contexts`, `check:workflow-status-functions`, `check:workflow-step-name-quoting`, `check-changeset-no-major`, `check-empty-changeset`, `check-adr-0087-registration`, `check:lockstep-package-count` (112) and `check:nul-bytes`. One is red on `main` itself and not this PR's: `check:liveness` (`translation/flows.screens` cites `service-automation/src/engine.ts`, which #25734 refactored; this PR touches neither). The other 9 are red or not measured because `ui/`, PR B or 4b has not landed yet, as designed: | Gate | Exit | Why red here | Clears when | |---|---|---|---| | `check-changeset-fixed` | 1 | the 38 `@object-ui/*` names and `object-ui` in `fixed` have no package without `ui/` (on cutover head `1c0d02eda4` + this PR + the ui patch: exit 0, 111 public + 1 declared private) | sub-issue 5 | | `check-prerelease-pin-watch --self-test`, `--verbose` | 1, 1 | named only by `prerelease-pin-watch.yml`; this PR deletes the script | PR B of #25697 | | `check-self-test-wired --self-test` | 1 | `ci.yml` `console-pin` and `prerelease-pin-watch.yml` still invoke deleted scripts | PR B of #25697 | | `check:pm-dispatch-gates` | 1 | 3 of 1,913 fast-tier cases, all on the same live invocations of deleted scripts | PR B of #25697 | | `check:console-sha`, `check:console-injection` | NOT-MEASURED (254) | root scripts deleted here; only the `console-pin` job names them | PR B of #25697 | | `check-sdui-manifest`, `check:sdui-lockstep` | 1, 1 | they read `.objectui-sha` | 4b PR 2 (#25712) | ## Depends on, outside this PR - **Sub-issue 5** (subtree PR): adds `ui/`; this PR merges right after it. - **PR B of #25697** (retire the pin gates in the cutover window): removes the `console-pin` job and `console` filter in `ci.yml`, `prerelease-pin-watch.yml`, and the live specimens in the `dispatch-gates` self-test that still name `check-prerelease-pin-watch.mjs`. Until it lands, `prerelease-pin-watch.yml` runs a script this PR deletes. - **4b PR 2 (#25712)**: `check-sdui-lockstep`, `check-sdui-manifest` and `gen-sdui-manifest-node` read `.objectui-sha` and go red without it; regenerating `sdui.manifest.json` from `ui/` is theirs (the root copy lags the old pin, and `build-dist.sh` ships the tracked one). Also the nested `ui/.github/` and the tests that read it, and both AGENTS.md files. - **Maintainer**: the npm token's `@object-ui` publish rights (card risk 1) — confirmed by Tesla, ruling 17a. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent fd40831 commit 2a61f08

93 files changed

Lines changed: 1424 additions & 25864 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
'@objectstack/console': patch
3+
'@objectstack/cli': patch
4+
---
5+
6+
build(console): `@objectstack/console` is built in this workspace from `ui/apps/console`, and the Console no longer arrives through a pinned objectui commit
7+
8+
Clause-②: no
9+
Metadata-protocol: none
10+
11+
- **The package.** `@objectstack/console` ships the same `dist/` it shipped at 18.1.0: the built Console (`index.html`, `assets/`, the manifests it served). Two files leave the tarball: `dist/.objectui-sha`, which named the objectui commit the Console was built from, and `dist/.objectstack-injection.json`, which recorded the spec and client dists injected into that build. Both described a pin that no longer exists: the Console is built from the `ui/` tree of the same commit as the framework, so its version is the framework's version.
12+
- **The CLI.** When a framework checkout has no built Console, `objectstack serve` / `objectstack dev` and the 503 at `/_console/` now name `pnpm console:build`, which builds `ui/apps/console` and copies its dist into `packages/console`. The remedy used to be `pnpm objectui:build`, which cloned objectui at the pinned commit.
13+
- **One version.** The `@object-ui/*` packages and the private VS Code extension join the `@objectstack/*` fixed group, so every public package of both scopes publishes at one version and the extension ships at it.
14+
15+
What to do: nothing as a consumer; install `@objectstack/console` as before. In a framework checkout, run `pnpm console:build` where you ran `pnpm objectui:build`.

‎.changeset/config.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@
118118
"@object-ui/react",
119119
"@object-ui/react-runtime",
120120
"@object-ui/sdui-parser",
121-
"@object-ui/types"
121+
"@object-ui/types",
122+
"object-ui"
122123
]
123124
],
124125
"linked": [],

‎.github/workflows/cut-rc.yml‎

Lines changed: 33 additions & 167 deletions
Large diffs are not rendered by default.

‎.github/workflows/lint.yml‎

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,31 +3064,6 @@ jobs:
30643064
continue-on-error: true
30653065
run: pnpm check:startup-registry-verdict
30663066

3067-
# objectui pin-changeset guard (#4731). A frontend-only refresh reaches the
3068-
# platform release record ONLY through the changeset `bump-objectui.sh`
3069-
# writes, and that list used to be guessed off objectui's commit subjects
3070-
# (`feat|fix` + a silent `head -40`). On one real range the guess dropped
3071-
# all 13 releasing non-feat/fix commits — every breaking `refactor(...)!`
3072-
# among them — and pulled in 5 that release nothing. The list and the bump
3073-
# level now come from what objectui DECLARED (`.changeset/*.md` added over
3074-
# the range; empty frontmatter = release-nothing). This self-test builds
3075-
# throwaway git repos carrying those exact shapes, runs the real scripts
3076-
# over them, and asserts the emitted changeset — including that a cap which
3077-
# fires announces itself and that an unwalkable range degrades loudly.
3078-
# #4843 folded `scripts/objectui-range.mjs` — the release page's Console
3079-
# section — onto that same `classifyRange()` criterion, so both self-tests
3080-
# run here: one criterion, two consumers, no room to drift apart.
3081-
- name: objectui pin-changeset digest guard
3082-
id: objectui-pin-changeset-digest-guard
3083-
continue-on-error: true
3084-
run: pnpm check:objectui-changeset
3085-
3086-
# Rationale: `scripts/bump-objectui.selftest.sh` header (#10797).
3087-
- name: objectui pin write-ordering guard
3088-
id: objectui-pin-write-ordering-guard
3089-
continue-on-error: true
3090-
run: pnpm check:objectui-bump
3091-
30923067
# Changeset-family gate self-tests (#6509). The SELF-TEST halves only —
30933068
# the real scans stay in pr-automation.yml's `changeset-check`, and the
30943069
# split is the whole point of this step.

‎.github/workflows/release.yml‎

Lines changed: 18 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,109 +1835,26 @@ jobs:
18351835
run: node scripts/check-changeset-fixed.mjs
18361836

18371837
# ──────────────────────────────────────────────────────────────────────
1838-
# ⛔ TOMBSTONE — the #3340 pin-currency gate that used to sit here is gone
1839-
# (2026-08-20 ruling, #10134). Do not re-add one.
1838+
# ⛔ TOMBSTONE — no objectui pin is read, built or checked here, and none
1839+
# is re-added (objectstack#25711, D1 ruling 「同一个版本号组」).
18401840
#
1841-
# It compared `.objectui-sha` against objectui `main` at publish time and
1842-
# refused a release whose pin lagged. The ruling removed the question, not
1843-
# just the job: WHICH objectui revision this repo pins is a decision taken
1844-
# in an objectstack issue, never derived from another repo's HEAD, so
1845-
# "the pin is behind main" is not a defect a release lane may diagnose.
1846-
#
1847-
# R4's lesson (#6170 — "a gate required on a PR the publishing lane can
1848-
# skip is not a gate") is untouched and does not resurrect this one:
1849-
# #3340's actual invariant is "everything published is covered by the
1850-
# changeset record", and that is carried by `scripts/bump-objectui.sh` +
1851-
# `scripts/objectui-changeset-digest.mjs` at BUMP time — on the manual pin
1852-
# PR, which is now the only way the pin ever moves. Publishing an old
1853-
# console is therefore a published decision, not an unnoticed gap.
1841+
# The Console is a workspace package now: `ui/apps/console`
1842+
# (@object-ui/console) builds against this tree's @objectstack/* through
1843+
# `workspace:^`, and `@objectstack/console#build:dist` (root turbo.json)
1844+
# copies that dist with the tracked sdui.manifest.json; `pnpm run release`
1845+
# runs it (`pnpm run console:build`) after the build below. The
1846+
# pin-currency gate, the vendored-dist cache keyed on `.objectui-sha`,
1847+
# its SHA stamp check and
1848+
# its spec-injection check are gone with the pin: each answered "was the
1849+
# Console built from the objectui commit, and against the spec, this
1850+
# release names", and both are true by construction when the Console
1851+
# source and the spec are one tree at one commit. The single-zod canary
1852+
# survives inside packages/console/build-dist.sh, on the bytes it ships.
18541853
# ──────────────────────────────────────────────────────────────────────
18551854

18561855
- name: Build
18571856
run: pnpm run build
18581857

1859-
- name: Read the spec's declared zod range (Console dist key input)
1860-
id: spec-zod
1861-
# Fails rather than keying on an empty or `undefined` range: a key that
1862-
# silently stopped carrying the range would restore across a zod move.
1863-
run: |
1864-
node -e '
1865-
const range = require("./packages/spec/package.json").dependencies?.zod;
1866-
if (typeof range !== "string" || range.trim() === "") {
1867-
console.error("packages/spec/package.json declares no dependencies.zod, so the Console dist key cannot carry it.");
1868-
process.exit(1);
1869-
}
1870-
console.log("range=" + range.trim());
1871-
' >> "$GITHUB_OUTPUT"
1872-
1873-
# This key hashes the pin and the build script, and carries the spec's
1874-
# DECLARED zod range (the step above). ci.yml's Console Pin Gate (#4290)
1875-
# hashes a SUPERSET of the files: those two, the probe scripts and the
1876-
# spec's entry layout (#20765). So the two workflows no longer share dist
1877-
# entries, and each one builds its own on a miss. Keeping this key narrower
1878-
# is deliberate.
1879-
# Following ci.yml would rebuild the console on every Version Packages
1880-
# merge, and publishing a cached console whose spec content lags is the
1881-
# existing cache design.
1882-
#
1883-
# The zod range is the one spec input the cached dist is NOT allowed to
1884-
# lag (#21108). The console bundles a single zod instance, the console's
1885-
# own copy, and its build refuses a console zod outside the injected spec's
1886-
# declared `zod` range (objectui#11353). A dist restored after that range
1887-
# moved would publish a console the build never judged against it. The
1888-
# range is read out of packages/spec/package.json, not hashed with it: the
1889-
# file's `version` moves on every Version Packages merge, and hashing the
1890-
# whole file would turn every publish into a cold console rebuild.
1891-
#
1892-
# Split restore/save, matching ci.yml, and not the combined actions/cache
1893-
# action: the combined form's post-step saves even when the job FAILED,
1894-
# and build-console.sh writes the SHA stamp BEFORE it asserts the bundle
1895-
# canary — so a canary failure here would seed this shared, repo-scoped
1896-
# key with a stamped-but-broken dist that later runs restore and sail
1897-
# through. See ci.yml's split-restore note for the full rationale.
1898-
- name: Restore vendored Console dist (keyed on the objectui pin)
1899-
id: console-dist-cache
1900-
uses: actions/cache/restore@v6
1901-
with:
1902-
path: packages/console/dist
1903-
key: ${{ runner.os }}-console-dist-${{ hashFiles('.objectui-sha', 'scripts/build-console.sh') }}-zod-${{ steps.spec-zod.outputs.range }}
1904-
1905-
- name: Build vendored @objectstack/console SPA
1906-
# Clones objectstack-ai/objectui at the SHA pinned in .objectui-sha,
1907-
# builds @object-ui/console, and copies dist/ into
1908-
# packages/console/dist/. Must run before publish so the prepublishOnly
1909-
# guard in @objectstack/console passes.
1910-
if: steps.console-dist-cache.outputs.cache-hit != 'true'
1911-
run: bash scripts/build-console.sh
1912-
1913-
- name: Verify Console dist stamp matches pin
1914-
run: pnpm check:console-sha
1915-
1916-
# The spec-injection half of the same question, spelled exactly as
1917-
# ci.yml's Console Pin Gate spells it — both consumers of one cache key
1918-
# apply one check. check:console-sha answers only "which objectui SHA",
1919-
# and scripts/assert-console-spec-injection.mjs runs INSIDE
1920-
# build-console.sh, which the `if: cache-hit != 'true'` above skips — so
1921-
# on a cache hit nothing had asked whether the dist this job is about to
1922-
# PUBLISH bundles this tree's @objectstack/spec rather than the published
1923-
# tarball. --require-stamp because the vacuity check:console-sha tolerates
1924-
# (no dist, or a dist no build ever stamped) is wrong on a publish lane.
1925-
- name: Verify the restored Console dist bundles this tree's spec
1926-
env:
1927-
CONSOLE_DIST_CACHE_KEY: ${{ runner.os }}-console-dist-${{ hashFiles('.objectui-sha', 'scripts/build-console.sh') }}-zod-${{ steps.spec-zod.outputs.range }}
1928-
run: pnpm check:console-injection --require-stamp
1929-
1930-
# Reached only with every console assertion above green: Actions steps
1931-
# default to `success()`, and nothing between the restore and here carries
1932-
# `if: always()` or `continue-on-error`. Saving only on a miss keeps an
1933-
# immutable entry from being rewritten on every release run.
1934-
- name: Save vendored Console dist
1935-
if: steps.console-dist-cache.outputs.cache-hit != 'true'
1936-
uses: actions/cache/save@v6
1937-
with:
1938-
path: packages/console/dist
1939-
key: ${{ runner.os }}-console-dist-${{ hashFiles('.objectui-sha', 'scripts/build-console.sh') }}-zod-${{ steps.spec-zod.outputs.range }}
1940-
19411858
- name: Downstream backward-compat smoke (live hotcrm)
19421859
# Pre-publish gate (#2035): the about-to-publish @objectstack/spec must
19431860
# not break a real third-party consumer pinned to a published release.
@@ -2031,9 +1948,10 @@ jobs:
20311948
run: bash scripts/release-spec-changes.sh --verify
20321949

20331950
# ──────────────────────────────────────────────────────────────────────
2034-
# The publish itself. `pnpm run release` = build + build-console +
2035-
# scripts/release-publish.sh, which is `changeset publish` followed by ONE
2036-
# atomic `git push origin --tags` (#2191: the action's concurrent per-tag
1951+
# The publish itself. `pnpm run release` = build (both scopes; the turbo
1952+
# cache makes it the build above) + console:build (the Console dist into
1953+
# packages/console) + scripts/release-publish.sh, which is `changeset
1954+
# publish` followed by ONE atomic `git push origin --tags` (#2191: the action's concurrent per-tag
20371955
# pushes raced GitHub's ref backend and lost ~half the tags).
20381956
#
20391957
# changesets/action is NOT used here, and that is deliberate: handed a

‎.github/workflows/showcase-smoke.yml‎

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,13 @@ jobs:
5555
# built `dist/`. Build the whole dependency closure (excluding the
5656
# showcase's own app build, which serve --dev doesn't need).
5757
- run: pnpm turbo run build --filter=@objectstack/example-showcase^...
58-
# The console SPA served at /_console is vendored by build-console.sh
59-
# (shallow-clones objectui@.objectui-sha, builds @object-ui/console, copies
60-
# dist → packages/console/dist). Without it serve --dev warns "Console dist
61-
# not found" and the app shell never renders.
62-
- name: Vendor the pinned Console SPA
63-
run: bash scripts/build-console.sh
64-
# Self-test the drift guard: a fresh build-console.sh must stamp the dist
65-
# with the pinned SHA so `pnpm check:console-sha` reports in-sync. Catches
66-
# a regression where the stamp step is dropped or the pin/stamp diverge.
67-
- name: Verify Console SHA stamp matches pin
68-
run: pnpm check:console-sha
58+
# The console SPA served at /_console is @objectstack/console's dist: a
59+
# copy of the workspace's own ui/apps/console build, which `build` does not
60+
# produce (packages/console/build-dist.sh, run by the `build:dist` task).
61+
# Without it serve --dev warns "Console dist not found" and the app shell
62+
# never renders.
63+
- name: Build the Console SPA from ui/apps/console
64+
run: pnpm console:build
6965
- name: Install Playwright Chromium
7066
working-directory: examples/app-showcase
7167
run: pnpm exec playwright install --with-deps chromium

‎.objectui-sha‎

Lines changed: 0 additions & 1 deletion
This file was deleted.

‎package.json‎

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
"description": "ObjectStack Protocol & Specification - Monorepo for TypeScript Interfaces, JSON Schemas, and Convention Configurations",
66
"scripts": {
77
"build": "turbo run build --filter=!@objectstack/docs --filter=!./ui*/apps/site",
8-
"dev": "node scripts/check-dev-prereqs.mjs && pnpm check:console-sha && pnpm --filter @objectstack/example-showcase dev",
9-
"dev:showcase": "node scripts/check-dev-prereqs.mjs && pnpm check:console-sha && pnpm --filter @objectstack/example-showcase dev",
10-
"dev:crm": "node scripts/check-dev-prereqs.mjs && pnpm check:console-sha && pnpm --filter @objectstack/example-crm dev",
11-
"dev:todo": "node scripts/check-dev-prereqs.mjs && pnpm check:console-sha && pnpm --filter @objectstack/example-todo dev",
8+
"dev": "node scripts/check-dev-prereqs.mjs && pnpm --filter @objectstack/example-showcase dev",
9+
"dev:showcase": "node scripts/check-dev-prereqs.mjs && pnpm --filter @objectstack/example-showcase dev",
10+
"dev:crm": "node scripts/check-dev-prereqs.mjs && pnpm --filter @objectstack/example-crm dev",
11+
"dev:todo": "node scripts/check-dev-prereqs.mjs && pnpm --filter @objectstack/example-todo dev",
1212
"spec:rebuild": "turbo run build --filter=...@objectstack/spec",
1313
"test": "VITEST_MAX_WORKERS=$(node scripts/vitest-worker-cap.mjs) turbo run test test:repo --concurrency=50%",
1414
"test:smoke": "turbo run test:smoke",
@@ -18,16 +18,13 @@
1818
"prepare": "node scripts/setup-git-hooks.mjs",
1919
"check:merge-driver": "node scripts/git-env.mjs --self-test && node scripts/git-merge-regen.mjs --self-test && node scripts/check-regen-pending.mjs --self-test",
2020
"version": "node scripts/release-pending-publish.mjs annotate-shipped; changeset version && node scripts/sync-protocol-version.mjs && node scripts/sync-template-versions.mjs && node scripts/sync-docs-image-tags.mjs && node scripts/sync-release-index-currency.mjs && node scripts/check-skill-compatibility-version.mjs --fix",
21-
"release": "pnpm run build && bash scripts/build-console.sh && bash scripts/release-publish.sh",
21+
"release": "pnpm run build && pnpm run console:build && bash scripts/release-publish.sh",
2222
"docs:dev": "pnpm --filter @objectstack/docs dev",
2323
"docs:build": "pnpm --filter @objectstack/docs build",
2424
"docs:start": "pnpm --filter @objectstack/docs start",
2525
"os": "node packages/cli/bin/run.js",
26-
"objectui:build": "bash scripts/build-console.sh",
26+
"console:build": "turbo run build:dist --filter=@objectstack/console",
2727
"gen:sdui-lockstep": "node scripts/check-sdui-lockstep.mjs --update",
28-
"objectui:bump": "bash scripts/bump-objectui.sh",
29-
"objectui:refresh": "bash scripts/bump-objectui.sh && bash scripts/build-console.sh",
30-
"objectui:clean": "rm -rf packages/console/dist .cache/objectui-*",
3128
"lint": "node --stack-size=4000 node_modules/eslint/bin/eslint.js . --no-inline-config",
3229
"i18n:extract": "tsx packages/cli/bin/run-dev.js i18n extract packages/platform-objects/scripts/i18n-extract.config.ts --locales=zh-CN,ja-JP,es-ES --fill=default --source-hashes --out=packages/platform-objects/src/apps/translations",
3330
"check:i18n": "node scripts/check-i18n-bundles.mjs --self-test && node scripts/check-i18n-bundles.mjs",
@@ -147,12 +144,7 @@
147144
"check:optional-error-sink": "node scripts/check-optional-error-sink-contract.mjs --self-test && node scripts/check-optional-error-sink-contract.mjs",
148145
"check:logger-receiver-detach": "node scripts/check-logger-receiver-detach.mjs --self-test && node scripts/check-logger-receiver-detach.mjs",
149146
"check:startup-registry-verdict": "node scripts/check-startup-registry-verdict.mjs --self-test && node scripts/check-startup-registry-verdict.mjs",
150-
"check:console-sha": "node scripts/check-console-sha.mjs",
151-
"check:console-injection": "node scripts/check-console-injection.mjs --self-test && node scripts/check-console-injection.mjs",
152147
"check:dev-prereqs": "node scripts/check-dev-prereqs.mjs --self-test && node scripts/check-dev-prereqs.mjs",
153-
"check:objectui-changeset": "node scripts/objectui-changeset-digest.mjs --self-test && node scripts/objectui-range.mjs --self-test",
154-
"check:objectui-bump": "bash scripts/bump-objectui.selftest.sh",
155-
"check:prerelease-pins": "node scripts/check-prerelease-pin-watch.mjs --self-test && node scripts/check-prerelease-pin-watch.mjs",
156148
"check:empty-changeset": "node scripts/check-empty-changeset.mjs --self-test && node scripts/check-empty-changeset.mjs",
157149
"check:adr-0087-registration": "node scripts/check-adr-0087-registration.mjs --self-test && node scripts/check-adr-0087-registration.mjs",
158150
"check:changeset-gate-self-tests": "node scripts/check-empty-changeset.mjs --self-test && node scripts/check-adr-0087-registration.mjs --self-test && node scripts/check-changeset-no-major.mjs --self-test",

0 commit comments

Comments
 (0)