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.
@@ -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
- - Reference other files with relative paths from the skill root.
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](../001-xdrs-core.md).
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](../006-research-standards.md).
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](../003-skill-standards.md).
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](../004-article-standards.md).
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](../007-plan-standards.md).
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](../001-xdrs-core.md) and [_core-adr-002](../002-xdr-standards.md) strictly. Key rules:
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](../006-research-standards.md).
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](../003-skill-standards.md).
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](../004-article-standards.md).
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](../007-plan-standards.md).
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](../001-xdrs-core.md) - XDR elements: types, scopes, subjects, folder structure
185
- - [_core-adr-002](../002-xdr-standards.md) - XDR document standards and mandatory template
186
- - [_core-adr-003](../003-skill-standards.md) - Skill standards and co-location rules
187
- - [_core-adr-004](../004-article-standards.md) - Article standards
188
- - [_core-adr-006](../006-research-standards.md) - Research standards
189
- - [_core-adr-007](../007-plan-standards.md) - Plan standards
190
- - [001-lint skill](../skills/001-lint/SKILL.md) - Linting code against XDRs
191
- - [002-write-xdr skill](../skills/002-write-xdr/SKILL.md) - Writing a new XDR
192
- - [003-write-skill skill](../skills/003-write-skill/SKILL.md) - Writing a new skill
193
- - [004-write-article skill](../skills/004-write-article/SKILL.md) - Writing a new article
194
- - [005-write-research skill](../skills/005-write-research/SKILL.md) - Writing a new research document
195
- - [_core-adr-005](../005-semantic-versioning-for-xdr-packages.md) - Semantic versioning rules for XDR packages
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](../../001-xdrs-core.md)
92
- - [_core-adr-002 - XDR standards](../../002-xdr-standards.md)
93
- - [_core-adr-003 - Skill standards](../../003-skill-standards.md)
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 with a relative path.
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](../../001-xdrs-core.md)
191
- - [_core-adr-002 - XDR standards](../../002-xdr-standards.md)
192
- - [_core-adr-003 - Skill standards](../../003-skill-standards.md)
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 with a relative path.
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](../../003-skill-standards.md)
158
- - [_core-adr-001 - XDRs core](../../001-xdrs-core.md)
159
- - [002-write-xdr skill](../002-write-xdr/SKILL.md)
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](relative/path/to/file.md) - Brief description of relevance
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 with a relative path.
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](../../004-article-standards.md)
143
- - [_core-adr-006 - Research standards](../../006-research-standards.md)
144
- - [_core-adr-001 - XDRs core](../../001-xdrs-core.md)
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 with a relative path.
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](../../006-research-standards.md)
270
- - [_core-adr-001 - XDRs core](../../001-xdrs-core.md)
271
- - [002-write-xdr skill](../002-write-xdr/SKILL.md)
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 with a relative path.
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](../../001-xdrs-core.md)
156
- - [_core-adr-007 - Plan standards](../../007-plan-standards.md)
157
- - [_core-adr-002 - XDR standards](../../002-xdr-standards.md)
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](../../adrs/principles/001-xdrs-core.md)
51
- - [_core-adr-002](../../adrs/principles/002-xdr-standards.md)
52
- - [_core-adr-003](../../adrs/principles/003-skill-standards.md)
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 localLinks = parseLocalLinks(content, path.dirname(indexPath));
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: path.resolve(baseDir, normalizedTarget)
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 ![diagram](assets/diagram.png).'),
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xdrs-core",
3
- "version": "0.17.1",
3
+ "version": "0.18.0",
4
4
  "description": "A standard way to organize Decision Records (XDRs) across scopes, subjects, and teams so that AI agents can reliably query and follow them.",
5
5
  "repository": {
6
6
  "type": "git",