xdrs-core 0.26.0 → 0.27.1
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/.filedist-package.yml +23 -0
- package/.xdrs/_core/adrs/principles/001-xdrs-core.md +2 -1
- package/.xdrs/_core/adrs/principles/002-policy-standards.md +9 -6
- package/.xdrs/_core/adrs/principles/003-skill-standards.md +2 -1
- package/.xdrs/_core/adrs/principles/004-article-standards.md +14 -2
- package/.xdrs/_core/adrs/principles/005-semantic-versioning-for-xdrs-packages.md +2 -0
- package/.xdrs/_core/adrs/principles/006-research-standards.md +2 -1
- package/.xdrs/_core/adrs/principles/007-plan-standards.md +2 -1
- package/.xdrs/_core/adrs/principles/008-xdr-standards-structured.md +12 -10
- package/.xdrs/_core/adrs/principles/009-presentation-standards.md +2 -0
- package/.xdrs/_core/adrs/principles/skills/001-review/SKILL.md +1 -1
- package/.xdrs/_core/adrs/principles/skills/002-write-policy/SKILL.md +5 -5
- package/.xdrs/_core/adrs/principles/skills/003-write-skill/SKILL.md +1 -1
- package/.xdrs/_core/adrs/principles/skills/004-write-article/SKILL.md +4 -2
- package/lib/lint.js +8 -6
- package/lib/lint.test.js +71 -3
- package/package.json +4 -43
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
sets:
|
|
2
|
+
- selector:
|
|
3
|
+
files:
|
|
4
|
+
- AGENTS.md
|
|
5
|
+
- .xdrs/_core/**
|
|
6
|
+
exclude:
|
|
7
|
+
- "**/*.test.js"
|
|
8
|
+
- "**/*.test.int.js"
|
|
9
|
+
- "**/*.test.int.report"
|
|
10
|
+
output:
|
|
11
|
+
path: .
|
|
12
|
+
symlinks:
|
|
13
|
+
- source: .xdrs/**/skills/*
|
|
14
|
+
target: .github/skills
|
|
15
|
+
gitignore: false
|
|
16
|
+
|
|
17
|
+
- selector:
|
|
18
|
+
files:
|
|
19
|
+
- .xdrs/index.md
|
|
20
|
+
output:
|
|
21
|
+
path: .
|
|
22
|
+
gitignore: false
|
|
23
|
+
managed: false
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: _core-adr-policy-001-xdrs-core
|
|
3
3
|
description: Defines the core XDRS framework including types (ADR, BDR, EDR), folder structure, scopes, subjects, and index requirements. Use when structuring or navigating policies.
|
|
4
|
+
apply-to: All XDRS scopes and document types
|
|
5
|
+
valid-from: 2025-01-01
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# _core-adr-policy-001: XDRs core
|
|
@@ -56,7 +58,6 @@ Policies can be of different kinds, depending on the nature of the decision:
|
|
|
56
58
|
- Articles use `[xdrs-root]/[scope]/[type]/[subject]/articles/.assets/`
|
|
57
59
|
- Research uses `[xdrs-root]/[scope]/[type]/[subject]/researches/.assets/`
|
|
58
60
|
- Skills use `[xdrs-root]/[scope]/[type]/[subject]/skills/[number]-[skill-name]/.assets/`
|
|
59
|
-
- Sub-directories inside `.assets/` are allowed to keep related files organized only when that `.assets/` folder already has more than 10 files. Otherwise, keep files flat in `.assets/`.
|
|
60
61
|
- **Scopes:**
|
|
61
62
|
- Short name that defines a group or a package of XDRS
|
|
62
63
|
- examples: `business-x`, `business-y`, `team-43`, `_core`
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: _core-adr-policy-002-policy-standards
|
|
3
3
|
description: Defines how Policy documents (the core Policy document type) should be written, including template, frontmatter, applicability fields, and conflict handling. Use when writing or reviewing any Policy, rules, contraints or a specific decision document.
|
|
4
|
+
apply-to: All Policy documents
|
|
5
|
+
valid-from: 2025-01-01
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# _core-adr-policy-002: Policy standards
|
|
@@ -25,8 +27,8 @@ Policy documents are the authoritative source of truth for their scope, type, an
|
|
|
25
27
|
|---|---|---|
|
|
26
28
|
| `name` | Yes | 1-64 characters. Lowercase letters, numbers, hyphens, and leading underscores only. Must not end with a hyphen. Must not contain consecutive hyphens. Must match the document identifier from the heading: `[scope]-[type]-policy-[number]-[short-title]`. |
|
|
27
29
|
| `description` | Yes | 1-1024 characters. Describes what this decision is about and when to use it. Should include keywords that help agents identify when to apply it. |
|
|
28
|
-
| `apply-to` |
|
|
29
|
-
| `valid-from` |
|
|
30
|
+
| `apply-to` | Yes | Short description of contexts this decision is applicable to. Keep it under 40 words. Use `All scopes` when the decision applies broadly. Examples: `Only frontend code`, `JavaScript projects`, `All scopes`. |
|
|
31
|
+
| `valid-from` | Yes | ISO date (`YYYY-MM-DD`) indicating from when this decision must be enforced. Before this date it should be used everywhere possible, but compliance is not enforced during reviews until after this date. Defaults to the date the Policy was created. |
|
|
30
32
|
| `license` | No | SPDX license expression (e.g. `MIT`, `Apache-2.0`, `CC-BY-4.0`). Indicates the license under which the document content is shared. If omitted, the license is governed by the repository or package defaults. |
|
|
31
33
|
| `metadata` | No | Arbitrary key-value map for additional properties not defined by this spec. |
|
|
32
34
|
|
|
@@ -35,6 +37,8 @@ Policy documents are the authoritative source of truth for their scope, type, an
|
|
|
35
37
|
---
|
|
36
38
|
name: _core-adr-policy-002-policy-standards
|
|
37
39
|
description: Defines how Policy documents should be written. Use when writing or reviewing any Policy.
|
|
40
|
+
apply-to: All scopes
|
|
41
|
+
valid-from: 2026-05-21
|
|
38
42
|
---
|
|
39
43
|
```
|
|
40
44
|
- Example with optional fields:
|
|
@@ -68,7 +72,6 @@ Policy documents are the authoritative source of truth for their scope, type, an
|
|
|
68
72
|
- Never use emojis in contents.
|
|
69
73
|
- Always use file names with lowercase.
|
|
70
74
|
- Any non-Markdown files referenced by a Policy (schemas, JSON examples, images, diagrams, binaries, or any other data files) SHOULD be used only when they are materially necessary and MUST live in `[xdrs-root]/[scope]/[type]/[subject]/.assets/`.
|
|
71
|
-
- Sub-directories inside this `.assets/` folder are allowed only when it already has more than 10 files. Otherwise, keep files flat.
|
|
72
75
|
- Avoid using lengthy instructions on the Policy. If there are long and detailed instructions related to the Policy, or instructions that are outside the decision, create another file with a guide. If the guide is small, keep it in the Policy itself.
|
|
73
76
|
- Policies should be under 1300 words long as a rule of thumb.
|
|
74
77
|
- This is important to make them focused on a clear decision
|
|
@@ -83,8 +86,8 @@ All Policies MUST follow this template
|
|
|
83
86
|
---
|
|
84
87
|
name: [scope]-[type]-policy-[number]-[short-title]
|
|
85
88
|
description: [What this decision is about and when to use it]
|
|
86
|
-
apply-to: [
|
|
87
|
-
valid-from: [
|
|
89
|
+
apply-to: [Required. Contexts this decision applies to, under 40 words. Use "All scopes" when broadly applicable.]
|
|
90
|
+
valid-from: [Required. ISO date YYYY-MM-DD from when enforcement begins. Defaults to creation date.]
|
|
88
91
|
license: [Optional. SPDX license expression]
|
|
89
92
|
metadata:
|
|
90
93
|
[optional-key]: [optional-value]
|
|
@@ -111,7 +114,7 @@ Question: In the end, state explicitly the question that needs to be answered. E
|
|
|
111
114
|
[Optional section with implementation specifics, applicability boundaries, rules, concise examples, or do/don't guidance. This is the answer to the question in the "Context and Problem Statement". (<1300 words)]
|
|
112
115
|
|
|
113
116
|
## Considered Options
|
|
114
|
-
[this section is present ONLY if the user explicitely indicated that there were multiple options to choose from while making this decision
|
|
117
|
+
[this section is present ONLY if the user explicitely indicated that there were multiple options to choose from while making this decision or have a backing research document]
|
|
115
118
|
|
|
116
119
|
[Related research, if any]
|
|
117
120
|
- [Research document title](researches/001-example.md) - Brief description of what it informed
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: _core-adr-policy-003-skill-standards
|
|
3
3
|
description: Defines skill package standards including structure, SKILL.md format, and co-location with XDRS packages. Use when creating or reviewing skills.
|
|
4
|
+
apply-to: All skill packages
|
|
5
|
+
valid-from: 2025-01-01
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# _core-adr-policy-003: Skill standards
|
|
@@ -116,7 +118,6 @@ Rules:
|
|
|
116
118
|
- `## Instructions` SHOULD include verification steps or acceptance criteria at the end of the task, or at the end of major phases when partial validation matters.
|
|
117
119
|
- For simple structure, flow, layout, or relationship indications, `SKILL.md` SHOULD prefer plain Markdown, tables, or ASCII art instead of external assets.
|
|
118
120
|
- Any non-Markdown files referenced from `SKILL.md` (schemas, JSON examples, images, diagrams, binaries, or any other data files) SHOULD be used only when they are materially necessary and MUST live in `.assets/` inside the same skill package.
|
|
119
|
-
- Sub-directories inside this `.assets/` folder are allowed only when it already has more than 10 files. Otherwise, keep files flat.
|
|
120
121
|
- Keep `SKILL.md` under 6500 words. Move lengthy reference material to `references/`.
|
|
121
122
|
- Use relative paths for all links; never use absolute paths starting with `/`.
|
|
122
123
|
- Always use lowercase file names.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: _core-adr-policy-004-article-standards
|
|
3
3
|
description: Defines article document standards for synthesizing and linking Policies, research, and skills. Use when creating or reviewing articles.
|
|
4
|
+
apply-to: All article documents
|
|
5
|
+
valid-from: 2025-01-01
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# _core-adr-policy-004: Article standards
|
|
@@ -19,6 +21,15 @@ Articles are Markdown documents placed inside a subject folder alongside policie
|
|
|
19
21
|
|
|
20
22
|
### Details
|
|
21
23
|
|
|
24
|
+
**Human-first writing**
|
|
25
|
+
|
|
26
|
+
- The primary objective of an article is to make information available and accessible to humans. Good copywriting style, storytelling, clear organization, and clustering of related information are essential. Avoid repetitive content; each sentence should add new value.
|
|
27
|
+
- Articles SHOULD stay under 2000 words (approximately a 10-minute read) to maximize reader engagement. When planning an article, keep it as small as possible. Break large subjects into separate chapters, each in its own article, so readers can consume and understand sections independently.
|
|
28
|
+
- When a topic is broken into multiple articles, organize them as a **series**: each article MUST declare its position at the very top (e.g., `_This is article 2/4 of the "Engineering Practices" series._`) and MUST link to the previous and next articles in the series so readers can navigate the sequence without returning to an index.
|
|
29
|
+
- Articles should be kept under 8000 words (hard limit). Move or point to detailed contents referenced in Policy decisions, researches, plans, or skills.
|
|
30
|
+
|
|
31
|
+
**Content and structure**
|
|
32
|
+
|
|
22
33
|
- Articles are views, not decisions. They summarize and synthesize content from Policies, Research, and Skills but are NOT the source of truth. When there is a conflict between an article and a Policy, the Policy takes precedence.
|
|
23
34
|
- Articles are not limited to synthesizing Policies. They may also document application features, APIs, general project information, reference tables, diagrams, FAQs and other elements useful to their intended audience.
|
|
24
35
|
- Articles must reference the Policies, Research documents, and Skills they synthesize. Never duplicate decision content; link back to the authoritative sources.
|
|
@@ -29,10 +40,8 @@ Articles are Markdown documents placed inside a subject folder alongside policie
|
|
|
29
40
|
- Place an article in the subject folder that best matches its topic using the required list of subjects per type defined in `_core-adr-policy-001`. If an article spans more than one subject, place it in `principles`.
|
|
30
41
|
- For simple structure, flow, layout, or relationship indications, articles SHOULD prefer plain Markdown, tables, or ASCII art instead of external assets.
|
|
31
42
|
- Any non-Markdown files referenced by an article (schemas, JSON examples, images, diagrams, binaries, or any other data files) SHOULD be used only when they are materially necessary and MUST live in `articles/.assets/` next to the article files.
|
|
32
|
-
- Sub-directories inside this `.assets/` folder are allowed only when it already has more than 10 files. Otherwise, keep files flat.
|
|
33
43
|
- Always use lowercase file names.
|
|
34
44
|
- Never use emojis in article content.
|
|
35
|
-
- Articles should be kept under 5000 words. Move or point to detailed contents referenced in Policy decisions, researches, plans or skills.
|
|
36
45
|
|
|
37
46
|
**Folder layout**
|
|
38
47
|
|
|
@@ -64,6 +73,9 @@ All articles MUST follow this template:
|
|
|
64
73
|
```markdown
|
|
65
74
|
# [scope]-[type]-article-[number]: [Short Title]
|
|
66
75
|
|
|
76
|
+
<!-- If this article is part of a series, add the line below (omit otherwise): -->
|
|
77
|
+
_This is article [N]/[Total] of the "[Series Name]" series. | Previous: [title](./[prev-file].md) | Next: [title](./[next-file].md)_
|
|
78
|
+
|
|
67
79
|
## Overview
|
|
68
80
|
|
|
69
81
|
[Brief description of what this article covers and its intended audience. (<40 words)]
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: _core-adr-policy-005-semantic-versioning-for-xdrs-packages
|
|
3
3
|
description: Defines how semantic versioning applies to XDRS packages. Use when publishing or versioning a package containing Policies, research, skills, or articles.
|
|
4
|
+
apply-to: XDRS packages using semantic versioning
|
|
5
|
+
valid-from: 2025-01-01
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# _core-adr-policy-005: Semantic versioning for XDRS packages
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: _core-adr-policy-006-research-standards
|
|
3
3
|
description: Defines research document standards including IMRAD structure and traceability to Policies. Use when creating or reviewing research documents.
|
|
4
|
+
apply-to: All research documents
|
|
5
|
+
valid-from: 2025-01-01
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# _core-adr-policy-006: Research standards
|
|
@@ -49,7 +51,6 @@ Research documents are Markdown files placed inside a subject folder alongside p
|
|
|
49
51
|
- A 1:1 relationship between one research document and one decision will likely be common in practice, but it is not required.
|
|
50
52
|
- One research document MAY also be referenced by multiple Policies, including a mix of ADRs, BDRs, and EDRs, when the same investigation remains relevant across several decisions.
|
|
51
53
|
- Any non-Markdown files referenced by a research document (schemas, JSON examples, images, diagrams, binaries, or any other data files) SHOULD be used only when they are materially necessary and MUST live in `researches/.assets/` next to the research files.
|
|
52
|
-
- Sub-directories inside this `.assets/` folder are allowed only when it already has more than 10 files. Otherwise, keep files flat.
|
|
53
54
|
- Research file names MUST be lowercase. Never use emojis.
|
|
54
55
|
- A research document MAY exist before the related Policy is written, or remain after the Policy changes, as long as its status and references stay clear.
|
|
55
56
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: _core-adr-policy-007-plan-standards
|
|
3
3
|
description: Defines plan document standards for describing problems, solutions, and activities. Use when creating or reviewing plans.
|
|
4
|
+
apply-to: All plan documents
|
|
5
|
+
valid-from: 2025-01-01
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# _core-adr-policy-007: Plan standards
|
|
@@ -32,7 +34,6 @@ Plans are Markdown documents placed inside a subject folder alongside policies.
|
|
|
32
34
|
- Always use lowercase file names.
|
|
33
35
|
- Never use emojis in plan content.
|
|
34
36
|
- Any non-Markdown files referenced by a plan (schemas, JSON examples, images, diagrams, binaries, or any other data files) SHOULD be used only when they are materially necessary and MUST live in `plans/.assets/` next to the plan files.
|
|
35
|
-
- Sub-directories inside this `.assets/` folder are allowed only when it already has more than 10 files. Otherwise, keep files flat.
|
|
36
37
|
|
|
37
38
|
**Folder layout**
|
|
38
39
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: _core-adr-policy-008-policy-standards-structured
|
|
3
3
|
description: Extends policy-standards with a numbered rule format for Policy documents that define strong policies or rules, or need individually referenceable items. Use when a Policy must expose explicit rule blocks that other documents or skills may cite by identifier.
|
|
4
|
+
apply-to: Policy documents requiring structured rule blocks
|
|
5
|
+
valid-from: 2025-01-01
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# _core-adr-policy-008: Policy standards - structured
|
|
@@ -26,7 +28,7 @@ Use this format when the decision defines strong rules or policies that must be
|
|
|
26
28
|
Each numbered rule must be written as:
|
|
27
29
|
|
|
28
30
|
```markdown
|
|
29
|
-
#### [NN]-[short
|
|
31
|
+
#### [NN]-[short descriptive title with mandatory or advisory language about the enforced policy item]
|
|
30
32
|
[Body using mandatory or advisory language as defined in _core-adr-policy-001. State the requirement and the situations in which it must or should be followed. Under 500 words.]
|
|
31
33
|
```
|
|
32
34
|
|
|
@@ -42,31 +44,31 @@ Rule bodies must use the mandatory or advisory language terms defined in `_core-
|
|
|
42
44
|
When another document or skill cites a specific rule, it must use the following dot-notation:
|
|
43
45
|
|
|
44
46
|
```
|
|
45
|
-
policy-name.NN-
|
|
47
|
+
policy-name.[NN-Short descriptive title as written in the heading]
|
|
46
48
|
```
|
|
47
49
|
|
|
48
50
|
Examples:
|
|
49
51
|
|
|
50
|
-
- `_core-adr-policy-008-policy-standards-structured.[01-use
|
|
51
|
-
- `_local-bdr-policy-003-data-retention-policy.[02-
|
|
52
|
+
- `_core-adr-policy-008-policy-standards-structured.[01-Always use numbered rules for strong or referenceable policies]`
|
|
53
|
+
- `_local-bdr-policy-003-data-retention-policy.[02-Purge schedule for PII]`
|
|
52
54
|
|
|
53
|
-
The `policy-name` must match the `name` field in the frontmatter of the source document exactly. The rule identifier
|
|
55
|
+
The `policy-name` must match the `name` field in the frontmatter of the source document exactly. The rule identifier inside the brackets must match the heading text exactly, including the two-digit prefix.
|
|
54
56
|
|
|
55
|
-
#### 01-use
|
|
57
|
+
#### 01-Always use numbered rules for strong or referenceable policies
|
|
56
58
|
|
|
57
59
|
Numbered rule blocks must be added to a Policy when the decision defines strong rules or policies that must be stated explicitly as stable items, or when there is a clear need for other documents, skills, or agents to cite individual rules by identifier. Adding numbered rules only for cosmetic organization is not recommended. Standard Policy documents that do not define strong rule sets and are not expected to be cited at the rule level should follow `_core-adr-policy-002-policy-standards` without this structured format.
|
|
58
60
|
|
|
59
|
-
#### 02-
|
|
61
|
+
#### 02-Rule numbering must be stable
|
|
60
62
|
|
|
61
63
|
Rule numbers must never be reused within the same document. When a rule is removed, its number becomes permanently retired for that document. Gaps in the sequence are expected and must not be filled by renumbering remaining rules, as existing citations depend on number stability.
|
|
62
64
|
|
|
63
|
-
#### 03-
|
|
65
|
+
#### 03-Rule body must use normative language
|
|
64
66
|
|
|
65
67
|
Every rule body must contain at least one mandatory or advisory language term as defined in `_core-adr-policy-001`. Rule bodies without normative language must not be published, as they fail to communicate whether compliance is required or recommended.
|
|
66
68
|
|
|
67
|
-
#### 04-
|
|
69
|
+
#### 04-Citations must use exact identifiers
|
|
68
70
|
|
|
69
|
-
Documents and skills that cite a rule must use the exact dot-notation form: `policy-name.NN-
|
|
71
|
+
Documents and skills that cite a rule must use the exact dot-notation form: `policy-name.[NN-Heading text as written]`. Prose paraphrases such as "see rule 3" or "the third rule in that Policy" must not be used as citations, because they are ambiguous and break when rules are reordered or reworded.
|
|
70
72
|
|
|
71
73
|
## Considered Options
|
|
72
74
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: _core-adr-policy-009-presentation-standards
|
|
3
3
|
description: Defines how Marp slide presentations are structured, named, placed, and linked within XDRS projects. Use when creating, reviewing, or linting slide decks that support XDRS documents.
|
|
4
|
+
apply-to: Marp slide presentations in XDRS projects
|
|
5
|
+
valid-from: 2025-01-01
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# _core-adr-policy-009: Presentation standards
|
|
@@ -22,7 +22,7 @@ Performs a structured review of code changes or files against the Policies in th
|
|
|
22
22
|
|
|
23
23
|
### Phase 2: Policy Compilation
|
|
24
24
|
|
|
25
|
-
1. Gather all Policies from the Policy root `index.md` (default: `.
|
|
25
|
+
1. Gather all Policies from the Policy root `index.md` (default: `.xdrs/index.md`) starting from the working directory.
|
|
26
26
|
- Policy scopes are controlled by nested folders; some are broad, others domain-specific.
|
|
27
27
|
- Extract frontmatter first to decide whether each Policy should be used for the current review context.
|
|
28
28
|
- All documents present in the collection are considered active.
|
|
@@ -107,8 +107,8 @@ Refer to `_core-adr-policy-008-policy-standards-structured` for full requirement
|
|
|
107
107
|
---
|
|
108
108
|
name: [scope]-[type]-[number]-[short-title]
|
|
109
109
|
description: [What this decision is about and when to use it]
|
|
110
|
-
apply-to: [
|
|
111
|
-
valid-from: [
|
|
110
|
+
apply-to: [Required. Contexts this decision applies to, under 40 words. Use "All scopes" when broadly applicable.]
|
|
111
|
+
valid-from: [Required. ISO date YYYY-MM-DD. Defaults to today's date when not specified by the user.]
|
|
112
112
|
---
|
|
113
113
|
|
|
114
114
|
# [scope]-[type]-[number]: [Short Title]
|
|
@@ -132,8 +132,8 @@ valid-from: [Optional. ISO date YYYY-MM-DD from when enforcement begins]
|
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
Mandatory rules to apply while drafting:
|
|
135
|
-
-
|
|
136
|
-
-
|
|
135
|
+
- Always include frontmatter `apply-to:`. Use `All scopes` when the decision applies broadly, or a more specific description when the decision is narrowly scoped.
|
|
136
|
+
- Always include frontmatter `valid-from:`. Use today's date in `YYYY-MM-DD` format when the user does not specify a date.
|
|
137
137
|
- Keep `apply-to:` under 40 words and use `valid-from:` only with `YYYY-MM-DD` ISO format.
|
|
138
138
|
- When frontmatter metadata is present, write it so a reader can decide whether the Policy should be used for the current case without guessing. `valid-from:` sets a convergence date for adoption, `apply-to:` narrows the contexts where the decision applies, and the decision text defines any remaining boundaries.
|
|
139
139
|
- Use mandatory language ("must", "always", "never") only for hard requirements; use advisory language ("should", "recommended") for guidance.
|
|
@@ -152,7 +152,7 @@ Mandatory rules to apply while drafting:
|
|
|
152
152
|
Check every item before finalizing:
|
|
153
153
|
|
|
154
154
|
1. **Length**: Is it under 1300 words? Trim verbose explanations. Move detailed skills to a separate file and link.
|
|
155
|
-
2. **Frontmatter**: Are `apply-to:` and `valid-from:` present
|
|
155
|
+
2. **Frontmatter**: Are `apply-to:` and `valid-from:` both present? `apply-to:` must describe the applicable context (use `All scopes` when broadly applicable). `valid-from:` must be set (use today's date if the user did not specify one).
|
|
156
156
|
3. **Originality**: Does every sentence add value that cannot be found in a generic web search? Remove obvious advice. Keep only the project-specific decision.
|
|
157
157
|
4. **Clarity**: Is the chosen option unambiguous? Is the "why" clear in one reading?
|
|
158
158
|
5. **Redundancy**: Is the Policy the primary source for the decision itself, with related documents linked instead of duplicated wherever possible?
|
|
@@ -120,7 +120,7 @@ If any check fails, revise before continuing.
|
|
|
120
120
|
1. Create the skill file at `.xdrs/[scope]/[type]/[subject]/skills/[number]-[skill-name]/SKILL.md`.
|
|
121
121
|
2. Create a symlink at `.github/skills/[number]-[skill-name]` so VS Code picks it up immediately:
|
|
122
122
|
```
|
|
123
|
-
mkdir -p .github/skills
|
|
123
|
+
mkdir -p .github/skills
|
|
124
124
|
ln -s ../../.xdrs/[scope]/[type]/[subject]/skills/[number]-[skill-name] .github/skills/[number]-[skill-name]
|
|
125
125
|
```
|
|
126
126
|
3. Evaluate whether the scope index at `.xdrs/[scope]/index.md` should be updated to reflect the new skill. If the scope index does not exist, create it following article standards and the scope index rules in `_core-adr-policy-001`.
|
|
@@ -90,6 +90,7 @@ when referencing information from those documents. Keep under 1950 words total.]
|
|
|
90
90
|
|
|
91
91
|
Rules to apply while drafting:
|
|
92
92
|
|
|
93
|
+
- **Write for humans first.** Use clear copywriting style, natural storytelling flow, and logical clustering of related information. Each paragraph should guide the reader forward — avoid repeating information already stated.
|
|
93
94
|
- Write for the stated audience; avoid jargon unexplained elsewhere.
|
|
94
95
|
- Every factual claim must link back to the authoritative Policy or Skill.
|
|
95
96
|
- If the article advises readers what to do, clearly separate active/applicable Policies from background, historical, or out-of-scope ones.
|
|
@@ -97,7 +98,7 @@ Rules to apply while drafting:
|
|
|
97
98
|
- Prefer plain Markdown, tables, Mermaid.js (sequence, state, activity, entity diagrams), or ASCII art for simple structure, flow, layout, or relationship indications.
|
|
98
99
|
- 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`).
|
|
99
100
|
- Use relative paths for all links; never use absolute paths starting with `/`.
|
|
100
|
-
-
|
|
101
|
+
- Target under 1950 words for best reader engagement (SHOULD). If content grows beyond that, break it into separate chapter articles rather than expanding a single file. The hard limit is 8000 words.
|
|
101
102
|
- Use lowercase file names. Never use emojis.
|
|
102
103
|
- If a conflict exists between the article and a Policy, note it and defer to the Policy.
|
|
103
104
|
|
|
@@ -131,7 +132,8 @@ Rules to apply while drafting:
|
|
|
131
132
|
- **Cross-subject topic** — place the article in `principles`, not in any single subject folder.
|
|
132
133
|
- **No existing articles folder** — create it; it is optional in the folder layout.
|
|
133
134
|
- **Conflicting information found** — note the conflict in the article and always defer to the Policy.
|
|
134
|
-
- **Article
|
|
135
|
+
- **Article approaches 2000 words** — split the content into separate chapter articles (e.g., `001-topic-overview.md`, `002-topic-deep-dive.md`) so each can be read and understood independently. Move detailed content to a Research, Skill, or Policy and link back. The hard ceiling is 8000 words; never exceed it.
|
|
136
|
+
- **Article is part of a series** — add the series position line immediately after the heading (e.g., `_This is article 2/4 of the "Engineering Practices" series. | Previous: ... | Next: ..._`) and link to the adjacent articles. When creating a new article that splits an existing one, update the neighbouring articles to reflect the new total and add or correct their navigation links.
|
|
135
137
|
|
|
136
138
|
## Constraints
|
|
137
139
|
|
package/lib/lint.js
CHANGED
|
@@ -32,7 +32,7 @@ const SLIDE_FILE_RE = /^.+-slides(?:-[a-z0-9-]+)?\.md$/;
|
|
|
32
32
|
const SLIDE_MAX_NAME_LENGTH = 64;
|
|
33
33
|
const EMOJI_RE = /\p{Extended_Pictographic}/u;
|
|
34
34
|
const POLICY_MAX_WORDS = 2600;
|
|
35
|
-
const ARTICLE_MAX_WORDS =
|
|
35
|
+
const ARTICLE_MAX_WORDS = 8000;
|
|
36
36
|
const RESEARCH_MAX_WORDS = 5000;
|
|
37
37
|
const SKILL_MAX_WORDS = 6500;
|
|
38
38
|
|
|
@@ -389,12 +389,14 @@ function lintXdrsElementFrontmatter(content, expectedName, filePath, errors) {
|
|
|
389
389
|
} else if (fm.descriptionText && fm.descriptionText.length > 1024) {
|
|
390
390
|
errors.push(`Policy frontmatter description must be 1024 characters or fewer: ${toDisplayPath(filePath)}`);
|
|
391
391
|
}
|
|
392
|
-
if (fm.validFrom
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
392
|
+
if (!fm.validFrom) {
|
|
393
|
+
errors.push(`Policy frontmatter must include a valid-from field: ${toDisplayPath(filePath)}`);
|
|
394
|
+
} else if (!isIsoDate(fm.validFrom)) {
|
|
395
|
+
errors.push(`Policy frontmatter valid-from must be a valid ISO date YYYY-MM-DD: ${toDisplayPath(filePath)}`);
|
|
396
396
|
}
|
|
397
|
-
if (fm.appliedTo
|
|
397
|
+
if (!fm.appliedTo) {
|
|
398
|
+
errors.push(`Policy frontmatter must include an apply-to field: ${toDisplayPath(filePath)}`);
|
|
399
|
+
} else {
|
|
398
400
|
const words = countWords(fm.appliedTo);
|
|
399
401
|
if (words === 0) {
|
|
400
402
|
errors.push(`Policy frontmatter apply-to must not be empty: ${toDisplayPath(filePath)}`);
|
package/lib/lint.test.js
CHANGED
|
@@ -234,6 +234,68 @@ test('accepts all known frontmatter fields in XDRS element documents', () => {
|
|
|
234
234
|
expect(result.errors.join('\n')).not.toContain('unknown field');
|
|
235
235
|
});
|
|
236
236
|
|
|
237
|
+
test('reports missing apply-to field in Policy frontmatter', () => {
|
|
238
|
+
const workspaceRoot = createWorkspace('xdrs-element-missing-apply-to', {
|
|
239
|
+
'.xdrs/index.md': rootIndex(),
|
|
240
|
+
'.xdrs/_local/adrs/index.md': localAdrIndex([
|
|
241
|
+
'- [001-main](principles/001-main.md) - Main decision'
|
|
242
|
+
]),
|
|
243
|
+
'.xdrs/_local/adrs/principles/001-main.md': [
|
|
244
|
+
'---',
|
|
245
|
+
'name: _local-adr-policy-001-main',
|
|
246
|
+
'description: Test XDRS element',
|
|
247
|
+
'valid-from: 2026-01-01',
|
|
248
|
+
'---',
|
|
249
|
+
'',
|
|
250
|
+
'# _local-adr-policy-001: Main decision',
|
|
251
|
+
'',
|
|
252
|
+
'## Context and Problem Statement',
|
|
253
|
+
'',
|
|
254
|
+
'Test body.',
|
|
255
|
+
'',
|
|
256
|
+
'## Decision Outcome',
|
|
257
|
+
'',
|
|
258
|
+
'Test decision outcome.',
|
|
259
|
+
''
|
|
260
|
+
].join('\n'),
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
const result = lintWorkspace(workspaceRoot);
|
|
264
|
+
|
|
265
|
+
expect(result.errors.join('\n')).toContain('Policy frontmatter must include an apply-to field');
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
test('reports missing valid-from field in Policy frontmatter', () => {
|
|
269
|
+
const workspaceRoot = createWorkspace('xdrs-element-missing-valid-from', {
|
|
270
|
+
'.xdrs/index.md': rootIndex(),
|
|
271
|
+
'.xdrs/_local/adrs/index.md': localAdrIndex([
|
|
272
|
+
'- [001-main](principles/001-main.md) - Main decision'
|
|
273
|
+
]),
|
|
274
|
+
'.xdrs/_local/adrs/principles/001-main.md': [
|
|
275
|
+
'---',
|
|
276
|
+
'name: _local-adr-policy-001-main',
|
|
277
|
+
'description: Test XDRS element',
|
|
278
|
+
'apply-to: All scopes',
|
|
279
|
+
'---',
|
|
280
|
+
'',
|
|
281
|
+
'# _local-adr-policy-001: Main decision',
|
|
282
|
+
'',
|
|
283
|
+
'## Context and Problem Statement',
|
|
284
|
+
'',
|
|
285
|
+
'Test body.',
|
|
286
|
+
'',
|
|
287
|
+
'## Decision Outcome',
|
|
288
|
+
'',
|
|
289
|
+
'Test decision outcome.',
|
|
290
|
+
''
|
|
291
|
+
].join('\n'),
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
const result = lintWorkspace(workspaceRoot);
|
|
295
|
+
|
|
296
|
+
expect(result.errors.join('\n')).toContain('Policy frontmatter must include a valid-from field');
|
|
297
|
+
});
|
|
298
|
+
|
|
237
299
|
test('reports unknown frontmatter fields in SKILL.md files', () => {
|
|
238
300
|
const workspaceRoot = createWorkspace('skill-unknown-frontmatter', {
|
|
239
301
|
'.xdrs/index.md': rootIndex(),
|
|
@@ -820,6 +882,8 @@ function xdrDocument(body) {
|
|
|
820
882
|
'---',
|
|
821
883
|
'name: _local-adr-policy-001-main',
|
|
822
884
|
'description: Test XDRS element',
|
|
885
|
+
'apply-to: All scopes',
|
|
886
|
+
'valid-from: 2026-01-01',
|
|
823
887
|
'---',
|
|
824
888
|
'',
|
|
825
889
|
'# _local-adr-policy-001: Main decision',
|
|
@@ -860,6 +924,8 @@ test('accepts a custom root folder name as the XDRS root when it contains index.
|
|
|
860
924
|
'---',
|
|
861
925
|
'name: _local-adr-policy-001-main-decision',
|
|
862
926
|
'description: Test XDRS element',
|
|
927
|
+
'apply-to: All scopes',
|
|
928
|
+
'valid-from: 2026-01-01',
|
|
863
929
|
'---',
|
|
864
930
|
'',
|
|
865
931
|
'# _local-adr-policy-001: Main decision',
|
|
@@ -893,6 +959,8 @@ test('falls back to .xdrs subdirectory when given path has no index.md', () => {
|
|
|
893
959
|
'---',
|
|
894
960
|
'name: _local-adr-policy-001-main-decision',
|
|
895
961
|
'description: Test XDRS element',
|
|
962
|
+
'apply-to: All scopes',
|
|
963
|
+
'valid-from: 2026-01-01',
|
|
896
964
|
'---',
|
|
897
965
|
'',
|
|
898
966
|
'# _local-adr-policy-001: Main decision',
|
|
@@ -1144,8 +1212,8 @@ test('reports XDRS element document exceeding 2600 word limit', () => {
|
|
|
1144
1212
|
expect(result.errors.join('\n')).toContain('Policy exceeds maximum word count of 2600');
|
|
1145
1213
|
});
|
|
1146
1214
|
|
|
1147
|
-
test('reports article exceeding
|
|
1148
|
-
const longBody = ('word '.repeat(
|
|
1215
|
+
test('reports article exceeding 8000 word limit', () => {
|
|
1216
|
+
const longBody = ('word '.repeat(8001)).trimEnd();
|
|
1149
1217
|
const workspaceRoot = createWorkspace('article-too-many-words', {
|
|
1150
1218
|
'.xdrs/index.md': rootIndex(),
|
|
1151
1219
|
'.xdrs/_local/adrs/index.md': localAdrIndex([
|
|
@@ -1156,7 +1224,7 @@ test('reports article exceeding 5000 word limit', () => {
|
|
|
1156
1224
|
|
|
1157
1225
|
const result = lintWorkspace(workspaceRoot);
|
|
1158
1226
|
|
|
1159
|
-
expect(result.errors.join('\n')).toContain('Article exceeds maximum word count of
|
|
1227
|
+
expect(result.errors.join('\n')).toContain('Article exceeds maximum word count of 8000');
|
|
1160
1228
|
});
|
|
1161
1229
|
|
|
1162
1230
|
test('reports research exceeding 5000 word limit', () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xdrs-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.1",
|
|
4
4
|
"description": "A framework to structure, compile and distribute Architectural (ADR), Business (BDR), and Engineering (EDR) decision records contents so that AI agents and humans can reliably find and use them with hierarchical scopes and controlled rollout in the format of distributable versioned packages.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,58 +20,19 @@
|
|
|
20
20
|
"files": [
|
|
21
21
|
".xdrs/_core/**",
|
|
22
22
|
".xdrs/index.md",
|
|
23
|
+
".filedist-package.yml",
|
|
23
24
|
"package.json",
|
|
24
25
|
"AGENTS.md",
|
|
25
26
|
"bin/core.js",
|
|
26
|
-
|
|
27
|
+
"lib/**/*.js"
|
|
27
28
|
],
|
|
28
29
|
"devDependencies": {
|
|
29
30
|
"jest": "^29.7.0"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
32
|
-
"filedist": "^0.
|
|
33
|
+
"filedist": "^0.34.1",
|
|
33
34
|
"ignore": "^7.0.5",
|
|
34
35
|
"minimatch": "^10.2.5"
|
|
35
36
|
},
|
|
36
|
-
"filedist": {
|
|
37
|
-
"sets": [
|
|
38
|
-
{
|
|
39
|
-
"selector": {
|
|
40
|
-
"files": [
|
|
41
|
-
"AGENTS.md",
|
|
42
|
-
".xdrs/_core/**"
|
|
43
|
-
],
|
|
44
|
-
"exclude": [
|
|
45
|
-
"**/*.test.js",
|
|
46
|
-
"**/*.test.int.js",
|
|
47
|
-
"**/*.test.int.report"
|
|
48
|
-
]
|
|
49
|
-
},
|
|
50
|
-
"output": {
|
|
51
|
-
"path": ".",
|
|
52
|
-
"symlinks": [
|
|
53
|
-
{
|
|
54
|
-
"source": ".xdrs/**/skills/*",
|
|
55
|
-
"target": ".github/skills"
|
|
56
|
-
}
|
|
57
|
-
],
|
|
58
|
-
"gitignore": false
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
"selector": {
|
|
63
|
-
"files": [
|
|
64
|
-
".xdrs/index.md"
|
|
65
|
-
]
|
|
66
|
-
},
|
|
67
|
-
"output": {
|
|
68
|
-
"path": ".",
|
|
69
|
-
"gitignore": false,
|
|
70
|
-
"managed": false,
|
|
71
|
-
"keepExisting": true
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
]
|
|
75
|
-
},
|
|
76
37
|
"bin": "bin/core.js"
|
|
77
38
|
}
|