Created Started Finished
By: Tom Sydney Kerckhove <syd@cs-syd.eu>
Ask a field named after a project scalar for that scalar's type HsNewtypeNotSynonym refuses a synonym for a domain scalar, and nothing refuses the commoner shape: a field holding the primitive while the type that names it sits unused in the same repository. A rule over that population has to decide which Text is a domain scalar, and the obvious way is a word list of names, ids, keys and hashes. That is a rule that fires on a name rather than on a type: postBodyText, rowText and errorMessage are all text and all correctly typed, and the list that excludes them is one somebody maintains against a corpus they cannot see. So the lexicon is the project's own newtypes. A field whose name ends in the name of a scalar newtype the project defines, and whose type is that newtype's underlying primitive, is a site that went without what the author had already decided to write down. The finding is then not an opinion about domain-ness, and the message can name the type to use. A project that has named nothing gets nothing, which is the right incentive and also the rule's honest limit: it cannot start the practice, only keep it. Measured over src/ and app/ of six repositories, 2330 modules: forty-three sites, nineteen in nix-ci, nineteen in centjes, four in smos and one here. Sixteen of centjes's are Typst report inputs holding a Description that has already been rendered. That is a rendering boundary, where the scalar genuinely stops being the domain type, and it is the honest residue rather than a fault in the matching. It is also what an author can say in one line and a checker cannot, which puts the rule in bucket C: the site that declines carries an [allow:HsScalarNewtypeUnused] with its reason, and the clean resource holds such a site so that path is exercised rather than described. Project tier, because the newtype and the site rarely share a module. Every finding measured in nix-ci crosses a package boundary, so the resources are whole repositories of two packages rather than single modules. Maybe, [] and NonEmpty are read through, which was measured both ways round and adds three findings in nix-ci that are all real. The one field of a scalar newtype is left out whatever it is called, since unHostname is how Hostname is taken apart rather than a site that declined it. A rule that ships has to hold here, and the one site it finds is ErrorDecl.errorDeclName, which held the name of a declaration as a Text while this repository already defines DeclName for exactly that. DeclName rather than TypeHead: a TypeHead is the head of an applied type with its arguments dropped, deliberately lossy so that the obligation engine can ask whether a type is tested at all, where this field is a declaration's own name, read off the same tcdLName that every DeclName in the declaration list comes from. The store format is bumped because the rule brings two tables. Without it, a project run over package outputs written by an older build would find nothing for this rule instead of saying why it cannot.