Skip to content

Commit b8f4acc

Browse files
feat(spec)!: retire the never-consumed CurrencyValueSchema / CurrencyValue export (ADR-0104 D1) (#27233)
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} --> _Requested by **Yibo Wang** · [project thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwBKtW8fybSYYTNn9GAARes3G)_ Fixes #27182 Ruling-ref: 6465431966 Claim: 6467480691 Clause-②: no (narrowing) Metadata-protocol: narrowed Skills-docs: none — REASON: no authoring surface. `git grep CurrencyValue -- skills` on base finds only the generated `skills/*/references/_index.md` export lists (regenerated here by `gen:skill-refs`, which now name `UniqueScopeSchema` in its place); no rule, example or table teaches the shape. ## 维护者速读 - **改了什么:** 删除 `field.zod.ts` 仍导出的 `CurrencyValueSchema` 与 `CurrencyValue` 类型;登记 `RETIRED_DEFS_BY_MAJOR[18]` 的 `data/CurrencyValue` 与 D3 语义条目 `currency-value-schema-retired`(FROM `{value, currency}` → 裸数字,币种写在 `currencyConfig.defaultCurrency`)。 - **为什么改:** ADR-0104 D1 早已裁定删除,18.2.0 仍导出;多币种史诗 #8345 开工前必须清掉,免得作者把它当成「记录币种」的形状。 - **风险与回滚:** 零读者(只剩自身测试和生成基线),运行时行为不变;只影响 TypeScript 导入(TS2305)。回滚 = revert 本 PR。 - **先看:** `packages/spec/src/migrations/entries/semantic/18.currency-value-schema-retired.ts`、`packages/spec/src/data/currency-value-retirement.test.ts`。 - **两分钟验证:** `git grep -n CurrencyValueSchema -- packages ':!**/CHANGELOG.md'` → 只剩登记条目、退役 pin 和散文;`pnpm --filter @objectstack/spec exec vitest run --project repo src/data/currency-value-retirement.test.ts` 全绿。 - **需要您做的:** 本 PR 触及 Tier H(`docs/adr/0104`、生成的 `skills/*/references/_index.md`),按治理需 os-zhuang 或 hotlong 的批准,之后由席位落地。 ## What changes - **Spec (`@objectstack/spec`, minor, BREAKING for TypeScript imports only).** `CurrencyValueSchema` and `export type CurrencyValue` are deleted from `packages/spec/src/data/field.zod.ts`. Route 3 of the `spec-property-retirement` kit (the `ApiKeySchema` and document-family precedent): no carrier key and no metadata type ever held the shape, so there is no `retiredKey()` tombstone, no `UNKNOWN_KEY_GUIDANCE` entry and no D2 conversion. - **ADR-0087: registered.** `retired-defs/18.data__CurrencyValue.ts` and the D3 semantic entry `semantic/18.currency-value-schema-retired.ts`, which carries the card's note: a currency value is a bare number (`{ value: 1000.5, currency: 'USD' }` → `1000.5`), the code is `currencyConfig: { currencyMode: 'fixed', defaultCurrency: 'USD' }`, and `valueSchemaFor(field, 'stored')` types a value. No `STEP18_RATIONALE` fragment (the `identity-api-key-schema-retired` precedent has none). - **Generated.** `json-schema.manifest/data.json` loses `data/CurrencyValue` and `authorable-surface/data.json` its two rows (both deliberate, as the build's manifest and gate (a) deletion checks require); `api-surface`, `export-origins`, `declaration-map`, the reference docs, the strictness-ledger counts (`data/` 165 → 164 sites, `field.zod.ts` 14 → 13) and `skills/*/references/_index.md` regenerated by `check:generated --fix`. `authorable-surface.base.json` (the released anchor) is untouched. - **Liveness / ledger.** `CurrencyValue` never had a liveness-ledger row (never walked). The strictness-ledger `field.zod.ts` row is re-graded with a dated note: `CurrencyValueSchema` deleted, `LocationCoordinatesSchema` the one site left under the existing verdict; the #8562 follow-up line now says one. - **ADR-0104 (Tier H).** A dated note under the "Reality wins" paragraph: the deletion landed in this PR, and where the FROM → TO note lives. - **Pins that move.** `field.test.ts` drops its `CurrencyValueSchema` block; `type-alias-convention.pin.test.ts` drops `Iso_data_field__CurrencyValueSchema` and its census goes 798 → 797 (title, header, `toHaveLength` with the history line). The `field-value.zod.ts` docblock now says the object shape is deleted. - **New pin** `packages/spec/src/data/currency-value-retirement.test.ts` (added to `vitest.repo-tests.json`): the def and D3 entry are registered; the export is gone from `/data` and the root entry, `CurrencyConfigSchema` survives (lit control); `valueSchemaFor({ type: 'currency' })` accepts `1000.5` and refuses `{ value, currency }`; tree-scoped absence over the declared radius with an anti-vacuity matcher test. ## Why ADR-0104 D1 decided "`currency` is a scalar number — `CurrencyValueSchema` is deleted", but the export shipped through 18.2.0 as `@deprecated`. The multi-currency epic #8345 (shape C′, ruling 6465431966 on #27119) needs it gone first, so that no author or AI reads `{value, currency}` as the way a record keeps its currency. ## Verification Base `origin/main` `fd73f2b39`; head `bf9ae4435`. <details><summary>Measure first (base)</summary> `git grep -n CurrencyValue` outside CHANGELOGs: `field.zod.ts` (declaration and alias), `field.test.ts`, the `Iso_` pin row, `api-surface` / `export-origins` / `declaration-map` / `json-schema.manifest` / `authorable-surface` / `authorable-surface.base.json`, generated reference docs, and prose (`field-value.zod.ts` docblock, `field-value.test.ts` test name, `content/docs/protocol/objectql/types.mdx`, ADR-0104, the strictness ledger). Nothing under `ui/` or `skills/**` rules. Control: `CurrencyConfigSchema` has live readers (validator, formula, ui i18n). </details> <details><summary>Gates</summary> - `pnpm --filter @objectstack/spec build` → exit 0 (after the deliberate manifest and authorable-surface deletions; the build refused each first, as designed). - `pnpm --filter @objectstack/spec check:generated` → 14 of 14 fresh after `--fix`. - `pnpm --filter @objectstack/spec test` → Test Files 740 passed | 1 skipped (741), Tests 22240 passed | 1 skipped | 1 todo. - `pnpm --filter @objectstack/spec test:repo` → Test Files 82 passed (82), Tests 1331 passed. - `pnpm --filter @objectstack/spec typecheck` → exit 0. - `check:liveness`, `check:empty-state`, `check:exported-any`, `check:dual-source-exports` → exit 0. `check:skill-examples` → exit 3 (prerequisite: needs a full-repo build; not measured). - `node scripts/check-adr-0087-registration.mjs --base origin/main` → ✓ `registered currency-value-schema-retired (new here)`. - `check-changeset-no-major` (pull_request event) → ✓ narrowing ships `minor`; `check-spec-parsed-alias` → 797 pinned, OK; `check-cross-package-test-inputs`, `check-doc-authoring`, `check-role-word`, `check-skills-token-ratchet` → OK. </details> ## Serial note Seat 3's #27218 (#27157) narrows `CurrencyConfigSchema` about 30 lines above this edit in `field.zod.ts` and touches `migrations/registry.ts.template`. Whichever lands second merges main (no rebase) and re-runs the generated files. ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. - [x] 2. Every name I added uses the casing for its kind. - [x] 3. No formatter ran; `pnpm lint` passes. - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. - [x] 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. - [x] 6. `packages/spec` touched: its generated artifacts are regenerated and committed. - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English. - [x] The *Before Submitting* list in CONTRIBUTING.md is done. --- _Generated by [Claude Code](https://claude.ai/code/session_01WGufziAkt9vZhLphG64TmD)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6d7634a commit b8f4acc

26 files changed

Lines changed: 337 additions & 118 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@objectstack/spec': minor
3+
---
4+
5+
feat(spec)!: `CurrencyValueSchema` and its `CurrencyValue` type are removed from `@objectstack/spec/data` (ADR-0104 D1)
6+
7+
Clause-②: no (narrowing)
8+
Metadata-protocol: narrowed
9+
10+
<!-- adr-0087: registered currency-value-schema-retired -->
11+
12+
**BREAKING** for TypeScript code only: `import { CurrencyValueSchema } from '@objectstack/spec/data'` (or from `@objectstack/spec`), and `import type { CurrencyValue }`, no longer compile (TS2305). The schema declared a `{ value, currency }` object that nothing ever parsed or stored, and it contradicted the real contract: a `currency` field's value is a bare number in the record validator, the SQL driver, import coercion and the field-zoo oracle, and the currency code is field configuration. ADR-0104 had already decided the deletion; the export stayed `@deprecated` until now, and it goes before multi-currency work starts so that no author reads it as the shape that records a currency. No metadata document changes, and runtime behaviour is unchanged.
13+
14+
- `CurrencyValueSchema` / `CurrencyValue` (`{ value: 1000.5, currency: 'USD' }`) → none. Write and read the bare number (`1000.5`), and declare the code on the field: `currencyConfig: { currencyMode: 'fixed', defaultCurrency: 'USD' }`. To type or check a value, use `valueSchemaFor(field, 'stored')` from `@objectstack/spec/data`, which answers a number for a currency field.
15+
16+
The fix: delete the import and use `number` for the value. The upgrade guide entry is `currency-value-schema-retired`, and `data/CurrencyValue` is listed in `RETIRED_DEFS_BY_MAJOR[18]`.

‎content/docs/protocol/objectql/types.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ is field configuration, never stored per value: under `currencyMode: fixed` it i
314314
under `dynamic`, the default, it is the tenant default currency (the
315315
`localization.currency` setting) and `defaultCurrency` is not the displayed
316316
currency. The old per-value object shape (`CurrencyValueSchema`) was
317-
never consumed by the validator, the driver, or import coercion and is
318-
deprecated in the spec.
317+
never consumed by the validator, the driver, or import coercion and has
318+
been removed from the spec.
319319
</Callout>
320320

321321
**Features:**

‎content/docs/references/data/field-value.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ Two canonical forms exist per field (ADR-0104 D1):
2525

2626
"Reality wins": where the deployed stored shape is coherent, the contract
2727
adopts it — deployed data is a wire contract we don't get to rewrite by
28-
editing Zod. This is why `currency` is a bare number (not the never-consumed
29-
`CurrencyValueSchema` object) and `location` is `{lat, lng}` (what field-zoo
28+
editing Zod. This is why `currency` is a bare number (the never-consumed
29+
`CurrencyValueSchema` object is deleted) and `location` is `{lat, lng}` (what field-zoo
3030
stores), not the never-consumed `{latitude, longitude}` shape.
3131

3232
Purity: schemas/constants/derivation only — no runtime logic, no caching

‎content/docs/references/data/field.mdx‎

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Field schema — Data Protocol reference
33
navTitle: Field
4-
description: "Field schemas of the ObjectStack Data Protocol: CurrencyConfig, CurrencyValue, Field and 7 more — each property with its type, default and a TypeScript example."
4+
description: "Field schemas of the ObjectStack Data Protocol: CurrencyConfig, Field and 7 more — each property with its type, default and a TypeScript example."
55
---
66

77
{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
@@ -13,8 +13,8 @@ description: "Field schemas of the ObjectStack Data Protocol: CurrencyConfig, Cu
1313
## TypeScript Usage
1414

1515
```typescript
16-
import { CurrencyConfigSchema, CurrencyValueSchema, FieldSchema, FieldMaskingKeepSchema, FieldMaskingRuleSchema, FieldType, InlineGridColumnSchema, LocationCoordinatesSchema, SelectOptionSchema, UniqueScopeSchema } from '@objectstack/spec/data';
17-
import type { CurrencyConfig, CurrencyValue, Field, FieldMaskingKeep, FieldMaskingRule, FieldType, InlineGridColumn, LocationCoordinates, SelectOption, UniqueScope } from '@objectstack/spec/data';
16+
import { CurrencyConfigSchema, FieldSchema, FieldMaskingKeepSchema, FieldMaskingRuleSchema, FieldType, InlineGridColumnSchema, LocationCoordinatesSchema, SelectOptionSchema, UniqueScopeSchema } from '@objectstack/spec/data';
17+
import type { CurrencyConfig, Field, FieldMaskingKeep, FieldMaskingRule, FieldType, InlineGridColumn, LocationCoordinates, SelectOption, UniqueScope } from '@objectstack/spec/data';
1818

1919
// Validate data
2020
const result = CurrencyConfigSchema.parse(data);
@@ -32,18 +32,6 @@ const result = CurrencyConfigSchema.parse(data);
3232
| **defaultCurrency** | `string` | optional | The currency code (ISO 4217, e.g. USD, CNY, EUR) of a `fixed`-mode field: its one currency, required under `fixed`. Not read under `dynamic` (the default), where amounts display in the tenant default currency. |
3333

3434

35-
---
36-
37-
## CurrencyValue
38-
39-
### Properties
40-
41-
| Property | Type | Required | Description |
42-
| :--- | :--- | :--- | :--- |
43-
| **value** | `number` | ✅ | Monetary amount |
44-
| **currency** | `string` | ✅ | Currency code (ISO 4217) |
45-
46-
4735
---
4836

4937
## Field

‎content/docs/references/index.mdx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Protocol reference — every schema by module
33
navTitle: Protocol Reference
4-
description: Every schema published by @objectstack/spec — 1560 schemas across 14 protocol modules
4+
description: Every schema published by @objectstack/spec — 1559 schemas across 14 protocol modules
55
---
66

77
{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
@@ -23,7 +23,7 @@ counts are sums of the rows they head. Regenerate with
2323
| [AI Protocol](/docs/references/ai) | 12 | 68 | Agents, tools, skills, RAG and knowledge sources, model registry, conversations. |
2424
| [API Protocol](/docs/references/api) | 32 | 440 | REST contracts, endpoints, routing, realtime, batch, discovery. |
2525
| [Automation Protocol](/docs/references/automation) | 15 | 77 | Flows and their nodes, approvals, ETL pipelines, webhooks, state machines, execution records. |
26-
| [Data Protocol](/docs/references/data) | 31 | 185 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. |
26+
| [Data Protocol](/docs/references/data) | 31 | 184 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. |
2727
| [Identity Protocol](/docs/references/identity) | 5 | 27 | Users and accounts, organizations, positions, SCIM provisioning. |
2828
| [Integration Protocol](/docs/references/integration) | 1 | 12 | The single connector protocol (ADR-0097) — catalog descriptors and provider-bound instances. |
2929
| [Kernel Protocol](/docs/references/kernel) | 29 | 151 | Plugin lifecycle and manifests, capabilities and security, metadata loading, service registry. |
@@ -34,7 +34,7 @@ counts are sums of the rows they head. Regenerate with
3434
| [Studio Protocol](/docs/references/studio) | 3 | 35 | Studio designer metadata — the authoring surfaces for the protocols above. |
3535
| [System Protocol](/docs/references/system) | 37 | 287 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. |
3636
| [UI Protocol](/docs/references/ui) | 16 | 172 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. |
37-
| **Total** | **202** | **1560** | 14 protocol modules |
37+
| **Total** | **202** | **1559** | 14 protocol modules |
3838

3939
---
4040

@@ -132,7 +132,7 @@ Flows and their nodes, approvals, ETL pipelines, webhooks, state machines, execu
132132

133133
## Data Protocol
134134

135-
**Source:** `packages/spec/src/data/` · **Import:** `@objectstack/spec/data` · **31 pages, 185 schemas**
135+
**Source:** `packages/spec/src/data/` · **Import:** `@objectstack/spec/data` · **31 pages, 184 schemas**
136136

137137
Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer.
138138

@@ -156,7 +156,7 @@ Objects, fields, queries, filters, datasources and drivers — the ObjectQL laye
156156
| [`driver/turso.zod.ts`](/docs/references/data/driver-turso) | `TursoConfig`, `TursoTransportMode` |
157157
| [`external-catalog.zod.ts`](/docs/references/data/external-catalog) | `ExternalCatalog`, `ExternalColumn`, `ExternalTable` |
158158
| [`feed.zod.ts`](/docs/references/data/feed) | `FeedFilterMode`, `FeedItemType` |
159-
| [`field.zod.ts`](/docs/references/data/field) | `CurrencyConfig`, `CurrencyValue`, `Field`, `FieldMaskingKeep`, `FieldMaskingRule`, `FieldType`, `InlineGridColumn`, `LocationCoordinates`, `SelectOption`, `UniqueScope` |
159+
| [`field.zod.ts`](/docs/references/data/field) | `CurrencyConfig`, `Field`, `FieldMaskingKeep`, `FieldMaskingRule`, `FieldType`, `InlineGridColumn`, `LocationCoordinates`, `SelectOption`, `UniqueScope` |
160160
| [`field-value.zod.ts`](/docs/references/data/field-value) | `Address`, `AddressValue`, `CalendarDateValue`, `ClockTimeValue`, `FileLikeValue`, `FileReferenceIdValue`, `FileRefusedValue`, `FileValue`, `InstantValue`, `LocationValue`, `ReferenceIdValue` |
161161
| [`filter.zod.ts`](/docs/references/data/filter) | `ComparisonOperator`, `EqualityOperator`, `FieldOperators`, `FieldReference`, `FilterArray`, `FilterCondition`, `NormalizedFilter`, `NowAnchor`, `QueryFilter`, `RangeOperator`, `SetOperator`, `SpecialOperator`, `StringOperator` |
162162
| [`hook.zod.ts`](/docs/references/data/hook) | `Hook`, `HookContext`, `HookEvent`, `HookRefusal` |

‎docs/adr/0104-field-runtime-value-shape-contract.md‎

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ lists in three packages, or silently corrupting data.
7676
The spec does export three per-type value schemas — and they make things
7777
worse, not better, because **all three are dead and two contradict reality**:
7878

79-
- `CurrencyValueSchema` (`packages/spec/src/data/field.zod.ts#CurrencyValueSchema`) declares `{value, currency}`;
79+
- `CurrencyValueSchema` (in `data/field.zod.ts`; deleted 2026-10-28, see the note under "Reality wins") declares `{value, currency}`;
8080
the validator, the SQL driver, import-coerce, and the field-zoo round-trip
8181
all treat currency as a **bare number**.
8282
- `LocationCoordinatesSchema` (`packages/spec/src/data/field.zod.ts#LocationCoordinatesSchema`) declares
@@ -163,13 +163,30 @@ Directive #2. It exports:
163163
**Reality wins.** Where the de-facto stored shape is coherent, the contract
164164
adopts it — deployed data is a wire contract we don't get to rewrite by
165165
editing Zod. Concretely: `currency` **is a scalar number** —
166-
`CurrencyValueSchema` is deleted (tombstoned in `UNKNOWN_KEY_GUIDANCE` /
167-
changelog with the FROM → TO note); `location` adopts the stored `{lat, lng}`
166+
`CurrencyValueSchema` is deleted (registered in `RETIRED_DEFS_BY_MAJOR` with a
167+
D3 semantic entry and the changelog carrying the FROM → TO note — see the
168+
2026-10-28 note below); `location` adopts the stored `{lat, lng}`
168169
and `LocationCoordinatesSchema` is rewritten to match; `AddressSchema` is
169170
either adopted by the contract and enforced, or deleted — it does not remain
170171
exported-but-dead. An exported-but-unconsumed value schema is exactly the
171172
inert metadata ADR-0078 forbids.
172173

174+
> **Note (2026-10-28, #27182, PR #27233) — `CurrencyValueSchema` is deleted.**
175+
> The deletion this paragraph decided had not happened: through 18.2.0 the
176+
> schema and its `CurrencyValue` type stayed exported from
177+
> `@objectstack/spec/data`, `@deprecated`, with zero readers. They are now
178+
> removed, ahead of the multi-currency epic #8345 (ruling 6465431966 on
179+
> #27119), so that no author reads `{value, currency}` as the shape that
180+
> records a currency. The schema had no carrier key, so there is no
181+
> `retiredKey()` tombstone and no guidance-map entry: the
182+
> FROM → TO note (a currency value is a bare number; the code is
183+
> `currencyConfig.defaultCurrency`) is carried by `RETIRED_DEFS_BY_MAJOR[18]`
184+
> (`data/CurrencyValue`, entry file
185+
> `packages/spec/src/migrations/entries/retired-defs/18.data__CurrencyValue.ts`),
186+
> the D3 semantic entry `currency-value-schema-retired` (entry file
187+
> `packages/spec/src/migrations/entries/semantic/18.currency-value-schema-retired.ts`)
188+
> and the changelog.
189+
173190
**Consumers converge on the contract** (each keeps its role, loses its private
174191
type lists):
175192

‎docs/audits/2026-07-unknown-key-strictness-ledger.counts/data.md‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ The `strict` column is the one the campaign schedules against; it counts both th
2121

2222
| Dir | Sites | strict | passthrough | catchall | strip |
2323
|---|---|---|---|---|---|
24-
| `data/` | 165 | 88 | 2 | 0 | 75 |
24+
| `data/` | 164 | 88 | 2 | 0 | 74 |
2525

2626
## `data/` — sites
2727

@@ -45,7 +45,7 @@ classify and is not listed (it becomes reportable the day it grows its first sit
4545
| `driver/turso.zod.ts` | 2 |
4646
| `external-catalog.zod.ts` | 4 |
4747
| `field-value.zod.ts` | 4 |
48-
| `field.zod.ts` | 14 |
48+
| `field.zod.ts` | 13 |
4949
| `filter.zod.ts` | 13 |
5050
| `hook-body.zod.ts` | 2 |
5151
| `hook.zod.ts` | 8 |
@@ -57,15 +57,15 @@ classify and is not listed (it becomes reportable the day it grows its first sit
5757
| `seed-loader.zod.ts` | 12 |
5858
| `seed.zod.ts` | 2 |
5959
| `validation.zod.ts` | 6 |
60-
| **total** | **165** |
60+
| **total** | **164** |
6161

6262
## `data/` — open
6363

6464
Per file, how many of its sites still silently discard unknown keys. The `Class`
6565
column that decides the bucket split is hand-written in the ledger; the arithmetic
6666
over it is here.
6767

68-
**75 strip of 165**, in 10 file(s).
68+
**74 strip of 164**, in 10 file(s).
6969

7070
| File | Strip | Sites |
7171
|---|---|---|
@@ -74,18 +74,18 @@ over it is here.
7474
| `driver-sql.zod.ts` | 2 | 2 |
7575
| `driver.zod.ts` | 9 | 9 |
7676
| `external-catalog.zod.ts` | 4 | 4 |
77-
| `field.zod.ts` | 2 | 14 |
77+
| `field.zod.ts` | 1 | 13 |
7878
| `filter.zod.ts` | 11 | 13 |
7979
| `hook.zod.ts` | 5 | 8 |
8080
| `query.zod.ts` | 4 | 5 |
8181
| `seed-loader.zod.ts` | 12 | 12 |
82-
| **total** | **75** | **165** |
82+
| **total** | **74** | **164** |
8383

8484
| Bucket | Sites |
8585
|---|---|
8686
| authorable — the ruling's forced scope | 0 |
8787
| unresolved — needs a per-schema verdict | 0 |
8888
| wire / open — out of forced scope | 73 |
89-
| no door — no carrier, ADR-0049 territory | 2 |
89+
| no door — no carrier, ADR-0049 territory | 1 |
9090
| no gate — carrier live, no parse | 0 |
9191
| covered — no carrier, no parse, guarded at every consumer | 0 |

‎docs/audits/2026-07-unknown-key-strictness-ledger.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,7 +1263,7 @@ triage row record which one was taken.
12631263
| `query.zod.ts` | open | ~~⚠️ classification conflict — see #4721~~ **RESOLVED (11:41Z ruling, closed by #4721).** The conflict was real and the answer was that per-FILE classification was the imprecise instrument: `SortNodeSchema` was carved out as `authorable` and closed (`strictObject` + `aliases: { direction: 'order' }`), the other 4 sites keep `open`. Those 4 are the dialect proper — `BaseQuerySchema`, `AggregationNodeSchema`, `FullTextSearchSchema`, `GroupByNodeSchema`'s object arm — and `BaseQuerySchema`'s own top-level strictness is #4001's to schedule, deliberately **not** taken by #4721 |
12641264
| `external-catalog.zod.ts` | wire (p) | **out of scope** |
12651265
| `hook.zod.ts` | wire | **out of scope** — `HookContextSchema` + `.session`/`.provenance`/`.user` are the runtime shape handed to a handler; verified in the data step |
1266-
| `field.zod.ts` | no door | ⛔ **not strictness work — re-verdicted 2026-08-13 (#4001 data batch).** This row's own instruction was "check whether they are record data (→ open) before closing", and the measured answer is the THIRD one: neither authorable nor open. Both remaining strip sites (`LocationCoordinatesSchema`, `CurrencyValueSchema`) are `@deprecated` DEAD EXPORTS that contradict the enforced value contract — `currency` stores a BARE NUMBER everywhere (validator, SQL driver `float` column, import coercion, field-zoo oracle), `location` stores `{lat, lng}` not `{latitude, longitude}`. Carrier: absent — no schema in the tree references either, so unreachability from every authoring root holds by construction and no BFS is needed (the only non-test references are two `type-alias-convention.pin.test.ts` rows). Parse: absent outside their own `field.test.ts` cases. Consumers' vocabulary: absent — zero references in objectui; `field-value.test.ts` pins from the other direction that the enforced contract REJECTS the retired `CurrencyValueSchema` object shape. The ADR-0049 answer this class prescribes already exists: ADR-0104's "Reality wins" section decides both removals ("an exported-but-unconsumed value schema is exactly the inert metadata ADR-0078 forbids"), the JSDoc deprecations are on `main` with "Removal rides the next spec major", and the removal is tracked at **#8562** — this row points there, never at a batch. Closing them instead would be #4583's precisely-validated dead slot, and worse than most instances of it: a `strictObject` `surface` name plus did-you-mean suggestions on a shape authors must NOT use is an invitation dressed as enforcement, on the exact spelling (`{value, currency}` / `{latitude, longitude}`) the real contract rejects. The third named shape the old row carried, `Address`, was never this file's site — `AddressSchema` is DECLARED in `field-value.zod.ts` since #7127 and only re-exported here |
1266+
| `field.zod.ts` | no door | ⛔ **not strictness work — re-verdicted 2026-08-13 (#4001 data batch).** *(2026-10-28, #27182: `CurrencyValueSchema` and its `CurrencyValue` type are DELETED — registered as `RETIRED_DEFS_BY_MAJOR[18]` `data/CurrencyValue` with the D3 entry `currency-value-schema-retired`, ADR-0104 D1 carried out ahead of the multi-currency epic #8345. One strip site remains, `LocationCoordinatesSchema`, and the verdict below stands for it.)* This row's own instruction was "check whether they are record data (→ open) before closing", and the measured answer is the THIRD one: neither authorable nor open. Both remaining strip sites (`LocationCoordinatesSchema`, `CurrencyValueSchema`) are `@deprecated` DEAD EXPORTS that contradict the enforced value contract — `currency` stores a BARE NUMBER everywhere (validator, SQL driver `float` column, import coercion, field-zoo oracle), `location` stores `{lat, lng}` not `{latitude, longitude}`. Carrier: absent — no schema in the tree references either, so unreachability from every authoring root holds by construction and no BFS is needed (the only non-test references are two `type-alias-convention.pin.test.ts` rows). Parse: absent outside their own `field.test.ts` cases. Consumers' vocabulary: absent — zero references in objectui; `field-value.test.ts` pins from the other direction that the enforced contract REJECTS the retired `CurrencyValueSchema` object shape. The ADR-0049 answer this class prescribes already exists: ADR-0104's "Reality wins" section decides both removals ("an exported-but-unconsumed value schema is exactly the inert metadata ADR-0078 forbids"), the JSDoc deprecations are on `main` with "Removal rides the next spec major", and the removal is tracked at **#8562** — this row points there, never at a batch. Closing them instead would be #4583's precisely-validated dead slot, and worse than most instances of it: a `strictObject` `surface` name plus did-you-mean suggestions on a shape authors must NOT use is an invitation dressed as enforcement, on the exact spelling (`{value, currency}` / `{latitude, longitude}`) the real contract rejects. The third named shape the old row carried, `Address`, was never this file's site — `AddressSchema` is DECLARED in `field-value.zod.ts` since #7127 and only re-exported here |
12671267
| `driver-sql.zod.ts` | wire | **out of scope** |
12681268

12691269
**Authorable strip in `data/`:**
@@ -1807,7 +1807,7 @@ from an abandoned one.
18071807
121 non-authorable in 21 rows — #13802 closed `field-value.zod.ts`'s two `open` sites by
18081808
maintainer ruling; the counts file carries the live number.)* The `no door`
18091809
ones carry the only follow-up in the set, and it is a different ratchet:
1810-
ADR-0049 removal, tracked at #8562 for `field.zod.ts`'s two.
1810+
ADR-0049 removal, tracked at #8562 for `field.zod.ts`'s two *(2026-10-28: one, after #27182 deleted `CurrencyValueSchema`)*.
18111811
- **The nine untriaged directories.** They were never in the ruling's forced
18121812
scope and are classified coarsely; a future campaign that wants them starts by
18131813
giving them per-file rows, at which point this gate begins holding them too.

‎packages/spec/api-surface/data.json‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@
143143
"CurrencyConfig (type)",
144144
"CurrencyConfigParsed (type)",
145145
"CurrencyConfigSchema (const)",
146-
"CurrencyValue (type)",
147-
"CurrencyValueSchema (const)",
148146
"CustomPersistenceConfig (type)",
149147
"CustomPersistenceConfigSchema (const)",
150148
"DATABASE_DRIVER_SELECTION_ALIASES (const)",

0 commit comments

Comments
 (0)