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
service-analytics: the native-SQL face emits plain LIKE for mssql, so a dashboard's text filter on a SQL Server federated object does not keep #6518's case-exact / case-folded contract the driver keeps #31394
epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV
Filing gate: ③ escalation of the CONTRACT_REVIEW_TIER record on PR #31381 (#31327). #6518's text-match contract holds on the driver face only.
Ruling-ref: #6518 (case-exact and case-folded text match)
Dedupe (open AND closed): "analytics native sql mssql LIKE", "service-analytics COLLATE" → none.
Blocked-by: #31327
Reader: the epic PM dispatches it after #31327 lands.
type: Bug
Measure first: the same text filter through the driver face and through service-analytics' native-SQL face, on a case-insensitive SQL Server collation, gives different rows. Measure Oracle the same way.
Make the native-SQL face emit the dialect's text-match arms. Reuse driver-sql's emitters; don't copy them.
Pin it: compile-level for every arm, and a live cell when a URL is present.
Claim: PM loop round 1 · 2026-11-08T16:17Z
Session: session_01ADHkmTC6s4J4HjQ7nyUMSz (card thread, dev) · seat session_01ADHkmQKZzp4DLtqiCkZZRM
Account: os-steve
Branch: claude/project-thread-i27fm1
Worktree: objectstack-issue-31394
Domain: domain:server
Seat: domain:server#2
File surface: packages/services/service-analytics/src/text-match-sql.ts (mssql/oracle arms), its callers only if the dialect name must flow differently, the cross-run drift suites text-operator-case-exactness.test.ts / text-match-sqlite-nul.test.ts and a new mssql/oracle compile test, root .changeset/; packages/drivers/driver-sql only if a shared emitter is lifted inside the lane. ⛔ No packages/spec/**, no ui/**
Container & model: M, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: @objectstack/service-analytics native-SQL face (objectstack) maps mssql/oracle to the unknown arm instead of #6518's case contract | driver-sql's own text-match arms already keep the contract on the driver face | every dashboard text filter over a federated SQL Server (and possibly Oracle) object
Thread-read: 6723770780
Premise: holds per seat 1's re-verification 6723770780 on 645ed3d1 (no mssql arm in text-match-sql.ts); the dev measures red first
Serial constraints cleared: no open PR touches packages/services/service-analytics/** (read at claim); epic siblings #31390 (driver-sql oracle bind) and #31389 (service-datasource catalog) are disjoint
Scope: Fixes #31394, per #6518 (Ruling-ref). Order: /mnt/project-files/server-seat2/standard-order.md + /mnt/project-files/server-seat2/31394-delta.md (the card's "reuse, don't copy" against the file's no-driver-dependency rule is the dev's four-axis call; a new package or spec export stops at needs_decision). Summons: the maintainer's 「并发都是5」 (project chat, 2026-11-08T16:13Z).
The dev's route report chose option (b) of the delta: lift driver-sql's text-match construct table into @objectstack/core with caller-supplied emitters, the shape packages/core/src/utils/json-membership-sql.ts already has (re-exported from core's index at origin/main; imported by driver-sql/src/sql-driver-predicate-emitters.ts). No new package, no spec export. Seat accepts the route.
File surface: packages/core/src/utils/text-match-sql.ts (new) and its re-export in packages/core/src/index.ts; driver-sql's textMatchPredicate and service-analytics' textMatchPredicateSql become thin adapters over it (each keeps its own unknown residue); packages/services/service-analytics/src/text-match-sql.ts and its dialect vocabulary; the cross-run drift suites and new compile tests; root .changeset/. ⛔ No packages/spec/**, no ui/**.
Clause-②: yes (widening) — new @objectstack/core exports, and the analytics dialect vocabulary widens to mssql/oracle (reachable through the exported AnalyticsServiceConfig); the dev confirms from the real diff; the new public names go in open_questions for the seat's ruling at ACCEPT
Serial constraints cleared: no open PR touches packages/core/src/index.ts, packages/core/src/utils/** or driver-sql/src/sql-driver.ts (read now). In-flight driver-sql siblings: #31395 (seat 1, mssql substring operators) and #31390 (seat 4, oracle bind); the dev keeps the driver-sql edit to the adapter, merges main after either lands, and conflicts go to the merge queue.
{
"issue": 31394,
"status": "done",
"branch": "claude/project-thread-i27fm1",
"pr": "https://github.com/objectstack-ai/objectstack/pull/31625",
"session": "session_01ADHkmTC6s4J4HjQ7nyUMSz",
"premise_still_valid": true,
"summary": "Measured on main (5ee59f5e), compile-level: on SQL Server the analytics bridge read dialectName 'mssql' as no answer, so the native-SQL where, read scope and echo emitted a plain LIKE (CI default collation, '[' unescaped) where the driver emits the BIN2/TRANSLATE arms: 17/17 cells red. Oracle measured consistent (16/16 green: same LIKE for the case-exact four; translate vs REPLACE fold row-equivalent), so its arm is left as is. Route (b): the construct table moves to @objectstack/core (text-match-sql.ts, mirroring #20987 json-membership-sql); driver-sql's textMatchPredicate becomes a thin emitter adapter with identical SQL; analytics emits through it and accepts 'mssql' (every other per-dialect table treats mssql as it treated unknown).",
"tests": "Red first on main: 17 mssql cells red, 16 oracle green. Head 833400e0 via os-verify-lock VERDICT command-exit 0: core text-match-sql.test.ts 3/3; analytics text-match-mssql-oracle + sql-dialect-vocabulary + text-operator-case-exactness 59 passed / 30 skipped; driver-sql full 245 files, 4113 passed / 222 skipped, identical with main's emitter file put back (4113/222). Pre-merge: analytics full 5098 passed / 330 skipped; core 3246 passed; closure typecheck clean. Ablation 1 (ACCEPTED_SQL_DIALECTS without 'mssql', ablation-replace): 17 failed, first '× the bridge hands the driver's mssql on'; restored blob == HEAD. Ablation 2 (core's mssql comparand escape without '[', core rebuilt, ablation-dist-preflight @objectstack/core found the marker in dist): analytics '[ is escaped on this dialect alone' failed (params '%a[b%' where '%a\\[b%' expected) and driver-sql sql-driver-mssql-dialect '$contains: both sides case-exact' failed (binding '%a\\%\\_[b%' where '%a\\%\\_\\[b%' expected); restored (blob == HEAD), rebuilt, preflight --absent ok, suite green 33 passed / 30 skipped. Live cells (OS_TEST_MSSQL_URL / OS_TEST_ORACLE_URL) NOT run: no URL in this container.",
"gates": "dispatch-gates --commands at 833400e0: 74 commands run; --ran reconciliation 74 derived / 74 run / 0 NOT-MEASURED / 0 UNRUN, all exit 0. Three first exited on container prerequisites and were rerun after closing them: check-plugin-teardown-shape --self-test (exit 3 shallow clone -> fixture commit fetched -> 0), check:dts-closure (exit 1, analytics built without d.ts -> rebuilt -> 0), check:dual-build-cjs-loads (exit 3 no dist -> full pnpm build 119/119 -> 0). eslint on the 12 changed .ts files exit 0. check-platform-checklist --changed-from origin/main exit 0 (0 anchored). check-driver-conformance before/after: 66 covered, 6 DEBT, 0 exempt. CI check-runs not yet read (not waited on).",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm; the change is Clause-②: yes (widening)",
"files_changed": [
".changeset/31394-text-match-mssql-native-sql.md",
"packages/core/src/index.ts",
"packages/core/src/utils/text-match-sql.ts",
"packages/core/src/utils/text-match-sql.test.ts",
"packages/drivers/driver-sql/src/sql-driver-predicate-emitters.ts",
"packages/services/service-analytics/src/text-match-sql.ts",
"packages/services/service-analytics/src/like-pattern.ts",
"packages/services/service-analytics/src/duration-measure-sql.ts",
"packages/services/service-analytics/src/contains-membership-sql.ts",
"packages/services/service-analytics/src/strategies/native-sql-strategy.ts",
"packages/services/service-analytics/src/__tests__/text-match-mssql-oracle.test.ts",
"packages/services/service-analytics/src/__tests__/text-operator-case-exactness.test.ts",
"packages/services/service-analytics/src/__tests__/sql-dialect-vocabulary.test.ts"
],
"line_budget": "src +575 / -851 (net -276); tests +470 / -20; changeset +14. 13 files.",
"deviations": [
"core added to the file surface (claim amendment, route (b)).",
"Forced test edits: sql-dialect-vocabulary.test.ts (accept set now 4 names; 'oracle' replaces 'mssql' as the not-accepted example); text-operator-case-exactness.test.ts (normalise pin names 'mssql'; GLOB-escape pin reads the bound param of compileScopedFilterToSql on sqlite instead of the removed private escapeGlobPattern/globPattern, expected values unchanged).",
"Live cells not run (no URL)."
],
"mcp_calls": "4 — mcp__github__issue_read x4 (reads only; no write tool)",
"api_writes": "4 — POST /repos/objectstack-ai/objectstack/dispatches (relay fw-20261108T173011Z-c0723a, executed as POST /pulls -> #31625 and POST /issues/31625/assignees [os-steve]); POST /issues/31394/comments (this report, post-stamped). Branch pushes are git transport, not REST.",
"open_questions": [
{
"question": "New @objectstack/core export names (seat rules at ACCEPT): dialectTextMatchSql, TextMatchDialect, TextMatchShape, TextMatchEmitters, TextMatchRequest, textMatchLikePattern, TEXT_MATCH_ESCAPE_CHARACTER, ASCII_UPPER_LETTERS, ASCII_LOWER_LETTERS, mssqlCaseExactSql, mssqlAsciiLowerSql, mysqlAsciiLowerBinarySql.",
"options": [
"A keep as named (dialectTextMatchSql parallels jsonMembershipPredicate's caller-emitter shape)",
"B rename before ACCEPT"
],
"recommendation": "A, because each name says the construct it emits and the set mirrors #20987's precedent"
},
{
"question": "#16206 declared ACCEPTED_SQL_DIALECTS as canonical SqlDialectName values with no knex aliases; this PR adds 'mssql' (a canonical SqlDialectName, not an alias) and keeps 'oracle' out because it measured consistent. Is that the right reading of #16206?",
"options": [
"A yes: widening by a canonical name follows the SqlDialectName anchor",
"B no: the accept set needs a fresh ruling"
],
"recommendation": "A, because the ruling's constraint was 'canonical, no aliases', which 'mssql' meets"
}
],
"security_findings": "none",
"out_of_scope_findings": [
"class: b · reach: analytics native-SQL face on SQL Server emits 'LIMIT 9223372036854775807' / LIMIT n (as it did for unknown), which SQL Server does not parse · evidence: OFFSET_ONLY_LIMIT_SQL / limit clause in native-sql-strategy.ts · dedupe words: analytics mssql LIMIT OFFSET FETCH",
"class: b · reach: SUM over a boolean (bit) column on SQL Server: analytics aggregand policy treats mssql as unknown, driver has mssqlAggregandOperandSql · evidence: aggregandDialectOf in native-sql-strategy.ts · dedupe words: analytics mssql bit SUM aggregand",
"class: c · reach: analytics read-scope membership/empty refusal says 'dialect … is not known' for mssql, which is now a known dialect · dedupe words: analytics refusal message mssql not known",
"carrier: PR #31625 body · noted, not filed"
]
}
On SQL Server, a dashboard's text filter now matches the same rows as the list view: the analytics native SQL compiles $contains / $notContains / $startsWith / $endsWith / $icontains exactly as driver-sql does (binary collation, ASCII-only fold, [ matched literally).
The per-dialect text-match construct table lives once in @objectstack/core (dialectTextMatchSql and its helpers); driver-sql's SQL and bindings are unchanged. AnalyticsServiceConfig.sqlDialect accepts 'mssql'. Oracle measured consistent and left as is.
Activity
objectstack-fleet commentedon Nov 8, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit · p3 ·
domain:server· blocked · 2026-11-08T06:54Z⛔ Not a claim.
service-analytics' native-SQL face emits plainLIKE. The driver face honors drivers(sql family): 文本算子的大小写折叠是「方言的」而非「契约的」——$contains在 SQLite 过折叠、$icontains在 PG/MySQL 过折叠 #6518's case-exact vs case-folded split (BIN2), so dashboards match differently from lists.area:data.pm:blocked: the body carriesBlocked-by: #31327.findingremoved.Generated by Claude Code
objectstack-fleet commentedon Nov 8, 2026
domain:server#1 · os-steve · session_01ADHkmPF1skfu2kx89BEXZi
Unblocked · re-verified · 2026-11-08T16:05Z (idle chore ①,
execution-duties.md)Blocked-by:driver-sql: SQL Server as a federation dialect — an external datasource over Microsoft SQL Server reads (and, double opt-in, writes) live, with type-compat and the predicate emitters modelling mssql #31327 (2026-11-08T15:18Z) — read live now: closedcompleted. Epic [Decision] Ontology over external systems: virtual objects on ADR-0015 federation — two driver tiers (plugin code · declarative OpenAPI), pushdown/identity/catalog/cache rules, Studio and AI drafts (2026 ontology research + deep design) #27261, whose PM was this card's reader, is closed, so the card returns to the lane queue.origin/main645ed3d1:packages/services/service-analytics/src/text-match-sql.ts(the per-dialect construct table) has no mssql arm: mssql still takes theunknownarm, so the drivers(sql family): 文本算子的大小写折叠是「方言的」而非「契约的」——$contains在 SQLite 过折叠、$icontains在 PG/MySQL 过折叠 #6518 case contract the driver keeps is not mirrored there.pm:blocked→pm:queue. ⛔ Not a claim.objectstack-fleet commentedon Nov 8, 2026
domain:server#2 · os-steve · session_01ADHkmQKZzp4DLtqiCkZZRM
Claim: PM loop round 1 · 2026-11-08T16:17Z
Session:
session_01ADHkmTC6s4J4HjQ7nyUMSz(card thread, dev) · seatsession_01ADHkmQKZzp4DLtqiCkZZRMAccount:
os-steveBranch:
claude/project-thread-i27fm1Worktree:
objectstack-issue-31394Domain:
domain:serverSeat:
domain:server#2File surface:
packages/services/service-analytics/src/text-match-sql.ts(mssql/oracle arms), its callers only if the dialect name must flow differently, the cross-run drift suitestext-operator-case-exactness.test.ts/text-match-sqlite-nul.test.tsand a new mssql/oracle compile test, root.changeset/;packages/drivers/driver-sqlonly if a shared emitter is lifted inside the lane. ⛔ Nopackages/spec/**, noui/**Container & model: M,
mode:thread,model: default tier(dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
@objectstack/service-analyticsnative-SQL face (objectstack) maps mssql/oracle to theunknownarm instead of #6518's case contract | driver-sql's own text-match arms already keep the contract on the driver face | every dashboard text filter over a federated SQL Server (and possibly Oracle) objectThread-read: 6723770780
Premise: holds per seat 1's re-verification 6723770780 on
645ed3d1(no mssql arm intext-match-sql.ts); the dev measures red firstSerial constraints cleared: no open PR touches
packages/services/service-analytics/**(read at claim); epic siblings #31390 (driver-sql oracle bind) and #31389 (service-datasource catalog) are disjointScope: Fixes #31394, per #6518 (Ruling-ref). Order:
/mnt/project-files/server-seat2/standard-order.md+/mnt/project-files/server-seat2/31394-delta.md(the card's "reuse, don't copy" against the file's no-driver-dependency rule is the dev's four-axis call; a new package or spec export stops at needs_decision). Summons: the maintainer's 「并发都是5」 (project chat, 2026-11-08T16:13Z).objectstack-fleet commentedon Nov 8, 2026
domain:server#2 · os-steve · session_01ADHkmQKZzp4DLtqiCkZZRM
Claim amendment · 2026-11-08T16:21Z · #31394 · File surface and Clause-② (Branch
claude/project-thread-i27fm1, Metadata-protocol unchanged)The dev's route report chose option (b) of the delta: lift driver-sql's text-match construct table into
@objectstack/corewith caller-supplied emitters, the shapepackages/core/src/utils/json-membership-sql.tsalready has (re-exported from core's index atorigin/main; imported bydriver-sql/src/sql-driver-predicate-emitters.ts). No new package, no spec export. Seat accepts the route.File surface:
packages/core/src/utils/text-match-sql.ts(new) and its re-export inpackages/core/src/index.ts; driver-sql'stextMatchPredicateand service-analytics'textMatchPredicateSqlbecome thin adapters over it (each keeps its ownunknownresidue);packages/services/service-analytics/src/text-match-sql.tsand its dialect vocabulary; the cross-run drift suites and new compile tests; root.changeset/. ⛔ Nopackages/spec/**, noui/**.Clause-②: yes (widening) — new
@objectstack/coreexports, and the analytics dialect vocabulary widens tomssql/oracle(reachable through the exportedAnalyticsServiceConfig); the dev confirms from the real diff; the new public names go in open_questions for the seat's ruling at ACCEPTSerial constraints cleared: no open PR touches
packages/core/src/index.ts,packages/core/src/utils/**ordriver-sql/src/sql-driver.ts(read now). In-flight driver-sql siblings: #31395 (seat 1, mssql substring operators) and #31390 (seat 4, oracle bind); the dev keeps the driver-sql edit to the adapter, mergesmainafter either lands, and conflicts go to the merge queue.objectstack-fleet commentedon Nov 8, 2026
domain:server#2 · os-steve · session_01ADHkmTC6s4J4HjQ7nyUMSz
os-dev-report
{ "issue": 31394, "status": "done", "branch": "claude/project-thread-i27fm1", "pr": "https://github.com/objectstack-ai/objectstack/pull/31625", "session": "session_01ADHkmTC6s4J4HjQ7nyUMSz", "premise_still_valid": true, "summary": "Measured on main (5ee59f5e), compile-level: on SQL Server the analytics bridge read dialectName 'mssql' as no answer, so the native-SQL where, read scope and echo emitted a plain LIKE (CI default collation, '[' unescaped) where the driver emits the BIN2/TRANSLATE arms: 17/17 cells red. Oracle measured consistent (16/16 green: same LIKE for the case-exact four; translate vs REPLACE fold row-equivalent), so its arm is left as is. Route (b): the construct table moves to @objectstack/core (text-match-sql.ts, mirroring #20987 json-membership-sql); driver-sql's textMatchPredicate becomes a thin emitter adapter with identical SQL; analytics emits through it and accepts 'mssql' (every other per-dialect table treats mssql as it treated unknown).", "tests": "Red first on main: 17 mssql cells red, 16 oracle green. Head 833400e0 via os-verify-lock VERDICT command-exit 0: core text-match-sql.test.ts 3/3; analytics text-match-mssql-oracle + sql-dialect-vocabulary + text-operator-case-exactness 59 passed / 30 skipped; driver-sql full 245 files, 4113 passed / 222 skipped, identical with main's emitter file put back (4113/222). Pre-merge: analytics full 5098 passed / 330 skipped; core 3246 passed; closure typecheck clean. Ablation 1 (ACCEPTED_SQL_DIALECTS without 'mssql', ablation-replace): 17 failed, first '× the bridge hands the driver's mssql on'; restored blob == HEAD. Ablation 2 (core's mssql comparand escape without '[', core rebuilt, ablation-dist-preflight @objectstack/core found the marker in dist): analytics '[ is escaped on this dialect alone' failed (params '%a[b%' where '%a\\[b%' expected) and driver-sql sql-driver-mssql-dialect '$contains: both sides case-exact' failed (binding '%a\\%\\_[b%' where '%a\\%\\_\\[b%' expected); restored (blob == HEAD), rebuilt, preflight --absent ok, suite green 33 passed / 30 skipped. Live cells (OS_TEST_MSSQL_URL / OS_TEST_ORACLE_URL) NOT run: no URL in this container.", "gates": "dispatch-gates --commands at 833400e0: 74 commands run; --ran reconciliation 74 derived / 74 run / 0 NOT-MEASURED / 0 UNRUN, all exit 0. Three first exited on container prerequisites and were rerun after closing them: check-plugin-teardown-shape --self-test (exit 3 shallow clone -> fixture commit fetched -> 0), check:dts-closure (exit 1, analytics built without d.ts -> rebuilt -> 0), check:dual-build-cjs-loads (exit 3 no dist -> full pnpm build 119/119 -> 0). eslint on the 12 changed .ts files exit 0. check-platform-checklist --changed-from origin/main exit 0 (0 anchored). check-driver-conformance before/after: 66 covered, 6 DEBT, 0 exempt. CI check-runs not yet read (not waited on).", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm; the change is Clause-②: yes (widening)", "files_changed": [ ".changeset/31394-text-match-mssql-native-sql.md", "packages/core/src/index.ts", "packages/core/src/utils/text-match-sql.ts", "packages/core/src/utils/text-match-sql.test.ts", "packages/drivers/driver-sql/src/sql-driver-predicate-emitters.ts", "packages/services/service-analytics/src/text-match-sql.ts", "packages/services/service-analytics/src/like-pattern.ts", "packages/services/service-analytics/src/duration-measure-sql.ts", "packages/services/service-analytics/src/contains-membership-sql.ts", "packages/services/service-analytics/src/strategies/native-sql-strategy.ts", "packages/services/service-analytics/src/__tests__/text-match-mssql-oracle.test.ts", "packages/services/service-analytics/src/__tests__/text-operator-case-exactness.test.ts", "packages/services/service-analytics/src/__tests__/sql-dialect-vocabulary.test.ts" ], "line_budget": "src +575 / -851 (net -276); tests +470 / -20; changeset +14. 13 files.", "deviations": [ "core added to the file surface (claim amendment, route (b)).", "Forced test edits: sql-dialect-vocabulary.test.ts (accept set now 4 names; 'oracle' replaces 'mssql' as the not-accepted example); text-operator-case-exactness.test.ts (normalise pin names 'mssql'; GLOB-escape pin reads the bound param of compileScopedFilterToSql on sqlite instead of the removed private escapeGlobPattern/globPattern, expected values unchanged).", "Live cells not run (no URL)." ], "mcp_calls": "4 — mcp__github__issue_read x4 (reads only; no write tool)", "api_writes": "4 — POST /repos/objectstack-ai/objectstack/dispatches (relay fw-20261108T173011Z-c0723a, executed as POST /pulls -> #31625 and POST /issues/31625/assignees [os-steve]); POST /issues/31394/comments (this report, post-stamped). Branch pushes are git transport, not REST.", "open_questions": [ { "question": "New @objectstack/core export names (seat rules at ACCEPT): dialectTextMatchSql, TextMatchDialect, TextMatchShape, TextMatchEmitters, TextMatchRequest, textMatchLikePattern, TEXT_MATCH_ESCAPE_CHARACTER, ASCII_UPPER_LETTERS, ASCII_LOWER_LETTERS, mssqlCaseExactSql, mssqlAsciiLowerSql, mysqlAsciiLowerBinarySql.", "options": [ "A keep as named (dialectTextMatchSql parallels jsonMembershipPredicate's caller-emitter shape)", "B rename before ACCEPT" ], "recommendation": "A, because each name says the construct it emits and the set mirrors #20987's precedent" }, { "question": "#16206 declared ACCEPTED_SQL_DIALECTS as canonical SqlDialectName values with no knex aliases; this PR adds 'mssql' (a canonical SqlDialectName, not an alias) and keeps 'oracle' out because it measured consistent. Is that the right reading of #16206?", "options": [ "A yes: widening by a canonical name follows the SqlDialectName anchor", "B no: the accept set needs a fresh ruling" ], "recommendation": "A, because the ruling's constraint was 'canonical, no aliases', which 'mssql' meets" } ], "security_findings": "none", "out_of_scope_findings": [ "class: b · reach: analytics native-SQL face on SQL Server emits 'LIMIT 9223372036854775807' / LIMIT n (as it did for unknown), which SQL Server does not parse · evidence: OFFSET_ONLY_LIMIT_SQL / limit clause in native-sql-strategy.ts · dedupe words: analytics mssql LIMIT OFFSET FETCH", "class: b · reach: SUM over a boolean (bit) column on SQL Server: analytics aggregand policy treats mssql as unknown, driver has mssqlAggregandOperandSql · evidence: aggregandDialectOf in native-sql-strategy.ts · dedupe words: analytics mssql bit SUM aggregand", "class: c · reach: analytics read-scope membership/empty refusal says 'dialect … is not known' for mssql, which is now a known dialect · dedupe words: analytics refusal message mssql not known", "carrier: PR #31625 body · noted, not filed" ] }Generated by Claude Code
objectstack-fleet commentedon Nov 8, 2026
domain:server#2 · os-steve · session_01ADHkmQKZzp4DLtqiCkZZRM
ACCEPT → PR #31625 comment 6725121433 · head
759110f4· 2026-11-08T18:08Z · landing: pr_ready + automerge_enable (in the merge queue)objectstack-fleet commentedon Nov 8, 2026
domain:server#2 · os-steve · session_01ADHkmQKZzp4DLtqiCkZZRM
落地 · 2026-11-08T18:37Z
90457e74(ACCEPT 6725121433; contract review PASS 6725117216 at TIER_DEFAULT)Fixes #31394)Landed:
$contains/$notContains/$startsWith/$endsWith/$icontainsexactly asdriver-sqldoes (binary collation, ASCII-only fold,[matched literally).@objectstack/core(dialectTextMatchSqland its helpers); driver-sql's SQL and bindings are unchanged.AnalyticsServiceConfig.sqlDialectaccepts'mssql'. Oracle measured consistent and left as is.