@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.
- package/LICENSE +202 -0
- package/NOTICE +16 -0
- package/README.md +411 -7
- package/dist/bin.d.ts +20 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +26 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli/corpus-loader.d.ts +198 -0
- package/dist/cli/corpus-loader.d.ts.map +1 -0
- package/dist/cli/corpus-loader.js +351 -0
- package/dist/cli/corpus-loader.js.map +1 -0
- package/dist/cli/corpus-statistics.d.ts +113 -0
- package/dist/cli/corpus-statistics.d.ts.map +1 -0
- package/dist/cli/corpus-statistics.js +119 -0
- package/dist/cli/corpus-statistics.js.map +1 -0
- package/dist/cli/diagnostic-reporter.d.ts +103 -0
- package/dist/cli/diagnostic-reporter.d.ts.map +1 -0
- package/dist/cli/diagnostic-reporter.js +254 -0
- package/dist/cli/diagnostic-reporter.js.map +1 -0
- package/dist/cli/project-ignore.d.ts +113 -0
- package/dist/cli/project-ignore.d.ts.map +1 -0
- package/dist/cli/project-ignore.js +199 -0
- package/dist/cli/project-ignore.js.map +1 -0
- package/dist/cli/safe-text.d.ts +25 -0
- package/dist/cli/safe-text.d.ts.map +1 -0
- package/dist/cli/safe-text.js +34 -0
- package/dist/cli/safe-text.js.map +1 -0
- package/dist/cli/supervisor.d.ts +108 -0
- package/dist/cli/supervisor.d.ts.map +1 -0
- package/dist/cli/supervisor.js +139 -0
- package/dist/cli/supervisor.js.map +1 -0
- package/dist/cli.d.ts +247 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +591 -0
- package/dist/cli.js.map +1 -0
- package/dist/corpus-validator.d.ts +183 -0
- package/dist/corpus-validator.d.ts.map +1 -0
- package/dist/corpus-validator.js +479 -0
- package/dist/corpus-validator.js.map +1 -0
- package/dist/document-identity-rule.d.ts +198 -0
- package/dist/document-identity-rule.d.ts.map +1 -0
- package/dist/document-identity-rule.js +244 -0
- package/dist/document-identity-rule.js.map +1 -0
- package/dist/ecr.d.ts +103 -0
- package/dist/ecr.d.ts.map +1 -0
- package/dist/ecr.js +216 -0
- package/dist/ecr.js.map +1 -0
- package/dist/glob-pattern.d.ts +94 -0
- package/dist/glob-pattern.d.ts.map +1 -0
- package/dist/glob-pattern.js +188 -0
- package/dist/glob-pattern.js.map +1 -0
- package/dist/heading-source-form.d.ts +77 -0
- package/dist/heading-source-form.d.ts.map +1 -0
- package/dist/heading-source-form.js +129 -0
- package/dist/heading-source-form.js.map +1 -0
- package/dist/identifier-grammar.d.ts +212 -0
- package/dist/identifier-grammar.d.ts.map +1 -0
- package/dist/identifier-grammar.js +273 -0
- package/dist/identifier-grammar.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/inline-reference-rule.d.ts +557 -0
- package/dist/inline-reference-rule.d.ts.map +1 -0
- package/dist/inline-reference-rule.js +802 -0
- package/dist/inline-reference-rule.js.map +1 -0
- package/dist/meta-documents.d.ts +91 -0
- package/dist/meta-documents.d.ts.map +1 -0
- package/dist/meta-documents.js +133 -0
- package/dist/meta-documents.js.map +1 -0
- package/dist/per-document-visitor.d.ts +510 -0
- package/dist/per-document-visitor.d.ts.map +1 -0
- package/dist/per-document-visitor.js +1032 -0
- package/dist/per-document-visitor.js.map +1 -0
- package/dist/references-section-rule.d.ts +482 -0
- package/dist/references-section-rule.d.ts.map +1 -0
- package/dist/references-section-rule.js +777 -0
- package/dist/references-section-rule.js.map +1 -0
- package/dist/section-hierarchy-rule.d.ts +299 -0
- package/dist/section-hierarchy-rule.d.ts.map +1 -0
- package/dist/section-hierarchy-rule.js +482 -0
- package/dist/section-hierarchy-rule.js.map +1 -0
- package/dist/source-alignment.d.ts +41 -0
- package/dist/source-alignment.d.ts.map +1 -0
- package/dist/source-alignment.js +166 -0
- package/dist/source-alignment.js.map +1 -0
- package/dist/source-lines.d.ts +69 -0
- package/dist/source-lines.d.ts.map +1 -0
- package/dist/source-lines.js +104 -0
- package/dist/source-lines.js.map +1 -0
- package/dist/spec-version.d.ts +19 -0
- package/dist/spec-version.d.ts.map +1 -0
- package/dist/spec-version.js +19 -0
- package/dist/spec-version.js.map +1 -0
- package/dist/types.d.ts +219 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/examples/docs/0. Orientation/0.0 - System Overview.md +34 -0
- package/examples/docs/0. Orientation/0.0.1 - Glossary.md +21 -0
- package/examples/docs/0. Orientation/0.0.2 - Quality Gates.md +22 -0
- package/examples/docs/3. Ingestion/3.1 - Ingestion - Validation Rules.md +33 -0
- package/examples/docs/4. Payments/4.10 - Settlement.md +22 -0
- package/examples/docs/4. Payments/4.2 - Payment Processing Contract.md +33 -0
- package/examples/docs/8. Orchestration/8.1 - Workflow Orchestration Contract.md +38 -0
- package/examples/docs/8. Orchestration/8.1.3 - Retry Policy.md +17 -0
- package/examples/docs/8. Orchestration/8.10 - Dead Letter Queue.md +20 -0
- package/examples/docs/README.md +7 -0
- package/package.json +65 -7
- package/protocol/navigation-protocol.md +223 -0
- package/spec/v2/1 - ECR - Structural Specification.md +1467 -0
- package/spec/v2/2 - ECR - User Guide.md +845 -0
- package/spec/v2/3 - Design Rationale - The Section Separator.md +243 -0
- package/src/bin.ts +30 -0
- package/src/cli/corpus-loader.ts +482 -0
- package/src/cli/corpus-statistics.ts +196 -0
- package/src/cli/diagnostic-reporter.ts +344 -0
- package/src/cli/project-ignore.ts +238 -0
- package/src/cli/safe-text.ts +39 -0
- package/src/cli/supervisor.ts +204 -0
- package/src/cli.ts +836 -0
- package/src/corpus-validator.ts +642 -0
- package/src/document-identity-rule.ts +422 -0
- package/src/ecr.ts +298 -0
- package/src/glob-pattern.ts +242 -0
- package/src/heading-source-form.ts +173 -0
- package/src/identifier-grammar.ts +380 -0
- package/src/index.ts +78 -0
- package/src/inline-reference-rule.ts +1235 -0
- package/src/meta-documents.ts +159 -0
- package/src/per-document-visitor.ts +1528 -0
- package/src/references-section-rule.ts +1182 -0
- package/src/section-hierarchy-rule.ts +705 -0
- package/src/source-alignment.ts +209 -0
- package/src/source-lines.ts +123 -0
- package/src/spec-version.ts +19 -0
- 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)
|