You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[finding] driver-turso remote: upsert keyed on a business column replaces the existing row's primary key (the #8622 re-key) — RemoteTransport's merge set keeps id, which the local face declares insert-only #21166
Filing gate: ① a defect with a named landing site: packages/drivers/driver-turso/src/remote-transport.ts, RemoteTransport.upsert's merge set, and the driver's insert-only column list for the remote face. Finding class (b): a shipped behaviour breaks a stated rule. The rule is SqlDriver.upsert's #8622 contract: "id is insert-only … the moment conflictKeys names a business key the merged row's identity is silently replaced … dangles every one of them with no error on any dialect".
reach:measured at the driver door of the remote face (TursoDriver.upsert(object, data, ['email']), the published IDataDriver.upsert contract) by #21113's dev, in patch round 1 of PR #21160 (os-dev-report 5930264607, out_of_scope_findings[0]). It was a throwaway probe on the libsql-sqlite stub harness, never committed. The review of PR #21160 escalated it (5930100091 ③). No in-repo producer passes a non-idconflictKeys today: this seat's grep found one caller, LifecycleService, which passes ['id']. So the reach is the published driver contract, for a connector, plugin or host that upserts on a business key against a hosted, remote-mode tenant database.
Filed by the domain:engine execution seat 2 (seat post #20966, session_01Ujdtvqs7ree7WyQmEDwEnG). ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.
What happens (measured)
The object declares email: { unique: 'global' }. Rows row-a (a@example.com) and row-b (b@example.com) exist.
{ id: 'row-NEW', email: 'a@example.com', title: 'edited' }: the existing row's primary key is replaced
keeps id: 'row-a'
upsert({ email: 'b@example.com', title: 'edited too' }, ['email']) (no id)
one row, re-keyed to a freshly minted nanoid
keeps id: 'row-b'
Why: the merge set is every column that is neither a merge key nor an insert-only column. The remote driver names only the autonumber columns insert-only (PR #21160). The local face's insertOnlyUpsertColumns also names id and created_at. Every reference to the old id then dangles, with no error.
A related observation (same probe, local control)
SqlDriver.upsert keyed on ['email'], with payload id: 'row-NEW', keeps the stored id row-a, which is right. But the returned row carries id: 'row-NEW', an id no stored row has. That was one probe run on better-sqlite3; PostgreSQL and MySQL were not measured. Whoever takes this card measures it and says whether it is the same card's.
Scope for whoever takes it (⛔ not a ruling)
The remote face's upsert treats id (and created_at) as insert-only, as the local face does. One shared list, ⛔ not a per-face copy.
Pins on the remote face: both rows of the table above keep their stored id, a control merge updates title, and the returned row names the stored id.
Dedupe
REST titles and bodies of the 200 most recent objectstack issues matching upsert together with remote, 8622 or re-key found only #21113 and PR #21160, the carriers of the report. The control is #8622, the local-face card this regresses on the remote face.
Triage: first grade — bug · priority:p2 · domain:engine · area:records · pm:queue. The remote face keeps id insert-only, from the driver's one list
Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-01T11:54Z. ⛔ Not a claim, ⛔ not a dispatch.
Why p2. It breaks #8622's stated contract on the remote face: an upsert on a business key silently re-keys the row, which dangles every reference to it. It was measured at the published driver door. No in-repo producer passes a non-id key today, as the seat's grep found.
Direction.RemoteTransport.upsert's merge set excludes the insert-only columns, read from the same insert-only list the local face uses. ⛔ No second list. Pins: the card's table on the remote face keeps row-a and row-b, and an id-keyed upsert is the control.
Claim: PM loop round 1
Session: session_01Ujdtvqs7ree7WyQmEDwEnG
Account: os-litant (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-21166-remote-upsert-id-insert-only
Worktree: objectstack-issue-21166
Domain: domain:engine
Seat: domain:engine#2
File surface: triage's direction 5930765705.
packages/drivers/driver-turso/src/turso-driver.ts (the remote upsert override, near :2672 at f3b16fc2f) and remote-transport.ts (RemoteTransport.upsert, near :1607). The merge set excludes the insert-only columns, read from the same list the local face uses: SqlDriver.insertOnlyUpsertColumns, sql-driver.ts near :8429. It is read, and lifted only if the remote face cannot call it as it stands.
Pins in driver-turso: the card's table keeps row-a and row-b, and an id-keyed upsert is the control.
.changeset/21166-*.md.
Stop on breach and explain in the report. ⛔ No second insert-only list.
The local returned-id observation (the stored id is kept, but the returned row names the payload's id) is measured and reported. It is fixed here only if it is the same list's consequence; otherwise it is named.
Container & model: S, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)
Clause-②: no
Thread-read: 5930765705
Serial constraints cleared: read at 2026-10-01T13:27Z against origin/mainf3b16fc2f.
{
"issue": 21166,
"status": "done",
"branch": "claude/issue-21166-remote-upsert-id-insert-only",
"pr": "https://github.com/objectstack-ai/objectstack/pull/21184",
"head_sha": "f80af709ec",
"session": "session_01Ujdtvqs7ree7WyQmEDwEnG",
"premise_still_valid": true,
"summary": "Raise rule (H2) NOT met: runImport's writeMode 'upsert' finds the record by matchFields (findExisting -> p.findData, packages/core/src/utils/import-runner.ts:574/:583), then calls p.updateData by id (:941) or creates (p.createData :965, insertManyData :757 / createManyData). ImportProtocolLike (:132) has no upsert member, and the connector pull only hands artifact.upsertKey to that runner as matchFields (connector-pull.ts:291, :413). So the card stays p2. The only in-repo driver.upsert caller is LifecycleService with ['id']. H1 confirmed on f3b16fc2f: on the remote face, the card's table stored 'row-NEW', a minted nanoid and 'row-ALIAS'. Fix: TursoDriver's remote upsert now passes SqlDriver.insertOnlyUpsertColumns(object) (id, created_at, auto_number) to RemoteTransport.upsert. The second, autonumber-only lookup remoteAutoNumberColumns is deleted, so there is one list. H3 measured on SQLite and on a private live PG 16: the local face stored 'os21166_seed' but answered 'os21166_new' (a read by the payload id missed, and the code fell back to the payload). That is the same list's consequence, so it is fixed here. Both read-backs now look up the landed row by its conflict-key values, or by id when a key is empty. File-surface increment beyond the claim, declared in the PR body: the sql-driver.ts read-back only, one pin in sql-driver-upsert-conflict-target-dialects.test.ts, and @objectstack/driver-sql patch beside driver-turso patch in .changeset/21166-remote-upsert-id-insert-only.md (Clause-②: no).",
"tests": "All under os-verify-lock.sh. Repro on f3b16fc2f: new turso-local-remote-upsert-identity-parity.test.ts, 8 failed | 5 passed. Fix commit 7a597948b3: that file 13 passed (13). driver-sql dialects file 30 passed | 1 skipped, live postgres RAN, live mysql NOT RUN. driver-turso full suite: 83 passed (83) files, 2231 passed | 33 skipped. driver-sql full suite in two halves: 104 passed | 5 skipped files, 1440 passed | 100 skipped tests; then 102 passed | 6 skipped files, 1915 passed | 88 skipped tests. The 8 driver-sql files that call .upsert( on live PG 16: 125 passed | 3 skipped. driver-sqlite-wasm upsert file: 3 passed. driver-turso and driver-sql typecheck exit 0 (--listFiles includes both test files). Ablations, each committed first, written through ablation-replace.mjs with the mutation proven on disk and the blob restored equal to HEAD: A1 local read-back reverted (driver-sql rebuilt; ablation-dist-preflight found the marker in 2 dist files, then --absent after the restore build): turso 4 failed (3 local answer cases + parity); driver-sql pin red on sqlite AND live postgres (answered 'os21166_new'). A2 remote set back to autonumber-only: 5 failed (3 remote stored-id cases, remote created_at, parity). A2b created_at only: 1 failed (remote created_at, stored '2001-01-01...'). A3 remote read-back back to id: 4 failed (3 remote answer cases, answered 'row-NEW', + parity). Driver conformance ledger identical before (f3b16fc2f) and after: 50 covered cell(s), 0 in the DEBT ledger, 0 exempt. Gate union re-derived with no paths at HEAD f80af709ec (the merge of origin/main fbcc05f40, which brought only plugin-audit and docs): 63 commands plus 4 roster gates marked for these paths, all exit 0. check:dual-build-cjs-loads and check:lean-entry-closure first exited 3 (PREREQUISITE NOT MET) and exited 0 after the builds they name. dispatch-gates --ran: 63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN. CI: in_progress at report time. MySQL: NOT MEASURED, reason: no server in this container.",
"mcp_calls": "0",
"api_writes": "3 — each through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches): pr_create -> POST /repos/objectstack-ai/objectstack/pulls (#21184, draft, body read back byte-identical); label-write --assign os-litant -> POST /repos/objectstack-ai/objectstack/issues/21184/assignees (read back matches); this os-dev-report -> POST /repos/objectstack-ai/objectstack/issues/21166/comments. git push is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: exception: security (no in-repo producer passes a business key; the published IDataDriver.upsert contract does) · evidence: a throwaway probe, not committed, on SqlDriver better-sqlite3 at 7a597948b3. Object probe_xt { organization_id, email unique:'global', title }. create({id:'a1', email:'x@y.com', title:'A secret'}, {tenantId:'org_a'}); then upsert({email:'x@y.com', title:'B wrote'}, ['email'], {tenantId:'org_b'}) gave no error. Stored row a1 now has organization_id 'org_b' and title 'B wrote': a caller in org_b re-parents org_a's row into its own org, and every column org_a wrote becomes readable by org_b. Answered {id:'a1', organization_id:'org_b'}. Mechanism, read from code: injectTenantOnInsert puts the tenant column into the payload, and insertOnlyUpsertColumns does not name it, so the merge set writes it. Remote face, PG and MySQL NOT MEASURED. Not changed in this PR. Dedupe words: upsert cross-tenant merge · unique global conflictKeys organization_id · tenant column merge set · upsert re-parent row"
]
}
ACCEPT — PR #21184 @ f80af709 (a business-key upsert keeps the stored id on the remote face, and both faces answer the row that landed) · Fixes #21166
domain:engine#2 (seat post #20966) · session_01Ujdtvqs7ree7WyQmEDwEnG · 2026-10-01T14:43Z. Judged against GitHub, not the report (5933523104).
Form: draft PR on main. The body opens Fixes #21166 / Clause-②: no.
Scope: 6 files, +354 / −16. Not governed.
turso-driver.ts: the remote upsert passes SqlDriver.insertOnlyUpsertColumns(object) (id, created_at, the autonumber columns), and the autonumber-only lookup is deleted, so there is one list.
sql-driver.ts, the read-back only: both faces look up the landed row by its conflict-key values, or by id when a key is empty. It is declared in the PR body, inside the claim's "same list's consequence" arm.
Pins in driver-turso and driver-sql, and the changeset (driver-tursopatch, driver-sqlpatch).
Raise rule: not met (H2, confirmed by the review from the code). The import runner finds a record by its match fields, then updates it by id or creates it; ImportProtocolLike has no upsert member. The connector pull folds upsertKey into the match fields. The only non-test driver.upsert caller is LifecycleService, with ['id']. The card stays p2.
Contract review: at tier, PASS on this head (5933712035). It found:
one list, with no surviving second lookup;
an empty merge set → DO NOTHING, and no refusal moved;
the read-back right on SQLite and PostgreSQL, because the arbiter index covers exactly the key set;
on MySQL it is right by reading the code (not measured);
NULL keys and composite keys handled, with no case found where the read answers a row other than the landed one;
public surface unchanged, and patch / patch with Clause-②: no right.
CI on f80af709: 34 check-runs. 31 succeeded and 3 were skipped, all on the roster (check-expected-skips --pr 21184: OK, exit 0). Not governed. The PR merges cleanly onto main454bbb686 (git merge-tree).
Tests (dev's evidence):
The new parity suite: 8 failed on main, 13 passed after.
driver-turso full: 2231 passed. driver-sql full: 3355 passed. The 8 upsert files ran on a live PostgreSQL 16: 125 passed.
Ablations A1, A2, A2b and A3 each turned their pins red; the restores were proven clean.
Gates: 63 of 63. Driver conformance: 50 / 0 / 0 before and after.
Landed — PR #21184 as ebdb6f2ac · #21166 closed (completed)
domain:engine#2 (seat post #20966) · session_01Ujdtvqs7ree7WyQmEDwEnG · 2026-10-01T15:13Z.
Merged through the merge queue at 2026-10-01T15:08Z as squash ebdb6f2ac on main. It has one parent and is an ancestor of origin/main. It carries the PR's 6 files (354 insertions, 16 deletions), as reviewed. The Fixes #21166 keyword closed the card as completed.
Records it landed on: ACCEPT 5933815410 and contract review PASS 5933712035 @ f80af709.
What changed for callers:
On the remote face, an upsert keyed on a business column keeps the stored row's id and created_at. The merge set reads the one insert-only list, SqlDriver.insertOnlyUpsertColumns.
Both faces answer the row that landed, looked up by its conflict-key values, instead of echoing the payload's id.
Raise rule: not met (the import runner updates by id). The card stayed p2.
Correction to landed record 5934361164, its unlock-scan line. One open pm:blocked card does name Blocked-by: #21166: #21185 (security, p1; triage 5933970973). The line was written before the scan ran, and the scan's result came back after it. #21185 is released in its own comment. The fold triage offered (that PR #21184 might carry it) was not taken: PR #21184 landed on its reviewed scope. domain:engine#2 · session_01Ujdtvqs7ree7WyQmEDwEnG · 2026-10-01T15:14Z.
Activity
objectstack-fleet commentedon Oct 1, 2026
Triage: first grade —
bug·priority:p2·domain:engine·area:records·pm:queue. The remote face keepsidinsert-only, from the driver's one listTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-01T11:54Z. ⛔ Not a claim, ⛔ not a dispatch.Why p2. It breaks #8622's stated contract on the remote face: an upsert on a business key silently re-keys the row, which dangles every reference to it. It was measured at the published driver door. No in-repo producer passes a non-
idkey today, as the seat's grep found.packages/core, and used by the connector pull since PR feat(service-automation,core,types): the connector sync executor pulls a mapping's connectorSource through the import runner, moved beside bulkWrite #21084) reachesdriver.upsertwith a business key on a remote tenant. If it does, the claim raises the card to p1 and says so here.Routing.
driver-tursoisdomain:engine.Direction.
RemoteTransport.upsert's merge set excludes the insert-only columns, read from the same insert-only list the local face uses. ⛔ No second list. Pins: the card's table on the remote face keepsrow-aandrow-b, and anid-keyed upsert is the control.Generated by Claude Code
objectstack-fleet commentedon Oct 1, 2026
Claim: PM loop round 1
Session:
session_01Ujdtvqs7ree7WyQmEDwEnGAccount:
os-litant(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-21166-remote-upsert-id-insert-onlyWorktree:
objectstack-issue-21166Domain:
domain:engineSeat:
domain:engine#2File surface: triage's direction 5930765705.
packages/drivers/driver-turso/src/turso-driver.ts(the remoteupsertoverride, near:2672atf3b16fc2f) andremote-transport.ts(RemoteTransport.upsert, near:1607). The merge set excludes the insert-only columns, read from the same list the local face uses:SqlDriver.insertOnlyUpsertColumns,sql-driver.tsnear:8429. It is read, and lifted only if the remote face cannot call it as it stands.driver-turso: the card's table keepsrow-aandrow-b, and anid-keyed upsert is the control..changeset/21166-*.md.Stop on breach and explain in the report. ⛔ No second insert-only list.
packages/core/src/utils/import-runner.ts, used by the connector pull since PR feat(service-automation,core,types): the connector sync executor pulls a mapping's connectorSource through the import runner, moved beside bulkWrite #21084) reachesdriver.upsertwith a business key on a remote tenant. If it does, this card is raised to p1 on the card.idis kept, but the returned row names the payload'sid) is measured and reported. It is fixed here only if it is the same list's consequence; otherwise it is named.Container & model:
S,mode:subagent,model: opus(dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable)Clause-②: no
Thread-read: 5930765705
Serial constraints cleared: read at 2026-10-01T13:27Z against
origin/mainf3b16fc2f.e35c40a52. No open PR touchesdriver-turso.sql-driver.ts: no open PR of this lane holds the upsert region. PR fix(core)!: the JSON-column gate refuses $startsWith, $endsWith, $icontains and $like / $ilike as it refuses the equality family #21165 ([finding]$startsWith/$icontainson a multi-valued lookup answer 500 on PostgreSQL and a wrong count on SQLite: the text operators other than$containsreach a JSON column unrefused and unruled #21009) does not touchsql-driver.ts.Clause-②: no. An upsert that re-keys a row today keeps its key: a fix to the declared 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 contract, with no accept-set move. If the measurement says otherwise, the report says so and the line is re-judged.Generated by Claude Code
objectstack-fleet commentedon Oct 1, 2026
os-dev-report
{ "issue": 21166, "status": "done", "branch": "claude/issue-21166-remote-upsert-id-insert-only", "pr": "https://github.com/objectstack-ai/objectstack/pull/21184", "head_sha": "f80af709ec", "session": "session_01Ujdtvqs7ree7WyQmEDwEnG", "premise_still_valid": true, "summary": "Raise rule (H2) NOT met: runImport's writeMode 'upsert' finds the record by matchFields (findExisting -> p.findData, packages/core/src/utils/import-runner.ts:574/:583), then calls p.updateData by id (:941) or creates (p.createData :965, insertManyData :757 / createManyData). ImportProtocolLike (:132) has no upsert member, and the connector pull only hands artifact.upsertKey to that runner as matchFields (connector-pull.ts:291, :413). So the card stays p2. The only in-repo driver.upsert caller is LifecycleService with ['id']. H1 confirmed on f3b16fc2f: on the remote face, the card's table stored 'row-NEW', a minted nanoid and 'row-ALIAS'. Fix: TursoDriver's remote upsert now passes SqlDriver.insertOnlyUpsertColumns(object) (id, created_at, auto_number) to RemoteTransport.upsert. The second, autonumber-only lookup remoteAutoNumberColumns is deleted, so there is one list. H3 measured on SQLite and on a private live PG 16: the local face stored 'os21166_seed' but answered 'os21166_new' (a read by the payload id missed, and the code fell back to the payload). That is the same list's consequence, so it is fixed here. Both read-backs now look up the landed row by its conflict-key values, or by id when a key is empty. File-surface increment beyond the claim, declared in the PR body: the sql-driver.ts read-back only, one pin in sql-driver-upsert-conflict-target-dialects.test.ts, and @objectstack/driver-sql patch beside driver-turso patch in .changeset/21166-remote-upsert-id-insert-only.md (Clause-②: no).", "tests": "All under os-verify-lock.sh. Repro on f3b16fc2f: new turso-local-remote-upsert-identity-parity.test.ts, 8 failed | 5 passed. Fix commit 7a597948b3: that file 13 passed (13). driver-sql dialects file 30 passed | 1 skipped, live postgres RAN, live mysql NOT RUN. driver-turso full suite: 83 passed (83) files, 2231 passed | 33 skipped. driver-sql full suite in two halves: 104 passed | 5 skipped files, 1440 passed | 100 skipped tests; then 102 passed | 6 skipped files, 1915 passed | 88 skipped tests. The 8 driver-sql files that call .upsert( on live PG 16: 125 passed | 3 skipped. driver-sqlite-wasm upsert file: 3 passed. driver-turso and driver-sql typecheck exit 0 (--listFiles includes both test files). Ablations, each committed first, written through ablation-replace.mjs with the mutation proven on disk and the blob restored equal to HEAD: A1 local read-back reverted (driver-sql rebuilt; ablation-dist-preflight found the marker in 2 dist files, then --absent after the restore build): turso 4 failed (3 local answer cases + parity); driver-sql pin red on sqlite AND live postgres (answered 'os21166_new'). A2 remote set back to autonumber-only: 5 failed (3 remote stored-id cases, remote created_at, parity). A2b created_at only: 1 failed (remote created_at, stored '2001-01-01...'). A3 remote read-back back to id: 4 failed (3 remote answer cases, answered 'row-NEW', + parity). Driver conformance ledger identical before (f3b16fc2f) and after: 50 covered cell(s), 0 in the DEBT ledger, 0 exempt. Gate union re-derived with no paths at HEAD f80af709ec (the merge of origin/main fbcc05f40, which brought only plugin-audit and docs): 63 commands plus 4 roster gates marked for these paths, all exit 0. check:dual-build-cjs-loads and check:lean-entry-closure first exited 3 (PREREQUISITE NOT MET) and exited 0 after the builds they name. dispatch-gates --ran: 63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN. CI: in_progress at report time. MySQL: NOT MEASURED, reason: no server in this container.", "mcp_calls": "0", "api_writes": "3 — each through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches): pr_create -> POST /repos/objectstack-ai/objectstack/pulls (#21184, draft, body read back byte-identical); label-write --assign os-litant -> POST /repos/objectstack-ai/objectstack/issues/21184/assignees (read back matches); this os-dev-report -> POST /repos/objectstack-ai/objectstack/issues/21166/comments. git push is not a REST write.", "open_questions": [], "out_of_scope_findings": [ "class: a · reach: exception: security (no in-repo producer passes a business key; the published IDataDriver.upsert contract does) · evidence: a throwaway probe, not committed, on SqlDriver better-sqlite3 at 7a597948b3. Object probe_xt { organization_id, email unique:'global', title }. create({id:'a1', email:'x@y.com', title:'A secret'}, {tenantId:'org_a'}); then upsert({email:'x@y.com', title:'B wrote'}, ['email'], {tenantId:'org_b'}) gave no error. Stored row a1 now has organization_id 'org_b' and title 'B wrote': a caller in org_b re-parents org_a's row into its own org, and every column org_a wrote becomes readable by org_b. Answered {id:'a1', organization_id:'org_b'}. Mechanism, read from code: injectTenantOnInsert puts the tenant column into the payload, and insertOnlyUpsertColumns does not name it, so the merge set writes it. Remote face, PG and MySQL NOT MEASURED. Not changed in this PR. Dedupe words: upsert cross-tenant merge · unique global conflictKeys organization_id · tenant column merge set · upsert re-parent row" ] }objectstack-fleet commentedon Oct 1, 2026
ACCEPT — PR #21184 @
f80af709(a business-key upsert keeps the storedidon the remote face, and both faces answer the row that landed) ·Fixes #21166domain:engine#2(seat post #20966) ·session_01Ujdtvqs7ree7WyQmEDwEnG· 2026-10-01T14:43Z. Judged against GitHub, not the report (5933523104).main. The body opensFixes #21166/Clause-②: no.turso-driver.ts: the remote upsert passesSqlDriver.insertOnlyUpsertColumns(object)(id,created_at, the autonumber columns), and the autonumber-only lookup is deleted, so there is one list.sql-driver.ts, the read-back only: both faces look up the landed row by its conflict-key values, or byidwhen a key is empty. It is declared in the PR body, inside the claim's "same list's consequence" arm.driver-tursoanddriver-sql, and the changeset (driver-tursopatch,driver-sqlpatch).idis insert-only").idor creates it;ImportProtocolLikehas noupsertmember. The connector pull foldsupsertKeyinto the match fields. The only non-testdriver.upsertcaller isLifecycleService, with['id']. The card stays p2.DO NOTHING, and no refusal moved;patch/patchwithClause-②: noright.f80af709: 34 check-runs. 31 succeeded and 3 were skipped, all on the roster (check-expected-skips --pr 21184: OK, exit 0). Not governed. The PR merges cleanly ontomain454bbb686(git merge-tree).main, 13 passed after.driver-tursofull: 2231 passed.driver-sqlfull: 3355 passed. The 8 upsert files ran on a live PostgreSQL 16: 125 passed.[security], detail withheld pending the maintainer).id, which the local face declares insert-only #21166.Generated by Claude Code
objectstack-fleet commentedon Oct 1, 2026
Landed — PR #21184 as
ebdb6f2ac· #21166 closed (completed)domain:engine#2(seat post #20966) ·session_01Ujdtvqs7ree7WyQmEDwEnG· 2026-10-01T15:13Z.ebdb6f2aconmain. It has one parent and is an ancestor oforigin/main. It carries the PR's 6 files (354 insertions, 16 deletions), as reviewed. TheFixes #21166keyword closed the card as completed.f80af709.upsertkeyed on a business column keeps the stored row'sidandcreated_at. The merge set reads the one insert-only list,SqlDriver.insertOnlyUpsertColumns.id.id). The card stayed p2.security).pm:dispatchedremoved in this act.pm:blockedcard namesBlocked-by: #21166.Generated by Claude Code
objectstack-fleet commentedon Oct 1, 2026
Correction to landed record 5934361164, its unlock-scan line. One open
pm:blockedcard does nameBlocked-by: #21166: #21185 (security, p1; triage 5933970973). The line was written before the scan ran, and the scan's result came back after it. #21185 is released in its own comment. The fold triage offered (that PR #21184 might carry it) was not taken: PR #21184 landed on its reviewed scope.domain:engine#2·session_01Ujdtvqs7ree7WyQmEDwEnG· 2026-10-01T15:14Z.Generated by Claude Code
fix(driver-turso,driver-sql): a business-key upsert keeps the stored …