Skip to content

feat(spec): field runtime value-shape contract — ADR-0104 phase 1 (D1) - #3429

Merged
os-zhuang merged 3 commits into
mainfrom
claude/field-value-shape-contract-1z4pil
Jul 24, 2026
Merged

feat(spec): field runtime value-shape contract — ADR-0104 phase 1 (D1)#3429
os-zhuang merged 3 commits into
mainfrom
claude/field-value-shape-contract-1z4pil

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

实施 ADR-0104(#3412 已合并)的 D4 阶段 1(D1):spec 拥有字段运行时值形状契约,四个消费方收敛,契约与 field-zoo oracle 互锁。

改动

新增:packages/spec/src/data/field-value.zod.ts(经 @objectstack/spec/data 导出)

  • 12 个语义类型集合:STRING_VALUE_TYPES / NUMERIC_VALUE_TYPES / BOOLEAN_VALUE_TYPES / CALENDAR_DATE_TYPES / INSTANT_TYPES / CLOCK_TIME_TYPES / SINGLE_OPTION_TYPES / MULTI_OPTION_TYPES / REFERENCE_VALUE_TYPES / FILE_REFERENCE_TYPES / STRUCTURED_JSON_TYPES / COMPUTED_VALUE_TYPES,以及共享的 MULTI_CAPABLE_TYPES + isMultiValueField(此前在 record-validator 和 import-coerce 各有一份手工拷贝)。
  • valueSchemaFor(field, 'stored' | 'expanded'):纯推导函数,给出每个字段类型的运行时值 Zod schema;stored/expanded 双形态把 lookup 的 $expand 原地替换多态显式命名。json 等开放类型是显式决定的开放,不再是没人检查的偶然。
  • 纯 schema/常量/推导,无运行时逻辑(Prime Directive ✨ Set up Copilot instructions #2);消费方负责按字段定义缓存。

「现实优先」处理三个死值 schema

  • CurrencyValueSchema@deprecated:currency 值在验证器、SQL 驱动、导入、field-zoo 全链路都是裸 number,{value,currency} 从未被消费。下个 spec major 移除。
  • LocationCoordinatesSchema@deprecated → 新 LocationValueSchema({lat,lng},即实际存储形态)。
  • AddressSchema正名采纳address 的值契约(AddressValueSchema)。

四个消费方收敛(各自删掉私有类型清单)

  • objectql record-validator.ts:集合与 isMultiValueField 改从 spec 导入;此前完全不校验的类型(单值 lookup/master_detail/user/tree、file 系、location/address/composite/repeater/record/vector)按契约做形状检查——warn-first(ADR-0104 R1/R2:违规仅告警放行,OS_DATA_VALUE_SHAPE_STRICT_ENABLED=1 提前开强制,后续 minor 再翻默认);update 路径去掉字段定义克隆,使按定义身份键控的 schema 缓存(WeakMap)能命中。
  • rest import-coerce.ts:六个本地集合全部改为 spec 派生(reference 作为非 authorable 的遗留别名保留为本地补充)。
  • driver-sql:JSON_COLUMN_TYPES / NUMERIC_SCALAR_TYPES 成员改由 spec 类集合派生 + 驱动内部别名(object/array/integer/int/float)。逐项核对与原清单成员完全一致,零行为变化。
  • qa/dogfood:field-zoo MATRIX 抽为 field-zoo.matrix.ts 伴生模块(沿用 authz-conformance 先例);新增 field-zoo-value-shape.test.ts —— 45 个写入向量必须能被 valueSchemaFor(stored) 解析,契约与 oracle 从此互锁,单元级、不启动 stack。

测试

  • spec 6834 ✓(含 field-value 新用例:类成员合法性/全覆盖/形状类互斥、各类型 stored 形态、expanded 形态、multiple 数组)
  • objectql 1039 ✓(含 warn-first / strict 双模式新用例)
  • rest 331 ✓ · driver-sql 284 ✓ · dogfood 契约-oracle 48

备注

  • changeset 已含(spec/objectql minor,rest/driver-sql patch),弃用项带 FROM→TO 迁移说明。
  • verify 只读探针扩展到全矩阵与 ADR 性能基准门属阶段 1 的后续小项,未阻塞本 PR(field-zoo HTTP 往返已覆盖端到端)。
  • D2(typed action handlers)与 D3(file-as-reference)按 ADR-0104 D4 分阶段另行实施。

🤖 Generated with Claude Code

https://claude.ai/code/session_01SHpGw3GBA9aFpfwVArRWfd


Generated by Claude Code

Spec now owns the runtime value shape of every field type
(data/field-value.zod.ts): semantic type classes, the shared
isMultiValueField, and valueSchemaFor(field, 'stored' | 'expanded').
Consumers converged (each loses its private hand-copied type lists):
- objectql record-validator: derives from spec; previously-opaque types
(single references, file-likes, location/address/composite/repeater/
record/vector) get warn-first shape checks (strict via
OS_DATA_VALUE_SHAPE_STRICT_ENABLED=1); update path no longer clones
field defs so the per-def schema cache hits.
- rest import-coerce: six local sets → spec-derived.
- driver-sql: JSON_COLUMN_TYPES / NUMERIC_SCALAR_TYPES membership now
spec-derived (+ driver-internal aliases).
- qa/dogfood: field-zoo MATRIX extracted to field-zoo.matrix.ts; new
field-zoo-value-shape.test.ts pins contract ⇔ oracle (45 vectors).
Deprecated (removal rides next spec major; FROM→TO in changeset):
CurrencyValueSchema (currency IS a bare number), LocationCoordinatesSchema
(stored shape is {lat, lng} → LocationValueSchema). AddressSchema adopted
as the enforced address value contract.
Tests: spec 6834, objectql 1039, rest 331, driver-sql 284, dogfood
value-shape 45 — all green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SHpGw3GBA9aFpfwVArRWfd
@vercel

vercelBot commented Jul 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJul 24, 2026 11:45am

Request Review

@github-actionsgithub-actionsBot added size/l documentation Improvements or additions to documentation protocol:data tests tooling and removed size/l labels Jul 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 5 package(s): @objectstack/objectql, @objectstack/driver-sql, packages/qa, @objectstack/rest, @objectstack/spec.

111 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx(via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx(via @objectstack/spec)
  • content/docs/ai/skills.mdx(via @objectstack/spec)
  • content/docs/api/client-sdk.mdx(via @objectstack/spec)
  • content/docs/api/environment-routing.mdx(via @objectstack/spec)
  • content/docs/api/error-catalog.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/api/error-handling-client.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/api/index.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/automation/approvals.mdx(via packages/spec)
  • content/docs/automation/flows.mdx(via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx(via packages/spec)
  • content/docs/automation/hooks.mdx(via @objectstack/spec)
  • content/docs/automation/index.mdx(via @objectstack/spec)
  • content/docs/automation/webhooks.mdx(via @objectstack/spec)
  • content/docs/automation/workflows.mdx(via @objectstack/spec)
  • content/docs/concepts/architecture.mdx(via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx(via packages/spec)
  • content/docs/concepts/index.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx(via @objectstack/objectql, packages/spec)
  • content/docs/concepts/north-star.mdx(via packages/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/driver-sql, @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx(via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx(via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx(via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx(via packages/objectql, @objectstack/spec)
  • content/docs/data-modeling/index.mdx(via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx(via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx(via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx(via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx(via @objectstack/spec)
  • content/docs/deployment/migration-from-objectql.mdx(via @objectstack/objectql)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/deployment/vercel.mdx(via @objectstack/objectql)
  • content/docs/getting-started/build-with-claude-code.mdx(via @objectstack/spec)
  • content/docs/getting-started/cli.mdx(via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx(via @objectstack/spec)
  • content/docs/getting-started/examples.mdx(via @objectstack/spec)
  • content/docs/getting-started/glossary.mdx(via @objectstack/driver-sql)
  • content/docs/getting-started/quick-reference.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx(via @objectstack/spec)
  • content/docs/getting-started/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx(via @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx(via packages/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via packages/spec)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/objectql, @objectstack/spec)
  • content/docs/kernel/services.mdx(via @objectstack/objectql)
  • content/docs/permissions/authentication.mdx(via @objectstack/objectql)
  • content/docs/permissions/authorization.mdx(via packages/qa, @objectstack/spec)
  • content/docs/permissions/delegated-administration.mdx(via packages/qa)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @objectstack/spec)
  • content/docs/permissions/positions.mdx(via @objectstack/spec)
  • content/docs/permissions/rls.mdx(via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx(via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx(via @objectstack/spec)
  • content/docs/plugins/anatomy.mdx(via @objectstack/driver-sql)
  • content/docs/plugins/development.mdx(via @objectstack/spec)
  • content/docs/plugins/index.mdx(via @objectstack/objectql, @objectstack/rest, @objectstack/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/objectql, @objectstack/driver-sql, @objectstack/rest, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx(via @objectstack/spec)
  • content/docs/protocol/diagram.mdx(via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx(via packages/rest, @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/objectql, @objectstack/driver-sql, @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/driver-sql, @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.mdx(via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx(via @objectstack/driver-sql, @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx(via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/objectql, @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx(via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx(via @objectstack/objectql, @objectstack/driver-sql, @objectstack/rest, @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v12.mdx(via @objectstack/rest, @objectstack/spec)
  • content/docs/releases/v13.mdx(via @objectstack/spec)
  • content/docs/releases/v16.mdx(via @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/objectql, @objectstack/spec)
  • content/docs/ui/actions.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @objectstack/spec)
  • content/docs/ui/forms.mdx(via @objectstack/spec)
  • content/docs/ui/index.mdx(via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx(via @objectstack/spec)
  • content/docs/ui/setup-app.mdx(via @objectstack/spec)
  • content/docs/ui/translations.mdx(via @objectstack/spec)
  • content/docs/ui/views.mdx(via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

…orts
24 additive exports (semantic type classes, isMultiValueField,
valueSchemaFor, value schemas), 0 breaking.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SHpGw3GBA9aFpfwVArRWfd
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:datasize/xlteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-zhuang@claude