@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,845 @@
1
+ # 2 - ECR - User Guide
2
+
3
+ This document defines the user-facing structural rules for **Explicit Constraint Referencing (ECR)** as applied to software documentation written in Markdown (see 1).
4
+
5
+ ## 2#1 - What This Document Covers
6
+
7
+ - [What problem ECR solves](#23---what-problem-ecr-solves)
8
+
9
+ - [The four structural rules of ECR](#24---the-four-rules-of-ecr)
10
+
11
+ - [Direction semantics](#25---direction-semantics)
12
+
13
+ - [Corpus-wide validation requirements](#26---corpus-wide-rules)
14
+
15
+ - [What ECR does not do](#27---what-ecr-does-not-do)
16
+
17
+ - [Minimal compliant example](#28---minimal-compliant-example)
18
+
19
+ - [Migration strategy for existing software documentation](#211---migrating-existing-documentation-to-ecr)
20
+
21
+
22
+ This document describes **structure only**.
23
+
24
+ It does not define:
25
+
26
+ - Graph construction
27
+
28
+ - Traversal semantics
29
+
30
+ - Linting implementation details
31
+
32
+ - Runtime interpretation of constraints
33
+
34
+
35
+ Those concerns belong to consuming systems (see 2#9).
36
+
37
+ ---
38
+
39
+ ## 2#2 - User Specification
40
+
41
+ Explicit Constraint Referencing (ECR) is a structural convention for writing Markdown documentation so that constraint relationships between documents are explicit and machine-traversable.
42
+
43
+ ECR does not introduce a new markup language.
44
+ It standardizes how existing Markdown is written so that interdependent constraints become an explicit graph, one a coding agent can traverse with ordinary text search.
45
+
46
+ This document defines the user-facing rules of ECR (see 1).
47
+
48
+ ---
49
+
50
+ ## 2#3 - What Problem ECR Solves
51
+
52
+ Software architectural documentation contains constraints that:
53
+
54
+ - govern other constraints
55
+
56
+ - reference other documents
57
+
58
+ - impose limits
59
+
60
+ - define contracts
61
+
62
+
63
+ Humans implicitly understand these relationships when reading documentation. Coding agents do not. And traditional Markdown documentation does not encode these relationships explicitly.
64
+
65
+ As documentation scales, governance boundaries become implicit and unverifiable. Constraint relationships that exist in practice are not machine-auditable.
66
+
67
+ ECR provides that structure by making constraint relationships explicit and consistently encoded so coding agents can see them.
68
+
69
+ ECR makes architectural authority, dependency, and contractual boundaries explicit and structurally enforceable.
70
+
71
+ ---
72
+
73
+ ## 2#4 - The Four Rules of ECR
74
+
75
+ ECR consists of four structural rules (see 1).
76
+
77
+ ---
78
+
79
+ ### 2#4.1 - Rule 1 — Every document has a numbered H1
80
+
81
+ Each document must begin with a numbered H1 heading:
82
+
83
+ ```markdown
84
+ # 3.1 - Ingestion - Validation Rules
85
+ ```
86
+
87
+ - The numeric prefix (`3.1`) is the **DocID**.
88
+
89
+ - DocIDs must be unique across the corpus.
90
+
91
+ - A dash separates the DocID from the title. A hyphen (`-`), en dash (`–`) or em dash (`—`) are all accepted.
92
+
93
+
94
+ The DocID is the document’s stable identity.
95
+
96
+ ---
97
+
98
+ ### 2#4.2 - Rule 2 — Sub-headings carry a SectionID
99
+
100
+ Every sub-heading carries a SectionID: the document’s DocID, the separator `#`, and a section path.
101
+
102
+ Example:
103
+
104
+ ```markdown
105
+ # 3.1 - Ingestion - Validation Rules
106
+
107
+ ## 3.1#1 - Mode-Aware Prompt Strategy
108
+
109
+ ### 3.1#1.1 - Expert Mode Prompts
110
+ ```
111
+
112
+ Rules:
113
+
114
+ - The identifier before the title is the DocID, `#`, then the section path.
115
+
116
+ - The number of section-path segments (after the `#`) must correspond to heading depth: one for `##`, two for `###`, and so on.
117
+
118
+ - A sub-section continues its parent's number: under `## 3.1#2`, the `###` headings are `3.1#2.1`, `3.1#2.2`, and so on.
119
+
120
+ - A dash separates the SectionID from the title, as in the H1.
121
+
122
+ - Section numbers must not skip structural levels.
123
+
124
+
125
+ Each numbered heading defines a stable **SectionID**.
126
+
127
+ ---
128
+
129
+ ### 2#4.3 - Rule 3 — Inline references must use `see` or `per`
130
+
131
+ Inline references create section-level edges.
132
+
133
+ Valid forms:
134
+
135
+ ```markdown
136
+ The validation logic is enforced per 3.1#2.
137
+ For orchestration details see 8.1#3.
138
+ ```
139
+
140
+ Rules:
141
+
142
+ - Only `see X` and `per X` create graph edges.
143
+
144
+ - `X` must be a valid DocID or SectionID.
145
+
146
+ - Numeric references written in other forms (e.g., “defined in 3.1.2”) do not create edges.
147
+
148
+ - If referencing a section `X#Y`, its document `X` must be declared in the References section. References to your own document's sections need no declaration.
149
+
150
+
151
+ Inline references inside code blocks or inline code are ignored.
152
+
153
+ **NOTE:**
154
+ - References are not concerned with the physical location of the referenced document in the file system.
155
+ - They refer only to a unique document ID across the documentation corpus.
156
+
157
+
158
+ ---
159
+
160
+ ### 2#4.4 - Rule 4 — Every document must declare its external references
161
+
162
+ Every document must contain a `## References` section.
163
+
164
+ Example:
165
+
166
+ ```markdown
167
+ ## References
168
+
169
+ - 3.1 - Ingestion - Validation Rules (authority - defines validation logic enforced by this document)
170
+ - 8.1 - Workflow Orchestration Contract (constraint - defines retry semantics applied to this workflow)
171
+ ```
172
+
173
+ Rules:
174
+
175
+ - The heading must be exactly `## References`.
176
+
177
+ - It must appear exactly once.
178
+
179
+ - If the document references anything, it must be followed immediately by a list. A document that references nothing leaves the section empty — the heading is still required, because an empty section states that there are no dependencies, and silence states nothing.
180
+
181
+ - Each entry must follow this structure:
182
+
183
+
184
+ ```
185
+ - {DocID} - {Title} ({direction} - {explanation})
186
+ ```
187
+
188
+ Allowed direction values:
189
+
190
+ - `authority`
191
+
192
+ - `dependency`
193
+
194
+ - `constraint`
195
+
196
+ - `contract`
197
+
198
+
199
+ The explanation must be non-empty text.
200
+
201
+ Each separator is a dash with a single space either side. As in headings, a hyphen, en dash or em dash are all accepted.
202
+
203
+ If the References section has no list, the document declares no external references. The linter reports this as information, not as an error.
204
+
205
+ **NOTE:**
206
+ - References are not concerned with the physical location of the referenced document in the file system.
207
+ - They refer only to a unique document ID across the documentation corpus.
208
+
209
+
210
+ ---
211
+
212
+ ## 2#5 - Direction Semantics
213
+
214
+ Each References entry defines a directed edge:
215
+
216
+ ```
217
+ Current Document → Referenced Document
218
+ ```
219
+
220
+ Direction labels describe the meaning of the relationship:
221
+
222
+ - **authority** — the referenced document governs this document
223
+
224
+ - **dependency** — this document relies on the referenced document
225
+
226
+ - **constraint** — the referenced document imposes restrictions
227
+
228
+ - **contract** — the referenced document defines structural obligations
229
+
230
+
231
+ Direction labels do not reverse edge direction. They type the relationship.
232
+
233
+ ---
234
+
235
+ ## 2#6 - Corpus-Wide Rules
236
+
237
+ When multiple documents are combined into a corpus:
238
+
239
+ - DocIDs must be globally unique.
240
+
241
+ - SectionIDs must be globally unique.
242
+
243
+ - Every referenced DocID must exist.
244
+
245
+ - Every inline referenced SectionID must exist.
246
+
247
+
248
+ Unresolved references invalidate ECR compliance.
249
+
250
+ Corpus-wide validation ensures that constraint relationships are globally resolvable, structurally consistent, and free from identifier ambiguity. This makes traversal deterministic and eliminates undocumented cross-document dependencies.
251
+
252
+ Any tool built on the extracted artefacts MUST:
253
+
254
+ - Treat validated structural artefacts as authoritative.
255
+
256
+ - Rebuild all derived indices deterministically from nodes and edges.
257
+
258
+ - Preserve graph identity independent of metadata.
259
+
260
+ - Ensure that metadata absence does not constitute a structural error.
261
+
262
+
263
+ These guarantees ensure that software architectural boundaries remain mechanically verifiable by coding agents as systems evolve.
264
+
265
+ ---
266
+
267
+ ## 2#7 - What ECR Does Not Do
268
+
269
+ ECR does not:
270
+
271
+ - Enforce stylistic Markdown rules
272
+
273
+ - Define semantic evaluation logic
274
+
275
+ - Interpret precedence
276
+
277
+ - Evaluate constraint satisfaction
278
+
279
+
280
+ ECR defines structure only.
281
+
282
+ Semantic interpretation belongs to whoever reads the documents.
283
+
284
+ ---
285
+
286
+ ## 2#8 - Minimal Compliant Example
287
+
288
+ ```markdown
289
+ # 5.1 - Reporting - Evaluation Strategy
290
+
291
+ ## 5.1#1 - Acceptance Criteria
292
+
293
+ Validation requirements are enforced per 3.1#2.
294
+
295
+ ## 5.1#2 - Evaluation Pipeline
296
+
297
+ Retry semantics are applied per 8.1#3.
298
+
299
+ ## References
300
+
301
+ - 3.1 - Ingestion - Validation Rules (authority - defines validation criteria enforced by evaluation)
302
+ - 8.1 - Workflow Orchestration Contract (constraint - retry semantics applied to evaluation runs)
303
+ ```
304
+
305
+ ---
306
+
307
+ ## 2#9 - Consuming an ECR Corpus
308
+
309
+ An ECR-compliant corpus is navigable with `grep` and nothing else. The
310
+ identifiers are exact and the edges are plain text on disk, so a coding agent
311
+ resolves a reference by searching for it rather than by querying a service. This
312
+ is the intended primary use, and it requires no software beyond what the agent
313
+ already has.
314
+
315
+ The linter is optional. It checks that a corpus holds to the rules and extracts
316
+ structural artefacts; it is not needed to read a corpus, only to validate one.
317
+
318
+ At a large enough corpus size, repeated full-corpus scans get slow, and a few
319
+ questions — transitive closure, cycle detection — are awkward to express as
320
+ searches at all. Nothing stops you precomputing them from the extracted
321
+ artefacts if you ever need to. That is a scale optimisation, not part of the
322
+ convention, and not something to build before the scans actually hurt.
323
+
324
+ Whatever consumes the corpus, the following hold:
325
+
326
+ - The graph contains DocIDs, SectionIDs and typed edges.
327
+ - Section content is not part of graph identity.
328
+ - Document titles and heading text are informational metadata. They MUST NOT
329
+ participate in structural identity, edge derivation, canonical ordering, or
330
+ equality comparison of graph structure. A consumer may persist them, separately
331
+ from structural state.
332
+ - Where a consumer persists structural artefacts and metadata together, it MUST
333
+ commit them atomically, so that no mixed structural state is observable.
334
+ - ECR does not define canonical ordering of nodes or edges. A consumer MUST
335
+ derive a deterministic ordering from stable identifiers.
336
+
337
+ ECR makes constraint topology explicit, and explicit topology is already
338
+ traversable. Anything further is a matter of speed, not of possibility.
339
+
340
+ ---
341
+
342
+
343
+ ## 2#10 - Common Mistakes
344
+
345
+ This section highlights common authoring errors that prevent documents from being ECR-compliant or from producing correct graph edges.
346
+
347
+ ---
348
+
349
+ ### 2#10.1 - ❌ Omitting the Section Separator
350
+
351
+ A sub-heading carries a SectionID, which always contains `#`. Writing the
352
+ identifier as dotted segments is the single most common mistake when migrating
353
+ an older corpus.
354
+
355
+ Incorrect:
356
+
357
+ ```markdown
358
+ # 3.1 - Ingestion
359
+
360
+ ## 3.1.1 - Validation Rules
361
+ ```
362
+
363
+ Correct:
364
+
365
+ ```markdown
366
+ # 3.1 - Ingestion
367
+
368
+ ## 3.1#1 - Validation Rules
369
+ ```
370
+
371
+ Without the separator, `3.1.1` is indistinguishable from document `3.1.1`, and a
372
+ corpus that contains both will produce colliding identifiers that no reader or
373
+ tool can resolve.
374
+
375
+ The dash between an identifier and its title is a different matter: hyphen-minus
376
+ (`-`), en dash (`–`) and em dash (`—`) are all accepted, because the dash
377
+ carries no structural meaning. Pick one for consistency if you like, but a
378
+ mixture will not fail validation.
379
+
380
+ ---
381
+
382
+
383
+ ### 2#10.2 - ❌ Writing Natural Language Instead of `see` or `per`
384
+
385
+ Only the following forms create inline edges:
386
+
387
+ - `see X`
388
+
389
+ - `per X`
390
+
391
+
392
+ Incorrect:
393
+
394
+ ```markdown
395
+ The validation logic is defined in 3.1.2.
396
+ ```
397
+
398
+ This does **not** create a graph edge.
399
+
400
+ Correct:
401
+
402
+ ```markdown
403
+ The validation logic is enforced per 3.1#2.
404
+ ```
405
+
406
+ If you do not use `see` or `per`, the reference will be ignored.
407
+
408
+ ---
409
+
410
+ ### 2#10.3 - ❌ Forgetting to Declare Referenced Documents
411
+
412
+ If you write:
413
+
414
+ ```markdown
415
+ See 3.1#2.
416
+ ```
417
+
418
+ Then your document must contain:
419
+
420
+ ```markdown
421
+ ## References
422
+
423
+ - 3.1 - Ingestion - Validation Rules (authority - ...)
424
+ ```
425
+
426
+ An inline reference cannot target a document the References section does not declare. A section reference such as `see 3.1#2` with `3.1` undeclared is always an error. A document reference such as `see 3.1` with `3.1` undeclared is an error when you lint a corpus in which document `3.1` exists.
427
+
428
+ **Numbers in ordinary prose.** `see` and `per` are also ordinary English: `100 requests per 60 seconds`, `see 3 examples below`. The linter reads these as references to DocIDs `60` and `3` and warns that they are undeclared. Because no such documents exist, they stay warnings and never fail validation. You can leave them as they are, or rephrase (`100 requests every 60 seconds`) to silence them. Section references are never mistaken for prose: nobody writes `per 60#2` in a sentence.
429
+
430
+ ---
431
+
432
+ ### 2#10.4 - ❌ Skipping Numbering Levels
433
+
434
+ Headings must carry a correctly formed SectionID.
435
+
436
+ Incorrect:
437
+
438
+ ```markdown
439
+ # 3.1 - Title
440
+
441
+ ### 3.1#1.1 - Subsection
442
+ ```
443
+
444
+ Correct:
445
+
446
+ ```markdown
447
+ # 3.1 - Title
448
+
449
+ ## 3.1#1 - Section
450
+
451
+ ### 3.1#1.1 - Subsection
452
+ ```
453
+
454
+ The number of numeric segments must match heading depth.
455
+
456
+ ---
457
+
458
+ ### 2#10.5 - ❌ Duplicate DocIDs Across the Corpus
459
+
460
+ Each document must have a globally unique DocID.
461
+
462
+ Incorrect:
463
+
464
+ Two documents both begin with:
465
+
466
+ ```markdown
467
+ # 3.1 - Something
468
+ ```
469
+
470
+ This will invalidate the corpus.
471
+
472
+ ---
473
+
474
+ ### 2#10.6 - ❌ Duplicate SectionIDs Within a Document
475
+
476
+ Each numbered heading must be unique.
477
+
478
+ Incorrect:
479
+
480
+ ```markdown
481
+ ## 3.1#1 - Section A
482
+ ## 3.1#1 - Section B
483
+ ```
484
+
485
+ Section identifiers must not repeat.
486
+
487
+ ---
488
+
489
+ ### 2#10.7 - ❌ Malformed References Entries
490
+
491
+ Each References entry must follow this exact structure:
492
+
493
+ ```
494
+ - {DocID} - {Title} ({direction} - {explanation})
495
+ ```
496
+
497
+ Common mistakes:
498
+
499
+ - Missing parentheses
500
+
501
+ - Missing explanation
502
+
503
+ - Using a direction not in the allowed list
504
+
505
+ - Missing the spaces around a separator dash (`3.1-Title` rather than `3.1 - Title`)
506
+
507
+
508
+ Allowed direction values:
509
+
510
+ - `authority`
511
+
512
+ - `dependency`
513
+
514
+ - `constraint`
515
+
516
+ - `contract`
517
+
518
+
519
+ ---
520
+
521
+ ### 2#10.8 - ❌ Assuming Content Is Part of Graph Identity
522
+
523
+ ECR graphs are built from:
524
+
525
+ - DocIDs
526
+
527
+ - SectionIDs
528
+
529
+ - Typed edges
530
+
531
+
532
+ Editing section text does not affect graph identity.
533
+
534
+ This includes changes to:
535
+
536
+ - Document titles (H1 heading text)
537
+ - Section heading text (heading titles)
538
+
539
+ Only changes to DocIDs, SectionIDs, or references change the structural graph.
540
+
541
+ ---
542
+
543
+ ### 2#10.9 - ❌ Forgetting the `## References` Section Entirely
544
+
545
+ Every ECR document must include exactly one `## References` section.
546
+
547
+ The `## References` section defines document-level edges. Inline references (`see X`, `per X`) define section-level edges. Both are structural: missing either changes what can be represented and validated.
548
+
549
+ Even if a document references no other documents, it must still include:
550
+
551
+ ```markdown
552
+ ## References
553
+ ```
554
+
555
+ The heading with no list beneath it is valid: it declares that the document has no external references, and the linter reports it as information rather than an error.
556
+
557
+ ---
558
+
559
+ ### 2#10.10 - ❌ Wrapping the Identifier in a Link or Formatting
560
+
561
+ Incorrect:
562
+
563
+ ```markdown
564
+ Retries are bounded, see [8.1#3.2](8.1-orchestration.md).
565
+ Retries are bounded per **8.1#3.2**.
566
+ ```
567
+
568
+ The brackets or asterisks between the keyword and the identifier mean a search for `see 8.1#3.2` no longer finds the reference, so neither an agent nor the linter can follow it.
569
+
570
+ The linter reports this as an **error** whenever it can tell that a reference was meant: when the target is a SectionID, as both examples above are, because the `#` form never appears in ordinary prose; and when the target is a bare DocID that the References section declares, that is the document's own DocID, or that the corpus confirms is a real document.
571
+
572
+ It **warns** only when the target is a bare number naming nothing known — undeclared, not your own, and absent from the corpus. There, `See *8.1* for details` cannot be told from a citation whose author reached for italics, so the linter says so rather than failing you.
573
+
574
+ The same applies to a line break between the keyword and the identifier, to a backslash escape inside it (`see 5\.1#1`), and to more than one space between the two. Each survives Markdown rendering and each defeats the search.
575
+
576
+ Correct:
577
+
578
+ ```markdown
579
+ Retries are bounded, see 8.1#3.2.
580
+ Retries are bounded per 8.1#3.2 ([orchestration contract](8.1-orchestration.md)).
581
+ ```
582
+
583
+ Keep the keyword and the identifier together as plain text. A link can still go elsewhere in the sentence, or around the whole reference: `[see 8.1#3.2](…)` is found by grep and followed by the linter.
584
+
585
+ ---
586
+
587
+ ## 2#11 - Migrating Existing Documentation to ECR
588
+
589
+ Most teams adopting ECR already have an existing Markdown corpus.
590
+
591
+ This section describes a practical, low-risk migration strategy.
592
+
593
+ ECR can be adopted incrementally.
594
+
595
+ ---
596
+
597
+ ### 2#11.1 - Step 1 — Assign Stable Document IDs
598
+
599
+ Start by assigning a DocID to each document.
600
+
601
+ Add a numbered H1 to the top of every file:
602
+
603
+ ```markdown
604
+ # 7.1 - Storage Layer
605
+ ```
606
+
607
+ Guidelines:
608
+
609
+ - Choose a numbering scheme that reflects your architecture.
610
+
611
+ - Keep IDs stable once assigned.
612
+
613
+ - Do not reuse numbers.
614
+
615
+ - Do not change IDs casually — they form graph identity.
616
+
617
+
618
+ At this stage, do not modify internal headings or references.
619
+
620
+ ---
621
+
622
+ ### 2#11.2 - Step 2 — Normalize Heading Structure
623
+
624
+ For each document:
625
+
626
+ - Ensure there is exactly one H1.
627
+
628
+ - Ensure sub-headings use the `DocID#section-path` form.
629
+
630
+ - Ensure heading depth matches numbering depth.
631
+
632
+
633
+ Example conversion:
634
+
635
+ Before:
636
+
637
+ ```markdown
638
+ ## Storage Modes
639
+ ```
640
+
641
+ After:
642
+
643
+ ```markdown
644
+ ## 7.1#1 - Storage Modes
645
+ ```
646
+
647
+ Do this one document at a time.
648
+
649
+ Run the linter after each file.
650
+
651
+ ---
652
+
653
+ ### 2#11.3 - Step 3 — Introduce the References Section
654
+
655
+ Add a `## References` section to each document.
656
+
657
+ Start with the obvious references — documents the text already cites.
658
+
659
+ Example:
660
+
661
+ ```markdown
662
+ ## References
663
+
664
+ - 3.1 - Ingestion - Validation Rules (authority - defines validation behaviour implemented here)
665
+ ```
666
+
667
+ Do not worry about perfection initially.
668
+
669
+ Focus on capturing major relationships first.
670
+
671
+ ---
672
+
673
+ ### 2#11.4 - Step 4 — Convert Natural Language References
674
+
675
+ Search for numeric cross-references:
676
+
677
+ - “defined in 3.1.2”
678
+
679
+ - “see section 8.1”
680
+
681
+ - “as described in 2.4”
682
+
683
+
684
+ Convert them to valid inline forms:
685
+
686
+ ```markdown
687
+ per 3.1#2
688
+ see 8.1
689
+ ```
690
+
691
+ Only `see` and `per` create edges.
692
+
693
+ If referencing a section such as `3.1#2`, ensure `3.1` appears in the References section.
694
+
695
+ ---
696
+
697
+ ### 2#11.5 - Step 5 — Resolve Linter Errors
698
+
699
+ Once the corpus is fully numbered:
700
+
701
+ - Fix duplicate DocIDs.
702
+
703
+ - Fix duplicate SectionIDs.
704
+
705
+ - Resolve missing referenced documents.
706
+
707
+ - Correct malformed References entries.
708
+
709
+
710
+ Run corpus-wide validation to ensure global uniqueness and resolution.
711
+
712
+ ---
713
+
714
+ ### 2#11.6 - Incremental vs Big-Bang Migration
715
+
716
+ Two strategies are possible:
717
+
718
+ #### 2#11.6.1 - Incremental Migration (Recommended)
719
+
720
+ - Convert one architectural layer at a time.
721
+
722
+ - Ensure internal consistency within that layer.
723
+
724
+ - Gradually extend ECR coverage outward.
725
+
726
+
727
+ This reduces risk and review overhead.
728
+
729
+ ---
730
+
731
+ #### 2#11.6.2 - Big-Bang Migration
732
+
733
+ - Assign DocIDs to all documents.
734
+
735
+ - Normalize all headings.
736
+
737
+ - Add References sections everywhere.
738
+
739
+ - Convert all inline references.
740
+
741
+
742
+ Only recommended for small corpora.
743
+
744
+ ---
745
+
746
+ ### 2#11.7 - Using an LLM to Assist Migration
747
+
748
+ LLMs can accelerate migration when used carefully.
749
+
750
+ Recommended approach:
751
+
752
+ 1. Select a single document.
753
+
754
+ 2. Provide the model with:
755
+
756
+ - The document text
757
+
758
+ - The ECR rules
759
+
760
+ - The target DocID
761
+
762
+ 3. Ask the model to:
763
+
764
+ - Normalize headings
765
+
766
+ - Add a References section
767
+
768
+ - Convert natural references to `see` / `per`
769
+
770
+
771
+ Review changes manually.
772
+
773
+ Do not migrate the entire corpus in one pass.
774
+ Work layer by layer to prevent numbering drift.
775
+
776
+ ---
777
+
778
+ ### 2#11.8 - Maintaining Stability After Migration
779
+
780
+ After migration:
781
+
782
+ - Treat DocIDs as stable identities.
783
+
784
+ - Avoid renumbering.
785
+
786
+ - Add new sections by extending numbering.
787
+
788
+ - Add new documents with new DocIDs.
789
+
790
+ - Do not “reuse” retired IDs.
791
+
792
+
793
+ ECR relies on identifier stability.
794
+
795
+ ---
796
+
797
+ ### 2#11.9 - Common Migration Pitfalls
798
+
799
+ - Renumbering documents after adoption.
800
+
801
+ - Forgetting to declare newly referenced documents.
802
+
803
+ - Letting an LLM “optimize” numbering across files.
804
+
805
+ - Migrating too many files simultaneously.
806
+
807
+
808
+ Adopt gradually. Validate continuously.
809
+
810
+ ---
811
+
812
+ ## 2#12 - Why Migration Is Worth It
813
+
814
+ Once a corpus is ECR-compliant:
815
+
816
+ - Constraint relationships become explicit.
817
+
818
+ - Drift becomes detectable.
819
+
820
+ - Cross-document governance becomes traversable.
821
+
822
+ - Agentic systems can reason over structure deterministically.
823
+
824
+
825
+ Once ECR-compliant, a documentation corpus becomes structurally auditable. Constraint relationships are explicit, globally resolvable, and mechanically validated. This reduces architectural drift, improves cross-team governance, and enables deterministic reasoning over institutional knowledge by coding agents.
826
+
827
+ For software teams building agentic systems, this transforms documentation from passive reference material into enforceable structural infrastructure.
828
+
829
+ ---
830
+
831
+ ## 2#13 - Why These Rules Matter
832
+
833
+ ECR works because it removes ambiguity.
834
+
835
+ If constraint relationships are not written in the exact, structured form ECR defines, the searches that make the graph traversable will not find them.
836
+
837
+ ECR is strict by design.
838
+
839
+ That strictness enables deterministic traversal and reliable agent reasoning.
840
+
841
+ ---
842
+
843
+ ## References
844
+
845
+ - 1 - ECR - Structural Specification (authority - the formal structural specification for ECR)