Skip to content

ci(test-ui): add the Test UI aggregate job and register it as a required context - #26569

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

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

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steve · project thread
Fixes #26460

Clause-②: no
Metadata-protocol: none

Tier H (.github/workflows/ci.yml, AGENTS.md; .claude/** rides along). Draft until an approval from GOVERNED_APPROVERS (os-zhuang, hotlong). The ruleset half — adding Test UI to the main ruleset's required status checks — is the maintainer's, done in the same sitting as the merge (#9325's two halves; precedent Lint UI / Build & E2E UI via #25857 and Type Check UI via #25878).

维护者速读

  • 改了什么:在 ci.yml 加一个汇总任务 Test UI(job id test-ui-gate),覆盖 16 个 Test UI (k/16) 分片,任一分片不是 success 就红;分片因 ui 过滤被跳过时为绿。注册表、汇总名册和两处写着必过名单的说明文字同步从 8 个变 9 个。
  • 为什么改:裁决 6435318516(字母 A,分阶段)。Test UI 分片都不是必过,队列照样合入 Test UI 红的 PR(ci: one setup-workspace composite action replaces the setup steps copied into 38 jobs, and pull requests stop saving the pnpm store #26419 → ui/scripts: doc-version-claims anchors the docs' Node version on literal node-version: lines in .github/workflows, so #26419 (Node read from .nvmrc) turns it red #26421)。ui 车道的第一阶段读数已完成:最近 50 次跑了 Test UI 的队列构建 flake 0/50(6436579765)。
  • 风险与回滚:只新增一个约 10 秒的任务,不改分片、超时、过滤。合入后在 ruleset 里加上 Test UI 才生效;回滚就是从 ruleset 删掉这一项再 revert 本 PR。若 Test UI 出现 flake,会把队列条目弹出。
  • 先看:.github/workflows/ci.yml 新增的 test-ui-gate 任务(判定的 case 分支);scripts/check-required-contexts.mjs 新增的注册行;AGENTS.md 第 525–528 行的名单。
  • 两分钟验证:node scripts/check-required-contexts.mjs && node scripts/check-aggregator-roster.mjs,应看到 ci.yml:test-ui-gate → 'Test UI' 和 5 aggregator(s);本 PR 的 checks 里应有一个名为 Test UI 的绿色检查。
  • 需要你做的:批准本 PR,合入时在 Settings → Rulesets → main 的必过检查里加上 Test UI。

What changes

  • .github/workflows/ci.yml: a new job test-ui-gate, name: Test UI, needs: [test-ui, filter], if: always(), placed right after test-ui. It copies test-gate's shape: the name: literal and if: always() are both load-bearing, and it declares its roster (OS_AGGREGATOR_MEMBERS: test-ui, OS_AGGREGATOR_NON_MEMBERS: filter). Its one step reads the matrix rollup needs['test-ui'].result:
  • scripts/check-required-contexts.mjs: one REQUIRED_CONTEXTS row (ci.yml, test-ui-gate, Test UI, authorized naming ruling 6435318516 and the reading 6436579765). Both statesTheSet surfaces' mustName gain Test UI. Self-test: battery (3) renames the bare Test UI name and expects red; battery (9) collides the Test UI (k/16) shard name with the bare gate name and expects red, plus the coexistence control.
  • scripts/check-aggregator-roster.mjs: REQUIRED_AGGREGATORS gains ci.yml/test-ui-gate/Test UI, the floor that keeps the new aggregate from losing its roster declaration. Self-test batteries (2) and (3) gain the dropped-member and phantom-needs: controls for it.
  • AGENTS.md (merge-queue rule) and .claude/skills/pm-dispatch/references/platform-readings.md: the required-set list grows from eight to nine. check:required-contexts reds until both name the registry exactly (statesTheSet); the count words are hand-followed.

Why

Ruling A (staged) on #26460, comment 6435318516. The ui step it orders first is done: the flake reading on the newest 50 queue builds that ran Test UI is 0/50, and every Test UI red in the last 24 hours has a named cause that is fixed on main (comment 6436579765).

Acceptance notes

  • Rollup, not per-shard credentials. test-gate counts shard attestations because one rollup word cannot carry several shards' verdicts. The Test UI shards publish no attestation, and adding one is a change to test-ui (pinned by the ui lane's ui/scripts/__tests__), so this job reads the rollup and fails closed on every value except success and a filter-explained skipped. The rollup's known blind spot, a matrix where some legs are skipped and the rest succeed, cannot occur here: all 16 legs share one job-level if: and a static matrix, and the ui lane pins the width at 16 (select-affected-tests-wiring.test.ts).
  • cancelled is red. That is also what a shard killed by its own timeout-minutes reads, which must not pass. On a superseded push it paints the old sha red, which no required check reads.
  • objectui's per-shard reader ui/scripts/check-test-shard-results.mjs (the ported Test aggregate, row 7 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's roster, "dropped until cutover") hardcodes the Test (shard N/M) spelling, so it cannot read Test UI (k/16) without a ui-lane change. Not used here; noted for the ui lane.

Verification

All on head 853ddedb4.

The two touched gates and their self-tests
node scripts/check-required-contexts.mjs                → exit 0 · 9 pinned, ci.yml:test-ui-gate → 'Test UI'
node scripts/check-required-contexts.mjs --self-test    → exit 0 · 179 assertions
node scripts/check-aggregator-roster.mjs                → exit 0 · 5 aggregator(s); all 5 required-context aggregate(s) declared
node scripts/check-aggregator-roster.mjs --self-test    → exit 0 · 63 assertions
dispatch-gates derived family

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran → exit 0: 80 derived, 80 run, 0 NOT-MEASURED (a derived zero). Five families first read exit 3 (PREREQUISITE NOT MET: no built packages/* dist) and were re-run green after turbo run build --filter='./packages/**': check:doc-formula-expressions, check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content. check:pm-dispatch-gates: 1935 fast-tier cases pass.

Also run, outside the derivation because the ui lane's pins read ci.yml as text: pnpm --dir ui exec vitest run scripts/__tests__ → exit 0, Test Files 178 passed, 2 skipped (180); Tests 5097 passed.

node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-declaration-mirrors.mjs :: exit 0
node scripts/check-declaration-mirrors.mjs --self-test :: exit 0
node scripts/check-dts-emitted.mjs --self-test :: exit 0
node scripts/check-platform-checklist-watchdog.mjs :: exit 0
node scripts/check-platform-checklist-watchdog.mjs --self-test :: exit 0
node scripts/check-release-section-coverage.mjs :: exit 0
node scripts/check-release-section-coverage.mjs --strict :: exit 0
node scripts/check-self-test-wired.mjs :: exit 0
node scripts/check-self-test-wired.mjs --self-test :: exit 0
node scripts/check-self-test-workflow-commands.mjs :: exit 0
node scripts/check-self-test-workflow-commands.mjs --self-test :: exit 0
node scripts/check-step-collectors.mjs :: exit 0
node scripts/check-step-collectors.mjs --self-test :: exit 0
node scripts/check-whole-set-label-write.mjs :: exit 0
node scripts/check-whole-set-label-write.mjs --self-test :: exit 0
node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0
node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0
node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0
node scripts/ci/scheduled-full-run.mjs --self-test :: exit 0
node scripts/docs-audit/check-drift-comment.mjs :: exit 0
node scripts/pm/bare-root-worklist.mjs --self-test :: exit 0
node scripts/pm/board-snapshot.mjs --self-test :: exit 0
node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0
node scripts/pm/check-harness-current.mjs --self-test :: exit 0
node scripts/pm/ci-failure.mjs --self-test :: exit 0
node scripts/render-release-coverage-anchor.mjs --self-test :: exit 0
pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0
pnpm check:agent-test-spelling :: exit 0
pnpm check:aggregator-roster :: exit 0
pnpm check:bash32-floor :: exit 0
pnpm check:ci-filter-parity :: exit 0
pnpm check:cli-command-ids :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:declared-population-live :: exit 0
pnpm check:doc-authoring :: exit 0
pnpm check:docs-audit-scope :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:dts-closure :: exit 0
pnpm check:dual-build-cjs-loads :: exit 0
pnpm check:entry-guard :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:lean-entry-closure :: exit 0
pnpm check:node-version :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:parse-guard :: exit 0
pnpm check:platform-checklist :: exit 0
pnpm check:pm-close-cards :: exit 0
pnpm check:pm-expected-skips :: exit 0
pnpm check:pm-fleet-write-dispatch :: exit 0
pnpm check:pm-fleet-write-execute :: exit 0
pnpm check:pm-fleet-write-validate :: exit 0
pnpm check:pm-governed-merges :: exit 0
pnpm check:pm-governed-prose :: exit 0
pnpm check:pm-half-states :: exit 0
pnpm check:pm-issue-transfer :: exit 0
pnpm check:pm-post-stamped :: exit 0
pnpm check:pm-record-recognisers :: exit 0
pnpm check:pm-skill-id-lint :: exit 0
pnpm check:pm-skill-ratchet :: exit 0
pnpm check:pnpm-acquisition :: exit 0
pnpm check:pnpm-filter-targets :: exit 0
pnpm check:pnpm-flag-spellings :: exit 0
pnpm check:ratchet-remedy-authority :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:required-contexts :: exit 0
pnpm check:scripts-symbol-anchors :: exit 0
pnpm check:shard-attestation :: exit 0
pnpm check:skill-frame-sync :: exit 0
pnpm check:sourcemap-no-sources-content :: exit 0
pnpm check:stall-guard-budget :: exit 0
pnpm check:stall-guard-headroom :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:workflow-status-functions :: exit 0
pnpm check:workflow-step-name-quoting :: exit 0
pnpm check:pm-dispatch-gates :: exit 0

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (No schema touched.)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint is CI's repo-wide run, not run locally.
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. Nothing publishes (CI workflow, repo scripts and instruction prose): skip-changeset; both declaration lines are above.
  • 6. packages/spec not touched.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English (the 维护者速读 block is the maintainer's Chinese summary).
  • The Before Submitting list in CONTRIBUTING.md is done. (Local runs are the derived gate subset above; the full farm is CI's.)

Generated by Claude Code

…uired context

A `test-ui-gate` job named `Test UI` over the 16 `test-ui` shards, in
test-gate's shape (`name:` literal, `if: always()`, roster declaration),
red on any rollup other than success or a filter-explained skip. One
REQUIRED_CONTEXTS row, the REQUIRED_AGGREGATORS floor row, self-test
cases for both, and the two statesTheSet instruction surfaces follow the
registry (eight to nine).

Claude-Session: https://claude.ai/code/session_01ADHkmNhqdySz5JeM3ARKGW
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 27, 2026
@github-actions github-actions Bot added size/m ci/cd documentation Improvements or additions to documentation labels Oct 27, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 853ddedb4844c75351d2773fe4ee50091e4b1f2a
Local-runs: none
Scope: .claude/skills/pm-dispatch/references/platform-readings.md, AGENTS.md, .github/workflows/ci.yml + scripts/check-required-contexts.mjs, scripts/check-aggregator-roster.mjs, ci.yml jobs filter / ui-deps / test-ui / test-gate / lint-ui / build-e2e-ui (read, not reviewed), scripts/check-shard-attestation.mjs (gate discovery only), .github/workflows/fleet-patrols.yml required-set-patrol

Card #26460 read in full: body, brief 6433960457, ruling 6435318516 (letter A, staged), ui claim 6436277065, flake reading 6436579765 (0/50), ui os-dev-report 6436597045, devx claim 6436627175, devx os-dev-report 6437393268. Net diff read as git diff f48aa451 pr/26569 (5 files, +119/-14); origin/main has moved three commits past the merge base and touches none of the five files, so the net diff is the merge diff.

① Derived judgments

  • Required-set change (the public surface of this PR): eight contexts become nine, Test UI added, nothing renamed or dropped. Right. The registry row (ci.yml / test-ui-gate / Test UI) names the ruling, the flake reading and the maintainer's ruleset half; RETIRED_CONTEXT_NAMES is untouched because no existing literal moves. The nine literals in the registry, in AGENTS.md line 523–527 and in platform-readings.md line 390–392 are membership-identical (the gate's statesTheSet census compares count and includes, not order; the two prose surfaces place Test UI between Type Check UI and Build & E2E UI while the registry appends it last — order was already unaligned across the three before this PR and is not a gate input).
  • The Test UI verdict table agrees exactly with test-ui's own if:. test-ui runs iff !cancelled() && ui_tree != 'false' && ui != 'false'; it is therefore skipped only when (a) ui_tree or ui is the literal 'false', which only the filter step can produce (both outputs are … || 'true'), or (b) the run was cancelled. The gate passes skipped only on filter == success && (ui_tree == 'false' || ui == 'false'), i.e. exactly case (a). Every other rollup word reds. Judged right, case by case:
    • filter fails or is cancelled on a PR: its outputs are empty or 'true', every ui if: reads != 'false' as true, ui-deps and test-ui RUN, the rollup is success/failure/cancelled, never skipped; a failed filter cannot manufacture a green skip. Right. On merge_group the paths-filter step is continue-on-error, so a failed diff there also runs every ui job. Right.
    • ui-deps fails or times out: test-ui's if: reads only cancelled() and the filter outputs, so the shards still run (cold build, by that job's own comment) and the rollup carries a real verdict. Right.
    • Run-level cancellation: shards skipped, filter success with ui='true' ⇒ the gate reds on "unexplained skip". That is one deliberate divergence from test-gate, which lets a skipped leg pass when filter itself reads cancelled (CI: Dogfood Regression Gate 把 cancelled 当失败 —— 每次连续推送都产生一条假红 #3668, pinned in check-shard-attestation's battery iv). Here the painted-red sha is a superseded push or an evicted queue entry, which no required check reads, and always() means the context is still published, so no pending state follows. Acceptable; noted in ④ as a should-fix comment, not a defect.
    • cancelled from a shard killed by its own timeout-minutes: red. Right (a timeout is not a pass).
    • Lifecycle words (abandoned): red via the *) arm. Right, and the maintainer's 2026-08-07 refusal to whitelist abandoned is honoured.
  • Can it leave the PR pending? No. if: always() with needs: [test-ui, filter] publishes the Test UI context on every run that starts, whatever the two needs conclude; the only way to publish nothing is a workflow that does not parse, which reds every ci.yml context alike. Confirmed on the head: run 40475173899 published Test UI (check-run 122093355274) 3 s after the last shard, log line rollup: 'success'; filter: 'success' (ui_tree='true', ui='true').
  • Can it pass a run where shards did not run for an unexplained reason? No. The matrix is a static literal of 16 under one job-level if:, so the rollup cannot mix skipped and succeeded legs; a success rollup is 16 concluded successes, and a skipped rollup passes only with the filter's explicit 'false'. The rollup blind spot test-gate closes with attestations (abandoned swallowing a sibling's failure, run 31114735713) is still open here in one direction: a lifecycle word reds rather than passes, so the failure mode is a false red, never a false green. Right for a first enrolment; the PR's acceptance note says why per-shard credentials are the ui lane's change, not this one's.
  • check:aggregator-roster floor gains test-ui-gate. Right: members test-ui + non-members filter equals needs: in both directions; no --leg tokens in the step, so the leg cross-check is vacuous by design (the gate reads the rollup, not attestations). check:shard-attestation discovers gates by a --verify invocation, so test-ui-gate is outside its roster and its download-artifact requirement, correctly.
  • No other accept-set change. The ui path filter already lists .github/workflows/**, so this PR itself (and every later workflow edit) runs the shards rather than skipping them; the new job adds about 10 s of serial wall after the last shard and no runner work. The Live required-set sweep is report-only (its header and verifyRequiredSet say so) and stays off the required path.
  • Check-runs on 853dded at the time of writing (2026-10-27 ~08:49Z). Required contexts concluded success: Test UI (the new one, 122093355274), Lint & Repo Gates, TypeScript Type Check, Build Core, Type Check UI, Build & E2E UI, Governed Surface Queue Guard. Also success: all 16 Test UI (k/16), Build UI Deps, Dogfood Regression Gate, Check Changeset, Check PR Size, Live required-set sweep, every Lint · and Type Check · lane, Test Core (2/8) and (3/8), the three claim/path guards. Still in progress: Test Core (1/8) and therefore the required Test Core aggregate, and the required Lint UI. No red anywhere. The landing waits for those two to conclude green (PD feat: Comprehensive CRM example demonstrating all ObjectStack protocol features #14, Tier H), as it does for the approval.

② Semver level

skip-changeset is correct: the diff touches a workflow, two repo-root gate scripts and two instruction surfaces; no packages/* path, no published export, no schema. Check Changeset is green on the head. The PR body carries Clause-②: no and Metadata-protocol: none, matching the ruling's execution line (6435318516) and the claim (6436627175). No breaking arm, no ADR-0087 disposition owed.

③ Boundary flags

  • Dev flag 1 — AGENTS.md and platform-readings.md edited without being named in the dispatch. Judged the minimum the gate requires, and true. Both are statesTheSet: true surfaces in INSTRUCTION_SURFACES; judgeInstructionSurfaces reds the registry PR itself when either fails to name every registry context (count and membership), so the list lines cannot be deferred to a follow-up. The edits are one list line each plus the hand-followed count words the same file's own ledger line says are unpinned (⛔ 但数量词未钉): AGENTS.md three lines in one paragraph (list, "those eight" ×2 → nine), platform-readings.md two lines (八个 → 九个, list). Nothing else in either file changed. Precedent ci(ui-merge): register Lint UI and Build & E2E UI in REQUIRED_CONTEXTS #25857 / ci(ui-merge): register Type Check UI in REQUIRED_CONTEXTS #25878 did the same two lines in the enrolment PR. The claim's "any doc the registry derives / only as far as the new row needs" covers it. The sentences are true on the head once the maintainer's ruleset half lands, which is the The ESLint required context carries ~54 check:* gates, so every one of their failures mis-routes its own diagnosis — and the rename needs a Settings change no agent seat can make #9325 two-step the files already describe; see ④ for the ordering.
  • Dev flag 2 — scripts/check-aggregator-roster.mjs not in the claim's file surface. Strictly, the gate would not red without the REQUIRED_AGGREGATORS row (discovery is by declaration), so this is one row beyond "only as far as the new row needs"; but the file's own header says the floor is "kept in step with REQUIRED_CONTEXTS", and an aggregate carrying a required context without a floor row is exactly the deletable-declaration hole the floor exists to close. One row plus two self-test controls. Accepted as the file's stated contract, not scope creep.
  • Dev flag 3 — PR not subscribed for activity. Process note; nothing for this record.
  • open_questions: [] on both os-dev-reports. Nothing to escalate.
  • Ruling order honoured: the ui step's reading (6436579765, 0/50 on the newest 50 queue builds that ran Test UI, every red in 24 h fixed on main) is on the card and precedes the PR; the devx claim and report cite it; authorized in the registry row cites it. Staged as ruled.
  • PR author is objectstack-fleet[bot]; assignee os-steve mirrors the card. Branch claude/project-thread-nsgh5p is the branch the newest Claim: (6436627175) names; the The card this PR closes must claim this branch check is green.
  • Tier: .github/workflows/ci.yml and AGENTS.md are Tier H rows of GOVERNED_SURFACES; the PR is draft awaiting a GOVERNED_APPROVERS review, with hotlong and os-zhuang requested. This record is the Tier S half for the .claude/** path; it lifts nothing on its own for the Tier H paths and the landing stays the maintainer's or an authorized approval plus the owning seat.

④ Design judgment

  • .github/workflows/ci.yml (test-ui-gate). Holds against the code it cites. name: Test UI is the bare literal check:required-contexts pins, and the shards keep their suffixed Test UI (k/16) names so assertion 9's whole-name comparison passes (the new self-test case proves the collision reds). if: always() and needs including filter match the test-gate shape the ruling names (ci.yml:1697 on this head), the roster declaration is exact, timeout-minutes: 10 and contents: read are the minimal envelope for a one-step shell job, and the bracket form needs['test-ui'].result is the correct expression for a hyphenated id. Every sentence in the job comment is true on the head except one cosmetic spelling: the prose says needs.test-ui.result while the step reads needs['test-ui'].result (same value; should-fix for a later pass, not this PR). Should-fix, non-blocking: the comment could say in one clause that a skip under a cancelled filter reds here where test-gate passes it (CI: Dogfood Regression Gate 把 cancelled 当失败 —— 每次连续推送都产生一条假红 #3668), so the next reader does not file that difference as a defect. Acceptance against the ruling: it is the aggregate letter A asked for, in the shape it named, after the ui reading it ordered first.
  • AGENTS.md (merge-queue rule, §7). The edited paragraph is rules text, carries no new incident narrative or issue citation (the PR number convention and pm-skill-id-lint are respected), names the nine literals verbatim, and keeps "treat those nine names as contract". True on the head modulo the ruleset half. Order of names is not a gate input (see ①).
  • .claude/skills/pm-dispatch/references/platform-readings.md (required-set ledger). Same one-line change, count word followed by hand as its own next bullet instructs. True on the head modulo the ruleset half.
  • Landing order with the ruleset flip. The queue-safe order is merge first, flip second, in one sitting (the The ESLint required context carries ~54 check:* gates, so every one of their failures mis-routes its own diagnosis — and the rename needs a Settings change no agent seat can make #9325 two-step the registry's own comment prescribes, and the Lint UI / Build & E2E UI precedent). If the maintainer adds Test UI to the main ruleset BEFORE this PR merges, every PR head and every merge-queue entry built from a ci.yml without test-ui-gate never publishes a Test UI check-run and sits permanently pending — the chore(ci): cut PR wall-clock ~9.5min → ~5-6min — dedupe dogfood, shard it, cache lint's build #3622 deadlock, and it would stall the whole queue, this PR's own entry included (a merge-group build uses the group's merged workflow, but entries ahead of it do not). Between the merge and the flip the context is merely advisory, the Live required-set sweep reports direction A, and nothing stalls; that window is the harmless one. The ci(test-shards): Test Core's two slowest shards set every core PR's wall clock at ~28 min (5.6 min dependency build + ~20 min tests) while the other six finish in 7–17 — re-derive the cli slicing and shard balance on post-merge readings #25870 overlap the claim names is in a different ci.yml section with no shared hunk; whichever lands second merges origin/main first per the claim.
  • scripts/check-required-contexts.mjs and scripts/check-aggregator-roster.mjs (cited, read as one change with the rule). Registry row, two mustName entries, the INSTRUCTION_SURFACES history comment (7→8, 8→9) and three new self-test controls are consistent with the live gate behaviour described in ①; the dev reports both scripts and both --self-test batteries exit 0 on the head, and the Lint · CI, release & engine gates lane that carries them is green on the head. Should-fix, non-blocking, pre-existing: the roster header now says "Five of this repo's required contexts are aggregator jobs", but Dogfood Regression Gate is a tombstoned context since skills(ci): two-speed CI — fast set on PR and merge-queue runs, full battery hourly on main and before a release, main-red stops the lane, four required contexts plus the guard, timing gates report-only, test budgets not deletions #22998 (full battery, not required), so the honest count of required aggregators is four plus one full-battery aggregate; the previous "Four" carried the same imprecision. A one-word follow-up in the devx lane, not a reason to hold the enrolment.

Implemented-by: claude/project-thread-nsgh5p
Reviewed-by: session_01Q4MDXRbEJCNdPAP4SiXwp9

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · devx seat 2 · 2026-10-27T08:50Z

Seat domain:devx#2 (#20163) · session_01Q4MDXRbEJCNdPAP4SiXwp9 · reviewed head 853ddedb · card #26460 (claim 6436627175, branch claude/project-thread-nsgh5p), ruling 6435318516 letter A, staged. The ui lane's reading 6436579765 (0/50 flakes) came first, as the ruling ordered. Thread-read: none.

Landing (Tier H: .github/workflows/ci.yml, AGENTS.md): it stays a draft with auto-merge off until a GOVERNED_APPROVERS approval. ⛔ Order matters: merge first, then the maintainer adds Test UI to the main ruleset in the same sitting. Adding it to the ruleset before this merges would leave every PR and queue entry whose ci.yml lacks the job pending forever (the #3622 deadlock). The card closes on Fixes.

@os-zhuang
os-zhuang marked this pull request as ready for review October 27, 2026 09:48
@os-zhuang
os-zhuang added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 833e4a8 Oct 27, 2026
67 checks passed
@os-zhuang
os-zhuang deleted the claude/project-thread-nsgh5p branch October 27, 2026 10:04
os-tesla pushed a commit that referenced this pull request Oct 27, 2026
Conflicts in three skill files main also edited (#26536, #26569): kept main's
root-run console:build wording and its ninth required context (Test UI), kept
this branch's removal of the objectui-only lines and the retired SHA-stamp
drift bullet (no .objectui-sha pin or build-console.sh exists any more).

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibvE77Ed7MKdzPxJTQQ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd documentation Improvements or additions to documentation size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants