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
Declarative "at most one row per parent where X" (conditional unique) — summary-based guards miss rows in the same bulk insert #25477
Ruled: 6377847361 · batch #9 item 4 · letter C · 2026-10-24T00:43:45Z (proposal 3: batch-aware summary, in-memory per batch; proposals 1 and 2 not now)
Context
hotsrm needs "each supplier has at most one primary contact" (srm_supplier_contact.is_primary). It must hold for UI edits and for the spreadsheet import, metadata only.
What we tried
indexes[].partial is retired, and a unique index on ['supplier', 'is_primary'] would also forbid two non-primary contacts.
A summary on the parent (primary_contact_count, count with filter: { is_primary: true }) plus a script rule on the child: record.is_primary == true && record.supplier.primary_contact_count > 0. This catches a second primary when the first already exists, but not two primary rows created in the same import batch: the import runner batches creates through createManyData / insertManyData, and the parent summary is not recomputed between the rows of one batch, so both rows pass.
Reproduction: import 供应商,姓名,邮箱,主联系人 with two rows for a new supplier, both 是 → both created, primary_contact_count = 2.
A declarative cross-row rule type (type: 'unique_where' or similar) that is judged per row inside bulk writes. (not chosen; ruling 6377847361)
At minimum: evaluate child script rules that read a parent summary against a summary that includes earlier rows of the same batch, or document that they do not.
Workaround in hotsrm (temporary)
The summary-based guard stays (it covers single writes and later imports), and a list view "主联系人重复" (primary_contact_count > 1) surfaces the batch case for manual repair during review.
Triage: decision-shaped (filing-gate ②: a feature / contract-shape proposal from a real app). Lands in packages/spec (object indexes or validation rules) and the engine's bulk-write path (createManyData / insertManyData). Marked needs-user-decision; not dispatchable until ruled.
Path: records · 写入规则在服务端兑现 | records-forms.field-unique-enforcement (P1, does not cover conditional uniqueness) — 缺项 | step ②
Type: Feature
推荐 C:不加新契约,让批量和逐条行为一致,hotsrm 现有的规则直接生效;A 受 MySQL 限制且要重开已退役的键。置信缺口:C 对大批量导入的性能代价未测,也不解决并发写入。问:A / B / C?
os-decision-facets
① 项目长远合理性:C 消除"批量与逐条结果不同"这个特例;A 重开已退役的键且方言不齐;B 新增一类规则。
② 实际业务拉动:hotsrm 实测(两行同批都标主联系人都通过);目前只有这一个应用在要。
③ 防 AI 犯错:C 下 AI 写的普通校验规则在批量导入里也成立,不会被静默绕过;A/B 要 AI 学新键。
④ 创业阶段不扩散:C 零新增键;A 重开一个键;B 新增一种规则类型。
Governing text: packages/spec/src/data/object.zod.ts docblock "type / partial were RETIRED at protocol 17 (#5248, #4943, ADR-0049)".
Prior rulings read: "partial index" → #5248 (maintainer chose remove over enforce, 2026-08-06; "comes back enforce-first"); ADR-0049, ADR-0078; thread: none.
Batch note: one of five import / automation proposals from hotsrm's trial import filed on 2026-10-23 (#25475, #25476, #25477, #25481, #25493); the earlier hotsrm platform evaluation is the decision card #25496. They can be ruled as one batch.
Session: session_01AkmasAfXt3cu83xGzkuKhe (objectstack triage, run on the maintainer's request in the project thread)
Closed 2026-10-24T01:38Z. Superseded by #25579 — the same card ("no declarative "at most one row per parent where X" (conditional unique)"), re-filed as objectstack-fleet[bot] with this body and these labels. This card was written off the fleet relay, under the maintainer's personal account, by a project-thread session through GitHub MCP, which pm-dispatch does not allow for content writes. The thread above stays here for reference; the queue continues on #25579.
Instruction: the maintainer 田騏, in the Objectstack project thread, 2026-10-24T01:19:49Z: 「我看到有一些使用个人账户而不是车队账户提交的issue,应该严格按照 pm-dispatch 的规则处理」
Session: session_018fnREjMeK9XQeHDwkJXKMW
Activity
objectstack-fleet commentedon Oct 23, 2026
Triage: decision-shaped (filing-gate ②: a feature / contract-shape proposal from a real app). Lands in
packages/spec(object indexes or validation rules) and the engine's bulk-write path (createManyData/insertManyData). Markedneeds-user-decision; not dispatchable until ruled.Path: records · 写入规则在服务端兑现 | records-forms.field-unique-enforcement (P1, does not cover conditional uniqueness) — 缺项 | step ②
Type: Feature
维护者速读
"每个供应商最多一个主联系人"这类规则,单条编辑能挡住,但一次批量导入里的两条主联系人会同时通过,因为批内不重算父级汇总。
where条件(SQL 部分索引,内存驱动模拟)。注意:indexes[].partial在协议 17 被退役(ADR-0049 enforce-or-remove:IndexSchema.type与IndexSchema.partial没有任何 DDL 消费者 #5248),当时的裁决是"真有需求时以 enforce-first 回来",而 MySQL 没有部分索引。unique_where),批量写入里逐行判定。推荐 C:不加新契约,让批量和逐条行为一致,hotsrm 现有的规则直接生效;A 受 MySQL 限制且要重开已退役的键。置信缺口:C 对大批量导入的性能代价未测,也不解决并发写入。问:A / B / C?
os-decision-facets
Governing text:
packages/spec/src/data/object.zod.tsdocblock "type/partialwere RETIRED at protocol 17 (#5248, #4943, ADR-0049)".Prior rulings read: "partial index" → #5248 (maintainer chose remove over enforce, 2026-08-06; "comes back enforce-first"); ADR-0049, ADR-0078; thread: none.
Batch note: one of five import / automation proposals from hotsrm's trial import filed on 2026-10-23 (#25475, #25476, #25477, #25481, #25493); the earlier hotsrm platform evaluation is the decision card #25496. They can be ruled as one batch.
Session:
session_01AkmasAfXt3cu83xGzkuKhe(objectstack triage, run on the maintainer's request in the project thread)Generated by Claude Code
os-elon-musk commentedon Oct 24, 2026
Ruling: batch #9 item 4 · letter C · maintainer 「#9 同意」 2026-10-24T00:43:45Z
C = 不加键:批量写入里,子表规则读父级汇总时把同批前面的行算进去(批量等于逐条)。实现须在内存里按批累计汇总(S),⛔ 不得每行回库重算;并发写不在范围,文档写明「批量等于逐条,并发不保证」。验收:本卡复现表的两行只建成一行,另一行报规则错误。A(条件唯一索引
where)的入口仍是 #5248 的 enforce-first 条件(每个驱动真执行才能上),等第二个应用或真实事故再开,记在卡上。工作量 engine S–M(server 车道)。标签
needs-user-decision→pm:queue;裁不派。简报:https://claude.ai/artifact/XKBVwFLq2V5nBTNy3enkbz(卡 4)。Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
Closed 2026-10-24T01:38Z. Superseded by #25579 — the same card ("no declarative "at most one row per parent where X" (conditional unique)"), re-filed as
objectstack-fleet[bot]with this body and these labels. This card was written off the fleet relay, under the maintainer's personal account, by a project-thread session through GitHub MCP, which pm-dispatch does not allow for content writes. The thread above stays here for reference; the queue continues on #25579.Instruction: the maintainer 田騏, in the Objectstack project thread, 2026-10-24T01:19:49Z: 「我看到有一些使用个人账户而不是车队账户提交的issue,应该严格按照 pm-dispatch 的规则处理」
Session:
session_018fnREjMeK9XQeHDwkJXKMW