@nielspeter/eess 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +94 -1
  2. package/dist/baseline-generator.d.ts +9 -0
  3. package/dist/baseline-generator.d.ts.map +1 -1
  4. package/dist/baseline-generator.js +9 -0
  5. package/dist/baseline-generator.js.map +1 -1
  6. package/dist/baseline.d.ts +1 -1
  7. package/dist/cardinality.d.ts.map +1 -1
  8. package/dist/cardinality.js +20 -5
  9. package/dist/cardinality.js.map +1 -1
  10. package/dist/cli-config.d.ts +106 -0
  11. package/dist/cli-config.d.ts.map +1 -0
  12. package/dist/cli-config.js +231 -0
  13. package/dist/cli-config.js.map +1 -0
  14. package/dist/collect-result.d.ts +94 -0
  15. package/dist/collect-result.d.ts.map +1 -0
  16. package/dist/collect-result.js +142 -0
  17. package/dist/collect-result.js.map +1 -0
  18. package/dist/combinators.d.ts +14 -0
  19. package/dist/combinators.d.ts.map +1 -1
  20. package/dist/combinators.js +53 -16
  21. package/dist/combinators.js.map +1 -1
  22. package/dist/condition.d.ts +37 -0
  23. package/dist/condition.d.ts.map +1 -1
  24. package/dist/condition.js +48 -1
  25. package/dist/condition.js.map +1 -1
  26. package/dist/correspondence.d.ts +30 -0
  27. package/dist/correspondence.d.ts.map +1 -1
  28. package/dist/correspondence.js +36 -1
  29. package/dist/correspondence.js.map +1 -1
  30. package/dist/dedupe-config-findings.d.ts.map +1 -1
  31. package/dist/dedupe-config-findings.js +27 -0
  32. package/dist/dedupe-config-findings.js.map +1 -1
  33. package/dist/diff-aware.d.ts +8 -9
  34. package/dist/diff-aware.d.ts.map +1 -1
  35. package/dist/diff-aware.js +38 -17
  36. package/dist/diff-aware.js.map +1 -1
  37. package/dist/emitter-findings.d.ts +167 -0
  38. package/dist/emitter-findings.d.ts.map +1 -0
  39. package/dist/emitter-findings.js +237 -0
  40. package/dist/emitter-findings.js.map +1 -0
  41. package/dist/errors.d.ts +48 -0
  42. package/dist/errors.d.ts.map +1 -1
  43. package/dist/errors.js +61 -0
  44. package/dist/errors.js.map +1 -1
  45. package/dist/exclusion-comments.d.ts +36 -1
  46. package/dist/exclusion-comments.d.ts.map +1 -1
  47. package/dist/exclusion-comments.js +185 -37
  48. package/dist/exclusion-comments.js.map +1 -1
  49. package/dist/execute-rule.d.ts +12 -3
  50. package/dist/execute-rule.d.ts.map +1 -1
  51. package/dist/execute-rule.js +184 -7
  52. package/dist/execute-rule.js.map +1 -1
  53. package/dist/file-walk.d.ts +22 -0
  54. package/dist/file-walk.d.ts.map +1 -0
  55. package/dist/file-walk.js +51 -0
  56. package/dist/file-walk.js.map +1 -0
  57. package/dist/format-json.d.ts +13 -0
  58. package/dist/format-json.d.ts.map +1 -1
  59. package/dist/format-json.js +24 -0
  60. package/dist/format-json.js.map +1 -1
  61. package/dist/index.d.ts +14 -46
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +13 -41
  64. package/dist/index.js.map +1 -1
  65. package/dist/internal.d.ts +55 -0
  66. package/dist/internal.d.ts.map +1 -0
  67. package/dist/internal.js +92 -0
  68. package/dist/internal.js.map +1 -0
  69. package/dist/mask-non-comment.d.ts +49 -0
  70. package/dist/mask-non-comment.d.ts.map +1 -0
  71. package/dist/mask-non-comment.js +261 -0
  72. package/dist/mask-non-comment.js.map +1 -0
  73. package/dist/owns-empty-discovery.d.ts.map +1 -1
  74. package/dist/owns-empty-discovery.js +12 -4
  75. package/dist/owns-empty-discovery.js.map +1 -1
  76. package/dist/path-suffix.d.ts +57 -0
  77. package/dist/path-suffix.d.ts.map +1 -0
  78. package/dist/path-suffix.js +73 -0
  79. package/dist/path-suffix.js.map +1 -0
  80. package/dist/predicate.d.ts +12 -0
  81. package/dist/predicate.d.ts.map +1 -1
  82. package/dist/predicate.js +20 -1
  83. package/dist/predicate.js.map +1 -1
  84. package/dist/preset-dispatch.d.ts +6 -34
  85. package/dist/preset-dispatch.d.ts.map +1 -1
  86. package/dist/preset-dispatch.js +30 -52
  87. package/dist/preset-dispatch.js.map +1 -1
  88. package/dist/report.d.ts +31 -7
  89. package/dist/report.d.ts.map +1 -1
  90. package/dist/report.js +174 -15
  91. package/dist/report.js.map +1 -1
  92. package/dist/rule-builder-like.d.ts +8 -2
  93. package/dist/rule-builder-like.d.ts.map +1 -1
  94. package/dist/rule-builder.d.ts +15 -0
  95. package/dist/rule-builder.d.ts.map +1 -1
  96. package/dist/rule-builder.js +41 -36
  97. package/dist/rule-builder.js.map +1 -1
  98. package/dist/rule-description.d.ts +50 -0
  99. package/dist/rule-description.d.ts.map +1 -1
  100. package/dist/rule-description.js +58 -0
  101. package/dist/rule-description.js.map +1 -1
  102. package/dist/selection-memo.d.ts +1 -3
  103. package/dist/selection-memo.d.ts.map +1 -1
  104. package/dist/selection-memo.js +1 -3
  105. package/dist/selection-memo.js.map +1 -1
  106. package/dist/silent-exclusion.d.ts +12 -0
  107. package/dist/silent-exclusion.d.ts.map +1 -1
  108. package/dist/silent-exclusion.js +22 -0
  109. package/dist/silent-exclusion.js.map +1 -1
  110. package/dist/terminal-builder.d.ts +29 -15
  111. package/dist/terminal-builder.d.ts.map +1 -1
  112. package/dist/terminal-builder.js +97 -51
  113. package/dist/terminal-builder.js.map +1 -1
  114. package/dist/vacuity-findings.d.ts +0 -6
  115. package/dist/vacuity-findings.d.ts.map +1 -1
  116. package/dist/vacuity-findings.js +27 -57
  117. package/dist/vacuity-findings.js.map +1 -1
  118. package/dist/violation.d.ts +22 -1
  119. package/dist/violation.d.ts.map +1 -1
  120. package/dist/violation.js.map +1 -1
  121. package/dist/watch.d.ts +71 -0
  122. package/dist/watch.d.ts.map +1 -0
  123. package/dist/watch.js +129 -0
  124. package/dist/watch.js.map +1 -0
  125. package/package.json +6 -1
@@ -1 +1 @@
1
- {"version":3,"file":"selection-memo.d.ts","sourceRoot":"","sources":["../src/selection-memo.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,aAAa,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,CAmB7E"}
1
+ {"version":3,"file":"selection-memo.d.ts","sourceRoot":"","sources":["../src/selection-memo.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,aAAa,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,CAmB7E"}
@@ -39,9 +39,7 @@ import { registerCacheReset } from './cache-registry.js';
39
39
  * const selectionOf = selectionMemo<ArchFunction>()
40
40
  *
41
41
  * private selected(): ArchFunction[] {
42
- * return selectionOf(this, () =>
43
- * this.getElements().filter((e) => this._predicates.every((p) => p.test(e))),
44
- * )
42
+ * return selectionOf(this, () => matchingElements(this.getElements(), this._predicates))
45
43
  * }
46
44
  */
47
45
  export function selectionMemo() {
@@ -1 +1 @@
1
- {"version":3,"file":"selection-memo.js","sourceRoot":"","sources":["../src/selection-memo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,aAAa;IAC3B,IAAI,KAAK,GAAG,IAAI,OAAO,EAAe,CAAA;IACtC,6EAA6E;IAC7E,0EAA0E;IAC1E,6EAA6E;IAC7E,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,0EAA0E;IAC1E,kBAAkB,CAAC,GAAG,EAAE;QACtB,KAAK,GAAG,IAAI,OAAO,EAAe,CAAA;IACpC,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAC/B,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAA;QACvC,MAAM,QAAQ,GAAG,OAAO,EAAE,CAAA;QAC1B,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QAC1B,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"selection-memo.js","sourceRoot":"","sources":["../src/selection-memo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,UAAU,aAAa;IAC3B,IAAI,KAAK,GAAG,IAAI,OAAO,EAAe,CAAA;IACtC,6EAA6E;IAC7E,0EAA0E;IAC1E,6EAA6E;IAC7E,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,0EAA0E;IAC1E,kBAAkB,CAAC,GAAG,EAAE;QACtB,KAAK,GAAG,IAAI,OAAO,EAAe,CAAA;IACpC,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAC/B,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAA;QACvC,MAAM,QAAQ,GAAG,OAAO,EAAE,CAAA;QAC1B,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QAC1B,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAA;AACH,CAAC"}
@@ -34,5 +34,17 @@ export declare function silent(pattern: string | RegExp): SilentExclusion;
34
34
  * Check whether a value is a SilentExclusion.
35
35
  */
36
36
  export declare function isSilent(value: unknown): value is SilentExclusion;
37
+ /**
38
+ * Record `patterns` into a builder's exclusion state, tracking which are silent.
39
+ *
40
+ * A free function over the two collections rather than a method, because the two
41
+ * builders that need it sit in incompatible class hierarchies — `eess-ts` has
42
+ * `RuleDeclaration -> TerminalBuilder -> RuleBuilder` where the kernel has two
43
+ * levels — so inheritance cannot share it. It mutates only what it is handed,
44
+ * so no private state crosses a package boundary.
45
+ *
46
+ * The two copies were byte-identical (`no-copy-paste` reported 100%).
47
+ */
48
+ export declare function recordExclusions(patterns: readonly (string | RegExp | SilentExclusion)[], exclusions: (string | RegExp)[], silentIndices: Set<number>): void;
37
49
  export {};
38
50
  //# sourceMappingURL=silent-exclusion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"silent-exclusion.d.ts","sourceRoot":"","sources":["../src/silent-exclusion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,QAAA,MAAM,MAAM,EAAE,OAAO,MAAmC,CAAA;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;IACjC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAA;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,eAAe,CAEhE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAEjE"}
1
+ {"version":3,"file":"silent-exclusion.d.ts","sourceRoot":"","sources":["../src/silent-exclusion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,QAAA,MAAM,MAAM,EAAE,OAAO,MAAmC,CAAA;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;IACjC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAA;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,eAAe,CAEhE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAEjE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,GAAG,eAAe,CAAC,EAAE,EACxD,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAC/B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GACzB,IAAI,CASN"}
@@ -27,4 +27,26 @@ export function silent(pattern) {
27
27
  export function isSilent(value) {
28
28
  return typeof value === 'object' && value !== null && SILENT in value;
29
29
  }
30
+ /**
31
+ * Record `patterns` into a builder's exclusion state, tracking which are silent.
32
+ *
33
+ * A free function over the two collections rather than a method, because the two
34
+ * builders that need it sit in incompatible class hierarchies — `eess-ts` has
35
+ * `RuleDeclaration -> TerminalBuilder -> RuleBuilder` where the kernel has two
36
+ * levels — so inheritance cannot share it. It mutates only what it is handed,
37
+ * so no private state crosses a package boundary.
38
+ *
39
+ * The two copies were byte-identical (`no-copy-paste` reported 100%).
40
+ */
41
+ export function recordExclusions(patterns, exclusions, silentIndices) {
42
+ for (const p of patterns) {
43
+ if (isSilent(p)) {
44
+ exclusions.push(p.pattern);
45
+ silentIndices.add(exclusions.length - 1);
46
+ }
47
+ else {
48
+ exclusions.push(p);
49
+ }
50
+ }
51
+ }
30
52
  //# sourceMappingURL=silent-exclusion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"silent-exclusion.js","sourceRoot":"","sources":["../src/silent-exclusion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,GAAkB,MAAM,CAAC,kBAAkB,CAAC,CAAA;AAcxD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,MAAM,CAAC,OAAwB;IAC7C,OAAO,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAA;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,CAAA;AACvE,CAAC"}
1
+ {"version":3,"file":"silent-exclusion.js","sourceRoot":"","sources":["../src/silent-exclusion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,GAAkB,MAAM,CAAC,kBAAkB,CAAC,CAAA;AAcxD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,MAAM,CAAC,OAAwB;IAC7C,OAAO,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAA;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,CAAA;AACvE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAwD,EACxD,UAA+B,EAC/B,aAA0B;IAE1B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;YAC1B,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAC1C,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { ArchViolation } from './violation.js';
2
+ import { type CollectResult } from './collect-result.js';
2
3
  import type { CheckOptions } from './check-options.js';
3
4
  import type { RuleMetadata } from './rule-metadata.js';
4
5
  import type { RuleDescription } from './rule-description.js';
@@ -21,20 +22,7 @@ import type { SilentExclusion } from './silent-exclusion.js';
21
22
  * family has no separate source/selection stages) or the zero came from
22
23
  * narrowing, not upstream emptiness.
23
24
  */
24
- export interface CollectResult {
25
- readonly violations: ArchViolation[];
26
- readonly examined: number;
27
- readonly sourceEmpty?: boolean;
28
- /**
29
- * A specific dead-glob explanation for a zero-examined rule, pre-formatted
30
- * by the dialect that computed it (`RuleBuilder.deadGlobDiagnosis()`) —
31
- * the kernel never touches picomatch or a project type to build this
32
- * itself. `undefined` means no diagnosis is available (no glob declared,
33
- * or the declared glob isn't actually dead), which falls through to the
34
- * generic zero-examined finding the same as before this field existed.
35
- */
36
- readonly deadGlob?: string;
37
- }
25
+ export type { CollectResult } from './collect-result.js';
38
26
  /**
39
27
  * Abstract base class for builders that share the terminal method pattern
40
28
  * (because, rule, excluding, check, warn, severity) but have different
@@ -106,11 +94,25 @@ export declare abstract class TerminalBuilder {
106
94
  describeRule(): RuleDescription;
107
95
  /** This rule's own account of itself, for `vacuity-findings.ts`. */
108
96
  private facts;
97
+ /**
98
+ * What every terminal method hands the filter pipeline.
99
+ *
100
+ * The same four fields were written out at each of `violations`, `check` and
101
+ * `warn` — `no-copy-paste` reported the three at 100% with `applyFilters ->
102
+ * executeCheck` as the only varying axis. `eess-ts`'s `TerminalBuilder`
103
+ * already had exactly this method; the kernel never adopted it.
104
+ *
105
+ * Not just tidier: three terminal methods that build the filter context
106
+ * separately can drift, and a field present on `.check()` but missing on
107
+ * `.violations()` means a rule fails in CI and passes when a preset
108
+ * aggregates it — the same finding, two answers.
109
+ */
110
+ private filterContext;
109
111
  /**
110
112
  * Execute the rule and return violations after exclusion filtering.
111
113
  * Does not throw — use for programmatic access (presets, aggregation).
112
114
  */
113
- violations(): ArchViolation[];
115
+ violations(): CollectResult;
114
116
  /**
115
117
  * Execute the rule and throw `ArchRuleError` if any violations are found.
116
118
  * This is the primary terminal method — use in test assertions.
@@ -166,6 +168,18 @@ export declare abstract class TerminalBuilder {
166
168
  * exist): the rule's own violations stand as computed.
167
169
  */
168
170
  private evidencedViolations;
171
+ /**
172
+ * Which finding a zero-examined rule earns, or `undefined` when it earned none
173
+ * because it declared the emptiness.
174
+ *
175
+ * Extracted from `evidencedViolations` under `check:arch`'s complexity rule.
176
+ * The precedence is the whole content and is unchanged: an empty source
177
+ * outranks every declaration (ADR-010 §3), an explicit declaration is
178
+ * satisfied, `.expectNonEmpty()` is unmet, a cardinality condition is
179
+ * satisfied by emptiness, and a nameable dead glob outranks the generic
180
+ * message because it is strictly more actionable.
181
+ */
182
+ private zeroExaminedFinding;
169
183
  /**
170
184
  * Execute the rule with the given severity.
171
185
  * `.severity('error')` is equivalent to `.check()`.
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-builder.d.ts","sourceRoot":"","sources":["../src/terminal-builder.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAK5D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,CAAA;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;;;;;;;;;GAUG;AACH,8BAAsB,eAAe;IACnC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,SAAS,CAAC,EAAE,YAAY,CAAA;IAClC,SAAS,CAAC,WAAW,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAK;IAC/C,SAAS,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAY;IACjD,2FAA2F;IAC3F,SAAS,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;IAEhC;;;;;;OAMG;IACH,WAAW,IAAI,IAAI;IAMnB;;;;;;;;;;;;OAYG;IACH,cAAc,IAAI,IAAI;IAMtB;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM7B;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IASlC;;;;;;;;;;OAUG;IACH,SAAS,CAAC,GAAG,QAAQ,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,eAAe,CAAC,EAAE,GAAG,IAAI;IAanE;;;OAGG;IACH,YAAY,IAAI,eAAe;IAW/B,oEAAoE;IACpE,OAAO,CAAC,KAAK;IAQb;;;OAGG;IACH,UAAU,IAAI,aAAa,EAAE;IAS7B;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAanC;;;;;OAKG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAalC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACH,OAAO,CAAC,mBAAmB;IAqB3B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAQvC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,SAAS,CAAC,IAAI,IAAI,IAAI;IAOtB;;;;;;;OAOG;IACH,SAAS,CAAC,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAKzD;;;;;;;OAOG;IACH,SAAS,CAAC,QAAQ,CAAC,iBAAiB,IAAI,aAAa;IAErD;;;;;;;OAOG;IACH,SAAS,CAAC,kBAAkB,IAAI,OAAO;CAGxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAiCrF"}
1
+ {"version":3,"file":"terminal-builder.d.ts","sourceRoot":"","sources":["../src/terminal-builder.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,KAAK,aAAa,EAAiB,MAAM,qBAAqB,CAAA;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAE5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAM5D;;;;;;;;;;;;;;;;;GAiBG;AACH,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD;;;;;;;;;;GAUG;AACH,8BAAsB,eAAe;IACnC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,SAAS,CAAC,EAAE,YAAY,CAAA;IAClC,SAAS,CAAC,WAAW,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAK;IAC/C,SAAS,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAY;IACjD,2FAA2F;IAC3F,SAAS,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;IAEhC;;;;;;OAMG;IACH,WAAW,IAAI,IAAI;IAMnB;;;;;;;;;;;;OAYG;IACH,cAAc,IAAI,IAAI;IAMtB;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM7B;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IASlC;;;;;;;;;;OAUG;IACH,SAAS,CAAC,GAAG,QAAQ,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,eAAe,CAAC,EAAE,GAAG,IAAI;IAMnE;;;OAGG;IACH,YAAY,IAAI,eAAe;IAQ/B,oEAAoE;IACpE,OAAO,CAAC,KAAK;IAQb;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,aAAa;IAcrB;;;OAGG;IACH,UAAU,IAAI,aAAa;IAa3B;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAInC;;;;;OAKG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAIlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACH,OAAO,CAAC,mBAAmB;IAwC3B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAQvC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,SAAS,CAAC,IAAI,IAAI,IAAI;IAOtB;;;;;;;OAOG;IACH,SAAS,CAAC,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAKzD;;;;;;;OAOG;IACH,SAAS,CAAC,QAAQ,CAAC,iBAAiB,IAAI,aAAa;IAErD;;;;;;;OAOG;IACH,SAAS,CAAC,kBAAkB,IAAI,OAAO;CAGxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAiCrF"}
@@ -1,6 +1,8 @@
1
1
  import { zeroExaminedViolation, deadGlobViolation, unmetExpectNonEmptyViolation, zeroLoadedSourceViolation, expiredExpectEmptyViolation, } from './vacuity-findings.js';
2
2
  import { UNSUPPRESSABLE } from './unsuppressable.js';
3
- import { isSilent } from './silent-exclusion.js';
3
+ import { collectResult } from './collect-result.js';
4
+ import { ruleDescriptionFrom } from './rule-description.js';
5
+ import { recordExclusions } from './silent-exclusion.js';
4
6
  import { executeCheck, executeWarn, applyFilters } from './execute-rule.js';
5
7
  import { shallowClone } from './shallow-clone.js';
6
8
  /**
@@ -87,15 +89,7 @@ export class TerminalBuilder {
87
89
  */
88
90
  excluding(...patterns) {
89
91
  const next = this.copy();
90
- for (const p of patterns) {
91
- if (isSilent(p)) {
92
- next._exclusions.push(p.pattern);
93
- next._silentIndices.add(next._exclusions.length - 1);
94
- }
95
- else {
96
- next._exclusions.push(p);
97
- }
98
- }
92
+ recordExclusions(patterns, next._exclusions, next._silentIndices);
99
93
  return next;
100
94
  }
101
95
  /**
@@ -103,14 +97,11 @@ export class TerminalBuilder {
103
97
  * Used by the `explain` CLI subcommand.
104
98
  */
105
99
  describeRule() {
106
- return {
100
+ return ruleDescriptionFrom({
101
+ metadata: this._metadata,
102
+ reason: this._reason,
107
103
  rule: this._metadata?.id ?? 'unnamed',
108
- id: this._metadata?.id,
109
- because: this._reason,
110
- suggestion: this._metadata?.suggestion,
111
- docs: this._metadata?.docs,
112
- imperative: this._metadata?.imperative,
113
- };
104
+ });
114
105
  }
115
106
  /** This rule's own account of itself, for `vacuity-findings.ts`. */
116
107
  facts() {
@@ -121,15 +112,45 @@ export class TerminalBuilder {
121
112
  };
122
113
  }
123
114
  /**
124
- * Execute the rule and return violations after exclusion filtering.
125
- * Does not throw — use for programmatic access (presets, aggregation).
115
+ * What every terminal method hands the filter pipeline.
116
+ *
117
+ * The same four fields were written out at each of `violations`, `check` and
118
+ * `warn` — `no-copy-paste` reported the three at 100% with `applyFilters ->
119
+ * executeCheck` as the only varying axis. `eess-ts`'s `TerminalBuilder`
120
+ * already had exactly this method; the kernel never adopted it.
121
+ *
122
+ * Not just tidier: three terminal methods that build the filter context
123
+ * separately can drift, and a field present on `.check()` but missing on
124
+ * `.violations()` means a rule fails in CI and passes when a preset
125
+ * aggregates it — the same finding, two answers.
126
126
  */
127
- violations() {
128
- return applyFilters(this.evidencedViolations(), {
127
+ filterContext() {
128
+ return {
129
129
  reason: this._reason,
130
130
  metadata: this._metadata,
131
131
  exclusions: this._exclusions,
132
132
  silentIndices: this._silentIndices,
133
+ // Bug 0258 round 2: an id-less rule still has a sentence, and every
134
+ // builder already implements `describeRule()`. Deferred, because this
135
+ // runs on every terminal call and is read only when an id-less rule meets
136
+ // an exclusion comment it cannot honour.
137
+ describe: () => this.describeRule().rule,
138
+ };
139
+ }
140
+ /**
141
+ * Execute the rule and return violations after exclusion filtering.
142
+ * Does not throw — use for programmatic access (presets, aggregation).
143
+ */
144
+ violations() {
145
+ const evidenced = this.evidencedViolations();
146
+ // `applyFilters` returns a bare array (and the SAME reference when no
147
+ // exclusion applies), so the evidence is re-stamped onto a fresh one here —
148
+ // stamping onto its return would mutate whatever a family memoized.
149
+ return collectResult(applyFilters(evidenced, this.filterContext()), {
150
+ examined: evidenced.examined,
151
+ sourceEmpty: evidenced.sourceEmpty,
152
+ declaredEmpty: evidenced.declaredEmpty,
153
+ deadGlob: evidenced.deadGlob,
133
154
  });
134
155
  }
135
156
  /**
@@ -139,12 +160,7 @@ export class TerminalBuilder {
139
160
  * @param options - Optional baseline, diff filtering, and output format
140
161
  */
141
162
  check(options) {
142
- executeCheck(this.evidencedViolations(), {
143
- reason: this._reason,
144
- metadata: this._metadata,
145
- exclusions: this._exclusions,
146
- silentIndices: this._silentIndices,
147
- }, options);
163
+ executeCheck(this.evidencedViolations(), this.filterContext(), options);
148
164
  }
149
165
  /**
150
166
  * Execute the rule and log violations to stderr. Does not throw.
@@ -153,12 +169,7 @@ export class TerminalBuilder {
153
169
  * @param options - Optional baseline, diff filtering, and output format
154
170
  */
155
171
  warn(options) {
156
- executeWarn(this.evidencedViolations(), {
157
- reason: this._reason,
158
- metadata: this._metadata,
159
- exclusions: this._exclusions,
160
- silentIndices: this._silentIndices,
161
- }, options);
172
+ executeWarn(this.evidencedViolations(), this.filterContext(), options);
162
173
  }
163
174
  /**
164
175
  * ADR-010 — the evidence gate. Calls `collectViolations()` once and turns
@@ -201,28 +212,63 @@ export class TerminalBuilder {
201
212
  * exist): the rule's own violations stand as computed.
202
213
  */
203
214
  evidencedViolations() {
204
- const { violations, examined, sourceEmpty, deadGlob } = this.collectViolations();
215
+ const collected = this.collectViolations();
216
+ const { examined, sourceEmpty, deadGlob } = collected;
217
+ const violations = [...collected];
218
+ // The evidence travels with every return below. A declaration reaches the
219
+ // emitter ON the receipt (ADR-014 §3) rather than through delivery options:
220
+ // one boolean over a sum cannot carry per-rule declarations, and this is the
221
+ // moment the terminal knows the fact and used to discard it.
222
+ const evidence = {
223
+ examined,
224
+ sourceEmpty,
225
+ deadGlob,
226
+ // `assertsCardinality()` is a declaration ONLY over zero subjects — ADR-010
227
+ // §3: "`.notExist()` over zero subjects is a declaration by construction."
228
+ // Over a non-empty selection it is an ordinary assertion that examined
229
+ // real units, and marking it declared there made every passing
230
+ // `.notExist()` expire the moment the emitter checked. Measured: it
231
+ // reddened six crossvalidate tests.
232
+ declaredEmpty: this._expectEmpty === true || (examined === 0 && this.assertsCardinality())
233
+ ? true
234
+ : undefined,
235
+ };
236
+ const withFinding = (f) => collectResult([...violations, f], evidence);
237
+ // Split out because threading the evidence through every branch pushed this
238
+ // method to cyclomatic complexity 11 and the repo's own `check:arch` said so.
239
+ // The ORDER is the content here, and it is unchanged.
205
240
  if (examined === 0) {
206
- if (sourceEmpty === true)
207
- return [...violations, zeroLoadedSourceViolation(this.facts())];
208
- if (this._expectEmpty === true)
209
- return violations;
210
- if (this._expectEmpty === false)
211
- return [...violations, unmetExpectNonEmptyViolation(this.facts())];
212
- if (this.assertsCardinality())
213
- return violations;
214
- // A specific dead-glob explanation, when the dialect could compute
215
- // one, outranks the generic zero-examined message — both name the
216
- // same underlying fact, and the specific one is strictly more
217
- // actionable (it names the actual glob and why it can never match).
218
- if (deadGlob !== undefined)
219
- return [...violations, deadGlobViolation(this.facts(), deadGlob)];
220
- return [...violations, zeroExaminedViolation(this.facts())];
241
+ const zero = this.zeroExaminedFinding(sourceEmpty, deadGlob);
242
+ return zero === undefined ? collectResult(violations, evidence) : withFinding(zero);
221
243
  }
222
244
  if (this._expectEmpty === true) {
223
- return [...violations, expiredExpectEmptyViolation(this.facts(), examined)];
245
+ return withFinding(expiredExpectEmptyViolation(this.facts(), examined));
224
246
  }
225
- return violations;
247
+ return collectResult(violations, evidence);
248
+ }
249
+ /**
250
+ * Which finding a zero-examined rule earns, or `undefined` when it earned none
251
+ * because it declared the emptiness.
252
+ *
253
+ * Extracted from `evidencedViolations` under `check:arch`'s complexity rule.
254
+ * The precedence is the whole content and is unchanged: an empty source
255
+ * outranks every declaration (ADR-010 §3), an explicit declaration is
256
+ * satisfied, `.expectNonEmpty()` is unmet, a cardinality condition is
257
+ * satisfied by emptiness, and a nameable dead glob outranks the generic
258
+ * message because it is strictly more actionable.
259
+ */
260
+ zeroExaminedFinding(sourceEmpty, deadGlob) {
261
+ if (sourceEmpty === true)
262
+ return zeroLoadedSourceViolation(this.facts());
263
+ if (this._expectEmpty === true)
264
+ return undefined;
265
+ if (this._expectEmpty === false)
266
+ return unmetExpectNonEmptyViolation(this.facts());
267
+ if (this.assertsCardinality())
268
+ return undefined;
269
+ if (deadGlob !== undefined)
270
+ return deadGlobViolation(this.facts(), deadGlob);
271
+ return zeroExaminedViolation(this.facts());
226
272
  }
227
273
  /**
228
274
  * Execute the rule with the given severity.
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-builder.js","sourceRoot":"","sources":["../src/terminal-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"terminal-builder.js","sourceRoot":"","sources":["../src/terminal-builder.ts"],"names":[],"mappings":"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"}
@@ -15,12 +15,6 @@ export interface RuleFacts {
15
15
  readonly reason: string | undefined;
16
16
  describeRule(): RuleDescription;
17
17
  }
18
- /**
19
- * The configuration finding for a rule that examined zero units with no
20
- * declared exemption — ADR-009 rule 2: named as a distinct cause (dead
21
- * selector, empty corpus, or an unreachable examining seam), not folded
22
- * into an ordinary violation message.
23
- */
24
18
  export declare function zeroExaminedViolation(facts: RuleFacts): ArchViolation;
25
19
  /**
26
20
  * The configuration finding for a rule that examined zero units BECAUSE one
@@ -1 +1 @@
1
- {"version":3,"file":"vacuity-findings.d.ts","sourceRoot":"","sources":["../src/vacuity-findings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAE5D;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,YAAY,IAAI,eAAe,CAAA;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAmBrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAenF;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAmB5E;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAmBzE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAkB7F"}
1
+ {"version":3,"file":"vacuity-findings.d.ts","sourceRoot":"","sources":["../src/vacuity-findings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAE5D;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,YAAY,IAAI,eAAe,CAAA;CAChC;AAuCD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAOrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAGnF;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAO5E;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAOzE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAM7F"}
@@ -4,13 +4,24 @@
4
4
  * selector, empty corpus, or an unreachable examining seam), not folded
5
5
  * into an ordinary violation message.
6
6
  */
7
- export function zeroExaminedViolation(facts) {
7
+ /**
8
+ * The shape every configuration finding in this module shares.
9
+ *
10
+ * All five differ ONLY in their `message`, which `no-copy-paste` reported as one
11
+ * cluster at 100%. Extracting it puts the contract they have in common in one
12
+ * place, and that contract is load-bearing rather than incidental:
13
+ *
14
+ * - `bypassFilters: true` — a vacuity finding must survive `--changed`, a
15
+ * baseline and an `eess-exclude`. A suppression mechanism that can suppress
16
+ * the complaint about itself is not a mechanism.
17
+ * - `file: ''`, `line: 0` — there is no source position, because the fault is
18
+ * the RULE, not a place in the code. That is also why the diff filter has to
19
+ * exempt these explicitly (see `diff-aware.ts`).
20
+ * - `suggestion` is the message — its own remedy, never the author's (bug 0021).
21
+ */
22
+ function configFinding(facts, message) {
8
23
  const described = facts.describeRule();
9
24
  const name = described.id ?? described.rule ?? facts.ruleClass.name;
10
- const message = `this rule examined zero units. If this is expected (the corpus is legitimately ` +
11
- `empty right now), declare it explicitly with .expectEmpty() — otherwise this is a ` +
12
- `dead selector, an empty project, or a rule that never reaches its own examining ` +
13
- `seam, and the fix is to widen the selection, not to suppress this finding.`;
14
25
  return {
15
26
  rule: described.rule ?? name,
16
27
  ruleId: described.id,
@@ -23,6 +34,13 @@ export function zeroExaminedViolation(facts) {
23
34
  bypassFilters: true,
24
35
  };
25
36
  }
37
+ export function zeroExaminedViolation(facts) {
38
+ const message = `this rule examined zero units. If this is expected (the corpus is legitimately ` +
39
+ `empty right now), declare it explicitly with .expectEmpty() — otherwise this is a ` +
40
+ `dead selector, an empty project, or a rule that never reaches its own examining ` +
41
+ `seam, and the fix is to widen the selection, not to suppress this finding.`;
42
+ return configFinding(facts, message);
43
+ }
26
44
  /**
27
45
  * The configuration finding for a rule that examined zero units BECAUSE one
28
46
  * of its declared globs is diagnosably dead — `deadGlob` is the pre-formed
@@ -33,20 +51,8 @@ export function zeroExaminedViolation(facts) {
33
51
  * diagnosis is available; see `evidencedViolations()`.
34
52
  */
35
53
  export function deadGlobViolation(facts, deadGlob) {
36
- const described = facts.describeRule();
37
- const name = described.id ?? described.rule ?? facts.ruleClass.name;
38
54
  const message = `this rule examined zero units — ${deadGlob}`;
39
- return {
40
- rule: described.rule ?? name,
41
- ruleId: described.id,
42
- element: name,
43
- file: '',
44
- line: 0,
45
- message,
46
- suggestion: message,
47
- because: facts.reason,
48
- bypassFilters: true,
49
- };
55
+ return configFinding(facts, message);
50
56
  }
51
57
  /**
52
58
  * The configuration finding for a `.expectNonEmpty()` declaration that
@@ -56,23 +62,11 @@ export function deadGlobViolation(facts, deadGlob) {
56
62
  * condition itself would otherwise tolerate.
57
63
  */
58
64
  export function unmetExpectNonEmptyViolation(facts) {
59
- const described = facts.describeRule();
60
- const name = described.id ?? described.rule ?? facts.ruleClass.name;
61
65
  const message = `this rule declared .expectNonEmpty() but examined zero units — the corpus this ` +
62
66
  `rule asserted should never be empty is empty right now. If that's still true, fix ` +
63
67
  `the selection (a glob typo, a missing folder); if the corpus legitimately can be ` +
64
68
  `empty, remove .expectNonEmpty().`;
65
- return {
66
- rule: described.rule ?? name,
67
- ruleId: described.id,
68
- element: name,
69
- file: '',
70
- line: 0,
71
- message,
72
- suggestion: message,
73
- because: facts.reason,
74
- bypassFilters: true,
75
- };
69
+ return configFinding(facts, message);
76
70
  }
77
71
  /**
78
72
  * The configuration finding for the ADR-010 part 3 precedence case: the
@@ -81,44 +75,20 @@ export function unmetExpectNonEmptyViolation(facts) {
81
75
  * "widen the selection", there is no selection yet to widen).
82
76
  */
83
77
  export function zeroLoadedSourceViolation(facts) {
84
- const described = facts.describeRule();
85
- const name = described.id ?? described.rule ?? facts.ruleClass.name;
86
78
  const message = `this rule's source loaded zero units before any selection ran — an empty project, ` +
87
79
  `an unreadable tsconfig, or a glob resolving to nothing. This outranks any ` +
88
80
  `.expectEmpty() declaration and any condition satisfied by emptiness: fix the ` +
89
81
  `project/source configuration, not the rule.`;
90
- return {
91
- rule: described.rule ?? name,
92
- ruleId: described.id,
93
- element: name,
94
- file: '',
95
- line: 0,
96
- message,
97
- suggestion: message,
98
- because: facts.reason,
99
- bypassFilters: true,
100
- };
82
+ return configFinding(facts, message);
101
83
  }
102
84
  /**
103
85
  * The configuration finding for a `.expectEmpty()` declaration that has
104
86
  * expired — ADR-010 part 3: the number IS the finding, so it is named.
105
87
  */
106
88
  export function expiredExpectEmptyViolation(facts, examined) {
107
- const described = facts.describeRule();
108
- const name = described.id ?? described.rule ?? facts.ruleClass.name;
109
89
  const message = `this rule declared .expectEmpty() but examined ${String(examined)} unit(s) — the ` +
110
90
  `declaration has expired. If the corpus legitimately grew past empty, remove ` +
111
91
  `.expectEmpty() from this rule; the underlying violations (if any) above still stand.`;
112
- return {
113
- rule: described.rule ?? name,
114
- ruleId: described.id,
115
- element: name,
116
- file: '',
117
- line: 0,
118
- message,
119
- suggestion: message,
120
- because: facts.reason,
121
- bypassFilters: true,
122
- };
92
+ return configFinding(facts, message);
123
93
  }
124
94
  //# sourceMappingURL=vacuity-findings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vacuity-findings.js","sourceRoot":"","sources":["../src/vacuity-findings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vacuity-findings.js","sourceRoot":"","sources":["../src/vacuity-findings.ts"],"names":[],"mappings":"AAiBA;;;;;GAKG;AACH;;;;;;;;;;;;;;GAcG;AACH,SAAS,aAAa,CAAC,KAAgB,EAAE,OAAe;IACtD,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,EAAE,CAAA;IACtC,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,IAAI,SAAS,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,CAAA;IACnE,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,IAAI;QAC5B,MAAM,EAAE,SAAS,CAAC,EAAE;QACpB,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,CAAC;QACP,OAAO;QACP,UAAU,EAAE,OAAO;QACnB,OAAO,EAAE,KAAK,CAAC,MAAM;QACrB,aAAa,EAAE,IAAI;KACpB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAgB;IACpD,MAAM,OAAO,GACX,iFAAiF;QACjF,oFAAoF;QACpF,kFAAkF;QAClF,4EAA4E,CAAA;IAC9E,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAgB,EAAE,QAAgB;IAClE,MAAM,OAAO,GAAG,mCAAmC,QAAQ,EAAE,CAAA;IAC7D,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,4BAA4B,CAAC,KAAgB;IAC3D,MAAM,OAAO,GACX,iFAAiF;QACjF,oFAAoF;QACpF,mFAAmF;QACnF,kCAAkC,CAAA;IACpC,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAgB;IACxD,MAAM,OAAO,GACX,oFAAoF;QACpF,4EAA4E;QAC5E,+EAA+E;QAC/E,6CAA6C,CAAA;IAC/C,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAAgB,EAAE,QAAgB;IAC5E,MAAM,OAAO,GACX,kDAAkD,MAAM,CAAC,QAAQ,CAAC,iBAAiB;QACnF,8EAA8E;QAC9E,sFAAsF,CAAA;IACxF,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC"}
@@ -32,6 +32,27 @@ export interface ArchViolation {
32
32
  file: string;
33
33
  /** Line number where the violating element starts */
34
34
  line: number;
35
+ /**
36
+ * Other files this one finding concerns, when it concerns more than one.
37
+ *
38
+ * A finding carries a single `file`, which is where it is REPORTED. Some
39
+ * findings are about a relationship — two bodies that duplicate each other,
40
+ * a cluster of them — and for those, one path cannot say what the finding is
41
+ * about. Anything that filters by file must see the rest, or it hides the
42
+ * finding from the very person who caused it.
43
+ *
44
+ * Bug 0239 is the measured case: a duplicate-body finding anchors on whichever
45
+ * member the source walk reached first, so a developer who pasted a body into
46
+ * a second file ran `--changed` and was told nothing — the finding sat on the
47
+ * file they had not touched, and which file that was came down to how the OS
48
+ * enumerated a directory.
49
+ *
50
+ * Optional, and additive. A single-file finding omits it and every existing
51
+ * producer keeps compiling; a consumer that ignores it behaves exactly as
52
+ * before. `file` remains where the finding is reported, so messages, editors
53
+ * and baselines are unaffected.
54
+ */
55
+ relatedFiles?: readonly string[];
35
56
  /** Human-readable description of what went wrong */
36
57
  message: string;
37
58
  /**
@@ -73,7 +94,7 @@ export interface ArchViolation {
73
94
  *
74
95
  * The baseline persists it and refuses to compare a stored measurement
75
96
  * against a current one carrying a different unit
76
- * ([bug 0171](../../../work/bugs/0171-a-metric-unit-change-silently-loosens-every-baselined-ratchet.md)).
97
+ * ([bug 0171](../../../work/bugs/fixed/0171-a-metric-unit-change-silently-loosens-every-baselined-ratchet.md)).
77
98
  * Without it, changing what a metric COUNTS silently moved every baselined
78
99
  * ceiling: `linesOfCode` went from span lines to code lines, entries kept
79
100
  * matching on identity, and a class could then grow to roughly three times
@@ -1 +1 @@
1
- {"version":3,"file":"violation.d.ts","sourceRoot":"","sources":["../src/violation.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAA;IACX,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAA;IACnB,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAA;IACf,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAA;IACZ,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0GAA0G;IAC1G,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC3B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;;;;;;GAWG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,OAAO,GAAG,MAAM,GACzB,OAAO,GAAG,MAAM,CAElB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAEtE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,CAE1D;AA0GD,0EAA0E;AAC1E,wBAAgB,kBAAkB,IAAI,SAAS;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB,EAAE,CAEF;AAED,mFAAmF;AACnF,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAID,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CA6DnF"}
1
+ {"version":3,"file":"violation.d.ts","sourceRoot":"","sources":["../src/violation.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAA;IACX,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAA;IACnB,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAA;IACf,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;;;;;;;;;;;;;;OAmBG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0GAA0G;IAC1G,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC3B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;;;;;;GAWG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,OAAO,GAAG,MAAM,GACzB,OAAO,GAAG,MAAM,CAElB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAEtE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,CAE1D;AA0GD,0EAA0E;AAC1E,wBAAgB,kBAAkB,IAAI,SAAS;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB,EAAE,CAEF;AAED,mFAAmF;AACnF,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAID,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CA6DnF"}