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.
@@ -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` | No | Short description of contexts this decision is applicable to. Keep it under 40 words. If omitted, the decision applies to all logically applicable elements. ONLY use this section if the usage is very specific to a specific case. Examples: `Only frontend code`, `JavaScript projects`. |
29
- | `valid-from` | No | 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. |
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: [Optional. Contexts this decision applies to, under 40 words]
87
- valid-from: [Optional. ISO date YYYY-MM-DD from when enforcement begins]
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 and have a backing research document]
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-descriptive-title-in-kebab-case]
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-short-descriptive-title-in-kebab-case
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-numbered-rules-for-strong-or-referenceable-policies]`
51
- - `_local-bdr-policy-003-data-retention-policy.[02-purge-schedule-for-pii]`
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 after the dot must match the heading text exactly, including the two-digit prefix and kebab-case title.
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-numbered-rules-for-strong-or-referenceable-policies
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-rule-numbering-must-be-stable
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-rule-body-must-use-normative-language
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-citations-must-use-exact-identifiers
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-short-descriptive-title-in-kebab-case`. 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.
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: `.policies/index.md`) starting from the working directory.
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: [Optional. Contexts this decision applies to, under 40 words]
111
- valid-from: [Optional. ISO date YYYY-MM-DD from when enforcement begins]
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
- - Include frontmatter `apply-to:` only when it adds value by narrowing the decision scope; omit it when the decision applies broadly.
136
- - Include frontmatter `valid-from:` only when there is a specific future enforcement date; omit it when the decision is immediately effective.
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 only when they add value, omitted entirely when not needed, and specific enough for a reader to decide whether the Policy is currently valid and applicable?
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/[number]-[skill-name]
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
- - Keep the article under 1950 words; move detailed content to Policies or Skills.
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 would exceed 1950 words** — move detailed content to a new Research, Skill, or Policy and link back.
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 = 5000;
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 !== undefined) {
393
- if (!isIsoDate(fm.validFrom)) {
394
- errors.push(`Policy frontmatter valid-from must be a valid ISO date YYYY-MM-DD: ${toDisplayPath(filePath)}`);
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 !== undefined) {
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 5000 word limit', () => {
1148
- const longBody = ('word '.repeat(5001)).trimEnd();
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 5000');
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.26.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
- "lib/**/*.js"
27
+ "lib/**/*.js"
27
28
  ],
28
29
  "devDependencies": {
29
30
  "jest": "^29.7.0"
30
31
  },
31
32
  "dependencies": {
32
- "filedist": "^0.26.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
  }