Skip to content

Commit 0222d3c

Browse files
os-zhuangclaude
andauthored
feat(spec)!: converge the dual-source MetadataFormat and CacheStrategy enum declarations (#4537) (#4557)
Two enum vocabularies were declared on both ./shared and ./system and had diverged on their VALUES — which accepted value set you got depended on nothing but the import path (the #4411 trap; #4535 A2, #4506 baseline). Value-level divergence is the silent kind: a mismatched value never fails to compile. MetadataFormat / MetadataFormatSchema — shared declaration is the single source: - system/metadata-persistence.zod.ts no longer declares its own 7-member copy; it re-exports shared/metadata-types.zod (the MetadataManagerConfig pattern, in reverse). The extension-style aliases yml/ts/js it carried had zero producers in this repo, objectui and cloud: FilesystemLoader.detectFormat normalizes at the boundary (.yml -> 'yaml', .ts -> 'typescript', .js -> 'javascript') and the database/remote/memory loaders always emit 'json'. - Direction: shared, not system — kernel/metadata-loader.zod has imported the shared schema since #4411 (MetadataManagerConfig.formats needs no change), and system already re-exports MetadataManagerConfigSchema FROM kernel, so a system-side source would close a module cycle (shared -> system -> kernel -> shared). CacheStrategy — system/cache.zod.ts (CacheStrategySchema) is the single declaration: - shared/enums.zod.ts CacheStrategyEnum (+ its CacheStrategy type export) removed: zero importers in all three repos, while the system schema is the one CacheTier.strategy gates on. Same disposition as AggregationFunctionEnum in the same file (objectui#2945): removed rather than reconciled. - 'adaptive', declared only on the system side with zero producers, is dropped — the enum carries the four values both declarations agreed on (lru | lfu | fifo | ttl). Bookkeeping: - dual-source-exports.baseline.json: the three converged rows deleted (shrink-only ratchet). - json-schema.manifest.json: shared/CacheStrategyEnum key deleted (deliberate retirement, #2978 flow). - Pin tests: yml/ts/js rejected on the system entry; 'adaptive' rejected on CacheStrategySchema. - api-surface.json, references docs, skill refs regenerated via check:generated --fix. - Changeset (major) carries the FROM -> TO migration lines. - No ADR-0087 conversion / tombstone: loader envelope + config vocabulary with no authorable-metadata producers (the #4411/#4536 route). Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL Co-authored-by: Claude <noreply@anthropic.com>
1 parent ac471a0 commit 0222d3c

19 files changed

Lines changed: 132 additions & 84 deletions
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
"@objectstack/spec": major
3+
---
4+
5+
feat(spec)!: converge the dual-source `MetadataFormat` and `CacheStrategy` enum declarations (#4537)
6+
7+
Two enum vocabularies were declared twice, on `./shared` and `./system`, and had
8+
diverged on their **values** — which type (and which accepted value set) you got
9+
depended on nothing but the import path (the #4411 trap; #4535/#4506 baseline).
10+
Both converge on one declaration each; the three
11+
`dual-source-exports.baseline.json` rows are deleted.
12+
13+
**`MetadataFormat` / `MetadataFormatSchema` — the shared declaration is the
14+
single source.** `system/metadata-persistence.zod` no longer declares its own
15+
7-member copy; it re-exports `shared/metadata-types.zod` (the
16+
`MetadataManagerConfig` pattern — `kernel/metadata-loader.zod` already imported
17+
the shared one since #4411). Breaking on the `./system` entry only: the
18+
extension-style aliases `'yml'`/`'ts'`/`'js'` are no longer accepted. They had
19+
zero producers in this repo, objectui and cloud — every loader normalizes at the
20+
boundary (`FilesystemLoader.detectFormat` maps `.yml``'yaml'`, `.ts`
21+
`'typescript'`, `.js``'javascript'`; the database/remote/memory loaders
22+
always emit `'json'`). Migration: write the canonical name —
23+
`'yml'``'yaml'`, `'ts'``'typescript'`, `'js'``'javascript'`.
24+
25+
**`CacheStrategy``system/cache.zod` (`CacheStrategySchema`) is the single
26+
declaration.** The `./shared` copy `CacheStrategyEnum` (and its `CacheStrategy`
27+
type export) is removed: it had zero importers in all three repos, while the
28+
system schema is the one `CacheTier.strategy` gates on — same disposition as
29+
`AggregationFunctionEnum` (objectui#2945): removed rather than reconciled.
30+
Migration: `import { CacheStrategySchema, type CacheStrategy } from
31+
'@objectstack/spec/system'`. The value `'adaptive'`, declared only on the
32+
system side with zero producers, is dropped — the enum carries the four values
33+
both declarations agreed on (`'lru' | 'lfu' | 'fifo' | 'ttl'`); pick one of
34+
those.
35+
36+
No ADR-0087 conversion / tombstone: loader envelope + config vocabulary with no
37+
authorable-metadata producers (the #4411 / #4536 route), verified by three-repo
38+
scan on the issue.

content/docs/references/shared/enums.mdx

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,13 @@ Sort direction used across query, data-engine, analytics
1414
## TypeScript Usage
1515

1616
```typescript
17-
import { CacheStrategyEnum, IsolationLevelEnum, MutationEventEnum, SortDirectionEnum, SortItem } from '@objectstack/spec/shared';
18-
import type { CacheStrategyEnum, IsolationLevelEnum, MutationEventEnum, SortDirectionEnum, SortItem } from '@objectstack/spec/shared';
17+
import { IsolationLevelEnum, MutationEventEnum, SortDirectionEnum, SortItem } from '@objectstack/spec/shared';
18+
import type { IsolationLevelEnum, MutationEventEnum, SortDirectionEnum, SortItem } from '@objectstack/spec/shared';
1919

2020
// Validate data
21-
const result = CacheStrategyEnum.parse(data);
21+
const result = IsolationLevelEnum.parse(data);
2222
```
2323

24-
---
25-
26-
## CacheStrategyEnum
27-
28-
Cache eviction strategy
29-
30-
### Allowed Values
31-
32-
* `lru`
33-
* `lfu`
34-
* `ttl`
35-
* `fifo`
36-
37-
3824
---
3925

4026
## IsolationLevelEnum

content/docs/references/shared/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"http",
88
"identifiers",
99
"mapping",
10-
"metadata-persistence",
1110
"metadata-types",
1211
"protection"
1312
]

content/docs/references/shared/metadata-types.mdx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ Supported metadata file formats
1414
## TypeScript Usage
1515

1616
```typescript
17-
import { BaseMetadataRecord } from '@objectstack/spec/shared';
18-
import type { BaseMetadataRecord } from '@objectstack/spec/shared';
17+
import { BaseMetadataRecord, MetadataFormat } from '@objectstack/spec/shared';
18+
import type { BaseMetadataRecord, MetadataFormat } from '@objectstack/spec/shared';
1919

2020
// Validate data
2121
const result = BaseMetadataRecord.parse(data);
@@ -39,3 +39,17 @@ Base metadata record fields shared across kernel and system
3939

4040
---
4141

42+
## MetadataFormat
43+
44+
Metadata file format
45+
46+
### Allowed Values
47+
48+
* `yaml`
49+
* `json`
50+
* `typescript`
51+
* `javascript`
52+
53+
54+
---
55+

content/docs/references/system/cache.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ Cache eviction strategy
128128
* `lfu`
129129
* `fifo`
130130
* `ttl`
131-
* `adaptive`
132131

133132

134133
---
@@ -145,7 +144,7 @@ Configuration for a single cache tier in the hierarchy
145144
| **type** | `Enum<'memory' \| 'redis' \| 'memcached' \| 'cdn'>` || Cache backend type |
146145
| **maxSize** | `number` | optional | Max size in MB |
147146
| **ttl** | `number` || Default TTL in seconds |
148-
| **strategy** | `Enum<'lru' \| 'lfu' \| 'fifo' \| 'ttl' \| 'adaptive'>` || Eviction strategy |
147+
| **strategy** | `Enum<'lru' \| 'lfu' \| 'fifo' \| 'ttl'>` || Eviction strategy |
149148
| **warmup** | `boolean` || Pre-populate cache on startup |
150149

151150

content/docs/references/system/meta.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
"---Content & Collaboration---",
4444
"book",
4545
"collaboration",
46-
"doc"
46+
"doc",
47+
"---More---",
48+
"metadata-types"
4749
]
4850
}

content/docs/references/system/metadata-persistence.mdx

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ Defines the lifecycle and mutability of a metadata item.
1616
## TypeScript Usage
1717

1818
```typescript
19-
import { MetadataCollectionInfo, MetadataDiffResult, MetadataExportOptions, MetadataFormat, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataRecord, MetadataSaveOptions, MetadataSaveResult, MetadataScope, MetadataSource, MetadataState, MetadataStats, MetadataWatchEvent, PackagePublishResult } from '@objectstack/spec/system';
20-
import type { MetadataCollectionInfo, MetadataDiffResult, MetadataExportOptions, MetadataFormat, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataRecord, MetadataSaveOptions, MetadataSaveResult, MetadataScope, MetadataSource, MetadataState, MetadataStats, MetadataWatchEvent, PackagePublishResult } from '@objectstack/spec/system';
19+
import { MetadataCollectionInfo, MetadataDiffResult, MetadataExportOptions, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataRecord, MetadataSaveOptions, MetadataSaveResult, MetadataScope, MetadataSource, MetadataState, MetadataStats, MetadataWatchEvent, PackagePublishResult } from '@objectstack/spec/system';
20+
import type { MetadataCollectionInfo, MetadataDiffResult, MetadataExportOptions, MetadataHistoryQueryOptions, MetadataHistoryQueryResult, MetadataHistoryRecord, MetadataHistoryRetentionPolicy, MetadataImportOptions, MetadataLoadOptions, MetadataLoadResult, MetadataLoaderContract, MetadataRecord, MetadataSaveOptions, MetadataSaveResult, MetadataScope, MetadataSource, MetadataState, MetadataStats, MetadataWatchEvent, PackagePublishResult } from '@objectstack/spec/system';
2121

2222
// Validate data
2323
const result = MetadataCollectionInfo.parse(data);
@@ -66,22 +66,7 @@ const result = MetadataCollectionInfo.parse(data);
6666
| **types** | `string[]` | optional | |
6767
| **namespaces** | `string[]` | optional | |
6868
| **output** | `string` || Output directory or file |
69-
| **format** | `Enum<'json' \| 'yaml' \| 'yml' \| 'ts' \| 'js' \| 'typescript' \| 'javascript'>` || |
70-
71-
72-
---
73-
74-
## MetadataFormat
75-
76-
### Allowed Values
77-
78-
* `json`
79-
* `yaml`
80-
* `yml`
81-
* `ts`
82-
* `js`
83-
* `typescript`
84-
* `javascript`
69+
| **format** | `Enum<'yaml' \| 'json' \| 'typescript' \| 'javascript'>` || Metadata file format |
8570

8671

8772
---
@@ -194,7 +179,7 @@ const result = MetadataCollectionInfo.parse(data);
194179
| :--- | :--- | :--- | :--- |
195180
| **data** | `any` || |
196181
| **stats** | `{ path?: string; size?: number; mtime?: string; hash?: string; … }` | optional | |
197-
| **format** | `Enum<'json' \| 'yaml' \| 'yml' \| 'ts' \| 'js' \| 'typescript' \| 'javascript'>` | optional | |
182+
| **format** | `Enum<'yaml' \| 'json' \| 'typescript' \| 'javascript'>` | optional | Metadata file format |
198183
| **source** | `string` | optional | |
199184
| **fromCache** | `boolean` | optional | |
200185
| **etag** | `string` | optional | |
@@ -264,7 +249,7 @@ const result = MetadataCollectionInfo.parse(data);
264249

265250
| Property | Type | Required | Description |
266251
| :--- | :--- | :--- | :--- |
267-
| **format** | `Enum<'json' \| 'yaml' \| 'yml' \| 'ts' \| 'js' \| 'typescript' \| 'javascript'>` | optional | |
252+
| **format** | `Enum<'yaml' \| 'json' \| 'typescript' \| 'javascript'>` | optional | Metadata file format |
268253
| **create** | `boolean` || |
269254
| **overwrite** | `boolean` || |
270255
| **path** | `string` | optional | |
@@ -342,7 +327,7 @@ const result = MetadataCollectionInfo.parse(data);
342327
| **hash** | `string` | optional | |
343328
| **etag** | `string` | optional | |
344329
| **modifiedAt** | `string` | optional | |
345-
| **format** | `Enum<'json' \| 'yaml' \| 'yml' \| 'ts' \| 'js' \| 'typescript' \| 'javascript'>` | optional | |
330+
| **format** | `Enum<'yaml' \| 'json' \| 'typescript' \| 'javascript'>` | optional | Metadata file format |
346331

347332

348333
---

content/docs/references/shared/metadata-persistence.mdx renamed to content/docs/references/system/metadata-types.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
---
2-
title: Metadata Persistence
3-
description: Metadata Persistence protocol schemas
2+
title: Metadata Types
3+
description: Metadata Types protocol schemas
44
---
55

66
{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
77

88
## TypeScript Usage
99

1010
```typescript
11-
import { MetadataFormat } from '@objectstack/spec/shared';
12-
import type { MetadataFormat } from '@objectstack/spec/shared';
11+
import { MetadataFormat } from '@objectstack/spec/system';
12+
import type { MetadataFormat } from '@objectstack/spec/system';
1313

1414
// Validate data
1515
const result = MetadataFormat.parse(data);

packages/spec/api-surface.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4437,8 +4437,6 @@
44374437
"ApplyProtectionContext (interface)",
44384438
"BaseMetadataRecord (type)",
44394439
"BaseMetadataRecordSchema (const)",
4440-
"CacheStrategy (type)",
4441-
"CacheStrategyEnum (const)",
44424440
"CorsConfig (type)",
44434441
"CorsConfigSchema (const)",
44444442
"CronExpressionInput (type)",

packages/spec/dual-source-exports.baseline.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"ActionLocationSchema — [./studio (const)] ≠ [./ui (const)]",
55
"ActivationEventSchema — [./kernel (const)] ≠ [./studio (const)]",
66
"AnalyticsQuery — [./contracts (interface)] ≠ [./data (type)]",
7-
"CacheStrategy — [./shared (type)] ≠ [./system (type)]",
87
"ConflictResolution — [./automation (type)] ≠ [./integration (type)] ≠ [./ui (type)]",
98
"ConflictResolutionSchema — [./automation (const)] ≠ [./integration (const)] ≠ [./ui (const)]",
109
"DataSyncConfig — [./automation (type)] ≠ [./integration (type)]",
@@ -25,8 +24,6 @@
2524
"MetadataEvent — [./api (type)] ≠ [./kernel (type)]",
2625
"MetadataEventSchema — [./api (const)] ≠ [./kernel (const)]",
2726
"MetadataExportOptions — [./contracts (interface)] ≠ [./system (type)]",
28-
"MetadataFormat — [./shared (type)] ≠ [./system (type)]",
29-
"MetadataFormatSchema — [./shared (const)] ≠ [./system (const)]",
3027
"MetadataImportOptions — [./contracts (interface)] ≠ [./system (type)]",
3128
"Notification — [./api (type)] ≠ [./ui (type)]",
3229
"NotificationChannel — [./contracts (type)] ≠ [./system (type)]",

0 commit comments

Comments
 (0)