Skip to content

ci(ui-merge): port objectui's lockfile-integrity gate into Type Check UI and retire lockfile-dedupe and the shadcn-check report - #26995

Merged
os-zhuang merged 1 commit into
mainfrom
claude/project-thread-oo129e
Oct 28, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/project-thread-oo129e

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steve · project thread

Part of #26717 (slice 2: roster rows 19, 18 and 26 land here; row 7-docs stays open on the card for the seat's decision, see Acceptance notes. Row 17 is out of scope by #25914's ruling.)

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:objectui 剩下的三个"移植或退役"检查处理完。锁文件重复检查(lockfile-integrity)接进根 CI 的 Type Check UI,只在 PR 上跑,发现问题只打一条报错注释,不挡合并,和 objectui 当年一样。另外两个退役:锁文件 dedupe 报告(90 天 145 次运行从未失败)和 shadcn 每周报告的分类脚本,连同它们的测试一起删掉。
  • 为什么改:objectui 并入后这些检查没有在任何地方运行;要么接回来,要么明确删掉,不留半死的脚本。
  • 风险与回滚:Type Check UI 是必需检查,但新步骤带 continue-on-error,它红了不会让这个 job 红,所以不会挡任何 PR。删掉的脚本没有别的读者。回滚就是 revert 本 PR。
  • 先看:.github/workflows/ci.yml 里 Type Check UI 新加的 check:lockfile-integrity 步骤;ui/scripts/__tests__/check-lockfile-integrity.test.ts 新加的四条接线测试。
  • 两分钟验证:pnpm --dir ui run check:lockfile-integrity --base-ref origin/main,预期 VERDICT clean — no package gained a copy.,退出码 0。
  • 需要你做的:本 PR 改了 ci.yml(Tier H),需要你明确批准;另外第 7-docs 行(objectui 文档站构建)记录里没定,席位会把选项拿给你。

What changes

Rows of the #25697 workflow roster (comment 6388182608), read from the objectui workflows #26058 deleted (lockfile-integrity.yml, lockfile-dedupe.yml, shadcn-check.yml at aa2f8e31f3's parent).

Row objectui workflow Disposition here
19 lockfile-integrity.yml (check:lockfile-integrity) ported: one step of Type Check UI, check:lockfile-integrity — compare this pull request's lockfile with its merge base
18 lockfile-dedupe.yml (check:lockfile-dedupe, report-only since objectui#9562's ruling A) retired: alias, ui/scripts/check-lockfile-dedupe.mjs and its test deleted; nothing replaces it, by choice (#25920: 145 runs / 90 days / 0 failures)
26 shadcn-check.yml (weekly report) retired: ui/scripts/shadcn-check-report.mjs (the workflow's classifier and issue-body renderer) and its test deleted; nothing replaces the weekly report, by choice
  • Row 19, the step. if: github.event_name == 'pull_request', continue-on-error: true, before pnpm install, running pnpm --dir ui run check:lockfile-integrity --base-ref "origin/${BASE_REF}" with BASE_REF from github.base_ref. Why this job: it already checks out with fetch-depth: 0, so origin/BASE and the merge base are in the clone (objectui paid a separate job for that history), and the ui paths filter lists pnpm-lock.yaml, so every lockfile change runs it. Before the install because the script needs only Node builtins and two repo modules, as objectui ran it; Lint UI's pre-install import graph check holds that. continue-on-error keeps objectui's classification: a finding prints ::error title=Lockfile integrity::PACKAGES on the pull request and does not fail the required job. Making it blocking stays the maintainer's call (NOT_A_GATE in ui/scripts/dependabot-merge-gate.mjs). No new job, no new check-run context, no new required context.
  • Row 26, what stays. shadcn:check and shadcn:analyze (and shadcn-sync.js, shadcn-local-patches.mjs, component-analysis.js) are not retired: they are the components package's maintainer commands, read by ui/packages/components/README.md, README_SHADCN_SYNC.md, shadcn-components.json, the other four shadcn:* aliases and scripts/regen-artifacts.mjs. The weekly workflow only scheduled them; its own artifact was the classifier, and that is what goes. The two ui tests that read shadcn-sync (shadcn-local-patches.test.ts, shadcn-sync-fetch-cache.test.ts) test those live scripts and stay.

Forced test edits

  • ui/scripts/__tests__/check-lockfile-integrity.test.ts: the note saying the port would "bring both pins back against the root job" is replaced by those pins, read from root ci.yml through helpers/root-ci: the step exists and runs the gate against the pull request base; the job checks out with fetch-depth: 0 before it; the step is continue-on-error and before the install; no other root workflow carries the alias. 13 → 17 cases.
  • ui/scripts/__tests__/check-lockfile-dedupe.test.ts and ui/scripts/__tests__/shadcn-check-report.test.ts: deleted with the scripts they test.

Tests

Measured in this worktree on head a463a624.

Row 19: the step's command, and its counter-probe
  • pnpm --dir ui run check:lockfile-integrity --base-ref origin/main (the step's run: with BASE_REF=main): exit 0, base: 7bb80845…:pnpm-lock.yaml (1941 resolutions) head: …/pnpm-lock.yaml (1941 resolutions), VERDICT clean — no package gained a copy.
  • Counter-probe: the root pnpm-lock.yaml mutated with the test's sample (a) (a second ai@7.0.65(zod@4.6.7) snapshot beside ai@7.0.118(zod@4.6.7); marker count 1 on disk), then the same command: exit 1, VERDICT 1 lockfile-integrity finding(s): 1 duplication(s). and ::error title=Lockfile integrity::ai — see the run log; this is a lockfile regression, not a bundle regression (objectui#8326). Restored by git checkout HEAD -- pnpm-lock.yaml under a trap; blob 8b64d515 before and after; git diff HEAD empty; re-run exit 0, VERDICT clean.
  • pnpm --dir ui exec vitest run scripts/__tests__/check-lockfile-integrity.test.ts: 17 passed.
Rows 18 and 26: every reader gone
  • git grep -n -F check:lockfile-dedupe: no hits (exit 1).
  • git grep -n -F shadcn-check-report -- ':!ui/content/docs/guide/ci-cd-pipeline.md' ':!ui/scripts/dependabot-merge-gate.mjs': no hits. The two remaining mentions are prose about objectui's deleted workflows (Acceptance notes).
  • git grep -n -F check-lockfile-dedupe -- ':!ui/content/docs/guide/ci-cd-pipeline.md' ':!ui/scripts/workspace-root.mjs': no hits. Same reason.

Acceptance notes

Verification

Final head a463a624, after a root pnpm build (VERDICT command-exit 0, 12m30s under os-verify-lock).

Gate sweep and reconciliation
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 74 commands for this change set (7 paths, 2175 changed lines). All 74 ran and exited 0, each exit code captured before any pipe. Among them: pnpm --dir ui exec vitest run scripts/ under os-verify-lock (176 files passed, 2 skipped; 5032 tests passed, 2 skipped; VERDICT command-exit 0), pnpm check:pm-dispatch-gates (fast tier, 1935 cases), pnpm check:required-contexts, pnpm check:ci-filter-parity, pnpm check:pm-expected-skips, pnpm check:workflow-step-name-quoting and pnpm check:published-files.

  • node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran LEDGER: ✓ 74 derived famil(ies) accounted for — 74 run, 0 NOT-MEASURED, 0 UNRUN.

  • origin/main moved 11 commits after the base 7bb80845; none touches this PR's files, so it is not merged in.

  • Not run locally: pnpm lint and the full test suites, which are CI's run.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ADHkmSracEMN5RmM9xs4Fu

… UI, retire lockfile-dedupe and the shadcn-check report

Rows 19, 18 and 26 of the objectui workflow roster.

- Row 19: check:lockfile-integrity runs as a pull_request-only,
  continue-on-error step of Type Check UI, before the install, against
  origin/<base>; the integrity test pins the step, the deep checkout and
  the alarm-only shape against root ci.yml.
- Row 18: the check:lockfile-dedupe alias, its script and its test are
  deleted (report-only, nothing else reads them).
- Row 26: shadcn-check-report.mjs (the weekly workflow's classifier) and
  its test are deleted; shadcn:check / shadcn:analyze stay, they are the
  components package's documented maintainer commands.

Claude-Session: https://claude.ai/code/session_01ADHkmSracEMN5RmM9xs4Fu
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 28, 2026
@github-actions github-actions Bot added size/xl ci/cd dependencies Pull requests that update a dependency file tests labels Oct 28, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · domain:skills#1 · session_01ADHkmSrRBdu9MdC6fc33Uu · head a463a624 · 2026-10-28T00:36Z

  1. 形态 — Tier H (.github/workflows/ci.yml): 7 files, +82/−2093. Three 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 roster rows:
    • Row 19 is ported as one step of Type Check UI: pull_request only, continue-on-error, placed before Install dependencies, running check:lockfile-integrity --base-ref "origin/${BASE_REF}". BASE_REF comes in through env:, not interpolated into run:. The job already checks out with fetch-depth: 0.
    • Row 18 (check:lockfile-dedupe: alias, script and test) is retired.
    • Row 26 is retired: shadcn-check-report.mjs and its test go. The shadcn:* maintainer commands and shadcn-sync.js stay; the README, shadcn-components.json and regen-artifacts read them.
    • No new job, check-run context or required context.
  2. 前提实测 — the seat read the step's pre-install closure at head: check-lockfile-integrity.mjs → invoked-as.mjs, workspace-root.mjs → ui-root.mjs, all Node builtins. Setup pnpm precedes the step in the job. ui/package.json keeps the check:lockfile-integrity alias, and the script reads --base-ref.
  3. 门禁 check-runs — dev reading: root pnpm build VERDICT 0; 74 derived commands, 74/74 exit 0 (--ran 74/74, 0 NOT-MEASURED, 0 UNRUN), including ui vitest run scripts/ (5032 passed) and check:required-contexts / ci-filter-parity / pm-expected-skips. Row 19 counter-probe: a duplicated ai snapshot exits 1 with ::error naming ai; restored by blob hash, then exit 0. CI on the head is in progress (10 success / 11 skipped / 34 running, none red at this read); it is read again before landing.
  4. 接受的偏差 — the forced test edit check-lockfile-integrity.test.ts 13 → 17 adds root-ci wiring pins and deletes none — accepted. The delta's "--tier MANDATORY for ci.yml" measured as no path-derived mandate — accepted; the gate set was derived and run in full anyway.
  5. 范围外去向:
  6. 落地条款 — ci.yml, Tier H: stays draft until the maintainer's explicit approval (a GOVERNED_APPROVERS review); then it lands through the queue. The seat does not ready or arm it.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: a463a624eb8640b3462b0cd22f6ce207c36bf3b5
Local-runs: none
Scope: .github/workflows/ci.yml, ui/package.json, ui/scripts/tests/check-lockfile-integrity.test.ts, the deleted ui/scripts/check-lockfile-dedupe.mjs, ui/scripts/shadcn-check-report.mjs and their tests + ui/scripts/check-lockfile-integrity.mjs, ui/scripts/workspace-root.mjs, ui/scripts/dependabot-merge-gate.mjs, ui/scripts/check-pre-install-import-graph.mjs, ui/scripts/tests/helpers/root-ci.ts, scripts/check-required-contexts.mjs

Director seat (summon #52, ledger objectstack#12708), summoned by the domain:skills#1 seat; effort ≥ xhigh. Read-only at the head above: the diff, card #26717 and its thread (triage 6446838341, the slice-2 claim 6456567399, dev report 6457446264, devx#1's row-17 note 6454613263), the seat's ACCEPT 6457468439, slice 1 (PR #26854, merged daf52bcc, this seat's record 6451016316), the head and origin/main (fd246c22, the PR's base) copies of ci.yml and the touched ui scripts and tests, objectui's own lockfile-integrity.yml at #26058's parent be789779, the head's check runs, reviews and timeline. .github/workflows/** is a governed-register row ⇒ the rules face, CONTRACT_REVIEW_TIER; Tier H, and ci.yml is under the maintainer's standing rule of explicit approval. The seat records; it does not approve, ready, queue or merge.

① Derived judgments

  • Row 19 is ported with the script's own contract intact. check-lockfile-integrity.mjs on main takes --base-ref (default origin/main), resolves git merge-base <ref> HEAD and throws — exit EXIT_CANNOT_RUN, a ::error:: — when a shallow clone has none (:401–413, :563); a finding prints ::error title=Lockfile integrity::<packages> (:453) and exits 1; it reads the one root pnpm-lock.yaml (workspace-root.mjs#lockfilePath, LOCKFILE). The step runs it in type-check-ui, which checks out with fetch-depth: 0 before any step (main L3330–3336), so origin/<base> and the merge base exist without objectui's extra fetch step; BASE_REF enters through env: (no interpolation into run:); if: github.event_name == 'pull_request' matches the script's subject, a pull request's delta; the job's own if: is untouched, so scripts/pm/check-expected-skips.mjs derives nothing new (a step-level if: is not a job gate). The ui filter lists pnpm-lock.yaml (main L467–469), the paths objectui's own pull_request: filter named.
  • Before the install is sound. The script's static closure is invoked-as.mjs and workspace-root.mjs → ui-root.mjs, Node builtins only (workspace-root.mjs:98–100 declares exactly this property); ui/scripts/check-pre-install-import-graph.mjs derives its population from the workflows ("never hard-coded", L47) and Lint UI runs it (main L3925–3926), so the new placement is measured by a gate on this PR, not asserted.
  • Non-blocking is the classification objectui reserved. dependabot-merge-gate.mjs#NOT_A_GATE (:273, :312) names Lockfile Integrity Check as a context that cannot gate; continue-on-error: true inside Type Check UI (a required context, check-required-contexts.mjs:466–470) keeps the job green on a finding. The forced test edit pins all of it: the four new cases read root ci.yml through helpers/root-ci (jobBlock, withoutComments, uiRun, rootWorkflowFiles — all on main), 13 → 17 cases, none deleted, and the NOT_A_GATE case stays.
  • Rows 18 and 26 are retired clean. check:lockfile-dedupe alias, check-lockfile-dedupe.mjs, shadcn-check-report.mjs and both tests go; at the head no test, script or workflow names them. What remains are prose: ui/content/docs/guide/ci-cd-pipeline.md (F14, 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), the workspace-root.mjs docblock, the dependabot-merge-gate.mjs header and its Lockfile Dedupe Check context (a gate that runs in no root workflow), and packages/console/CHANGELOG.md (history). The shadcn:* maintainer commands and shadcn-sync.js are kept because the components READMEs, shadcn-components.json and regen-artifacts.mjs read them — "only what nothing else reads", as the claim required.
  • Scope matches the claim. Row 17 untouched (e2e: the MSW test in console-rendering.spec passes when the worker is absent (it is absent), and 18 of 22 live specs run nowhere in CI — delete the vacuous test and make the four live specs count #25914's ruling 6435339772 keeps it); row 7-docs not decided here and routed to the maintainer with the card open (Part of); no new job, context or required context; ui/package.json hunks limited to the alias line. skip-changeset: nothing publishes.

② Semver level

skip-changeset. Correct.

③ Boundary flags

  • Landing state at this record: readied and auto-merge armed by os-zhuang (GOVERNED_APPROVERS) at 2026-10-28T00:37:36–37Z, with no approval review on the PR yet. The arming is the maintainer's own act after the dev's draft and the seat's ACCEPT (both describe a draft). The governed guard still needs a GOVERNED_APPROVERS review, and this PR edits ci.yml, which the maintainer's standing rule puts under his explicit approval; this record is not that approval and changes nothing about it.
  • The alarm is quieter than objectui's, by one surface. objectui ran row 19 as its own non-required check-run (Lockfile Integrity Check), so a finding showed as a red context on the pull request. Here a finding is an ::error annotation inside a green Type Check UI. Same non-blocking classification, less visible signal; the step's comment and the test's ⛔ stays an alarm case say what it is. Whether a red non-required context is wanted instead is the maintainer's call (the card's own line: any new context is the maintainer's). Recorded, not a should-fix.
  • The dev reports dispatch-gates --tier finding no path-derived mandate for ci.yml although the claim named it MANDATORY; the seat served CONTRACT_REVIEW_TIER by the claim and this record serves it too. The tier script's glob set is outside this PR.
  • Check runs on a463a624 at this record: 14 success, 11 expected skips, 31 in_progress — among them Type Check UI (the step's first run on a pull request), Lint UI (the pre-install import-graph gate) and the Test UI shards (the 17-case test). Nothing red; a red there re-opens this record. main has not moved on the touched files since the base.
  • Dev deviations: none. The dev's counter-probe (a duplicated ai snapshot → exit 1 with the annotation, restored by blob hash) is the card's acceptance line for a ported gate; the run id for the step lands on the card when Type Check UI finishes.
  • Nothing to carry: no should-fix.

④ Design judgment

  • Folding the gate into the job that already pays for the full history, before its install, is the cheapest correct home; keeping the finding non-blocking is the classification the gate's own header reserves for the maintainer; and retiring two scripts nothing ran rather than leaving them half-dead is what the card asked. Holds, with the signal-surface note above left to the maintainer.

Implemented-by: claude/project-thread-oo129e
Reviewed-by: session_01ADHkmQr732toX135tyo5zs

VERDICT: PASS


Generated by Claude Code

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 size/xl skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants