@timiagama/ecr 0.0.1 → 0.1.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 (138) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +16 -0
  3. package/README.md +411 -7
  4. package/dist/bin.d.ts +20 -0
  5. package/dist/bin.d.ts.map +1 -0
  6. package/dist/bin.js +26 -0
  7. package/dist/bin.js.map +1 -0
  8. package/dist/cli/corpus-loader.d.ts +198 -0
  9. package/dist/cli/corpus-loader.d.ts.map +1 -0
  10. package/dist/cli/corpus-loader.js +351 -0
  11. package/dist/cli/corpus-loader.js.map +1 -0
  12. package/dist/cli/corpus-statistics.d.ts +113 -0
  13. package/dist/cli/corpus-statistics.d.ts.map +1 -0
  14. package/dist/cli/corpus-statistics.js +119 -0
  15. package/dist/cli/corpus-statistics.js.map +1 -0
  16. package/dist/cli/diagnostic-reporter.d.ts +103 -0
  17. package/dist/cli/diagnostic-reporter.d.ts.map +1 -0
  18. package/dist/cli/diagnostic-reporter.js +254 -0
  19. package/dist/cli/diagnostic-reporter.js.map +1 -0
  20. package/dist/cli/project-ignore.d.ts +113 -0
  21. package/dist/cli/project-ignore.d.ts.map +1 -0
  22. package/dist/cli/project-ignore.js +199 -0
  23. package/dist/cli/project-ignore.js.map +1 -0
  24. package/dist/cli/safe-text.d.ts +25 -0
  25. package/dist/cli/safe-text.d.ts.map +1 -0
  26. package/dist/cli/safe-text.js +34 -0
  27. package/dist/cli/safe-text.js.map +1 -0
  28. package/dist/cli/supervisor.d.ts +108 -0
  29. package/dist/cli/supervisor.d.ts.map +1 -0
  30. package/dist/cli/supervisor.js +139 -0
  31. package/dist/cli/supervisor.js.map +1 -0
  32. package/dist/cli.d.ts +247 -0
  33. package/dist/cli.d.ts.map +1 -0
  34. package/dist/cli.js +591 -0
  35. package/dist/cli.js.map +1 -0
  36. package/dist/corpus-validator.d.ts +183 -0
  37. package/dist/corpus-validator.d.ts.map +1 -0
  38. package/dist/corpus-validator.js +479 -0
  39. package/dist/corpus-validator.js.map +1 -0
  40. package/dist/document-identity-rule.d.ts +198 -0
  41. package/dist/document-identity-rule.d.ts.map +1 -0
  42. package/dist/document-identity-rule.js +244 -0
  43. package/dist/document-identity-rule.js.map +1 -0
  44. package/dist/ecr.d.ts +103 -0
  45. package/dist/ecr.d.ts.map +1 -0
  46. package/dist/ecr.js +216 -0
  47. package/dist/ecr.js.map +1 -0
  48. package/dist/glob-pattern.d.ts +94 -0
  49. package/dist/glob-pattern.d.ts.map +1 -0
  50. package/dist/glob-pattern.js +188 -0
  51. package/dist/glob-pattern.js.map +1 -0
  52. package/dist/heading-source-form.d.ts +77 -0
  53. package/dist/heading-source-form.d.ts.map +1 -0
  54. package/dist/heading-source-form.js +129 -0
  55. package/dist/heading-source-form.js.map +1 -0
  56. package/dist/identifier-grammar.d.ts +212 -0
  57. package/dist/identifier-grammar.d.ts.map +1 -0
  58. package/dist/identifier-grammar.js +273 -0
  59. package/dist/identifier-grammar.js.map +1 -0
  60. package/dist/index.d.ts +19 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +11 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/inline-reference-rule.d.ts +557 -0
  65. package/dist/inline-reference-rule.d.ts.map +1 -0
  66. package/dist/inline-reference-rule.js +802 -0
  67. package/dist/inline-reference-rule.js.map +1 -0
  68. package/dist/meta-documents.d.ts +91 -0
  69. package/dist/meta-documents.d.ts.map +1 -0
  70. package/dist/meta-documents.js +133 -0
  71. package/dist/meta-documents.js.map +1 -0
  72. package/dist/per-document-visitor.d.ts +510 -0
  73. package/dist/per-document-visitor.d.ts.map +1 -0
  74. package/dist/per-document-visitor.js +1032 -0
  75. package/dist/per-document-visitor.js.map +1 -0
  76. package/dist/references-section-rule.d.ts +482 -0
  77. package/dist/references-section-rule.d.ts.map +1 -0
  78. package/dist/references-section-rule.js +777 -0
  79. package/dist/references-section-rule.js.map +1 -0
  80. package/dist/section-hierarchy-rule.d.ts +299 -0
  81. package/dist/section-hierarchy-rule.d.ts.map +1 -0
  82. package/dist/section-hierarchy-rule.js +482 -0
  83. package/dist/section-hierarchy-rule.js.map +1 -0
  84. package/dist/source-alignment.d.ts +41 -0
  85. package/dist/source-alignment.d.ts.map +1 -0
  86. package/dist/source-alignment.js +166 -0
  87. package/dist/source-alignment.js.map +1 -0
  88. package/dist/source-lines.d.ts +69 -0
  89. package/dist/source-lines.d.ts.map +1 -0
  90. package/dist/source-lines.js +104 -0
  91. package/dist/source-lines.js.map +1 -0
  92. package/dist/spec-version.d.ts +19 -0
  93. package/dist/spec-version.d.ts.map +1 -0
  94. package/dist/spec-version.js +19 -0
  95. package/dist/spec-version.js.map +1 -0
  96. package/dist/types.d.ts +219 -0
  97. package/dist/types.d.ts.map +1 -0
  98. package/dist/types.js +11 -0
  99. package/dist/types.js.map +1 -0
  100. package/examples/docs/0. Orientation/0.0 - System Overview.md +34 -0
  101. package/examples/docs/0. Orientation/0.0.1 - Glossary.md +21 -0
  102. package/examples/docs/0. Orientation/0.0.2 - Quality Gates.md +22 -0
  103. package/examples/docs/3. Ingestion/3.1 - Ingestion - Validation Rules.md +33 -0
  104. package/examples/docs/4. Payments/4.10 - Settlement.md +22 -0
  105. package/examples/docs/4. Payments/4.2 - Payment Processing Contract.md +33 -0
  106. package/examples/docs/8. Orchestration/8.1 - Workflow Orchestration Contract.md +38 -0
  107. package/examples/docs/8. Orchestration/8.1.3 - Retry Policy.md +17 -0
  108. package/examples/docs/8. Orchestration/8.10 - Dead Letter Queue.md +20 -0
  109. package/examples/docs/README.md +7 -0
  110. package/package.json +65 -7
  111. package/protocol/navigation-protocol.md +223 -0
  112. package/spec/v2/1 - ECR - Structural Specification.md +1467 -0
  113. package/spec/v2/2 - ECR - User Guide.md +845 -0
  114. package/spec/v2/3 - Design Rationale - The Section Separator.md +243 -0
  115. package/src/bin.ts +30 -0
  116. package/src/cli/corpus-loader.ts +482 -0
  117. package/src/cli/corpus-statistics.ts +196 -0
  118. package/src/cli/diagnostic-reporter.ts +344 -0
  119. package/src/cli/project-ignore.ts +238 -0
  120. package/src/cli/safe-text.ts +39 -0
  121. package/src/cli/supervisor.ts +204 -0
  122. package/src/cli.ts +836 -0
  123. package/src/corpus-validator.ts +642 -0
  124. package/src/document-identity-rule.ts +422 -0
  125. package/src/ecr.ts +298 -0
  126. package/src/glob-pattern.ts +242 -0
  127. package/src/heading-source-form.ts +173 -0
  128. package/src/identifier-grammar.ts +380 -0
  129. package/src/index.ts +78 -0
  130. package/src/inline-reference-rule.ts +1235 -0
  131. package/src/meta-documents.ts +159 -0
  132. package/src/per-document-visitor.ts +1528 -0
  133. package/src/references-section-rule.ts +1182 -0
  134. package/src/section-hierarchy-rule.ts +705 -0
  135. package/src/source-alignment.ts +209 -0
  136. package/src/source-lines.ts +123 -0
  137. package/src/spec-version.ts +19 -0
  138. package/src/types.ts +267 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus-validator.js","sourceRoot":"","sources":["../src/corpus-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Document Identity Rule (ECR101)
3
+ *
4
+ * Validates the document identity constraint defined in the ECR specification:
5
+ * - 1#9.3 -- Document Identity Rule [ECR101]
6
+ * - 1#9.8 -- Per-Document Structural Invariants ("Exactly one valid H1 DocID")
7
+ *
8
+ * This rule consumes heading node data from an AST traversal and validates
9
+ * the "exactly one H1 with a valid DocID and title" constraint. It delegates
10
+ * identifier parsing to {@link IdentifierGrammar} and emits {@link Diagnostic}
11
+ * objects for any violations.
12
+ */
13
+ import type { DocID, Diagnostic, PositionRange } from './types.js';
14
+ import { IdentifierGrammar } from './identifier-grammar.js';
15
+ /**
16
+ * Canonical rule identifier for the Document Identity Rule.
17
+ *
18
+ * Referenced as [ECR101] in the ECR specification (1#9.3).
19
+ */
20
+ export declare const DOCUMENT_IDENTITY_RULE_ID: string;
21
+ /**
22
+ * Data extracted from a single heading AST node, provided by the
23
+ * document traversal layer.
24
+ *
25
+ * The rule does not parse Markdown itself; it operates on heading
26
+ * data supplied by the visitor/traversal infrastructure.
27
+ */
28
+ export interface HeadingNodeData {
29
+ /** Markdown heading depth (1 for H1, 2 for H2, etc.). */
30
+ readonly depth: number;
31
+ /** Plain text content of the heading node (e.g. `"3.1 - Scenario Authoring"`). */
32
+ readonly text: string;
33
+ /**
34
+ * Positional range of the heading node within the source document.
35
+ * Optional; depends on whether the Markdown parser provides positional metadata.
36
+ */
37
+ readonly range?: PositionRange;
38
+ }
39
+ /**
40
+ * Represents the successfully extracted document identity from a valid H1 heading.
41
+ */
42
+ export interface DocumentIdentity {
43
+ /** The DocID extracted from the H1 heading. */
44
+ readonly docId: DocID;
45
+ /** The title extracted from the H1 heading (display/diagnostic metadata only). */
46
+ readonly title: string;
47
+ /** Positional range of the H1 heading, when available. */
48
+ readonly range?: PositionRange;
49
+ }
50
+ /**
51
+ * The complete result produced by finalising the Document Identity Rule
52
+ * after all headings have been evaluated.
53
+ *
54
+ * Contains zero or more diagnostics and, when the rule passes,
55
+ * the extracted document identity.
56
+ */
57
+ export interface DocumentIdentityRuleResult {
58
+ /** Diagnostics emitted during evaluation (errors for violations, info/warnings as applicable). */
59
+ readonly diagnostics: readonly Diagnostic[];
60
+ /**
61
+ * The extracted document identity.
62
+ * Present only when exactly one valid H1 heading was found.
63
+ */
64
+ readonly identity?: DocumentIdentity;
65
+ }
66
+ /**
67
+ * Configuration options for constructing a {@link DocumentIdentityRule} instance.
68
+ */
69
+ export interface DocumentIdentityRuleOptions {
70
+ /**
71
+ * The opaque, host-provided URI identifying the document being validated.
72
+ * Attached to all emitted diagnostics.
73
+ */
74
+ readonly uri: string;
75
+ /**
76
+ * The {@link IdentifierGrammar} instance used for DocID parsing
77
+ * and separator validation.
78
+ */
79
+ readonly grammar: IdentifierGrammar;
80
+ /**
81
+ * The document's raw Markdown, for the heading source-form check of 1#9.11
82
+ * rule 1. When absent, as in unit tests that supply only parsed heading
83
+ * text, the check is skipped.
84
+ */
85
+ readonly sourceText?: string;
86
+ }
87
+ /**
88
+ * Validates the Document Identity Rule as defined in the ECR specification (1#9.3, 1#9.8).
89
+ *
90
+ * The rule enforces that a document contains exactly one H1 heading whose
91
+ * text matches `DocID <dash> Title`, where DocID conforms to the identifier
92
+ * grammar and Title is non-empty.
93
+ *
94
+ * Usage:
95
+ * 1. Construct a rule instance with the document URI and an {@link IdentifierGrammar}.
96
+ * 2. Call {@link evaluateHeading} for every heading node encountered during AST traversal.
97
+ * 3. Call {@link finalise} after all headings have been evaluated to obtain
98
+ * the complete result including any "missing H1" diagnostics.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * const grammar = new IdentifierGrammar();
103
+ * const rule = new DocumentIdentityRule({ uri: 'file:///doc.md', grammar });
104
+ *
105
+ * rule.evaluateHeading({ depth: 1, text: '3.1 - My Document', range: someRange });
106
+ * rule.evaluateHeading({ depth: 2, text: '3.1#1 - Section', range: anotherRange });
107
+ *
108
+ * const result: DocumentIdentityRuleResult = rule.finalise();
109
+ * ```
110
+ */
111
+ export declare class DocumentIdentityRule {
112
+ /** The opaque, host-provided URI identifying the document being validated. */
113
+ private readonly uri;
114
+ /** The grammar instance used for identifier parsing and separator validation. */
115
+ private readonly grammar;
116
+ /** All H1 headings encountered during evaluation, in traversal order. */
117
+ private readonly collectedH1Headings;
118
+ /** Checks the H1's source line against the document recipe. */
119
+ private readonly headingSourceForm;
120
+ /**
121
+ * Constructs a new Document Identity Rule evaluator.
122
+ *
123
+ * @param options - Configuration including the document URI and grammar instance
124
+ */
125
+ constructor(options: DocumentIdentityRuleOptions);
126
+ /**
127
+ * Evaluates a single heading node against the document identity constraint.
128
+ *
129
+ * For H1 headings (depth === 1), the rule records the heading for
130
+ * analysis during {@link finalise}. Headings with depth \> 1 are
131
+ * ignored by this rule.
132
+ *
133
+ * @param headingNodeData - Data extracted from a heading AST node
134
+ */
135
+ evaluateHeading(headingNodeData: HeadingNodeData): void;
136
+ /**
137
+ * Finalises the rule evaluation and produces the complete result.
138
+ *
139
+ * This method must be called after all heading nodes have been supplied
140
+ * via {@link evaluateHeading}. It analyses all collected H1 headings
141
+ * and emits appropriate diagnostics:
142
+ *
143
+ * - Zero H1 headings: emits a "missing H1" error diagnostic
144
+ * - Multiple H1 headings: emits a "multiple H1" error diagnostic
145
+ * - Exactly one H1 with invalid separator: emits a separator error diagnostic
146
+ * - Exactly one H1 with invalid format: emits a format error diagnostic
147
+ * - Exactly one valid H1: extracts the document identity
148
+ *
149
+ * @returns The complete rule result including all diagnostics and,
150
+ * when valid, the extracted document identity
151
+ */
152
+ finalise(): DocumentIdentityRuleResult;
153
+ /**
154
+ * Builds the result for the case where no H1 headings were found.
155
+ *
156
+ * @returns A rule result containing a "missing H1" error diagnostic
157
+ */
158
+ private buildMissingH1Result;
159
+ /**
160
+ * Builds the result for the case where multiple H1 headings were found.
161
+ *
162
+ * @returns A rule result containing a "multiple H1" error diagnostic
163
+ */
164
+ private buildMultipleH1Result;
165
+ /**
166
+ * Builds the result for the case where exactly one H1 heading was found.
167
+ *
168
+ * Validates the separator and heading format, emitting appropriate
169
+ * diagnostics for violations or extracting the document identity on success.
170
+ *
171
+ * @returns A rule result containing diagnostics and/or the extracted identity
172
+ */
173
+ private buildSingleH1Result;
174
+ /**
175
+ * Validates the separator used in an H1 heading.
176
+ *
177
+ * Delegates to {@link IdentifierGrammar.validateSeparator} and, when an
178
+ * invalid separator is detected, returns an error diagnostic describing
179
+ * the violation.
180
+ *
181
+ * @param heading - The collected H1 heading to validate
182
+ * @returns A diagnostic if the separator is invalid, or `undefined` if valid
183
+ */
184
+ private validateHeadingSeparator;
185
+ /**
186
+ * Creates a diagnostic object for the Document Identity Rule.
187
+ *
188
+ * All diagnostics share the same rule ID ({@link DOCUMENT_IDENTITY_RULE_ID}),
189
+ * severity (error), and document URI.
190
+ *
191
+ * @param message - Human-readable description of the issue
192
+ * @param range - Optional positional range of the heading within the source document
193
+ * @param data - Optional machine-readable detail, such as a `cause`
194
+ * @returns A fully populated diagnostic object
195
+ */
196
+ private createDiagnostic;
197
+ }
198
+ //# sourceMappingURL=document-identity-rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-identity-rule.d.ts","sourceRoot":"","sources":["../src/document-identity-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAC;AAKvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAQ5D;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAiB,CAAC;AAM1D;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAMD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,kFAAkF;IAClF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IACzC,kGAAkG;IAClG,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CACtC;AAMD;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAsCD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,oBAAoB;IAC/B,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAE5C,yEAAyE;IACzE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuB;IAE3D,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IAEtD;;;;OAIG;gBACgB,OAAO,EAAE,2BAA2B;IAOvD;;;;;;;;OAQG;IACI,eAAe,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI;IAa9D;;;;;;;;;;;;;;;OAeG;IACI,QAAQ,IAAI,0BAA0B;IAkB7C;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAQ5B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAa7B;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IA2D3B;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB;CAgBzB"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Document Identity Rule (ECR101)
3
+ *
4
+ * Validates the document identity constraint defined in the ECR specification:
5
+ * - 1#9.3 -- Document Identity Rule [ECR101]
6
+ * - 1#9.8 -- Per-Document Structural Invariants ("Exactly one valid H1 DocID")
7
+ *
8
+ * This rule consumes heading node data from an AST traversal and validates
9
+ * the "exactly one H1 with a valid DocID and title" constraint. It delegates
10
+ * identifier parsing to {@link IdentifierGrammar} and emits {@link Diagnostic}
11
+ * objects for any violations.
12
+ */
13
+ import { IdentifierGrammar } from './identifier-grammar.js';
14
+ import { HEADING_SOURCE_FORM_CAUSE, HeadingSourceForm } from './heading-source-form.js';
15
+ // ---------------------------------------------------------------------------
16
+ // Rule identifier constant
17
+ // ---------------------------------------------------------------------------
18
+ /**
19
+ * Canonical rule identifier for the Document Identity Rule.
20
+ *
21
+ * Referenced as [ECR101] in the ECR specification (1#9.3).
22
+ */
23
+ export const DOCUMENT_IDENTITY_RULE_ID = 'ECR101';
24
+ // ---------------------------------------------------------------------------
25
+ // Diagnostic severity constant
26
+ // ---------------------------------------------------------------------------
27
+ /**
28
+ * The severity used for all Document Identity Rule diagnostics.
29
+ *
30
+ * Per 1#9.8, violation of any per-document structural invariant is an ERROR.
31
+ */
32
+ const DIAGNOSTIC_SEVERITY = 'error';
33
+ /**
34
+ * Matches heading text that begins with a number, i.e. one that at least
35
+ * attempts a DocID.
36
+ */
37
+ const STARTS_WITH_DIGIT_PATTERN = /^\s*\d/;
38
+ // ---------------------------------------------------------------------------
39
+ // Rule class
40
+ // ---------------------------------------------------------------------------
41
+ /**
42
+ * Validates the Document Identity Rule as defined in the ECR specification (1#9.3, 1#9.8).
43
+ *
44
+ * The rule enforces that a document contains exactly one H1 heading whose
45
+ * text matches `DocID <dash> Title`, where DocID conforms to the identifier
46
+ * grammar and Title is non-empty.
47
+ *
48
+ * Usage:
49
+ * 1. Construct a rule instance with the document URI and an {@link IdentifierGrammar}.
50
+ * 2. Call {@link evaluateHeading} for every heading node encountered during AST traversal.
51
+ * 3. Call {@link finalise} after all headings have been evaluated to obtain
52
+ * the complete result including any "missing H1" diagnostics.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * const grammar = new IdentifierGrammar();
57
+ * const rule = new DocumentIdentityRule({ uri: 'file:///doc.md', grammar });
58
+ *
59
+ * rule.evaluateHeading({ depth: 1, text: '3.1 - My Document', range: someRange });
60
+ * rule.evaluateHeading({ depth: 2, text: '3.1#1 - Section', range: anotherRange });
61
+ *
62
+ * const result: DocumentIdentityRuleResult = rule.finalise();
63
+ * ```
64
+ */
65
+ export class DocumentIdentityRule {
66
+ /** The opaque, host-provided URI identifying the document being validated. */
67
+ uri;
68
+ /** The grammar instance used for identifier parsing and separator validation. */
69
+ grammar;
70
+ /** All H1 headings encountered during evaluation, in traversal order. */
71
+ collectedH1Headings;
72
+ /** Checks the H1's source line against the document recipe. */
73
+ headingSourceForm;
74
+ /**
75
+ * Constructs a new Document Identity Rule evaluator.
76
+ *
77
+ * @param options - Configuration including the document URI and grammar instance
78
+ */
79
+ constructor(options) {
80
+ this.uri = options.uri;
81
+ this.grammar = options.grammar;
82
+ this.collectedH1Headings = [];
83
+ this.headingSourceForm = new HeadingSourceForm(options.sourceText);
84
+ }
85
+ /**
86
+ * Evaluates a single heading node against the document identity constraint.
87
+ *
88
+ * For H1 headings (depth === 1), the rule records the heading for
89
+ * analysis during {@link finalise}. Headings with depth \> 1 are
90
+ * ignored by this rule.
91
+ *
92
+ * @param headingNodeData - Data extracted from a heading AST node
93
+ */
94
+ evaluateHeading(headingNodeData) {
95
+ if (headingNodeData.depth !== 1) {
96
+ return;
97
+ }
98
+ const collectedHeading = {
99
+ text: headingNodeData.text,
100
+ ...(headingNodeData.range !== undefined ? { range: headingNodeData.range } : {}),
101
+ };
102
+ this.collectedH1Headings.push(collectedHeading);
103
+ }
104
+ /**
105
+ * Finalises the rule evaluation and produces the complete result.
106
+ *
107
+ * This method must be called after all heading nodes have been supplied
108
+ * via {@link evaluateHeading}. It analyses all collected H1 headings
109
+ * and emits appropriate diagnostics:
110
+ *
111
+ * - Zero H1 headings: emits a "missing H1" error diagnostic
112
+ * - Multiple H1 headings: emits a "multiple H1" error diagnostic
113
+ * - Exactly one H1 with invalid separator: emits a separator error diagnostic
114
+ * - Exactly one H1 with invalid format: emits a format error diagnostic
115
+ * - Exactly one valid H1: extracts the document identity
116
+ *
117
+ * @returns The complete rule result including all diagnostics and,
118
+ * when valid, the extracted document identity
119
+ */
120
+ finalise() {
121
+ const headingCount = this.collectedH1Headings.length;
122
+ if (headingCount === 0) {
123
+ return this.buildMissingH1Result();
124
+ }
125
+ if (headingCount > 1) {
126
+ return this.buildMultipleH1Result();
127
+ }
128
+ return this.buildSingleH1Result();
129
+ }
130
+ // -------------------------------------------------------------------------
131
+ // Private helpers
132
+ // -------------------------------------------------------------------------
133
+ /**
134
+ * Builds the result for the case where no H1 headings were found.
135
+ *
136
+ * @returns A rule result containing a "missing H1" error diagnostic
137
+ */
138
+ buildMissingH1Result() {
139
+ const diagnostic = this.createDiagnostic('Document is missing an H1 heading with a valid DocID.');
140
+ return { diagnostics: [diagnostic] };
141
+ }
142
+ /**
143
+ * Builds the result for the case where multiple H1 headings were found.
144
+ *
145
+ * @returns A rule result containing a "multiple H1" error diagnostic
146
+ */
147
+ buildMultipleH1Result() {
148
+ const firstHeading = this.collectedH1Headings[0];
149
+ const headingCount = String(this.collectedH1Headings.length);
150
+ const diagnostic = this.createDiagnostic(`Document contains ${headingCount} H1 headings, but exactly one is required.`, firstHeading?.range);
151
+ return { diagnostics: [diagnostic] };
152
+ }
153
+ /**
154
+ * Builds the result for the case where exactly one H1 heading was found.
155
+ *
156
+ * Validates the separator and heading format, emitting appropriate
157
+ * diagnostics for violations or extracting the document identity on success.
158
+ *
159
+ * @returns A rule result containing diagnostics and/or the extracted identity
160
+ */
161
+ buildSingleH1Result() {
162
+ const heading = this.collectedH1Headings[0];
163
+ if (heading === undefined) {
164
+ return this.buildMissingH1Result();
165
+ }
166
+ const separatorDiagnostic = this.validateHeadingSeparator(heading);
167
+ if (separatorDiagnostic !== undefined) {
168
+ return { diagnostics: [separatorDiagnostic] };
169
+ }
170
+ const headingParseResult = this.grammar.parseHeading(heading.text);
171
+ if (!headingParseResult.valid) {
172
+ const formatDiagnostic = this.createDiagnostic(`H1 heading does not match the required format: DocID <dash> Title.`, heading.range);
173
+ return { diagnostics: [formatDiagnostic] };
174
+ }
175
+ const identity = {
176
+ docId: headingParseResult.docId,
177
+ title: headingParseResult.title,
178
+ ...(heading.range !== undefined ? { range: heading.range } : {}),
179
+ };
180
+ // An H1 no recipe can find is reported, but its identity is still
181
+ // established. Withholding it would skip every other rule for the
182
+ // document and turn each citation of it elsewhere into an unresolved
183
+ // target -- one mistake reported many times over. The document fails
184
+ // either way, and the guarantee covers only corpora that pass.
185
+ const obstruction = this.headingSourceForm.findObstruction(heading.range, 1, identity.docId);
186
+ if (obstruction !== undefined) {
187
+ return {
188
+ diagnostics: [
189
+ this.createDiagnostic(HeadingSourceForm.explain(obstruction, 1, identity.docId), heading.range, { cause: HEADING_SOURCE_FORM_CAUSE, obstruction, docId: identity.docId }),
190
+ ],
191
+ identity,
192
+ };
193
+ }
194
+ return { diagnostics: [], identity };
195
+ }
196
+ /**
197
+ * Validates the separator used in an H1 heading.
198
+ *
199
+ * Delegates to {@link IdentifierGrammar.validateSeparator} and, when an
200
+ * invalid separator is detected, returns an error diagnostic describing
201
+ * the violation.
202
+ *
203
+ * @param heading - The collected H1 heading to validate
204
+ * @returns A diagnostic if the separator is invalid, or `undefined` if valid
205
+ */
206
+ validateHeadingSeparator(heading) {
207
+ const separatorResult = this.grammar.validateSeparator(heading.text);
208
+ if (separatorResult.valid) {
209
+ return undefined;
210
+ }
211
+ // An H1 with no number at all is the usual case in an unconverted
212
+ // document, and deserves a message that says so.
213
+ if (!STARTS_WITH_DIGIT_PATTERN.test(heading.text)) {
214
+ return this.createDiagnostic(`H1 "${heading.text.trim()}" is not numbered. The H1 carries the document's DocID, ` +
215
+ `for example "3.1 - ${heading.text.trim()}".`, heading.range);
216
+ }
217
+ const diagnostic = this.createDiagnostic(`H1 heading has no recognisable separator. ` +
218
+ `Expected: a number, a dash (-, – or —), then the title.`, heading.range);
219
+ return diagnostic;
220
+ }
221
+ /**
222
+ * Creates a diagnostic object for the Document Identity Rule.
223
+ *
224
+ * All diagnostics share the same rule ID ({@link DOCUMENT_IDENTITY_RULE_ID}),
225
+ * severity (error), and document URI.
226
+ *
227
+ * @param message - Human-readable description of the issue
228
+ * @param range - Optional positional range of the heading within the source document
229
+ * @param data - Optional machine-readable detail, such as a `cause`
230
+ * @returns A fully populated diagnostic object
231
+ */
232
+ createDiagnostic(message, range, data) {
233
+ const diagnostic = {
234
+ ruleId: DOCUMENT_IDENTITY_RULE_ID,
235
+ severity: DIAGNOSTIC_SEVERITY,
236
+ message,
237
+ uri: this.uri,
238
+ ...(range !== undefined ? { range } : {}),
239
+ ...(data !== undefined ? { data } : {}),
240
+ };
241
+ return diagnostic;
242
+ }
243
+ }
244
+ //# sourceMappingURL=document-identity-rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-identity-rule.js","sourceRoot":"","sources":["../src/document-identity-rule.ts"],"names":[],"mappings":"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"}
package/dist/ecr.d.ts ADDED
@@ -0,0 +1,103 @@
1
+ /**
2
+ * ECR Public API -- Ecr Facade
3
+ *
4
+ * Top-level public API for the ECR structural linter.
5
+ *
6
+ * Derived from section 1#13 (Public Interface Contract) and
7
+ * section 1#10 (Output Schema) of the ECR Structural Specification (doc 1).
8
+ *
9
+ * This module provides the {@link Ecr} facade, which delegates
10
+ * per-document validation to {@link PerDocumentVisitor} and
11
+ * corpus-wide integrity checks to {@link CorpusValidator}.
12
+ *
13
+ * Per-document results are returned exactly as the visitor produces
14
+ * them: every severity is set by the rule that reports the finding.
15
+ *
16
+ * The facade applies one orchestration-level policy:
17
+ *
18
+ * **Cross-document duplicate SectionID detection**: The corpus
19
+ * validator only sees SectionIDs that survive per-document
20
+ * extraction (i.e., those that pass ECR102). A heading like
21
+ * `## 3.1#1 - X` inside a document with DocID `4.1` fails ECR102
22
+ * (it names another document) and is never extracted — yet its
23
+ * SectionID text is still globally significant. The facade
24
+ * performs an additional cross-document duplicate check by
25
+ * collecting SectionIDs from both extracted sections and
26
+ * per-document diagnostics that carry a `sectionId` field.
27
+ */
28
+ import type { LintResult, CorpusResult } from "./types.js";
29
+ /**
30
+ * A single document supplied to corpus validation.
31
+ *
32
+ * Each entry provides the Markdown text and an opaque, host-provided URI
33
+ * that identifies the document instance.
34
+ */
35
+ export interface CorpusDocumentInput {
36
+ /** Opaque, host-provided URI identifying the document instance. */
37
+ readonly uri: string;
38
+ /** Raw Markdown text of the document. */
39
+ readonly markdownText: string;
40
+ /** Optional version tag for the document instance. */
41
+ readonly version?: number;
42
+ }
43
+ /**
44
+ * Top-level public API for the ECR structural linter.
45
+ *
46
+ * Provides two operations:
47
+ * - Single-document linting via {@link Ecr.lintDocument}
48
+ * - Corpus-wide validation via {@link Ecr.validateCorpus}
49
+ *
50
+ * This class is stateless across invocations. Successive calls with
51
+ * identical inputs produce identical results.
52
+ */
53
+ export declare class Ecr {
54
+ /**
55
+ * Lint a single Markdown document against per-document ECR structural invariants.
56
+ *
57
+ * Creates a {@link PerDocumentVisitor} for the given document and delegates
58
+ * the linting operation to it.
59
+ *
60
+ * @param uri - Opaque, host-provided URI identifying the document instance.
61
+ * @param markdownText - Raw Markdown text of the document.
62
+ * @param version - Optional version tag propagated through to the result.
63
+ * @returns Structured lint result containing diagnostics and optionally extracted artefacts.
64
+ */
65
+ lintDocument(uri: string, markdownText: string, version?: number): LintResult;
66
+ /**
67
+ * Validate a corpus of Markdown documents.
68
+ *
69
+ * Executes per-document linting on every document (Pass 1), then performs
70
+ * corpus-wide integrity checks on successfully linted documents (Pass 2).
71
+ *
72
+ * After the standard corpus validation, the facade performs an additional
73
+ * cross-document duplicate SectionID check that considers SectionIDs from
74
+ * per-document diagnostics (not just extracted sections), ensuring that
75
+ * headings rejected by ECR102 (e.g., wrong DocID prefix) still participate
76
+ * in global uniqueness enforcement.
77
+ *
78
+ * @param documents - Collection of documents to validate.
79
+ * @returns Corpus result containing per-document results, corpus-wide diagnostics, and an optional global identifier index.
80
+ */
81
+ validateCorpus(documents: readonly CorpusDocumentInput[]): CorpusResult;
82
+ /**
83
+ * Detects duplicate SectionIDs across documents by examining both
84
+ * extracted sections and per-document diagnostics.
85
+ *
86
+ * The standard {@link CorpusValidator} only checks extracted sections
87
+ * (those that pass ECR102). This method extends coverage to include
88
+ * SectionIDs mentioned in per-document diagnostics — for example,
89
+ * a heading `## 3.1#1 - X` inside a document with DocID `4.1` fails
90
+ * ECR102 (it names another document) but the SectionID `3.1#1` is still
91
+ * present in the diagnostic's `sectionId` field. If document `3.1` also
92
+ * defines `3.1#1`, that is a corpus-level duplicate.
93
+ *
94
+ * This method only emits diagnostics for duplicates NOT already
95
+ * detected by the standard corpus validator (i.e., duplicates involving
96
+ * at least one SectionID from a diagnostic rather than an extracted section).
97
+ *
98
+ * @param entries - The per-document lint entries from Pass 1
99
+ * @returns Additional corpus-level diagnostics for duplicate SectionIDs
100
+ */
101
+ private detectCrossDocumentDuplicateSectionIds;
102
+ }
103
+ //# sourceMappingURL=ecr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecr.d.ts","sourceRoot":"","sources":["../src/ecr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EAIb,MAAM,YAAY,CAAC;AASpB;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB,yCAAyC;IACzC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,sDAAsD;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAeD;;;;;;;;;GASG;AACH,qBAAa,GAAG;IACd;;;;;;;;;;OAUG;IACI,YAAY,CACjB,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,GACf,UAAU;IASb;;;;;;;;;;;;;;OAcG;IACI,cAAc,CACnB,SAAS,EAAE,SAAS,mBAAmB,EAAE,GACxC,YAAY;IAkDf;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,sCAAsC;CAuG/C"}