Skip to content

[Decision] Test UI is not a required context, so the merge queue lands a PR whose Test UI shard is red (#26419 → #26421): enrol a Test UI aggregate as required, keep it advisory with a seat read, or keep it as is #26460

Closed

Description

@objectstack-fleet

Ruled: 6435318516 · letter A (staged) · 2026-10-27T06:31Z

Filing gate ②: a maintainer-only decision. Enrolling a required context is a new gate (「新增门禁默认否」), and it revisits ruling 30 = B on #25752 (test shards read afterwards on main). Maintainer, 2026-10-27, verbatim: 「立决策卡」, on the triage seat's R697 report. Filed by the triage seat (session_01AavokzJ5DndAwitDXvKy4U, seat post #6015). ⛔ Not a claim.

维护者速读

合并队列只认 8 个必过检查。Test Core 有一个汇总任务(Test Core)是必过的,但 Test UI 的 16 个分片没有汇总,都不是必过。所以 Test UI 红了,队列照样合入。今天凌晨 #26419 就是这样:它的席位 03:24Z 发现会红,撤回草稿,但已经入队,03:20Z 先合了。现在 main 上 Test UI(8/16)是确定性的红,修复在 #26421。10-26 下午的 corpus guard 红(#26222/#26223/#26234)也是同一个口子。请裁:A 仿照 Test Core 加一个 Test UI 汇总任务,列入必过——新增门禁;B 不加必过,让席位放行前必须读队列构建里的 Test UI 结果,红了就不放行;C 维持现状,红了合入后再修。选 A / B / C?

Premises (measured 2026-10-27, on origin/main)

Options

Option What Consequence Workload
A A Test UI aggregate job (as Test Core has), enrolled in REQUIRED_CONTEXTS and in the ruleset. The queue refuses a red Test UI, and main stops taking ui test reds. A flaky shard ejects queue entries; the flake-anchor workflow already reports those. No extra runtime: the shards already run in the queue. devx · 1 PR, Tier H (.github/workflows/**) · the maintainer flips the ruleset entry in the same sitting (precedent: Lint UI and Build & E2E UI, enrolled 2026-10-26T00:25Z)
B No gate. At ACCEPT the seat reads the queue build's (or the PR head's) Test UI and does not land it on red. No CI change, but P3 is exactly the case where the seat read it and still could not stop a queued PR. It does not close the gap. skills · 1 line in the review checklist
C Keep it as is. Each such red is fixed after it lands. Twice in two days so far. none

Recommendation

A, after the dev measures P5 on the last 50 queue builds. The shards already run in every queue build, so A adds no runtime, only the refusal. B relies on a seat act that P3 shows cannot stop a PR already in the queue. If P5 shows Test UI flaking above Test Core's rate, fix the flakes first ("a failing test is never an infra flake") and then enrol.

os-decision-facets
① 项目长远合理性:A 让 ui 测试和 core 测试同等对待(Test Core 早已必过),消除并仓后留下的不对称;不新增测试,只新增拒绝。
② 实际业务拉动:两天内两次 main 变红(#26234、#26421),一次已经影响发版前的全量检查。
③ 防 AI 犯错:A 是合并前响亮拒绝;B 靠席位记得读,而 P3 证明入队之后席位已经拦不住。
④ 创业阶段不扩散:A 是新门禁(默认否),但不多跑任何东西;如果分片不稳,先修不稳再列入。
Prior rulings read: required contexts · Test UI advisory · ruling 30 → #25752 ruling 30 (B, for the cutover sitting), step 6 enrolment of Lint UI and Build & E2E UI; 「新增门禁默认否」; 「平台测试清单反复变红,肯定要修啊」; ADR none; thread: #26422, #26421

After the ruling

A: domain:devx dispatches the aggregate job (Tier H), and the maintainer enrols the context in Settings → Rulesets in the same sitting as the merge (#9325's two-halves rule). B: domain:skills widens the ACCEPT check.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_017iXjUm1rujwDk7f3KT1Pkk (seat); implementing card thread session_01ADHkmRBcYqig1yVS7FYsGL
    Account: os-steve
    Branch: claude/project-thread-2ddfc7 (platform-assigned card-thread branch; a card thread can push only its assigned branch, and the name carries no issue number, so this claim is the identity record)
    Worktree: the card thread's own container
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: read-only measurement of the newest 50 merge-queue CI runs (Test UI shards), one stamped reading comment on #26460, and test-only flake fixes in seat 1 packages (S, skip-changeset); ⛔ no .github/** / ci.yml / REQUIRED_CONTEXTS edit (stop on breach; explain in the report). ⛔ ui/.github/** and the root .github/workflows/ci.yml are out of bounds (maintainer's word, ui-merge epic in flight). Changeset in the root .changeset/.
    Container & model: S, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a: renderer defect in ui/, the producing code is the cited ui file; no platform path covers it; reached through the public Console
    Thread-read: 6435318516
    Premise: holds: ruling 6435318516 (letter A, staged) puts the ui lane first: measure the Test UI flake rate on the last 50 merge-queue builds and fix the flakes the anchors name; the four anchors (#26222, #26223, #26247, #26422) read closed at 2026-10-27T07:30Z. This claim covers the ui step 1 only; the aggregate job (Tier H, ci.yml) stays with domain:devx
    Serial constraints cleared: none

    Dispatch order handed to the card thread by the project coordinator (three partitions: ruling / mechanism hypotheses / suggested route); the dev does not claim, and starts only once this claim names its branch.

  2. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Test UI flake reading (ui step 1 of ruling 6435318516) · ui seat 1 card thread · session_01ADHkmRBcYqig1yVS7FYsGL · 2026-10-27T07:51Z

    Result: no Test UI flake is live on main. The ui step is complete, so domain:devx can land the Test UI aggregate.

    Source: the Actions API, workflow CI (id 224644133), event=merge_group, every job of every attempt (filter=all). A red shard is classified from its check-run annotations (the failing test file and the assertion). Two terms: a build is one merge-group CI run, and ran Test UI means its 16 Test UI (k/16) shards ran rather than being skipped by the ui filter. No build in any window below had a re-run attempt or a cancelled Test UI shard.

    1. Main reading: the newest 50 queue builds that ran Test UI

    Window 2026-10-26 23:32Z → 2026-10-27 07:10Z (run 40465493520 is the newest completed)
    Builds / shards 50 builds · 800 shard jobs
    Red shards 4, in 4 builds
    (a) deterministic, inherited 4: ui/scripts/__tests__/doc-version-claims.test.ts L2893 / L2917, expected 1 to be greater than or equal to 15. Root #26419 (d15f99d72f) moved the workflows' literal node-version: lines to .nvmrc. Builds 40443632873 (#26419, root), 40443739774 (#26325), 40443830059 (#26412) and 40446655069 (#26426) were stacked on it or on main after it merged. Fixed by #26421 → PR #26432, 6746140361
    (b) flake 0
    (c) real defect in the queued PR 0
    Flake rate 0 / 50

    2. The literal reading: the newest 50 queue builds of any kind

    Window 2026-10-27 04:20Z → 07:10Z. Only 18 of those 50 ran Test UI (288 shards). The other 32 skipped it because their diff did not reach ui/. 0 red, flake rate 0 / 50. That is why section 1 counts builds that ran Test UI: 18 builds over three hours is too thin to measure a flake rate.

    3. 24-hour extension, to reach the four anchors and their fixes

    Window 2026-10-26 07:31Z → 2026-10-27 07:10Z: 395 completed queue builds, 31 red. 165 of them ran Test UI (2640 shards).

    Test file Hits (build, time Z) Class Fix on main
    ui/packages/app-shell/src/services/MetadataService.specKeyObjectPayload.test.ts L175 and …retiredObjectEnabled.test.ts L161, expected 48 to be 47 (anchors #26222, #26223) 7 builds, 10-26 15:46 → 16:42 (#26177, #26053, #26197, #26033, #26158 ×2, #26203) (a): #26005 adopted sharing as the 48th ObjectSchema key, and the corpus guards pinned 47 PR #26231, a1477dec8a
    ui/apps/console/src/pages/settings/__tests__/SettingsView.shellLeave-13231.test.tsx L195, Unable to find … Profile page (anchor #26096) 3 independent: 40293762961 (#25996, 08:39), 40316529606 (#26057, 11:38), 40337868008 (#26027, 14:14) (b): after the save, the page's unsaved-edits registration was still held when the test clicked, so the leave was cancelled (os-dev report on #26096) PR #26212, f42b55f2f3, test-only
    ui/packages/app-shell/src/__tests__/buildIdentity-12970.test.ts L41, expected '1bbb7bf490' to be null 1: 40325012039 (#26019, 12:45) (b): the console project's VITE_APP_VERSION define leaked into process.env, and it went red only when another project's config resolved after the console's PR #26197 (#26126), f143cd8809
    vi.mock errors across ui/apps/console, with Build Core red on app-shell Cannot redeclare block-scoped variable 'isNew' 40316357014 (#26056, 11:36) plus 7 builds stacked behind it, 11:37 → 11:48 (c): #26056's own group, on the green #26057 group d6b39f6376. #26056 was corrected and merged at 12:51 as 6d15acabda in the PR before it landed
    doc-version-claims.test.ts (anchor #26422) the 4 builds in section 1 (a) PR #26432, 6746140361

    The anchor #26247 (plugin-security/src/controlled-by-parent-owner-may-edit.test.ts) is a Test Core (5/8) red (builds 40355861805 and 40358686385), not Test UI. It was one deterministic break from #26064's queued commit 17f21e8d, and #26064 fixed it before landing (733b3c849a). No queue build after that has a red Test Core shard.

    Fixes verified on main

    Each fix commit is an ancestor of origin/main f48aa4510. git merge-base --is-ancestor gave exit 0 for a1477dec8a, 733b3c849a, 6746140361, f42b55f2f3 and f143cd8809, and an exit 0 proves itself even in a shallow checkout. No test file named above has gone red in a queue build since its fix landed:

    Fix Queue builds that ran Test UI after it landed Red shards from that file
    #26197 (16:06Z 10-26) 104 0
    #26212 (16:58Z 10-26) 98 0
    #26231 (17:10Z 10-26) 98 0
    #26432 (04:12Z 10-27) 19 0 (no red shard at all)

    For the aggregate

    In the last 24 hours, every Test UI red in the queue had a named cause that is now fixed on main. 15 of the 31 red builds were Test UI alone (one red shard or several, from one cause). Under ruling A the required aggregate would refuse each of those queue entries, which is the intended refusal. Two flake files in 24 hours were both fixed within hours, and 98+ builds since then are clean. So this reading gives no reason to hold back the enrolment. No PR was opened for this step: no flake file is still live, so step 2 of the dispatch had nothing to fix.

    Caveat: merge-group Test UI runs only the shards' affected selection (ui/scripts/select-affected-tests.mjs), so a flake in a file that no queued diff selects stays out of this reading. The scheduled full battery on main is the backstop for those files.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26460,
      "status": "done",
      "branch": "claude/project-thread-2ddfc7",
      "pr": null,
      "session": "session_01ADHkmRBcYqig1yVS7FYsGL",
      "premise_still_valid": true,
      "summary": "ui step 1 of ruling 6435318516 (claim 6436277065). Measured Test UI over merge_group CI builds (Actions API, workflow 224644133, filter=all), classified every red shard from its check-run annotations, and posted the reading as comment 6436579765. Main reading, the newest 50 queue builds that ran Test UI (10-26 23:32Z to 10-27 07:10Z, 800 shards): 4 red, all (a) doc-version-claims from #26419, fixed by PR #26432 (6746140361). (b) = 0, (c) = 0, flake rate 0/50. The literal newest 50 builds of any kind: 18 ran Test UI, 0 red. Over a 24h extension (395 builds, 165 ran Test UI): 2 flake files, SettingsView.shellLeave-13231 (3 hits, seat 2, fixed by PR #26212 f42b55f2f3) and buildIdentity-12970 (1 hit, fixed by PR #26197 f143cd8809), plus 7 (a) corpus-guard builds (PR #26231 a1477dec8a) and one (c) group (#26056's own Build Core isNew redeclare, corrected before it merged). All four anchors are verified: the fix commits a1477dec8a, 733b3c849a and 6746140361 are ancestors of origin/main f48aa4510, and no named file has gone red in the queue since its fix. No flake is live, so step 2 had nothing to fix and no PR was opened. Seat 1 approved posting the reading before it went up.",
      "tests": "No code change and no tests run. The reading is API data: run lists from /actions/workflows/224644133/runs?event=merge_group (4 pages, 400 runs, 395 completed), jobs from /actions/runs/ID/jobs?filter=all, failure lines from /check-runs/ID/annotations. Job log downloads were refused by the container proxy (CONNECT 403), so annotations were the evidence. Ancestry: git merge-base --is-ancestor gave exit 0 for a1477dec8a, 733b3c849a, 6746140361, f42b55f2f3 and f143cd8809 against origin/main f48aa4510.",
      "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack exited 2 with 'this branch changes nothing against origin/main (merge base f486e9c1b) — nothing to derive'. Empty diff, so there is no local gate subset and no PR check-runs.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm (no PR)",
      "mcp_calls": "0 — no MCP GitHub calls; reads went through the container proxy's REST",
      "api_writes": "2 — post-stamped via relay: POST /repos/objectstack-ai/objectstack/issues/26460/comments for the reading (6436579765) and this os-dev-report. No git push, no pr_create.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed: merge-group Test UI runs only the affected selection, so a flake in a file no queued diff selects is outside this reading. The scheduled full battery on main is the backstop. Stated as a caveat in 6436579765."
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 11 · 2026-10-27T07:54Z
    Session: session_01Q4MDXRbEJCNdPAP4SiXwp9 (devx seat 2) · card thread cmsg_01FdL1XeUyvVNxLreh3F4Qi9C2Dy8KN4fv23aea1JR1i9T
    Account: os-steve
    Branch: claude/project-thread-nsgh5p (the harness-pinned branch of the card thread; it names no issue, so this claim is the identity record; amended on spawn)
    Worktree: objectstack-issue-26460
    Domain: domain:devx
    Seat: domain:devx#2 (seat post #20163)
    File surface: .github/workflows/ci.yml, one new aggregate job named exactly Test UI over the 16 test-ui shards, in the test-gate shape (name: literal and if: always() both load-bearing, a needs-result check that reds on any non-success shard), placed next to test-ui; scripts/check-required-contexts.mjs one REQUIRED_CONTEXTS row (workflow: 'ci.yml', job the new job id, context: 'Test UI', authorized naming ruling 6435318516) plus its self-test cases and any doc the registry derives. Any gate that counts ci.yml jobs or required contexts and reds on the new one, only as far as the new row needs. ⛔ No other ci.yml job; no shard, timeout or filter change. The ruleset entry is the maintainer's, in the same sitting as the merge. The PR is Tier H (.github/workflows/**): draft until a GOVERNED_APPROVERS approval
    Container & model: S, mode:thread, model: default tier (TIER_DEFAULT, from dispatch-gates --tier: no path-derived mandate), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Ruling-ref: 6435318516
    Responsibility: n/a — maintainer-only decision card (「立决策卡」); ruled A (staged) at 6435318516; the ui step's reading (flake rate 0/50) is 6436579765
    Thread-read: 6436579765
    Premise: on origin/main, REQUIRED_CONTEXTS has 8 rows and no Test UI; ci.yml job test-ui is named Test UI (${{ matrix.shard }}/16) and has no aggregate (the dev re-reads both before editing)
    Serial constraints cleared: #25870 (this seat, claim 6436188889) also edits ci.yml, but only the Test Core "Declarations skipped" / closure steps; this claim touches no Test Core line. ci.yml is not a single-claim path. Whichever lands second merges origin/main first


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26460,
      "status": "done",
      "branch": "claude/project-thread-nsgh5p",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26569",
      "session": "session_01ADHkmNhqdySz5JeM3ARKGW",
      "premise_still_valid": true,
      "summary": "devx step of ruling 6435318516 (letter A, staged; claim 6436627175), after the ui step's flake reading 0/50 (6436579765). Premise re-read on origin/main f48aa4510: REQUIRED_CONTEXTS had 8 rows and no Test UI; test-ui is a 16-leg matrix named 'Test UI (${{ matrix.shard }}/16)' with no aggregate. Added ci.yml job test-ui-gate, name: Test UI, needs [test-ui, filter], if: always(), roster declaration (members test-ui, non-member filter), one step: rollup success passes, skipped passes only when filter succeeded and ui_tree or ui is 'false' (#4928), everything else red. Registered the context in REQUIRED_CONTEXTS and the REQUIRED_AGGREGATORS floor, with self-test cases in both; the two statesTheSet surfaces (AGENTS.md merge-queue rule, pm-dispatch platform-readings.md) go eight to nine, as #25857/#25878 did. Draft PR #26569, Tier H: waits on a GOVERNED_APPROVERS approval (os-zhuang, hotlong); the ruleset entry is the maintainer's in the same sitting as the merge.",
      "tests": "head 853ddedb4: node scripts/check-required-contexts.mjs exit 0 (9 pinned, ci.yml:test-ui-gate -> 'Test UI'); --self-test exit 0, 179 assertions (new: rename of the bare Test UI name red; Test UI shard-name collision red + coexistence control). node scripts/check-aggregator-roster.mjs exit 0 (5 aggregators, all 5 required declared); --self-test exit 0, 63 assertions (new: dropped-member and phantom-needs controls for test-ui-gate). pnpm --dir ui exec vitest run scripts/__tests__ under os-verify-lock: VERDICT command-exit 0, Test Files 178 passed | 2 skipped (180), Tests 5097 passed (the ui pins that read ci.yml as text). No ablation: the diff changes a workflow, gate scripts and prose, not tested runtime behaviour.",
      "gates": "head 853ddedb4: dispatch-gates --commands derived 80 families; all run, each exit captured before any pipe; --ran reconciliation exit 0: 80 derived, 80 run, 0 NOT-MEASURED (derived zero). Five first exited 3 (PREREQUISITE NOT MET, no built dist): check:doc-formula-expressions, check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content; re-run exit 0 after turbo run build --filter='./packages/**' (lock VERDICT command-exit 0). check:pm-dispatch-gates exit 0 (1935 fast-tier cases). PR check-runs: in_progress at report time.",
      "line_budget": "+119 / -14 across 5 files (133 changed lines, under the 3000 human-merge threshold)",
      "files_changed": [".github/workflows/ci.yml", "scripts/check-required-contexts.mjs", "scripts/check-aggregator-roster.mjs", "AGENTS.md", ".claude/skills/pm-dispatch/references/platform-readings.md"],
      "deviations": [
        "AGENTS.md and .claude/skills/pm-dispatch/references/platform-readings.md are governed surfaces the increment does not name. They were edited (one list line each, eight to nine) because check:required-contexts reds otherwise: both are statesTheSet surfaces whose mustName must equal the registry exactly. Read as the claim's 'any doc the registry derives' / 'only as far as the new row needs', following #25857 and #25878, which edited the same two lines in the registry PR. The PR is Tier H either way.",
        "scripts/check-aggregator-roster.mjs is not named in the claim's file surface: REQUIRED_AGGREGATORS gained the test-ui-gate row because its header keeps it in step with REQUIRED_CONTEXTS (the required names that aggregate), so the new aggregate cannot silently lose its roster declaration.",
        "The PR was not subscribed for activity: the dispatch contract owns CI convergence; patch rounds come through the seat."
      ],
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "4 — issue_read x3 (get, get_comments x2), pull_request_read x1 (get, PR read-back); no MCP write",
      "api_writes": "3 — git push of claude/project-thread-nsgh5p; relay pr_create (PR #26569, draft, assignee os-steve, label skip-changeset); this os-dev-report comment via post-stamped",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: ui lane (seat 1) · noted, not filed: ui/scripts/check-test-shard-results.mjs (objectui's per-shard `Test` aggregate reader, row 7 of #25697, 'dropped until cutover') hardcodes `Test (shard N/M)`, so it cannot read `Test UI (k/16)`. If the ui lane wants per-shard conclusions instead of the rollup word, its port re-derives the spelling from the root job and test-ui-gate's step can call it.",
        "carrier: none · noted, not filed: 'cancelled' reads red, so a superseded PR push paints the old sha's Test UI red; no required check reads an old sha."
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: session_01Q4MDXRbEJCNdPAP4SiXwp9 (devx seat 2) · seat signs off on the maintainer's word 「devx 车道当前任务处理完就下班」 (2026-10-27 08:42Z) · next: a GOVERNED_APPROVERS approval of PR #26569, then merge, then the maintainer adds Test UI to the main ruleset in the same sitting

    PR #26569 (head 853ddedb) carries a Contract review PASS (6437562805) and the seat ACCEPT (6437580781); CI was green except two jobs still running at review time. It is Tier H (.github/workflows/ci.yml, AGENTS.md) and stays a draft. ⛔ Merge first, ruleset second: listing Test UI in the ruleset before the job exists on main leaves every PR and queue entry pending (the #3622 deadlock). The card closes on Fixes when it merges.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    devx seat 2 · half-state corrected · 2026-10-27T23:03Z

    This card is closed but still carried pm:awaiting-maintainer. Closing strips pm:* status labels in the same stroke, so the label is removed now. Nothing else changed.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Triage: the ruleset half is done — Test UI is a required context on main · 2026-10-28T07:20Z

    ⛔ Not a claim.


    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:devxpriority:p1High: required for production / M2teststooling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions