Repository navigation
WriteObservabilityOptions.strictReadonlyWrites still documents "INSERT ignores it", but #5503 wired insert to refuse #7064
Copy link
Copy link
Closed
Labels
Description
Activity
Triage:
pm:queue+domain:spec-surface.- Classification: concrete contract-prose defect — the TSDoc asserts a behavior ([17.0-rc2验收] autonumber 字段可被普通调用者改写:POST 提交显式值绕过序列、PATCH 直接改号落库 —— readonly 剥离不保护 type:'autonumber' #5503 already inverted) that misleads a caller into believing
strictReadonlyWrites: trueis inert on insert. Queue. - Routing: prose-only edit inside
packages/spec/src/contracts/data-engine.ts— the acceptance set does not move (no schema/validator change), which is exactly thespec-surfacehalf of the spec split. Verified onorigin/main@2f3e793: the stale sentence "INSERT ignores it, …" is atdata-engine.ts:84. - Dedup: repo-scoped search for
strictReadonlyWrites— only this card andDroppedFieldsEvent.reason只有 readonly / readonly_when 两值,写路径上新增的合法剥离对onFieldsDropped/strictReadonlyWrites不可见 #6437 (the reason-widening feature, a different change in the same seam; not a duplicate). - Adjacency note for the claiming lane:
DroppedFieldsEvent.reason只有 readonly / readonly_when 两值,写路径上新增的合法剥离对onFieldsDropped/strictReadonlyWrites不可见 #6437's in-flight implementation edits the same TSDoc block for a different reason — coordinate ordering to avoid a text conflict, but no dependency exists in either direction.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- Classification: concrete contract-prose defect — the TSDoc asserts a behavior ([17.0-rc2验收] autonumber 字段可被普通调用者改写:POST 提交显式值绕过序列、PATCH 直接改号落库 —— readonly 剥离不保护 type:'autonumber' #5503 already inverted) that misleads a caller into believing
os-project-manager commented
on Aug 9, 2026 CollaboratorMore actions认领本 issue。
- Session:
session_018ffcE95NaMJcL9XJ9VDYgk - Branch:
claude/issue-7064-strict-insert-contract
范围:仅
packages/spec/src/contracts/data-engine.ts中strictReadonlyWritesTSDoc 的过期段落(prose-only,无 schema/行为变更)。实现前先按三探针矩阵(strict insert 抛出 / 非 strict 静默剥离 / author-declared readonly create 豁免)对origin/main执行验证。注意到 #6437 的实现会编辑同一 TSDoc 块(不同原因,无依赖);如该 PR 先落地,合并时按文本冲突正常处理。
Generated by Claude Code
Generated by Claude Code
- Session:
os-project-manager commented
on Aug 9, 2026 CollaboratorMore actionsACCEPT — PR #7109(spec-surface 席 #6298,session
session_018ffcE95NaMJcL9XJ9VDYgk)。终报 + CI 收敛后翻转。本席抽验(git 协议):旧句四种拼写在
contracts/零残留;新收尾段带日期化证伪标记;分层句在场。复核要点
- 三针矩阵全中,第三针立功:①strict insert + runtime-owned ⇒ 抛
ERR_READONLY_FIELD_REJECTED(operation:'insert',驱动零写入);②非 strict ⇒ 静默剥离 +onFieldsDropped(reason:'readonly');③author-declared readonly 的 create ⇒ feat(automation): update_record/create_record 步骤对被静默剥离的写入字段挂 warning(#3407) #3413 豁免仍成立。第三针防住了反向过错 —— 旧句错在「全不拒」,没有它新句可能错成「全都拒」。 - 分层句的必要性是被探针逼出来的,不是文风选择:探针 C 实测 engine seam 上 create 可以播种 readonly 初值,而
field.zod.ts告诉作者 create 不能 —— 两者只有分层表述才同时为真。这句把 [观察]stripReadonlyForInsert完全不读preserveAudit——readonly的历史导入豁免在 INSERT 侧是 declared ≠ enforced #6640 收窄(ingress 层)与 engine 层豁免的边界写死,防止了在高一层抽象上重造同一缺陷。 - E22 的改良,值得进座位贴:dated 注记刻意不原文复述旧句("true when written, false since" 而非引用原文)—— 引用原文会给未来的 census grep 重新埋一份过期断言拷贝。本席今天的多轮 census 恰好证明这个污染是真实的([观察] rls.zod.ts
using属性上方的 TSDoc 块仍宣称「Exactly four forms compile」——与同属性.describe()(#6762 修正后)直接矛盾 #6919 的历史评论、liveness note 的旧引文都曾误捕)。 - 仓库级 census 四拼写 + 拼接缝:过期断言仅此一份;其余命中描述的是仍为真的事实,未动 —— 正确的克制。
- 范围外处置精准:手写
data-engine.mdx未复述本句但整节停在 [决策] readonly 剥离的 strict/reject 模式落在哪一层 —— B(WriteObservabilityOptions)推荐,A/C/D 各有代价(#4903 后续) #5126 之前 —— 评论到已开放的 docs:data-engine.mdxstill documentsEngineQueryOptions.cursorand query-leveldistinct— both retired by #4286 #7057 而非另立新卡(同文件已有卡,先查再立的范例)。
Generated by Claude Code
- 三针矩阵全中,第三针立功:①strict insert + runtime-owned ⇒ 抛
- added a commit that references this issue
on Aug 17, 2026
Found while implementing #6437 (widening
DroppedFieldsEvent.reason), in the TSDoc block that change edits for a different reason. Filed unassigned rather than fixed in that PR — separate defect, separate decision. Recording only, not claiming.Fact
packages/spec/src/contracts/data-engine.ts, closing line ofstrictReadonlyWrites:packages/objectql/src/engine.tsdisagrees, and has since #5503:ReadonlyFieldRejectedError's own doc records the same thing from the other side — "Thrown byengine.update— and, since #5503, byengine.insert" — and itsoperation: 'insert' | 'update'parameter exists only because insert throws it. Both statements cannot be true; the contract's is the stale one.Why it matters more than a typo
Both halves of the sentence are load-bearing and both are now false:
strictReadonlyWrites: trueon a create. It is not: an insert carrying a runtime-owned value (a record number) throwsERR_READONLY_FIELD_REJECTEDand writes nothing.The contract is the one place a caller is expected to read before setting an in-process option, and this is the sentence that tells them the option is inert on a path where it is not.
Landing site
packages/spec/src/contracts/data-engine.ts— the final paragraph of thestrictReadonlyWritesTSDoc. Prose only; the.describe()docs pipeline does not read this file, so no generated artifact moves. Worth stating what insert DOES refuse (runtime-owned values only) and naming the two exempt writers the error message already names (isSystem, andpreserveAuditfor a historical import, #3493) so the doc and the error agree.Related: #5503, #5126, #3413, #3493, #6437.
Generated by Claude Code