@nielspeter/eess 0.2.2 → 0.4.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 (157) hide show
  1. package/README.md +3 -3
  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.d.ts +69 -4
  7. package/dist/baseline.d.ts.map +1 -1
  8. package/dist/baseline.js +119 -13
  9. package/dist/baseline.js.map +1 -1
  10. package/dist/cache-registry.d.ts +14 -0
  11. package/dist/cache-registry.d.ts.map +1 -0
  12. package/dist/cache-registry.js +37 -0
  13. package/dist/cache-registry.js.map +1 -0
  14. package/dist/cardinality.d.ts +35 -0
  15. package/dist/cardinality.d.ts.map +1 -0
  16. package/dist/cardinality.js +65 -0
  17. package/dist/cardinality.js.map +1 -0
  18. package/dist/check-options.d.ts +14 -0
  19. package/dist/check-options.d.ts.map +1 -1
  20. package/dist/comment-suppression.d.ts +60 -0
  21. package/dist/comment-suppression.d.ts.map +1 -0
  22. package/dist/comment-suppression.js +89 -0
  23. package/dist/comment-suppression.js.map +1 -0
  24. package/dist/condition.d.ts +6 -0
  25. package/dist/condition.d.ts.map +1 -1
  26. package/dist/correspondence-core.d.ts +35 -0
  27. package/dist/correspondence-core.d.ts.map +1 -0
  28. package/dist/correspondence-core.js +38 -0
  29. package/dist/correspondence-core.js.map +1 -0
  30. package/dist/correspondence.d.ts +27 -5
  31. package/dist/correspondence.d.ts.map +1 -1
  32. package/dist/correspondence.js +39 -5
  33. package/dist/correspondence.js.map +1 -1
  34. package/dist/dedupe-config-findings.d.ts +56 -0
  35. package/dist/dedupe-config-findings.d.ts.map +1 -0
  36. package/dist/dedupe-config-findings.js +74 -0
  37. package/dist/dedupe-config-findings.js.map +1 -0
  38. package/dist/define.d.ts +44 -2
  39. package/dist/define.d.ts.map +1 -1
  40. package/dist/define.js +45 -4
  41. package/dist/define.js.map +1 -1
  42. package/dist/diff-aware.d.ts +8 -0
  43. package/dist/diff-aware.d.ts.map +1 -1
  44. package/dist/diff-aware.js +11 -2
  45. package/dist/diff-aware.js.map +1 -1
  46. package/dist/diff-disclosure.d.ts +72 -0
  47. package/dist/diff-disclosure.d.ts.map +1 -0
  48. package/dist/diff-disclosure.js +110 -0
  49. package/dist/diff-disclosure.js.map +1 -0
  50. package/dist/disk-set.d.ts +27 -0
  51. package/dist/disk-set.d.ts.map +1 -0
  52. package/dist/disk-set.js +12 -0
  53. package/dist/disk-set.js.map +1 -0
  54. package/dist/edge-coverage.d.ts +96 -0
  55. package/dist/edge-coverage.d.ts.map +1 -0
  56. package/dist/edge-coverage.js +108 -0
  57. package/dist/edge-coverage.js.map +1 -0
  58. package/dist/errors.d.ts +25 -0
  59. package/dist/errors.d.ts.map +1 -1
  60. package/dist/errors.js +32 -0
  61. package/dist/errors.js.map +1 -1
  62. package/dist/execute-rule.d.ts +2 -1
  63. package/dist/execute-rule.d.ts.map +1 -1
  64. package/dist/execute-rule.js +38 -6
  65. package/dist/execute-rule.js.map +1 -1
  66. package/dist/format-github.d.ts.map +1 -1
  67. package/dist/format-github.js +37 -5
  68. package/dist/format-github.js.map +1 -1
  69. package/dist/format-json.d.ts +83 -1
  70. package/dist/format-json.d.ts.map +1 -1
  71. package/dist/format-json.js +70 -9
  72. package/dist/format-json.js.map +1 -1
  73. package/dist/format.d.ts +4 -2
  74. package/dist/format.d.ts.map +1 -1
  75. package/dist/format.js +41 -19
  76. package/dist/format.js.map +1 -1
  77. package/dist/glob-site.d.ts +232 -0
  78. package/dist/glob-site.d.ts.map +1 -0
  79. package/dist/glob-site.js +156 -0
  80. package/dist/glob-site.js.map +1 -0
  81. package/dist/identity-root.d.ts +55 -0
  82. package/dist/identity-root.d.ts.map +1 -0
  83. package/dist/identity-root.js +170 -0
  84. package/dist/identity-root.js.map +1 -0
  85. package/dist/index.d.ts +41 -3
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +33 -3
  88. package/dist/index.js.map +1 -1
  89. package/dist/owns-empty-discovery.d.ts +5 -0
  90. package/dist/owns-empty-discovery.d.ts.map +1 -0
  91. package/dist/owns-empty-discovery.js +77 -0
  92. package/dist/owns-empty-discovery.js.map +1 -0
  93. package/dist/path-universe.d.ts +44 -0
  94. package/dist/path-universe.d.ts.map +1 -0
  95. package/dist/path-universe.js +21 -0
  96. package/dist/path-universe.js.map +1 -0
  97. package/dist/predicate.d.ts +33 -0
  98. package/dist/predicate.d.ts.map +1 -1
  99. package/dist/preset-dispatch.d.ts +19 -0
  100. package/dist/preset-dispatch.d.ts.map +1 -1
  101. package/dist/preset-dispatch.js +43 -3
  102. package/dist/preset-dispatch.js.map +1 -1
  103. package/dist/project-relative.d.ts +25 -0
  104. package/dist/project-relative.d.ts.map +1 -0
  105. package/dist/project-relative.js +54 -0
  106. package/dist/project-relative.js.map +1 -0
  107. package/dist/report.d.ts +11 -5
  108. package/dist/report.d.ts.map +1 -1
  109. package/dist/report.js +17 -0
  110. package/dist/report.js.map +1 -1
  111. package/dist/rule-builder-like.d.ts +11 -0
  112. package/dist/rule-builder-like.d.ts.map +1 -0
  113. package/dist/rule-builder-like.js +2 -0
  114. package/dist/rule-builder-like.js.map +1 -0
  115. package/dist/rule-builder.d.ts +109 -84
  116. package/dist/rule-builder.d.ts.map +1 -1
  117. package/dist/rule-builder.js +202 -158
  118. package/dist/rule-builder.js.map +1 -1
  119. package/dist/rule-description.d.ts +33 -1
  120. package/dist/rule-description.d.ts.map +1 -1
  121. package/dist/rule-description.js +17 -1
  122. package/dist/rule-description.js.map +1 -1
  123. package/dist/rule-metadata.d.ts +20 -3
  124. package/dist/rule-metadata.d.ts.map +1 -1
  125. package/dist/selection-memo.d.ts +47 -0
  126. package/dist/selection-memo.d.ts.map +1 -0
  127. package/dist/selection-memo.js +68 -0
  128. package/dist/selection-memo.js.map +1 -0
  129. package/dist/shallow-clone.d.ts +20 -0
  130. package/dist/shallow-clone.d.ts.map +1 -0
  131. package/dist/shallow-clone.js +27 -0
  132. package/dist/shallow-clone.js.map +1 -0
  133. package/dist/stderr.d.ts +16 -0
  134. package/dist/stderr.d.ts.map +1 -0
  135. package/dist/stderr.js +73 -0
  136. package/dist/stderr.js.map +1 -0
  137. package/dist/terminal-builder.d.ts +209 -9
  138. package/dist/terminal-builder.d.ts.map +1 -1
  139. package/dist/terminal-builder.js +264 -20
  140. package/dist/terminal-builder.js.map +1 -1
  141. package/dist/type-guards.d.ts +38 -0
  142. package/dist/type-guards.d.ts.map +1 -0
  143. package/dist/type-guards.js +42 -0
  144. package/dist/type-guards.js.map +1 -0
  145. package/dist/unsuppressable.d.ts +54 -0
  146. package/dist/unsuppressable.d.ts.map +1 -0
  147. package/dist/unsuppressable.js +76 -0
  148. package/dist/unsuppressable.js.map +1 -0
  149. package/dist/vacuity-findings.d.ts +55 -0
  150. package/dist/vacuity-findings.d.ts.map +1 -0
  151. package/dist/vacuity-findings.js +124 -0
  152. package/dist/vacuity-findings.js.map +1 -0
  153. package/dist/violation.d.ts +152 -4
  154. package/dist/violation.d.ts.map +1 -1
  155. package/dist/violation.js +262 -1
  156. package/dist/violation.js.map +1 -1
  157. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -3,10 +3,16 @@ export type { Condition, ConditionContext } from './condition.js';
3
3
  export { not, and, or } from './combinators.js';
4
4
  export type { Matcher } from './combinators.js';
5
5
  export type { ArchViolation, ArchFix } from './violation.js';
6
+ export { byCodepoint, severityFor, remedyRepeatsMessage } from './violation.js';
6
7
  export { applyFixes } from './apply-fixes.js';
7
8
  export type { ApplyResult } from './apply-fixes.js';
9
+ export { UNSUPPRESSABLE } from './unsuppressable.js';
8
10
  export { RuleBuilder } from './rule-builder.js';
9
11
  export { TerminalBuilder } from './terminal-builder.js';
12
+ export type { CollectResult } from './terminal-builder.js';
13
+ export { marksAssertsCardinality, assertsCardinality } from './cardinality.js';
14
+ export { registerCacheReset, clearRegisteredCaches } from './cache-registry.js';
15
+ export { selectionMemo } from './selection-memo.js';
10
16
  export { ArchRuleError } from './errors.js';
11
17
  export type { RuleMetadata } from './rule-metadata.js';
12
18
  export type { RuleDescription } from './rule-description.js';
@@ -19,8 +25,8 @@ export { formatViolationsGitHub } from './format-github.js';
19
25
  export type { CheckOptions, OutputFormat, BaselineFilter, DiffFilterLike } from './check-options.js';
20
26
  export { detectFormat, isCI } from './environment.js';
21
27
  export { definePredicate, defineCondition } from './define.js';
22
- export { dispatchRule, validateOverrides, throwIfViolations } from './preset-dispatch.js';
23
- export { reportViolations, finishPreset } from './report.js';
28
+ export { dispatchRule, validateOverrides, throwIfViolations, presetConstructsNothingViolation, } from './preset-dispatch.js';
29
+ export { reportViolations, finishPreset, violationsEmittedCount } from './report.js';
24
30
  export type { ReportMode, ReportOptions, PresetReportOptions } from './report.js';
25
31
  export type { RuleSeverity, PresetBaseOptions } from './preset-dispatch.js';
26
32
  export { matchSelections } from './matching.js';
@@ -30,13 +36,45 @@ export type { Selection, ElementInfo, Direction, RelationSpec, CorrespondenceOpt
30
36
  export { applyFilters } from './execute-rule.js';
31
37
  export { escapeGitHub } from './format-github.js';
32
38
  export { hashViolation } from './baseline.js';
39
+ export { discoverIdentityRoot, normalizeIdentityText } from './identity-root.js';
40
+ export { writeStderr } from './stderr.js';
33
41
  export { bold, red, dim, yellow, cyan, gray } from './ansi.js';
34
42
  export { parseExclusionComments, isExcludedByComment } from './exclusion-comments.js';
35
43
  export type { ExclusionComment, ExclusionWarning, ParseResult } from './exclusion-comments.js';
36
- export { silent } from './silent-exclusion.js';
44
+ export { silent, isSilent } from './silent-exclusion.js';
37
45
  export type { SilentExclusion } from './silent-exclusion.js';
38
46
  export { withBaseline, generateBaseline, Baseline } from './baseline.js';
39
47
  export type { BaselineEntry, BaselineFile } from './baseline.js';
40
48
  export { collectViolations } from './baseline-generator.js';
41
49
  export { diffAware, DiffFilter } from './diff-aware.js';
50
+ export { recordEdgeCoverage, untestedRules, edgeCoverageNotice, resetEdgeCoverage, } from './edge-coverage.js';
51
+ export type { UntestedReason, EdgeCoverage } from './edge-coverage.js';
52
+ export type { GlobKind, GlobPosition, GlobBase, DeclaredGlob, GlobSite, OpaqueGlob, GlobLeaf, GlobTree, DeclaredGlobs, GlobNode, } from './glob-site.js';
53
+ export { isFaultPosition, countDeclaredGlobs, isGlobNode, isOpaqueGlob, globAnyOf, globNode, stampGlobs, negateGlobs, combineGlobs, } from './glob-site.js';
54
+ export type { PathUniverse } from './path-universe.js';
55
+ export { viewsFor } from './path-universe.js';
56
+ export type { OnDisk, DiskSet } from './disk-set.js';
57
+ export { isAnchored, isProjectRelative } from './project-relative.js';
58
+ export { isRecord, isNullaryCallable } from './type-guards.js';
59
+ export { shallowClone } from './shallow-clone.js';
60
+ export { suppressionNotice, activeNotice, resetDiffDisclosureForTests } from './diff-disclosure.js';
61
+ export { resetCommentSuppression, recordCommentSuppression, commentSuppressions, commentSuppressionNotice, } from './comment-suppression.js';
62
+ export { dedupeConfigFindings } from './dedupe-config-findings.js';
63
+ export { assertionLessViolation } from './terminal-builder.js';
64
+ export { toPortablePath } from './identity-root.js';
65
+ export type { Describable } from './rule-description.js';
66
+ export { isDescribable } from './rule-description.js';
67
+ export { resetStderrGuardForTests } from './stderr.js';
68
+ export { DECLARE_INSTEAD } from './unsuppressable.js';
69
+ export { UNSUPPRESSABLE_MECHANISMS } from './unsuppressable.js';
70
+ export { subjectOf } from './violation.js';
71
+ export { identityCollisions } from './violation.js';
72
+ export { resetIdentityCollisions } from './violation.js';
73
+ export { disambiguateIdentities } from './violation.js';
74
+ export { isArchRuleError } from './errors.js';
75
+ export type { ArchJsonViolation, ArchJsonSuppression, ArchJsonUntestedAllowlist, ArchJsonReport, } from './format-json.js';
76
+ export type { CorrespondenceResult } from './correspondence-core.js';
77
+ export { setCorrespondence } from './correspondence-core.js';
78
+ export { marksOwnEmptyDiscovery, ownsEmptyDiscovery } from './owns-empty-discovery.js';
79
+ export type { RuleBuilderLike } from './rule-builder-like.js';
42
80
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -5,10 +5,15 @@
5
5
  // defineCondition extension points. Nothing here depends on ts-morph or any
6
6
  // dialect-specific parser.
7
7
  export { not, and, or } from './combinators.js';
8
+ export { byCodepoint, severityFor, remedyRepeatsMessage } from './violation.js';
8
9
  export { applyFixes } from './apply-fixes.js';
10
+ export { UNSUPPRESSABLE } from './unsuppressable.js';
9
11
  // Rule builder, terminal builder, error
10
12
  export { RuleBuilder } from './rule-builder.js';
11
13
  export { TerminalBuilder } from './terminal-builder.js';
14
+ export { marksAssertsCardinality, assertsCardinality } from './cardinality.js';
15
+ export { registerCacheReset, clearRegisteredCaches } from './cache-registry.js';
16
+ export { selectionMemo } from './selection-memo.js';
12
17
  export { ArchRuleError } from './errors.js';
13
18
  // Code frame & formatting
14
19
  export { generateCodeFrame } from './code-frame.js';
@@ -19,8 +24,8 @@ export { detectFormat, isCI } from './environment.js';
19
24
  // Custom predicate/condition factories
20
25
  export { definePredicate, defineCondition } from './define.js';
21
26
  // Preset dispatch — generic per-rule severity/override infrastructure for presets
22
- export { dispatchRule, validateOverrides, throwIfViolations } from './preset-dispatch.js';
23
- export { reportViolations, finishPreset } from './report.js';
27
+ export { dispatchRule, validateOverrides, throwIfViolations, presetConstructsNothingViolation, } from './preset-dispatch.js';
28
+ export { reportViolations, finishPreset, violationsEmittedCount } from './report.js';
24
29
  // Matching engine — shared by correspondence() and eess-ts's crossLayer
25
30
  export { matchSelections } from './matching.js';
26
31
  // Cross-validation — bind two element Selections and assert they correspond
@@ -29,12 +34,37 @@ export { correspondence, CorrespondenceBuilder } from './correspondence.js';
29
34
  export { applyFilters } from './execute-rule.js';
30
35
  export { escapeGitHub } from './format-github.js';
31
36
  export { hashViolation } from './baseline.js';
37
+ export { discoverIdentityRoot, normalizeIdentityText } from './identity-root.js';
38
+ export { writeStderr } from './stderr.js';
32
39
  export { bold, red, dim, yellow, cyan, gray } from './ansi.js';
33
40
  // Exclusions
34
41
  export { parseExclusionComments, isExcludedByComment } from './exclusion-comments.js';
35
- export { silent } from './silent-exclusion.js';
42
+ export { silent, isSilent } from './silent-exclusion.js';
36
43
  // Baseline & diff-aware
37
44
  export { withBaseline, generateBaseline, Baseline } from './baseline.js';
38
45
  export { collectViolations } from './baseline-generator.js';
39
46
  export { diffAware, DiffFilter } from './diff-aware.js';
47
+ // Edge coverage — allowlist conditions disclose when they tested nothing
48
+ export { recordEdgeCoverage, untestedRules, edgeCoverageNotice, resetEdgeCoverage, } from './edge-coverage.js';
49
+ export { isFaultPosition, countDeclaredGlobs, isGlobNode, isOpaqueGlob, globAnyOf, globNode, stampGlobs, negateGlobs, combineGlobs, } from './glob-site.js';
50
+ export { viewsFor } from './path-universe.js';
51
+ export { isAnchored, isProjectRelative } from './project-relative.js';
52
+ export { isRecord, isNullaryCallable } from './type-guards.js';
53
+ export { shallowClone } from './shallow-clone.js';
54
+ export { suppressionNotice, activeNotice, resetDiffDisclosureForTests } from './diff-disclosure.js';
55
+ export { resetCommentSuppression, recordCommentSuppression, commentSuppressions, commentSuppressionNotice, } from './comment-suppression.js';
56
+ export { dedupeConfigFindings } from './dedupe-config-findings.js';
57
+ export { assertionLessViolation } from './terminal-builder.js';
58
+ export { toPortablePath } from './identity-root.js';
59
+ export { isDescribable } from './rule-description.js';
60
+ export { resetStderrGuardForTests } from './stderr.js';
61
+ export { DECLARE_INSTEAD } from './unsuppressable.js';
62
+ export { UNSUPPRESSABLE_MECHANISMS } from './unsuppressable.js';
63
+ export { subjectOf } from './violation.js';
64
+ export { identityCollisions } from './violation.js';
65
+ export { resetIdentityCollisions } from './violation.js';
66
+ export { disambiguateIdentities } from './violation.js';
67
+ export { isArchRuleError } from './errors.js';
68
+ export { setCorrespondence } from './correspondence-core.js';
69
+ export { marksOwnEmptyDiscovery, ownsEmptyDiscovery } from './owns-empty-discovery.js';
40
70
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,2BAA2B;AAK3B,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAK/C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG7C,wCAAwC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAI3C,0BAA0B;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEnD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAI3D,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAErD,uCAAuC;AACvC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE9D,kFAAkF;AAClF,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACzF,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI5D,wEAAwE;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAG/C,4EAA4E;AAC5E,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAU3E,6EAA6E;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAE9D,aAAa;AACb,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAErF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAG9C,wBAAwB;AACxB,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Declare that this condition reports an empty discovery population itself. */
2
+ export declare function marksOwnEmptyDiscovery<T extends object>(condition: T): T;
3
+ /** Does this condition report an empty discovery population itself? */
4
+ export declare function ownsEmptyDiscovery(condition: object): boolean;
5
+ //# sourceMappingURL=owns-empty-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owns-empty-discovery.d.ts","sourceRoot":"","sources":["../src/owns-empty-discovery.ts"],"names":[],"mappings":"AA4DA,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,CAGxE;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE7D"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * A condition that diagnoses its own empty discovery population.
3
+ *
4
+ * [ts-archunit Plan 0081](https://github.com/nielspeter/ts-archunit/blob/main/plans/completed/0081-a-condition-declares-discovery-ownership.md). The
5
+ * dead-glob gate can see that a `.layer()` or `.inFolder()` glob matched nothing,
6
+ * but it short-circuits **before** the condition runs, so where a condition
7
+ * produces a better finding — one that names the dead layer, with a remedy
8
+ * pointing at the call the reader must edit — the gate would replace it with a
9
+ * generic message. This symbol is how a condition says "leave it to me".
10
+ *
11
+ * ## Why per condition, and not per builder
12
+ *
13
+ * It was per builder, and the granularity was load-bearing rather than cosmetic.
14
+ * At v0.45.0 `PairFinalBuilder` returned `true` unconditionally while its own
15
+ * docstring claimed *"All three now produce a finding naming the layer"* — and
16
+ * that claim was false: `haveMatchingCounterpart` checked for empty layers inside
17
+ * its pair loop, so a dead **final** layer produced no configuration finding at
18
+ * all. The coarse declaration suppressed the gate for exactly the case its
19
+ * declared owner did not handle, and the result was silence where the truth was
20
+ * one dead glob
21
+ * ([ts-archunit bug 0040](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0040-a-crosslayer-rule-reports-nothing-when-its-layer-resolves-nothing.md)).
22
+ *
23
+ * v0.45.1 fixed the condition, so the blanket claim became true again. It would
24
+ * have gone false again the moment a fourth condition reached that builder,
25
+ * because nothing forced the new condition to say anything. Now the claim is not
26
+ * a claim: the builder reads the tag off the condition it was given.
27
+ *
28
+ * **An untagged condition does not own it, so the gate covers it.** That default
29
+ * is the load-bearing half — under it, v0.45.0's hole would have degraded to a
30
+ * generic message rather than silence, and a generic message is recoverable. An
31
+ * agent reading "this glob matched nothing" fixes the glob; silence sends it to
32
+ * write files into a layer that will never match.
33
+ *
34
+ * ## Unreachable by construction — a registry, not a property
35
+ *
36
+ * The first version was a `unique symbol` keyed onto the condition object, copying
37
+ * `ASSERTS_CARDINALITY`. Review broke it in two lines:
38
+ *
39
+ * ```ts
40
+ * const stolen = Object.getOwnPropertySymbols(haveMatchingCounterpart())[0]
41
+ * const mine: PairCondition = { description: 'x', evaluate: () => [], [stolen]: true }
42
+ * ```
43
+ *
44
+ * Measured: **0 configuration findings** on a dead layer. `PairCondition` is a
45
+ * public type and all three condition factories are public exports, so the symbol
46
+ * was readable off any shipped condition — the one-line silent opt-out this file
47
+ * claimed could not exist, reachable through documented API.
48
+ *
49
+ * The `ASSERTS_CARDINALITY` precedent is stronger than the copy was, and that is
50
+ * why copying it was not enough: `defineCondition` is its *sanctioned constructor*,
51
+ * and a test asserts that constructor emits no own symbols. `PairCondition` has no
52
+ * sanctioned constructor, so there is nothing to make the analogous guarantee.
53
+ *
54
+ * A module-level `WeakSet` has no such hole. Membership is not a property of the
55
+ * object, so it cannot be read off one, copied, or forged — a caller would need
56
+ * this module's binding, and it is not exported. `WeakSet` rather than `Set` so a
57
+ * condition is not retained after its rule is discarded.
58
+ */
59
+ const OWNERS = new WeakSet();
60
+ /** Declare that this condition reports an empty discovery population itself. */
61
+ export function marksOwnEmptyDiscovery(condition) {
62
+ OWNERS.add(condition);
63
+ return condition;
64
+ }
65
+ /** Does this condition report an empty discovery population itself? */
66
+ export function ownsEmptyDiscovery(condition) {
67
+ return OWNERS.has(condition);
68
+ }
69
+ /*
70
+ * Not every builder needs this. `SliceRuleBuilder` declares ownership at the
71
+ * BUILDER level and correctly so: its reason — `assignedFrom` fanning out one glob
72
+ * tree per entry, where a single dead entry among populated siblings is a
73
+ * legitimate project shape — is identical for every condition reachable through
74
+ * it. Registry membership is for the case where ownership varies by condition,
75
+ * which is what made a blanket declaration wrong for cross-layer.
76
+ */
77
+ //# sourceMappingURL=owns-empty-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owns-empty-discovery.js","sourceRoot":"","sources":["../src/owns-empty-discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,MAAM,MAAM,GAAG,IAAI,OAAO,EAAU,CAAA;AAEpC,gFAAgF;AAChF,MAAM,UAAU,sBAAsB,CAAmB,SAAY;IACnE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACrB,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,OAAO,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;AAC9B,CAAC;AAED;;;;;;;GAOG"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Every path a glob could legitimately match in a project — the shape of the
3
+ * data, not how to build it.
4
+ *
5
+ * `PathUniverse` and `viewsFor` are pure: given the materialized string
6
+ * arrays, they need no `ArchProject`/ts-morph and stay in the kernel. Only
7
+ * the MATERIALIZER — walking a real project's source files into this shape —
8
+ * needs the dialect's own project type, and lives in that dialect (e.g.
9
+ * `packages/ts/src/core/path-universe.ts`'s `pathUniverse()`).
10
+ */
11
+ export interface PathUniverse {
12
+ /** Absolute paths of every file in the project. */
13
+ readonly filePaths: readonly string[];
14
+ /**
15
+ * Immediate parent directories only.
16
+ *
17
+ * Not all ancestors. A directory-matching predicate typically tests
18
+ * `filePath.substring(0, filePath.lastIndexOf('/'))` — the immediate
19
+ * parent and nothing else — so an all-ancestors set is not a harmless
20
+ * over-approximation, it is a false green: many ancestors are no file's
21
+ * direct parent, so a glob naming one of those can never select anything
22
+ * while an all-ancestors universe would call it satisfiable.
23
+ */
24
+ readonly parentDirs: readonly string[];
25
+ /** `filePaths` relative to the tsconfig directory, for message wording. */
26
+ readonly tsconfigRelativeFilePaths: readonly string[];
27
+ /** `parentDirs` relative to the tsconfig directory, for message wording. */
28
+ readonly tsconfigRelativeParentDirs: readonly string[];
29
+ }
30
+ /**
31
+ * The views a glob of this kind is matched against.
32
+ *
33
+ * Satisfiability is taken against the **union** — a glob is unsatisfiable
34
+ * only when nothing in any view matches it. That is deliberately generous,
35
+ * so that a wrong `base` cannot make a glob look unmatched by accident. It
36
+ * does NOT make `base` message-only: the anchor check in `syntacticFault`
37
+ * consults it directly, and an unanchored `base: 'absolute'` glob is dead
38
+ * regardless of what any view holds — see `GlobBase`.
39
+ *
40
+ * `import-target`, `specifier` and `literal` are not path kinds and have no
41
+ * views, so they can never be found unsatisfiable here.
42
+ */
43
+ export declare function viewsFor(universe: PathUniverse, kind: 'file-path' | 'parent-dir' | 'import-target' | 'specifier' | 'literal'): readonly (readonly string[])[];
44
+ //# sourceMappingURL=path-universe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-universe.d.ts","sourceRoot":"","sources":["../src/path-universe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IACrC;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,2EAA2E;IAC3E,QAAQ,CAAC,yBAAyB,EAAE,SAAS,MAAM,EAAE,CAAA;IACrD,4EAA4E;IAC5E,QAAQ,CAAC,0BAA0B,EAAE,SAAS,MAAM,EAAE,CAAA;CACvD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,eAAe,GAAG,WAAW,GAAG,SAAS,GAC3E,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAIhC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The views a glob of this kind is matched against.
3
+ *
4
+ * Satisfiability is taken against the **union** — a glob is unsatisfiable
5
+ * only when nothing in any view matches it. That is deliberately generous,
6
+ * so that a wrong `base` cannot make a glob look unmatched by accident. It
7
+ * does NOT make `base` message-only: the anchor check in `syntacticFault`
8
+ * consults it directly, and an unanchored `base: 'absolute'` glob is dead
9
+ * regardless of what any view holds — see `GlobBase`.
10
+ *
11
+ * `import-target`, `specifier` and `literal` are not path kinds and have no
12
+ * views, so they can never be found unsatisfiable here.
13
+ */
14
+ export function viewsFor(universe, kind) {
15
+ if (kind === 'file-path')
16
+ return [universe.filePaths, universe.tsconfigRelativeFilePaths];
17
+ if (kind === 'parent-dir')
18
+ return [universe.parentDirs, universe.tsconfigRelativeParentDirs];
19
+ return [];
20
+ }
21
+ //# sourceMappingURL=path-universe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-universe.js","sourceRoot":"","sources":["../src/path-universe.ts"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,QAAQ,CACtB,QAAsB,EACtB,IAA4E;IAE5E,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAA;IACzF,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,0BAA0B,CAAC,CAAA;IAC5F,OAAO,EAAE,CAAA;AACX,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { DeclaredGlobs } from './glob-site.js';
1
2
  /**
2
3
  * A predicate that tests whether an architectural element matches a condition.
3
4
  * Used in `.that()` clauses to filter elements before rule evaluation.
@@ -7,5 +8,37 @@ export interface Predicate<T> {
7
8
  readonly description: string;
8
9
  /** Returns true if the element matches this predicate. */
9
10
  test(element: T): boolean;
11
+ /**
12
+ * The path globs this predicate matches against, if any.
13
+ *
14
+ * Declaring them lets the builder answer "can this rule ever have subjects?"
15
+ * without running it (plan 0069). Optional: a predicate that matches on
16
+ * something other than a path — a name, a decorator, a type — declares
17
+ * nothing and is treated as opaque, which is never a fault.
18
+ *
19
+ * Leaves are `DeclaredGlob`, so a predicate cannot claim a `position`; the
20
+ * builder stamps that on according to where the predicate was registered.
21
+ */
22
+ readonly globs?: DeclaredGlobs;
23
+ /**
24
+ * What to call this predicate's globs in a **configuration finding**, when
25
+ * the call the user made is not the call the predicate makes.
26
+ *
27
+ * Plan 0074, the second consequence of 0069's appendix item 4: presets must
28
+ * thread the option name into the site's origin (`shared: "…"`, not
29
+ * `resideInFolder("…")`), or the message names a call the user never made.
30
+ *
31
+ * A preset option is one name that expands to several predicates —
32
+ * `shared: ['…']` becomes `atPath()`, which is `or(resideInFile,
33
+ * resideInFolder)`. Measured before this existed, the finding read "This
34
+ * rule's selector reside in file matching … or reside in folder matching …
35
+ * can never match anything", naming two calls the author never wrote and
36
+ * omitting the option they did.
37
+ *
38
+ * Deliberately **not** `description`, which is overloaded: that renders the
39
+ * human-readable rule text, and rewriting it would change every violation
40
+ * message the preset produces, not just the configuration finding.
41
+ */
42
+ readonly originLabel?: string;
10
43
  }
11
44
  //# sourceMappingURL=predicate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"predicate.d.ts","sourceRoot":"","sources":["../src/predicate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,0DAA0D;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAA;CAC1B"}
1
+ {"version":3,"file":"predicate.d.ts","sourceRoot":"","sources":["../src/predicate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD;;;GAGG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,0DAA0D;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAA;IACzB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAA;IAE9B;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B"}
@@ -36,6 +36,25 @@ export declare function dispatchRule(builder: Dispatchable, rule: string | (Rule
36
36
  * (likely typos).
37
37
  */
38
38
  export declare function validateOverrides(overrides: Record<string, RuleSeverity> | undefined, knownIds: string[]): void;
39
+ /**
40
+ * A configuration finding for a preset call that constructed **zero** rules —
41
+ * every optional capability was left off, or a required discovery pattern
42
+ * (a folder glob, a repositories glob) matched nothing, so the call checked
43
+ * nothing and would otherwise pass silently. The vacuity matrix
44
+ * (`scripts/vacuity-matrix.mjs`) is what proves a preset needs this: it
45
+ * probes every published preset at its minimal type-correct call, and a
46
+ * preset reaching `fail-open` there is exactly this shape.
47
+ *
48
+ * Unsuppressable (ADR-010) for the same reason a zero-examined rule is: the
49
+ * caller's mistake is in how the preset was configured, not in the code the
50
+ * preset would have checked, and `.excluding()`/a baseline/`--changed` all
51
+ * aim at the latter.
52
+ *
53
+ * @param presetName - The preset's own name, e.g. `'agentGuardrails'`.
54
+ * @param optionsHint - The option names that would enable a rule, for the
55
+ * remedy — e.g. `'noGenericErrors, noStubs, noEmptyBodies'`.
56
+ */
57
+ export declare function presetConstructsNothingViolation(presetName: string, optionsHint: string): ArchViolation;
39
58
  /**
40
59
  * Emit (stderr text) and throw a single `ArchRuleError` with all aggregated
41
60
  * violations, if any. Kept for backward compatibility; it is now `finishPreset`
@@ -1 +1 @@
1
- {"version":3,"file":"preset-dispatch.d.ts","sourceRoot":"","sources":["../src/preset-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEpE,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAA;AAEnD;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CACzC;AAED;;;GAGG;AACH,UAAU,YAAY;IACpB,IAAI,CAAC,CAAC,EAAE,YAAY,GAAG;QAAE,UAAU,IAAI,aAAa,EAAE,CAAA;KAAE,CAAA;IACxD,UAAU,IAAI,aAAa,EAAE,CAAA;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,MAAM,GAAG,CAAC,YAAY,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,EAC9C,eAAe,EAAE,YAAY,EAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,GAClD,aAAa,EAAE,CAmBjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,EACnD,QAAQ,EAAE,MAAM,EAAE,GACjB,IAAI,CAWN;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,IAAI,CAEnE"}
1
+ {"version":3,"file":"preset-dispatch.d.ts","sourceRoot":"","sources":["../src/preset-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,OAAO,EAAgB,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAIpE,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAA;AAEnD;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CACzC;AAED;;;GAGG;AACH,UAAU,YAAY;IACpB,IAAI,CAAC,CAAC,EAAE,YAAY,GAAG;QAAE,UAAU,IAAI,aAAa,EAAE,CAAA;KAAE,CAAA;IACxD,UAAU,IAAI,aAAa,EAAE,CAAA;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,MAAM,GAAG,CAAC,YAAY,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,EAC9C,eAAe,EAAE,YAAY,EAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,GAClD,aAAa,EAAE,CAwBjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,EACnD,QAAQ,EAAE,MAAM,EAAE,GACjB,IAAI,CAWN;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gCAAgC,CAC9C,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,aAAa,CAcf;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,IAAI,CAEnE"}
@@ -1,5 +1,8 @@
1
+ import { severityFor } from './violation.js';
1
2
  import { formatViolations } from './format.js';
2
3
  import { finishPreset } from './report.js';
4
+ import { writeStderr } from './stderr.js';
5
+ import { UNSUPPRESSABLE } from './unsuppressable.js';
3
6
  /**
4
7
  * Dispatch a single rule within a preset.
5
8
  *
@@ -19,9 +22,14 @@ export function dispatchRule(builder, rule, defaultSeverity, overrides) {
19
22
  const violations = builder.rule(meta).violations();
20
23
  if (effective === 'warn') {
21
24
  if (violations.length > 0) {
22
- console.warn(formatViolations(violations));
25
+ writeStderr(formatViolations(violations));
23
26
  }
24
- return [];
27
+ // `bypassFilters` outranks a per-rule `overrides: { id: 'warn' }` — see
28
+ // `severityFor`. A config finding like `presetConstructsNothingViolation`
29
+ // is `UNSUPPRESSABLE` by its own text; silently dropping it here just
30
+ // because its OWN rule was downgraded is exactly the suppression path
31
+ // that text promises does not exist.
32
+ return violations.filter((v) => severityFor(v, 'warn') === 'error');
25
33
  }
26
34
  return violations;
27
35
  }
@@ -35,11 +43,43 @@ export function validateOverrides(overrides, knownIds) {
35
43
  const knownSet = new Set(knownIds);
36
44
  for (const key of Object.keys(overrides)) {
37
45
  if (!knownSet.has(key)) {
38
- console.warn(`[eess] Override key '${key}' does not match any rule in this preset. ` +
46
+ writeStderr(`[eess] Override key '${key}' does not match any rule in this preset. ` +
39
47
  `Available rules: ${knownIds.join(', ')}`);
40
48
  }
41
49
  }
42
50
  }
51
+ /**
52
+ * A configuration finding for a preset call that constructed **zero** rules —
53
+ * every optional capability was left off, or a required discovery pattern
54
+ * (a folder glob, a repositories glob) matched nothing, so the call checked
55
+ * nothing and would otherwise pass silently. The vacuity matrix
56
+ * (`scripts/vacuity-matrix.mjs`) is what proves a preset needs this: it
57
+ * probes every published preset at its minimal type-correct call, and a
58
+ * preset reaching `fail-open` there is exactly this shape.
59
+ *
60
+ * Unsuppressable (ADR-010) for the same reason a zero-examined rule is: the
61
+ * caller's mistake is in how the preset was configured, not in the code the
62
+ * preset would have checked, and `.excluding()`/a baseline/`--changed` all
63
+ * aim at the latter.
64
+ *
65
+ * @param presetName - The preset's own name, e.g. `'agentGuardrails'`.
66
+ * @param optionsHint - The option names that would enable a rule, for the
67
+ * remedy — e.g. `'noGenericErrors, noStubs, noEmptyBodies'`.
68
+ */
69
+ export function presetConstructsNothingViolation(presetName, optionsHint) {
70
+ const message = `${presetName}(...) constructed zero rules at this call — no capability of this ` +
71
+ `preset was enabled, or a discovery pattern matched nothing, so it checks nothing ` +
72
+ `and passes silently. Enable at least one option (${optionsHint}), or remove the call.`;
73
+ return {
74
+ rule: presetName,
75
+ element: presetName,
76
+ file: '',
77
+ line: 0,
78
+ message,
79
+ suggestion: `${message} ${UNSUPPRESSABLE}`,
80
+ bypassFilters: true,
81
+ };
82
+ }
43
83
  /**
44
84
  * Emit (stderr text) and throw a single `ArchRuleError` with all aggregated
45
85
  * violations, if any. Kept for backward compatibility; it is now `finishPreset`
@@ -1 +1 @@
1
- {"version":3,"file":"preset-dispatch.js","sourceRoot":"","sources":["../src/preset-dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,YAAY,EAA4B,MAAM,aAAa,CAAA;AAuBpE;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAqB,EACrB,IAA8C,EAC9C,eAA6B,EAC7B,SAAmD;IAEnD,8EAA8E;IAC9E,gFAAgF;IAChF,6EAA6E;IAC7E,2BAA2B;IAC3B,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAC3D,MAAM,SAAS,GAAG,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,eAAe,CAAA;IACzD,IAAI,SAAS,KAAK,KAAK;QAAE,OAAO,EAAE,CAAA;IAElC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAA;IAElD,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzB,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAA;QAC5C,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAmD,EACnD,QAAkB;IAElB,IAAI,CAAC,SAAS;QAAE,OAAM;IACtB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CACV,wBAAwB,GAAG,4CAA4C;gBACrE,oBAAoB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5C,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAA2B;IAC3D,YAAY,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;AAC/C,CAAC"}
1
+ {"version":3,"file":"preset-dispatch.js","sourceRoot":"","sources":["../src/preset-dispatch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,YAAY,EAA4B,MAAM,aAAa,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAuBpD;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAqB,EACrB,IAA8C,EAC9C,eAA6B,EAC7B,SAAmD;IAEnD,8EAA8E;IAC9E,gFAAgF;IAChF,6EAA6E;IAC7E,2BAA2B;IAC3B,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAC3D,MAAM,SAAS,GAAG,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,eAAe,CAAA;IACzD,IAAI,SAAS,KAAK,KAAK;QAAE,OAAO,EAAE,CAAA;IAElC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAA;IAElD,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzB,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,WAAW,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAA;QAC3C,CAAC;QACD,wEAAwE;QACxE,0EAA0E;QAC1E,sEAAsE;QACtE,sEAAsE;QACtE,qCAAqC;QACrC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,CAAA;IACrE,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAmD,EACnD,QAAkB;IAElB,IAAI,CAAC,SAAS;QAAE,OAAM;IACtB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,WAAW,CACT,wBAAwB,GAAG,4CAA4C;gBACrE,oBAAoB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5C,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gCAAgC,CAC9C,UAAkB,EAClB,WAAmB;IAEnB,MAAM,OAAO,GACX,GAAG,UAAU,oEAAoE;QACjF,mFAAmF;QACnF,oDAAoD,WAAW,wBAAwB,CAAA;IACzF,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,CAAC;QACP,OAAO;QACP,UAAU,EAAE,GAAG,OAAO,IAAI,cAAc,EAAE;QAC1C,aAAa,EAAE,IAAI;KACpB,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAA2B;IAC3D,YAAY,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;AAC/C,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Whether a glob can already match an absolute path.
3
+ *
4
+ * Extracted from ts-archunit's larger `project-relative.ts`, most of which
5
+ * (`rootOf`/`relativeToRoot`, workspace multi-root awareness) needs
6
+ * `ArchProject`/ts-morph and stays deferred — this one predicate is pure
7
+ * string syntax with no dependency on either, and `glob-diagnosis.ts` needs
8
+ * it to be kernel-eligible at all, so it gets its own small home here rather
9
+ * than waiting on the ts-morph-blocked half of the file it came from.
10
+ *
11
+ * Covers POSIX-absolute and Windows drive-absolute globs as well as an
12
+ * explicit globstar.
13
+ */
14
+ export declare function isAnchored(glob: string): boolean;
15
+ /**
16
+ * Does this glob name a location relative to the project root?
17
+ *
18
+ * Only an **unanchored, relative** glob is normalized. `'**\/x'` is explicitly
19
+ * "anywhere" and must keep meaning that; `'/abs/x'` is already absolute. So
20
+ * this is the same population `syntacticFault` calls `unanchored`, which is
21
+ * what makes the two consistent: a glob stops being reported dead for being
22
+ * unanchored exactly when it starts working.
23
+ */
24
+ export declare function isProjectRelative(glob: string): boolean;
25
+ //# sourceMappingURL=project-relative.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-relative.d.ts","sourceRoot":"","sources":["../src/project-relative.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAyBvD"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Whether a glob can already match an absolute path.
3
+ *
4
+ * Extracted from ts-archunit's larger `project-relative.ts`, most of which
5
+ * (`rootOf`/`relativeToRoot`, workspace multi-root awareness) needs
6
+ * `ArchProject`/ts-morph and stays deferred — this one predicate is pure
7
+ * string syntax with no dependency on either, and `glob-diagnosis.ts` needs
8
+ * it to be kernel-eligible at all, so it gets its own small home here rather
9
+ * than waiting on the ts-morph-blocked half of the file it came from.
10
+ *
11
+ * Covers POSIX-absolute and Windows drive-absolute globs as well as an
12
+ * explicit globstar.
13
+ */
14
+ export function isAnchored(glob) {
15
+ return glob.startsWith('**/') || glob.startsWith('/') || /^[A-Za-z]:\//.test(glob);
16
+ }
17
+ /**
18
+ * Does this glob name a location relative to the project root?
19
+ *
20
+ * Only an **unanchored, relative** glob is normalized. `'**\/x'` is explicitly
21
+ * "anywhere" and must keep meaning that; `'/abs/x'` is already absolute. So
22
+ * this is the same population `syntacticFault` calls `unanchored`, which is
23
+ * what makes the two consistent: a glob stops being reported dead for being
24
+ * unanchored exactly when it starts working.
25
+ */
26
+ export function isProjectRelative(glob) {
27
+ // A `./` segment is excluded, and that exclusion is load-bearing rather than
28
+ // fussy. `syntacticFault` reports `dot-segment` for a `./` anywhere in a
29
+ // glob, so normalizing one would make the rule MATCH at runtime while the
30
+ // gate still reported it dead — two derivations disagreeing about the same
31
+ // glob, which is the failure this project spends most of its guards on.
32
+ //
33
+ // `./` is a mistake in both worlds — it never occurs in an absolute path and
34
+ // it says nothing extra in a relative one — so the honest fix is to leave it
35
+ // failing, with advice that says to remove it.
36
+ // `..` is not relative-to-the-root in any usable sense: containment returns
37
+ // `undefined` for anything above the root, deliberately, so a `../`
38
+ // glob would normalize to nothing and be reported dead with three false
39
+ // causes. Excluded alongside `./` — both are mistakes in both readings.
40
+ if (/(?:^|\/)\.\.?\//.test(glob))
41
+ return false;
42
+ // Derived from `isAnchored`, not restated — two lists that disagree is the
43
+ // failure this file spends most of its guards on. `isAnchored` covers `/x`,
44
+ // `**/x` and a drive-absolute `C:/x`.
45
+ if (isAnchored(glob))
46
+ return false;
47
+ // `*/x/**` is deliberately NOT normalized, even though it is unanchored.
48
+ // Normalizing it would make it match, which sounds like an improvement until
49
+ // you notice it is the LAST reachable `unanchored` fault for a path glob —
50
+ // the anchor advice would become unreachable. Left failing, with a remedy
51
+ // that works: `'**/x/**'`.
52
+ return !glob.startsWith('*/');
53
+ }
54
+ //# sourceMappingURL=project-relative.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-relative.js","sourceRoot":"","sources":["../src/project-relative.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACpF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,6EAA6E;IAC7E,yEAAyE;IACzE,0EAA0E;IAC1E,2EAA2E;IAC3E,wEAAwE;IACxE,EAAE;IACF,6EAA6E;IAC7E,6EAA6E;IAC7E,+CAA+C;IAC/C,4EAA4E;IAC5E,oEAAoE;IACpE,wEAAwE;IACxE,wEAAwE;IACxE,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAC9C,2EAA2E;IAC3E,4EAA4E;IAC5E,sCAAsC;IACtC,IAAI,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAClC,yEAAyE;IACzE,6EAA6E;IAC7E,2EAA2E;IAC3E,0EAA0E;IAC1E,2BAA2B;IAC3B,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;AAC/B,CAAC"}
package/dist/report.d.ts CHANGED
@@ -20,12 +20,18 @@ export interface PresetReportOptions extends ReportOptions {
20
20
  readonly report?: ReportMode;
21
21
  }
22
22
  /**
23
- * The single place that knows how to *emit* violations — text (stderr), JSON,
24
- * or GitHub annotations (stdout). No throw, no filtering, no control flow: just
25
- * emission. `executeCheck` (the `.check()` path) and `finishPreset` (the preset
26
- * path) both delegate here, so the two reporting paths can no longer diverge
27
- * (plan 0070). Emits nothing for an empty set.
23
+ * How many violations this module has actually WRITTEN, ever.
24
+ *
25
+ * Read as a delta by a caller that aggregates reporting, to answer one question it
26
+ * cannot otherwise answer: *did something emit while I was loading that module?*
27
+ *
28
+ * The alternative a caller might reach for — counting the writes it SUPPRESSED and
29
+ * inferring "then nothing was written" — is a double negative and is unsound: a
30
+ * module that suppresses one terminal and leaks through another satisfies it while
31
+ * leaking. Measured on `eess-ts`, which shipped that inference and fell into
32
+ * exactly that case. Count emissions, not silences.
28
33
  */
34
+ export declare function violationsEmittedCount(): number;
29
35
  export declare function reportViolations(violations: ArchViolation[], options?: ReportOptions): void;
30
36
  /**
31
37
  * Finish a preset: deliver its aggregated violations per the requested mode