Skip to content

test(ui-merge): the governance pins on objectui's workflows retire to their roster rows and root gates; the Node anchor reads the root workflows - #25940

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-6qe56u
Oct 26, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-6qe56u

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Part of #25712 (4b PR 2d-2b: the last ui/scripts/__tests__ files that scan ui/.github/workflows/ as a population stop reading it).
Part of objectstack#25677.

Clause-②: no
Metadata-protocol: none

维护者速读(草稿)

  • 改了什么: 2d-2a(test(ui-merge): the repo-gates wiring pins retire with their port; "no workflow runs this" pins read the root workflows #25904)之后,还剩 8 个测试文件把嵌套的 ui/.github/workflows/ 当作一个总体来扫描。这个目录在 monorepo 里不运行。
    • doc-version-claims 和 check-lockfile-dedupe 的扫描改成读根目录的 .github/workflows/。
    • ci-setup-pnpm-wiring 改为断言根目录 4 个 UI job 都通过根目录的 ./.github/actions/setup-pnpm 安装 pnpm。
    • dependabot-merge-gate、merge-queue-reporting、check-lockfile-integrity 里读 objectui workflow 的 pin 退役,每条都写明由谁承接:路线表的行号,或者根目录现在承担这件事的 gate。其余用例保留。
    • workflow-cache-save-bound 和 labeler-package-coverage 两个文件整个删除,因为里面每个用例都读 objectui 的 workflow 或 labeler 配置。
    • 按 dispatcher 对 F12 的裁定 B,根目录 labeler.yml 不加 ui/ 规则(原因见下)。
  • 为什么改: 2d-3 要删除 ui/.github/workflows/,删之前这 8 个文件必须先不依赖它。改完以后,无论 ui/.github/workflows/ 在不在,保留和修改的 6 个文件都是绿的(本地两种布局都是 96 个用例通过)。
  • 风险与代价(含回滚): 只动测试和一个测试 ledger,不动任何会运行的代码、workflow 或受管面。退役的 pin 都写明了承接方。回滚 = revert 本 PR。
  • 席位意见:(留空)
  • 你要做的: 无。Tier S,由席位落地。

席位核对

(left for the dispatch seat)

Why

GitHub runs only the repository root's .github/workflows/. Since the cutover (#25825), objectui's workflows sit at ui/.github/workflows/ and run nowhere. 2d-1 (#25879) moved the readers of ui/.github/workflows/ci.yml. 2d-2a (#25904) took 18 of the 27 files that scan the workflow directory as a population. This PR takes the other 8, the governance files. check-pre-install-import-graph stays with 2d-3, because its gate, not just its test, derives its population from the nested workflows.

The rule is the same as in 2d-1 and 2d-2a. A pin is either retargeted to the root workflows by path, or retired with a comment naming who carries its subject. Nothing is skipped and nothing is folded into a root workflow.

What changes

  • dependabot-merge-gate. Three groups of pins read objectui's pull_request workflows through ./workflow-checks.ts: the bucket partition, the exemption control for RENAMED_SINCE_4959, and the six pins on dependabot-auto-merge.yml. They retire as roster row 9 (→ sub-issue 4). The gate's one caller is that workflow, which runs nowhere, and no root workflow merges Dependabot pull requests. Everything that judges a check-run list stays: the spec: view 元数据两种形状并存,且 objectui 写侧产出的可能不是根 schema 收的那一种 —— 需裁定唯一 authorable 形状 #4959 counterfactual, absence, the optional bucket, waitForGate, main(), the verdict text, the check-runs-only boundary, and the reasons.
  • merge-queue-reporting. The chore(deps)(deps): bump better-auth from 1.7.0-rc.1 to 1.7.0-rc.2 #3523 step 1 pins, the floor derived from REQUIRED_CONTEXTS (deriveMergeGroupFloor() and its three cases) and the step 2 pins all read objectui's workflows. The root gates already carry both chore(deps)(deps): bump better-auth from 1.7.0-rc.1 to 1.7.0-rc.2 #3523 holes, for every context the repository requires today: scripts/check-required-contexts.mjs (check:required-contexts) holds each required context's workflow to a merge_group: trigger (assertion 6) and to a pull_request trigger with no path filter (assertion 7), and check:workflow-status-functions pins the filter contract's status-function half. Both run in Lint · CI, release & engine gates. The CI page describe stays and now scans MUST_SUBSCRIBE_MERGE_GROUP alone.
  • check-lockfile-dedupe, check-lockfile-integrity. The wiring pins on objectui's lockfile-dedupe.yml and lockfile-integrity.yml retire as roster rows 18 and 19 (kept, follow-up port, re-aimed at the one root pnpm-lock.yaml). The dedupe test's live-reading scan now reads the root workflows through helpers/root-ci.ts, and LIVE_READING_SITES drops the nested workflow. The population controls and the classification cases stay.
  • ci-setup-pnpm-wiring. Three population cases swept objectui's workflows for calls to scripts/ci-setup-pnpm.sh, and they retire. A new describe asks the same questions of the four root * UI jobs, by path: no corepack outside the shared setup, and checkout before ./.github/actions/setup-pnpm before the first pnpm. All four hold at this head. The script and its self-test stay; no root job calls the script.
  • doc-version-claims. The node-version anchor (WORKFLOWS_DIR) is now the root .github/workflows/ (rootWorkflowsDir). All 56 root declarations read '22'. The census cross-check's key counter now skips whole-line YAML comments: root half-state-patrol.yml:111 quotes a commented setup example, and counting it would read the parser's correct silence as a lost lane.
  • Deleted: workflow-cache-save-bound.test.ts (11 cases) and labeler-package-coverage.test.ts (7 cases). Every case read objectui's workflows or ui/.github/labeler.yml. Their carriers are in rows 7 and 8 of the table.
  • ui/scripts/markdown-test-inputs.mjs. It drops the deleted labeler test's entry, and the walker: of merge-queue-reporting (its readdirSync(workflowDir) is gone).

F12 as ruled → B, labels absent

The dispatcher first ruled that this PR should add the ui/ globs to the root .github/labeler.yml and retarget labeler-package-coverage to it. Measuring first showed that this would turn root Auto Label red on every pull request touching ui/packages:

  • Root Auto Label (pr-automation.yml) is not actions/labeler. It is node scripts/pr-labels.mjs --paths, an additive POST with pull-requests: write only, and pr-labels.mjs treats any 4xx as fatal ("a 422 is a label that does not exist in the repo").

  • 28 of the 32 labels in ui/.github/labeler.yml do not exist in this repository's label registry:

    • package: core, package: types, package: react, package: components, package: app-shell, package: auth, package: cli, package: collaboration, package: create-plugin, package: fields, package: i18n, package: layout, package: mobile, package: permissions, package: providers, package: react-runtime, package: runner, package: sdui-parser;
    • plugin, plugin: charts, plugin: editor, plugin: kanban, plugin: markdown;
    • data-adapter, configuration, examples, apps, breaking-change.

    Only documentation, tests, dependencies and ci/cd exist.

The dispatcher re-ruled B:

  • no ui/ globs go into the root labeler;
  • the test's pins retire as roster row 14, because the monorepo label taxonomy belongs to sub-issue 4;
  • ui/.github/labeler.yml stays as an inert config until sub-issue 4 rules, and 2d-3 lists it as "kept, pending sub-issue 4".

Disposition table (8 files)

# File Retired Kept / retargeted Carried by now
1 dependabot-merge-gate found the workflows and the shard matrix, classifies every produced check exactly once, requires only contexts whose workflow carries NO path filter, marks optional exactly those blocking contexts whose workflow IS path-filtered; the exemption-control half of classifies every context the incident produced; the workflow cannot merge without consulting the gate (6 cases on dependabot-auto-merge.yml) the #4959 counterfactual (incident classification included), absence, optional bucket, waitForGate, main(), legibility, boundary, reasons roster row 9 (→ sub-issue 4)
2 merge-queue-reporting step 1 (3 cases), the derived floor (3 cases and deriveMergeGroupFloor()), step 2 (3 it.each over ci.yml/lint.yml and the 2 fail-OPEN cases) the CI page describe (4 cases), scanning the map root check:required-contexts assertions 6 and 7, and check:workflow-status-functions (Lint · CI, release & engine gates)
3 check-lockfile-dedupe has a workflow, --report-only, path-filtered, no merge_group, shared pnpm setup live-reading scan retargeted to root .github/workflows/; population controls; classification roster row 18 (kept, follow-up port)
4 check-lockfile-integrity exists and runs the gate, checks out deep enough to have a merge base classification roster row 19 (kept, follow-up port)
5 ci-setup-pnpm-wiring no workflow runs corepack outside the shared script, every workflow that invokes pnpm also runs the shared setup, every job that calls the setup script checks the repository out first retargeted: the four root * UI jobs, by path, against ./.github/actions/setup-pnpm; the script's own cases root type-check-ui, test-ui, lint-ui, build-e2e-ui
6 doc-version-claims (none) retargeted: the node-version anchor reads root .github/workflows/; the census skips comment lines root .github/workflows/
7 workflow-cache-save-bound (deleted) the 7 population cases (split restore/save, bounded and non-fatal saves, save after the last command, crowding) (none) #25869 row F1 (bound the root ui jobs' saves the objectui way; F11, the combined pnpm-store cache, is F1's scope)
ceiling pins: ci.yml::e2e ≤30, lint.yml::lint 25 root build-e2e-ui (ceiling 45) and lint-ui (ceiling 30); see follow-up F13
ci.yml::docs ≤15, live-e2e.yml ≤40, performance-budget.yml 25 roster rows 7 (Build Docs), 17, 22 (kept, follow-up port)
check-links.yml 20, cross-repo-issue-closer.yml 20, labeler.yml 20, changelog.yml unbounded roster rows 6, 8, 14, 2 (→ sub-issue 4)
8 labeler-package-coverage (deleted) all 7 (lit control, every package labelled, no dangling rule, package: X spelling, exemption lists, docs tree, issues: write) (none); ui/.github/labeler.yml stays, inert roster row 14 (→ sub-issue 4); F12 → B, above

Follow-up rows (not folded here)

What 2d-3 still owes (not here)

Verification

This head is main 2a728ba2 (with #25904) plus this commit. The test runs below were taken on main cb0a2fcf with 2d-2a and this commit applied. That tree's ui/ and scripts/pm/ are byte-identical to this head's: the only commit between them is #25830, which touches neither. The derived gates were re-run on this head. Test runs are from ui/, per ui/AGENTS.md.

Run Result
The 6 modified test files, ui/.github/workflows/ present 6 files, 96 tests, all passed
The same 6 with ui/.github/workflows/ moved aside (the 2d-3 layout) 6 files, 96 tests, all passed
Whole scripts/__tests__ suite, --shard=1/4 through 4/4, under scripts/pm/os-verify-lock.sh 5,370 passed, 1 failed, 2 skipped
pnpm type-check:scripts the one error is packages/components/src/renderers/action/resolve-icon.ts(265,69) TS2339, identical on unmodified main here; none in a touched file
pnpm exec eslint --max-warnings=0 (touched files), lint:coverage, check:test-path-roots, check:vi-mock-override-shape; root pnpm check:test-source-alias all exit 0

The one suite failure is the base red riding main: check-pre-install-import-graph, unresolved: scripts/objectstack-pin.mjs. Main's push run 40264138159 is red on the same row. It clears in 2d-3 with the nested workflows.

Derived gates (node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack): 18 families from this PR's 9 paths, 1830 changed lines. All 18 exit 0 at this head, and --ran reconciles 18 run, 0 NOT-MEASURED, 0 UNRUN. The same 18 also exited 0 on the cb0a2fcf tree. The slowest were check:query-options-erasure (567 s), check-comment-mask-corpus (326 s) and check:engine-double-contract (140 s), measured on a shared box.

Push-environment battery (GITHUB_ACTIONS=true GITHUB_EVENT_NAME=push node scripts/pm/check-dispatch-gates.mjs, both tiers): "✓ dispatch-gates self-test: 2182 cases pass." (fast 1917 in 403.6 s, slow 265 in 1124.4 s).

🤖 Generated with Claude Code

https://claude.ai/code/session_01A6SEitNngAMugGbuJHWsDS

… their roster rows and root gates; the Node anchor reads the root workflows

GitHub runs only the repository root's .github/workflows/. The last eight
ui/scripts/__tests__ files that scan ui/.github/workflows/ as a population
stop reading it.

- dependabot-merge-gate: the bucket partition against the check names
  objectui's pull_request workflows produce, its exemption control, and the
  six pins on dependabot-auto-merge.yml retire as roster row 9 (sub-issue
  4). The gate's one caller runs nowhere and no root workflow merges
  Dependabot pull requests. The verdict, deadline and legibility cases stay.
- merge-queue-reporting: the #3523 step 1 and step 2 pins and the floor
  derived from REQUIRED_CONTEXTS read objectui's workflows. The root
  check:required-contexts (assertions 6 and 7) and
  check:workflow-status-functions carry both holes for the contexts the
  repository requires today. The CI page describe stays, scanning the map.
- check-lockfile-dedupe, check-lockfile-integrity: the wiring pins on
  objectui's lockfile-dedupe.yml and lockfile-integrity.yml retire as roster
  rows 18 and 19 (kept, follow-up port). The dedupe gate's live-reading scan
  reads the root workflows.
- ci-setup-pnpm-wiring: the population cases over objectui's workflows
  retire; the four root ui jobs are held to the root setup-pnpm composite.
- doc-version-claims: the node-version anchor reads the root workflows,
  and the census counter skips whole-line YAML comments.
- workflow-cache-save-bound and labeler-package-coverage are deleted: every
  case read objectui's workflows or its labeler config. The root ui jobs'
  cache saves belong to the card that bounds them; the labeler pins retire
  as roster row 14, and ui/.github/labeler.yml stays until the label
  taxonomy is decided.
- markdown-test-inputs.mjs drops the deleted labeler test's entry and the
  merge-queue test's workflow walker.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A6SEitNngAMugGbuJHWsDS
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 26, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 26, 2026 04:54
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 26, 2026 04:54
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 40271867662 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

分类:failure —— 按下面的日志分诊。

失败的 job(日志抽取,best effort):

  • Test UI (14/16) — 失败步骤: Run the ui tests (shard 14/16)

    × finds no pre-install gate reaching a package 11ms
    FAIL   unit  scripts/__tests__/check-pre-install-import-graph.test.ts > the real tree — every step objectui#6148 measured is still derived > finds no pre-install gate reaching a package
      ↳ 失败原因: AssertionError: a script this repository runs before `pnpm install` needs `node_modules` to load: expected [ Array(1) ] to deeply equal []
    

↳ 失败原因 是判读的关键:超时(Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言(AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️ 断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError。 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 12 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit 17c5e68 Oct 26, 2026
58 of 59 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-6qe56u branch October 26, 2026 05:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

2 participants