Skip to content

cutover(ui-merge): the switch itself — freeze both repos, git subtree add objectui as ui/ with its adaptation commit, land 4a / PR B / 4b PR 2 in order, migrate open objectui branches and cards, archive the objectui repo (parent #25677, 5/6) #25752

Open

Description

@objectstack-fleet

Filing gate ③ + ④: sub-issue 5/6 of the epic #25677 (pm:epic; epic PM session_01RSDL3SFtJaKzcymvCD8RsU). Part of #25677. ⛔ Not a claim and ⛔ not dispatched to a dev seat: the epic PM runs this card step by step, and every step marked maintainer is Tesla's (repository settings, the human merges of the Tier H PRs, the archive click).

Blocked-by: #25697 (PR B, lands inside this window), #25711 (4a, lands inside this window), #25712 (4b PR 2, lands inside this window), #25727 (2c, its pre-freeze round is step 2 below). The parent's item 5 named 3 and 4 as the blockers; this card is where their last PRs land, so they block the merge step, not the card's start.

谁付代价(业务筛): every day the two repos stay separate costs the fleet the pin PRs (~40/month), the three-serial-PR shape of every cross-repo feature and 24 × 13 min of Spec Shape Gate; users get Console/spec version consistency by injection only (11.5.0 shipped an old client that way). The parent's 维护者速读 carries the readings; this card is the day the cost stops.

维护者速读

这张卡就是切换日的流程表。前面的子单把两边都准备好了(objectui 侧 2–2e 五轮就绪、objectstack 侧惰性接线 A/A2、发布合一 4a 草稿、治理 4b 第 1 刀),验证分支 #25718 已经跑了 7 轮,剩下的红全部归类并有归属(下面「切换 PR 自带的适配」逐条列)。切换那天:提前 24 小时通知、两仓冻结 1–2 天、一个约 259 万行的 subtree PR 由你人工合并、紧接着按顺序合 4a → PR B → 4b PR 2(都是 Tier H,都要你批)、ruleset / required checks / npm token 由你改、objectui 仓 README 改迁移说明后归档。你的四个动作都在「maintainer」标记处;其余由席位做并逐步在本卡留审计评论。七项决定(A–G)你已于 10-25 09:06Z 裁定,见最后一节;冻结前先落三张预备卡(2c 第二轮、E、F)。

Procedure (the seat drives; maintainer steps are Tesla's)

  1. T-24h notice (seat): one comment here and one on objectui's pinned seat note naming the freeze window; land every green PR in both repos; Dependabot paused on objectui for the window. After this comment nothing new is enqueued in objectui.
  2. Final objectui round (seat → 2c round 2, tooling(objectui-readiness 3): objectui compiles against objectstack main HEAD — bump .objectstack-sha past the spec commits since e649c2d91e, fix the fallout (TranslationPreview TS1360), repeat until cutover (parent #25677, 2c/6) #25727): .objectstack-sha to objectstack main HEAD; the four ui/ SKILL.md frontmatter flags (metadata.internal: true for .claude/skills/objectui-contributor, .claude/skills/verify, packages/plugin-dashboard; see decision C for skills/objectui); re-run git apply --check scripts/ui-import/4a-ui-side.patch against that objectui main and refresh the patch if it fails (bill item 10). objectui main is then frozen (branch protection: maintainer, or the seat stops merging).
  3. Refresh the verify branch on that objectui main with the recipe in scratchpad/notes (non-squash git subtree pull --prefix=ui, helper files --theirs, lock = pnpm install --lockfile-only on the spliced lock then pnpm dedupe, ⛔ never re-run splice-lockfile.mjs --out on a spliced base — bill item 8) and read the run: every red must be in the accepted-class list below; a new class stops the window.
  4. Cutover PR (seat opens as draft against main; maintainer merges, Tier H by size ~2.59M lines): commit 1 = git subtree add --prefix=ui objectui <frozen main sha> (history kept, as the tooling(monorepo): 在试验分支上把 objectui 并入 ui/ workspace(subtree add、单 lockfile、turbo 构建图),交冲突清单、必改脚本清单与各类 PR 的 CI 时长读数 — 不落 main(父单 1/6) #25678 spike); commit 2 = the adaptation commit, the bill made concrete:
    • lockfile: scripts/ui-import/splice-lockfile.mjs then pnpm dedupe (5a + items 6/16: run 7 measured 50/527 ui importer rows moving onto objectstack's versions and the vite/postcss TS2321 class clearing); root pnpm-workspace.yaml overrides scoped so objectui's dependency lines are not rewritten (react-router 7, happy-dom 21 — 5a);
    • ui/ manifests: every @objectstack/* dependency workspace:^; ui/package.json whole-suite test script dropped (item 4); ui/turbo.json parked as turbo.objectui.json (root turbo.json owns the graph); QUICK_REFERENCE rows on workspace:^;
    • gates: check-type-check-coverage.mjs accepts objectui's type-check spelling for members under ui/ and the remaining findings get ledger rows (item 1); check:lockfile-integrity per-package verdict (dedupe or allowlist with reason) and check:lockfile-dedupe run from the workspace root (items 6/7); root build filter may tighten to !./ui/apps/site (item 3);
    • census: packages/client/src/envelope-caller-census.test.ts converts the recorded OBJECTUI_CENSUS constant into a live LEDGER row for ui/packages/data-objectstack/src/index.ts (analytics.query, production consumer, not envelope-dependent), count 28 → 29 (item 17);
    • skills catalog: per decision C (item 18);
    • decisions carried here: ui/skills/objectui → root skills/ (C); root eslint.config.mjs global ignores gains ui/** (G1, item 25); check:test-source-alias vitest-alias half scoped to non-ui/ members (F, item 21d); check:dts-closure expands * subpath patterns against dist (item 22); scripts/js-comment-mask.mjs stops reading JSX text as a comment opener, with a pinned self-test (item 23); check:adr-anchors allowlist rows for the ui/**/CHANGELOG.md ADR-0075 lines (item 19); check:undeclared-dep-imports ledger row for ui/apps/console/src with the bundled-SPA evidence (item 20); watch-hint / population declarations list ui/** (item 21a); ui/.objectstack-pin/** deleted (item 21b);
    • the verify branch is the proof: the PR's CI must match the last verify read class for class.
  5. Land the window's PRs in order (maintainer approves and merges each; the seat flips ready and requests review from GOVERNED_APPROVERS only now, never before): subtree PR → 4a 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 (release lane; approval 5641652106 already stands; carries decisions B/17c and D/17b) → PR B of tooling(ui-wiring): objectstack-side inert wiring for the ui/ workspace — workspace globs, root turbo tasks, path-filtered ui test/typecheck/lint/E2E jobs, spec change compiles the Console; pin gates retire at cutover (parent #25677, 3/6) #25697 (retires Spec Shape Gate, Console Pin Gate, prerelease-pin-watch, check-single-claim-paths, findObjectuiPin; item 12) → 4b PR 2 (tooling(ui-merge): governance in-repo — liveness evidence and spec tests stop citing objectui by commit, one sdui-parser, AGENTS.md / pm scripts drop objectui#, ui/AGENTS.md nests, 18 governance workflows merged or retired (parent #25677, 4b/6) #25712: README Export Check port, ui/.changeset presence gates, sdui manifest from ui/, AGENTS.md cross-repo convention rewrite, the six ui/** Tier H rows with item 16; items 2/13 — QUICK_REFERENCE moved to 4a). Each lands with main green or with only the classes the previous PR in the chain is about to clear; the seat posts the 维护者速读 + ## 席位核对 finale on each.
  6. Repository settings (maintainer): required checks — drop Spec Shape Gate, Console Pin Gate, prerelease-pin-watch contexts, add Test UI, Type Check UI, Lint UI, Build & E2E UI (names as A2's ci.yml spells them); the release npm token's publish rights on @object-ui (decision A); the Vercel project for objectui's docs site (4b's docs-deploy.yml). The seat lists the exact context names in a comment before this step.
  7. Branch and card migration (seat): every open objectui branch with a PR is ported with git format-patch origin/main..<branch> --stdout | git am --directory=ui onto an objectstack branch and re-opened as an objectstack PR (Part of its transferred card); the ~28 open objectui cards transfer to objectstack with scripts/pm/issue-transfer.mjs (same organisation), labels mapped (domain:ui lane folds in per 4b); objectui seat notes closed; stale claude/* branches (382, one with a PR) deleted after the transfer.
  8. Archive objectui (seat PR + maintainer click): objectui README first section becomes the migration notice (where the code lives now, how to port a branch, where issues went); the repo is archived by the maintainer. The parent's item 6 (first joint 18.x release, docs-site deploy, process: a published-type change objectui consumes lands in lockstep with objectui's adaptation — #24947 left framework main and objectui main uncompilable together, so cloud's pin round had to stop 7 commits short #25556) is sub-issue 6.

Accepted red classes on the verify branch at freeze (anything else stops the window)

pin / spec-drift class (Test UI 1, 2 — cleared by step 2); QUICK_REFERENCE release-sync class (Test UI 9, 13, 14 — decision B); type-check coverage findings (source gates, debt ledger — item 1); lint-lane workspace-glob classes and Validate Package Dependencies (cleared by PR B / 4b PR 2); census (item 17) and skills catalog (item 18) — cleared by the adaptation commit; main-side regressions not of this epic (e.g. check-liveness translation/flows.screens, red on main since #25734) are tracked by their owning lane and do not count. Added from runs 8–11: clocked-window class (Test UI 3/16, DraftChangesPanel.securityProblems) — cleared by 2c round 2 (a) / card F; ESLint 121 errors under ui/** — cleared by G1 in the adaptation commit; check:dts-closure @object-ui/i18n wildcard — cleared by the item 22 gate fix; plugin-pinyin-search boot-reconcile 5 s timeout (main's #25634, item 26) — main-side timing, re-run once, not ours.

Done when

  • ui/ is on main with objectui's history; 4a, PR B and 4b PR 2 are merged; main is green except for classes the maintainer has explicitly accepted into ledgers.
  • No .objectui-sha / .objectstack-sha and none of the pin scripts in 4a's items 3–4 are in the tree; the required-checks set names no retired gate.
  • Every open objectui PR has an objectstack PR or a closing comment; every open objectui card is transferred; objectui is archived with the migration notice as its README head.
  • Hand-off comment to sub-issue 6 with the first joint release's expected version.

Size: XL (procedure; the PR is mechanical). Clause-②: no. Metadata-protocol: none.

风险

Decisions for the maintainer — DECIDED (Tesla, director thread, 2026-10-25 09:06Z: 「第 16 项 · 同意;17a · 有权限;17b · 你决定;17c · 17d · 同意」「17e · 17f · 17g · 同意」)

  • A (17a). The release npm token HAS publish rights on the @object-ui scope (Tesla's word). Step 6 needs no token change; the first joint release (sub-issue 6) is the measurement.
  • B (17c). Retire the QUICK_REFERENCE release-sync rows (sync-quick-reference-release, its tests, the synced rows). Carried by 4a 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 (seat ruling 09:09Z: the only release-path caller is the changeset-release.yml 4a deletes and 4a's ui patch already edits ui/QUICK_REFERENCE.md); 4b PR 2 drops the item.
  • C (17d). Move ui/skills/objectui into the root skills/ catalog; mark the three contributor skills under ui/ metadata.internal: true (packages/plugin-dashboard in 2c round 2 (a); .claude/skills/objectui-contributor and .claude/skills/verify in the governed round 2 (b)). The move is in the cutover adaptation commit.
  • D (17b). Tesla delegated to the director; ruling B: the private VS Code extension object-ui stays in the changesets fixed group (4a implements: root .changeset/config.json fixed gains object-ui, check-changeset-fixed accepts the declared private member).
  • E (17e). Rename the 9 @object-ui/types duration keys so the key name carries the unit, with ADR-0087 conversions (autoPlay, autoResponseDelay, timeout, delay, duration, delayDuration, openDelay, closeDelay, refreshInterval; bill item 21(d)). Prep card, objectui-side, before the freeze.
  • F (17f). Adopt for the function-body half: warm module-scope imports in the ~25 ui test files check:test-source-alias names (the clocked-window class that reddened Test UI 3/16 on verify runs 8 and 11, bill item 24); scope the vitest-alias half of the gate to non-ui/ members (adaptation commit). Prep card, objectui-side, before the freeze.
  • G (17g). G1: the root ESLint flat config ignores ui/** at cutover (adaptation commit, one ignores entry with the config's own census comment); Lint UI stays ui/'s lint; the two configs converge in aftercare aftercare(ui-merge): the first joint 18.x release from the merged repo — both scopes at one version, @object-ui published, docs site deployed — then close #25556 as superseded and the epic (parent #25677, 6/6) #25753 (bill item 25: 121 errors, all under ui/**, mostly react-hooks/static-components).
  • Item 16 (4b). ui/.claude/** stays Tier H (human-approved) until it folds into the root .claude/**.

Pre-freeze prep cards (dispatched 2026-10-25 after the rulings; each lands in objectui before step 2's final pin bump)

Dedupe

search_issues 2026-10-25 05:33Z 「objectui merge cutover day freeze subtree add ui/ archive objectui repo migrate branches transfer issues」: 33 hits, all this epic's family (#25677, #25678, #25685, #25711, #25712, #25726, #25727) plus #25556; no card describes the cutover day itself — the parent's item 5 is this card's only prior text; #25556 (open) is sub-issue 6's. New.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:devxpm:epicpriority:p1High: required for production / M2tooling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions