xdrs-core 0.17.1 → 0.18.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/.xdrs/_core/adrs/principles/001-xdrs-core.md +3 -2
- package/.xdrs/_core/adrs/principles/002-xdr-standards.md +2 -2
- package/.xdrs/_core/adrs/principles/003-skill-standards.md +1 -1
- package/.xdrs/_core/adrs/principles/004-article-standards.md +1 -1
- package/.xdrs/_core/adrs/principles/006-research-standards.md +1 -1
- package/.xdrs/_core/adrs/principles/007-plan-standards.md +1 -1
- package/.xdrs/_core/adrs/principles/articles/001-xdrs-overview.md +22 -22
- package/.xdrs/_core/adrs/principles/skills/001-lint/SKILL.md +3 -3
- package/.xdrs/_core/adrs/principles/skills/002-write-xdr/SKILL.md +5 -4
- package/.xdrs/_core/adrs/principles/skills/003-write-skill/SKILL.md +5 -4
- package/.xdrs/_core/adrs/principles/skills/004-write-article/SKILL.md +6 -5
- package/.xdrs/_core/adrs/principles/skills/005-write-research/SKILL.md +5 -4
- package/.xdrs/_core/adrs/principles/skills/006-write-plan/SKILL.md +5 -4
- package/.xdrs/_core/bdrs/principles/001-xdr-decisions-and-skills-usage.md +3 -3
- package/lib/lint.js +22 -7
- package/lib/lint.test.js +105 -1
- package/package.json +1 -1
|
@@ -107,6 +107,7 @@ Collectively, these are referred to as XDRs.
|
|
|
107
107
|
- `governance`: Engineering governance, risk controls, and compliance mechanics.
|
|
108
108
|
- Examples: dependency governance, approval policies, mandatory quality checks.
|
|
109
109
|
- Never use emojis
|
|
110
|
+
- **Links:** Links that reference a parent folder MUST use absolute paths from the repository root with a leading `/` (e.g., `/.xdrs/_core/adrs/principles/001-xdrs-core.md`). Sibling files and child folder references SHOULD use relative paths (e.g., `002-other-doc.md`, `assets/image.png`, `subdir/file.md`). Never use relative paths that traverse up the directory tree (e.g., `../../assets/test.png`, `../other.md`); they break when files are moved and are harder to read.
|
|
110
111
|
- **Indexes**
|
|
111
112
|
- Keep a canonical index with all XDRs of a certain type+scope in `.xdrs/[scope]/[type]/index.md`
|
|
112
113
|
- Canonical index requirements:
|
|
@@ -144,8 +145,8 @@ subject/
|
|
|
144
145
|
## References
|
|
145
146
|
|
|
146
147
|
- [_core-adr-002 - XDR standards](002-xdr-standards.md) - Standards for writing individual XDR decision documents
|
|
147
|
-
- [001-lint skill](skills/001-lint/SKILL.md) - Skill for reviewing code changes against XDRs
|
|
148
|
-
- [002-write-xdr skill](skills/002-write-xdr/SKILL.md) - Skill for creating a new XDR following this standard
|
|
148
|
+
- [001-lint skill](/.xdrs/_core/adrs/principles/skills/001-lint/SKILL.md) - Skill for reviewing code changes against XDRs
|
|
149
|
+
- [002-write-xdr skill](/.xdrs/_core/adrs/principles/skills/002-write-xdr/SKILL.md) - Skill for creating a new XDR following this standard
|
|
149
150
|
- [_core-adr-003 - Skill standards](003-skill-standards.md)
|
|
150
151
|
- [_core-adr-004 - Article standards](004-article-standards.md)
|
|
151
152
|
- [_core-adr-006 - Research standards](006-research-standards.md)
|
|
@@ -148,8 +148,8 @@ Question: In the end, state explicitly the question that needs to be answered. E
|
|
|
148
148
|
## References
|
|
149
149
|
|
|
150
150
|
- [_core-adr-001 - XDRs core](001-xdrs-core.md) - Framework elements: types, scopes, subjects, folder structure
|
|
151
|
-
- [001-lint skill](skills/001-lint/SKILL.md) - Skill for reviewing code changes against XDRs
|
|
152
|
-
- [002-write-xdr skill](skills/002-write-xdr/SKILL.md) - Skill for creating a new XDR following this standard
|
|
151
|
+
- [001-lint skill](/.xdrs/_core/adrs/principles/skills/001-lint/SKILL.md) - Skill for reviewing code changes against XDRs
|
|
152
|
+
- [002-write-xdr skill](/.xdrs/_core/adrs/principles/skills/002-write-xdr/SKILL.md) - Skill for creating a new XDR following this standard
|
|
153
153
|
- [_core-adr-003 - Skill standards](003-skill-standards.md)
|
|
154
154
|
- [_core-adr-004 - Article standards](004-article-standards.md)
|
|
155
155
|
- [_core-adr-006 - Research standards](006-research-standards.md)
|
|
@@ -116,7 +116,7 @@ Rules:
|
|
|
116
116
|
- For simple structure, flow, layout, or relationship indications, `SKILL.md` SHOULD prefer plain Markdown, tables, or ASCII art instead of external assets.
|
|
117
117
|
- Images and other local resource files referenced from `SKILL.md` SHOULD be used only when they are materially necessary and SHOULD live in `assets/` inside the same skill package.
|
|
118
118
|
- Keep `SKILL.md` under 6500 words. Move lengthy reference material to `references/`.
|
|
119
|
-
-
|
|
119
|
+
- Links that reference a parent folder MUST use absolute paths from the repository root with a leading `/`. Sibling files and child folder references SHOULD use relative paths (e.g., `assets/image.png`, `subdir/file.md`). Never use relative paths that traverse up the directory tree (e.g., `../other.md`).
|
|
120
120
|
- Always use lowercase file names.
|
|
121
121
|
- Never use emojis in skill content.
|
|
122
122
|
|
|
@@ -89,4 +89,4 @@ when referencing an information from those documents.]
|
|
|
89
89
|
- [_core-adr-001 - XDRs core](001-xdrs-core.md)
|
|
90
90
|
- [_core-adr-003 - Skill standards](003-skill-standards.md)
|
|
91
91
|
- [_core-adr-006 - Research standards](006-research-standards.md)
|
|
92
|
-
- [004-write-article skill](skills/004-write-article/SKILL.md) - Step-by-step instructions for creating a new article
|
|
92
|
+
- [004-write-article skill](/.xdrs/_core/adrs/principles/skills/004-write-article/SKILL.md) - Step-by-step instructions for creating a new article
|
|
@@ -133,4 +133,4 @@ Prefer tables, bullets, or ASCII art for simple comparisons. Use external figure
|
|
|
133
133
|
- [_core-adr-001 - XDRs core](001-xdrs-core.md)
|
|
134
134
|
- [_core-adr-003 - Skill standards](003-skill-standards.md)
|
|
135
135
|
- [_core-adr-004 - Article standards](004-article-standards.md)
|
|
136
|
-
- [005-write-research skill](skills/005-write-research/SKILL.md) - Step-by-step instructions for creating a research document
|
|
136
|
+
- [005-write-research skill](/.xdrs/_core/adrs/principles/skills/005-write-research/SKILL.md) - Step-by-step instructions for creating a research document
|
|
@@ -135,4 +135,4 @@ Due date: YYYY-MM-DD
|
|
|
135
135
|
- [_core-adr-001 - XDRs core](001-xdrs-core.md) - Framework elements: types, scopes, subjects, folder structure
|
|
136
136
|
- [_core-adr-004 - Article standards](004-article-standards.md) - Companion artifact type for synthetic views
|
|
137
137
|
- [_core-adr-006 - Research standards](006-research-standards.md) - Companion artifact type for exploratory evidence
|
|
138
|
-
- [006-write-plan skill](skills/006-write-plan/SKILL.md) - Step-by-step instructions for creating a new plan
|
|
138
|
+
- [006-write-plan skill](/.xdrs/_core/adrs/principles/skills/006-write-plan/SKILL.md) - Step-by-step instructions for creating a new plan
|
|
@@ -17,23 +17,23 @@ same decision system.
|
|
|
17
17
|
record the adopted direction. They are the central policy artifact of the framework for the
|
|
18
18
|
scope and topic they cover. Three decision record types exist: **ADR** for architectural and
|
|
19
19
|
technical decisions, **BDR** for business and operational decisions, and **EDR** for engineering
|
|
20
|
-
implementation decisions. See [_core-adr-001](
|
|
20
|
+
implementation decisions. See [_core-adr-001](/.xdrs/_core/adrs/principles/001-xdrs-core.md).
|
|
21
21
|
- **Research** captures exploration before or around a decision: constraints, findings, options,
|
|
22
22
|
pros, and cons. Research supports elaboration, discussion, and updates,
|
|
23
23
|
but it is not the final rule. A single Research document may inform multiple downstream ADRs,
|
|
24
24
|
BDRs, or EDRs. If Research and an XDR disagree, the XDR wins. See
|
|
25
|
-
[_core-adr-006](
|
|
25
|
+
[_core-adr-006](/.xdrs/_core/adrs/principles/006-research-standards.md).
|
|
26
26
|
- **Skills** describe how to execute work under the constraints of the decisions. They add the
|
|
27
27
|
procedural detail that XDRs intentionally avoid. A Skill may be used by a human, an AI agent, or
|
|
28
28
|
both. Skills are task-based, should end in a verifiable outcome, and are only mandatory when a
|
|
29
|
-
policy such as an XDR makes them mandatory. See [_core-adr-003](
|
|
29
|
+
policy such as an XDR makes them mandatory. See [_core-adr-003](/.xdrs/_core/adrs/principles/003-skill-standards.md).
|
|
30
30
|
- **Articles** are synthetic views, like this one. They explain a topic across multiple XDRs,
|
|
31
31
|
Research documents, and Skills, helping readers understand the system without making new
|
|
32
|
-
decisions. See [_core-adr-004](
|
|
32
|
+
decisions. See [_core-adr-004](/.xdrs/_core/adrs/principles/004-article-standards.md).
|
|
33
33
|
- **Plans** describe a problem, a proposed solution, and the approach and activities needed to
|
|
34
34
|
solve it. They have a clear start and end and a well-defined scope. Plans are ephemeral: they
|
|
35
35
|
must be deleted after full implementation, with lasting outputs captured as Decisions, Skills,
|
|
36
|
-
Articles, or other artifacts. See [_core-adr-007](
|
|
36
|
+
Articles, or other artifacts. See [_core-adr-007](/.xdrs/_core/adrs/principles/007-plan-standards.md).
|
|
37
37
|
- **Indexes and folder structure** are the discovery layer. They do not make decisions by
|
|
38
38
|
themselves, but they determine how people and agents find the right artifacts, how scopes
|
|
39
39
|
override one another, and how a large set of decisions remains navigable.
|
|
@@ -139,7 +139,7 @@ guidance, and the explanatory overview close together without collapsing them in
|
|
|
139
139
|
|
|
140
140
|
### Guidelines
|
|
141
141
|
|
|
142
|
-
Follow [_core-adr-001](
|
|
142
|
+
Follow [_core-adr-001](/.xdrs/_core/adrs/principles/001-xdrs-core.md) and [_core-adr-002](/.xdrs/_core/adrs/principles/002-xdr-standards.md) strictly. Key rules:
|
|
143
143
|
|
|
144
144
|
- Use **mandatory language** (`must`, `never`, `required`) for non-negotiable rules and
|
|
145
145
|
**advisory language** (`should`, `recommended`) for guidance.
|
|
@@ -157,13 +157,13 @@ Follow [_core-adr-001](../001-xdrs-core.md) and [_core-adr-002](../002-xdr-stand
|
|
|
157
157
|
- **New subject** — create the subject folder under the existing scope+type path. Add an
|
|
158
158
|
allowed subject or use `principles` if none fits (propose a new subject via a `_core` ADR).
|
|
159
159
|
- **New research** — add a `researches/[number]-[short-title].md` inside the relevant subject
|
|
160
|
-
folder, following [_core-adr-006](
|
|
160
|
+
folder, following [_core-adr-006](/.xdrs/_core/adrs/principles/006-research-standards.md).
|
|
161
161
|
- **New skill** — add a `skills/[number]-[skill-name]/SKILL.md` inside the relevant subject
|
|
162
|
-
folder, following [_core-adr-003](
|
|
162
|
+
folder, following [_core-adr-003](/.xdrs/_core/adrs/principles/003-skill-standards.md).
|
|
163
163
|
- **New article** — add an `articles/[number]-[short-title].md` inside the relevant subject
|
|
164
|
-
folder, following [_core-adr-004](
|
|
164
|
+
folder, following [_core-adr-004](/.xdrs/_core/adrs/principles/004-article-standards.md).
|
|
165
165
|
- **New plan** — add a `plans/[number]-[short-title].md` inside the relevant subject
|
|
166
|
-
folder, following [_core-adr-007](
|
|
166
|
+
folder, following [_core-adr-007](/.xdrs/_core/adrs/principles/007-plan-standards.md).
|
|
167
167
|
|
|
168
168
|
### Using XDRs in your own project
|
|
169
169
|
|
|
@@ -181,15 +181,15 @@ Follow [_core-adr-001](../001-xdrs-core.md) and [_core-adr-002](../002-xdr-stand
|
|
|
181
181
|
|
|
182
182
|
## References
|
|
183
183
|
|
|
184
|
-
- [_core-adr-001](
|
|
185
|
-
- [_core-adr-002](
|
|
186
|
-
- [_core-adr-003](
|
|
187
|
-
- [_core-adr-004](
|
|
188
|
-
- [_core-adr-006](
|
|
189
|
-
- [_core-adr-007](
|
|
190
|
-
- [001-lint skill](
|
|
191
|
-
- [002-write-xdr skill](
|
|
192
|
-
- [003-write-skill skill](
|
|
193
|
-
- [004-write-article skill](
|
|
194
|
-
- [005-write-research skill](
|
|
195
|
-
- [_core-adr-005](
|
|
184
|
+
- [_core-adr-001](/.xdrs/_core/adrs/principles/001-xdrs-core.md) - XDR elements: types, scopes, subjects, folder structure
|
|
185
|
+
- [_core-adr-002](/.xdrs/_core/adrs/principles/002-xdr-standards.md) - XDR document standards and mandatory template
|
|
186
|
+
- [_core-adr-003](/.xdrs/_core/adrs/principles/003-skill-standards.md) - Skill standards and co-location rules
|
|
187
|
+
- [_core-adr-004](/.xdrs/_core/adrs/principles/004-article-standards.md) - Article standards
|
|
188
|
+
- [_core-adr-006](/.xdrs/_core/adrs/principles/006-research-standards.md) - Research standards
|
|
189
|
+
- [_core-adr-007](/.xdrs/_core/adrs/principles/007-plan-standards.md) - Plan standards
|
|
190
|
+
- [001-lint skill](/.xdrs/_core/adrs/principles/skills/001-lint/SKILL.md) - Linting code against XDRs
|
|
191
|
+
- [002-write-xdr skill](/.xdrs/_core/adrs/principles/skills/002-write-xdr/SKILL.md) - Writing a new XDR
|
|
192
|
+
- [003-write-skill skill](/.xdrs/_core/adrs/principles/skills/003-write-skill/SKILL.md) - Writing a new skill
|
|
193
|
+
- [004-write-article skill](/.xdrs/_core/adrs/principles/skills/004-write-article/SKILL.md) - Writing a new article
|
|
194
|
+
- [005-write-research skill](/.xdrs/_core/adrs/principles/skills/005-write-research/SKILL.md) - Writing a new research document
|
|
195
|
+
- [_core-adr-005](/.xdrs/_core/adrs/principles/005-semantic-versioning-for-xdr-packages.md) - Semantic versioning rules for XDR packages
|
|
@@ -88,7 +88,7 @@ Scope: [scope identifier]
|
|
|
88
88
|
|
|
89
89
|
## References
|
|
90
90
|
|
|
91
|
-
- [_core-adr-001 - XDRs core](
|
|
92
|
-
- [_core-adr-002 - XDR standards](
|
|
93
|
-
- [_core-adr-003 - Skill standards](
|
|
91
|
+
- [_core-adr-001 - XDRs core](/.xdrs/_core/adrs/principles/001-xdrs-core.md)
|
|
92
|
+
- [_core-adr-002 - XDR standards](/.xdrs/_core/adrs/principles/002-xdr-standards.md)
|
|
93
|
+
- [_core-adr-003 - Skill standards](/.xdrs/_core/adrs/principles/003-skill-standards.md)
|
|
94
94
|
|
|
@@ -141,7 +141,8 @@ Mandatory rules to apply while drafting:
|
|
|
141
141
|
- Make clear when the decision applies and any important exception boundaries.
|
|
142
142
|
- Keep exploratory option analysis in a related Research document when it would distract from the final decision text.
|
|
143
143
|
- Prefer plain Markdown, tables, or ASCII art for simple structure, flow, layout, or relationship indications.
|
|
144
|
-
- If the XDR genuinely needs local images or supporting files, store them in `.xdrs/[scope]/[type]/[subject]/assets/` and link
|
|
144
|
+
- If the XDR genuinely needs local images or supporting files, store them in `.xdrs/[scope]/[type]/[subject]/assets/` and link them using a same-folder relative path (e.g., `assets/image.png`).
|
|
145
|
+
- Links that reference a parent folder MUST use absolute paths from the repository root with a leading `/` (e.g., `/.xdrs/_core/adrs/principles/001-xdrs-core.md`). Sibling files and child folder references SHOULD use relative paths (e.g., `002-other-doc.md`, `assets/image.png`, `subdir/file.md`). Never use relative paths that traverse up the directory tree (e.g., `../../assets/test.png`, `../other.md`).
|
|
145
146
|
- No emojis. Lowercase filenames.
|
|
146
147
|
- Target under 1300 words total; under 2600 words for complex decisions.
|
|
147
148
|
|
|
@@ -187,6 +188,6 @@ If any check fails, revise and re-run this phase before proceeding.
|
|
|
187
188
|
|
|
188
189
|
## References
|
|
189
190
|
|
|
190
|
-
- [_core-adr-001 - XDRs core](
|
|
191
|
-
- [_core-adr-002 - XDR standards](
|
|
192
|
-
- [_core-adr-003 - Skill standards](
|
|
191
|
+
- [_core-adr-001 - XDRs core](/.xdrs/_core/adrs/principles/001-xdrs-core.md)
|
|
192
|
+
- [_core-adr-002 - XDR standards](/.xdrs/_core/adrs/principles/002-xdr-standards.md)
|
|
193
|
+
- [_core-adr-003 - Skill standards](/.xdrs/_core/adrs/principles/003-skill-standards.md)
|
|
@@ -98,7 +98,8 @@ Rules:
|
|
|
98
98
|
- Do not present the skill itself as policy; mandatory behavior must come from referenced XDRs or other policy artifacts.
|
|
99
99
|
- When the skill depends on XDRs, make the activation logic and instructions consistent with the XDR metadata so the skill does not operationalize inactive or out-of-scope decisions.
|
|
100
100
|
- Prefer plain Markdown, tables, or ASCII art for simple structure, flow, layout, or relationship indications.
|
|
101
|
-
- If `SKILL.md` genuinely needs local images or supporting files, store them in `.xdrs/[scope]/[type]/[subject]/skills/[number]-[skill-name]/assets/` and link
|
|
101
|
+
- If `SKILL.md` genuinely needs local images or supporting files, store them in `.xdrs/[scope]/[type]/[subject]/skills/[number]-[skill-name]/assets/` and link them using a same-folder relative path (e.g., `assets/image.png`).
|
|
102
|
+
- Links that reference a parent folder MUST use absolute paths from the repository root with a leading `/` (e.g., `/.xdrs/_core/adrs/principles/001-xdrs-core.md`). Sibling files and child folder references SHOULD use relative paths (e.g., `002-other-doc.md`, `assets/image.png`, `subdir/file.md`). Never use relative paths that traverse up the directory tree (e.g., `../../assets/test.png`, `../other.md`).
|
|
102
103
|
- No emojis. Lowercase filenames. Target under 6500 words.
|
|
103
104
|
|
|
104
105
|
### Phase 5: Review the Draft
|
|
@@ -154,6 +155,6 @@ If any check fails, revise before continuing.
|
|
|
154
155
|
|
|
155
156
|
## References
|
|
156
157
|
|
|
157
|
-
- [_core-adr-003 - Skill standards](
|
|
158
|
-
- [_core-adr-001 - XDRs core](
|
|
159
|
-
- [002-write-xdr skill](
|
|
158
|
+
- [_core-adr-003 - Skill standards](/.xdrs/_core/adrs/principles/003-skill-standards.md)
|
|
159
|
+
- [_core-adr-001 - XDRs core](/.xdrs/_core/adrs/principles/001-xdrs-core.md)
|
|
160
|
+
- [002-write-xdr skill](/.github/skills/002-write-xdr/SKILL.md)
|
|
@@ -84,7 +84,7 @@ when referencing information from those documents. Keep under 1950 words total.]
|
|
|
84
84
|
|
|
85
85
|
## References
|
|
86
86
|
|
|
87
|
-
- [XDR id or Skill name](
|
|
87
|
+
- [XDR id or Skill name](/.xdrs/[scope]/[type]/[subject]/[number]-[short-title].md) - Brief description of relevance
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
Rules to apply while drafting:
|
|
@@ -94,7 +94,8 @@ Rules to apply while drafting:
|
|
|
94
94
|
- If the article advises readers what to do, clearly separate active/applicable XDRs from background, historical, or out-of-scope ones.
|
|
95
95
|
- Never reproduce decision text verbatim; summarize and link.
|
|
96
96
|
- Prefer plain Markdown, tables, or ASCII art for simple structure, flow, layout, or relationship indications.
|
|
97
|
-
- If the article genuinely needs local images or supporting files, store them in `.xdrs/[scope]/[type]/[subject]/articles/assets/` and link
|
|
97
|
+
- If the article genuinely needs local images or supporting files, store them in `.xdrs/[scope]/[type]/[subject]/articles/assets/` and link them using a same-folder relative path (e.g., `assets/image.png`).
|
|
98
|
+
- Links that reference a parent folder MUST use absolute paths from the repository root with a leading `/` (e.g., `/.xdrs/_core/adrs/principles/001-xdrs-core.md`). Sibling files and child folder references SHOULD use relative paths (e.g., `002-other-doc.md`, `assets/image.png`, `subdir/file.md`). Never use relative paths that traverse up the directory tree (e.g., `../../assets/test.png`, `../other.md`).
|
|
98
99
|
- Keep the article under 1950 words; move detailed content to XDRs or Skills.
|
|
99
100
|
- Use lowercase file names. Never use emojis.
|
|
100
101
|
- If a conflict exists between the article and a Decision Record, note it and defer to the XDR.
|
|
@@ -139,6 +140,6 @@ Rules to apply while drafting:
|
|
|
139
140
|
|
|
140
141
|
## References
|
|
141
142
|
|
|
142
|
-
- [_core-adr-004 - Article standards](
|
|
143
|
-
- [_core-adr-006 - Research standards](
|
|
144
|
-
- [_core-adr-001 - XDRs core](
|
|
143
|
+
- [_core-adr-004 - Article standards](/.xdrs/_core/adrs/principles/004-article-standards.md)
|
|
144
|
+
- [_core-adr-006 - Research standards](/.xdrs/_core/adrs/principles/006-research-standards.md)
|
|
145
|
+
- [_core-adr-001 - XDRs core](/.xdrs/_core/adrs/principles/001-xdrs-core.md)
|
|
@@ -135,7 +135,8 @@ Rules:
|
|
|
135
135
|
- Use good-enough evidence. Experienced professional judgment is allowed, but the conclusions still need support that other colleagues can inspect and learn from.
|
|
136
136
|
- Ensure the methods and test conditions are reproducible enough for an experienced professional to rerun or evolve the critical parts later.
|
|
137
137
|
- Prefer plain Markdown, bullet points, tables, or ASCII art for simple explanations and comparisons, especially in the introduction and results.
|
|
138
|
-
- If the research genuinely needs local images or supporting files, store them in `.xdrs/[scope]/[type]/[subject]/researches/assets/` and link
|
|
138
|
+
- If the research genuinely needs local images or supporting files, store them in `.xdrs/[scope]/[type]/[subject]/researches/assets/` and link them using a same-folder relative path (e.g., `assets/image.png`).
|
|
139
|
+
- Links that reference a parent folder MUST use absolute paths from the repository root with a leading `/` (e.g., `/.xdrs/_core/adrs/principles/001-xdrs-core.md`). Sibling files and child folder references SHOULD use relative paths (e.g., `002-other-doc.md`, `assets/image.png`, `subdir/file.md`). Never use relative paths that traverse up the directory tree (e.g., `../../assets/test.png`, `../other.md`).
|
|
139
140
|
- Keep section word limits within the standard and keep the document under 5000 words total unless the introduction explicitly states that a very detailed analysis is required.
|
|
140
141
|
|
|
141
142
|
### Phase 8: Check Section Goals
|
|
@@ -266,9 +267,9 @@ If any check fails, revise before continuing.
|
|
|
266
267
|
|
|
267
268
|
## References
|
|
268
269
|
|
|
269
|
-
- [_core-adr-006 - Research standards](
|
|
270
|
-
- [_core-adr-001 - XDRs core](
|
|
271
|
-
- [002-write-xdr skill](
|
|
270
|
+
- [_core-adr-006 - Research standards](/.xdrs/_core/adrs/principles/006-research-standards.md)
|
|
271
|
+
- [_core-adr-001 - XDRs core](/.xdrs/_core/adrs/principles/001-xdrs-core.md)
|
|
272
|
+
- [002-write-xdr skill](/.github/skills/002-write-xdr/SKILL.md)
|
|
272
273
|
|
|
273
274
|
## Constraints
|
|
274
275
|
|
|
@@ -114,7 +114,8 @@ Rules to apply while drafting:
|
|
|
114
114
|
- If the plan scope is too large for 2 years, break it into multiple plans.
|
|
115
115
|
- Remember that this plan must be deleted after full implementation. Write it with that ephemeral nature in mind.
|
|
116
116
|
- Prefer plain Markdown, tables, or ASCII art for structure and flow.
|
|
117
|
-
- If the plan genuinely needs local images or supporting files, store them in `.xdrs/[scope]/[type]/[subject]/plans/assets/` and link
|
|
117
|
+
- If the plan genuinely needs local images or supporting files, store them in `.xdrs/[scope]/[type]/[subject]/plans/assets/` and link them using a same-folder relative path (e.g., `assets/image.png`).
|
|
118
|
+
- Links that reference a parent folder MUST use absolute paths from the repository root with a leading `/` (e.g., `/.xdrs/_core/adrs/principles/001-xdrs-core.md`). Sibling files and child folder references SHOULD use relative paths (e.g., `002-other-doc.md`, `assets/image.png`, `subdir/file.md`). Never use relative paths that traverse up the directory tree (e.g., `../../assets/test.png`, `../other.md`).
|
|
118
119
|
- Use lowercase file names. Never use emojis.
|
|
119
120
|
|
|
120
121
|
### Phase 6: Place and Register
|
|
@@ -152,6 +153,6 @@ Rules to apply while drafting:
|
|
|
152
153
|
|
|
153
154
|
## References
|
|
154
155
|
|
|
155
|
-
- [_core-adr-001 - XDRs core](
|
|
156
|
-
- [_core-adr-007 - Plan standards](
|
|
157
|
-
- [_core-adr-002 - XDR standards](
|
|
156
|
+
- [_core-adr-001 - XDRs core](/.xdrs/_core/adrs/principles/001-xdrs-core.md)
|
|
157
|
+
- [_core-adr-007 - Plan standards](/.xdrs/_core/adrs/principles/007-plan-standards.md)
|
|
158
|
+
- [_core-adr-002 - XDR standards](/.xdrs/_core/adrs/principles/002-xdr-standards.md)
|
|
@@ -47,6 +47,6 @@ Disallowed:
|
|
|
47
47
|
|
|
48
48
|
## References
|
|
49
49
|
|
|
50
|
-
- [_core-adr-001](
|
|
51
|
-
- [_core-adr-002](
|
|
52
|
-
- [_core-adr-003](
|
|
50
|
+
- [_core-adr-001](/.xdrs/_core/adrs/principles/001-xdrs-core.md)
|
|
51
|
+
- [_core-adr-002](/.xdrs/_core/adrs/principles/002-xdr-standards.md)
|
|
52
|
+
- [_core-adr-003](/.xdrs/_core/adrs/principles/003-skill-standards.md)
|
package/lib/lint.js
CHANGED
|
@@ -96,12 +96,13 @@ function lintWorkspace(targetPath, options = {}) {
|
|
|
96
96
|
|
|
97
97
|
function lintRootIndex(rootIndexPath, xdrsRoot, actualTypeIndexes, errors) {
|
|
98
98
|
const content = fs.readFileSync(rootIndexPath, 'utf8');
|
|
99
|
+
const repoRoot = path.dirname(xdrsRoot);
|
|
99
100
|
|
|
100
101
|
if (!content.includes(REQUIRED_ROOT_INDEX_TEXT)) {
|
|
101
102
|
errors.push(`Root index is missing required override text: ${toDisplayPath(rootIndexPath)}`);
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
const links = parseLocalLinks(content, path.dirname(rootIndexPath));
|
|
105
|
+
const links = parseLocalLinks(content, path.dirname(rootIndexPath), repoRoot);
|
|
105
106
|
for (const linkPath of links) {
|
|
106
107
|
if (!fs.existsSync(linkPath)) {
|
|
107
108
|
errors.push(`Broken link in root index: ${displayPath(rootIndexPath, linkPath)}`);
|
|
@@ -572,7 +573,8 @@ function lintPlanExpectedEndDate(content, filePath, errors) {
|
|
|
572
573
|
|
|
573
574
|
function lintTypeIndex(indexPath, xdrsRoot, artifacts, errors) {
|
|
574
575
|
const content = fs.readFileSync(indexPath, 'utf8');
|
|
575
|
-
const
|
|
576
|
+
const repoRoot = path.dirname(xdrsRoot);
|
|
577
|
+
const localLinks = parseLocalLinks(content, path.dirname(indexPath), repoRoot);
|
|
576
578
|
const linkedSet = new Set();
|
|
577
579
|
const scopeName = path.relative(xdrsRoot, indexPath).split(path.sep)[0];
|
|
578
580
|
const localScopePath = normalizePath(path.join(xdrsRoot, '_local'));
|
|
@@ -603,15 +605,24 @@ function lintDocumentLinks(documentPath, xdrsRoot, scopeName, errors) {
|
|
|
603
605
|
const documentDir = path.dirname(documentPath);
|
|
604
606
|
const resourceDir = path.join(documentDir, RESOURCE_DIR_NAME);
|
|
605
607
|
const localScopePath = normalizePath(path.join(xdrsRoot, '_local'));
|
|
608
|
+
const repoRoot = path.dirname(xdrsRoot);
|
|
606
609
|
|
|
607
610
|
for (let index = 0; index < lines.length; index += 1) {
|
|
608
611
|
if (ignoredLines[index]) {
|
|
609
612
|
continue;
|
|
610
613
|
}
|
|
611
614
|
|
|
612
|
-
for (const link of parseLocalLinkTargets(lines[index], documentDir)) {
|
|
615
|
+
for (const link of parseLocalLinkTargets(lines[index], documentDir, repoRoot)) {
|
|
613
616
|
const isResourceLink = shouldValidateResourceLink(link.rawTarget);
|
|
614
617
|
|
|
618
|
+
if (!isResourceLink && !link.isAbsolutePath) {
|
|
619
|
+
const relativeToDoc = path.relative(documentDir, link.resolvedPath);
|
|
620
|
+
const goesUpToParent = relativeToDoc.startsWith('..');
|
|
621
|
+
if (goesUpToParent) {
|
|
622
|
+
errors.push(`Relative links to parent directories must use absolute paths starting with / in ${toDisplayPath(documentPath)}:${index + 1}: ${link.rawTarget}`);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
615
626
|
if (!fs.existsSync(link.resolvedPath)) {
|
|
616
627
|
if (isResourceLink) {
|
|
617
628
|
errors.push(`Broken asset link in ${toDisplayPath(documentPath)}: ${link.rawTarget}`);
|
|
@@ -632,11 +643,11 @@ function lintDocumentLinks(documentPath, xdrsRoot, scopeName, errors) {
|
|
|
632
643
|
}
|
|
633
644
|
}
|
|
634
645
|
|
|
635
|
-
function parseLocalLinks(markdown, baseDir) {
|
|
636
|
-
return parseLocalLinkTargets(markdown, baseDir).map((link) => link.resolvedPath);
|
|
646
|
+
function parseLocalLinks(markdown, baseDir, repoRoot) {
|
|
647
|
+
return parseLocalLinkTargets(markdown, baseDir, repoRoot).map((link) => link.resolvedPath);
|
|
637
648
|
}
|
|
638
649
|
|
|
639
|
-
function parseLocalLinkTargets(markdown, baseDir) {
|
|
650
|
+
function parseLocalLinkTargets(markdown, baseDir, repoRoot) {
|
|
640
651
|
const links = [];
|
|
641
652
|
const linkRe = /!?\[[^\]]+\]\(([^)]+)\)/g;
|
|
642
653
|
let match = linkRe.exec(markdown);
|
|
@@ -644,9 +655,13 @@ function parseLocalLinkTargets(markdown, baseDir) {
|
|
|
644
655
|
const rawTarget = match[1].trim();
|
|
645
656
|
const normalizedTarget = normalizeLocalLinkTarget(rawTarget);
|
|
646
657
|
if (normalizedTarget) {
|
|
658
|
+
const isAbsolutePath = normalizedTarget.startsWith('/');
|
|
647
659
|
links.push({
|
|
648
660
|
rawTarget,
|
|
649
|
-
resolvedPath:
|
|
661
|
+
resolvedPath: isAbsolutePath && repoRoot
|
|
662
|
+
? path.join(repoRoot, normalizedTarget)
|
|
663
|
+
: path.resolve(baseDir, normalizedTarget),
|
|
664
|
+
isAbsolutePath
|
|
650
665
|
});
|
|
651
666
|
}
|
|
652
667
|
match = linkRe.exec(markdown);
|
package/lib/lint.test.js
CHANGED
|
@@ -145,7 +145,7 @@ test('allows _local XDR linking to another _local scope document', () => {
|
|
|
145
145
|
'',
|
|
146
146
|
'## Context and Problem Statement',
|
|
147
147
|
'',
|
|
148
|
-
'See [second](002-second.md).',
|
|
148
|
+
'See [second](/.xdrs/_local/adrs/principles/002-second.md).',
|
|
149
149
|
''
|
|
150
150
|
].join('\n'),
|
|
151
151
|
'.xdrs/_local/adrs/principles/002-second.md': [
|
|
@@ -187,6 +187,110 @@ test('reports non-_local canonical index linking to _local scope document', () =
|
|
|
187
187
|
expect(result.errors.join('\n')).toContain('Non-_local document must not link into _local scope');
|
|
188
188
|
});
|
|
189
189
|
|
|
190
|
+
test('reports relative non-asset links to parent directories in XDR documents', () => {
|
|
191
|
+
const workspaceRoot = createWorkspace('parent-dir-relative-link-in-xdr', {
|
|
192
|
+
'.xdrs/index.md': rootIndex(),
|
|
193
|
+
'.xdrs/_local/adrs/index.md': localAdrIndex([
|
|
194
|
+
'- [001-main](principles/001-main.md) - Main decision'
|
|
195
|
+
]),
|
|
196
|
+
'.xdrs/_local/adrs/principles/001-main.md': xdrDocument('See [other](../other.md).'),
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const result = lintWorkspace(workspaceRoot);
|
|
200
|
+
|
|
201
|
+
expect(result.errors.join('\n')).toContain('Relative links to parent directories must use absolute paths');
|
|
202
|
+
expect(result.errors.join('\n')).toContain('../other.md');
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test('allows child directory relative non-asset links in XDR documents', () => {
|
|
206
|
+
const workspaceRoot = createWorkspace('child-dir-relative-link-in-xdr', {
|
|
207
|
+
'.xdrs/index.md': rootIndex(),
|
|
208
|
+
'.xdrs/_local/adrs/index.md': localAdrIndex([
|
|
209
|
+
'- [001-main](principles/001-main.md) - Main decision'
|
|
210
|
+
]),
|
|
211
|
+
'.xdrs/_local/adrs/principles/001-main.md': xdrDocument('See [skill](skills/001-lint/SKILL.md).'),
|
|
212
|
+
});
|
|
213
|
+
const skillDir = path.join(workspaceRoot, '.xdrs/_local/adrs/principles/skills/001-lint');
|
|
214
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
215
|
+
fs.writeFileSync(path.join(skillDir, 'SKILL.md'), '---\nname: 001-lint\ndescription: test skill\n---\n# Skill');
|
|
216
|
+
|
|
217
|
+
const result = lintWorkspace(workspaceRoot);
|
|
218
|
+
|
|
219
|
+
expect(result.errors.join('\n')).not.toContain('Relative links to parent directories');
|
|
220
|
+
expect(result.errors.join('\n')).not.toContain('Broken local link');
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test('allows same-directory relative non-asset links in XDR documents', () => {
|
|
224
|
+
const workspaceRoot = createWorkspace('same-dir-relative-link-in-xdr', {
|
|
225
|
+
'.xdrs/index.md': rootIndex(),
|
|
226
|
+
'.xdrs/_local/adrs/index.md': localAdrIndex([
|
|
227
|
+
'- [001-main](principles/001-main.md) - Main decision',
|
|
228
|
+
'- [002-other](principles/002-other.md) - Other decision'
|
|
229
|
+
]),
|
|
230
|
+
'.xdrs/_local/adrs/principles/001-main.md': xdrDocument('See [other](002-other.md).'),
|
|
231
|
+
'.xdrs/_local/adrs/principles/002-other.md': xdrDocument('Other body.').replace('_local-adr-001-main', '_local-adr-002-other').replace('# _local-adr-001: Main decision', '# _local-adr-002: Other decision'),
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
const result = lintWorkspace(workspaceRoot);
|
|
235
|
+
|
|
236
|
+
expect(result.errors.join('\n')).not.toContain('absolute paths');
|
|
237
|
+
expect(result.errors.join('\n')).not.toContain('Broken local link');
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test('allows relative asset links in XDR documents', () => {
|
|
241
|
+
const workspaceRoot = createWorkspace('relative-asset-link', {
|
|
242
|
+
'.xdrs/index.md': rootIndex(),
|
|
243
|
+
'.xdrs/_local/adrs/index.md': localAdrIndex([
|
|
244
|
+
'- [001-main](principles/001-main.md) - Main decision'
|
|
245
|
+
]),
|
|
246
|
+
'.xdrs/_local/adrs/principles/001-main.md': xdrDocument('See .'),
|
|
247
|
+
});
|
|
248
|
+
const assetsDir = path.join(workspaceRoot, '.xdrs/_local/adrs/principles/assets');
|
|
249
|
+
fs.mkdirSync(assetsDir, { recursive: true });
|
|
250
|
+
fs.writeFileSync(path.join(assetsDir, 'diagram.png'), Buffer.alloc(0));
|
|
251
|
+
|
|
252
|
+
const result = lintWorkspace(workspaceRoot);
|
|
253
|
+
|
|
254
|
+
expect(result.errors.join('\n')).not.toContain('Non-asset links must use absolute paths');
|
|
255
|
+
expect(result.errors.join('\n')).not.toContain('Broken asset link');
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test('reports absolute path link that is broken', () => {
|
|
259
|
+
const workspaceRoot = createWorkspace('broken-absolute-link', {
|
|
260
|
+
'.xdrs/index.md': rootIndex(),
|
|
261
|
+
'.xdrs/_local/adrs/index.md': localAdrIndex([
|
|
262
|
+
'- [001-main](principles/001-main.md) - Main decision'
|
|
263
|
+
]),
|
|
264
|
+
'.xdrs/_local/adrs/principles/001-main.md': xdrDocument('See [missing](/.xdrs/_local/adrs/principles/999-nonexistent.md).'),
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
const result = lintWorkspace(workspaceRoot);
|
|
268
|
+
|
|
269
|
+
expect(result.errors.join('\n')).toContain('Broken local link');
|
|
270
|
+
expect(result.errors.join('\n')).toContain('999-nonexistent.md');
|
|
271
|
+
expect(result.errors.join('\n')).not.toContain('Non-asset links must use absolute paths');
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
test('reports non-_local XDR linking to _local scope via absolute path', () => {
|
|
275
|
+
const workspaceRoot = createWorkspace('abs-non-local-links-to-local', {
|
|
276
|
+
'.xdrs/index.md': rootIndex(),
|
|
277
|
+
'.xdrs/_local/adrs/index.md': localAdrIndex([
|
|
278
|
+
'- [001-main](principles/001-main.md) - Main decision'
|
|
279
|
+
]),
|
|
280
|
+
'.xdrs/_local/adrs/principles/001-main.md': xdrDocument('Local decision.'),
|
|
281
|
+
'.xdrs/myteam/adrs/index.md': teamAdrIndex([
|
|
282
|
+
'- [001-team](principles/001-team.md) - Team decision'
|
|
283
|
+
]),
|
|
284
|
+
'.xdrs/myteam/adrs/principles/001-team.md': teamXdrDocument(
|
|
285
|
+
'See [local doc](/.xdrs/_local/adrs/principles/001-main.md).'
|
|
286
|
+
),
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
const result = lintWorkspace(workspaceRoot, { ignoreReadOnly: false });
|
|
290
|
+
|
|
291
|
+
expect(result.errors.join('\n')).toContain('Non-_local document must not link into _local scope');
|
|
292
|
+
});
|
|
293
|
+
|
|
190
294
|
function teamAdrIndex(entries) {
|
|
191
295
|
return [
|
|
192
296
|
'# myteam ADR Index',
|
package/package.json
CHANGED