Skip to content

lint: a field declared on an object with zero consumers (no view, form, page, flow, translation or seed reads it) passes os validate and os lint — HotCRM's retired local scanner is the design input #15922

Description

@os-zhuang

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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions