Skip to content

build(scenarios): a minimal unpublished build, and a narrow ./score entry that reads no objectql or plugin-sharing - #30938

Merged
objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/project-thread-cin84b
Nov 6, 2026
Merged

objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/project-thread-cin84b

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

domain:devx#1 · os-elon-musk · session_016WV4cwgUKpQgCE3UWsA74d

Fixes #30915
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:私有包 @objectstack/scenarios 加了一个不发布的最小 tsup 构建(dist/ 下 ESM + CJS + .d.ts),四个导出子路径全部指向构建产物;./score 改为窄入口,只含图形打分与答题/写操作评分,不再牵出 objectql 和 plugin-sharing;原先的完整入口改名为 ./score/full。
  • 为什么改:按裁决 D 打分器搬进了这个包,但包里只有 .ts 源码,cloud 打包后用纯 Node 加载会报 ERR_MODULE_NOT_FOUND;内联打包又等于把源码复制进 cloud(2.87 MB → 3.95 MB),违反裁决。
  • 风险与回滚:包仍是 private、不发布;仓内的测试和 run-scenarios 仍直接读 src/,行为零改动。唯一外部消费者是 cloud#3604(尚未落地)。回滚即 revert。
  • 先看:① packages/qa/scenarios/package.json 的 exports(./score 与 ./score/full 的分工);② src/score/narrow.ts(只做 re-export,没有搬文件);③ turbo.json 一行:本包 test 改为先跑本包 build。
  • 两分钟验证:pnpm --filter @objectstack/scenarios build && pnpm --filter @objectstack/scenarios exec vitest run test/build,预期 5 个测试全绿。
  • 需要你做的:无,席位落地。

What changes

@objectstack/scenarios (packages/qa/scenarios) exported .ts sources only. A consumer that links the framework tree and bundles its own entry with tsup leaves the dependency external, so plain Node then loads src/score/index.ts, whose .js specifiers only a TypeScript resolver follows: ERR_MODULE_NOT_FOUND, ESM and CJS alike (measured by the cloud#3604 dev; reproduced here, see the ablation below).

  1. A minimal build, still private and unpublished. tsup.config.ts builds one entry per export subpath to dist/ (ESM .js, CJS .cjs, .d.ts / .d.cts, splitting: false, dependencies external), using tsconfig.build.json (rootDir: src). build ends with check-dts-emitted.mjs (8/8 declarations present). Every exports subpath (., ./score, ./score/full, ./runner) now has import / require conditions on the built files, wired the way packages/lint is (a type: module multi-entry tsup package; no private package under packages/ had a tsup build to copy). The suites and run-scenarios (tsx src/runner/cli.ts) import src/ relatively and are untouched; no in-repo package imports @objectstack/scenarios by specifier.
  2. A narrow ./score entry. src/score/narrow.ts re-exports scenario-graph, scenario-naming, scenario-operation-grade, scenario-run-grade and scenario-score (so scoreGraphShape, artifactToEvalGraph, gradeRun, gradePersonaRun, gradeOperation, …). Its import graph reads @objectstack/core and @objectstack/spec only. The previous whole entry, src/score/index.ts, is unchanged code and is now ./score/full: it adds the capability-tag checks (scenario-tags.ts, which read @objectstack/objectql and @objectstack/plugin-sharing) and the card-level scoreCardArtifact / gradeCardOperation / gradeCardAnswer. No score module moved, so Scenario grading: an overstep refused on read, an agent that pre-validates, and a plain decline all grade as failures; cards with persona scope lack the row-scope tag #30883 (editing score behaviour in src/score/**) does not collide.
  3. Wiring. turbo.json: @objectstack/scenarios#test depends on build (was ^build), so the package's own dist/ exists before its suite runs; turbo run test --filter=@objectstack/scenarios --dry=json lists @objectstack/scenarios#build as the test's dependency. Any turbo run build / pnpm build (the root script) now builds the package, which is how a pinned framework tree is built. docker/Dockerfile in this repo installs published packages and builds no workspace package, so it needs nothing.

READMEs (packages/qa/scenarios/README.md, docs/qa/scenarios/README.md) and the index.ts header name the two entries.

Tests

  • test/build/built-consumer.test.ts: a throwaway package that depends on @objectstack/scenarios, imports scoreGraphShape statically and import()s @objectstack/scenarios/score, is built with the repo's tsup (--format esm,cjs). The test asserts the bundle keeps the specifier external and does not carry the scorer, then loads dist/index.js and dist/index.cjs with plain node. A preloaded module.registerHooks resolve recorder lists every URL the child resolves: the scorer loads from packages/qa/scenarios/dist/, nothing from src/, nothing matching objectql or plugin-sharing, and (control) @objectstack/core is seen.
  • test/build/narrow-score-graph.test.ts: walks the source import graph from src/score/narrow.ts (type-only imports included) and asserts no @objectstack/objectql / @objectstack/plugin-sharing specifier, and the exact @objectstack/* set it reads. Control: the same walker from src/score/index.ts finds both.

Acceptance notes

  • Surface move inside a private package. ./score no longer exports scoreCardArtifact, the scenario-tags exports, gradeCardOperation or gradeCardAnswer; they are under ./score/full. The card's acceptance requires ./score's graph to exclude objectql and plugin-sharing, and the two card-level graders live in index.ts beside scoreCardArtifact, so keeping them in ./score would have meant moving code out of index.ts, which the claim's serial constraint with Scenario grading: an overstep refused on read, an agent that pre-validates, and a plain decline all grade as failures; cards with persona scope lack the row-scope tag #30883 rules out. Its only out-of-repo consumer, cloud#3604, reads scoreGraphShape and the run grader, both in ./score.
  • Changeset. skip-changeset: the package is private (the dispatch order's fast lane). Measured: the Check Changeset job (.github/workflows/pr-automation.yml) exempts on the label alone and has no private-package branch, so nothing there asks a private package with a build for a changeset. Earlier PRs on this package did carry '@objectstack/scenarios': patch changesets (.changeset/30289-…, 30291-…, 30292-…); .changeset/config.json has privatePackages: { version: true, tag: false }, so a changeset would only bump the private version.
  • Twin declarations. tsup emits a .d.ts and a .d.cts per entry, the simple packages/lint pattern, not packages/core's single-declaration pass. The runner exports classes, but no consumer reaches this package through both resolution modes today.

Verification

All at e748dfb0a0, the final head (origin/main 26c965cb8f merged, which brought #30846's loader change).

  • pnpm --filter @objectstack/scenarios build: exit 0, check-dts-emitted: @objectstack/scenarios - 8/8 declared declaration file(s) present.
  • pnpm --filter @objectstack/scenarios test: Test Files 20 passed (20), Tests 256 passed (256). typecheck: exit 0.
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (exit 0) derived 65 commands; all 65 ran, every one exit 0. pnpm check:dual-build-cjs-loads first exited 3 (PREREQUISITE NOT MET, no dist for 61 packages) and exited 0 after a whole-tree turbo run build (119/119 tasks). dispatch-gates.mjs --ran: exit 0, "65 derived famil(ies) accounted for — 65 run, 0 NOT-MEASURED".
Ablation 1: the pre-fix export (`./score` import condition back on src/score/index.ts)

node scripts/ablation-replace.mjs --file packages/qa/scenarios/package.json --anchor '"default": "./dist/score.js"' --replacement '"default": "./src/score/index.ts"' -- … vitest run test/build/built-consumer.test.ts: mutation landed (anchor 1 → 0, blob 144f294e → 0d0da83a). Both plain-Node legs red with the card's error, Error [ERR_MODULE_NOT_FOUND]: Cannot find module '…/packages/qa/scenarios/src/schema.js' imported from …/src/score/index.ts. Restored: blob == HEAD, git diff HEAD empty.

Ablation 2: the narrow entry re-exports scenario-tags

ablation-replace.mjs --file packages/qa/scenarios/src/score/narrow.ts --anchor "export * from './scenario-graph.js';" --replacement "export { artifactToEvalGraph } from './scenario-graph.js';\nexport * from './scenario-tags.js';" then pnpm build: ablation-dist-preflight.mjs @objectstack/scenarios "@objectstack/plugin-sharing" → marker live in dist. vitest run test/build: 3 failed | 2 passed (the source-graph leg and both plain-Node legs red; the full-entry control and the external-bundle check stay green). Restored: blob == HEAD, git diff HEAD empty; rebuilt, grep -c 'plugin-sharing\|objectql' on dist/score.js, dist/score.cjs, dist/score.d.ts = 0 each, and test/build 5/5 green.

65 gates, exit codes at e748dfb
node scripts/check-adr-links.mjs :: exit 0
node scripts/check-adr-links.mjs --self-test :: exit 0
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-adoption.mjs :: exit 0
node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-console-intercept-disarm.mjs :: exit 0
node scripts/check-console-intercept-disarm.mjs --self-test :: exit 0
node scripts/check-dts-emitted.mjs --self-test :: exit 0
node scripts/check-issue-citations.mjs :: exit 0
node scripts/check-osv-exemptions.mjs :: exit 0
node scripts/check-osv-exemptions.mjs --self-test :: exit 0
node scripts/check-plugin-teardown-shape.mjs :: exit 0
node scripts/check-plugin-teardown-shape.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/docs-audit/check-affected-docs.mjs :: exit 0
node scripts/docs-audit/check-drift-comment.mjs :: exit 0
node scripts/osv-base-relative.mjs --self-test :: exit 0
pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0
pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0
pnpm --filter @objectstack/spec run check:llms-txt :: exit 0
pnpm check:changeset-fixed :: exit 0
pnpm check:ci-filter-parity :: exit 0
pnpm check:closed-ceremony-text :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:doc-authoring :: 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:engine-double-contract :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:issue-citations :: exit 0
pnpm check:keyed-text-bounds :: exit 0
pnpm check:lean-entry-closure :: exit 0
pnpm check:logger-receiver-detach :: exit 0
pnpm check:manifest-repository-directory :: exit 0
pnpm check:merge-driver :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:objectql-double-limit :: exit 0
pnpm check:org-identifier :: exit 0
pnpm check:override-consistency :: exit 0
pnpm check:page-declaration-shape :: exit 0
pnpm check:platform-object-tenancy-census :: exit 0
pnpm check:pnpm-flag-spellings :: exit 0
pnpm check:published-files :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:registry-log-declared :: exit 0
pnpm check:rest-log-spy-declared :: exit 0
pnpm check:slot-lookup :: exit 0
pnpm check:sourcemap-no-sources-content :: exit 0
pnpm check:system-context-census :: exit 0
pnpm check:test-source-alias :: exit 0
pnpm check:tier-file-adoption :: exit 0
pnpm check:turbo-task-graph :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:undeclared-dep-imports :: exit 0
pnpm check:vendor-export-contract-resolve :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
pnpm check:workspace-manifest-cycles :: exit 0

🤖 Generated with Claude Code

https://claude.ai/code/session_016WV4cwgUKpQgCE3UWsA74d


Generated by Claude Code

…re entry

@objectstack/scenarios exported .ts sources only, so a consumer that links
the framework tree and bundles its own entry with tsup (which leaves the
dependency external) could not load ./score under plain Node:
ERR_MODULE_NOT_FOUND on the .js specifiers, ESM and CJS alike.

- tsup builds dist/ (ESM .js, CJS .cjs, .d.ts/.d.cts) per export subpath;
  the package stays private and unpublished, and the suites and
  run-scenarios keep reading src/.
- ./score is now the narrow entry (src/score/narrow.ts, re-exports only):
  graph-shape scorer, naming, operation and run graders. Its import graph
  reads @objectstack/core and @objectstack/spec, never objectql or
  plugin-sharing. ./score/full is the previous whole entry
  (src/score/index.ts, unchanged code).
- turbo runs the package's own build before its test, which now includes a
  tsup-built consumer loaded by plain Node with a resolve recorder.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cwgUKpQgCE3UWsA74d
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Nov 6, 2026
@github-actions github-actions Bot added size/m dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation tests labels Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/scenarios, touching 1 documentable anchor(s). ⚠️ 5 changed file(s) yielded no anchor (packages/qa/scenarios/README.md, packages/qa/scenarios/package.json, packages/qa/scenarios/src/score/index.ts, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/plugins/index.mdx (via tsconfig.build.json (literal, a string literal on a changed line))
  • content/docs/protocol/kernel/index.mdx (via tsconfig.build.json (literal, a string literal on a changed line))
  • content/docs/protocol/kernel/plugin-spec.mdx (via tsconfig.build.json (literal, a string literal on a changed line))
What this run could not see
  • 5 changed file(s) yielded no anchor (packages/qa/scenarios/README.md, packages/qa/scenarios/package.json, packages/qa/scenarios/src/score/index.ts, …) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 6ddf827236902c0ccaee56b65431a4c8a9c7ac09 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 5de6f21f1de3d31ee9f7c0fa0d5bdacb9ba2173f — the merge of head 702570a3381412eb2eaacccabb37d50fb1b50dae into base 6ddf827236902c0ccaee56b65431a4c8a9c7ac09, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 5de6f21f1de3d31ee9f7c0fa0d5bdacb9ba2173f && git checkout 5de6f21f1de3d31ee9f7c0fa0d5bdacb9ba2173f
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 6ddf827236902c0ccaee56b65431a4c8a9c7ac09 702570a3381412eb2eaacccabb37d50fb1b50dae && git checkout -B drift-repro 6ddf827236902c0ccaee56b65431a4c8a9c7ac09 && git merge --no-ff 702570a3381412eb2eaacccabb37d50fb1b50dae

node scripts/docs-audit/affected-docs.mjs --json 6ddf827236902c0ccaee56b65431a4c8a9c7ac09

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 6ddf827236902c0ccaee56b65431a4c8a9c7ac09 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw

席位核对 · ACCEPT · #30915 · 2026-11-06T12:50Z

Head-sha: e748dfb0a07e44016c54018d9f9591f9337428f2

  • Shape: 10 files (+335/−15) in packages/qa/scenarios/**, two README lines and one turbo.json line. Private package, skip-changeset, Fixes #30915.
  • Measured by the seat in the diff:
    • A tsup build writes ESM, CJS and .d.ts to dist/, with one entry per export subpath and splitting: false, so each entry's externals are exactly its own graph. Every exports subpath now points at dist/. The package stays private. tsup comes from the root devDependencies, as in every other package.
    • ./score is the narrow entry src/score/narrow.ts: re-exports only, with no module moved, so Scenario grading: an overstep refused on read, an agent that pre-validates, and a plain decline all grade as failures; cards with persona scope lack the row-scope tag #30883's score edits do not collide. ./score/full is the old src/score/index.ts, with the capability-tag checks and scoreCardArtifact, gradeCardOperation and gradeCardAnswer. Inside the repo, nothing outside the package imports @objectstack/scenarios. The named consumer, cloud#3604, needs only scoreGraphShape and the run graders, and both are in ./score.
    • @objectstack/scenarios#test now depends on its own build, which still runs ^build through the build task. The suites and run-scenarios keep reading src/.
    • Acceptance is pinned by test/build/built-consumer.test.ts (a tsup-built consumer import()s ./score under plain Node) and narrow-score-graph.test.ts (./score reaches neither objectql nor plugin-sharing). The dev ablated both and saw them go red.
  • Gates: the dev reports 256 package tests and typecheck green, and 65 derived gates of 65 at exit 0. check-governed-merges --pr 30938: NOT governed, 350 lines. CI is still running at this head, so auto-merge lands it on green.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 6, 2026 12:51
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 6, 2026 12:51
…OS_SKIP_DTS build passes it

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cwgUKpQgCE3UWsA74d
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw

席位核对 · ACCEPT (delta) · #30915 · 2026-11-06T13:20Z

Head-sha: e4cfda26111f581b05eb51bb3e99b2859d6040ee

  • Delta from e748dfb0: one test file (+5/−1). built-consumer.test.ts now requires only dist/score.js and dist/score.cjs. CI builds with OS_SKIP_DTS, so no .d.ts is emitted there, and that made Test Core (4/8) red on the previous head (job 127901551822). The .d.ts emission stays checked by check-dts-emitted in the package's build script whenever OS_SKIP_DTS is unset.
  • Measured by the dev: reproduced with OS_SKIP_DTS=1, then green after the fix (test/build 5/5). A plain build gives check-dts-emitted 8/8 and typecheck exit 0. The gates that read test files also exit 0. Auto-merge stays armed.

…t to stdout at exit

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cwgUKpQgCE3UWsA74d
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw

席位核对 · ACCEPT (delta) · #30915 · 2026-11-06T13:31Z

Head-sha: fb3e0224222b4f284998301a4aa4ef5c00b6e643

  • Delta from e4cfda26: the same test file only. The child-process recorder used to write its whole resolve record (about 139 KB) to stdout from an exit handler. That write does not finish draining a 64 KB pipe before the process exits, so a slow reader under CI load got a truncated JSON (job 127915847898, position 146175). The recorder now writeFileSyncs the record to a temp file named by SCENARIOS_RESOLVE_RECORD, and the parent reads that file. stdout carries only the one-line verdict.
  • Measured by the dev: the mechanism is confirmed with a slow reader (the record is lost), and the fix holds over 5 runs of test/build (5/5 each). Typecheck exits 0 and the test-file gates exit 0. No buffer or timeout was raised. Auto-merge stays armed.

…-cin84b

# Conflicts:
#	packages/qa/scenarios/package.json
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:devx#1 · os-elon-musk · session_016WV4cymvo9YoyLwKCXXBNw

席位核对 · ACCEPT (delta) · #30915 · 2026-11-06T14:06Z

Head-sha: 702570a3381412eb2eaacccabb37d50fb1b50dae

@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

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

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

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

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

  • Test Core (2/8) — 失败步骤: Run this shard's tests

    @objectstack/platform-objects:test:  FAIL  src/apps/translations/app-nav-translation-parity.test.ts > every nav id an app presents is translated in every locale > account — zh-Hant
      ↳ 失败原因: @objectstack/platform-objects:test: AssertionError: untranslated nav ids in apps.account.navigation: expected [ 'grp_account_ai_assistant' ] 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 队列共有 18 个失败构建(不含本次)。

分诊清单:

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

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

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

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

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

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

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

  • Test Core (2/8) — 失败步骤: Run this shard's tests

    @objectstack/platform-objects:test:  FAIL  src/apps/translations/app-nav-translation-parity.test.ts > every nav id an app presents is translated in every locale > account — zh-Hant
      ↳ 失败原因: @objectstack/platform-objects:test: AssertionError: untranslated nav ids in apps.account.navigation: expected [ 'grp_account_ai_assistant' ] 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 已在队列失败 1 次(不含本次)。 内容未变而反复失败 ⇒ 高度怀疑 flaky 测试或与同组 PR 的语义冲突,重排不解决。
  • 过去 24h 队列共有 20 个失败构建(不含本次)。

分诊清单:

  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 6910797 Nov 6, 2026
65 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-cin84b branch November 6, 2026 15:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

2 participants