Repository navigation
A MISSPELLED format name in a json_schema validation rule still enforces nothing — format: 'emial' is logged-and-dropped, at runtime AND at publish #5178
Description
Found while implementing #5029 (PR pending) — filed unassigned, deliberately not fixed there. #5029's ruling was "register ajv-formats so format is enforced"; this is the residual half that registration does not close, and #5029 pins the current behaviour by test rather than changing it.
What is still unenforced
After #5029 the runtime's shared ajv is new Ajv({ allErrors: true, strict: false }) + addFormats(ajv), so format: 'email' now really rejects not-an-email. But strict: false is also what makes an unrecognised format name a non-event: ajv logs one line at compile time and drops the keyword.
Reproduced with the repo's own ajv + ajv-formats and the runtime's own options:
$ node -e "const Ajv=require('ajv'); const addFormats=require('ajv-formats');
const ajv=new Ajv({allErrors:true,strict:false}); addFormats(ajv);
const v=ajv.compile({type:'object',properties:{e:{type:'string',format:'emial'}}});
console.log('validates {e: zzz} =', v({e:'zzz'}));"
unknown format "emial" ignored in schema at path "#/properties/e"
validates {e: zzz} = true
So an author who types emial, e-mail, uri-reference (real) vs urireference (not), datetime vs date-time, ipv_4, … gets a rule that is declared, appears in the metadata, runs on every write, enforces type / required — and enforces nothing for the keyword they actually wrote. Same declared-but-not-enforced shape as #5029 itself, with the trigger moved from "we forgot the plugin" to "the author made a typo".
Why the #4762 publish gate does not catch it either
packages/lint/src/validate-rule-compilability.ts compiles each json_schema rule with the same ajv environment the runtime uses — deliberately, and #5029 extended that parity to the ajv-formats registration. A schema whose format name the runtime silently drops is therefore a schema the gate also compiles happily. That is correct for that gate (a gate inventing a verdict the runtime does not share is the strict: true mistake in a different hat), and it is why this needs its own decision rather than a tweak there.
Why this is worth a decision rather than a shrug
A misspelling is the single most likely authoring mistake in a hand-written or AI-generated JSON Schema, and it is invisible: nothing in the metadata, the UI, or a test run says the constraint is inert. The failure is also silent in the direction that matters — the record is accepted. And it is decidable statically: the set of registered format names is knowable from the metadata alone, with no record in hand, which is exactly the property #4762 used to argue for an authoring-time gate.
Options
- New publish-gate rule (
validation-rule-json-schema-unknown-format): the gate walks the schema, collects everyformatvalue, and errors on any name not in the registeredajv-formatsset — naming the rule, the object, the JSON pointer, and the nearest match. Keeps the runtime untouched, keeps runtime/gate compile parity intact (this is a separate judgement layered on top, not a different compile), and rejects before deployment. Cost: the gate must enumerate the registered format set, which couples it to the plugin version. strict: 'log'→ throw on unknown format in the runtime. ajv'sstrictSchema/validateFormatsknobs can make an unknown format a compile error. Rejects the same class, but at runtime and fail-open (the rule is skipped and logged, percheckJsonSchema), i.e. it converts one silent gap into another — andstrict: falseis load-bearing for vendor keywords, so this must not be done by loosening that dial globally.- Do nothing but document it (the status quo A
json_schemavalidation rule'sformatkeyword is silently IGNORED — ajv runs withoutajv-formats, soformat: 'email'enforces nothing #5029 pinned).
Acceptance sketch
- A
json_schemarule carryingformat: 'emial'is refused at publish time (option 1), naming the offending pointer and suggestingemail. - A rule carrying every legitimate registered format stays green — the gate must not turn working metadata red.
- The runtime/gate compile-parity test from A
formatrule with an invalid regex, and ajson_schemarule ajv cannot compile, still fail OPEN — the same trap #4649 closed, one rule type over #4762/Ajson_schemavalidation rule'sformatkeyword is silently IGNORED — ajv runs withoutajv-formats, soformat: 'email'enforces nothing #5029 still passes unchanged: whatever this adds is a judgement beside the compile, not a divergent compile.
Blocked-by: #5029(已解除:#5029 于 2026-08-04 关闭,ajv-formats 已注册,registered format set 已良定义)
Blocked-by: #5417(已解除:#5417 → PR #5455 于 2026-08-05 13:0xZ MERGED,packages/lint 文件面释放)
Activity
os-zhuang commentedon Aug 4, 2026
分诊(engine/services 车道 PM,会话
session_01Pbu27iNUfQCHeuS551Rqo7):落点判定domain:devx—— 三个选项里可取的方案 1 是packages/lint的新门禁规则(validation-rule-json-schema-unknown-format),按锚定规则归 devx 车道;打pm:queue经队列标签移交,labeling ≠ claiming,本会话不认领。给接手 PM 的两条:
Blocked-by: #5029(正文已写)按「PR fix(objectql,lint)!:json_schema规则的format关键字真正生效 —— 注册 ajv-formats (#5029) #5182 合入 main」为解除判据 —— 注册的 format 集在那之前不成立;fix(objectql,lint)!:json_schema规则的format关键字真正生效 —— 注册 ajv-formats (#5029) #5182 已验收、等 CI 绿入队。json_schema规则的format关键字真正生效 —— 注册 ajv-formats (#5029) #5182 的 parity 测试形状下可控 —— 从运行时源读注册这条先例可沿用。Generated by Claude Code
fix(objectql,lint)!: `json_schema` 规则的 `format` 关键字真正生效(注册 ajv-format…
os-zhuang commentedon Aug 5, 2026
分诊更新(devx 车道 PM,
session_01GX3sL71LFq8m2usg6VqTSE,2026-08-05):Blocked-by: #5029已解除(该单 08-04 关闭,runtime 已注册ajv-formats)。Blocked-by: #5417:本单方案 1 的新规则与 lint: a form section with alabelbut nonamecan never be translated and nothing warns — 70/70 HotCRM form sections are in that state #5417(在飞,lint 无名 section 规则)同落packages/lint、共享规则注册面,按同文件跨轮串行;lint: a form section with alabelbut nonamecan never be translated and nothing warns — 70/70 HotCRM form sections are in that state #5417 落地后本单回队。formatrule with an invalid regex, and ajson_schemarule ajv cannot compile, still fail OPEN — the same trap #4649 closed, one rule type over #4762 论证过的 authoring-time gate 性质;方案 3 保留静默缺口,出局。format 集与插件版本耦合的成本,用「从运行时同一注册路径枚举」而非硬编码清单来消化,派发时写明。Generated by Claude Code
os-zhuang commentedon Aug 5, 2026
认领:PM 循环第 3 轮(devx 车道)
会话:
session_01GX3sL71LFq8m2usg6VqTSE分支:
claude/issue-5178-unknown-format-gateWorktree:
objectstack-issue-5178域:
domain:devx文件面:
packages/lint/src/**(新规则validation-rule-json-schema-unknown-format+ 注册面 + 测试)—— #5417/PR #5455 已 MERGED,该包文件面已释放;基于合并后的packages/lint工作(它刚收进一条新规则,注册面有位移)方向按 08-05 裁定执行:方案 1(publish-gate 规则,拒于发布时);format 集从运行时同一注册路径枚举,不硬编码清单。
Generated by Claude Code
os-zhuang commentedon Aug 5, 2026
验收(devx 车道 PM,
session_01GX3sL71LFq8m2usg6VqTSE,2026-08-05):ACCEPT → PR #5490,转 ready 并挂 auto-merge。json_schemavalidation rule'sformatkeyword is silently IGNORED — ajv runs withoutajv-formats, soformat: 'email'enforces nothing #5029 原钉断言逐字节未动。obj.validations ?? obj.validationRules别名读法(#5017 全包 grep 的第八处,第三个文件) #5096 元测试的真红按其设计显式修复(PLUMBING + 理由)。formatrule with an invalid regex, and ajson_schemarule ajv cannot compile, still fail OPEN — the same trap #4649 closed, one rule type over #4762 留给维护者的问题;CLI_ONLY/P2 边界已是 [runtime/metadata] 作者时规则只存在于 CLI:Studio/REST/MCP 的运行时授权面是第四扇门,26 条规则一条不跑——#4409 修完后最大的敞口 #4463 在案数据)判断正确。Generated by Claude Code
feat(lint): refuse a MISSPELLED `format` in a `json_schema` validatio…
docs(validating-metadata): the four-door table records the object run…