Skip to content

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

Merged
os-zhuang merged 16 commits into
mainfrom
claude/project-thread-a0vh3h
Oct 25, 2026
Merged

os-zhuang merged 16 commits into
mainfrom
claude/project-thread-a0vh3h

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

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

🤖 Generated with Claude Code

https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe

… objectui pin (objectstack#25711, WIP)

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
…the in-workspace Console build (objectstack#25711, WIP)

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
…ts as live specimens (objectstack#25711, WIP)

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
…ted pin pieces (objectstack#25711, WIP)

- check-pnpm-filter-targets: the foreign-scope live assertion is tree-aware;
  without ui/ no committed filter names @object-ui/ (build-console.sh left).
- pnpm-filter-targets: the @object-ui/ foreign entry states its new cause and
  when it retires (the PR that lands ui/).
- collect-release-notes: section 3 reads a pinless ref instead of failing on
  the missing .objectui-sha.
- bare-root-worklist: the two check-console-injection UNJUDGED rows are gone
  with the gate.
- check-type-check-coverage: the @objectstack/console EXEMPT note names
  build-dist.sh.
- dispatch-gates self-test: the prerelease-pin-watch literal specimen leaves.
- cut-rc builds the Console before the version commit; release.yml and
  cut-rc comments name console:build; packages/console README describes the
  in-workspace build.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
…window, and the changeset (objectstack#25711, WIP)

scripts/ui-import/4a-ui-side.patch removes objectui's pin on objectstack, the
dist-injection Vite probes, objectui's own release lane and its own Changesets
config inside ui/. ui/ does not exist on main until the subtree PR of sub-issue
5, so it ships as a patch with its apply and verify commands in the README.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
…list drops the deleted Console test (objectstack#25711, WIP)

check:lockstep-package-count derives the count from the fixed group, which now
holds both scopes (73 @objectstack + 39 @object-ui). vitest.repo-tests.json still
named build-console-objectstack-root.test.ts, deleted with build-console.sh.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
… relative link (objectstack#25711, WIP)

A relative href is a 404 on npm, and on GitHub until ui/ lands.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Dispatch seat note — HELD, do not merge before the cutover window. Content ACCEPTed on card #25711 (comment there carries the checks and rulings). check-governed-merges --pr objectstack-ai/objectstack#25745: GOVERNED, tier H(人合) — .github/workflows/** ×4, 12,835 changed lines > 3,000. By the order this PR is red on main by design until the ui/ subtree lands (child 5): check-changeset-fixed needs ui/; ci.yml's console-pin and pin-watch jobs still invoke scripts this PR deletes until PR B of #25697 lands beside it. So: stays draft, no review requested, not enqueued. In the cutover window the seat posts the final 维护者速读 and 席位核对 here, labels the PR, and requests review from GOVERNED_APPROVERS; it lands only after an authorized APPROVED, together with child 5, PR B and 4b PR 2. Before that, git apply --check scripts/ui-import/4a-ui-side.patch is re-run against the final objectui main.


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review October 25, 2026 05:06
@os-zhuang
os-zhuang enabled auto-merge October 25, 2026 05:06
@objectstack-fleet
objectstack-fleet Bot disabled auto-merge October 25, 2026 05:07
@objectstack-fleet
objectstack-fleet Bot marked this pull request as draft October 25, 2026 05:07
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Dispatch seat — HOLD reaffirmed. @os-zhuang please leave this PR in draft until the seat opens the cutover window.

At 05:06Z this PR was approved, marked ready and had auto-merge enabled. At 05:07Z the card thread put it back to draft and disabled auto-merge; the approval (review 5641652106) stands untouched. Nothing was lost, but had the queue taken it, main would have gone red: by the order this PR is red on main by design until the ui/ subtree lands — check-changeset-fixed needs ui/, and the console-pin / pin-watch jobs in ci.yml still invoke scripts this PR deletes until PR B of #25697 lands beside it (seat note above, 05:0x; card #25711 carries the ACCEPT and the rulings).

Landing order for the cutover window (epic #25677, child 5 procedure): subtree import + adaptation → this PR (4a) → PR B of #25697 → 4b PR 2 (#25712). In that window the seat posts the final 维护者速读 and ## 席位核对 here, flips ready, and requests review from GOVERNED_APPROVERS; the PR lands only after an authorized APPROVED given at that point. Until then: draft, no review requested, not enqueued. A ready/auto-merge flip before that is reverted by the seat.

If the hold itself should be overruled, that is Tesla's call, in the epic's decision thread, not on this PR.


Generated by Claude Code

… and the QUICK_REFERENCE release sync retires (objectstack#25711, WIP)

Tesla's rulings of 2026-10-25: decision 17b, ruling B, keeps the private VS Code
extension `object-ui` in the fixed group. The root check-changeset-fixed now
accepts a declared private member (PRIVATE_FIXED_MEMBERS) while
privatePackages.version is true, and check:lockstep-package-count counts
published members only. The ui-side patch drops its private-arm change to
objectui's check-changeset-fixed and keeps the extension rows of
check-unused-dependencies. Decision 17c, ruling B, is carried in the same patch:
QUICK_REFERENCE.md's synced "Current Release" rows, the sync script and its two
tests retire. The patch is regenerated against verify head 9e37acd.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
…1, WIP)

main moved .objectui-sha (#25735) and the root build script (#25738); the pin stays
deleted and the build keeps main's site exclusion.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
os-zhuang pushed a commit that referenced this pull request Oct 26, 2026
…e Pin Gate, prerelease-pin-watch (#25827)

Part of #25697 (item 6, PR B). PR A (#25710) carried items 1 to 5 and is
merged; the card stays open for the epic PM, who hands this PR to the
cutover.
Blocked-by: #25752 (cutover PR first)
Part of objectstack#25677

Clause-②: no
Metadata-protocol: none

## What this retires

Once `ui/` lives in this repository, the gates that proved the objectui
pin from the outside have nothing left to prove. This PR deletes them:

- `.github/workflows/spec-shape-gate.yml` (**Spec Shape Gate**), with
`scripts/ci/spec-shape-gate.mjs` and
`scripts/ci/spec-shape-retirements.json`.
- The `console-pin` job (**Console Pin Gate**) in `ci.yml`, and the
`console` list and output of its `filter` job.
- `.github/workflows/prerelease-pin-watch.yml` (**Stable release
watch**).
- The `Spec Shape Gate` row of `RELEASE_GATE_WORKFLOWS` in
`scripts/ci/scheduled-full-run.mjs`. The release gate now reads `CI` and
`Lint & Type Check`. `release.yml` and `cut-rc.yml` have no read of
their own (measured); both reach the roster only through
`scheduled-full-run.mjs --release-gate`.

What replaces them is already on `main` from PR A: `Type Check UI` and
`Build & E2E UI` compile and build the Console from `ui/` in the PR that
changes one of the seven packages objectui installs (`ui_consumers`
filter).

The console scripts (`build-console.sh`, `check-console-sha.mjs`,
`check-console-injection.mjs`, `console-spec-probes.mjs`,
`assert-console-spec-injection.mjs`) stay, as the order says. 4a #25745
deletes them with the pin.

## Hit-class table

Census: `git grep -n -E 'spec-shape-gate|Spec Shape
Gate|spec-shape-retirements|prerelease-pin-watch|Console Pin
Gate|console-pin'` at the base `52f3f518e1` gives 169 hits in 33 files.
Also posted on the card:
#25697 (comment)

| Class | Files (hits) | Treatment |
|---|---|---|
| The retired gates themselves | `spec-shape-gate.yml` (15),
`scripts/ci/spec-shape-gate.mjs` (21),
`scripts/ci/spec-shape-retirements.json` (1), `prerelease-pin-watch.yml`
(6) | deleted |
| `ci.yml` job and filter | `ci.yml` (7) | `console-pin` job, `console`
filter list and output deleted; the comments that pointed at them
re-worded |
| Release-gate roster | `scripts/ci/scheduled-full-run.mjs` (19) |
roster row dropped; the self-tests that encoded a three-row roster are
rewritten to the two-row roster with the same assertion shape (none
deleted or skipped); two dated diagnosis fixtures kept verbatim |
| Gates that encode the deleted job or script |
`check-ci-filter-parity.mjs` (5), `check-expected-skips.mjs` (5),
`dispatch-gates.self-test.mjs` (20), `dispatch-gates.mjs` (7) |
filter-parity `console` subject retired with its battery (floor 10 to
9); the `Console Pin Gate` expected-skip row removed and its recorded
runs re-spelled to the live roster; the live-tree job-filter cases
re-pointed at `Build Core`; synthetic specimens kept; tense fixes |
| Orphan the deletion forces | `scripts/check-prerelease-pin-watch.mjs`
(15), `package.json` (2) | deleted, with the `check:spec-shape-gate` and
`check:prerelease-pins` aliases (deviation 1) |
| Instruction prose naming a deleted gate as live | `AGENTS.md` (2),
`docs/releases-maintenance.md` (2) | prose fixes, listed below |
| Comments naming a retired gate as live | `cut-rc.yml:358`,
`docs-deploy.yml`, `lint.yml` (2), `release-coverage-patrol.yml`,
`release.yml:1510`, `check-release-section-coverage.mjs` (2),
`check-self-test-workflow-commands.mjs`,
`check-vendor-version-stamps.mjs` (2), `check-required-contexts.mjs` |
past tense, or a one-paragraph addendum to the existing tombstone |
| Left for 4a #25745, which deletes or rewrites them |
`release.yml:1874` and `:1917`, `cut-rc.yml:383`,
`packages/console/README.md:54`, `check-console-injection.mjs` (6) |
untouched here, so the two PRs do not conflict on them |
| Dated history and fixtures | `docs/audits/*` (5),
`scripts/docs-audit/README.md`,
`scripts/fixtures/merge-queue-triage/*.json` (2), the
`fleet-write/validate.mjs` fixture,
`packages/spec/liveness/dashboard.json:146`, `pnpm-workspace.yaml:184`,
the #9533 tombstone in `check-required-contexts.mjs` | kept as written |

## Tier H prose touched

- `AGENTS.md` line 533: drops `Console Pin Gate` from the list of
full-battery jobs.
- `AGENTS.md` lines 1103 to 1104: the sibling-removal rule named the
full battery's `Console Pin Gate` as what reds a breaking removal on
`main`. It now names `Type Check UI`, which compiles the Console under
`ui/` in the PR that makes the removal. Line count unchanged (1117, the
ratchet ceiling).
- `docs/releases-maintenance.md`: the "What still checks the pin"
paragraph is now "What used to check the pin", and the release-gate
roster reads `CI`, `Lint & Type Check`.

No ADR is touched.

## Required contexts that vanish

**None.** Read at the time of this PR: the `main` ruleset requires
`TypeScript Type Check`, `Test Core`, `Build Core`, `Lint & Repo Gates`,
`Governed Surface Queue Guard`, and classic branch protection requires
`TypeScript Type Check`, `Build Core`, `Test Core`, `Dogfood Regression
Gate`. Neither `Spec Shape Gate` nor `Console Pin Gate` is in either
list, so the sitting needs no ruleset change for this PR. `node
scripts/check-required-contexts.mjs --verify-required-set` exits 0: the
registry and the live set agree in both directions.

## Landing with 4a #25745

This PR and 4a are two halves of one change and land as a batch, 4a
first:

- **On `main` alone this PR is red in one place.** The order keeps
`check-console-injection.mjs` and `console-spec-probes.mjs` until 4a and
deletes `Console Pin Gate`, their only PR-time runner. Two live-tree
cases of the dispatch-gates fast tier then red: the silent load-break
pair `check:console-injection` from `console-spec-probes.mjs`, and the
`pull_request`-only narrowing of the scheduled-only zero. That step
belongs to `Lint & Repo Gates`. With 4a merged first, the same tier
passes 1917 of 1917 (verification record below). Neither case was
weakened.
- **Two files overlap.** `package.json` (both PRs delete the
`check:prerelease-pins` alias) and one comment in
`scripts/pm/dispatch-gates.self-test.mjs` near line 1006. Take the
`main` side (4a) in both; checked on the local merge below.

## Deviations from the order

1. `scripts/check-prerelease-pin-watch.mjs` and its
`check:prerelease-pins` alias are deleted here as well. Once the
workflow is gone the script has no CI caller and `check-self-test-wired`
reds the orphan. 4a deletes the same file, so the two deletions agree.
2. `prerelease-pin-watch.yml` does not watch the objectui pin. It
watched better-auth prerelease overrides in `pnpm-workspace.yaml`, and
its watch list was already empty. It is deleted as ordered.
3. Beyond the order's file list, these gates had to follow the deletion
so they stay true: `check-ci-filter-parity.mjs`,
`check-expected-skips.mjs`, `dispatch-gates.self-test.mjs`. Each keeps
its assertion shape; nothing is skipped or loosened.

## Verification record

Head `1776dbd798a4ebde5abc974e5b8d01c6db3fd3ef`, base `52f3f518e1`.

- **Derived gate sweep** (`node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack`): 86 derived, 82 run. 81 exit 0.
`pnpm check:pm-dispatch-gates` exits 1 (the two cases above, 2 of 1917).
4 exit 3, prerequisite not met, because they need every workspace dist
built: `check:dts-closure`, `check:dual-build-cjs-loads`,
`check:lean-entry-closure`, `check:sourcemap-no-sources-content`. `Build
Core` runs them on this PR. `dispatch-gates.mjs --ran`: 86 accounted, 0
unrun.
- **Named by the order:** `node scripts/ci/scheduled-full-run.mjs
--self-test` 0, `pnpm check:shard-attestation` 0, `pnpm --filter
@objectstack/spec check:liveness` 0, `check-required-contexts.mjs
--verify-required-set` 0.
- **Merged tree** (`main` `abebc4e14d` + 4a `4ac569dc00` + this PR,
local, conflicts resolved to the `main` side): `pnpm
check:pm-dispatch-gates` exit 0 (fast tier 1917 of 1917). The same
86-command sweep on the merged tree: 80 exit 0, 6 exit 3 (prerequisite
not met: the throwaway worktree has no package dists or package-level
installs, so `check:doc-formula-expressions` and `check:type-check-debt`
join the four above; both exit 0 on this branch), no finding.

```text
exit  command (this branch, head 1776dbd)
0  node scripts/check-aggregator-roster.mjs
0  node scripts/check-aggregator-roster.mjs --self-test
0  node scripts/check-ci-filter-parity.mjs
0  node scripts/check-ci-filter-parity.mjs --self-test
0  node scripts/check-closing-keyword-parity.mjs
0  node scripts/check-closing-keyword-parity.mjs --self-test
0  node scripts/check-comment-mask-corpus.mjs
0  node scripts/check-declaration-mirrors.mjs
0  node scripts/check-declaration-mirrors.mjs --self-test
0  node scripts/check-dts-emitted.mjs --self-test
0  node scripts/check-merged-branch-reaper-outcome.mjs
0  node scripts/check-merged-branch-reaper-outcome.mjs --self-test
0  node scripts/check-position-name-fold-loaders.mjs
0  node scripts/check-position-name-fold-loaders.mjs --self-test
0  node scripts/check-release-section-coverage.mjs
0  node scripts/check-release-section-coverage.mjs --self-test
0  node scripts/check-release-section-coverage.mjs --strict
0  node scripts/check-scripts-symbol-anchors.mjs
0  node scripts/check-scripts-symbol-anchors.mjs --self-test
0  node scripts/check-self-test-wired.mjs
0  node scripts/check-self-test-wired.mjs --self-test
0  node scripts/check-self-test-workflow-commands.mjs
0  node scripts/check-self-test-workflow-commands.mjs --self-test
0  node scripts/check-step-collectors.mjs
0  node scripts/check-step-collectors.mjs --self-test
0  node scripts/check-whole-set-label-write.mjs
0  node scripts/check-whole-set-label-write.mjs --self-test
0  node scripts/ci/assert-turbo-remote-cache.mjs --self-test
0  node scripts/ci/prune-turbo-cache.mjs --self-test
0  node scripts/ci/scheduled-full-run.mjs --self-test
0  node scripts/docs-audit/check-drift-comment.mjs
0  node scripts/pm/bare-root-worklist.mjs --self-test
0  node scripts/pm/ci-failure.mjs --self-test
0  node scripts/release-dist-tags.mjs --self-test
0  node scripts/release-verify-npm.mjs --self-test
0  node scripts/render-release-coverage-anchor.mjs --self-test
0  pnpm --filter @objectstack/lint run check:doc-formula-expressions
0  pnpm check:agent-test-spelling
0  pnpm check:bash32-floor
0  pnpm check:cli-command-ids
0  pnpm check:cross-package-test-inputs
0  pnpm check:declared-population-live
0  pnpm check:doc-authoring
0  pnpm check:docs-audit-scope
0  pnpm check:driver-memory-census
0  pnpm check:entry-guard
0  pnpm check:gitlink-declared
0  pnpm check:manifest-repository-directory
0  pnpm check:merge-driver
0  pnpm check:node-version
0  pnpm check:nul-bytes
0  pnpm check:parse-guard
0  pnpm check:pm-close-cards
0  pnpm check:pm-expected-skips
0  pnpm check:pm-fleet-write-dispatch
0  pnpm check:pm-fleet-write-execute
0  pnpm check:pm-fleet-write-validate
0  pnpm check:pm-governed-merges
0  pnpm check:pm-governed-prose
0  pnpm check:pm-issue-transfer
0  pnpm check:pm-post-stamped
0  pnpm check:pm-record-recognisers
0  pnpm check:pm-skill-id-lint
0  pnpm check:pm-skill-ratchet
0  pnpm check:pnpm-acquisition
0  pnpm check:pnpm-filter-targets
0  pnpm check:pnpm-flag-spellings
0  pnpm check:ratchet-remedy-authority
0  pnpm check:refd-timer-probe
0  pnpm check:required-contexts
0  pnpm check:select-gate-families
0  pnpm check:shard-attestation
0  pnpm check:stall-guard-budget
0  pnpm check:stall-guard-headroom
0  pnpm check:turbo-task-graph
0  pnpm check:type-check-coverage
0  pnpm check:type-check-debt
0  pnpm check:vendor-version-stamps
0  pnpm check:watch-hint-literal
0  pnpm check:workflow-status-functions
0  pnpm check:workflow-step-name-quoting
1  pnpm check:pm-dispatch-gates
3  pnpm check:dts-closure
3  pnpm check:dual-build-cjs-loads
3  pnpm check:lean-entry-closure
3  pnpm check:sourcemap-no-sources-content
```

## 维护者速读(草稿)

**改了什么**:删掉三个只为「跨仓库钉版本」存在的门禁:Spec Shape Gate(每小时拉 objectui main
编译一遍)、Console Pin Gate(按 `.objectui-sha` 克隆 objectui
构建控制台)、prerelease-pin-watch(盯 better-auth
预发布版本,清单早已为空)。发布前的全量电池名单从三个工作流减为 `CI` 与 `Lint & Type Check`。AGENTS.md
两处、发布维护文档一处把它们改为过去时。

**为什么改**:objectui 合入 `ui/` 之后,控制台在同一个 PR 里由 `Type Check UI`、`Build & E2E
UI` 编译构建,规格一改就当场验证,不再需要隔一小时去克隆另一个仓库。留着旧门禁只会对着已不存在的钉版本报错。

**风险与代价(含回滚)**:不影响必需检查(这三个都不在必需集合里)。必须在 4a #25745 之后合入:单独合入时 `Lint &
Repo Gates` 会因控制台脚本失去 PR 期运行者而红两条,4a 删除这些脚本后即消失。回滚就是还原此 PR,三个工作流与脚本原样恢复。

**席位意见**:

**你要做的**:切换当天在 4a 之后合入本 PR(Tier H,需你批准)。规则集无需改动。

---
_Generated by [Claude
Code](https://claude.ai/code/session_01H835wAyqCCeF7jiYq7XSxi)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/xl tests tooling

Projects

None yet

3 participants