Skip to content

Commit e73d5cd

Browse files
os-zhuangclaude
andcommitted
chore(spec): prune 15 dead field display-config props (dead-surface plan, P2)
Removes FieldSchema enhanced-type *display* knobs that had no runtime reader and no renderer consumer — dead in both layers per the field liveness audit, and confirmed by greps (no object def / seed constructs them) + the full spec suite (6562 tests) staying green: code theme/lineNumbers · rating allowHalf · location displayMap/allowGeocoding · address addressFormat · color colorFormat/allowAlpha/presetColors · slider showValue/marks · barcode/qr barcodeFormat/qrErrorCorrection/displayValue/allowScanning Kept: the wired knobs (language, maxRating, step) and the functional nested configs (currencyConfig/vectorConfig/fileAttachmentConfig — they carry data the field type needs, e.g. vector dimensions; the audit's "flat sibling" claim lives in the objectui repo and can't be verified here, so they're left for that repo). Field *types* are unchanged; only unused optional config props are removed. field.zod.ts schema + field.test.ts (assertions/configs) + field.json ledger updated; reference docs regenerated; liveness gate green (field 34 live/24 dead). First executed batch of the dead-surface disposition plan. Pruning is a coupled refactor (schema → Field factory → tests → forms → translations), so it proceeds as small per-cluster verified PRs, not one sweep — see the plan doc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 40a7f1e commit e73d5cd

4 files changed

Lines changed: 261 additions & 137 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@objectstack/spec": minor
3+
---
4+
5+
chore(spec): prune 15 dead field display-config properties (ADR-0049 / dead-surface plan). Removes `FieldSchema` enhanced-type *display* knobs that had no runtime reader and no renderer consumer (dead in both layers per the field liveness audit): code `theme`/`lineNumbers`, rating `allowHalf`, location `displayMap`/`allowGeocoding`, address `addressFormat`, color `colorFormat`/`allowAlpha`/`presetColors`, slider `showValue`/`marks`, barcode/qr `barcodeFormat`/`qrErrorCorrection`/`displayValue`/`allowScanning`. The wired knobs (`language`, `maxRating`, `step`) and the functional nested configs (`currencyConfig`/`vectorConfig`/`fileAttachmentConfig`) are kept. Field *types* are unchanged; only unused optional config props are removed. Narrows the false spec surface (narrow-and-true).

packages/spec/liveness/field.json

Lines changed: 242 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,78 +2,247 @@
22
"type": "field",
33
"_note": "FieldSchema (flat — all field-type configs are top-level optional props). Seeded from docs/audits/2026-06-fieldschema-property-liveness.md. ~half dead. Nested config objects (currencyConfig/vectorConfig/fileAttachmentConfig/encryptionConfig/maskingRule/cached/dataQuality) are wholly dead → classified at top level. Naming-drift props are server-live but client-snake. Framework evidence cited with paths; objectui-renderer evidence as prose.",
44
"props": {
5-
"name": { "status": "live", "evidence": "packages/objectql/src/engine.ts" },
6-
"label": { "status": "live", "note": "renderers." },
7-
"type": { "status": "live", "evidence": "packages/objectql/src/engine.ts" },
8-
"description": { "status": "live", "note": "display." },
9-
"format": { "status": "live", "evidence": "packages/objectql/src/engine.ts" },
10-
"required": { "status": "live", "evidence": "packages/objectql/src/validation/record-validator.ts" },
11-
"multiple": { "status": "live", "evidence": "packages/objectql/src/engine.ts" },
12-
"defaultValue": { "status": "live", "evidence": "packages/objectql/src/engine.ts" },
13-
"min": { "status": "live", "evidence": "packages/objectql/src/validation/record-validator.ts" },
14-
"max": { "status": "live", "evidence": "packages/objectql/src/validation/record-validator.ts" },
15-
"options": { "status": "live", "note": "select options {label,value,color,default} — renderers + validation." },
16-
"deleteBehavior": { "status": "live", "evidence": "packages/objectql/src/engine.ts", "note": "reference cascade/restrict." },
17-
"expression": { "status": "live", "evidence": "packages/objectql/src/engine.ts", "note": "formula." },
18-
"summaryOperations": { "status": "live", "evidence": "packages/objectql/src/engine.ts", "note": "rollup {object,field,function,relationshipField}." },
19-
"requiredWhen": { "status": "live", "evidence": "packages/objectql/src/validation/record-validator.ts", "note": "CEL." },
20-
"readonlyWhen": { "status": "live", "note": "renderer CEL." },
21-
"visibleWhen": { "status": "live", "note": "renderer CEL." },
22-
"conditionalRequired": { "status": "live", "note": "deprecated alias of requiredWhen — plan removal." },
23-
"readonly": { "status": "live", "note": "renderer." },
24-
"hidden": { "status": "live", "note": "renderer." },
25-
"system": { "status": "live", "evidence": "packages/objectql/src/engine.ts" },
26-
"sortable": { "status": "live", "note": "grid." },
27-
"inlineEdit": { "status": "live", "note": "grid inline editing." },
28-
"language": { "status": "live", "note": "code field — CodeField.tsx:13 (only language is live; theme/lineNumbers dead)." },
29-
"step": { "status": "live", "note": "slider — SliderField.tsx (min/max/step live)." },
30-
"group": { "status": "live", "note": "field group/layout (renderer)." },
31-
"inlineHelpText": { "status": "live", "note": "display help (renderer)." },
32-
"unique": { "status": "live", "evidence": "packages/plugins/driver-sql/src/sql-driver.ts:1853", "note": "CAVEAT — DDL-only; NOT validated on the write path (violations surface as raw driver errors)." },
33-
"precision": { "status": "live", "note": "CAVEAT — UI display formatting only; DDL never sizes (maps to float). (NumberField.tsx:16)." },
34-
"scale": { "status": "live", "note": "CAVEAT — grid formatting only; DDL never sizes." },
35-
"reference": { "status": "live", "evidence": "packages/objectql/src/engine.ts:1672", "note": "CAVEAT — $expand/cascade/seed live; FK DDL reads reference_to (unmapped from reference)." },
36-
"autonumberFormat": { "status": "live", "evidence": "packages/objectql/src/engine.ts:765", "note": "CAVEAT — runtime sequence formatting live; UI AutoNumberField ignores it." },
37-
"maxLength": { "status": "live", "evidence": "packages/objectql/src/validation/record-validator.ts:127", "note": "CAVEAT — server validation honors camelCase, but the client form reads snake_case max_length." },
38-
"minLength": { "status": "live", "evidence": "packages/objectql/src/validation/record-validator.ts:130", "note": "CAVEAT — server camel; client form reads min_length." },
39-
"referenceFilters": { "status": "dead", "evidence": "lookup dialog reads lookup_filters (LookupField.tsx:171) — entirely dead as authored (naming drift)" },
40-
"maxRating": { "status": "dead", "evidence": "RatingField reads `max` (RatingField.tsx:13) — dead + redundant with max" },
41-
"columnName": { "status": "dead", "evidence": "resolveColumnName (spec system-names.ts:182) has ZERO call sites; SQL driver hardcodes column = field key", "note": "DANGEROUS — advertises custom physical columns the driver never honors." },
42-
"searchable": { "status": "dead", "evidence": "field-level — no DDL/query consumer; search is object-level / view searchableFields" },
43-
"index": { "status": "dead", "evidence": "field-level — driver reads object indexes[] (sql-driver.ts:1252); field bool unused" },
44-
"externalId": { "status": "dead", "evidence": "field-level — upsert keys off dataset-level externalId (seed-loader.ts:175)" },
45-
"currencyConfig": { "status": "dead", "evidence": "nested config — renderers read flat currency/precision (CurrencyField.tsx:40); no currencyConfig consumer" },
46-
"vectorConfig": { "status": "dead", "evidence": "nested config — renderers read flat dimensions; no consumer, no vector-index DDL" },
47-
"fileAttachmentConfig": { "status": "dead", "evidence": "nested config — renderers read flat multiple/accept/maxSize (FileField.tsx:16); no size/type/virus enforcement in write path" },
48-
"encryptionConfig": { "status": "dead", "evidence": "no consumer; the only at-rest protection is the separate type:'secret' channel (engine.ts encryptSecretFields)" },
49-
"maskingRule": { "status": "dead", "evidence": "no consumer" },
50-
"auditTrail": { "status": "dead", "evidence": "no consumer (aspirational governance)" },
51-
"dataQuality": { "status": "dead", "evidence": "no consumer (aspirational governance)" },
52-
"cached": { "status": "dead", "evidence": "no consumer" },
53-
"dependencies": { "status": "dead", "evidence": "no consumer" },
54-
"trackFeedHistory": { "status": "dead", "evidence": "no consumer" },
55-
"caseSensitive": { "status": "dead", "evidence": "no consumer" },
56-
"writeRequiresMasterRead": { "status": "dead", "evidence": "no consumer (governance)" },
57-
"theme": { "status": "dead", "evidence": "code field — only language is live" },
58-
"lineNumbers": { "status": "dead", "evidence": "code field — only language is live" },
59-
"allowHalf": { "status": "dead", "evidence": "rating — unread" },
60-
"displayMap": { "status": "dead", "evidence": "location — unread" },
61-
"allowGeocoding": { "status": "dead", "evidence": "location — unread" },
62-
"addressFormat": { "status": "dead", "evidence": "address — unread" },
63-
"colorFormat": { "status": "dead", "evidence": "color — ColorField uses a fixed hex input" },
64-
"allowAlpha": { "status": "dead", "evidence": "color — unread" },
65-
"presetColors": { "status": "dead", "evidence": "color — unread" },
66-
"showValue": { "status": "dead", "evidence": "slider — unread" },
67-
"marks": { "status": "dead", "evidence": "slider — unread" },
68-
"barcodeFormat": { "status": "dead", "evidence": "barcode/qr — unread" },
69-
"qrErrorCorrection": { "status": "dead", "evidence": "barcode/qr — unread" },
70-
"displayValue": { "status": "dead", "evidence": "barcode/qr — unread" },
71-
"allowScanning": { "status": "dead", "evidence": "barcode/qr — unread" },
72-
"inlineTitle": { "status": "dead", "evidence": "master-detail explicit override — auto-derivation works (deriveMasterDetail.ts); overrides unread" },
73-
"inlineColumns": { "status": "dead", "evidence": "master-detail explicit override — unread" },
74-
"inlineAmountField": { "status": "dead", "evidence": "master-detail explicit override — unread" },
75-
"relatedList": { "status": "dead", "evidence": "detail-page related lists come from view metadata, not FieldSchema" },
76-
"relatedListTitle": { "status": "dead", "evidence": "master-detail explicit override — unread" },
77-
"relatedListColumns": { "status": "dead", "evidence": "master-detail explicit override — unread" }
5+
"name": {
6+
"status": "live",
7+
"evidence": "packages/objectql/src/engine.ts"
8+
},
9+
"label": {
10+
"status": "live",
11+
"note": "renderers."
12+
},
13+
"type": {
14+
"status": "live",
15+
"evidence": "packages/objectql/src/engine.ts"
16+
},
17+
"description": {
18+
"status": "live",
19+
"note": "display."
20+
},
21+
"format": {
22+
"status": "live",
23+
"evidence": "packages/objectql/src/engine.ts"
24+
},
25+
"required": {
26+
"status": "live",
27+
"evidence": "packages/objectql/src/validation/record-validator.ts"
28+
},
29+
"multiple": {
30+
"status": "live",
31+
"evidence": "packages/objectql/src/engine.ts"
32+
},
33+
"defaultValue": {
34+
"status": "live",
35+
"evidence": "packages/objectql/src/engine.ts"
36+
},
37+
"min": {
38+
"status": "live",
39+
"evidence": "packages/objectql/src/validation/record-validator.ts"
40+
},
41+
"max": {
42+
"status": "live",
43+
"evidence": "packages/objectql/src/validation/record-validator.ts"
44+
},
45+
"options": {
46+
"status": "live",
47+
"note": "select options {label,value,color,default} — renderers + validation."
48+
},
49+
"deleteBehavior": {
50+
"status": "live",
51+
"evidence": "packages/objectql/src/engine.ts",
52+
"note": "reference cascade/restrict."
53+
},
54+
"expression": {
55+
"status": "live",
56+
"evidence": "packages/objectql/src/engine.ts",
57+
"note": "formula."
58+
},
59+
"summaryOperations": {
60+
"status": "live",
61+
"evidence": "packages/objectql/src/engine.ts",
62+
"note": "rollup {object,field,function,relationshipField}."
63+
},
64+
"requiredWhen": {
65+
"status": "live",
66+
"evidence": "packages/objectql/src/validation/record-validator.ts",
67+
"note": "CEL."
68+
},
69+
"readonlyWhen": {
70+
"status": "live",
71+
"note": "renderer CEL."
72+
},
73+
"visibleWhen": {
74+
"status": "live",
75+
"note": "renderer CEL."
76+
},
77+
"conditionalRequired": {
78+
"status": "live",
79+
"note": "deprecated alias of requiredWhen — plan removal."
80+
},
81+
"readonly": {
82+
"status": "live",
83+
"note": "renderer."
84+
},
85+
"hidden": {
86+
"status": "live",
87+
"note": "renderer."
88+
},
89+
"system": {
90+
"status": "live",
91+
"evidence": "packages/objectql/src/engine.ts"
92+
},
93+
"sortable": {
94+
"status": "live",
95+
"note": "grid."
96+
},
97+
"inlineEdit": {
98+
"status": "live",
99+
"note": "grid inline editing."
100+
},
101+
"language": {
102+
"status": "live",
103+
"note": "code field — CodeField.tsx:13 (only language is live; theme/lineNumbers dead)."
104+
},
105+
"step": {
106+
"status": "live",
107+
"note": "slider — SliderField.tsx (min/max/step live)."
108+
},
109+
"group": {
110+
"status": "live",
111+
"note": "field group/layout (renderer)."
112+
},
113+
"inlineHelpText": {
114+
"status": "live",
115+
"note": "display help (renderer)."
116+
},
117+
"unique": {
118+
"status": "live",
119+
"evidence": "packages/plugins/driver-sql/src/sql-driver.ts:1853",
120+
"note": "CAVEAT — DDL-only; NOT validated on the write path (violations surface as raw driver errors)."
121+
},
122+
"precision": {
123+
"status": "live",
124+
"note": "CAVEAT — UI display formatting only; DDL never sizes (maps to float). (NumberField.tsx:16)."
125+
},
126+
"scale": {
127+
"status": "live",
128+
"note": "CAVEAT — grid formatting only; DDL never sizes."
129+
},
130+
"reference": {
131+
"status": "live",
132+
"evidence": "packages/objectql/src/engine.ts:1672",
133+
"note": "CAVEAT — $expand/cascade/seed live; FK DDL reads reference_to (unmapped from reference)."
134+
},
135+
"autonumberFormat": {
136+
"status": "live",
137+
"evidence": "packages/objectql/src/engine.ts:765",
138+
"note": "CAVEAT — runtime sequence formatting live; UI AutoNumberField ignores it."
139+
},
140+
"maxLength": {
141+
"status": "live",
142+
"evidence": "packages/objectql/src/validation/record-validator.ts:127",
143+
"note": "CAVEAT — server validation honors camelCase, but the client form reads snake_case max_length."
144+
},
145+
"minLength": {
146+
"status": "live",
147+
"evidence": "packages/objectql/src/validation/record-validator.ts:130",
148+
"note": "CAVEAT — server camel; client form reads min_length."
149+
},
150+
"referenceFilters": {
151+
"status": "dead",
152+
"evidence": "lookup dialog reads lookup_filters (LookupField.tsx:171) — entirely dead as authored (naming drift)"
153+
},
154+
"maxRating": {
155+
"status": "dead",
156+
"evidence": "RatingField reads `max` (RatingField.tsx:13) — dead + redundant with max"
157+
},
158+
"columnName": {
159+
"status": "dead",
160+
"evidence": "resolveColumnName (spec system-names.ts:182) has ZERO call sites; SQL driver hardcodes column = field key",
161+
"note": "DANGEROUS — advertises custom physical columns the driver never honors."
162+
},
163+
"searchable": {
164+
"status": "dead",
165+
"evidence": "field-level — no DDL/query consumer; search is object-level / view searchableFields"
166+
},
167+
"index": {
168+
"status": "dead",
169+
"evidence": "field-level — driver reads object indexes[] (sql-driver.ts:1252); field bool unused"
170+
},
171+
"externalId": {
172+
"status": "dead",
173+
"evidence": "field-level — upsert keys off dataset-level externalId (seed-loader.ts:175)"
174+
},
175+
"currencyConfig": {
176+
"status": "dead",
177+
"evidence": "nested config — renderers read flat currency/precision (CurrencyField.tsx:40); no currencyConfig consumer"
178+
},
179+
"vectorConfig": {
180+
"status": "dead",
181+
"evidence": "nested config — renderers read flat dimensions; no consumer, no vector-index DDL"
182+
},
183+
"fileAttachmentConfig": {
184+
"status": "dead",
185+
"evidence": "nested config — renderers read flat multiple/accept/maxSize (FileField.tsx:16); no size/type/virus enforcement in write path"
186+
},
187+
"encryptionConfig": {
188+
"status": "dead",
189+
"evidence": "no consumer; the only at-rest protection is the separate type:'secret' channel (engine.ts encryptSecretFields)"
190+
},
191+
"maskingRule": {
192+
"status": "dead",
193+
"evidence": "no consumer"
194+
},
195+
"auditTrail": {
196+
"status": "dead",
197+
"evidence": "no consumer (aspirational governance)"
198+
},
199+
"dataQuality": {
200+
"status": "dead",
201+
"evidence": "no consumer (aspirational governance)"
202+
},
203+
"cached": {
204+
"status": "dead",
205+
"evidence": "no consumer"
206+
},
207+
"dependencies": {
208+
"status": "dead",
209+
"evidence": "no consumer"
210+
},
211+
"trackFeedHistory": {
212+
"status": "dead",
213+
"evidence": "no consumer"
214+
},
215+
"caseSensitive": {
216+
"status": "dead",
217+
"evidence": "no consumer"
218+
},
219+
"writeRequiresMasterRead": {
220+
"status": "dead",
221+
"evidence": "no consumer (governance)"
222+
},
223+
"inlineTitle": {
224+
"status": "dead",
225+
"evidence": "master-detail explicit override — auto-derivation works (deriveMasterDetail.ts); overrides unread"
226+
},
227+
"inlineColumns": {
228+
"status": "dead",
229+
"evidence": "master-detail explicit override — unread"
230+
},
231+
"inlineAmountField": {
232+
"status": "dead",
233+
"evidence": "master-detail explicit override — unread"
234+
},
235+
"relatedList": {
236+
"status": "dead",
237+
"evidence": "detail-page related lists come from view metadata, not FieldSchema"
238+
},
239+
"relatedListTitle": {
240+
"status": "dead",
241+
"evidence": "master-detail explicit override — unread"
242+
},
243+
"relatedListColumns": {
244+
"status": "dead",
245+
"evidence": "master-detail explicit override — unread"
246+
}
78247
}
79248
}

0 commit comments

Comments
 (0)