Skip to content

tooling(cutover prep 5a): the ui/ import carries objectui's lockfile resolutions into the merged pnpm-lock.yaml and scopes the git-root overrides that would rewrite a dependency line objectui owns (parent #25677, 5a/6) #25726

Closed

Description

@objectstack-fleet

Filing gate ④: sub-issue 5a/6 of the epic #25677 (pm:epic; epic PM session_01RSDL3SFtJaKzcymvCD8RsU). Part of #25677; preparation for sub-issue 5 (cutover). ⛔ Not a claim. Measured on the DO NOT MERGE verification PR #25718, run 3 (40148461539, head 1cade69) and the lockfiles of objectui main (cd70b78) and that branch.

Why. The verification branch built its single pnpm-lock.yaml by deleting objectui's lockfile and running pnpm install (verify commit 717defb). That resolves every ui/* dependency afresh from its range, and puts the git-root pnpm-workspace.yaml overrides (48 today) over the imported tree. Against objectui main's lockfile, 138 importer×dependency rows moved across 69 packages (308 unchanged). The merged tree therefore runs objectui's code on dependency versions objectui never tested, and the first CI run that reached the component tests shows it: every remaining Test UI failure is a radix Select / Tooltip interaction (@radix-ui/react-select 2.3.7→2.4.1, react-tooltip 1.2.16→1.4.1 and 15 other radix minors), the generated lucide icon-name list drifts (lucide-react 1.43.0→1.61.0, +94/−9 names, red gate + 13 unit failures), and the root override react-router@<8.3.0 → ^8.3.0 rewrites the react-router under objectui's react-router-dom@7.18 to 8.5.0 — a major mismatch inside one router line that type-checks and would ship. happy-dom moves 20.11.2→21.0.4 (major) by the same mechanism. A cutover that ships this is a dependency upgrade of 69 packages smuggled into a repository move; the merge must be dependency-neutral, with upgrades filed on their own cards afterwards.

Who does it, where it lands: the epic PM dispatches it (os-dev, objectstack checkout + the objectui checkout for the source lockfile). Deliverable = one reusable script plus a procedure, verified on a scratch copy of the verification worktree; the epic PM applies the resulting lockfile as a verify commit on #25718 to re-measure Test UI, and sub-issue 5's cutover PR runs the same script against the then-current objectui main. No PR to main before cutover unless the script is wanted earlier (then it is inert tooling under scripts/, not a governed surface).

维护者速读

验证分支的单一锁文件是"删掉 objectui 的 pnpm-lock.yaml、重新 install"得来的,结果 ui/ 下 69 个依赖包换了版本(138 处),根 pnpm-workspace.yaml 的 48 条 overrides 也套到了 objectui 的包上。合并树上剩下的组件测试红全是 radix Select/Tooltip 小版本变化造成的;lucide 从 1.43 跳到 1.61 让生成的图标名单漂移;根 override react-router@<8.3.0 → ^8.3.0 把 objectui 的 react-router-dom 7 底下的 react-router 换成了 8.5.0。本卡只做一件事:导入时把 objectui 自己锁文件里的解析原样搬进合并锁文件(pnpm install --frozen-lockfile 通过、与 objectui 锁相比 0 处变动),并把会改写 objectui 依赖线的根 overrides 限定作用域。依赖升级不随合并走,之后单独立卡。

Measured

Evidence Reading
Resolution diff (objectui main lock vs verify branch lock, ui importers) 138 rows / 69 packages moved; table on #25697 (run 3 pointer)
Type Check UI run 3 red at check:icon-record-names: lucide-record-icon-names.ts drifted (lucide 1.61.0 resolved; objectui pins 1.43.0)
Test UI run 3, shards 1/4/9/14 ListView.fieldListRead-11984, ListView.sortFieldFallback, importWriteModes-12697, CreateViewDialog.chartBinding-11576, PublicFormsPage.servedRule-11545, action-disabled-reason-11839, MarketplacePackagePage.installMode-12288 — Select/Tooltip behaviour; 13 unit failures in check-lucide-icon-record-names.test.ts
Merged lock snapshots react-router-dom@7.18.4 → react-router: 8.5.0 (objectui lock: 7.18.2 → 7.18.2)
Merged lock importers.ui happy-dom specifier rewritten ^20.11.2 → ^21.0.4 by the root override

Scope

  1. Lockfile splice script (name is the dev's, e.g. scripts/ui-import/splice-lockfile.mjs, Node builtins + the yaml already in the workspace): inputs = objectstack's pnpm-lock.yaml, objectui's pnpm-lock.yaml at the imported sha, the prefix ui/. Output = a merged lockfile in which (a) every objectui importer is re-keyed under ui/ (. → ui), (b) each ui importer's dependency keeps objectui's resolved version and specifier, except @objectstack/* entries which become the workspace links the adaptation already writes (link:../../../packages/<name>), (c) the packages: and snapshots: entries those versions need are carried over (and peer-suffixed snapshot keys recomputed by pnpm, see 2), (d) objectstack's own importers are untouched. The script prints the moved-row count against the source lock the way the measurement did (0 is the pass).
  2. Reconcile with pnpm, not by hand: after the splice, pnpm install --lockfile-only must leave the file unchanged, and pnpm install --frozen-lockfile must pass. Where pnpm insists on a change (peer-suffix keys, dedupe of a version both sides pin identically), the script's output is adjusted until the diff is explainable line by line; the dev states what pnpm changed and why.
  3. Overrides: classify the 48 git-root overrides against the ui tree: security floors objectui lacks (qs, tar, undici, minimatch, …) stay — a single lockfile applying one advisory policy is a goal of the merge; an override that moves a dependency objectui pins to another major or into a mismatched line is scoped: react-router@<8.3.0 becomes react-router@>=8.0.0 <8.3.0 (objectui stays on the 7.18 line until its own router card); happy-dom@>=17.0.0 <22.0.0 → ^21.0.4 is measured (Test UI on 21 vs 20) and scoped to >=21.0.0 <22.0.0 if 21 is not green for objectui's suites. Each scoping change carries the advisory it keeps covering, so the security intent is not weakened.
  4. Procedure note for sub-issue 5 (one file under docs/ or the script's header): the order — subtree add → delete ui/pnpm-lock.yaml → splice → pnpm install --frozen-lockfile → regenerate nothing (if the moved-row count is 0, no generated file such as lucide-record-icon-names.ts changes).

Out of scope: upgrading any objectui dependency (own cards after cutover); objectstack's own resolutions; the react-router 7→8 move for objectui.

Verification (the dev's)

  • On a scratch copy of the verification worktree (/home/claude/objectstack-issue-25697 at d17ed5e; objectui lock from git show 0dad5c2e11^:ui/pnpm-lock.yaml or the objectui checkout at cd70b78): run the splice, then pnpm install --frozen-lockfile passes; the moved-row count is 0; pnpm --dir ui exec vitest run on the seven failing files above is green; pnpm --dir ui run check:icon-record-names is green without regenerating the list (revert verify commit d17ed5e's regeneration in the scratch copy first).
  • react-router under react-router-dom in the merged lock is 7.18.x; happy-dom is whatever the measurement decided, stated.
  • Objectstack's own packages: pnpm install --frozen-lockfile and pnpm exec turbo run build --filter=@objectstack/core... unchanged (the splice must not touch their rows — diff of the objectstack importers is empty).

Done when

  • The script and procedure are on the verification branch as a verify commit (applied by the epic PM from the dev's patch) and Test UI / Type Check UI no longer show a dependency-version failure; the moved-row count against objectui's lock is 0.
  • The patch is filed at /mnt/project-files/d1-merge/5a-lockfile-splice.patch for sub-issue 5.

Size: M — one script (~300 lines), one override classification, one procedure note; verification is the bulk. Clause-②: no. Metadata-protocol: none. Blocked-by: none (the verification worktree exists); sub-issue 5 is blocked by this.

风险

  • pnpm's peer-dependency suffixes in snapshots: keys make a textual splice fragile; the reconcile step (2) is what keeps the result honest — if pnpm rewrites more than the dev can explain, the fallback is pnpm install with objectui's resolutions pinned via a temporary overrides block generated from objectui's lock, then removed.
  • Scoping an override must not drop coverage of the advisory it was added for; each change states the advisory range it still covers.

Dedupe

Open issues 2026-10-25 01:10Z filtered on lockfile / overrides / react-router / happy-dom: none about the ui/ import; this epic's own cards only. New.

Activity

  1. added
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    priority:p1High: required for production / M2
    domain:devxDomain lane — seat card indexed by label:pm:seat
    pm:epicReserved by a dedicated epic PM, parent or sub-issue; other PMs never take it; never with pm:queue
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    on Oct 25, 2026
  2. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: epic #25677 round 4 (dispatch of sub-issue 5a)
    Session: session_01RSDL3SFtJaKzcymvCD8RsU
    Account: os-tesla
    Branch: none for the dev — the deliverable is a patch the epic PM applies as a verify commit on objectstack claude/project-thread-dwhq6r-25697-verify (#25718, DO NOT MERGE) and files at /mnt/project-files/d1-merge/5a-lockfile-splice.patch for sub-issue 5; no PR to main on this card
    Worktree: a scratch copy of /home/claude/objectstack-issue-25697 (verification branch at d17ed5e) plus the thread's objectui checkout for the source lockfile (cd70b78)
    Domain: domain:devx
    Seat: epic:#25677
    File surface: one new script under scripts/ui-import/ (name the dev's), one procedure note beside it, pnpm-workspace.yaml overrides: scoping lines, pnpm-lock.yaml (generated by the script + pnpm); no .github/**, no AGENTS.md, no package code
    Container & model: M, mode:subagent, model: opus, effort: high; no governed path on the surface
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: none
    Serial constraints cleared: #25723 (objectui#13484) touches objectui scripts/, not the lockfile or overrides; PR A2 (not yet opened) touches scripts/pm/ and scripts/partition-test-shards.mjs; no overlap. The verification branch is the only place this is applied before cutover.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Dev report received; patch applied as verify commit cfa1676 on objectstack#25718 (DO NOT MERGE, run 5). The patch (5 files: pnpm-lock.yaml, pnpm-workspace.yaml, scripts/ui-import/splice-lockfile.mjs, scripts/ui-import/README.md, revert of ui/packages/components/src/lib/lucide-record-icon-names.ts) is on that branch for sub-issue 5 to pick up; git apply --check clean on d17ed5e, pnpm install --frozen-lockfile passes in the verification worktree.

    Measured (the dev, against objectui@cd70b7818's lock): before splice 219 of 527 ui importer×dependency rows moved (the card's 138 was taken at an earlier head); after splice 0; after pnpm install --lockfile-only reconcile 3 — all from overrides kept on purpose: happy-dom 20.11.2→21.0.4 (ui, ui/apps/console), better-auth 1.7.2→1.7.12 (ui/packages/auth; security floor, auth suite 34 files / 322 tests green on it). react-router override scoped to >=8.0.0 <8.3.0: objectui's react-router-dom 7.18.2 → react-router 7.18.2 line is kept; GHSA-qwww-vcr4-c8h2 has no 7.x fix, so the 7.18 line carries it exactly as objectui's own lock does today — belongs to a router card, not this one. lucide-react back on 1.43.0 (the run-4 regenerated icon list is reverted), radix back on objectui's versions. Side effects pnpm makes on reconcile: 11 direct specifiers rewritten (postcss ×8, happy-dom ×2, better-auth ×1), transitive security floors raised (esbuild 0.28.1, undici 7.30.1, qs 6.16, hono 4.13.12, …), 94 base importer rows change only in peer suffixes (base direct versions and specifiers untouched; the script asserts base importers byte-identical before writing), 113 packages: entries deduped away. Target dom tests green on the spliced tree: ListView.fieldListRead-11984, ListView.sortFieldFallback, importWriteModes-12697, CreateViewDialog.chartBinding-11576, MarketplacePackagePage.installMode-12288, action-disabled-reason-11839, PublicFormsPage.servedRule-11545, check-lucide-icon-record-names — 8 files, 155 tests.

    Open on this card until run 5 is read: (1) happy-dom 21 vs 20 over the broad sample did not finish (30+ min on a loaded box); Test UI on run 5 is the measurement — if happy-dom failures remain, the selector becomes happy-dom@>=21.0.0 <22.0.0 and the splice + --lockfile-only are re-run. (2) ACCEPT and the splice's place in the cutover procedure (sub-issue 5) follow the run-5 read.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — dispatch seat. The 5a deliverable is accepted and the card closes.


    Generated by Claude Code

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:devxDomain lane — seat card indexed by label:pm:seatpm:epicReserved by a dedicated epic PM, parent or sub-issue; other PMs never take it; never with pm:queuepriority:p1High: required for production / M2toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions