Skip to content

docs(spec,cli): seed replace deletes nothing, and the AppPlugin loads skip a landed row a person deleted - #31135

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-nd6b2f
Nov 7, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-nd6b2f

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by 田騏 · project thread

Fixes #31099

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么: 只改文字。seed.zod.ts 里 replace 不再写成"先删整表再插入",改为"不删任何东西,只插入,给调用方已清空的缓存表用";insert 不再写"重复时失败",改为"每次重放都再插一遍";mode 的说明补上已落地行的记录规则和 { reseed: true } 这扇门。os diff 对 replace 数据集的提示同步改正。
  • 为什么改: 旧文字和加载器实际行为相反:作者或 AI 读到"replace 会清表",会以为重放能刷新数据,实际只会把行再插一遍。上一张卡已经改了技能包和文档,spec 的 .describe() 和 CLI 提示还停在旧说法。
  • 风险与回滚: 无行为变化,只动注释、.describe()、一条 CLI 提示字符串和它的测试,以及自动生成的 4 个参考页。回滚即 revert。
  • 先看: packages/spec/src/data/seed.zod.ts(SeedMode 注释、mode 的 JSDoc 新段落和 .describe());packages/cli/src/commands/diff.ts 第 81 行。
  • 两分钟验证: pnpm --filter @objectstack/cli exec vitest run --project unit test/diff-upgrade-plan.test.ts,预期 7 个测试全过,replace 的提示为 "a replay deletes nothing and inserts these again"。
  • 需要你做的: 无,席位落地。

What changes

Text only; no behaviour change. Every sentence was worded from the loader and AppPlugin code on main (5f00374), not from the old text.

  • packages/spec/src/data/seed.zod.ts
    • SeedMode comments: insert no longer says "fail on duplicate" — it inserts every record with no match, so each replay inserts them again, and a row the database refuses is that row's error (SeedLoaderService.writeRecord / decideWriteAction insert unconditionally; a refused row is pushed to the load's errors while the rest land). replace no longer says "Delete ALL records in object then insert": it inserts every record, no match, and deletes nothing (its writeRecord arm is a bare insert; nothing in the loader deletes).
    • mode docstring: a new paragraph on the landed-keys rule. The loads AppPlugin runs for an organization (single-tenant boot seed, per-organization replay through seed-replayer, dev hot reload), where the composition registers sys_seed_landed_key, record the key of every keyed row an ignore or upsert dataset landed and do not insert again a recorded row that is now gone; a never-recorded key still lands; a seed publish and a package install or upgrade keep no record; seed-replayer(organizationId, { reseed: true }) inserts every missing row.
    • mode .describe(): the same facts, compressed; no tracker number. The ignore-is-default text (ruling 6631016988 on [Decision] A restart puts seeded records back: a customer's edit to a seeded row is overwritten by the next boot #30081) is unchanged.
    • The history string at L116–117 is left as is (historical, card: optional).
  • packages/cli/src/commands/diff.ts seedModeNote: replace now reads "a replay deletes nothing and inserts these again, so rows already in the table stay". packages/cli/test/diff-upgrade-plan.test.ts pins the new string (it pinned the old one).
  • content/docs/references/**: 4 pages regenerated by gen:schema && gen:docs from the .describe().
  • Changeset: @objectstack/spec patch + @objectstack/cli patch.

Wording is in step with the already-reviewed content/docs/data-modeling/seed-data.mdx ("A Deleted Seed Row Stays Deleted") and skills/objectstack-data/references/seeds.md.

Tests

  • pnpm --filter @objectstack/cli exec vitest run --project unit on 89162ff: Test Files 396 passed, Tests 5576 passed. The integration layer is declared to CI (the diff touches no integration file or spawn entry).
  • After merging origin/main (head 68060aa, closure rebuilt): diff-upgrade-plan and the incoming connect-agent-both-halves-wire.pin (unit layer): 2 files, 9 tests passed. The incoming authoring-rule-command-parity is an integration-layer file, declared to CI.
  • eslint on the three touched source/test files: exit 0.

Acceptance notes

  • Independent Fable review of the whole diff: PASS with should-fix (name the sys_seed_landed_key condition and "keyed row" in the docstring; sharpen the insert comment). Both applied in 89162ff; delta review PASS. Verdict comment to follow on this PR.
  • Left alone, noted: seedModeNote says nothing for insert, which also inserts every record again on each replay. Outside this card's item 2 (the replace line only).
  • docs/qa/platform-checklist/areas/platform-core.json quotes the old replace text inside a historical "declared ≠ implemented" clause; out of the card's file surface, left as is.

Verification

Derived gates (dispatch-gates --commands) — 108 run on 89162ff, all exit 0
  • node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.txt :: exit 0 — "108 derived famil(ies) accounted for — 108 run, 0 NOT-MEASURED".
  • First pass: 12 families exited 3 (PREREQUISITE NOT MET: packages/spec/dist stale after the docstring commit, a shallow clone for check-plugin-teardown-shape --self-test, and unbuilt workspace dists). After pnpm --filter @objectstack/spec build and git fetch --unshallow origin main, all 12 reran with exit 0.
  • pnpm --filter @objectstack/spec run check:generated :: exit 0 (also post-merge: "All 14 generated artifacts are up to date").
  • pnpm check:doc-authoring :: exit 0 (no tracker number in .describe()).
Merge of origin/main

Merged once before opening (68060aa). The incoming commits touch no seed, spec or diff.ts file. Re-checked: the CLI closure rebuilt, check:generated exit 0, the CLI test files above, and dispatch-gates --ran still 108/108.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic.
  • 2. Every name I added uses the casing for its kind (no names added).
  • 3. No formatter ran; eslint passes on the touched files (pnpm lint repo-wide is CI's).
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: its generated artifacts are regenerated and committed.
  • 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 repo's own Chinese reader section).
  • The Before Submitting list in CONTRIBUTING.md is done.

🤖 Generated with Claude Code

https://claude.ai/code/session_017ihL2dzed5sJnRTmwXHWV7

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#4 · marchtian · session_017ihL2dzed5sJnRTmwXHWV7

Fable review — full diff, then delta

An isolated reviewer subagent (model fable, read-only) was given the diff and card #31099, not the author's conclusions, and checked every sentence against seed-loader.ts, app-plugin.ts, protocol-publish-batch.ts, domains/packages.ts, marketplace-install-local-plugin.ts and sys-seed-landed-key.object.ts.

Round 1 (diff 5f00374492..ca38274b): PASS with should-fix.

  1. should-fix — the new mode docstring paragraph named the loads that keep the record but not the condition that the composition registers sys_seed_landed_key (openLandedKeyLedger answers none without it), and said "every row" where only a keyed row is recorded. Applied in 89162ff.
  2. nit — the insert comment "(a row the database refuses fails)" is true but did not say the rest still land. Applied in 89162ff: "is that row's error".
  3. nit — the marketplace's fallback seed-replayer keeps no record; the sentence is scoped to "the loads AppPlugin runs", so not false. No change.

Checked true: replace and insert are bare inserts and nothing in the loader deletes; the record is kept only for upsert/ignore; a withdrawn row is not re-inserted under honour; a never-recorded key still lands; reseed inserts every missing row; the three honouring call sites and the three no-record constructions; the CLI note and its test pin match; the changeset carries both line-initial declarations; no tracker number in .describe(); the regenerated references match the .describe().

Round 2 (delta ca38274b..89162ffb): PASS. One cosmetic nit (a short line in the reflowed paragraph), left as is.

Head after the merge of origin/main: 68060aa (the merge brings no seed, spec or diff.ts change).

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:data tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 7, 2026
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/cli, @objectstack/spec, touching 4 documentable anchor(s).

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

  • content/docs/data-modeling/seed-data.mdx (via SeedSchema (symbol, a top-level const))
  • content/docs/kernel/services-checklist.mdx (via os diff (command, read off packages/cli/src/commands/diff.ts))
  • content/docs/protocol/backward-compatibility.mdx (via os diff (command, read off packages/cli/src/commands/diff.ts))
  • content/docs/protocol/objectql/schema.mdx (via os diff (command, read off packages/cli/src/commands/diff.ts))
What this run could not see
  • the SDK route bridge reached 63 of 226 client-bound route-ledger rows — the other 163 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 163: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 59 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 104 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • 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 — 180 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 98583cd692c6a67891617529d2f7aec4963859b8 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from a295035a7cc5972c3ef13ccfb7f1ddfb61914496 — the merge of head 68060aa22bf15b378c1b8adb2fca27cb844054ef into base 98583cd692c6a67891617529d2f7aec4963859b8, 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 a295035a7cc5972c3ef13ccfb7f1ddfb61914496 && git checkout a295035a7cc5972c3ef13ccfb7f1ddfb61914496
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 98583cd692c6a67891617529d2f7aec4963859b8 68060aa22bf15b378c1b8adb2fca27cb844054ef && git checkout -B drift-repro 98583cd692c6a67891617529d2f7aec4963859b8 && git merge --no-ff 68060aa22bf15b378c1b8adb2fca27cb844054ef

node scripts/docs-audit/affected-docs.mjs --json 98583cd692c6a67891617529d2f7aec4963859b8

⚠️ 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 98583cd692c6a67891617529d2f7aec4963859b8 → 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:spec#4 · marchtian · session_017ihL2eHDXrsKgGAUHq956U

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 68060aa22bf15b378c1b8adb2fca27cb844054ef
Local-runs: none
Scope: packages/spec/src/data/seed.zod.ts + packages/metadata-protocol/src/seed-loader.ts, packages/runtime/src/app-plugin.ts, packages/metadata-protocol/src/protocol-publish-batch.ts, packages/runtime/src/domains/packages.ts, packages/cloud-connection/src/marketplace-install-local-plugin.ts, packages/cli/src/commands/package/install.ts, packages/metadata-core/src/package-upgrade-plan.ts, packages/platform-objects/src/plugin.ts, packages/cli/src/commands/diff.ts, packages/cli/test/diff-upgrade-plan.test.ts, the 4 regenerated reference pages, the changeset

① Derived judgments

Accept set and public surface: unchanged. SeedMode keeps its five members in order; mode: SeedMode.default('ignore') is untouched; no field of SeedSchema is added, removed, renamed or re-typed. Only enum member comments, the mode JSDoc, the mode .describe(), one CLI note string and its test pin move. Ruling 6631016988 on #30081 (ignore is the default, create-only) is kept in the .describe() lead and the docstring.

Every changed sentence checked against main:

  • insert comment — TRUE: SeedLoaderService.writeRecord case 'insert' calls engine.insert without consulting existing; decideWriteAction answers insert for insert, replace and default; a refused row is counted and pushed to the load's errors on both the sequential and batched paths while the rest land.
  • replace comment — TRUE: the 'replace' arm is a bare engine.insert ("caller should have cleared the table"); nothing in the loader deletes.
  • Docstring landed-keys paragraph — TRUE: seedLoaderOptionsFor(ctx, 'honour') on the single-tenant inline seed, the seed-replayer replay (honour unless reseed === true) and the metadata:reloaded hot reload; openLandedKeyLedger keeps no ledger without landedKeys, on a dry run, without an organization, or when sys_seed_landed_key is not registered; recorded keys read only for upsert/ignore; only keyed rows; a never-recorded key still lands.
  • "A seed publish and a package install or upgrade keep no record" — TRUE: the publish batch and applyPublishedSeeds construct the loader without landedKeys; os package install → marketplace install-local seeds through runInlineSeed without landedKeys (also its reseed and heal).
  • Re-seed door seed-replayer(organizationId, { reseed: true }) — TRUE: honour off ⇒ isWithdrawnRow false; keys still recorded.
  • .describe() — TRUE, a compression of the docstring; no #NNNN.
  • CLI note "a replay deletes nothing and inserts these again, so rows already in the table stay" — TRUE and reachable (seedModeOverwritesMatchedRows is upsert || update only); the test pin carries the identical string.
  • The 4 regenerated reference pages equal the new .describe() word for word (MDX brace escaping aside).

No finding in ①.

② Semver level

Consistent: @objectstack/spec patch (comments, JSDoc, .describe()), @objectstack/cli patch (one message and its pin). Clause-②: no and Metadata-protocol: none are right and sit line-initial in the changeset and the PR body. No finding.

③ Boundary flags

Author objectstack-fleet[bot]; open_questions: []. Two dev notes, both should-fix, outside this card, non-blocking — the seat files a card for each:

  1. os diff prints no note for mode insert, whose loader arm is identical to replace's, so one behaviour reads two ways in the same output (CLI lane).
  2. docs/qa/platform-checklist/areas/platform-core.json still quotes the old replace text as a declared ≠ implemented posture and cites seed.zod.ts#SeedMode for it; after this PR the source no longer holds that text (QA checklist).
    Read, not flagged: the marketplace's own fallback buildSeedReplayer builds its loader without landedKeys; the new text scopes the rule to the loads AppPlugin runs, so it is not contradicted. No card.

④ Design judgment

packages/spec/src/data/seed.zod.ts holds against the code it cites and the card's acceptance (item 1): the insert/replace comments describe the writeRecord arms as they are; the docstring and .describe() gain the landed-keys exception (three AppPlugin loads, the sys_seed_landed_key condition, ignore/upsert only, keyed rows only, never-recorded keys still land, publish and package install keep no record) and the re-seed door, each clause traceable to code. The history string stays historical, as the card allows. The author-side Fable round's two should-fixes are in the head. No finding.

Implemented-by: claude/project-thread-nd6b2f
Reviewed-by: session_017ihL2eHDXrsKgGAUHq956U

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#4 · marchtian · session_017ihL2eHDXrsKgGAUHq956U

维护者速读

  • 改了什么: 只改文字。seed.zod.ts 的 replace 不再写成"先删整表再插入",改为"不删任何东西,只插入";insert 不再写"重复时失败",改为"每次重放都再插一遍";mode 的说明补上已落地行记录规则和 { reseed: true } 这扇门。os diff 对 replace 数据集的提示同步改正。
  • 为什么改: 旧文字和加载器实际行为相反,作者或 AI 会以为 replace 重放能刷新数据,实际只会再插一遍。
  • 风险与回滚: 无行为变化:注释、.describe()、一条 CLI 提示和它的测试、4 个自动生成的参考页。回滚即 revert。
  • 先看: packages/spec/src/data/seed.zod.ts;packages/cli/src/commands/diff.ts 第 81 行。
  • 两分钟验证: pnpm --filter @objectstack/cli exec vitest run --project unit test/diff-upgrade-plan.test.ts,7 个测试全过。
  • 需要你做的: 无。Tier S,席位落地。

席位意见:ACCEPT。逐句对照了加载器与 AppPlugin 代码,接受集与公开面不变;两条范围外问题已另立卡(#31139 os diff 对 insert 无提示,#31140 QA 清单旧引文)。

席位核对

  1. Shape: 8 files, +37 / −10: seed.zod.ts comments/JSDoc/.describe(), diff.ts one string + its test pin, 4 regenerated content/docs/references/** pages, one changeset (@objectstack/spec patch, @objectstack/cli patch). Clause-②: no, Metadata-protocol: none, line-initial in the body and the changeset.
  2. Premise measured: on main 5f00374 the old replace / insert text and the seedModeNote line were still there (claim 6707348860); the fix matches the loader arms (writeRecord, decideWriteAction) and PR fix(metadata-protocol,runtime): a seed row a person deleted is no longer inserted again by the next seed replay (per-organization record of landed seed keys) #31083's landed-keys ledger.
  3. Gates (check-runs on 68060aa22b): 65 runs, 57 success, 8 skipped, 0 failure. check-expected-skips OK (8 skips, every one in main's roster). check-governed-merges --pr 31135: NOT governed, 47 changed lines ⇒ Tier S. Dev's derived gates 108/108 exit 0.
  4. Accepted deviations: none. The history string at ~L116 is left historical, as the card allows.
  5. Out of scope → where: os diff gives insert no note → cli(diff): os diff says nothing for a seed dataset in mode insert, which inserts every record again on each replay, though it now explains the identical replace arm #31139 (finding); platform-core.json stale declared ≠ implemented clause → qa(checklist): platform-core.json still holds replace as declared ≠ implemented and cites the "Delete ALL records" text that #31099 removes from seed.zod.ts #31140 (finding). Cross-seat: the packages/cli line was folded into this card by triage 6704154593; the CLI seat was told. Skills-docs: not owed (Metadata-protocol: none).
  6. Landing clause: author-side full Fable review PASS (6707877121, delta PASS); seat contract review at CONTRACT_REVIEW_TIER PASS on this head (record on this PR). Tier S ⇒ pr_ready + automerge_enable through the relay.

@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

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

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

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

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

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

    @objectstack/service-settings:test:  FAIL  src/setup-nav-hub-parity.test.ts > Setup sidebar and settings hub list the same pages under the same names (#27854) > ar: each sidebar entry reads as its hub
      ↳ 失败原因: @objectstack/service-settings:test: AssertionError: expected [ { ns: 'access_policy', …(2) } ] to deeply equal []
    
  • Test Core (2/8) — 失败步骤: Run this shard's tests

    @objectstack/platform-objects:test:  FAIL  src/pages/sys-user-ai-assistants-tab.test.ts > sys_user_detail — the AI Assistants tab > carries the label in every locale the sibling tabs spell
      ↳ 失败原因: @objectstack/platform-objects:test: AssertionError: Details: expected [ 'ar', 'en', 'es-ES', 'ja-JP', …(2) ] to deeply equal [ 'en', 'es-ES', 'ja-JP', …(2) ]
    
  • Test Core (1/8) — 失败步骤: Run this shard's tests

    @objectstack/cli:test:  FAIL   unit  test/platform-page-i18n-parity.test.ts > shipped platform record pages -- i18n ownership (#14817) > holds every inline locale map on those pages complete in every 
      ↳ 失败原因: @objectstack/cli:test: AssertionError: expected [ { …(2) } ] 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 队列共有 17 个失败构建(不含本次)。

分诊清单:

  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 protocol:data size/s tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spec + cli: seed mode text still says replace deletes every row and omits the landed-keys rule (seed.zod.ts, os diff note)

2 participants