xdrs-core 0.49.1 → 0.51.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.
@@ -26,6 +26,7 @@ Foundational standards, principles, and guidelines.
26
26
  - [_core-adr-policy-018](principles/018-external-path-symlinks.md) - **External path symlinks** — How to make XDRS files accessible from paths outside the .xdrs/ root using symlinks
27
27
  - [_core-adr-policy-019](principles/019-compiled-scope-type.md) - **compiled scope type** — Defines the `compiled` scope type: scopes whose policies are compiled from external authoritative sources with strict source traceability and no invented content
28
28
  - [_core-adr-policy-020](principles/020-media-and-asset-standards.md) - **Media and asset standards** — Canonical diagram format preference order and non-Markdown asset rules for all XDRS document types
29
+ - [_core-adr-policy-021](principles/021-skill-bundling.md) - **Skill bundling** — Optional per-skill Makefile mechanism to stage a self-contained dist/ output for standalone distribution
29
30
 
30
31
  ## Skills
31
32
 
@@ -73,6 +73,19 @@ Examples:
73
73
  - `.xdrs/business-x/edrs/devops/skills/ci-pipeline-debug/SKILL.md`
74
74
  - `.xdrs/_local/adrs/principles/skills/my-nice-skill/SKILL.md`
75
75
 
76
+ Multiple skills under the same `[subject]/skills/` folder MAY share common instruction modules through a sibling `.assets/` directory placed directly under `skills/` (not inside any individual skill package) — for example `skills/.assets/shared-check.md`, referenced with a relative link from any skill in that folder. This keeps shared procedures DRY without duplicating instructions across skills.
77
+
78
+ A skill MAY optionally be distributed as a self-contained standalone package (for example, to share it outside this repository) using the bundling mechanism defined in [`_core-adr-policy-021`](021-skill-bundling.md). Bundling is optional; skills that are always consumed as part of the full package do not need it.
79
+
80
+ **Directory roles**
81
+
82
+ | Path | Purpose |
83
+ |---|---|
84
+ | `SKILL.md` | Required entry point: frontmatter + instructions. |
85
+ | `scripts/` | Optional executable scripts the agent may run. |
86
+ | `references/` | Optional deep reference material split out of `SKILL.md`. |
87
+ | `.assets/` | Optional images, templates, and other local resource files. |
88
+
76
89
  **Skill naming**
77
90
 
78
91
  Unlike Policies, Research, Articles, and Initiatives, skill packages are not auto-numbered. A skill is identified by a descriptive name, keeping it compatible with the wider agentskills ecosystem, where clients (including this framework's own agentskills-format consumers) expect a plain descriptive identifier rather than an auto-generated sequence number. The name MAY still contain digits, including as a prefix, when that is simply part of the descriptive name (e.g., `2fa-setup`). Each skill name MUST be unique within its `scope/type/subject/skills/` namespace; check for an existing skill with the same name before creating a new one.
@@ -82,23 +95,51 @@ Unlike Policies, Research, Articles, and Initiatives, skill packages are not aut
82
95
  ```
83
96
  ---
84
97
  name: [skill-name] # required: matches the folder name exactly; max 64 chars
85
- description: > # required: what the skill does AND when to activate it; max 1024 chars
98
+ description: > # required: what the skill does AND when to activate it; max 1024 chars (SHOULD stay near 250 when the trigger can be stated that tightly)
86
99
  Concise explanation of the skill and the situations in which an agent should load it.
87
100
  license: <license> # optional
88
- metadata: # optional: arbitrary key/value pairs
89
- author: <team-or-person>
90
- version: "1.0"
91
- compatibility: <env> # optional: system requirements or intended products
92
- allowed-tools: <tools> # optional (experimental): space-delimited pre-approved tools
101
+ metadata: # required
102
+ author: <team-or-person> # required
103
+ version: "1.0.0" # required: full semantic versioning
104
+ updated: YYYY-MM-DD # required: date of the last material content change
93
105
  ---
94
106
 
95
107
  ## Overview
96
108
 
97
109
  Brief description of the skill goal.
98
110
 
111
+ ### Inputs
112
+
113
+ #### Required
114
+ - Bare minimum the skill needs to start working, one bullet per item, or "None".
115
+
116
+ #### Optional
117
+ - Extra helpful context the skill can use if given, one bullet per item, or "None".
118
+
119
+ ### Outputs
120
+
121
+ #### Contents
122
+ - Generated files or chat-delivered results, one bullet per item, or "None".
123
+
124
+ #### Changes
125
+ - External system mutations that are part of the skill's main objective, one bullet per item, or "None".
126
+
127
+ ### Halt Conditions
128
+ - Specific triggers that make the skill stop before completing, one bullet per item, or "None".
129
+
130
+ ### User Interaction
131
+
132
+ Optional section: human-in-the-loop (HITL) exchanges during execution — a clarifying question or
133
+ an approval gate — one bullet per item, or "None". Omit this section entirely when none apply.
134
+
135
+ ### Runtime Requirements
136
+
137
+ Optional section: tooling, network access, or environment prerequisites beyond the LLM itself,
138
+ one bullet per item. Omit this section entirely when none apply.
139
+
99
140
  ## Instructions
100
141
 
101
- Step-by-step instructions the agent should follow.
142
+ Step-by-step instructions the agent should follow. State one clearly recommended approach first when several are viable; note alternatives briefly afterward.
102
143
 
103
144
  ## Examples
104
145
 
@@ -107,19 +148,58 @@ Concrete input/output examples that illustrate correct behavior.
107
148
  ## Edge Cases
108
149
 
109
150
  Known gotchas and how to handle them.
151
+
152
+ ## Anti-Patterns
153
+
154
+ At least 3 entries, each grounded in a real observed mistake:
155
+ - **Mistake:** what an agent or author incorrectly did.
156
+ **Why it happens:** the reasoning or shortcut that leads there.
157
+ **Instead:** the correct approach.
110
158
  ```
111
159
 
112
160
  Rules:
113
161
  - The `name` field MUST match the folder name exactly (e.g., `code-review`). This keeps skill identifiers simple and aligned with the filesystem hierarchy.
114
162
  - The directory name and the `name:` field MUST contain only lowercase alphanumeric characters and hyphens (e.g., `code-review`, `2fa-setup`).
115
- - `## Overview` SHOULD state the task objective, expected outcome, and relevant prerequisites or tools when they matter.
116
- - `## 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.
163
+ - `metadata` is REQUIRED. `metadata.version` MUST use full semantic versioning (`MAJOR.MINOR.PATCH`, e.g. `1.0.0`), consistent with [`_core-adr-policy-005`](005-semantic-versioning-for-xdrs-packages.md); `metadata.author` MUST be non-empty; `metadata.updated` MUST be an ISO `YYYY-MM-DD` date, refreshed whenever the skill's content materially changes.
164
+ - `description` SHOULD stay near 250 characters when the activation trigger can be stated that tightly, even though the hard cap remains 1024 characters — it is loaded into context on every activation scan.
165
+ - `## Overview` SHOULD state the task objective, expected outcome, and relevant prerequisites or tools when they matter, and MUST contain nested subsections, in order, for `### Inputs`, `### Outputs`, `### Halt Conditions`, then the optional `### User Interaction` and `### Runtime Requirements`.
166
+ - `### Inputs` MUST contain `#### Required` (the bare minimum needed to invoke the skill) then `#### Optional` (helpful extra context), in that order.
167
+ - `## Instructions` SHOULD state one clearly recommended approach first when multiple are viable, noting alternatives briefly afterward, and SHOULD include verification steps or acceptance criteria at the end of the task or major phases.
168
+ - `## Examples` SHOULD include 2-3 example prompts a user could give as input, alongside a short description of what to expect during execution and as output for each.
169
+ - `### Outputs` covers only end-objective results, not intermediary items, and MUST contain `#### Contents` (generated files or chat-delivered results) then `#### Changes` (external system mutations that are part of the main objective), in that order.
170
+ - `### Halt Conditions` MUST list this skill's specific stop-before-completing triggers, grounded in at least missing required input, dubious/ambiguous input, and insufficient agent confidence — distinct from `## Edge Cases` (activation/boundary conditions) and `## Anti-Patterns` (execution mistakes). A partial or empty result the skill still finishes and returns belongs in `### Outputs`, not `### Halt Conditions`.
171
+ - `### User Interaction` is OPTIONAL: documents human-in-the-loop (HITL) exchanges during execution — a clarifying question or an approval gate — distinct from `### Halt Conditions` (which stop execution rather than pause-and-resume it) and `### Runtime Requirements` (static prerequisites, not an interactive exchange); omit the section entirely when the skill has none.
172
+ - `### Runtime Requirements` is OPTIONAL: free-form bullets for tooling, network, or environment prerequisites beyond the LLM itself; omit the section entirely when none apply.
173
+ - Every bullet in `#### Required`, `#### Optional`, `#### Contents`, `#### Changes`, `### Halt Conditions`, and `### User Interaction` MUST be under 10 words, or the section MUST contain a single "None" bullet instead.
174
+ - `## Anti-Patterns` is REQUIRED with a minimum of 3 entries, each naming a Mistake, Why it happens, and the correct approach Instead, grounded in real observed issues rather than theoretical ones. Keep it distinct from `## Edge Cases`: Edge Cases are activation/boundary conditions, Anti-Patterns are execution mistakes.
175
+ - Key recommendations MAY be tagged `[PROVEN]`, `[RECOMMENDED]`, or `[EXPERIMENTAL]` when a skill offers several viable approaches at different confidence levels.
117
176
  - For diagram format preferences and non-Markdown asset rules, see [`_core-adr-policy-020`](020-media-and-asset-standards.md).
118
- - Keep `SKILL.md` under 6500 words. Move lengthy reference material to `references/`.
177
+ - `SKILL.md` MUST stay under 7000 words. Move lengthy reference material to `references/`; each `references/*.md` file MUST stay under 4000 words, splitting further when a single file grows unwieldy.
119
178
  - Use relative paths for all links; MUST NOT use absolute paths starting with `/`.
120
179
  - File names MUST be lowercase.
121
180
  - MUST NOT use emojis in skill content.
122
181
 
182
+ **Script standards**
183
+
184
+ When a skill includes `scripts/`:
185
+ - Each script MUST declare its runtime/interpreter at the top (shebang or equivalent header comment).
186
+ - SHOULD use the language already used by the consuming project when known, rather than mandating one language repo-wide.
187
+ - MUST avoid non-essential external dependencies, or document install steps in `SKILL.md` when unavoidable.
188
+ - SHOULD support both human-readable and machine-readable (JSON) output when producing analysis or report output.
189
+ - SHOULD stay single-purpose.
190
+
191
+ **Quality gate**
192
+
193
+ Before creating a skill, confirm it removes real ambiguity or repetitive effort compared to not having it. Skills that only restate a Policy, or that handle a one-off task unlikely to recur, SHOULD NOT be created.
194
+
195
+ **Clarify First**
196
+
197
+ Generative skills — those producing a deliverable document (Policy, Skill, Article, Research, Initiative, Presentation) — SHOULD list the 2-4 inputs they need confirmed (e.g., topic, scope, audience) and ask the user when any is unknown, stopping once those inputs are confirmed rather than over-interrogating. Skills that route, review, or report instead of authoring a new deliverable do not need this pattern.
198
+
199
+ **Halt behavior**
200
+
201
+ Skills MUST halt on missing required input, dubious/ambiguous input, or insufficient agent confidence, unless the user explicitly instructs the agent to proceed anyway. This override applies generally; a skill's own `## Halt Conditions` list does not need to restate it.
202
+
123
203
  **Validation**
124
204
 
125
205
  Use the [skills-ref](https://github.com/agentskills/agentskills/tree/main/skills-ref) CLI to validate before committing:
@@ -134,6 +214,10 @@ skills-ref validate .xdrs/[scope]/[type]/[subject]/skills/[skill-name]
134
214
  * Reason: Breaks the natural association between a decision (Policy) and the skill that implements it; makes navigation harder.
135
215
  * (CHOSEN) **agentskills-compatible packages co-located with XDRS** - Standardized format with scoped discovery and clear ownership.
136
216
  * Reason: Reuses proven agentskills tooling, aligns with the existing XDRS scope/subject hierarchy, and keeps skills close to the decisions they implement.
217
+ * (REJECTED) **Fully self-contained skills, no shared assets** - Every skill package repeats any instruction shared with another skill.
218
+ * Reason: Duplicates maintenance burden across skills and drifts out of sync over time.
219
+ * (CHOSEN) **Shared `.assets/` modules plus optional bundling** - Keep shared instruction modules DRY in-repo, and offer an optional per-skill bundling mechanism for standalone distribution.
220
+ * Reason: Preserves DRY authoring for the common case while still allowing a single skill to be distributed as a self-contained artifact when needed ([`_core-adr-policy-021`](021-skill-bundling.md)).
137
221
 
138
222
  ## References
139
223
 
@@ -142,4 +226,6 @@ skills-ref validate .xdrs/[scope]/[type]/[subject]/skills/[skill-name]
142
226
  - [skills-ref validation library](https://github.com/agentskills/agentskills/tree/main/skills-ref)
143
227
  - [_core-adr-policy-001 - XDRS standards](001-xdrs-standards.md)
144
228
  - [_core-adr-policy-004 - Article standards](004-article-standards.md)
229
+ - [_core-adr-policy-005 - Semantic versioning for XDRS packages](005-semantic-versioning-for-xdrs-packages.md)
145
230
  - [_core-adr-policy-006 - Research standards](006-research-standards.md)
231
+ - [_core-adr-policy-021 - Skill bundling](021-skill-bundling.md)
@@ -62,12 +62,13 @@ When multiple source entries point to the same content (e.g., a web page and its
62
62
 
63
63
  #### 07-compilation-meta-policy
64
64
 
65
- Before any compilation begins, at least one local meta-policy file named `NNN-core.md` MUST exist in a `[type]/principles/` directory of the target scope (e.g., `adrs/principles/001-core.md`). Compilation tools and agents MUST scan all type folders (`adrs`, `bdrs`, `edrs`) for such meta-policy files; each meta-policy governs compilation for its own type folder.
65
+ Before any compilation begins, at least one local meta-policy file named `NNN-core.md` MUST exist in a `[type]/principles/` directory of the target scope (e.g., `adrs/principles/001-core.md`). Compilation tools and agents MUST scan all type folders (`adrs`, `bdrs`, `edrs`) for such meta-policy files; each meta-policy governs compilation for its own type folder, including every subject compiled under it.
66
66
 
67
67
  The meta-policy MUST contain the following sections:
68
68
 
69
- - `## Sources` — one bullet per source using the format `- [web] https://...`, `- [git] git@...`, or `- [local] ./path`. Each source entry MAY include an inline description after the URL.
69
+ - `## Sources` — one bullet per source using the format `- [web] name: https://...`, `- [git] name: git@...`, or `- [local] name: ./path`. `name` MUST be a lowercase kebab-case slug (`[a-z0-9-]+`) that meaningfully identifies the source's organisation, project, or content (e.g., `github-official-docs`, `spreadsheet-team-123`). It is used as the folder name under `.assets/sources/` (rule 12) and as the path prefix in `## Source` sections (rule 10). Multiple bullets MAY share the same `name` to list alternate access methods for the same logical source — the preference order in rule 06 picks which one is actually fetched. Each source entry MAY include an inline description after the URL.
70
70
  - `## Selectors` — describes which portions of the fetched source to include or exclude, expressed as document sections, filename patterns, topics, or other criteria.
71
+ - `## Sync Settings` — governs re-synchronisation behaviour (rule 13). MUST contain a `Source re-sync period days: N` bullet, where `N` is a positive integer number of days. MAY contain a `Source storage: temporary` bullet; when absent, source storage defaults to persistent (rule 12).
71
72
 
72
73
  The meta-policy MAY also contain:
73
74
 
@@ -85,15 +86,15 @@ There is no fixed position for `compiled`-type scopes in the root `index.md`. Wh
85
86
 
86
87
  #### 10-source-section
87
88
 
88
- Every compiled policy MUST include a `## Source` section placed after the `## References` section (or after `## Decision Outcome` when no `## References` section is present). The section MUST list the relative file path(s) of the source document(s) used to produce the policy as plain text. Paths MUST NOT be written as markdown links, because the source files exist only inside a temporary local directory that is created during the compilation or review process.
89
+ Every compiled policy MUST include a `## Source` section placed after the `## References` section (or after `## Decision Outcome` when no `## References` section is present). The section MUST list the relative file path(s) of the source document(s) used to produce the policy as plain text, relative to the scope's `.assets/sources/` directory. Paths MUST NOT be written as markdown links: when source storage is temporary, the paths only exist for the duration of the compilation or review process; when source storage is persistent, `.assets/sources/` is exempt from orphan-asset tracking and, per rule 14, MUST NOT be linked to directly — these paths identify compilation inputs, not navigable or citable XDRS resources.
89
90
 
90
91
  Example:
91
92
 
92
93
  ```
93
94
  ## Source
94
95
 
95
- - source-1/standards/owasp-top-10-2021/A01-broken-access-control.md
96
- - source-2/docs/security-controls.html
96
+ - owasp-top10/standards/owasp-top-10-2021/A01-broken-access-control.md
97
+ - security-controls-docs/docs/security-controls.html
97
98
  ```
98
99
 
99
100
  #### 11-compilation-notes
@@ -109,6 +110,37 @@ All access control implementations MUST enforce the principle of least privilege
109
110
  **compilation-note:** derived from OWASP A01:2021 "How to Prevent", bullet 3 — "Deny by default".
110
111
  ```
111
112
 
113
+ #### 12-source-storage-and-tracking
114
+
115
+ Unless a meta-policy declares `Source storage: temporary`, fetched and selected source content (rule 13) MUST be persisted under `[type]/principles/.assets/sources/[name]/`, sibling to the governing meta-policy, where `[name]` is the source's slug from its `## Sources` bullet. This location is shared across every subject compiled under that meta-policy's type folder; it is not duplicated per subject. Persisted source content MUST be committed to version control and MUST NOT be gitignored.
116
+
117
+ When `Source storage: temporary` is declared, bulk fetched content MUST instead be written only to the ephemeral compilation working directory and removed at the end of the compilation run.
118
+
119
+ Regardless of storage mode, a tracking file `.assets/sources/[name]/source.md` MUST always be created and kept up to date, with the following format:
120
+
121
+ ```
122
+ # Source
123
+
124
+ last-fetch-timestamp: YYYY-MM-DD HH:MM:SS
125
+ last-compilation-timestamp: YYYY-MM-DD HH:MM:SS
126
+ ```
127
+
128
+ `last-fetch-timestamp` MUST be updated whenever that source is freshly fetched. `last-compilation-timestamp` MUST be updated only after a compilation cycle consuming that source completes lint and review successfully. If a meta-policy's `Source storage` setting changes between compilation runs, the next compilation MUST reconcile storage accordingly: switching to `temporary` MUST remove any previously persisted bulk content under `.assets/sources/[name]/` while keeping `source.md`; switching away from `temporary` MUST resume persisting bulk content going forward.
129
+
130
+ #### 13-selective-persistence-and-resync-optimization
131
+
132
+ Only content matched by `## Selectors` and actually used by at least one compiled policy's `## Source` section MAY be written to `.assets/sources/[name]/`. Content excluded by selectors, or that becomes unused after a re-sync, MUST be removed from persisted storage — `.assets/sources/[name]/` MUST NOT accumulate content beyond what compiled policies currently depend on.
133
+
134
+ Before fetching, compilation tools and agents MUST evaluate whether a re-sync is necessary: compare the elapsed days since `last-fetch-timestamp` against `Source re-sync period days`, and confirm `last-compilation-timestamp` is not older than `last-fetch-timestamp`. If every source governed by a meta-policy is within its re-sync period and already fully compiled, no fetch or recompilation is required unless explicitly requested. When a re-sync does proceed, newly fetched and selected content MUST be compared against the previous `.assets/sources/[name]/` snapshot (for example, by content hash) to scope which existing compiled policies need re-verification and which can be kept unchanged.
135
+
136
+ #### 14-source-documents-not-authoritative
137
+
138
+ By default, content persisted under `.assets/sources/` MUST NOT be treated as a source of truth, cited, or used directly to make architectural, business, or engineering decisions. Only compiled policies — the numbered Policy documents produced from this content — are authoritative for decision-making. Content under `.assets/sources/` exists to support synchronisation, diffing, and recompilation (rules 12 and 13); it is unstructured relative to compiled policies and MAY be misleading, inconsistent, or outdated.
139
+
140
+ An exception MUST be documented in a dedicated `[type]/principles/NNN-direct-source-usage.md` policy, mirroring the dedicated-file convention of rule 08. That policy MUST explicitly state when and how direct use of source documents is permitted. Absent such a policy, direct use of source documents for decisions is forbidden.
141
+
142
+ This rule governs reasoning and usage, not the document-link graph. Independently of this rule, and regardless of whether a `NNN-direct-source-usage.md` policy exists, no document MAY hyperlink directly into `.assets/sources/`; that restriction is enforced mechanically and addresses a separate, structural concern.
143
+
112
144
  ## References
113
145
 
114
146
  - [_core-adr-policy-008 - Policy structured standards](008-policy-structured-standards.md) — numbered rule format required for all policies in compiled scopes
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: _core-adr-policy-021-skill-bundling
3
+ description: Defines how a skill package MAY be bundled into a self-contained standalone distributable via a per-skill Makefile, including dist/ staging, recursive dependency delegation, and selective copying. Use when packaging a skill for standalone distribution outside the full xdrs-core package.
4
+ apply-to: Skill packages that need standalone distribution outside the full xdrs-core package
5
+ valid-from: 2026-09-19
6
+ ---
7
+
8
+ # _core-adr-policy-021: Skill bundling
9
+
10
+ ## Context and Problem Statement
11
+
12
+ Skills sometimes need to be shared or distributed as standalone artifacts outside the full `xdrs-core` package — for example, published separately or handed to a team that does not consume the whole repository. A skill that references shared `.assets/` modules (see `_core-adr-policy-003`) or embeds another skill as a dependency cannot simply be copied as a single `SKILL.md` file without breaking those references. No automated bundling utility exists yet, so each skill's own build process must resolve its dependencies; this means the same short recursive-copy pattern is duplicated across every bundling-enabled skill's `Makefile`, an accepted tradeoff until a shared build utility exists.
13
+
14
+ Question: How should a skill package that depends on shared assets or other skills be packaged into a self-contained standalone distributable?
15
+
16
+ ## Decision Outcome
17
+
18
+ **Optional per-skill `Makefile` that stages a self-contained `dist/` output, recursively delegating to each dependency's own bundling `Makefile`**
19
+
20
+ A skill MAY add its own `Makefile` to become bundling-enabled. Running `make build` inside the skill's folder stages a self-contained copy of the skill and everything it needs in a local, gitignored `dist/` folder, with exactly two top-level entries: `dist/build/` (the skill's own files, ready to use standalone) and `dist/<skill-name>.zip` (a packaged archive of it) — see Details for the exact layout. Inside `dist/build/`, the skill's own resources stay flat while every bundled dependency is corralled into its own `dist/<dependency-name>/` subfolder, so it is always immediately recognizable as a separate bundled/copied skill rather than merged into the skill's own files. When the skill embeds another skill as a dependency and that dependency is itself bundling-enabled, `build` delegates to the dependency's own `make build` and copies its output wholesale, so the mechanism nests recursively without a central build utility. This is independent of the repository-level `.filedist-package.yml` distribution flow used to publish whole XDRS packages; it operates entirely within a single skill's own folder.
21
+
22
+ ### Details
23
+
24
+ #### 01-bundling-is-optional
25
+ A skill MAY opt into standalone bundling by adding its own `Makefile` with `build`, `test`, and `clean` targets inside its own package folder (`skills/[skill-name]/Makefile`). Skills that are always consumed as part of the full `xdrs-core` package are not required to add one.
26
+
27
+ #### 02-dist-output-location
28
+ When present, the bundling `Makefile` MUST stage the skill's own unpacked files in `dist/build/`, relative to the root of the skill's own package (`skills/[skill-name]/dist/build/`). `dist/` MUST NOT be committed: a `.gitignore` entry covering `dist` (a bare `dist` or `**/dist` line) MUST exist in either the repository root `.gitignore` or a `.gitignore` local to the skill package. If the root `.gitignore` already covers it, no additional local entry is needed.
29
+
30
+ #### 03-works-without-bundling
31
+ A skill's `SKILL.md` MUST remain fully functional when consumed directly from its normal in-repo location, without ever running `make build`. The `dist/` output is an additional, optional artifact for standalone distribution; `SKILL.md` MUST NOT hard-depend on `dist/` existing.
32
+
33
+ #### 04-selective-copy
34
+ `make build` MUST copy only the files strictly necessary for the skill to run: its own `SKILL.md`, whichever of `scripts/`, `references/`, or `.assets/` it actually uses, and the specific shared modules or dependency skills it references. Tests, fixtures, or unrelated repository resources MUST NOT be copied into `dist/`.
35
+
36
+ #### 05-preserve-relative-paths
37
+ Files that belong to the skill's own package (`scripts/`, `references/`, its own `.assets/`) MUST be copied preserving their path relative to `SKILL.md` unchanged, since `SKILL.md` and its own files move into `dist/build/` together as a unit and their relative relationship to each other does not change. Links to a bundled dependency (a shared `.assets/` module elsewhere or another skill) are the one exception: `dist/build/` sits two directory levels below the original `SKILL.md`, so an unrewritten external link would no longer resolve once the target has been copied. `build` MUST rewrite such links inside the copied `SKILL.md` (and any other copied file that references them) to the flattened path defined by rule `06-recursive-delegation`, using a mechanical text substitution (for example `sed`).
38
+
39
+ #### 06-recursive-delegation
40
+ When a skill's `build` target embeds another skill as a dependency, `build` MUST stage that dependency under `dist/build/dist/<dependency-name>/` (a `dist/` subfolder nested inside `dist/build/` itself, not a sibling of it): if the dependency has its own bundling `Makefile`, run `$(MAKE) -C <dependency-path> build` first and copy the contents of its already-built `dist/build/` (not its whole `dist/` output, so its own zip is not carried along) into `dist/build/dist/<dependency-name>/`; if it does not, create `dist/build/dist/<dependency-name>/` and copy only its bare `SKILL.md` into it. Using the same `dist/build/dist/<dependency-name>/` shape in both cases keeps the bundle consistent regardless of whether the dependency is itself bundling-enabled, and — because the copied subtree carries its own already-rewritten links unchanged — nested transitive dependencies resolve correctly with no further rewriting. After staging, `build` MUST rewrite the original cross-package reference inside the copied `SKILL.md` (per rule `05-preserve-relative-paths`) to `dist/<dependency-name>/SKILL.md` (relative from inside `dist/build/`). A minimal illustrative pattern:
41
+
42
+ ```makefile
43
+ DEPS := ../shared-skill ../another-skill
44
+ BUILD := dist/build
45
+
46
+ build: clean
47
+ mkdir -p $(BUILD)
48
+ cp SKILL.md $(BUILD)/
49
+ @for d in $(DEPS); do \
50
+ name=$$(basename $$d); \
51
+ mkdir -p $(BUILD)/dist/$$name; \
52
+ if [ -f $$d/Makefile ]; then \
53
+ $(MAKE) -C $$d build; \
54
+ cp -R $$d/dist/build/. $(BUILD)/dist/$$name/; \
55
+ else \
56
+ cp $$d/SKILL.md $(BUILD)/dist/$$name/; \
57
+ fi; \
58
+ sed -i.bak "s#$$d/SKILL.md#dist/$$name/SKILL.md#g" $(BUILD)/SKILL.md && rm -f $(BUILD)/SKILL.md.bak; \
59
+ done
60
+
61
+ test: build
62
+ clean:
63
+ rm -rf dist
64
+ ```
65
+
66
+ #### 07-dependency-must-have-own-makefile
67
+ A skill that is itself listed as another skill's bundling dependency, and that has cross-skill references of its own, MUST have its own bundling `Makefile`. Without one, only its bare `SKILL.md` can be copied and its own references cannot be resolved automatically. This is not mechanically lint-enforceable; authors MUST self-check it when wiring a dependency into another skill's `Makefile`, and a `make test` run that exercises every resolved reference is the practical backstop for catching a violation.
68
+
69
+ #### 08-no-cycle-detection
70
+ The recursive delegation described in rule `06-recursive-delegation` has no cycle detection. Authors MUST NOT introduce circular bundling dependencies between skills, since that would cause unbounded recursive `make build` invocations.
71
+
72
+ #### 09-standard-targets
73
+ The bundling `Makefile` MUST expose `build`, `test`, and `clean` targets, mirroring the repository root `Makefile` convention. `clean` MUST remove only its own `dist/` and MUST NOT cascade into dependency skills' own `dist/` folders. `test` SHOULD cascade into each bundling-enabled dependency's own `test` target and SHOULD verify the skill still works from its bundled `dist/` output.
74
+
75
+ #### 10-zip-artifact
76
+ `make build` SHOULD also produce a single zip archive of the complete `dist/build/` tree (which already includes every bundled dependency folder from rule `06-recursive-delegation`) as `dist/<skill-name>.zip`. Since `dist/build/` is a subdirectory of `dist/`, the archive naturally cannot include itself: create it directly, for example with `cd dist/build && zip -rq ../<skill-name>.zip .`.
77
+
78
+ #### 11-build-depends-on-clean
79
+ The `build` target MUST depend on the `clean` target (`build: clean`) so every build starts from a clean `dist/`, instead of duplicating `clean`'s removal logic inline.
80
+
81
+ ## References
82
+
83
+ - [_core-adr-policy-001 - XDRS standards](001-xdrs-standards.md)
84
+ - [_core-adr-policy-003 - Skill standards](003-skill-standards.md)
85
+ - [_core-adr-policy-008 - Policy structured standards](008-policy-structured-standards.md)
@@ -4,12 +4,49 @@ description: >
4
4
  Compiles or updates any scope declaring `scope-type: compiled` from its configured external sources. Reads compilation meta-policies to discover sources, fetches content (git clone, local copy, or web scrape), plans policy changes, migrates policies one at a time with structured format, `## Source` sections, and `**compilation-note:**` markers, then runs lint and review. Documents source inconsistencies without inventing fixes. Activate when the user asks to compile, update, sync, refresh, or recompile a compiled scope.
5
5
  metadata:
6
6
  author: flaviostutz
7
- version: "1.0"
7
+ version: "1.0.0"
8
+ updated: 2026-09-19
8
9
  ---
9
10
 
10
11
  ## Overview
11
12
 
12
- Performs a full compilation cycle for any scope declaring `scope-type: compiled`: discovers compilation meta-policies across all type folders, fetches sources into a temporary directory, plans which policies to create, update, or remove, migrates them one at a time with full source traceability, runs lint and review, and documents any inconsistencies found in the source. Works for both initial compilation and re-compilation (updates). Requires `_core-adr-policy-019-compiled-scope-type` to be present in the workspace.
13
+ Performs a full compilation cycle for any scope declaring `scope-type: compiled`: discovers compilation meta-policies across all type folders, checks whether each governed source is already in sync before doing any work, fetches due sources into a temporary staging directory, plans which policies to create, update, or remove, migrates them one at a time with full source traceability, runs lint and review, persists selected source content and updates sync tracking, and documents any inconsistencies found in the source. Works for both initial compilation and re-compilation (updates). By default, fetched source content used to compile policies is persisted under `.assets/sources/[name]/` in the scope (see `_core-adr-policy-019` rules 12–13); this content is never authoritative for decisions (rule 14). Requires `_core-adr-policy-019-compiled-scope-type` to be present in the workspace.
14
+
15
+ ### Inputs
16
+
17
+ #### Required
18
+
19
+ - Name of the compiled scope to sync.
20
+
21
+ #### Optional
22
+
23
+ - Force-refetch flag to bypass the re-sync short-circuit.
24
+
25
+ ### Outputs
26
+
27
+ #### Contents
28
+
29
+ - Updated compiled scope, or a no-op already-in-sync report.
30
+
31
+ #### Changes
32
+
33
+ - Policy files created, updated, or removed.
34
+
35
+ ### Halt Conditions
36
+
37
+ - No local meta-policy found in the scope.
38
+ - Scope does not declare scope-type: compiled.
39
+ - A source cannot be fetched or converted.
40
+
41
+ ### User Interaction
42
+
43
+ - Confirmation of the CREATE/UPDATE/REMOVE plan before migrating.
44
+
45
+ ### Runtime Requirements
46
+
47
+ - Network/git access for remote sources.
48
+ - `uvx markitdown` for non-Markdown source conversion, if needed.
49
+ - `npx @playwright/cli` as a web-scraping fallback.
13
50
 
14
51
  ## Instructions
15
52
 
@@ -19,39 +56,51 @@ Performs a full compilation cycle for any scope declaring `scope-type: compiled`
19
56
  2. Scan ALL type folders (`adrs/`, `bdrs/`, `edrs/`) inside the target scope for local meta-policy files whose filename matches `NNN-core.md` in `[type]/principles/`. Collect every match.
20
57
  3. If no meta-policy is found in any type folder, output: `FAIL — Compilation cannot proceed: no local meta-policy NNN-core.md found in any [type]/principles/ folder of [scope-name]. Create it first with ## Sources and ## Selectors sections per _core-adr-policy-019 rule 07.`
21
58
  4. Read every found meta-policy fully. For each, extract:
22
- - **Sources**: parse all `- [web] ...`, `- [git] ...`, `- [local] ...` bullet entries from the `## Sources` section.
23
- - **Selectors**: read the `## Selectors` section content (used in Phase 2).
24
- - **Fetch Procedures**: read the `## Fetch Procedures` section if present (used in Phase 1).
25
- - **Compilation Notes**: read if present (used in Phase 2–3).
26
- - **Review Notes**: read if present (used in Phase 6).
27
-
28
- ### Phase 1: Fetch Sources
29
-
30
- 1. Create a temporary directory `.tmp/compilation-[YYYYMMDDHHMMSS]/` in the workspace root.
31
- 2. For each source discovered in Phase 0, fetch in the following preference order (first available wins; if all equivalent URLs are listed, try each in order):
32
- - **Git URL** (`- [git] ...`): run `git clone --depth=1 [url] .tmp/compilation-[ts]/source-N/`. If `git` is not available or the clone fails, fall back to the next option.
33
- - **Local folder** (`- [local] ...`): copy the folder contents to `.tmp/compilation-[ts]/source-N/`.
34
- - **Web URL** (`- [web] ...`): before scraping, search the workspace for a skill specialized in fetching content from this URL or website domain (e.g., a skill whose description or name references the domain, the product, or the content type). Some websites require special handling — SSO, client certificates, shadow DOM, iframes, CAPTCHAs, or other quirks. If a specialized fetch skill is found, follow it to retrieve the content. If no specialized skill exists, fall back to `npx --package=@playwright/cli@latest playwright-cli`; run with `--help` to confirm available commands and save output as `.html` file(s) in `.tmp/compilation-[ts]/source-N/`.
59
+ - **Sources**: parse all `- [web] ...`, `- [git] ...`, `- [local] ...` bullet entries from the `## Sources` section, including each source's `name` slug (per `_core-adr-policy-019` rule 07).
60
+ - **Selectors**: read the `## Selectors` section content (used in Phase 3).
61
+ - **Sync Settings**: parse `Source re-sync period days` and, if present, `Source storage: temporary` from the `## Sync Settings` section (used in Phase 1 and Phase 9).
62
+ - **Fetch Procedures**: read the `## Fetch Procedures` section if present (used in Phase 2).
63
+ - **Compilation Notes**: read if present (used in Phase 3–4).
64
+ - **Review Notes**: read if present (used in Phase 7).
65
+
66
+ ### Phase 1: Check Sync Necessity
67
+
68
+ 1. For each source `name` extracted in Phase 0, look for `.assets/sources/[name]/source.md` in the governed type folder.
69
+ 2. If `source.md` does not exist for a source, that source has never been synced — it is due for Phase 2.
70
+ 3. If `source.md` exists, read its `last-fetch-timestamp` and `last-compilation-timestamp`. Compute the elapsed days since `last-fetch-timestamp`. That source is due for Phase 2 if either is true: the elapsed days exceed the meta-policy's `Source re-sync period days`, or `last-compilation-timestamp` is older than `last-fetch-timestamp` (a previous run fetched but never finished compiling).
71
+ 4. If the input includes an explicit force-refetch/recompile request (see Inputs > Optional), treat every source as due regardless of timestamps.
72
+ 5. If no source across any governed meta-policy is due, output: `OK — [scope-name] is already in sync. No action taken.` and halt — do not proceed to later phases.
73
+ 6. Otherwise, proceed to Phase 2, but scope fetching and compilation to only the meta-policies and sources that are due; meta-policies with no due sources MAY be skipped entirely.
74
+
75
+ ### Phase 2: Fetch Sources
76
+
77
+ 1. Create a temporary directory `.tmp/compilation-[YYYYMMDDHHMMSS]/staging/` in the workspace root.
78
+ 2. For each due source (from Phase 1), fetch in the following preference order (first available wins; if all equivalent URLs are listed, try each in order):
79
+ - **Git URL** (`- [git] ...`): run `git clone --depth=1 [url] .tmp/compilation-[ts]/staging/[name]/`. If `git` is not available or the clone fails, fall back to the next option.
80
+ - **Local folder** (`- [local] ...`): copy the folder contents to `.tmp/compilation-[ts]/staging/[name]/`.
81
+ - **Web URL** (`- [web] ...`): before scraping, search the workspace for a skill specialized in fetching content from this URL or website domain (e.g., a skill whose description or name references the domain, the product, or the content type). Some websites require special handling — SSO, client certificates, shadow DOM, iframes, CAPTCHAs, or other quirks. If a specialized fetch skill is found, follow it to retrieve the content. If no specialized skill exists, fall back to `npx --package=@playwright/cli@latest playwright-cli`; run with `--help` to confirm available commands and save output as `.html` file(s) in `.tmp/compilation-[ts]/staging/[name]/`.
35
82
  3. If any source cannot be fetched via any listed option, report the failure and continue with remaining sources. Do not abort the entire compilation for a single failed source.
36
- 4. Convert non-markdown documents found in the fetched source directories. Use only the format converters actually needed:
83
+ 4. Immediately after a source is fetched successfully, create `.assets/sources/[name]/source.md` if absent and update its `last-fetch-timestamp` to the current time — this happens regardless of the `Source storage` setting, since the tracking file always persists per `_core-adr-policy-019` rule 12.
84
+ 5. Convert non-markdown documents found in the fetched source directories. Use only the format converters actually needed:
37
85
  - PDF files: `uvx markitdown[pdf] <file> -o <output>.md`
38
86
  - XLSX files: `uvx markitdown[xlsx] <file> -o <output>.md`
39
87
  - DOCX files: `uvx markitdown[docx] <file> -o <output>.md`
40
88
  - PPTX files: `uvx markitdown[pptx] <file> -o <output>.md`
41
89
  - HTML files saved from web scraping: `uvx markitdown <file.html> -o <output>.md`
42
90
 
43
- ### Phase 2: Plan Policies
91
+ ### Phase 3: Plan Policies
44
92
 
45
- 1. For each type folder governed by a meta-policy (from Phase 0), apply the `## Selectors` rules to the fetched content to determine which portions to include.
93
+ 1. For each type folder governed by a meta-policy (from Phase 0), apply the `## Selectors` rules to the fetched staging content to determine which portions to include.
46
94
  2. List all existing policies in the scope under each governed type folder.
47
- 3. Analyse the selected content and produce a TODO list showing for each expected policy:
95
+ 3. If `.assets/sources/[name]/` already holds a previous persisted snapshot, diff the newly selected staging content against it (for example, by content hash per file) to pre-seed which policies are likely unaffected.
96
+ 4. Analyse the selected content and produce a TODO list showing for each expected policy:
48
97
  - **CREATE** — new policy to be compiled from source (does not yet exist in scope)
49
98
  - **UPDATE** — existing policy whose source content has changed
50
99
  - **REMOVE** — existing policy whose source content no longer exists or is excluded by selectors
51
- - **KEEP** — existing policy that is up to date; no action needed
52
- 4. Present the TODO list to the user and wait for confirmation before proceeding to Phase 3.
100
+ - **KEEP** — existing policy that is up to date; no action needed (default for policies whose source content is unchanged per the step 3 diff)
101
+ 5. Present the TODO list to the user and wait for confirmation before proceeding to Phase 4.
53
102
 
54
- ### Phase 3: Migrate Policies (one at a time)
103
+ ### Phase 4: Migrate Policies (one at a time)
55
104
 
56
105
  For each TODO item marked CREATE or UPDATE, in sequence:
57
106
 
@@ -62,21 +111,21 @@ For each TODO item marked CREATE or UPDATE, in sequence:
62
111
 
63
112
  2. **Add a `**compilation-note:**` marker** inside a rule body only when the mapping from source to rule is not obvious — for example: indirect references, conclusions drawn by connecting multiple source sections, interpretations that required judgment, or cases where the same source passage could be read differently. Do NOT add a marker when the rule is a direct, literal transcription of a single source statement. Place the marker as a new sentence at the end of the rule body. Example:
64
113
  ```
65
- All API keys MUST be rotated every 90 days. **compilation-note:** derived from [source-1/security/api-guidelines.md section 4.2] — "Keys should be invalidated and replaced quarterly"; frequency inferred as 90 days from the term "quarterly".
114
+ All API keys MUST be rotated every 90 days. **compilation-note:** derived from [api-guidelines/security/api-guidelines.md section 4.2] — "Keys should be invalidated and replaced quarterly"; frequency inferred as 90 days from the term "quarterly".
66
115
  ```
67
116
 
68
- 3. **Add a `## Source` section** as the LAST section of the policy (after `## References` if present, otherwise after `## Decision Outcome`). List the relative file path(s) of the source document(s) as plain text — NOT as markdown links. Paths are relative to the temporary source directory (e.g., `source-1/docs/chapter-3.md`).
117
+ 3. **Add a `## Source` section** as the LAST section of the policy (after `## References` if present, otherwise after `## Decision Outcome`). List the relative file path(s) of the source document(s) as plain text — NOT as markdown links. Paths are relative to `.assets/sources/` and use the source's `name` slug as their first segment (e.g., `api-guidelines/standards/section-4/api-security.md`), regardless of whether storage is currently persistent or temporary.
69
118
  ```
70
119
  ## Source
71
120
 
72
- - source-1/standards/section-4/api-security.md
121
+ - api-guidelines/standards/section-4/api-security.md
73
122
  ```
74
123
 
75
124
  4. For REMOVE items: delete the policy file and remove its entry from the type's `index.md`.
76
125
 
77
- 5. Note any content in the source that is inconsistent, contradictory, or cannot be faithfully expressed as a valid XDRS policy. Record these for Phase 7.
126
+ 5. Note any content in the source that is inconsistent, contradictory, or cannot be faithfully expressed as a valid XDRS policy. Record these for Phase 8.
78
127
 
79
- ### Phase 4: Verify Each Policy
128
+ ### Phase 5: Verify Each Policy
80
129
 
81
130
  After writing each policy:
82
131
 
@@ -84,25 +133,25 @@ After writing each policy:
84
133
  2. Confirm the policy uses structured numbered rule blocks (`_core-adr-policy-008`).
85
134
  3. Confirm `**compilation-note:**` markers are present for every rule whose mapping from source is non-obvious (indirect references, multi-source conclusions, interpretations requiring judgment). Direct literal transcriptions do not require a marker.
86
135
  4. Confirm no normative statements are present that cannot be traced to the listed source file.
87
- 5. Add any new inconsistencies found to the list for Phase 7.
136
+ 5. Add any new inconsistencies found to the list for Phase 8.
88
137
 
89
- ### Phase 5: Lint
138
+ ### Phase 6: Lint
90
139
 
91
140
  1. Run `npx xdrs-core lint` from the workspace root (or `make lint` if a `Makefile` is present with a `lint` target).
92
141
  2. Review all reported errors and warnings.
93
142
  3. Fix only mechanical and structural errors (missing required frontmatter fields, naming violations, index link mismatches). Do NOT invent content to satisfy content-level findings.
94
143
  4. Re-run lint after fixes until it passes or only unfixable findings remain.
95
144
 
96
- ### Phase 6: Review
145
+ ### Phase 7: Review
97
146
 
98
147
  1. Read and follow `.xdrs/_core/adrs/principles/skills/review/SKILL.md` fully, scoped to the compiled scope.
99
148
  2. Apply any review notes from the meta-policy's `## Review Notes` section as additional mandatory conventions during this review.
100
149
  3. Fix only mechanical and structural findings from the review. Do NOT invent content to resolve content-level findings.
101
- 4. Any review findings that require inventing or guessing content MUST be recorded as inconsistencies in Phase 7.
150
+ 4. Any review findings that require inventing or guessing content MUST be recorded as inconsistencies in Phase 8.
102
151
 
103
- ### Phase 7: Document Inconsistencies
152
+ ### Phase 8: Document Inconsistencies
104
153
 
105
- 1. Collect all inconsistencies noted during Phases 3, 4, and 6.
154
+ 1. Collect all inconsistencies noted during Phases 4, 5, and 7.
106
155
  2. If any inconsistencies exist:
107
156
  - Determine the next available policy number in the `001–100` principles block for the relevant type folder.
108
157
  - Create or update `[type]/principles/NNN-inconsistencies-from-source.md` in the scope.
@@ -111,11 +160,46 @@ After writing each policy:
111
160
  - Do NOT propose or include fixes.
112
161
  3. If no inconsistencies exist, report that the compilation is clean.
113
162
 
114
- ### Phase 8: Cleanup
163
+ ### Phase 9: Persist Sources and Update Tracking
115
164
 
116
- 1. Remove the temporary directory `.tmp/compilation-[ts]/` created in Phase 1.
165
+ 1. For each meta-policy and source processed in this run, check its `Source storage` setting.
166
+ 2. If storage is persistent (the default): replace the contents of `.assets/sources/[name]/` (excluding `source.md`) with the staged content actually selected and used in Phase 3–4 — remove any previously persisted file that is no longer selected or used, per `_core-adr-policy-019` rule 13.
167
+ 3. If storage is `temporary`: do not copy any bulk staged content into `.assets/sources/[name]/`; only `source.md` lives there.
168
+ 4. For every source processed in this run, update `.assets/sources/[name]/source.md`'s `last-compilation-timestamp` to the current time — this step only runs after Phase 6 (Lint) and Phase 7 (Review) both pass for the policies depending on that source.
169
+ 5. If a source's `Source storage` setting changed since its last run, reconcile per `_core-adr-policy-019` rule 12: switching to `temporary` removes previously persisted bulk content (keeping `source.md`); switching away from `temporary` begins persisting bulk content from this run onward.
170
+
171
+ ### Phase 10: Cleanup
172
+
173
+ 1. Remove the temporary staging directory `.tmp/compilation-[ts]/` created in Phase 2. Never remove or modify persisted content under `.assets/sources/` — that is governed solely by Phase 9.
117
174
  2. Report a compilation summary:
118
175
  - Policies created, updated, removed.
119
176
  - Inconsistencies documented (with file path).
120
177
  - Any sources that could not be fetched.
121
178
  - Lint and review pass/fail status.
179
+ - Sources persisted, kept temporary, or skipped as already in sync.
180
+
181
+ ## Anti-Patterns
182
+
183
+ - **Mistake:** Inventing content to fill gaps when source material is incomplete or ambiguous.
184
+ **Why it happens:** The agent wants to produce a "complete" policy and fills gaps with plausible-sounding text.
185
+ **Instead:** Transcribe faithfully, preserve ambiguities as-is, and record inconsistencies in Phase 8 instead of guessing.
186
+
187
+ - **Mistake:** Skipping the Phase 3 confirmation and migrating policies before the user approves the CREATE/UPDATE/REMOVE plan.
188
+ **Why it happens:** Momentum from prior compilations makes the plan feel obviously correct.
189
+ **Instead:** Always present the TODO list and wait for explicit confirmation before Phase 4.
190
+
191
+ - **Mistake:** Leaving the temporary `.tmp/compilation-[ts]/` directory behind after a run.
192
+ **Why it happens:** Phase 10 cleanup is easy to forget once the summary is reported.
193
+ **Instead:** Always remove the temporary directory as the first Phase 10 step, even on partial failures.
194
+
195
+ - **Mistake:** Persisting every fetched file under `.assets/sources/[name]/`, including content excluded by selectors or no longer used by any compiled policy.
196
+ **Why it happens:** It feels safer to keep everything "just in case" rather than compute what is actually still used.
197
+ **Instead:** Persist only Selector-matched content actually referenced by a compiled policy's `## Source` section, per `_core-adr-policy-019` rule 13; remove the rest during Phase 9.
198
+
199
+ - **Mistake:** Skipping Phase 1 and always re-fetching and recompiling, even when every source is well within its re-sync period.
200
+ **Why it happens:** Re-running the full cycle unconditionally feels more thorough or "safe".
201
+ **Instead:** Always check `.assets/sources/[name]/source.md` timestamps against `Source re-sync period days` first, and short-circuit with a no-op report when nothing is due.
202
+
203
+ - **Mistake:** Reading or citing content under `.assets/sources/` as if it were an authoritative policy, or adding a markdown link to it from another document.
204
+ **Why it happens:** The raw source content is readily available and often more detailed than the compiled policy.
205
+ **Instead:** Treat only compiled policies as authoritative per `_core-adr-policy-019` rule 14; source content exists solely to support fetch/diff/recompilation, and linking to it is also forbidden mechanically by lint.