@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
package/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright 2026 Timi Agama
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Explicit Constraint Referencing (ECR)
|
|
2
|
+
Copyright 2026 Timi Agama
|
|
3
|
+
|
|
4
|
+
This product includes software developed by Timi Agama.
|
|
5
|
+
|
|
6
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
you may not use this file except in compliance with the License.
|
|
8
|
+
You may obtain a copy of the License at
|
|
9
|
+
|
|
10
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
|
|
12
|
+
Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
See the License for the specific language governing permissions and
|
|
16
|
+
limitations under the License.
|
package/README.md
CHANGED
|
@@ -1,11 +1,415 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ECR — Explicit Constraint Referencing
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**A Markdown convention that helps reduce coding agent errors by turning
|
|
4
|
+
cross-references in architecture docs into a graph that coding agents navigate
|
|
5
|
+
with `grep`.**
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
coding agent can navigate with `grep` alone — no index, no server, no plugin.
|
|
7
|
+
Agents gain IDE-like "Go to Definition" and "Find all references" across large
|
|
8
|
+
document corpora, reducing missed constraints and context-window bloat.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
No server. No index. No embeddings. Just numbered headings and a
|
|
11
|
+
`## References` section.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Why coding agents miss constraints
|
|
16
|
+
|
|
17
|
+
Your architecture documentation contains constraints. Some govern other
|
|
18
|
+
constraints. Some impose limits. Some define contracts that other components
|
|
19
|
+
must satisfy.
|
|
20
|
+
|
|
21
|
+
You understand those relationships when you read the docs. A coding agent does
|
|
22
|
+
not — because ordinary Markdown does not encode them in a form an agent can
|
|
23
|
+
deterministically traverse. They live in your head, in the ordering of files,
|
|
24
|
+
in the fact that you happen to remember that the retry policy in one document
|
|
25
|
+
constrains the payment flow in another.
|
|
26
|
+
|
|
27
|
+
Without stable identifiers and explicit references, the agent either pulls
|
|
28
|
+
more documentation into context hoping the relevant constraint is there, or
|
|
29
|
+
proceeds with what it has found and silently violates a constraint written
|
|
30
|
+
somewhere it never looked.
|
|
31
|
+
|
|
32
|
+
The second failure is the expensive one, and it is easy to miss in local
|
|
33
|
+
review. Nothing in the file you are reading points at the thing you missed.
|
|
34
|
+
|
|
35
|
+
## ECR exploits how coding agents already work
|
|
36
|
+
|
|
37
|
+
A coding agent does not read your whole repository into its context window.
|
|
38
|
+
|
|
39
|
+
Its harness gives it tools to inspect the repository on demand: list files,
|
|
40
|
+
search for text or symbols, open the relevant files, read specific sections,
|
|
41
|
+
and run commands.
|
|
42
|
+
|
|
43
|
+
When an agent works on code, it has stable identifiers: function names, type
|
|
44
|
+
names, imports, filenames, symbols. It can search for `retryWithBackoff`, find
|
|
45
|
+
where it is defined and used, read a handful of relevant files, and never load
|
|
46
|
+
the repository into context.
|
|
47
|
+
|
|
48
|
+
That is how an agent can operate on a codebase far larger than its context
|
|
49
|
+
window. The model builds the context it needs as it works.
|
|
50
|
+
|
|
51
|
+
Code already gives the agent stable identifiers to search for. Architecture
|
|
52
|
+
prose usually does not.
|
|
53
|
+
|
|
54
|
+
The "retry policy" is "retry semantics" in one document, "backoff rules" in
|
|
55
|
+
another, "the orchestration contract" in a third. There is nothing exact to
|
|
56
|
+
search for.
|
|
57
|
+
|
|
58
|
+
ECR gives architecture documentation the same kind of searchable structure
|
|
59
|
+
that code already has. Stable identifiers and explicit references turn "what
|
|
60
|
+
constrains this?" into something the agent can actually look up.
|
|
61
|
+
|
|
62
|
+
## What ECR does
|
|
63
|
+
|
|
64
|
+
Your IDE gives you two operations on code: **Go to Definition** and **Find All
|
|
65
|
+
References**. ECR gives your architecture documents the same two operations,
|
|
66
|
+
with `grep` doing the job the IDE's index does, and with nothing to build or
|
|
67
|
+
keep in sync.
|
|
68
|
+
|
|
69
|
+
| IDE operation | ECR equivalent | Answers |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| Go to Definition | forward reference | What does this document rely on or answer to? |
|
|
72
|
+
| Find All References | reverse reference | What elsewhere relies on or refers to this? |
|
|
73
|
+
|
|
74
|
+
> General-purpose links help you navigate from a known source to a known
|
|
75
|
+
> destination. ECR adds something different: stable section identities and
|
|
76
|
+
> explicit relationships that an agent can traverse mechanically in both
|
|
77
|
+
> directions.
|
|
78
|
+
>
|
|
79
|
+
> That means the agent can **retrieve a constraint from the specific section
|
|
80
|
+
> that defines it rather than loading the document that contains it**. And it
|
|
81
|
+
> can search backwards to discover everything elsewhere in the corpus that
|
|
82
|
+
> refers to that constraint.
|
|
83
|
+
|
|
84
|
+
The two directions solve different problems. Forward references surface the
|
|
85
|
+
constraints a document knows it must obey. Reverse references surface
|
|
86
|
+
everything elsewhere in the corpus that relies on it — relationships the
|
|
87
|
+
target has no reason to know exist, and each one a limit on what you can
|
|
88
|
+
safely change.
|
|
89
|
+
|
|
90
|
+
In practice, both operations are one search.
|
|
91
|
+
|
|
92
|
+
For example, one document sets a constraint. The sub-heading containing the constraint has
|
|
93
|
+
a stable identifier `8.1#3.2`:
|
|
94
|
+
|
|
95
|
+
```markdown
|
|
96
|
+
### 8.1#3.2 - Bounds
|
|
97
|
+
|
|
98
|
+
At most five attempts. A stage that exhausts its attempts fails permanently
|
|
99
|
+
and is reported, not re-queued.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Another document, elsewhere in the corpus, depends on that constraint and
|
|
103
|
+
cites it by the same stable identifier:
|
|
104
|
+
|
|
105
|
+
```markdown
|
|
106
|
+
A discrepancy halts settlement for that merchant only. Orchestration-level
|
|
107
|
+
retry does not apply — see 8.1#3.2.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
They need not share a folder, a filename convention, an index or a database.
|
|
111
|
+
The stable identifier is enough to make the section-level link searchable, so
|
|
112
|
+
finding either end from the other is one search:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
grep -r "8.1#3.2" docs/
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
That is the mechanism. The identifier is exact, so the search is exact: it
|
|
119
|
+
returns the section that defines the constraint and every document citing it,
|
|
120
|
+
wherever they sit. Nothing is indexed, nothing is embedded, and there is no
|
|
121
|
+
ranking to be wrong about.
|
|
122
|
+
|
|
123
|
+
Nobody loads a repository into their head to use **Go to Definition**. The
|
|
124
|
+
index does the work and you read only what it returns. ECR works the same way:
|
|
125
|
+
the edges are plain text on disk, so an agent greps and pulls the few sections
|
|
126
|
+
that matter instead of the whole corpus. **The graph lives in your filesystem,
|
|
127
|
+
not in your context window.**
|
|
128
|
+
|
|
129
|
+
## The four rules
|
|
130
|
+
|
|
131
|
+
**1. Every document has a numbered H1.** That number is its DocID — its
|
|
132
|
+
identity, independent of title or path.
|
|
133
|
+
|
|
134
|
+
```markdown
|
|
135
|
+
# 4.2 - Payment Processing Contract
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**2. Every sub-heading number begins with the DocID.**
|
|
139
|
+
|
|
140
|
+
```markdown
|
|
141
|
+
# 4.2 - Payment Processing Contract
|
|
142
|
+
## 4.2#1 - Idempotency
|
|
143
|
+
### 4.2#1.1 - Key Derivation
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
A sub-heading number is a SectionID, and it is self-locating: `4.2#1.1` is
|
|
147
|
+
document `4.2`, section 1, sub-section 1. The `#` marks where the document
|
|
148
|
+
identifier ends and the section path begins, so `4.2#1` and `4.2.1#1` are
|
|
149
|
+
different things and neither can be mistaken for the other.
|
|
150
|
+
|
|
151
|
+
**3. Inline references use `see` or `per`.**
|
|
152
|
+
|
|
153
|
+
```markdown
|
|
154
|
+
Retry semantics are applied per 8.1#3.
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Not "as described in the orchestration doc." A number, so it can be found.
|
|
158
|
+
|
|
159
|
+
**4. Every document declares its external references** in a `## References`
|
|
160
|
+
section, with a typed direction and a reason.
|
|
161
|
+
|
|
162
|
+
```markdown
|
|
163
|
+
## References
|
|
164
|
+
|
|
165
|
+
- 3.1 - Prompt Contracts (authority - defines the guardrail criteria enforced here)
|
|
166
|
+
- 8.1 - Orchestration Contract (constraint - retry semantics applied to evaluation runs)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
That's the whole convention. Four rules, no new syntax, no tooling required to
|
|
170
|
+
adopt it.
|
|
171
|
+
|
|
172
|
+
### Direction semantics
|
|
173
|
+
|
|
174
|
+
| Direction | Meaning (ECR) | Agent action (recommended) |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| `authority` | the cited document governs this one | Read it first. Treat it as the governing source. Flag apparent conflicts. |
|
|
177
|
+
| `constraint` | the cited document restricts this one | Check your change doesn't violate it. |
|
|
178
|
+
| `contract` | the cited document defines interfaces or obligations | Conform exactly. |
|
|
179
|
+
| `dependency` | this document consumes the cited one | Read it to use it correctly. |
|
|
180
|
+
|
|
181
|
+
### Searching precisely
|
|
182
|
+
|
|
183
|
+
A literal search shows the mechanism. Two refinements make it reliable:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# Go to Definition — locate the section a reference names
|
|
187
|
+
grep -rInE "^#+ 8\.1#3([^0-9]|$)" docs/
|
|
188
|
+
|
|
189
|
+
# Find All References — every document citing that section or its sub-sections
|
|
190
|
+
grep -rInE "([Ss]ee|[Pp]er) 8\.1#3([^0-9]|$)" docs/
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The reverse search is where ECR exposes relationships the target section
|
|
194
|
+
cannot know about. On the [example corpus](examples/docs/) it returns five documents across
|
|
195
|
+
four folders, three of which cite `8.1#3.2` specifically: downstream
|
|
196
|
+
documents a change to the retry bounds could break. One of them, settlement, appears nowhere in the orchestration contract.
|
|
197
|
+
|
|
198
|
+
Match `[Ss]ee` and `[Pp]er`, not just lowercase: a reference at the start of a
|
|
199
|
+
sentence is still a reference, and a pattern that misses it under-reports the
|
|
200
|
+
exact thing you are searching for. The `([^0-9]|$)` ending stops `8.1#3` also
|
|
201
|
+
matching `8.1#30`. Matching a whole document rather than its sections needs a
|
|
202
|
+
stronger guard, because `.` and `#` are not word boundaries — the supplied
|
|
203
|
+
[coding agent navigation protocol](protocol/navigation-protocol.md) carries the tested pattern.
|
|
204
|
+
|
|
205
|
+
## Why `grep` is enough
|
|
206
|
+
|
|
207
|
+
What ECR produces is a directed graph: documents and sections are nodes,
|
|
208
|
+
cross-references are edges, and document-level edges carry relationship types.
|
|
209
|
+
|
|
210
|
+
The useful property of a graph is that you can answer questions about a node
|
|
211
|
+
by following its edges, without reading every other node. That's the property
|
|
212
|
+
being borrowed. `grep` may scan every file, but the agent only reads what the
|
|
213
|
+
edges lead it to. An agent asking "what governs this component?" doesn't read
|
|
214
|
+
your entire documentation corpus — it resolves an identifier and follows
|
|
215
|
+
edges, and every edge it follows is one it can justify rather than infer.
|
|
216
|
+
|
|
217
|
+
It matters that the identifiers are stable and the edges are plain text. Exact
|
|
218
|
+
identifiers make retrieval deterministic: against the same corpus, the same
|
|
219
|
+
query returns the same sections every time, with no ranking, no similarity
|
|
220
|
+
threshold, and no chance of a plausible-looking near-miss. Plain text on disk
|
|
221
|
+
means the traversal tool is `grep`, which every coding agent already has.
|
|
222
|
+
|
|
223
|
+
## Evidence from one project
|
|
224
|
+
|
|
225
|
+
Here is my experience with it: **one project, my own assessment, not a benchmark**.
|
|
226
|
+
|
|
227
|
+
I converted a documentation corpus to ECR: **47 Markdown files**, 40 carrying
|
|
228
|
+
`## References`, **1,672 numbered headings**, and **575 inter-document references** —
|
|
229
|
+
413 References entries plus 162 inline `see`/`per` citations, 95 of them
|
|
230
|
+
section-precise.
|
|
231
|
+
|
|
232
|
+
Then I pointed a coding agent at the [navigation protocol](protocol/navigation-protocol.md), told it to use ECR,
|
|
233
|
+
and started building. It produced around **19,000 lines of TypeScript across
|
|
234
|
+
124 source files** with **34 test files**. Retrieval was `grep`. There was no
|
|
235
|
+
server, no index, no embedding model and no MCP tool in the loop — the agent
|
|
236
|
+
read the protocol, walked the references, and pulled the sections it needed.
|
|
237
|
+
|
|
238
|
+
In my judgement the result contained unusually few errors for a build of that
|
|
239
|
+
complexity. That's a subjective claim about an unpublished, commercially
|
|
240
|
+
confidential corpus, and you should weight it accordingly. The mechanism
|
|
241
|
+
underneath it, though, is not subjective — you can check that on your own
|
|
242
|
+
documentation in about two minutes.
|
|
243
|
+
|
|
244
|
+
## Getting started
|
|
245
|
+
|
|
246
|
+
### Commands
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
npx @timiagama/ecr init ./ecr # install ECR documentation
|
|
250
|
+
npx @timiagama/ecr lint ./docs # check structural compliance
|
|
251
|
+
npx @timiagama/ecr stats ./docs # measure the structure you already have
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Try it on the example corpus
|
|
255
|
+
|
|
256
|
+
A small [example corpus](examples/docs/) ships with the package, so you can try the tool before
|
|
257
|
+
pointing it at your own documents:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
npx @timiagama/ecr stats --example
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
documents 9
|
|
265
|
+
with a References section 9
|
|
266
|
+
sections 34
|
|
267
|
+
|
|
268
|
+
unique DocIDs 9
|
|
269
|
+
unique SectionIDs 34
|
|
270
|
+
|
|
271
|
+
References entries 21
|
|
272
|
+
authority 5
|
|
273
|
+
constraint 2
|
|
274
|
+
contract 2
|
|
275
|
+
dependency 12
|
|
276
|
+
|
|
277
|
+
inline see/per references 17
|
|
278
|
+
section-precise 10
|
|
279
|
+
|
|
280
|
+
total edges 38
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### What the commands do
|
|
284
|
+
|
|
285
|
+
`init` copies the ECR documentation into the directory you choose. Open its
|
|
286
|
+
README.md for the user guide, specification, navigation protocol and examples.
|
|
287
|
+
The folder structure matches this repository, so the links work locally.
|
|
288
|
+
Keep this documentation outside your own corpus—for example, ECR documentation
|
|
289
|
+
in ./ecr and your documents in ./docs. It also adds that directory to
|
|
290
|
+
`.ecrignore`, so linting your whole project with `ecr lint .` skips it.
|
|
291
|
+
|
|
292
|
+
`lint` exits `0` when the corpus is clean, `1` when it contains errors, and
|
|
293
|
+
`2` when the command could not run, so it drops straight into CI.
|
|
294
|
+
`--format json` gives you the same diagnostics as data.
|
|
295
|
+
|
|
296
|
+
READMEs, `CLAUDE.md`, contributing guides and changelogs are excluded
|
|
297
|
+
automatically. Use `--ignore` for anything project-specific:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
npx @timiagama/ecr lint ./docs --ignore '**/*-CHECKLIST.md' --ignore 'LAST-REVIEW.md'
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
To keep patterns out of every command, put them in a `.ecrignore` file in your
|
|
304
|
+
project root, the directory you run `ecr` from, one per line, relative to that
|
|
305
|
+
directory. Blank lines and lines starting with `#` are ignored. Folders named
|
|
306
|
+
`node_modules` are always skipped.
|
|
307
|
+
|
|
308
|
+
A pattern ending in `/**` excludes a whole directory, which is then not read at all.
|
|
309
|
+
|
|
310
|
+
Symbolic links and junctions inside the corpus are not followed, because `rg`
|
|
311
|
+
and `grep -r` do not follow them either: a document your agent's searches cannot
|
|
312
|
+
reach is left out rather than validated. Each link that could lead to a document
|
|
313
|
+
is listed as not followed; one covered by `--ignore` is listed as excluded
|
|
314
|
+
instead. The directory you name may itself be a link.
|
|
315
|
+
|
|
316
|
+
There is no `backlinks` command, and there never will be. Navigation is what
|
|
317
|
+
`grep` is for; a navigation command here would make the tool a dependency of
|
|
318
|
+
the thing ECR exists to prove unnecessary.
|
|
319
|
+
|
|
320
|
+
You can adopt ECR entirely by hand. The tooling is optional.
|
|
321
|
+
|
|
322
|
+
## Adopting ECR
|
|
323
|
+
|
|
324
|
+
### Migrating existing documentation
|
|
325
|
+
|
|
326
|
+
You do not need to convert everything at once. ECR degrades gracefully: a
|
|
327
|
+
partially-converted corpus is more navigable than an unconverted one, and
|
|
328
|
+
documents without DocIDs are simply outside the graph.
|
|
329
|
+
|
|
330
|
+
A workable order:
|
|
331
|
+
|
|
332
|
+
1. Assign DocIDs to your architectural documents — the ones that constrain
|
|
333
|
+
other documents. Leave READMEs and guides alone.
|
|
334
|
+
2. Renumber headings to extend the DocID.
|
|
335
|
+
3. Add `## References` to each document, typing the direction of each edge.
|
|
336
|
+
4. Convert natural-language references ("as described in the storage doc")
|
|
337
|
+
into `see` / `per` citations with numbers.
|
|
338
|
+
5. Run `ecr lint` and resolve what it reports.
|
|
339
|
+
|
|
340
|
+
Step 2 changes heading numbers to SectionIDs (`## 8.1#3 - Retry Semantics`),
|
|
341
|
+
and step 4 needs corpus-wide knowledge: resolving
|
|
342
|
+
`as described in the storage doc` to `per 7.1#2` means knowing what documents
|
|
343
|
+
exist and what they cover.
|
|
344
|
+
|
|
345
|
+
#### Using a coding agent to migrate
|
|
346
|
+
|
|
347
|
+
Migration always requires knowledge of the corpus, which makes it a good fit
|
|
348
|
+
for a coding agent. Much of the work is mechanical once the DocID set is known,
|
|
349
|
+
but it is too corpus-aware to script blindly.
|
|
350
|
+
|
|
351
|
+
My advice, from doing this on a real corpus:
|
|
352
|
+
|
|
353
|
+
- **Start with two fresh sessions from the same model family.** Use one session
|
|
354
|
+
to implement and a separate session to review. In my experience, a fresh
|
|
355
|
+
session reviews what is on the page rather than what the first one intended.
|
|
356
|
+
- **Finish with a review by a model from a different family.** In my
|
|
357
|
+
experience, a second model family catches assumptions the first one can
|
|
358
|
+
repeat.
|
|
359
|
+
|
|
360
|
+
Run `ecr lint` after each pass. The linter catches structural breakage; the
|
|
361
|
+
reviews catch the judgement calls the linter cannot see, such as whether an
|
|
362
|
+
edge is really an `authority` or just a `dependency`.
|
|
363
|
+
|
|
364
|
+
### Authoring documents with AI
|
|
365
|
+
|
|
366
|
+
You do not have to maintain ECR structure by hand. Give the [user guide](<spec/v2/2 - ECR - User Guide.md>) and [specification](<spec/v2/1 - ECR - Structural Specification.md>) to a coding agent, desktop harness or general-purpose model alongside the documents it is working on, and it can help create or amend ECR-compliant Markdown.
|
|
367
|
+
|
|
368
|
+
The linter checks structural compliance. Human review is still needed for the judgement calls ECR cannot make — for example, whether a relationship is really an `authority`, `constraint`, `contract` or `dependency`.
|
|
369
|
+
|
|
370
|
+
## What ECR is not
|
|
371
|
+
|
|
372
|
+
- It does not interpret constraint semantics. It exposes structure; you decide
|
|
373
|
+
what the structure means.
|
|
374
|
+
- It does not evaluate whether a constraint is satisfied.
|
|
375
|
+
- It does not enforce Markdown style.
|
|
376
|
+
- It is not a search engine. Retrieval is exact-match on identifiers, which is
|
|
377
|
+
the point — there is no ranking to be wrong about.
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
What distinguishes ECR isn't that its references form a graph. Any linked corpus
|
|
381
|
+
does. ECR makes the structure **stable**, **section-addressable**, **explicit** and
|
|
382
|
+
**mechanically reversible**, with **typed document-level relationships**.
|
|
383
|
+
|
|
384
|
+
## Beyond architecture docs
|
|
385
|
+
|
|
386
|
+
ECR can be useful anywhere an agent needs to navigate a document corpus by
|
|
387
|
+
exact reference rather than similarity. For example, I used the same approach
|
|
388
|
+
in an oil-and-gas engineering PoC where every answer the AI agent provided had
|
|
389
|
+
to cite its evidence. I converted the engineering documents to ECR-compliant
|
|
390
|
+
Markdown so an agent could locate the exact supporting section on demand. The
|
|
391
|
+
same pattern may be useful for standards, policies, legal documents,
|
|
392
|
+
procedures, or other documents where traceable references matter.
|
|
393
|
+
|
|
394
|
+
## Documentation
|
|
395
|
+
|
|
396
|
+
This repository contains the ECR 2.0.0 specification and `@timiagama/ecr`, a
|
|
397
|
+
linter that implements it.
|
|
398
|
+
|
|
399
|
+
- [Specification](<spec/v2/1 - ECR - Structural Specification.md>) — the formal
|
|
400
|
+
grammar and rules
|
|
401
|
+
- [User guide](<spec/v2/2 - ECR - User Guide.md>) — writing ECR-compliant
|
|
402
|
+
documents
|
|
403
|
+
- [Design rationale](<spec/v2/3 - Design Rationale - The Section Separator.md>)
|
|
404
|
+
— why identifiers carry a `#`
|
|
405
|
+
- [Navigation protocol](protocol/navigation-protocol.md) — the instructions
|
|
406
|
+
you give your coding agent
|
|
407
|
+
- [Example corpus](examples/docs/) — a small example corpus of nine documents
|
|
408
|
+
across four folders, to try the tool on and to see ECR in use;
|
|
409
|
+
`npx @timiagama/ecr lint --example` lints it
|
|
410
|
+
|
|
411
|
+
## Licence
|
|
412
|
+
|
|
413
|
+
Apache License 2.0. See [LICENSE](LICENSE).
|
|
414
|
+
|
|
415
|
+
Apache-2.0 includes an explicit patent grant that MIT does not provide.
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ECR Executable Entry Point
|
|
4
|
+
*
|
|
5
|
+
* This file runs the CLI unconditionally and does nothing else. It must not
|
|
6
|
+
* guard itself with a "was I invoked directly?" check that compares
|
|
7
|
+
* `process.argv[1]` with this module's path: package managers install the
|
|
8
|
+
* binary as a symlink (`node_modules/.bin/ecr`), Node resolves the module to
|
|
9
|
+
* its real path, and the two never match, so a guarded entry point silently
|
|
10
|
+
* exits 0 without running. Keeping the commands in `cli.ts` and the side
|
|
11
|
+
* effect here removes the need for any such check.
|
|
12
|
+
*
|
|
13
|
+
* It is also where supervision is asked for, because this file knows the one
|
|
14
|
+
* thing a supervised run needs: the script a child process would have to run,
|
|
15
|
+
* which is this file itself, at its real path rather than through whatever
|
|
16
|
+
* symlink invoked it. A host embedding the library instead of the command
|
|
17
|
+
* gets no supervision, and bounds its own work.
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=bin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG"}
|