Filed by the director seat (#12708, summon #15, session_01TezFG8ZMrNH6n5VTNpPpdH) as the platform half of the hotcrm#1543 ruling (F, maintainer, 2026-09-05, verbatim 「1543 选 F」). Unlabelled on purpose — domain:*, type and priority are triage's. Not claimed.
The gap
An authored field that nothing in the app consumes — no view column, no form section, no page block, no flow node, no translation entry, no seed row — is schema-valid and passes os validate, os lint, tsc and the app's test suite. The declaration is inert and nothing in the toolchain says so.
This is the "declared but never read" class of #4698 applied to fields. #4698 closed via PR #4985 with the sharing-rule instance only (a has(...) condition the seeder skips); its own review recorded that the general "unread key" diagnostic was not built, and the tenant-unique instance went to the engine lane. The field-level detector has never existed in the platform.
Measured, on the one app that built its own
HotCRM (objectstack-ai/hotcrm, origin/main b1599507) carried scripts/scan-field-consumers.ts (573 lines) + test/field-consumer-scan.test.ts (318 lines) to answer exactly this question. The 2026-08-31 ruling in that repo's AGENTS.md ("Lint, validation, gates and diagnostics belong to the platform, uniformly … ⛔ Do not grow a gate farm") and hotcrm#1543's ruling F retire it there; this card is where the capability lands instead.
What that scanner measured, worth carrying over as design input rather than re-deriving:
- It walks the registered metadata stack only (six roots), never
test/ — so its ledger cannot see test fixtures, which is what made hotcrm#1543 a decision.
- It distinguishes consumer kinds: display roots (
views, pages, apps) vs carrier roots (translations, data, mappings), yielding verdicts live / display-only / carrier-only / inert. Whether the platform diagnostic keeps that taxonomy or reports a single "zero consumers" verdict is the first design question.
- It is object-aware: the same field name on two objects gets two verdicts (HotCRM measured
tax_rate, line_number, description as such pairs). A name-only scan misreports both.
- Its live ledger on HotCRM read 15 inert rows (1 on
crm_product, 14 more adjudicated on hotcrm#1199), all of which passed every platform check.
What is asked
An os lint rule (or os validate diagnostic — triage/devx to place it) that reports a declared field with zero consumers across the registered metadata stack, loudly, with the field's object and the roots scanned. Whether the report is a warning or a refusal, and whether display-only / carrier-only are separate verdicts, are the design questions for the implementing lane; the retired scanner's source (HotCRM git history before the #1543 retirement PR) is reference material, not code to port.
Dedup
search_issues in this repo for "lint declared field no consumer inert" returned #4698 (closed, the must-hit control — this card is its field-level remainder), #13935, #14446, #13832, #13053 (different subjects). No open card covers the field-level detector.
Refs: hotcrm#1543 (ruling F) · #4698 / PR #4985 · hotcrm#1198 / hotcrm#1199 (the adjudications the scanner fed) · objectstack#13848 (the 2026-08-31 hotcrm scope rulings).
Filed by the director seat (#12708, summon #15,
session_01TezFG8ZMrNH6n5VTNpPpdH) as the platform half of the hotcrm#1543 ruling (F, maintainer, 2026-09-05, verbatim 「1543 选 F」). Unlabelled on purpose —domain:*, type and priority are triage's. Not claimed.The gap
An authored field that nothing in the app consumes — no view column, no form section, no page block, no flow node, no translation entry, no seed row — is schema-valid and passes
os validate,os lint,tscand the app's test suite. The declaration is inert and nothing in the toolchain says so.This is the "declared but never read" class of #4698 applied to fields. #4698 closed via PR #4985 with the sharing-rule instance only (a
has(...)condition the seeder skips); its own review recorded that the general "unread key" diagnostic was not built, and the tenant-unique instance went to the engine lane. The field-level detector has never existed in the platform.Measured, on the one app that built its own
HotCRM (
objectstack-ai/hotcrm,origin/mainb1599507) carriedscripts/scan-field-consumers.ts(573 lines) +test/field-consumer-scan.test.ts(318 lines) to answer exactly this question. The 2026-08-31 ruling in that repo'sAGENTS.md("Lint, validation, gates and diagnostics belong to the platform, uniformly … ⛔ Do not grow a gate farm") and hotcrm#1543's ruling F retire it there; this card is where the capability lands instead.What that scanner measured, worth carrying over as design input rather than re-deriving:
test/— so its ledger cannot see test fixtures, which is what made hotcrm#1543 a decision.views,pages,apps) vs carrier roots (translations,data,mappings), yielding verdictslive/display-only/carrier-only/inert. Whether the platform diagnostic keeps that taxonomy or reports a single "zero consumers" verdict is the first design question.tax_rate,line_number,descriptionas such pairs). A name-only scan misreports both.crm_product, 14 more adjudicated on hotcrm#1199), all of which passed every platform check.What is asked
An
os lintrule (oros validatediagnostic — triage/devx to place it) that reports a declared field with zero consumers across the registered metadata stack, loudly, with the field's object and the roots scanned. Whether the report is a warning or a refusal, and whetherdisplay-only/carrier-onlyare separate verdicts, are the design questions for the implementing lane; the retired scanner's source (HotCRM git history before the #1543 retirement PR) is reference material, not code to port.Dedup
search_issuesin this repo for "lint declared field no consumer inert" returned #4698 (closed, the must-hit control — this card is its field-level remainder), #13935, #14446, #13832, #13053 (different subjects). No open card covers the field-level detector.Refs: hotcrm#1543 (ruling F) · #4698 / PR #4985 · hotcrm#1198 / hotcrm#1199 (the adjudications the scanner fed) · objectstack#13848 (the 2026-08-31 hotcrm scope rulings).