Skip to content

docs(spec): tenancy-posture prose says which side of the open/commercial split gates activation - #29454

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-n75m44
Nov 2, 2026
Merged

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

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steve · project thread
Fixes #29318

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:只改 tenancy-posture.ts 的两段注释(文件头「开源代码与激活授权」一节、postureStampsOrganization 的说明),外加一个 spec patch changeset;无代码、无 schema、无生成物变化。
  • 为什么改:原文「open code does not mean free activation」没说是哪一侧,读起来像开源安装也要许可证;按 ADR-0132,开源安装挂上 @objectstack/organizations 即可启用 group/isolated,只有商业侧子类才加许可证门。
  • 风险与回滚:纯注释,零运行时风险;回滚即 revert 本 PR。
  • 先看:packages/spec/src/security/tenancy-posture.ts 第 23–48 行(文件头一节)与 postureStampsOrganization 的说明块。
  • 两分钟验证:git diff origin/main -- packages/spec/src/security/tenancy-posture.ts,预期只见注释行变化,且每句激活相关的话都写明是开源侧还是商业侧。
  • 需要你做的:无,席位落地。

What changes

  • Header section (was "Open code, entitled activation", now "Open code; activation is entitled only on a commercial host"). It keeps the implementation-vs-entitlement separation and now says which side each sentence describes:
    • On an open install, activation is gate-free: the open runtime carries no licence check (ADR-0132 D2) and entitles both walled postures by construction (ADR-0132 D4), so mounting it is enough. Measured on origin/main: packages/plugins/organizations/src/organizations-plugin.ts declares supportedPostures = ['group', 'isolated'] with the "NO LICENCE GATE HERE" note beside it.
    • On a commercial host, activation is entitled: the package of the same name subclasses the open one and answers its licence gate in its own constructor, and the host's manifest resolves the name to it (ADR-0132 D2, D3). "Open code does not mean free activation" is kept, scoped to that side, matching the ADR-0105 D12 amendment's "on the commercial side".
  • Cloud ADR-0016 铁律 paragraph. The guarantee no longer rests on "not giving the posture away". It now says the iron rule is satisfied by the wall itself on both sides: a multi-org shape never runs unwalled (ADR-0093 D5). Whether switching the posture on is free is the entitlement question, not the iron rule's. The Chinese quotation (强制免费、治理收费) is unchanged.
  • postureStampsOrganization docblock. "Open code does not mean free activation" is now scoped the same way: mounting the runtime is enough on an open install, and only a commercial host gates activation.
  • Changeset .changeset/29318-tenancy-posture-activation-prose.md: @objectstack/spec patch (the docblocks ship in the published .d.ts).

No forced test edits.

Tests

Comment-only diff. pnpm --filter @objectstack/spec build && pnpm --filter @objectstack/spec check:generated: all 14 generated artifacts up to date (the file has no .describe(), so nothing generated moves). Spec typecheck and test were run locally (readings under Verification).

Acceptance notes

  • The OrgScopingEntitlement docblock further down already scopes its "packaging decision" sentence to the commercial runtime and names ADR-0132 D4 for the open package, so it is left as it is.

Verification

All readings at head e82aa69a (the only commit), in objectstack-ai/objectstack.

Spec build, generated artifacts, typecheck, test
  • pnpm --filter @objectstack/spec build && pnpm --filter @objectstack/spec check:generated under the verify lock: VERDICT command-exit 0, "All 14 generated artifacts are up to date".
  • pnpm --filter @objectstack/spec typecheck: exit 0.
  • pnpm --filter @objectstack/spec test: VERDICT command-exit 0, Test Files 791 passed (791), Tests 23469 passed, 1 todo.
Derived gates (dispatch-gates --commands, 73 families)
  • All 73 derived commands exit 0. Four first answered exit 3 (prerequisite not met, nothing measured): the teardown-shape self-test on the shallow clone, and check:doc-formula-expressions, check:dual-build-cjs-loads, check:lean-entry-closure on unbuilt packages. After fetching the self-test's control commit and turbo run build --filter=./packages/** (VERDICT command-exit 0), all four exit 0.
  • node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran FILE: "73 derived, 73 run, 0 NOT-MEASURED, 0 UNRUN", exit 0.
  • check-changeset-no-major.mjs --base origin/main --event FILE on this body, offline: exit 0, level axis "clause-② no and metadata-protocol none ... a non-protocol change at patch".
  • Local-only check:dev-prereqs: its self-test passes; the scan exits 1 because 35 ui/ workspace packages are not built in this container (an unmet local precondition, not a finding on this diff). NOT MEASURED for that half.

Dogfood: n/a, no ! in the title and no (narrowing) arm.


Generated by Claude Code

…tion is gated on

The header's "Open code, entitled activation" section and the
postureStampsOrganization docblock said "open code does not mean free
activation" with no side named. On an open install the organizations
runtime carries no licence gate and entitles both walled postures
(ADR-0132 D1, D2, D4); only a commercial host's subclass gates activation
(ADR-0132 D2, D3). The cloud ADR-0016 paragraph no longer rests the
guarantee on withholding the posture: it rests on refusing to run a
multi-org shape unwalled (ADR-0093 D5). Comment-only.

Claude-Session: https://claude.ai/code/session_01ADHkmPErSzAW8P6oQg3W1k
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the size/s label Nov 2, 2026
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/spec/src/security/tenancy-posture.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/src/security/tenancy-posture.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 — 168 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 aca58cdb62bdb8ed350f0b45885728374ca1f6ad → packageMentionDocs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling labels Nov 2, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS

Head-sha: e82aa69a · read 2026-11-02T15:43Z

维护者速读

席位意见:可落地,等契约复审。

席位核对 — ACCEPT · domain:spec#1 · head e82aa69a

  1. Shape: draft, base main, Fixes #29318, Clause-②: no / Metadata-protocol: none in the body and the changeset (spec patch). 2 files (the .ts and the changeset), +36/-14. Not governed.
  2. Surface: inside claim 6580442396: header section and postureStampsOrganization docblock only. There is no .describe(); check:generated 14/14 up to date.
  3. Readings (dev, on e82aa69a): 73/73 derived gates, DERIVED zero; spec typecheck 0; spec 791/791 files; offline level gate accepted (patch). No forced test edits, no open questions.
  4. Landing: a docblock on the published-schema face, so one CONTRACT_REVIEW_TIER review by the seat (claim line follows). After a PASS and green CI, the seat readies and queues.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS

Contract-review-claim: session_01ADHkmPi25XXKx92Xmg4viS · head e82aa69 · 2026-11-02T15:44Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: e82aa69ae79e185d3a6aabc93d00c4930824bda7
Local-runs: none
Scope: packages/spec/src/security/tenancy-posture.ts + docs/adr/0132-multi-organization-runtime-is-open-core.md (D1–D4), docs/adr/0105-group-tenancy-posture-and-first-class-org-scope.md (D12 and its 2026-07-27 and 2026-09-06 amendments), docs/adr/0093-tenancy-mode-and-membership-lifecycle.md (D5), packages/plugins/organizations/src/organizations-plugin.ts, packages/plugins/organizations/src/membership-policy-gate.ts, packages/plugins/organizations/package.json, .changeset/29318-tenancy-posture-activation-prose.md

Inputs: card #29318 (body, triage 6576560344, claim 6580442396, dev report 6581334071), PR #29454 body and file list, git diff origin/main...e82aa69a (merge-base a6441636), the head's check-runs. The seat's ACCEPT (6581394170) was read as a record of what it claims, not as evidence; every claim below was re-derived from the tree and the cited ADRs.

① Derived judgments

  • Accept-set: unchanged. Both hunks in tenancy-posture.ts lie inside /** … */ blocks (the file header, lines 23–48, and the postureStampsOrganization docblock). The file contains zero .describe() calls on main and at the head; TenancyPostureSchema, OrgScopingEntitlementSchema, PlatformGlobalObjectsSchema, every exported function and OrgScopingEntitlement are byte-identical. packages/spec/api-surface/security.json records existence only (five entries from this file, none moved) and content/docs/references/security/misc.mdx carries no sentence from either docblock. Comment-only holds.
  • Done-when, sentence by sentence. Header: "On an OPEN install, activation is gate-free … mounting it is enough" names the open side; "On a COMMERCIAL host, activation is entitled … There, and only there, open code does not mean free activation" names the commercial side. Docblock: "On an open install mounting it is enough (ADR-0132 D4); only on a commercial host is that activation licence-gated (ADR-0132 D2)". No sentence in the file now says, or can be read to say, that an open install is licence-gated. The sibling OrgScopingEntitlement docblock (unchanged) already scopes "the commercial runtime owns it" and "on a commercial host that is the licence-gated one" to that side and names D4 for the open package, so it does not reintroduce the defect.
  • ADR-0016 paragraph vs. the paragraph above it. The old text grounded the iron rule in "not by giving the posture away", which, read beside "That runtime is open code too", asserted a withheld posture that the open package no longer withholds. The new text grounds it in the wall ("REFUSING to run one unwalled, ADR-0093 D5") on both sides and hands the "is switching it on free" question to the entitlement bullets. That is exactly the distinction ADR-0105 D12's 2026-07-27 amendment draws ("a security property (never run a multi-org shape unwalled), not a packaging one (give the posture away)") and ADR-0132's Context section repeats ("a wall is enforcement"). The two paragraphs no longer contradict each other. The Chinese quotation 强制免费、治理收费 is unchanged.
  • Factual claims, each against its source.
    • "ENABLING a multi-organization posture … requires the @objectstack/organizations runtime to be mounted (ADR-0105 D12, ADR-0093 D5)" — D12: both walled postures probe the org-scoping runtime, without it the posture resolves single + degraded and serve refuses; D5: the refusal. True.
    • "ships from this repository under Apache-2.0 (ADR-0132 D1)" — D1 verbatim; packages/plugins/organizations/package.json "license": "Apache-2.0". True.
    • "The open runtime carries no licence check of any kind (ADR-0132 D2)" — D2's own words; the plugin constructor (organizations-plugin.ts ≈L243–258) has no gate call, option, hook or callback and says so. True.
    • "entitles both walled postures by construction (ADR-0132 D4)" — D4; supportedPostures = ['group', 'isolated'] at ≈L236. True.
    • "The commercial package of the same name subclasses the open one and answers its licence gate in its own constructor, and the host's manifest resolves the name to that package (ADR-0132 D2, D3); it may also narrow which walled postures it entitles" — D2 (subclassing, gate in constructor), D3 (workspace:* resolution from the host manifest), D4 closing sentence and the ADR-0105 amendment ("the commercial runtime may still narrow what it entitles"). The closed code is not readable from this repo; the prose cites the ADRs and not the code, which is the right footing. True as far as the open record reaches.
    • "There, and only there, open code does not mean free activation" — the ADR-0105 2026-09-06 amendment's "still an entitlement on the commercial side". True.
    • "the platform delivers by REFUSING to run one unwalled (ADR-0093 D5) … You never silently get an unenforced organization boundary" — D5 refuses by default; its OS_ALLOW_DEGRADED_TENANCY=1 escape is loud (terminal warning plus /auth/config), so "silently" is the right qualifier. Pre-existing wording, mirrored in ADR-0105 D12 itself. True.
  • Overstatement check. One phrase is loose rather than false: "activation is gate-free … mounting it is enough" (header bullet). On an open install a walled posture still meets the membership-policy boot refusal (assertWalledMembershipPolicyDeclared, membership-policy-gate.ts, run from the open plugin's init), which the plugin itself calls a "gate". It is a safety check, not an entitlement, and the bullet's next clause defines "gate" as the licence check, so the sentence is not a false statement of fact. Should-fix (nice-to-have): "licence-gate-free" / "mounting it is all the entitlement there is" would close the reading. Not blocking.
  • Noted, not filed (outside the card's file surface): packages/qa/dogfood/test/authz-conformance.matrix.ts:202 (a test note) still ends "not by giving the posture away". It already states D2 and D4 in the same sentence, so it is not contradictory, only stale in emphasis.

② Semver level

@objectstack/spec patch is right. Comment-only on a published package: no key, accepted value, default, meaning, export or type moves, so Metadata-protocol: none and Clause-②: no (no arm) are the only correct declarations, and none takes patch. Both lines appear on the PR body and in the changeset body, identically. The postureStampsOrganization JSDoc ships in the published .d.ts, so a changeset (not skip-changeset) is the right carrier.

③ Boundary flags

  • Not a governed surface: paths are packages/spec/src/** and .changeset/**; the Governed Surface Queue Guard check-run is success. The review is owed by the published-schema face (hits: packages/spec/src/security/tenancy-posture.ts), which is why this record exists.
  • Head repo = base repo (objectstack-ai/objectstack), branch claude/project-thread-n75m44; not a fork PR.
  • Open/commercial line: the prose draws it where ADR-0132 draws it and no further; nothing here restates or decides the commercial half (ADR-0132 Provenance), and no new citation of a cloud record is introduced.
  • Check-runs on e82aa69a as polled at 2026-11-02T15:46Z: 18 success (among them Governed Surface Queue Guard, Check Changeset, Spec property liveness, Lint · ESLint, Type Check · source gates, PR-body guards, Check PR Size), 12 skipped, 16 in_progress (Test Core 1–8, Build Core, Build UI Deps, Live E2E UI, Type Check · consumer gates / workspace / debt ledger, Lint · docs & code guards), 0 failure. Green is not yet established; landing waits for the required set.

④ Design judgment

Judged against ADR-0132 D1–D4, the ADR-0105 D12 amendments and the open plugin on main. The header now carries the implementation/entitlement split as two side-scoped bullets instead of one unqualified sentence, and it keeps the three load-bearing facts a reader of the spec needs: the wall is open, mounting the open runtime is the whole activation story on an open install, and the commercial subclass is where entitlement lives. The ADR-0016 paragraph is rebuilt on the same ground the ADRs stand on (refusal, not withholding), so the file no longer argues with itself. The docblock on postureStampsOrganization repeats the scoping in one sentence rather than restating the header. Nothing is promised that the code does not enforce, apart from the "gate-free" looseness above, which is a should-fix and not a must-fix. No must-fix found.

Implemented-by: claude/project-thread-n75m44
Reviewed-by: session_01ADHkmPi25XXKx92Xmg4viS

VERDICT: PASS

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 2, 2026 15:50
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 2, 2026 15:50
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS

Flake judgement · re-run once · 2026-11-02T17:33Z

Test UI (9/16) failed on head e82aa69a (run 41473960530, attempt 1). One test failed out of 409 files: StudioDesignSurface.refusedLeafUnsaved-29113.test.tsx, which asserts reloadAsks() is true right after a refused report save and got false.

This PR changes two comment blocks in packages/spec/src/security/tenancy-posture.ts and a changeset. Nothing the app-shell test reads moves. The same assertion failed the same way on PR #29437, which touches no ui/ file either. That makes it a timing flake in the test, not this PR. The seat re-runs the failed jobs once, and files the flake for the ui lane.

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

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

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

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

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

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

    @objectstack/spec:test:      ✓ inverts the card's measured control: the three bogus keys now FAIL parse instead of adding zero warnings  502ms
      ↳ 失败原因: (这条 FAIL 之后 12 行内没有可识别的原因行 —— 点进 job 看)
    @objectstack/spec:test:  FAIL   local  scripts/dropped-refinements.test.ts > the committed ledger > names at least one site per entry, and its header totals match its body
      ↳ 失败原因: @objectstack/spec:test: AssertionError: expected 993 to be 998 // Object.is equality
    @objectstack/spec:test:repo:  FAIL   repo  scripts/strictness-ledger-doc.test.ts > the ledger and the generated counts agree > is checked in current — every shard on disk equals a fresh render, and no
      ↳ 失败原因: @objectstack/spec:test:repo: AssertionError: expected Map{ …(14) } to deeply equal Map{ …(14) }
    @objectstack/spec:test:repo:  FAIL   repo  scripts/strictness-ledger-doc.test.ts > the ledger and the generated counts agree > the read-time totals equal the sums of the shards' own rows
      ↳ 失败原因: @objectstack/spec:test:repo: AssertionError: expected 'untriaged: 1297 object site(s) across…' to be 'untriaged: 1296 object site(s) across…' // Object.is equality
    

↳ 失败原因 是判读的关键:超时(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 队列共有 20 个失败构建(不含本次)。

分诊清单:

  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 2, 2026

Copy link
Copy Markdown
Contributor

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

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

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

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

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

    @objectstack/spec:test:      ✓ inverts the card's measured control: the three bogus keys now FAIL parse instead of adding zero warnings  348ms
      ↳ 失败原因: (这条 FAIL 之后 12 行内没有可识别的原因行 —— 点进 job 看)
    @objectstack/spec:test:  FAIL   local  scripts/dropped-refinements.test.ts > the committed ledger > names at least one site per entry, and its header totals match its body
      ↳ 失败原因: @objectstack/spec:test: AssertionError: expected 993 to be 998 // Object.is equality
    

↳ 失败原因 是判读的关键:超时(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 队列共有 24 个失败构建(不含本次)。

分诊清单:

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s tooling

Projects

None yet

1 participant