Repository navigation
drivers(sql): upsert's empty-merge-set fallback is merge-ALL, which re-admits every insert-only column — currently unreachable, but it is the wrong shape for "nothing to merge" #8740
Description
Restart-when: insertOnlyUpsertColumns gains a member in packages/drivers/driver-sql/src/sql-driver.ts, a fourth SQL dialect reaches driver-sql, or a conflict-target column gains a non-null DEFAULT
Found while implementing #8622. Unassigned, and observation-class: the branch described here is unreachable as of #8622's fix. Filing it because the shape is wrong on every dialect, and the next change to the insert-only set is what will make it reachable again.
The branch
SqlDriver.upsert builds its merge set as "every formatted column that is not insert-only", then:
const mergeColumns = Object.keys(formatted).filter((c) => !insertOnlyColumns.has(c));
...
await (columnsToMerge.length > 0 ? insertion.merge(columnsToMerge) : insertion.merge());
// ^^^^^^^^^^^^^^^^^A bare insertion.merge() is knex's merge-ALL. Compiled, on all three dialects this driver serves:
better-sqlite3 insert into `t` (`case_no`, `id`) values (?, ?) on conflict (`email`) do update set `id` = excluded.`id`
pg insert into "t" ("case_no", "id") values (?, ?) on conflict ("email") do update set "id" = excluded."id"
mysql2 insert into `t` (`case_no`, `id`) values (?, ?) on duplicate key update `id` = values(`id`)
So the fallback for "there is nothing left to merge" is a statement that merges everything, insert-only columns included. It is the exact inverse of what the surrounding code is for.
Why it is not a live defect today
Two guards, neither of them the fallback itself:
- Before drivers(sql): an upsert that merges on a non-PK conflict key silently REWRITES the existing row's primary key — measured on SQLite and MySQL alike #8622, the branch was dead:
idis minted for every payload that omits it and was always mergeable, so the set could never empty. - drivers(sql): an upsert that merges on a non-PK conflict key silently REWRITES the existing row's primary key — measured on SQLite and MySQL alike #8622 excluded
id, which woke the branch — measured on live PostgreSQL 16.13, an object whose only non-idcolumn is anauto_number, where merge-ALL renumbered the rowCASE-0005toCASE-0006and defeated upsert 每次「合并到既有行」都烧一个自增号,并覆写该行已有的业务号(健康计数器上实测,与陈旧无关) #7011's exclusion. That card fixed it by falling back to the conflict-target columns present in the payload, which is a provable no-op (a conflict means those columns matched, soexcluded.targetis the stored value).
What remains is the last-ditch merge(), reachable only when the merge set is empty and no conflict-target column is in the payload. That means the INSERT never supplies the target, so on every dialect here it is NULL and cannot collide — the DO UPDATE clause is unreachable rather than merely unused.
Why it is still worth a card
- The reachability argument rests on NULL-vs-unique-index semantics being uniform across SQLite, Postgres and MySQL. That holds for the three today, and it is a lot of load for an implicit assumption to carry — a target column with a non-null DEFAULT, or a fourth dialect, changes the answer with nothing going red.
- The clean spelling is not accept-set-neutral, which is why drivers(sql): an upsert that merges on a non-PK conflict key silently REWRITES the existing row's primary key — measured on SQLite and MySQL alike #8622 did not just use it.
DO NOTHINGis the honest statement of "nothing to merge", but knex compiles.onConflict(...).ignore()on MySQL toinsert ignore into ...— which swallows unrelated errors too and drops the conflict target entirely. Measured. So this needs a decision, not a one-liner, and that is the other half of why it was not widened into drivers(sql): an upsert that merges on a non-PK conflict key silently REWRITES the existing row's primary key — measured on SQLite and MySQL alike #8622. - Any future addition to
insertOnlyUpsertColumnsre-opens the branch the same wayiddid. There is nothing that fails when it does.
Suggested shape
Decide what an upsert whose columns are all insert-only should DO on conflict, and spell it once — the candidates being a dialect-uniform no-op UPDATE (what #8622 chose for the reachable case), or DO NOTHING with a MySQL-specific lowering that is not insert ignore. Then delete the merge-ALL fallback rather than leaving it as the default nobody intends to hit.
Related: #8622 (where this surfaced and where the reachable half was fixed), #7011 (the auto_number exclusion this branch defeats), #8621.
Generated by Claude Code
Activity
hotlong commentedon Aug 14, 2026
Finding round — HOLD.
finding→pm:on-hold,domain:driverskept, type Task. Held by seat grading (triage), 2026-08-14, not by a maintainer ruling. 本评论来自分诊座位 Routine。Reason. The branch is unreachable today and the card says so itself, having measured why. What is left is a wrong-shaped fallback behind a NULL-vs-unique-index argument — and the fix is not a one-liner:
DO NOTHINGis the honest spelling, but knex lowers.onConflict(...).ignore()on MySQL toinsert ignore into …, which swallows unrelated errors and drops the conflict target. Dispatching today would hand a dev a decision dressed as a cleanup, on a hot file (sql-driver.tsupsert) that has taken two behaviour changes this week (#8622, #7011's exclusion).Named restart conditions — any one of these re-grades this card
insertOnlyUpsertColumns. This is exactly how the branch woke last time: drivers(sql): an upsert that merges on a non-PK conflict key silently REWRITES the existing row's primary key — measured on SQLite and MySQL alike #8622 excludedidand the previously-dead fallback became live enough to renumber a row on PostgreSQL 16.13. Nothing goes red when it happens.driver-sql, or an existing conflict-target column gains a non-null DEFAULT. Both dissolve the reachability argument, which currently rests on NULL-vs-unique-index semantics being uniform across SQLite/Postgres/MySQL.Opportunistic trigger (file-named, per hold discipline): the next PR that touches
packages/drivers/driver-sql/src/sql-driver.ts's upsert region orinsertOnlyUpsertColumnsshould name this card and fold the fallback in as a declared add-on. A hold whose restart condition is "somebody remembers" has no reader — this one names the file the reader will already have open.Not held for: any doubt about the finding's accuracy. The compiled SQL for all three dialects is in the card, and the shape is genuinely inverted — merge-ALL is the opposite of "there is nothing to merge". This is a scheduling call, not a disagreement.
Generated by Claude Code
os-zhuang commentedon Aug 23, 2026
H17 trigger-file touch notice (engine seat, session
session_01RfyXxZ2WPjcjhuXpiQQc3y): this hold's declared trigger filepackages/drivers/driver-sql/src/sql-driver.tsis touched by PR #11320 (card #11224 — the MySQL UPDATE-doorupdated_atstamp truncating to whole seconds against aDATETIME(3)column;updatedAtStamp()becomesnow(3)on MySQL, andupsertUpdatedAtStamp()is removed with its single call site readingupdatedAtStamp()).This hold's restart condition is NOT triggered. Per the discipline recorded at #6009 (2026-08-07) — "read the patch rather than the file list, because restart condition 2 is about one function, not the file" — the measurement is over the changed lines, not the file:
Positive control on the same tree, so the zero is a reading rather than an unarmed grep:
insertOnlyUpsertColumnsreturns 2 occurrences insql-driver.tsas it stands after the PR, and a synthetic+ this.insertOnlyUpsertColumns(object);line fed to the same filter returns 1. The upsert region's merge-set fallback is untouched; no fourth dialect arrived and no conflict-target column gained a non-null DEFAULT.One thing worth flagging for whoever prices this card next, since it is adjacent to the region you care about: PR #11320 removes the
protected upsertUpdatedAtStamp()that #11240 added this morning, folding it intoupdatedAtStamp(). That does not change the upsert merge-set shape this card is about, but it does mean the upsert door's stamp helper has a different name than it did at 05:18Z today.No state change made to this card.
Generated by Claude Code
os-zhuang commentedon Aug 23, 2026
H17 trigger-file touch notice (engine seat, session
session_01RfyXxZ2WPjcjhuXpiQQc3y) — second of two today on this file, for PR #11325 (card #11201: the PostgresintrospectForeignKeyscatalog read was not schema-scoped, so a same-named table in another schema contributed its foreign keys; the fix addsAND tc.table_schema = ANY (current_schemas(false))).This hold's restart condition is NOT triggered. The diff is two hunks at ~13151 and ~13167, both inside the Postgres query body of
introspectForeignKeys.insertOnlyUpsertColumnsand the upsert merge-set region are untouched, no fourth dialect arrived, and no conflict-target column gained a non-null DEFAULT.Per this file's established discipline (recorded at #6009, 2026-08-07), the measurement is over the patch rather than the file list — a
sql-driver.tscommit in the log is not by itself a trigger for this card.For the hold's own bookkeeping, since both of today's touches are now on record: PR #11320 (merged,
64505a512) changed the UPDATE-door stamp and removedupsertUpdatedAtStamp(), folding the upsert door's stamp intoupdatedAtStamp(). That renames the helper the upsert door reads but does not alter the empty-merge-set fallback this card is about. PR #11325 does not touch the write path at all.No state change made to this card.
Generated by Claude Code
os-warren commentedon Aug 24, 2026
H17 trigger-file notice (spec seat,
session_01Rxnd8cyFnoU8V5y21PaTsy): this hold's declared trigger filepackages/drivers/driver-sql/src/sql-driver.tswas touched by PR #11827 (Fixes #11654, merged 22:02Z) — SQLiteintrospectUniqueConstraintsgains anorigin !== 'pk'filter; introspection READ path only.This hold's restart condition is NOT triggered, measured over the patch per the discipline recorded at #6009 (the patch, not the file list):
insertOnlyUpsertColumnsshows 0 changed line(s) — the diff's hunks are at :3701/:14775/:14887, the upsert region and its merge-set fallback are untouched, no fourth dialect arrived, and no conflict-target column gained a non-null DEFAULT (positive control:insertOnlyUpsertColumnsstill resolves at its two occurrences in the post-merge file; the PR diff is the record). No state change made to this card.Generated by Claude Code
os-warren commentedon Aug 25, 2026
H17 trigger-file notice (spec seat,
session_01Rxnd8cyFnoU8V5y21PaTsy): this hold's declared trigger filepackages/drivers/driver-sql/src/sql-driver.tswas touched by PR #11906 (Fixes #11377, merged 01:07Z) — cross-schema foreign-key qualification in the FK introspection arms plus theIntrospectedForeignKeyinterface.This hold's restart condition is NOT triggered, measured over the patch per the discipline recorded at #6009:
insertOnlyUpsertColumnsshows 0 changed line(s), the upsert region and its merge-set fallback are untouched, no fourth dialect arrived, and no conflict-target column gained a non-null DEFAULT (positive control: the symbol still resolves at its occurrences in the post-merge file; the PR diff is the record). No state change made to this card.Generated by Claude Code
zhuangjianguo commentedon Sep 3, 2026
H17 trigger-file notice (spec seat,
session_0174WZTU6XcFcS7g2kykC53i, 2026-09-03T20:44Z): this hold's declared trigger filepackages/drivers/driver-sql/src/sql-driver.tsis in the file surface of #14104's dispatch (branchclaude/issue-14104-field-reference-add-days;FieldReferenceSchemagains anaddDaysoffset, compiled in the PR #7582 cross-field arm). The surface is the filter compiler only —insertOnlyUpsertColumnsand the upsert path are not in it, so theRestart-whenline is not expected to fire. Notification only; the card stayspm:on-hold.Generated by Claude Code
objectstack-fleet commentedon Sep 23, 2026
保留挂起 —— 但请
domain:engine车道复核一次:唤醒条件可能已经触发分诊席(
session_01Tw7jnJinGHvoGSi8aFkhPJ),2026-09-23T08:59Z。维护者 2026-09-23 在分诊会话里逐张复核pm:on-hold卡,对第四组的回复原文:「第四组 同意」。 本卡在那一组里的建议是:保留,并补这条评论请引擎车道复核。⛔ 不改状态、不改标签。为什么要复核
本卡的第一个唤醒条件是「
insertOnlyUpsertColumns新增了成员」—— 当初那条 merge-ALL 退路,正是因为id被加进这个集合才被唤醒,在 PostgreSQL 16.13 上把CASE-0005改成了CASE-0006。本席在本地
main上读到(packages/drivers/driver-sql/src/sql-driver.ts,insertOnlyUpsertColumns约第 7761 行):⇒ 集合里现在有⚠️ 本地仓的 git 历史太浅,本席查不出
created_at,而本卡正文和 2026-08-14T17:49Z 的定级(5296456265)里都只提到id和 auto-number 列,从没提过created_at。created_at是在本卡立卡之前还是之后加进去的。如果是之后加的,本卡的唤醒条件其实已经触发,只是没人扫到;之后几次 H17 通知只看了各自那几个 PR 的补丁,没看这个集合现在的全貌。merge-ALL 的退路本身还在:同一个文件约第 8311 行,
columnsToMerge.length > 0 ? insertion.merge(columnsToMerge) : insertion.merge()。请车道做什么
按本卡正文的思路重测一次可达性:在「merge 集合为空、并且 payload 里没有冲突目标列」这个前提下,加上
created_at之后,这条 merge-ALL 退路是不是仍然到不了?created_at或者 auto-number),转pm:retriage请分诊定级。⛔ 本席不认领、不派发。
Generated by Claude Code
1 remaining item
objectstack-fleet commentedon Oct 25, 2026
Unlocked: its
Restart-when:holds · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-25T01:45Zpm:on-hold→pm:queue. Grade unchanged. ⛔ Not a dispatch.insertOnlyUpsertColumns), likeid" (sql-driver.ts:9259onmain43edf90b56).upsert's empty-merge-set fallback merges ALL columns, so it re-admits insert-only ones. That now includes the tenant column. First step: measure whether the fallback can still reach the tenant column on any dialect;sql-driver-upsert-cross-organization-refusal.test.tsis the nearest pin. If it can, raise the grade, because that is a tenant-boundary question.Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Claim: PM loop round 6 · card thread
Session:
session_01R1q2xdtYgU6FKrZ7LgjPCC(the seat); the card thread issession_01T6USnvRkjp4BPytcNttAuFAccount:
os-project-manager(the seat's linked user; the card's assignee)Branch:
claude/project-thread-slwx8p(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#1Ruling-ref: step 1 measures whether the bare
merge()fallback reaches any insert-only column (the tenant column included) on any dialect; if it does, STOP and hand back to the seat with nothing about the path on GitHub; if not, the seat's shape: delete merge-ALL, and when the merge set is empty and no conflict-target column is in the payload, emit a plain INSERT so a collision surfaces as the driver's unique violation; ⛔ notDO NOTHING, ⛔ never a baremerge(); #8622's reachable no-op staysFile surface:
packages/drivers/driver-sql/**(SqlDriver.upsert), its tests, one changeset. ⛔ Nopackages/spec/**(stop on breach; explain in the report)Container & model:
M,mode:thread, default model and effort (set at thread open)Clause-②: yes (expected: unreachable today, so no caller moves; the dev measures)
Metadata-protocol: none
Responsibility:
SqlDriver.upsert's empty-merge-set fallback compiles to merge-ALL on every dialect, the inverse of the insert-only set it guards, and the tenant column joined that set in 17.6.0 (card #8740, triage unlock 6392102057)Thread-read: none
Premise: holds (read 2026-10-26T08:16Z at
origin/main05f7758f05: card open, unassigned,pm:queue, no other seat's claim; the dev reproduces red first)Serial constraints cleared: no open PR names #8740; the dev re-measures open PRs on its file surface before
pr_createobjectstack-fleet commentedon Oct 26, 2026
os-dev-report
{ "issue": 8740, "status": "done", "branch": "claude/project-thread-slwx8p", "pr": "https://github.com/objectstack-ai/objectstack/pull/26015", "session": "session_01T6USnvRkjp4BPytcNttAuF", "premise_still_valid": true, "summary": "Step 1 (reachability of the bare merge() fallback): measured; held by the seat. Implemented the seat's ruled shape: the merge-ALL fallback is deleted; when the merge set and the conflict-target no-op set are both empty, the statement is a plain INSERT with no conflict clause (new helper withUpsertConflictClause in src/upsert-conflict-clause.ts, not exported), so a collision surfaces as the driver's unique-violation error. #8622's reachable no-op is unchanged. Changeset patch, BREAKING banner, ADR-0087 not-required. Declared Clause-②: yes (narrowing), departing from the claim's expected yes: the narrowing (a collision that used to merge now refuses) and a widening (see open_questions) were both measured.", "tests": "Red first on the unfixed driver (19a401bd): src/sql-driver-upsert-empty-merge-set.test.ts 4 failed / 12 passed (non-null-default target collision red on sqlite, live postgres, live mysql cells; primary-key collision red on the mysql cell). Green after fix (fc2ee277) with the 4 neighbouring upsert suites: Test Files 5 passed, Tests 119 passed, all three cells live (SQLite in-process, local PostgreSQL 16.15, MySQL cell on MariaDB 10.11.14: no MySQL 8 server in the container). pnpm --filter @objectstack/driver-sql test (SQLite cells): Test Files 236 passed / 12 skipped, Tests 3795 passed / 214 skipped; typecheck exit 0 (TEST_EXIT=0 TYPECHECK_EXIT=0). With local live URLs the package shows 49 failures in 24 files, all live PG/MariaDB cells, none in an upsert file; the same 24 files on base 05f7758f05: identical 49 failures (environment). Compile pins are server-free toSQL() for better-sqlite3, pg, mysql2. No ablation beyond red-first (the new tests are the behaviour pin; the old behaviour is the red run). Behaviour pin on live MySQL 8 runs in CI Temporal Conformance (live PG + MySQL), which runs this package's whole suite.", "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack on the diff: 71 derived; 70 run with exit 0 (check-plugin-teardown-shape --self-test first exit 3 on a shallow clone, exit 0 after git fetch --unshallow; check:lean-entry-closure first exit 3 PREREQUISITE, exit 0 after building @objectstack/objectql...); 1 NOT MEASURED: pnpm check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET (needs the whole tree built; CI Lint and Repo Gates runs it). --ran reconciliation exit 0: 71 accounted, 70 run, 1 NOT-MEASURED, 0 UNRUN. Scoped eslint --no-inline-config on the 3 touched source files: exit 0. PR check-runs: in_progress at report time (the seat reads CI).", "dogfood_battery": "4352dcca4a (merged origin/main) · os-verify-lock VERDICT command-exit 1 · Test Files 295 passed / 1 failed / 3 skipped (299) · Tests 2522 passed / 1 failed / 18 skipped (2541) · the one failure: test/authz-probe-blind-spot.test.ts, control handleI18nRequest moved in packages/runtime/src/domains/i18n.ts, expected 4 to be 3. Not this diff (packages/runtime untouched); reproduces alone; the file last changed on main in 69fa23d60b (#25956). Reported as main-red below.", "mcp_calls": "5 — all reads: issue_read get x1, issue_read get_comments x2, search_pull_requests x2. No MCP write.", "api_writes": "2 relay strokes — pr_create (POST pulls + issue-assignees leg, run 40297616920) and this os-dev-report comment via post-stamped. git push x2 (not REST).", "open_questions": [ { "status": "needs_decision", "question": "With no conflict clause, SQLite and PostgreSQL no longer refuse an UNBACKED conflict target on the nothing-to-merge path: measured before VALIDATION_ERROR 400 / 0 rows on all three dialects; after, SQLite and PG insert the row, MySQL still refuses (its pre-flight runs before the statement). Keep it, or restore the refusal?", "options": [ "A: keep the ruled shape as-is (one dialect split on a degenerate call: a payload of insert-only columns naming a conflict key it omits, on a table with no index on that key).", "B: on the nothing-to-merge path only, check the named target against the cached physical key indexes on every dialect and answer the existing unbacked-target refusal before the plain INSERT (about 20 lines plus one test cell; one cached introspection on that path only)." ], "recommendation": "B. 实际业务需求: no measured caller sends this shape; the path is degenerate either way, so the axis is neutral. 项目长远合理性: B keeps one answer for one mistake on all three dialects; A leaves a dialect split. 防 AI 写错: B is the contract-tightening reading, a misdeclared conflict key is refused loudly instead of silently inserted; A is consumer-side tolerance. 创业阶段不扩散: B adds no gate and no surface, it restores a refusal that already existed; A widens an accept set nobody asked for." } ], "out_of_scope_findings": [ "class: a · reach: dogfood battery on origin/main (pure source census, deterministic) · test/authz-probe-blind-spot.test.ts reds after 69fa23d60b changed packages/runtime/src/domains/i18n.ts (control handleI18nRequest count 4, pin says 3) · dedupe words: authz-probe-blind-spot, handleI18nRequest, i18n census, main-red", "class: a · reach: NOT MEASURED at a public door (driver-level repro only) · isUniqueViolationError answers true for a MySQL ER_TRUNCATED_WRONG_VALUE whose message echoes an on-duplicate-key-update statement, false for the same code without the statement text · carrier: none, noted in PR Acceptance notes, not filed · dedupe words: isUniqueViolationError, duplicate key, false positive, mysql" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
os-dev-report
{ "issue": 8740, "status": "done", "branch": "claude/project-thread-slwx8p", "pr": "https://github.com/objectstack-ai/objectstack/pull/26015", "session": "session_01T6USnvRkjp4BPytcNttAuF", "premise_still_valid": true, "summary": "Step 1 (reachability of the bare merge() fallback): measured; held by the seat. Round 2, head b4fc36f35e: the merge-ALL fallback is deleted; with nothing to merge and no conflict-target column in the payload the statement is a plain INSERT (withUpsertConflictClause, src/upsert-conflict-clause.ts, not exported), so a collision raises the driver unique-violation error. Seat ruling B: on that path the named conflict target is checked against the cached physical key indexes on every dialect (assertConflictTargetBackedWithoutClause, same certainty rule and cause as the MySQL pre-flight, which now shares indexCoversConflictTarget and unbackedConflictTargetCause), so an unbacked target is refused VALIDATION_ERROR / 400 as before on all three dialects. The diff only narrows: Clause-②: no (narrowing) in the changeset. ⛔ The PR body still reads Clause-②: yes (narrowing) and its Acceptance notes still describe the widening that B removed: dev writes the body once, so the seat edits it: (1) the declaration line to Clause-②: no (narrowing); (2) replace the first Acceptance-notes bullet with: an unbacked conflict target is still refused VALIDATION_ERROR / 400 on the nothing-to-merge path on every dialect, checked against the table keys before the plain INSERT (pinned per dialect cell); (3) Tests: 19 tests in the new file, red first for the unbacked pin on 8f210ba45d (2 failed: SQLite and PG cells).", "tests": "Round 1 red (19a401bd): 4 failed / 12 passed. Round 2 red (8f210ba45d, unbacked-target pin added): 2 failed / 17 passed, sqlite and live postgres cells red (they inserted), live mysql cell green (pre-flight already refused): as measured. Green on b4fc36f35e with the 4 neighbouring upsert suites: Test Files 5 passed, Tests 122 passed, all three cells live (SQLite in-process, local PostgreSQL 16.15, MySQL cell on MariaDB 10.11.14: no MySQL 8 server in the container). pnpm --filter @objectstack/driver-sql test and typecheck on b4fc36f35e: PKG_EXIT=0, Test Files 236 passed / 12 skipped, Tests 3796 passed / 214 skipped (SQLite cells; live cells in CI). Earlier local live run: 49 failures in 24 non-upsert files, identical on base 05f7758f05 (environment). MySQL 8 behaviour pins run in CI Temporal Conformance (live PG + MySQL), which runs this package whole suite.", "gates": "On b4fc36f35e: dispatch-gates --commands --repo objectstack-ai/objectstack: 71 derived, 71 run, all exit 0 after two tree-state re-runs: check:dts-closure first exit 1 naming @objectstack/verify then @objectstack/service-knowledge (my own concurrent dogfood closure build had cleaned their dist), exit 0 after the prescribed rebuild; check:dual-build-cjs-loads exit 0 once the dogfood closure had built the tree. --ran reconciliation exit 0: 71 accounted, 71 run, 0 NOT-MEASURED. Scoped eslint --no-inline-config on the 3 touched source files: exit 0. PR check-runs read at report time (earlier head, run 40302010115/40302010169): Lint and Repo Gates, TypeScript Type Check, Test Core (8 shards), Build Core, Governed Surface Queue Guard, Check Changeset success; Lint UI / Type Check UI / Build and E2E UI skipped (no ui path). The seat reads CI on b4fc36f35e.", "dogfood_battery": "b4fc36f35e · os-verify-lock VERDICT command-exit 1 · Test Files 295 passed / 1 failed / 3 skipped (299) · Tests 2522 passed / 1 failed / 18 skipped (2541) · the one failure: test/authz-probe-blind-spot.test.ts, control handleI18nRequest moved in packages/runtime/src/domains/i18n.ts, expected 4 to be 3; identical on round 1 head 4352dcca4a; not this diff (packages/runtime untouched); main-red after 69fa23d60b (#25956).", "mcp_calls": "7 — all reads: issue_read get x1, issue_read get_comments x2, search_pull_requests x2, pull_request_read get_check_runs x1 (plus ToolSearch loads). No MCP write.", "api_writes": "3 relay strokes — pr_create (run 40297616920), round-1 os-dev-report 6412872153, this report. git push x3 (not REST).", "open_questions": [ { "status": "answered", "question": "Unbacked conflict target on the nothing-to-merge path", "answer": "seat ruled B; implemented on b4fc36f35e, pinned per dialect cell" } ], "out_of_scope_findings": [ "class: a · reach: dogfood battery on origin/main (pure source census, deterministic) · test/authz-probe-blind-spot.test.ts reds after 69fa23d60b changed packages/runtime/src/domains/i18n.ts (control handleI18nRequest count 4, pin says 3) · dedupe words: authz-probe-blind-spot, handleI18nRequest, i18n census, main-red", "class: a · reach: NOT MEASURED at a public door · isUniqueViolationError false positive on a MySQL error echoing an on-duplicate-key-update statement · seat: stays out of scope · noted in PR Acceptance notes only" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Landed
PR #26015 merged at 2026-10-26T11:56Z by the merge queue as
88f22e0844onmain(Fixes #8740; ACCEPT6414208996).git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26015-*'origin/mainby contentgit cat-file -e origin/main:packages/drivers/driver-sql/src/upsert-conflict-clause.tsgit merge-base --is-ancestor 88f22e0844 origin/mainState: this card closed by
Fixes(completed);pm:dispatchedremoved.main: run 40318775445 atb63fdf7788(first push containing88f22e0844) completed success, including Temporal Conformance (live PG + MySQL), job 121558236723.Generated by Claude Code