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
driver-mongodb: field unique is built as a sparse index, so two explicit null values collide, unlike the NULL-distinct rule of driver-sql and driver-memory #29278
Filing gate: ① out-of-scope finding of the #29176 dev (os-dev-report 6575284496, out_of_scope_findings class b), read from source, NOT MEASURED (the dev's container could not download mongod). Filed by domain:server seat 3. ⛔ Not a claim. Suggested-grade: p3 · a driver diverges from the shared unique rule; no grant or disclosure.
Reach: a deployment on driver-mongodb with an optional field declared unique, when two records hold no value in it.
Reader who acts: a domain:server seat (packages/drivers/driver-mongodb/src/mongodb-schema.ts).
What happens (source reading)
mongodb-schema.ts builds a field's unique as { unique: true, sparse: true }. A sparse index skips only documents that lack the field; it still indexes an explicit null, so two documents storing null collide.
driver-sql's unique index and driver-memory's key model are NULL-distinct (see the memory-unique-constraint.ts docblock): two null rows never collide.
Measure on a real mongod first (the conformance harness). If confirmed, build the unique index so missing and null are both excluded (for example a partialFilterExpression on the field's type, or the driver omitting null fields on write), and add the case to the driver conformance ledger so all drivers answer it alike.
Read fresh. Read from source, not measured: driver-mongodb builds unique as a sparse index, which still indexes an explicit null, so two null rows collide where driver-sql and driver-memory treat NULLs as distinct. One driver diverges from the shared rule; nothing is granted or disclosed. p3. Measure on a real mongod first, then add the case to the driver conformance ledger.
Claim: PM loop round 3 · 2026-11-02T11:18Z
Session: session_01ADHkmQjPiXgNoSaEpqeGvY (seat); dev = card thread (session named in its first report)
Account: os-steve
Branch: the card thread's harness-pinned branch, named in its first report (it names no issue, so this claim is the identity record)
Worktree: the card thread's own
Domain: domain:server
Seat: domain:server#1
File surface: packages/drivers/driver-mongodb/src/mongodb-schema.ts (and its index-sync site), driver tests, the driver conformance case, a @objectstack/driver-mongodb changeset. ⛔ No packages/spec/**, no driver-sql / driver-memory behaviour change, no new error code; ⛔ no fix shipped without a real mongod measurement. (stop on breach; explain in the report)
Container & model: S, mode:thread, model as the thread was opened, effort: medium
Clause-②: yes (widening) (expected: two explicit null values in an optional unique field, refused on Mongo today, are admitted as on sql and memory; the dev measures)
Metadata-protocol: none (expected)
Responsibility: the code is the driver-mongodb unique index · the platform path is the shared NULL-distinct unique rule · reached by every Mongo deployment with an optional unique field
Thread-read: 6575398009
Premise: as filed; the dev re-measures on current main first
Serial constraints cleared: no open PR of this seat touches driver-mongodb; the dev reads open PRs on the package before the first write
Orders: the seat's standard order plus the card delta, in the project's shared folder (server-seat1/standard-order.md, server-seat1/29278-delta.md).
Claim: PM loop round 3 (revised: branch and dev session named) · 2026-11-02T11:21Z
Session: session_01ADHkmQjPiXgNoSaEpqeGvY (seat); dev = card thread session_01ADHkmRc2jLWPKqPfVHStXw
Account: os-steve
Branch: claude/project-thread-rmcblv (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
Worktree: the card thread's own
Domain: domain:server
Seat: domain:server#1
File surface: packages/drivers/driver-mongodb/src/mongodb-schema.ts (and its index-sync site), driver tests, the driver conformance case, a @objectstack/driver-mongodb changeset. ⛔ No packages/spec/**, no driver-sql / driver-memory behaviour change, no new error code; ⛔ no fix shipped without a real mongod measurement. (stop on breach; explain in the report)
Container & model: S, mode:thread, model as the thread was opened, effort: medium
Clause-②: yes (widening) (expected: two explicit null values in an optional unique field, refused on Mongo today, are admitted as on sql and memory; the dev measures)
Metadata-protocol: none (expected)
Responsibility: the code is the driver-mongodb unique index · the platform path is the shared NULL-distinct unique rule · reached by every Mongo deployment with an optional unique field
Thread-read: 6575398009
Premise: as filed; the dev re-measures on current main first
Serial constraints cleared: no open PR of this seat touches driver-mongodb; the dev reads open PRs on the package before the first write
Orders: the seat's standard order plus the card delta, in the project's shared folder (server-seat1/standard-order.md, server-seat1/29278-delta.md).
Hold · 2026-11-02T11:40Z · claim 6575878708 withdrawn
This card is a driver-mongodb defect fix, and driver-mongodb is under the maintainer's investment freeze (#5499: "driver-mongodb 暂无客户"; new driver-memory / driver-mongodb cards go straight to pm:on-hold citing #5499, not to pm:queue). It entered the queue by mistake and this seat dispatched it without checking. The card thread stopped at Step 0 with zero writes (no mongod reachable from the container), so nothing was built.
Moved pm:dispatched → pm:on-hold. Wake condition, verbatim from #5499:
Hold withdrawn · 2026-11-02T11:45Z · correction of 6576235761
The hold 6576235761 was wrong. The #5499 freeze was lifted for driver-mongodb on 2026-08-11T00:00Z, as origin/main records in packages/spec/src/data/aggregation-conformance.ts (head note: "the maintainer lifted the #5499 investment freeze for driver-mongodb on 2026-08-11") and in packages/drivers/driver-mongodb/src/test-mongod.ts ("The premise that is GONE is #5499 … It dissolved 2026-08-11"). This seat read the #5499 body and missed the lift.
Back to pm:dispatched, assignee os-steve. Claim 6575878708 (revised: branch claude/project-thread-rmcblv, dev session_01ADHkmRc2jLWPKqPfVHStXw) stands again. The dev measured the premise on a real mongod 8.3.7 (two null → E11000, two missing → admitted, two '' → E11000) and resumes the fix.
{
"issue": 29278,
"status": "done",
"branch": "claude/project-thread-rmcblv",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29339",
"session": "session_01ADHkmRc2jLWPKqPfVHStXw",
"premise_still_valid": true,
"summary": "Premise MEASURED on a real mongod 8.3.7 (conda-forge build, supplied via MONGOMS_SYSTEM_BINARY; fastdl.mongodb.org is 403 here; Steve approved running it): on base the sparse unique index refuses a second null (E11000) and admits two missing. Field-level and declared indexes[] unique indexes are now partial over every non-null BSON type (no sparse), with a plain read index idx_FIELDS beside each because the planner COLLSCANs an equality lookup on a partial index. A legacy sparse unique index the driver built is rebuilt at the next schema sync (drop + create under its name, measured); any other same-name index is left alone. memory, sql and mongo now answer the two-nulls case alike.",
"tests": "new src/mongodb-unique-null-distinct.test.ts (7 recording-Db + 8 real-mongod): base 276ca307 8 failed/7 passed, head 84fb196d 15/15. driver-mongodb full suite with real mongod 38 files / 911 tests passed, default lane 721 passed 190 skipped. Ablations via ablation-replace.mjs (suite reads src, no dist leg): A1 unique:false 6 red; A2 any same-name index read as legacy 2 red; A3 no read index 3 red; each restored blob==HEAD, git diff HEAD empty. Cross-driver probe on built dist (head 84fb196d): null x2, missing x2, (eu,null) x2 admitted on all three; '' x2, 'X' x2, (eu,t) x2 refused on all three.",
"gates": "head e38ab227: dispatch-gates --commands 60 families, 60 x exit 0 (check-plugin-teardown-shape --self-test first exit 3, prerequisite; re-run exit 0 after git fetch --depth=1 origin 621a4876); --ran: 60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN. pnpm --filter @objectstack/driver-mongodb typecheck exit 0. pnpm exec eslint --no-inline-config packages/drivers/driver-mongodb exit 0. check:driver-conformance 66 covered / 0 DEBT / 0 exempt on base and head. PR check-runs: in_progress at report time.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "4 — issue_read x2 (get, get_comments), pull_request_read get (#29271), list_pull_requests; no write tool",
"api_writes": "2 — relay pr_create (#29339, run 41443883629) and this os-dev-report comment via post-stamped.mjs",
"files_changed": [
"packages/drivers/driver-mongodb/src/mongodb-schema.ts",
"packages/drivers/driver-mongodb/src/mongodb-unique-null-distinct.test.ts",
".changeset/29278-mongodb-unique-null-distinct.md"
],
"line_budget": "449 insertions, 12 deletions across 3 files (src 166, test 281, changeset 14); effort M (the index migration needed code)",
"deviations": [
"No shared conformance case-set: the case-sets live in packages/spec/src/data, which this lane does not edit; replaced by a measured three-driver probe (PR acceptance notes) and an open question.",
"Declared indexes[] unique entries changed too (same file, same defect class): a single-column declaration converges on idx_FIELD_unique with the field-level route, so leaving it sparse would ask for one name with two option sets.",
"A plain read index idx_FIELDS is added beside each unique index (measured COLLSCAN otherwise); not named in the delta.",
"origin/main moved 27 commits past base 276ca307; none touch packages/drivers or packages/spec/src/data, so the branch was not merged before the PR.",
"Harness asks to assign os-steve and request his review on the PR; skipped per os-dev (pr_create carries no assignees) and the no-MCP-write rule.",
"The real-mongod readings depend on a conda-forge mongod binary in this container; the opt-in suite still runs on no CI lane (#5517)."
],
"open_questions": [
{
"question": "Should the spec seat add a shared unique NULL-distinct conformance case-set so every driver enrolls in one standard?",
"options": ["A: spec seat files a card for packages/spec/src/data/unique-conformance.ts; drivers enroll in a follow-up", "B: keep per-driver pins only"],
"recommendation": "A, because the gate (check:driver-conformance) only enforces cross-driver agreement through a shared case-set; today the agreement is a one-off probe."
},
{
"question": "Keep the extra plain read index beside each unique index?",
"options": ["A: keep it (lookups by a unique field stay indexed; one more index per unique field to maintain on writes)", "B: drop it and accept COLLSCAN on lookups by a unique field"],
"recommendation": "A, because B turns every lookup by email/SKU-style fields into a full collection scan, a worse regression than the p3 bug."
},
{
"question": "Is the drop-then-create rebuild of a legacy index at schema sync acceptable, given a brief window without a unique index?",
"options": ["A: as shipped (a duplicate written in the window fails the sync loudly with E11000)", "B: leave legacy indexes alone and log a warning naming the manual rebuild"],
"recommendation": "A, because B leaves every deployed collection on the old refusal with no fix reaching it."
}
],
"security_findings": "none",
"out_of_scope_findings": []
}
pm:dispatched is removed. Seat records: review PASS 6577415377, ACCEPT 6577460267.
The card's "Wanted" asked for a shared NULL-distinct unique conformance case-set. That set would sit in packages/spec/src/data, which is outside the server lane's claim. It is handed to the spec lane through the coordinator, and the case-set stays unbuilt until a spec seat takes it. driver-sql, driver-memory and driver-mongodb now agree on two null values, as measured on PR #29339.
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p3 ·
domain:server·pm:queue· 2026-11-02T10:56Z⛔ Not a claim.
uniqueas a sparse index, which still indexes an explicitnull, so twonullrows collide where driver-sql and driver-memory treat NULLs as distinct. One driver diverges from the shared rule; nothing is granted or disclosed. p3. Measure on a realmongodfirst, then add the case to the driver conformance ledger.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#1 · os-steve · session_01ADHkmQjPiXgNoSaEpqeGvY
Claim: PM loop round 3 · 2026-11-02T11:18Z
Session:
session_01ADHkmQjPiXgNoSaEpqeGvY(seat); dev = card thread (session named in its first report)Account:
os-steveBranch: the card thread's harness-pinned branch, named in its first report (it names no issue, so this claim is the identity record)
Worktree: the card thread's own
Domain:
domain:serverSeat:
domain:server#1File surface:
packages/drivers/driver-mongodb/src/mongodb-schema.ts(and its index-sync site), driver tests, the driver conformance case, a@objectstack/driver-mongodbchangeset. ⛔ Nopackages/spec/**, no driver-sql / driver-memory behaviour change, no new error code; ⛔ no fix shipped without a realmongodmeasurement. (stop on breach; explain in the report)Container & model:
S,mode:thread, model as the thread was opened,effort: mediumClause-②: yes (widening) (expected: two explicit
nullvalues in an optional unique field, refused on Mongo today, are admitted as on sql and memory; the dev measures)Metadata-protocol: none (expected)
Responsibility: the code is the driver-mongodb unique index · the platform path is the shared NULL-distinct unique rule · reached by every Mongo deployment with an optional unique field
Thread-read: 6575398009
Premise: as filed; the dev re-measures on current
mainfirstSerial constraints cleared: no open PR of this seat touches
driver-mongodb; the dev reads open PRs on the package before the first writeOrders: the seat's standard order plus the card delta, in the project's shared folder (server-seat1/standard-order.md, server-seat1/29278-delta.md).
objectstack-fleet commentedon Nov 2, 2026
domain:server#1 · os-steve · session_01ADHkmQjPiXgNoSaEpqeGvY
Claim: PM loop round 3 (revised: branch and dev session named) · 2026-11-02T11:21Z
Session:
session_01ADHkmQjPiXgNoSaEpqeGvY(seat); dev = card threadsession_01ADHkmRc2jLWPKqPfVHStXwAccount:
os-steveBranch:
claude/project-thread-rmcblv(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree: the card thread's own
Domain:
domain:serverSeat:
domain:server#1File surface:
packages/drivers/driver-mongodb/src/mongodb-schema.ts(and its index-sync site), driver tests, the driver conformance case, a@objectstack/driver-mongodbchangeset. ⛔ Nopackages/spec/**, no driver-sql / driver-memory behaviour change, no new error code; ⛔ no fix shipped without a realmongodmeasurement. (stop on breach; explain in the report)Container & model:
S,mode:thread, model as the thread was opened,effort: mediumClause-②: yes (widening) (expected: two explicit
nullvalues in an optional unique field, refused on Mongo today, are admitted as on sql and memory; the dev measures)Metadata-protocol: none (expected)
Responsibility: the code is the driver-mongodb unique index · the platform path is the shared NULL-distinct unique rule · reached by every Mongo deployment with an optional unique field
Thread-read: 6575398009
Premise: as filed; the dev re-measures on current
mainfirstSerial constraints cleared: no open PR of this seat touches
driver-mongodb; the dev reads open PRs on the package before the first writeOrders: the seat's standard order plus the card delta, in the project's shared folder (server-seat1/standard-order.md, server-seat1/29278-delta.md).
objectstack-fleet commentedon Nov 2, 2026
domain:server#1 · os-steve · session_01ADHkmQjPiXgNoSaEpqeGvY
Hold · 2026-11-02T11:40Z · claim 6575878708 withdrawn
This card is a driver-mongodb defect fix, and driver-mongodb is under the maintainer's investment freeze (#5499: "driver-mongodb 暂无客户"; new driver-memory / driver-mongodb cards go straight to
pm:on-holdciting #5499, not topm:queue). It entered the queue by mistake and this seat dispatched it without checking. The card thread stopped at Step 0 with zero writes (nomongodreachable from the container), so nothing was built.Moved
pm:dispatched→pm:on-hold. Wake condition, verbatim from #5499:objectstack-fleet commentedon Nov 2, 2026
domain:server#1 · os-steve · session_01ADHkmQjPiXgNoSaEpqeGvY
Hold withdrawn · 2026-11-02T11:45Z · correction of 6576235761
The hold 6576235761 was wrong. The #5499 freeze was lifted for
driver-mongodbon 2026-08-11T00:00Z, asorigin/mainrecords inpackages/spec/src/data/aggregation-conformance.ts(head note: "the maintainer lifted the #5499 investment freeze fordriver-mongodbon 2026-08-11") and inpackages/drivers/driver-mongodb/src/test-mongod.ts("The premise that is GONE is #5499 … It dissolved 2026-08-11"). This seat read the #5499 body and missed the lift.Back to
pm:dispatched, assigneeos-steve. Claim 6575878708 (revised: branchclaude/project-thread-rmcblv, devsession_01ADHkmRc2jLWPKqPfVHStXw) stands again. The dev measured the premise on a realmongod8.3.7 (twonull→ E11000, two missing → admitted, two''→ E11000) and resumes the fix.objectstack-fleet commentedon Nov 2, 2026
domain:server#1 · os-steve · session_01ADHkmRc2jLWPKqPfVHStXw
os-dev-report
{ "issue": 29278, "status": "done", "branch": "claude/project-thread-rmcblv", "pr": "https://github.com/objectstack-ai/objectstack/pull/29339", "session": "session_01ADHkmRc2jLWPKqPfVHStXw", "premise_still_valid": true, "summary": "Premise MEASURED on a real mongod 8.3.7 (conda-forge build, supplied via MONGOMS_SYSTEM_BINARY; fastdl.mongodb.org is 403 here; Steve approved running it): on base the sparse unique index refuses a second null (E11000) and admits two missing. Field-level and declared indexes[] unique indexes are now partial over every non-null BSON type (no sparse), with a plain read index idx_FIELDS beside each because the planner COLLSCANs an equality lookup on a partial index. A legacy sparse unique index the driver built is rebuilt at the next schema sync (drop + create under its name, measured); any other same-name index is left alone. memory, sql and mongo now answer the two-nulls case alike.", "tests": "new src/mongodb-unique-null-distinct.test.ts (7 recording-Db + 8 real-mongod): base 276ca307 8 failed/7 passed, head 84fb196d 15/15. driver-mongodb full suite with real mongod 38 files / 911 tests passed, default lane 721 passed 190 skipped. Ablations via ablation-replace.mjs (suite reads src, no dist leg): A1 unique:false 6 red; A2 any same-name index read as legacy 2 red; A3 no read index 3 red; each restored blob==HEAD, git diff HEAD empty. Cross-driver probe on built dist (head 84fb196d): null x2, missing x2, (eu,null) x2 admitted on all three; '' x2, 'X' x2, (eu,t) x2 refused on all three.", "gates": "head e38ab227: dispatch-gates --commands 60 families, 60 x exit 0 (check-plugin-teardown-shape --self-test first exit 3, prerequisite; re-run exit 0 after git fetch --depth=1 origin 621a4876); --ran: 60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN. pnpm --filter @objectstack/driver-mongodb typecheck exit 0. pnpm exec eslint --no-inline-config packages/drivers/driver-mongodb exit 0. check:driver-conformance 66 covered / 0 DEBT / 0 exempt on base and head. PR check-runs: in_progress at report time.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "4 — issue_read x2 (get, get_comments), pull_request_read get (#29271), list_pull_requests; no write tool", "api_writes": "2 — relay pr_create (#29339, run 41443883629) and this os-dev-report comment via post-stamped.mjs", "files_changed": [ "packages/drivers/driver-mongodb/src/mongodb-schema.ts", "packages/drivers/driver-mongodb/src/mongodb-unique-null-distinct.test.ts", ".changeset/29278-mongodb-unique-null-distinct.md" ], "line_budget": "449 insertions, 12 deletions across 3 files (src 166, test 281, changeset 14); effort M (the index migration needed code)", "deviations": [ "No shared conformance case-set: the case-sets live in packages/spec/src/data, which this lane does not edit; replaced by a measured three-driver probe (PR acceptance notes) and an open question.", "Declared indexes[] unique entries changed too (same file, same defect class): a single-column declaration converges on idx_FIELD_unique with the field-level route, so leaving it sparse would ask for one name with two option sets.", "A plain read index idx_FIELDS is added beside each unique index (measured COLLSCAN otherwise); not named in the delta.", "origin/main moved 27 commits past base 276ca307; none touch packages/drivers or packages/spec/src/data, so the branch was not merged before the PR.", "Harness asks to assign os-steve and request his review on the PR; skipped per os-dev (pr_create carries no assignees) and the no-MCP-write rule.", "The real-mongod readings depend on a conda-forge mongod binary in this container; the opt-in suite still runs on no CI lane (#5517)." ], "open_questions": [ { "question": "Should the spec seat add a shared unique NULL-distinct conformance case-set so every driver enrolls in one standard?", "options": ["A: spec seat files a card for packages/spec/src/data/unique-conformance.ts; drivers enroll in a follow-up", "B: keep per-driver pins only"], "recommendation": "A, because the gate (check:driver-conformance) only enforces cross-driver agreement through a shared case-set; today the agreement is a one-off probe." }, { "question": "Keep the extra plain read index beside each unique index?", "options": ["A: keep it (lookups by a unique field stay indexed; one more index per unique field to maintain on writes)", "B: drop it and accept COLLSCAN on lookups by a unique field"], "recommendation": "A, because B turns every lookup by email/SKU-style fields into a full collection scan, a worse regression than the p3 bug." }, { "question": "Is the drop-then-create rebuild of a legacy index at schema sync acceptable, given a brief window without a unique index?", "options": ["A: as shipped (a duplicate written in the window fails the sync loudly with E11000)", "B: leave legacy indexes alone and log a warning naming the manual rebuild"], "recommendation": "A, because B leaves every deployed collection on the old refusal with no fix reaching it." } ], "security_findings": "none", "out_of_scope_findings": [] }Stamped 2026-11-02T12:21Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#1 · os-steve · session_01ADHkmQjPiXgNoSaEpqeGvY
Landed · 2026-11-02T13:25Z
5924e5002f, through the merge queueFixes #29278pm:dispatchedis removed. Seat records: review PASS 6577415377, ACCEPT 6577460267.The card's "Wanted" asked for a shared NULL-distinct
uniqueconformance case-set. That set would sit inpackages/spec/src/data, which is outside the server lane's claim. It is handed to the spec lane through the coordinator, and the case-set stays unbuilt until a spec seat takes it. driver-sql, driver-memory and driver-mongodb now agree on twonullvalues, as measured on PR #29339.