Skip to content

Commit 1b1f490

Browse files
os-zhuangclaude
andauthored
chore(spec): prune 7 dead field governance/compliance props (dead-surface plan) (#1946)
Removes FieldSchema props that implied data-protection/governance behavior but had zero runtime consumer — false promises (encryption/masking imply at-rest protection that never happened; the real channel is type:'secret'): encryptionConfig · maskingRule · auditTrail · cached · dataQuality · writeRequiresMasterRead · trackFeedHistory Cleanup: field.zod.ts schema + the now-unused EncryptionConfigSchema/MaskingRuleSchema imports + field.form.ts (5 form fields) + field.test.ts (writeRequiresMasterRead) + field.json ledger; reference docs regenerated. Kept caseSensitive + dependencies (potentially functional — conservative). Field *types* unchanged. Verified: liveness gate green (field 34 live/17 dead); full @objectstack/spec suite green (242 files, 6562 tests); grep-confirmed no object def/seed constructs them; ran the real `objectstack dev` showcase (37 plugins, 75 objects) — boots clean, Console 200, showcase_field_zoo parses+serves (code field no longer carries auditTrail), no field errors in the server log. Second batch of the dead-surface disposition plan (per-cluster verified PRs). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 97c55b3 commit 1b1f490

5 files changed

Lines changed: 11 additions & 59 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 7 dead field governance/compliance properties (dead-surface plan, P0/P2). Removes `FieldSchema` props that implied data-protection/governance behavior but had no runtime consumer — false promises (the real at-rest channel is `type: 'secret'`): `encryptionConfig`, `maskingRule`, `auditTrail`, `cached`, `dataQuality`, `writeRequiresMasterRead`, `trackFeedHistory`. Also drops the now-unused `EncryptionConfigSchema`/`MaskingRuleSchema` imports. Kept `caseSensitive` and `dependencies` (potentially functional — conservative). Field types unchanged.

packages/spec/liveness/field.json

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -184,42 +184,14 @@
184184
"status": "dead",
185185
"evidence": "nested config — renderers read flat multiple/accept/maxSize (FileField.tsx:16); no size/type/virus enforcement in write path"
186186
},
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-
},
207187
"dependencies": {
208188
"status": "dead",
209189
"evidence": "no consumer"
210190
},
211-
"trackFeedHistory": {
212-
"status": "dead",
213-
"evidence": "no consumer"
214-
},
215191
"caseSensitive": {
216192
"status": "dead",
217193
"evidence": "no consumer"
218194
},
219-
"writeRequiresMasterRead": {
220-
"status": "dead",
221-
"evidence": "no consumer (governance)"
222-
},
223195
"inlineTitle": {
224196
"status": "dead",
225197
"evidence": "master-detail explicit override — auto-derivation works (deriveMasterDetail.ts); overrides unread"

packages/spec/src/data/field.form.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ export const fieldForm = defineForm({
5858
fields: [
5959
{ field: 'expression', widget: 'textarea', helpText: 'CEL expression to calculate this field (makes it read-only)' },
6060
{ field: 'summaryOperations', type: 'composite', helpText: 'Roll-up summary configuration (for parent-child relationships)' },
61-
{ field: 'cached', type: 'composite', helpText: 'Caching configuration for computed fields' },
6261
],
6362
},
6463
{
@@ -78,12 +77,6 @@ export const fieldForm = defineForm({
7877
{ field: 'hidden', colSpan: 1, helpText: 'Hide field from default UI views' },
7978
{ field: 'searchable', colSpan: 1, helpText: 'Include in global search results' },
8079
{ field: 'sortable', colSpan: 1, helpText: 'Allow sorting lists by this field' },
81-
// Audit & History
82-
{ field: 'auditTrail', colSpan: 1, helpText: 'Track detailed changes with user and timestamp' },
83-
{ field: 'trackFeedHistory', colSpan: 1, helpText: 'Show changes in activity feed' },
84-
// Security & Compliance
85-
{ field: 'encryptionConfig', type: 'composite', colSpan: 2, helpText: 'Field-level encryption (GDPR/HIPAA/PCI-DSS)' },
86-
{ field: 'maskingRule', type: 'composite', colSpan: 2, helpText: 'Data masking rules for PII protection' },
8780
],
8881
},
8982
],

packages/spec/src/data/field.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@ describe('FieldSchema', () => {
279279
type: 'master_detail',
280280
reference: 'parent_object',
281281
deleteBehavior: 'cascade',
282-
writeRequiresMasterRead: true,
283282
};
284283

285284
const result = FieldSchema.parse(masterDetailField);

packages/spec/src/data/field.zod.ts

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import { z } from 'zod';
44
import { SystemIdentifierSchema } from '../shared/identifiers.zod';
55
import { ExpressionInputSchema } from '../shared/expression.zod';
6-
import { EncryptionConfigSchema } from '../system/encryption.zod';
7-
import { MaskingRuleSchema } from '../system/masking.zod';
86

97
/**
108
* Field Type Enum
@@ -401,7 +399,6 @@ export const FieldSchema = lazySchema(() => z.object({
401399
+ 'Required for relationship types. Used by $expand to resolve foreign key IDs into full objects.'
402400
),
403401
referenceFilters: z.array(z.string()).optional().describe('Filters applied to lookup dialogs (e.g. "active = true")'),
404-
writeRequiresMasterRead: z.boolean().optional().describe('If true, user needs read access to master record to edit this field'),
405402
deleteBehavior: z.enum(['set_null', 'cascade', 'restrict']).optional().default('set_null').describe('What happens if referenced record is deleted'),
406403
/**
407404
* Master-detail INLINE EDITING. On a child's `master_detail`/`lookup` field
@@ -477,27 +474,14 @@ export const FieldSchema = lazySchema(() => z.object({
477474
// File attachment field config
478475
fileAttachmentConfig: FileAttachmentConfigSchema.optional().describe('Configuration for file and attachment field types'),
479476

480-
/** Enhanced Security & Compliance */
481-
// Encryption configuration
482-
encryptionConfig: EncryptionConfigSchema.optional().describe('Field-level encryption configuration for sensitive data (GDPR/HIPAA/PCI-DSS)'),
483-
484-
// Data masking rules
485-
maskingRule: MaskingRuleSchema.optional().describe('Data masking rules for PII protection'),
486-
487-
// Audit trail
488-
auditTrail: z.boolean().default(false).describe('Enable detailed audit trail for this field (tracks all changes with user and timestamp)'),
489-
477+
// Pruned 2026-06 (dead in both layers — aspirational governance with no runtime
478+
// consumer; encryption/masking implied at-rest protection that never happened —
479+
// the real channel is type:'secret'). See
480+
// docs/audits/2026-06-dead-surface-disposition-plan.md (P0/P2 field prune):
481+
// encryptionConfig, maskingRule, auditTrail, cached, dataQuality.
482+
490483
/** Field Dependencies & Relationships */
491-
// Field dependencies
492484
dependencies: z.array(z.string()).optional().describe('Array of field names that this field depends on (for formulas, visibility rules, etc.)'),
493-
494-
/** Computed Field Optimization */
495-
// Computed field caching
496-
cached: ComputedFieldCacheSchema.optional().describe('Caching configuration for computed/formula fields'),
497-
498-
/** Data Quality & Governance */
499-
// Data quality rules
500-
dataQuality: DataQualityRulesSchema.optional().describe('Data quality validation and monitoring rules'),
501485

502486
/** Layout & Grouping */
503487
group: z.string().optional().describe('Field group name for organizing fields in forms and layouts (e.g., "contact_info", "billing", "system")'),
@@ -523,7 +507,6 @@ export const FieldSchema = lazySchema(() => z.object({
523507
system: z.boolean().optional().describe('Auto-injected system/audit field (e.g. created_at, updated_by, organization_id). Tools that surface system fields separately from author-declared business fields should branch on this flag.'),
524508
sortable: z.boolean().optional().default(true).describe('Whether field is sortable in list views'),
525509
inlineHelpText: z.string().optional().describe('Help text displayed below the field in forms'),
526-
trackFeedHistory: z.boolean().optional().describe('Track field changes in Chatter/activity feed (Salesforce pattern)'),
527510
caseSensitive: z.boolean().optional().describe('Whether text comparisons are case-sensitive'),
528511
autonumberFormat: z.string().optional().describe('Auto-number display format pattern (e.g., "CASE-{0000}")'),
529512
/** Indexing */

0 commit comments

Comments
 (0)