You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(lint): report a declared field with zero consumers across the registered metadata roots (#15922) (#16323)
* feat(lint): report a declared field with zero consumers across the registered metadata roots
New advisory rule `field-no-consumers` (`validateFieldConsumers`): an object
field that nothing in the stack reads or displays is a warning on validate,
build and lint. Object-aware (the same name on two objects gets two
verdicts), carriers (translations, seeds, mappings, permission grants, flow
writes, prose) never count, and the finding carries the verdict, the carrier
paths a removal must clean, and the roots scanned. Exemptions are derived from
the spec: injected system columns, the ADR-0079 title field, master_detail.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
* docs: the CLI transcripts print 43 author-time rules now that field-no-consumers is registered
`check:docs-transcript-drift` holds the four hand-written `os validate` /
`os build` transcripts equal to what `authoringRulesFor()` derives; the new
registry entry moves that count from 42 to 43.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
---------
Co-authored-by: Claude Code <noreply@anthropic.com>
New advisory rule `field-no-consumers` (`validateFieldConsumers`): a field declared on an object that nothing in the stack reads or displays is reported as a `warning` by `os validate`, `os build` and `os lint`.
6
+
7
+
Until now such a field was schema-valid and passed every platform check — the declaration was inert and nothing in the toolchain said so. The rule is object-aware (the same field name on two objects gets two verdicts, resolved against the object whose declaration encloses each reference), and it distinguishes consumers from carriers: a view column, form section, page binding, flow node, dataset dimension, widget filter, formula, validation, hook or action is a consumer; a translation label, a seed value, an import-mapping column, a field-level permission grant or a flow that only writes the field is a carrier and never counts. The finding carries the verdict (`carrier-only` with the carrier paths a removal must clean, or `inert`), the roots scanned, and — when the name is also declared elsewhere — the other objects, so a per-object verdict is never mistaken for a name-level one.
8
+
9
+
Exempt, each derived from the spec rather than listed by hand: the registry-injected system columns an author re-declared, the record's title field (ADR-0079 `nameField` ladder), and `master_detail` fields (ADR-0035 — cascade delete, `controlled_by_parent` sharing and roll-ups read the relationship by declaration). A stack that declares no consumer root at all (objects only, or objects plus carriers) is not judged: its consumers live in another package. Test fixtures are never scanned.
10
+
11
+
Public surface: `validateFieldConsumers`, `FIELD_NO_CONSUMERS`, `FIELD_CONSUMER_ROOTS`, `FIELD_CARRIER_ROOTS`, and the `FieldConsumerFinding` / `FieldConsumerVerdict` / `FieldConsumerSeverity` types.
0 commit comments