Repository navigation
datasource.config 至今无人校验:驱动 configSchema 是声明但完全惰性的(ADR-0049 enforce-or-remove,#4001 收尾发现) #4410
Description
Activity
先回答那个前置问题:前端确实在读一个驱动的
configSchema——但不是这个issue 里提的"需要先确认前端是否真的在读它,否则可能是第三处虚假声明",答案是:不是第三处虚假声明,是一处重复声明。
objectui的DatasourceResourcePage.tsx(packages/app-shell/src/views/metadata-admin/datasource/)会GET /api/v1/datasources/drivers,然后用返回的configSchema.properties渲染连接表单——title作标签、description作说明、default作初值、format: 'password'走密码控件、enum走下拉,configSchema.required决定必填星号。JSDoc 那句 "Used by the UI to generate the connection form" 是真的。但它读的是
service-datasource/driver-catalog.ts里的DRIVER_CATALOG——另一套手写的 JSON-Schema 字面量,和packages/spec的 per-driver zod schema 各写各的,互不校验,两边都不做验证。所以DriverDefinitionSchema.configSchema确实是死的,只是它旁边还躺着一份活的副本。一活一死,中间没有任何东西对得上。处置:enforce
按 issue 倾向的方向做了。
packages/spec/src/data/driver/成为唯一契约,三个消费者读它:DatasourceSchema解析config(以及每个readReplicas条目)、DriverDefinitionSchema.configSchema发布它的 JSON-Schema 投影、连接表单渲染同一份投影。mysql和sqlite/sqlite-wasm此前根本没有 config 形状,尽管表单在提供、工厂能构建。第二道作者入口也补上了:Setup 向导走
metadata.register(只做name/label结构检查,不是 zod parse),所以它绕开了DatasourceSchema。DatasourceAdminService的 create/update/test 现在查同一个 registry——testConnection在探测之前校验,否则向导会对着 localhost 报一个绿色的"连接成功"。装门禁反过来逼出的东西
config一旦有门禁,里面每个键就都在声称自己被读。于是逐个对着读它的代码核了一遍,结果又是一批"声明了但没人读",这次是接上而不是放行:datasource.pool—— 声明过、strict、还被带进了 connection spec,然后被工厂硬编码的{min:0,max:5}覆盖掉。datasource.schemaMode—— 在 record → spec 之间被丢掉,工厂只好去两个永远不可能有它的地方找。结果是schemaMode: 'external'的库被当作managed构建,驱动层的 DDL 闸门是开的。datasource.ssl—— 同样停在 record,带 CA 证书的 TLS 块什么也没配上;这正是它自己 schema 注释里警告的失效模式。- mongo
password—— 被忽略,所以带config.password的 mongo 数据源是用空密码拼 URL 的。
indexes/maxRecordsPerObject(memory)没有可接的地方——InMemoryDriverConfig没有这两个字段,驱动不建索引也不淘汰——按 ADR-0049 移除,拒绝信息里带上原因。一处中途改回的设计
config.ssl我最初建模成boolean | {ca,cert,key},对客户端接受的形状是诚实的。后来读 objectui 的renderField发现:不是 boolean/enum/number 的属性一律渲染成文本输入框——那样向导会写出一个字符串,而新门禁恰好拒绝它,等于造出一个存不进去的表单。所以config.ssl收敛成开关简写,证书走数据源级ssl块(也就是这次刚接上的那个)。分支
claude/datasource-config-validation-i7wdmo已推送。pnpm test132/132、pnpm typecheck122/122、pnpm lint全绿,spec 的 8 个生成物 gate 全部 up to date,严格性账本的driver/行已从"blocked on #4410"改成 strict。工厂里剩下的 4 处未声明
??容错(file/uri/user/connectionString)没有顺手删——删了会静默改变已持久化记录的数据位置,正确路径是 ADR-0087 转换条目,已单独开 #4456 跟踪。
Generated by Claude Code
- added a commit that references this issue
on Aug 1, 2026 - added 3 commits that reference this issue
on Aug 2, 2026
从 #4001 的收尾核查中发现。#4207 把
DatasourceSchema顶层收紧成.strict()时,把config作为「逃生口」留开,理由写在data/datasource.zod.ts的模块注释里:这句话是假的。 它在两个独立的层面上都不成立。
证据
没有东西去填它。
DriverDefinitionSchema.configSchema声明为z.record(z.string(), z.unknown())(data/datasource.zod.ts:284),而仓库里仅有的两个驱动定义都把它设成空对象:data/driver/memory.zod.ts:279—configSchema: {}data/driver/mongo.zod.ts:67—configSchema: {}, // Will be populated with JSON Schema version of MongoConfigSchema at runtime那句注释承诺的 "at runtime" 填充不存在。
没有东西去读它。 全仓 grep
configSchema的命中全部属于 automation 的流程节点 descriptor(那个是活的,两回事)。驱动的configSchema在本仓没有任何读取点。四个驱动插件(driver-memory/driver-mongodb/driver-sql/driver-sqlite-wasm)也都没有拿任何 schema 去 parse 自己的 config。对应的 zod schema 存在,但接在空气上。
PostgresConfigSchema/MongoConfigSchema/MemoryConfigSchema都在data/driver/里写得很完整(连接串、host、port、pool、ssl…),是纯导出,没有任何消费者。为什么这个比一般的「声明未执行」更值得修
因为 #4001 的修复主动把作者指引到这个洞里。
belongsInConfig给出的处方原文是:于是一个把
host写在顶层的作者——那是现在会报错的位置——被平台以权威口吻,指引到一个同样的拼写错误重新变得静默的槽里。这正是 #4001 要消灭的失效模式,由 #4001 自己的修复重现了一次。具体后果举例:
config: { hostname: 'db.internal' }(正确的键是host)今天完全静默——z.record收下它,驱动读不到host,于是连到 localhost 默认值上。这与 #4001 描述的原始 bug 逐字同构,只是低了一层。对 AI 作者尤其糟糕:它拿到成功响应,报告「数据源已配置」。
处置
#<PR>已经先做了止血——把那句假承诺删掉,改成指向 per-driver schema 的诚实措辞,并把data/driver/三个文件补进 #4001 的严格性账本。但那只是不再撒谎,洞还在。本 issue 追踪真正的二选一(ADR-0049 enforce-or-remove):
configSchema真的生效:驱动注册时用自己的 zod schema(或其 JSON Schema 投影)parsedatasource.config,未知键按 未知键静默剥离仍是全仓默认:把 #3405 的 strict 收紧从一个 schema 推广到整个可授权面(ADR-0078 完整性闸门) #4001 的标准配可修错误信息拒绝。注意这条要先回答一个问题:configSchema的 JSDoc 说它 "Used by the UI to generate the connection form" —— 那是../objectui,本仓看不到,需要先确认前端是否真的在读它,否则可能是第三处虚假声明。configSchema字段和三个*ConfigSchema导出都属于 ADR-0049 的「声明但不执行」,应当按spec-property-retirement走退役流程,而不是继续摆在那里让人以为它管用。倾向 enforce:三个 schema 已经写好了,
datasource是注册元数据类型,而 config 是唯一一个作者会写、却在收紧之后仍然完全无校验的槽。参考
docs/audits/2026-07-unknown-key-strictness-ledger.md