@nielspeter/eess 0.2.2 → 0.5.0

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 (209) hide show
  1. package/README.md +97 -4
  2. package/dist/assertion-advice.d.ts +26 -0
  3. package/dist/assertion-advice.d.ts.map +1 -0
  4. package/dist/assertion-advice.js +29 -0
  5. package/dist/assertion-advice.js.map +1 -0
  6. package/dist/baseline-generator.d.ts +9 -0
  7. package/dist/baseline-generator.d.ts.map +1 -1
  8. package/dist/baseline-generator.js +9 -0
  9. package/dist/baseline-generator.js.map +1 -1
  10. package/dist/baseline.d.ts +69 -4
  11. package/dist/baseline.d.ts.map +1 -1
  12. package/dist/baseline.js +119 -13
  13. package/dist/baseline.js.map +1 -1
  14. package/dist/cache-registry.d.ts +14 -0
  15. package/dist/cache-registry.d.ts.map +1 -0
  16. package/dist/cache-registry.js +37 -0
  17. package/dist/cache-registry.js.map +1 -0
  18. package/dist/cardinality.d.ts +35 -0
  19. package/dist/cardinality.d.ts.map +1 -0
  20. package/dist/cardinality.js +80 -0
  21. package/dist/cardinality.js.map +1 -0
  22. package/dist/check-options.d.ts +14 -0
  23. package/dist/check-options.d.ts.map +1 -1
  24. package/dist/cli-config.d.ts +59 -0
  25. package/dist/cli-config.d.ts.map +1 -0
  26. package/dist/cli-config.js +84 -0
  27. package/dist/cli-config.js.map +1 -0
  28. package/dist/collect-result.d.ts +94 -0
  29. package/dist/collect-result.d.ts.map +1 -0
  30. package/dist/collect-result.js +142 -0
  31. package/dist/collect-result.js.map +1 -0
  32. package/dist/combinators.d.ts +14 -0
  33. package/dist/combinators.d.ts.map +1 -1
  34. package/dist/combinators.js +53 -16
  35. package/dist/combinators.js.map +1 -1
  36. package/dist/comment-suppression.d.ts +60 -0
  37. package/dist/comment-suppression.d.ts.map +1 -0
  38. package/dist/comment-suppression.js +89 -0
  39. package/dist/comment-suppression.js.map +1 -0
  40. package/dist/condition.d.ts +43 -0
  41. package/dist/condition.d.ts.map +1 -1
  42. package/dist/condition.js +48 -1
  43. package/dist/condition.js.map +1 -1
  44. package/dist/correspondence-core.d.ts +35 -0
  45. package/dist/correspondence-core.d.ts.map +1 -0
  46. package/dist/correspondence-core.js +38 -0
  47. package/dist/correspondence-core.js.map +1 -0
  48. package/dist/correspondence.d.ts +57 -5
  49. package/dist/correspondence.d.ts.map +1 -1
  50. package/dist/correspondence.js +74 -5
  51. package/dist/correspondence.js.map +1 -1
  52. package/dist/dedupe-config-findings.d.ts +56 -0
  53. package/dist/dedupe-config-findings.d.ts.map +1 -0
  54. package/dist/dedupe-config-findings.js +101 -0
  55. package/dist/dedupe-config-findings.js.map +1 -0
  56. package/dist/define.d.ts +44 -2
  57. package/dist/define.d.ts.map +1 -1
  58. package/dist/define.js +45 -4
  59. package/dist/define.js.map +1 -1
  60. package/dist/diff-aware.d.ts +8 -1
  61. package/dist/diff-aware.d.ts.map +1 -1
  62. package/dist/diff-aware.js +39 -9
  63. package/dist/diff-aware.js.map +1 -1
  64. package/dist/diff-disclosure.d.ts +72 -0
  65. package/dist/diff-disclosure.d.ts.map +1 -0
  66. package/dist/diff-disclosure.js +110 -0
  67. package/dist/diff-disclosure.js.map +1 -0
  68. package/dist/disk-set.d.ts +27 -0
  69. package/dist/disk-set.d.ts.map +1 -0
  70. package/dist/disk-set.js +12 -0
  71. package/dist/disk-set.js.map +1 -0
  72. package/dist/edge-coverage.d.ts +96 -0
  73. package/dist/edge-coverage.d.ts.map +1 -0
  74. package/dist/edge-coverage.js +108 -0
  75. package/dist/edge-coverage.js.map +1 -0
  76. package/dist/emitter-findings.d.ts +167 -0
  77. package/dist/emitter-findings.d.ts.map +1 -0
  78. package/dist/emitter-findings.js +237 -0
  79. package/dist/emitter-findings.js.map +1 -0
  80. package/dist/errors.d.ts +73 -0
  81. package/dist/errors.d.ts.map +1 -1
  82. package/dist/errors.js +93 -0
  83. package/dist/errors.js.map +1 -1
  84. package/dist/exclusion-comments.d.ts +36 -1
  85. package/dist/exclusion-comments.d.ts.map +1 -1
  86. package/dist/exclusion-comments.js +185 -37
  87. package/dist/exclusion-comments.js.map +1 -1
  88. package/dist/execute-rule.d.ts +11 -1
  89. package/dist/execute-rule.d.ts.map +1 -1
  90. package/dist/execute-rule.js +220 -11
  91. package/dist/execute-rule.js.map +1 -1
  92. package/dist/file-walk.d.ts +22 -0
  93. package/dist/file-walk.d.ts.map +1 -0
  94. package/dist/file-walk.js +51 -0
  95. package/dist/file-walk.js.map +1 -0
  96. package/dist/format-github.d.ts.map +1 -1
  97. package/dist/format-github.js +37 -5
  98. package/dist/format-github.js.map +1 -1
  99. package/dist/format-json.d.ts +96 -1
  100. package/dist/format-json.d.ts.map +1 -1
  101. package/dist/format-json.js +94 -9
  102. package/dist/format-json.js.map +1 -1
  103. package/dist/format.d.ts +4 -2
  104. package/dist/format.d.ts.map +1 -1
  105. package/dist/format.js +41 -19
  106. package/dist/format.js.map +1 -1
  107. package/dist/glob-site.d.ts +232 -0
  108. package/dist/glob-site.d.ts.map +1 -0
  109. package/dist/glob-site.js +156 -0
  110. package/dist/glob-site.js.map +1 -0
  111. package/dist/identity-root.d.ts +55 -0
  112. package/dist/identity-root.d.ts.map +1 -0
  113. package/dist/identity-root.js +170 -0
  114. package/dist/identity-root.js.map +1 -0
  115. package/dist/index.d.ts +18 -12
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +12 -10
  118. package/dist/index.js.map +1 -1
  119. package/dist/internal.d.ts +55 -0
  120. package/dist/internal.d.ts.map +1 -0
  121. package/dist/internal.js +92 -0
  122. package/dist/internal.js.map +1 -0
  123. package/dist/mask-non-comment.d.ts +49 -0
  124. package/dist/mask-non-comment.d.ts.map +1 -0
  125. package/dist/mask-non-comment.js +261 -0
  126. package/dist/mask-non-comment.js.map +1 -0
  127. package/dist/owns-empty-discovery.d.ts +5 -0
  128. package/dist/owns-empty-discovery.d.ts.map +1 -0
  129. package/dist/owns-empty-discovery.js +85 -0
  130. package/dist/owns-empty-discovery.js.map +1 -0
  131. package/dist/path-suffix.d.ts +57 -0
  132. package/dist/path-suffix.d.ts.map +1 -0
  133. package/dist/path-suffix.js +73 -0
  134. package/dist/path-suffix.js.map +1 -0
  135. package/dist/path-universe.d.ts +44 -0
  136. package/dist/path-universe.d.ts.map +1 -0
  137. package/dist/path-universe.js +21 -0
  138. package/dist/path-universe.js.map +1 -0
  139. package/dist/predicate.d.ts +45 -0
  140. package/dist/predicate.d.ts.map +1 -1
  141. package/dist/predicate.js +20 -1
  142. package/dist/predicate.js.map +1 -1
  143. package/dist/preset-dispatch.d.ts +6 -15
  144. package/dist/preset-dispatch.d.ts.map +1 -1
  145. package/dist/preset-dispatch.js +35 -17
  146. package/dist/preset-dispatch.js.map +1 -1
  147. package/dist/project-relative.d.ts +25 -0
  148. package/dist/project-relative.d.ts.map +1 -0
  149. package/dist/project-relative.js +54 -0
  150. package/dist/project-relative.js.map +1 -0
  151. package/dist/report.d.ts +42 -12
  152. package/dist/report.d.ts.map +1 -1
  153. package/dist/report.js +190 -14
  154. package/dist/report.js.map +1 -1
  155. package/dist/rule-builder-like.d.ts +17 -0
  156. package/dist/rule-builder-like.d.ts.map +1 -0
  157. package/dist/rule-builder-like.js +2 -0
  158. package/dist/rule-builder-like.js.map +1 -0
  159. package/dist/rule-builder.d.ts +124 -84
  160. package/dist/rule-builder.d.ts.map +1 -1
  161. package/dist/rule-builder.js +230 -181
  162. package/dist/rule-builder.js.map +1 -1
  163. package/dist/rule-description.d.ts +83 -1
  164. package/dist/rule-description.d.ts.map +1 -1
  165. package/dist/rule-description.js +75 -1
  166. package/dist/rule-description.js.map +1 -1
  167. package/dist/rule-metadata.d.ts +20 -3
  168. package/dist/rule-metadata.d.ts.map +1 -1
  169. package/dist/selection-memo.d.ts +45 -0
  170. package/dist/selection-memo.d.ts.map +1 -0
  171. package/dist/selection-memo.js +66 -0
  172. package/dist/selection-memo.js.map +1 -0
  173. package/dist/shallow-clone.d.ts +20 -0
  174. package/dist/shallow-clone.d.ts.map +1 -0
  175. package/dist/shallow-clone.js +27 -0
  176. package/dist/shallow-clone.js.map +1 -0
  177. package/dist/silent-exclusion.d.ts +12 -0
  178. package/dist/silent-exclusion.d.ts.map +1 -1
  179. package/dist/silent-exclusion.js +22 -0
  180. package/dist/silent-exclusion.js.map +1 -1
  181. package/dist/stderr.d.ts +16 -0
  182. package/dist/stderr.d.ts.map +1 -0
  183. package/dist/stderr.js +73 -0
  184. package/dist/stderr.js.map +1 -0
  185. package/dist/terminal-builder.d.ts +224 -10
  186. package/dist/terminal-builder.d.ts.map +1 -1
  187. package/dist/terminal-builder.js +336 -46
  188. package/dist/terminal-builder.js.map +1 -1
  189. package/dist/type-guards.d.ts +38 -0
  190. package/dist/type-guards.d.ts.map +1 -0
  191. package/dist/type-guards.js +42 -0
  192. package/dist/type-guards.js.map +1 -0
  193. package/dist/unsuppressable.d.ts +54 -0
  194. package/dist/unsuppressable.d.ts.map +1 -0
  195. package/dist/unsuppressable.js +76 -0
  196. package/dist/unsuppressable.js.map +1 -0
  197. package/dist/vacuity-findings.d.ts +49 -0
  198. package/dist/vacuity-findings.d.ts.map +1 -0
  199. package/dist/vacuity-findings.js +94 -0
  200. package/dist/vacuity-findings.js.map +1 -0
  201. package/dist/violation.d.ts +173 -4
  202. package/dist/violation.d.ts.map +1 -1
  203. package/dist/violation.js +262 -1
  204. package/dist/violation.js.map +1 -1
  205. package/dist/watch.d.ts +71 -0
  206. package/dist/watch.d.ts.map +1 -0
  207. package/dist/watch.js +129 -0
  208. package/dist/watch.js.map +1 -0
  209. package/package.json +6 -1
@@ -1,5 +1,63 @@
1
- import { isSilent } from './silent-exclusion.js';
2
- import { executeCheck, executeWarn, applyFilters } from './execute-rule.js';
1
+ import { assertionAdviceFor } from './assertion-advice.js';
2
+ import { collectResult } from './collect-result.js';
3
+ import { selectMatching, matchingElements } from './correspondence.js';
4
+ import { recordPredicate } from './predicate.js';
5
+ import { countDeclaredGlobs, stampGlobs } from './glob-site.js';
6
+ import { TerminalBuilder, assertionLessViolation } from './terminal-builder.js';
7
+ import { assertsCardinality as conditionAssertsCardinality } from './cardinality.js';
8
+ import { ruleDescriptionOf, ruleDescriptionFrom } from './rule-description.js';
9
+ import { conditionContextFrom } from './condition.js';
10
+ /**
11
+ * A declared glob's own label in a dead-glob finding — the predicate/
12
+ * condition's description, disambiguated with the literal glob only when
13
+ * more than one site shares the description (a variadic predicate like
14
+ * `importFrom(...globs)` already spells every glob into its own
15
+ * description, so a substring test would collapse the one case this exists
16
+ * to separate — keyed on the site COUNT instead).
17
+ */
18
+ function describeOrigin(description, glob, siteCount) {
19
+ return siteCount > 1 ? `${description} ("${glob.glob}")` : description;
20
+ }
21
+ /**
22
+ * The actual walk `RuleBuilder.globs()` delegates to — a free function
23
+ * rather than a method body, to keep the class itself under this repo's own
24
+ * 300-line class-length gate (`arch.internal.rules.ts`).
25
+ */
26
+ /**
27
+ * The globs a rule declares, stamped with where each came from.
28
+ *
29
+ * Exported (as family plumbing) so `eess-ts` can call it instead of keeping its
30
+ * own copy — they were 94% similar, and the difference was not cosmetic: only
31
+ * the eess-ts copy honoured `originLabel`. The kernel's `Predicate` has carried
32
+ * that field all along and this function ignored it, so a preset's label was
33
+ * dropped for `eess-md`, `eess-mermaid` and `eess-gherkin`. Found by unifying.
34
+ */
35
+ export function declaredGlobsOf(
36
+ // `readonly`, widened so a caller holding a frozen declaration can pass it
37
+ // without a copy. Strictly more permissive; the body only iterates.
38
+ predicates, conditions) {
39
+ const trees = [];
40
+ for (const predicate of predicates) {
41
+ if (predicate.globs) {
42
+ const count = countDeclaredGlobs(predicate.globs);
43
+ trees.push(stampGlobs(predicate.globs, 'selector', (g) =>
44
+ // A preset's `originLabel` names the option the user wrote rather
45
+ // than the calls it expanded into. Used VERBATIM, skipping
46
+ // `describeOrigin`: that appends `("glob")` to disambiguate a
47
+ // predicate holding several sites, and a label already names exactly
48
+ // one option and one glob — left in, the finding read
49
+ // `shared: "**/x/**" ("**/x/**")`.
50
+ predicate.originLabel ?? describeOrigin(predicate.description, g, count)));
51
+ }
52
+ }
53
+ for (const condition of conditions) {
54
+ if (condition.globs) {
55
+ const count = countDeclaredGlobs(condition.globs);
56
+ trees.push(stampGlobs(condition.globs, 'condition', (g) => describeOrigin(condition.description, g, count)));
57
+ }
58
+ }
59
+ return trees;
60
+ }
3
61
  /**
4
62
  * Abstract base class for all rule builders.
5
63
  *
@@ -9,29 +67,46 @@ import { executeCheck, executeWarn, applyFilters } from './execute-rule.js';
9
67
  * 3. Add condition methods that call `addCondition()`
10
68
  *
11
69
  * The builder accumulates predicates and conditions. Nothing executes
12
- * until a terminal method (`.check()`, `.warn()`, `.severity()`) is called.
70
+ * until a terminal method (`.check()`, `.warn()`, `.severity()`) is called —
71
+ * inherited from {@link TerminalBuilder} (plan 0088 Phase 4), which also
72
+ * supplies `because`/`rule`/`excluding`/`violations`/`expectEmpty`/
73
+ * `expectNonEmpty` and the ADR-010 evidence gate. `RuleBuilder` keeps its own
74
+ * `<T, P>` two-param generic — `P` is the dialect's project type, kept
75
+ * separate from `TerminalBuilder` (which has no project concept, since
76
+ * `correspondence()`, `SmellBuilder`, and the graphql builders don't share a
77
+ * uniform notion of "one project") — every builder across all five dialects
78
+ * depends on this exact two-param signature, so it is not replaced by the
79
+ * fold, only extended.
13
80
  */
14
- export class RuleBuilder {
81
+ export class RuleBuilder extends TerminalBuilder {
15
82
  project;
16
83
  _predicates = [];
17
84
  _conditions = [];
18
- _reason;
19
- _metadata;
20
- _exclusions = [];
21
- _silentIndices = new Set();
22
85
  _phase = 'predicate';
86
+ /** Whether `.should()` was ever reached — bug 0155 state 3/4 vs state 1. */
87
+ _reachedShould = false;
88
+ /**
89
+ * Descriptions of predicate-only methods used AFTER `.should()` — bug 0155
90
+ * state 2. A dual-use method dispatches to a condition in that phase and
91
+ * never lands here, so anything recorded is genuinely a filter written where
92
+ * an assertion was meant.
93
+ */
94
+ _misplaced = [];
23
95
  constructor(project) {
96
+ super();
24
97
  this.project = project;
25
98
  }
26
99
  // --- Chain methods (grammar transitions) ---
27
100
  /**
28
- * Begin the predicate phase. Returns `this` for chaining.
101
+ * Begin the predicate phase. Returns a COPY — a held selection is never
102
+ * edited by narrowing it (see `TerminalBuilder.copy()`).
29
103
  * Purely a readability marker — `.that().haveNameMatching(...)` reads like English.
30
104
  * Explicitly resets phase to 'predicate' — defensive against `.should().that()` misuse.
31
105
  */
32
106
  that() {
33
- this._phase = 'predicate';
34
- return this;
107
+ const next = this.copy();
108
+ next._phase = 'predicate';
109
+ return next;
35
110
  }
36
111
  /**
37
112
  * Add another predicate (AND). Returns `this` for chaining.
@@ -48,6 +123,7 @@ export class RuleBuilder {
48
123
  should() {
49
124
  const fork = this.fork();
50
125
  fork._phase = 'condition';
126
+ fork._reachedShould = true;
51
127
  return fork;
52
128
  }
53
129
  /**
@@ -72,70 +148,11 @@ export class RuleBuilder {
72
148
  }
73
149
  return this.addCondition(custom);
74
150
  }
75
- /**
76
- * Attach a human-readable rationale to the rule.
77
- * Included in violation messages when `.check()` throws.
78
- */
79
- because(reason) {
80
- this._reason = reason;
81
- return this;
82
- }
83
- /**
84
- * Attach rich metadata to the rule.
85
- * Provides educational context in violation output: why, how to fix, docs link.
86
- *
87
- * If `metadata.because` is set, it also sets the reason (same as `.because()`).
88
- */
89
- rule(metadata) {
90
- this._metadata = metadata;
91
- if (metadata.because) {
92
- this._reason = metadata.because;
93
- }
94
- return this;
95
- }
96
- /**
97
- * Exclude specific violations from reporting by matching against
98
- * the violation's `element`, `file`, or `message` fields.
99
- *
100
- * Matched violations are silently suppressed. Use for permanent,
101
- * intentional exceptions — not for temporary violations (use baseline for those).
102
- *
103
- * Patterns are matched against all three fields. Prefer anchored regexes
104
- * or full string matches over short substrings, especially for `message`
105
- * matching, to avoid accidentally suppressing unrelated violations whose
106
- * messages happen to contain the same text.
107
- *
108
- * Emits a warning if an exclusion matches zero violations — so renamed
109
- * or deleted exceptions don't silently stay in the rule.
110
- *
111
- * For narrowing a rule's scope at the predicate phase (so the rule never
112
- * evaluates the excluded element), use `satisfy(not(<predicate>))` instead.
113
- * See the "Excluding a file from a rule's scope" recipe in docs/recipes.md.
114
- *
115
- * @example
116
- * // Exclude by element name (fully qualified)
117
- * .excluding('Asset.getImageUrl')
118
- *
119
- * @example
120
- * // Exclude by file path (regex anchored to suffix)
121
- * .excluding(/repositories\/index\.ts$/)
122
- *
123
- * @example
124
- * // Multiple exclusions, mixed forms
125
- * .excluding('Asset.getImageUrl', /\/legacy\//, /generated/)
126
- */
127
- excluding(...patterns) {
128
- for (const p of patterns) {
129
- if (isSilent(p)) {
130
- this._exclusions.push(p.pattern);
131
- this._silentIndices.add(this._exclusions.length - 1);
132
- }
133
- else {
134
- this._exclusions.push(p);
135
- }
136
- }
137
- return this;
138
- }
151
+ // `because`, `rule`, `excluding`, `violations`, `check`, `warn`, `severity`,
152
+ // `expectEmpty`, `expectNonEmpty` are inherited from `TerminalBuilder`
153
+ // (plan 0088 Phase 4) — this class used to duplicate all of them, and the
154
+ // two copies had already drifted (the exact hazard `ts-archunit`'s own
155
+ // `RuleBuilder`/`TerminalBuilder` merge commit documents).
139
156
  // --- Terminal methods ---
140
157
  /**
141
158
  * Return the predicate-filtered elements as a labelled `Selection<T>` for
@@ -146,114 +163,141 @@ export class RuleBuilder {
146
163
  * @param opts.identify - map an element to its message metadata (name/file/line)
147
164
  */
148
165
  select(opts) {
149
- const filtered = this.getElements().filter((element) => this._predicates.every((predicate) => predicate.test(element)));
150
- return { elements: filtered, label: opts.label, identify: opts.identify };
166
+ return selectMatching(this.getElements(), this._predicates, opts);
151
167
  }
152
168
  /**
153
169
  * Return a structured description of this rule without executing it.
154
170
  * Used by the `explain` CLI subcommand.
155
171
  */
156
172
  describeRule() {
157
- return {
158
- rule: this.buildRuleDescription(),
159
- id: this._metadata?.id,
160
- because: this._reason,
161
- suggestion: this._metadata?.suggestion,
162
- docs: this._metadata?.docs,
163
- imperative: this._metadata?.imperative,
164
- };
165
- }
166
- /**
167
- * Execute the rule and return violations after exclusion filtering.
168
- * Does not throw — use for programmatic access (presets, aggregation).
169
- */
170
- violations() {
171
- const raw = this.evaluate();
172
- return applyFilters(raw, {
173
- reason: this._reason,
173
+ return ruleDescriptionFrom({
174
174
  metadata: this._metadata,
175
- exclusions: this._exclusions,
176
- silentIndices: this._silentIndices,
175
+ reason: this._reason,
176
+ rule: this.buildRuleDescription(),
177
177
  });
178
178
  }
179
179
  /**
180
- * Execute the rule and throw `ArchRuleError` if any violations are found.
181
- * This is the primary terminal method — use in test assertions.
180
+ * ADR-010: is this rule's assertion satisfied by an empty selection, as a
181
+ * property of what its conditions assert (`.notExist()`) rather than a
182
+ * caller's `.expectEmpty()` declaration?
183
+ *
184
+ * `.every()`, not `.some()` — `.andShould()` ANDs, so a rule reading
185
+ * `.should().notExist().andShould().beExported()` still asserts something
186
+ * about subjects that exist, and exempting it on the strength of the one
187
+ * cardinality condition would silence the other. An empty condition list is
188
+ * NOT exempt: `[].every()` is vacuously `true`, and a rule with zero
189
+ * conditions is the assertion-less case `collectViolations()` now reports as
190
+ * a configuration finding (bug 0155; it used to be an unreachable stderr
191
+ * warning, which this comment named until that fix landed) — this override
192
+ * must not paper over it by also declaring it cardinality-satisfied.
182
193
  *
183
- * @param options - Optional baseline and diff filtering
194
+ * **Load-bearing:** for a DEAD selector this early return is the only thing
195
+ * between an assertion-less rule and a silent pass (the gate runs after the
196
+ * zero-examined branch). Pinned in `assertion-less-rules.test.ts`.
184
197
  */
185
- check(options) {
186
- const violations = this.evaluate();
187
- executeCheck(violations, {
188
- reason: this._reason,
189
- metadata: this._metadata,
190
- exclusions: this._exclusions,
191
- silentIndices: this._silentIndices,
192
- }, options);
193
- }
194
198
  /**
195
- * Execute the rule and log violations to stderr. Does not throw.
196
- * Use for rules that should warn but not fail CI.
199
+ * Does this rule assert anything at all? — bug 0155.
197
200
  *
198
- * @param options - Optional baseline and diff filtering
201
+ * Conditions alone are not enough: a predicate-only method written *after*
202
+ * `.should()` silently shrank the set the conditions run over, possibly to
203
+ * empty, in which case they hold vacuously. That rule asserts nothing
204
+ * meaningful even though `_conditions` is non-empty.
199
205
  */
200
- warn(options) {
201
- const violations = this.evaluate();
202
- executeWarn(violations, {
203
- reason: this._reason,
204
- metadata: this._metadata,
205
- exclusions: this._exclusions,
206
- silentIndices: this._silentIndices,
207
- }, options);
206
+ assertsSomething() {
207
+ return this._conditions.length > 0 && this._misplaced.length === 0;
208
+ }
209
+ assertionAdvice() {
210
+ return assertionAdviceFor({
211
+ reachedShould: this._reachedShould,
212
+ misplaced: this._misplaced,
213
+ conditionCount: this._conditions.length,
214
+ });
215
+ }
216
+ assertsCardinality() {
217
+ if (this._conditions.length === 0)
218
+ return false;
219
+ return this._conditions.every((condition) => conditionAssertsCardinality(condition));
208
220
  }
209
221
  /**
210
- * Execute the rule with the given severity.
211
- * `.severity('error')` is equivalent to `.check()`.
212
- * `.severity('warn')` is equivalent to `.warn()`.
222
+ * ADR-010 part 3: did this rule's own underlying source (the project, a
223
+ * diagram, an SDL string — whatever `P` loads) produce nothing at all,
224
+ * before `getElements()`'s own domain-specific extraction or any
225
+ * predicate ran? Default `false` — the kernel has no way to know, since
226
+ * `P` is opaque here. A dialect's concrete builder, which knows `P`'s real
227
+ * shape (e.g. `ArchProject`), overrides this to check its own project's
228
+ * file count directly — never `getElements().length`, which conflates "the
229
+ * source is empty" with "this domain legitimately has nothing in a
230
+ * healthy project" (e.g. zero JSX elements in a backend-only codebase).
213
231
  */
214
- severity(level) {
215
- if (level === 'error') {
216
- this.check();
217
- }
218
- else {
219
- this.warn();
220
- }
232
+ sourceEmpty() {
233
+ return false;
234
+ }
235
+ /** Declared globs, position derived from `_phase`. Pure — no `P` needed. */
236
+ globs() {
237
+ return declaredGlobsOf(this._predicates, this._conditions);
238
+ }
239
+ /** This rule's own project, for `diagnose()`/`doctor` outside `.check()`. */
240
+ getProject() {
241
+ return this.project;
242
+ }
243
+ /** A `globs()` tree diagnosably dead, when zero examined — same shape as `sourceEmpty()`. */
244
+ deadGlobDiagnosis() {
245
+ return undefined;
221
246
  }
222
247
  // --- Protected: for subclasses ---
223
248
  /**
224
249
  * Register a predicate. Called by concrete builder methods like
225
- * `.haveNameMatching()`, `.extend()`, etc.
250
+ * `.haveNameMatching()`, `.extend()`, etc. Returns a COPY — see `copy()`.
226
251
  */
227
252
  addPredicate(predicate) {
228
- this._predicates.push(predicate);
229
- return this;
253
+ const next = this.copy();
254
+ recordPredicate(predicate, next._predicates, next._misplaced, next._phase);
255
+ return next;
230
256
  }
231
257
  /**
232
258
  * Register a condition. Called by concrete builder methods like
233
- * `.notContain()`, `.notExist()`, etc.
259
+ * `.notContain()`, `.notExist()`, etc. Returns a COPY — see `copy()`.
234
260
  */
235
261
  addCondition(condition) {
236
- this._conditions.push(condition);
237
- return this;
262
+ const next = this.copy();
263
+ next._conditions.push(condition);
264
+ return next;
238
265
  }
239
266
  /**
240
- * Create a fork of this builder with the same predicates but empty conditions.
241
- * Used by `.should()` to support named selections without mutation.
267
+ * An independent copy, carrying **both** predicates and conditions.
268
+ * Extends `TerminalBuilder.copy()` with the fields this class adds.
242
269
  *
243
- * Subclasses with additional constructor args MUST override this method.
270
+ * Subclasses with additional mutable-reference fields of their own (arrays,
271
+ * sets, maps a chain method pushes onto) MUST override this and call
272
+ * `super.copy()` first, the same reason `TerminalBuilder.copy()`'s own
273
+ * docstring gives — `Object.assign` shallow-copies a field, it does not
274
+ * give it independent identity.
275
+ */
276
+ copy() {
277
+ const clone = super.copy();
278
+ clone._predicates = [...this._predicates];
279
+ clone._conditions = [...this._conditions];
280
+ clone._misplaced = [...this._misplaced];
281
+ return clone;
282
+ }
283
+ /**
284
+ * A fork of this builder, carrying BOTH lists. Used by `.should()` to support
285
+ * named selections without mutation.
286
+ *
287
+ * **Nothing here clears the conditions** (bug 0156). It used to, and a second
288
+ * `.should()` therefore silently discarded the first assertion — a rule that
289
+ * asserted something turned into one that asserted less, by a chain method.
290
+ * `.should().X().should().Y()` now accumulates exactly as `.andShould()` does.
291
+ *
292
+ * Ported from `packages/ts/src/core/rule-builder.ts`, where the engine copy
293
+ * landed the fix and left the kernel behind. Found by the architect review of
294
+ * PR #72: `eess-md`, `eess-mermaid` and `eess-gherkin` all extend THIS class,
295
+ * so they carried the defect — and `check:corpus`, `check:ledger` and
296
+ * `check:diagram` are md/mermaid gates, meaning this repo's own corpus
297
+ * enforcement ran on the broken copy.
244
298
  */
245
299
  fork() {
246
- // Object.create/getPrototypeOf return untyped — casts unavoidable at JS interop boundary
247
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
248
- const proto = Object.getPrototypeOf(this);
249
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
250
- const fork = Object.create(proto);
251
- Object.assign(fork, this);
252
- fork._predicates = [...this._predicates];
253
- fork._conditions = [];
254
- fork._exclusions = [...this._exclusions];
255
- fork._silentIndices = new Set(this._silentIndices);
256
- fork._metadata = this._metadata ? { ...this._metadata } : undefined;
300
+ const fork = this.copy();
257
301
  fork._reason = fork._metadata?.because ?? this._reason;
258
302
  return fork;
259
303
  }
@@ -262,38 +306,45 @@ export class RuleBuilder {
262
306
  * Build the rule description from predicates and conditions.
263
307
  */
264
308
  buildRuleDescription() {
265
- const predicateDesc = this._predicates.map((p) => p.description).join(' and ');
266
- const conditionDesc = this._conditions.map((c) => c.description).join(' and ');
267
- const parts = [];
268
- if (predicateDesc)
269
- parts.push(`that ${predicateDesc}`);
270
- if (conditionDesc)
271
- parts.push(`should ${conditionDesc}`);
272
- return parts.join(' ');
309
+ return ruleDescriptionOf(this._predicates, this._conditions);
273
310
  }
274
311
  /**
275
- * Execute the full pipeline: filter elements with predicates,
276
- * evaluate conditions, return violations.
312
+ * Execute the full pipeline: filter elements with predicates, evaluate
313
+ * conditions, return violations plus the ADR-010 evidence — the
314
+ * post-predicate subject count, whatever it is. `TerminalBuilder.check()` /
315
+ * `.warn()` / `.violations()` decide what a zero count means (a
316
+ * configuration finding, unless `.expectEmpty()` was declared); this method
317
+ * only reports the count, never interprets it.
318
+ *
319
+ * `sourceEmpty` (ADR-010 part 3) is deliberately not `allElements.length
320
+ * === 0` — a domain's own `getElements()` legitimately returning nothing in
321
+ * a healthy, fully-loaded project (e.g. zero JSX elements in a
322
+ * backend-only codebase) is not brokenness, and conflating the two broke
323
+ * `.notExist()`'s cardinality exemption for exactly that case. Subclasses
324
+ * that can answer "did my underlying source load anything at all" override
325
+ * `sourceEmpty()`; the default assumes it did.
277
326
  */
278
- evaluate() {
279
- // Step 1: Get all elements from the concrete builder
327
+ collectViolations() {
280
328
  const allElements = this.getElements();
281
- // Step 2: Filter with predicates (AND — all predicates must match)
282
- const filtered = allElements.filter((element) => this._predicates.every((predicate) => predicate.test(element)));
283
- // Step 3: If no elements match predicates, no violations
329
+ const filtered = matchingElements(allElements, this._predicates);
330
+ const examined = filtered.length;
284
331
  if (filtered.length === 0) {
285
- return [];
332
+ const sourceEmpty = this.sourceEmpty();
333
+ // Skip the diagnosis (a real filesystem walk, in a dialect's
334
+ // override) when the project itself is already known empty — nothing
335
+ // useful to say about one glob's fate against zero loaded files, and
336
+ // `sourceEmpty` outranks it in `evidencedViolations()` regardless.
337
+ const deadGlob = sourceEmpty ? undefined : this.deadGlobDiagnosis();
338
+ return collectResult([], { examined, sourceEmpty, deadGlob });
286
339
  }
287
- // Step 3b: Warn if no conditions were added and phase is still 'predicate'
288
- // — likely a predicate-only method was called after .should().
289
- // Phase-aware methods dispatch correctly, so this only fires for predicate-only methods.
290
- if (this._conditions.length === 0 && this._phase === 'predicate') {
340
+ // Bug 0155 — gate-first, before the conditions run. See
341
+ // `assertionLessViolation` for why this is a finding and not a warning,
342
+ // and why there is no `_phase` term.
343
+ // `_expectEmpty === undefined`: a declared emptiness expectation is an
344
+ // assertion too — see `assertionLessViolation`.
345
+ if (!this.assertsSomething() && this._expectEmpty === undefined) {
291
346
  const ruleId = this._metadata?.id ?? (this.buildRuleDescription() || 'unnamed');
292
- console.warn(`[eess] Rule '${ruleId}' has predicates but no conditions. ` +
293
- `Did you use a predicate-only method after .should()? ` +
294
- `Predicate-only methods (e.g. areExported, areAsync) filter elements; ` +
295
- `use a condition method or .satisfy() after .should().`);
296
- return [];
347
+ return collectResult([assertionLessViolation(ruleId, this.assertionAdvice())], { examined });
297
348
  }
298
349
  // Step 4: Build context for conditions
299
350
  const context = this.buildConditionContext();
@@ -302,7 +353,7 @@ export class RuleBuilder {
302
353
  for (const condition of this._conditions) {
303
354
  violations.push(...condition.evaluate(filtered, context));
304
355
  }
305
- return violations;
356
+ return collectResult(violations, { examined });
306
357
  }
307
358
  /**
308
359
  * Build the `ConditionContext` passed to each condition.
@@ -312,13 +363,11 @@ export class RuleBuilder {
312
363
  * Call `super.buildConditionContext()` and spread the result.
313
364
  */
314
365
  buildConditionContext() {
315
- return {
366
+ return conditionContextFrom({
367
+ metadata: this._metadata,
368
+ reason: this._reason,
316
369
  rule: this.buildRuleDescription(),
317
- because: this._reason,
318
- ruleId: this._metadata?.id,
319
- suggestion: this._metadata?.suggestion,
320
- docs: this._metadata?.docs,
321
- };
370
+ });
322
371
  }
323
372
  }
324
373
  //# sourceMappingURL=rule-builder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rule-builder.js","sourceRoot":"","sources":["../src/rule-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rule-builder.js","sourceRoot":"","sources":["../src/rule-builder.ts"],"names":[],"mappings":"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"}