eslint-plugin-traceability 1.10.1 → 1.11.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +2 -2
  2. package/README.md +3 -2
  3. package/lib/src/maintenance/cli.js +12 -12
  4. package/lib/src/maintenance/detect.js +19 -19
  5. package/lib/src/maintenance/flags.js +111 -25
  6. package/lib/src/rules/helpers/require-story-core.d.ts +55 -9
  7. package/lib/src/rules/helpers/require-story-core.js +85 -62
  8. package/lib/src/rules/helpers/require-story-helpers.d.ts +27 -48
  9. package/lib/src/rules/helpers/require-story-helpers.js +154 -116
  10. package/lib/src/rules/helpers/require-story-io.js +51 -31
  11. package/lib/src/rules/helpers/require-story-visitors.js +47 -6
  12. package/lib/src/rules/helpers/valid-annotation-format-validators.js +5 -1
  13. package/lib/src/rules/helpers/valid-annotation-options.d.ts +9 -0
  14. package/lib/src/rules/helpers/valid-annotation-options.js +67 -20
  15. package/lib/src/rules/helpers/valid-annotation-utils.js +31 -31
  16. package/lib/src/rules/helpers/valid-story-reference-helpers.js +19 -19
  17. package/lib/src/rules/prefer-implements-annotation.js +29 -1
  18. package/lib/src/rules/require-story-annotation.js +15 -0
  19. package/lib/src/rules/require-test-traceability.js +1 -6
  20. package/lib/src/utils/annotation-checker.js +32 -8
  21. package/lib/src/utils/reqAnnotationDetection.js +36 -22
  22. package/lib/tests/cli-error-handling.test.js +1 -0
  23. package/lib/tests/config/eslint-config-validation.test.d.ts +8 -0
  24. package/lib/tests/config/eslint-config-validation.test.js +8 -0
  25. package/lib/tests/config/flat-config-presets-integration.test.js +1 -3
  26. package/lib/tests/config/require-story-annotation-config.test.d.ts +9 -0
  27. package/lib/tests/config/require-story-annotation-config.test.js +9 -0
  28. package/lib/tests/integration/cli-integration.test.js +9 -1
  29. package/lib/tests/maintenance/batch.test.js +1 -0
  30. package/lib/tests/maintenance/cli.test.js +1 -0
  31. package/lib/tests/maintenance/detect-isolated.test.js +1 -0
  32. package/lib/tests/maintenance/detect.test.js +1 -0
  33. package/lib/tests/maintenance/index.test.js +1 -0
  34. package/lib/tests/maintenance/report.test.js +1 -0
  35. package/lib/tests/maintenance/update-isolated.test.js +1 -0
  36. package/lib/tests/maintenance/update.test.js +1 -0
  37. package/lib/tests/perf/maintenance-cli-large-workspace.test.d.ts +1 -0
  38. package/lib/tests/perf/maintenance-cli-large-workspace.test.js +130 -0
  39. package/lib/tests/perf/maintenance-large-workspace.test.d.ts +1 -0
  40. package/lib/tests/perf/maintenance-large-workspace.test.js +149 -0
  41. package/lib/tests/plugin-default-export-and-configs.test.js +2 -0
  42. package/lib/tests/plugin-setup-error.test.d.ts +1 -0
  43. package/lib/tests/plugin-setup-error.test.js +1 -0
  44. package/lib/tests/plugin-setup.test.js +1 -1
  45. package/lib/tests/rules/auto-fix-behavior-008.test.js +39 -0
  46. package/lib/tests/rules/error-reporting.test.js +1 -0
  47. package/lib/tests/rules/prefer-implements-annotation.test.js +8 -0
  48. package/lib/tests/rules/require-branch-annotation.test.js +2 -0
  49. package/lib/tests/rules/require-story-core-edgecases.test.js +1 -0
  50. package/lib/tests/rules/require-story-core.autofix.test.js +10 -3
  51. package/lib/tests/rules/require-story-core.test.js +14 -7
  52. package/lib/tests/rules/require-story-helpers-edgecases.test.d.ts +1 -0
  53. package/lib/tests/rules/require-story-helpers-edgecases.test.js +2 -1
  54. package/lib/tests/rules/require-story-helpers.test.js +18 -11
  55. package/lib/tests/rules/require-story-io-behavior.test.d.ts +1 -0
  56. package/lib/tests/rules/require-story-io-behavior.test.js +1 -0
  57. package/lib/tests/rules/require-story-io.edgecases.test.d.ts +1 -0
  58. package/lib/tests/rules/require-story-io.edgecases.test.js +1 -0
  59. package/lib/tests/rules/require-story-visitors-edgecases.test.d.ts +1 -0
  60. package/lib/tests/rules/require-story-visitors-edgecases.test.js +1 -0
  61. package/lib/tests/rules/valid-story-reference.test.js +2 -0
  62. package/lib/tests/utils/annotation-checker.test.js +2 -1
  63. package/lib/tests/utils/branch-annotation-helpers.test.js +2 -1
  64. package/lib/tests/utils/require-story-core-test-helpers.d.ts +1 -1
  65. package/lib/tests/utils/require-story-core-test-helpers.js +16 -16
  66. package/lib/tests/utils/temp-dir-helpers.js +1 -1
  67. package/package.json +9 -2
  68. package/user-docs/api-reference.md +123 -12
  69. package/user-docs/examples.md +41 -0
  70. package/user-docs/migration-guide.md +36 -3
@@ -19,12 +19,15 @@ The `prefer-implements-annotation` rule is an **opt-in migration helper** that i
19
19
 
20
20
  ### traceability/require-story-annotation
21
21
 
22
- Description: Ensures every function declaration has a JSDoc comment with an `@story` annotation referencing the related user story. When you adopt multi-story `@supports` annotations, this rule also accepts `@supports` as an alternative way to prove story coverage, so either `@story` or at least one `@supports` tag will satisfy the presence check. When run with `--fix`, the rule inserts a single-line placeholder JSDoc `@story` annotation above missing functions, methods, TypeScript declare functions, and interface method signatures using a built-in template aligned with Story 008.0. This template is currently fixed but structured for future configurability, and fixes are strictly limited to adding this placeholder annotation without altering the function body or changing any runtime behavior. Selective enabling of different auto-fix behaviors (such as applying fixes only to certain scopes or node types) is planned for a future version.
22
+ Description: Ensures every function declaration has a JSDoc comment with an `@story` annotation referencing the related user story. When you adopt multi-story `@supports` annotations, this rule also accepts `@supports` as an alternative way to prove story coverage, so either `@story` or at least one `@supports` tag will satisfy the presence check. When run with `--fix`, the rule inserts a single-line placeholder JSDoc `@story` annotation above missing functions, methods, TypeScript declare functions, and interface method signatures using a built-in template aligned with Story 008.0. This template is now configurable on a per-rule basis, and the rule exposes an explicit auto-fix toggle so you can choose between diagnostic-only behavior and automatic placeholder insertion. The default template remains aligned with Story 008.0, but you can now customize it per rule configuration and optionally disable auto-fix entirely when you only want diagnostics without edits.
23
23
 
24
24
  Options:
25
25
 
26
26
  - `scope` (string[], optional) – Controls which function-like node types are required to have @story annotations. Allowed values: "FunctionDeclaration", "FunctionExpression", "MethodDefinition", "TSDeclareFunction", "TSMethodSignature". Default: ["FunctionDeclaration", "FunctionExpression", "MethodDefinition", "TSDeclareFunction", "TSMethodSignature"].
27
27
  - `exportPriority` ("all" | "exported" | "non-exported", optional) – Controls whether the rule checks all functions, only exported ones, or only non-exported ones. Default: "all".
28
+ - `annotationTemplate` (string, optional) – Overrides the default placeholder JSDoc used when inserting missing `@story` annotations for functions and non-method constructs. When omitted or blank, the built-in template from Story 008.0 is used.
29
+ - `methodAnnotationTemplate` (string, optional) – Overrides the default placeholder JSDoc used when inserting missing `@story` annotations for class methods and TypeScript method signatures. When omitted or blank, falls back to `annotationTemplate` if provided, otherwise the built-in template.
30
+ - `autoFix` (boolean, optional) – When set to `false`, disables all automatic fix behavior for this rule while retaining its suggestions and diagnostics. When omitted or `true`, the rule behaves as before, inserting placeholder annotations in `--fix` mode.
28
31
 
29
32
  Default Severity: `error`
30
33
  Example:
@@ -83,18 +86,19 @@ if (error) {
83
86
 
84
87
  ### traceability/valid-annotation-format
85
88
 
86
- Description: Validates that all traceability annotations (`@story`, `@req`) follow the correct JSDoc or inline comment format. When run with `--fix`, the rule limits changes to safe `@story` path suffix normalization only—for example, adding `.md` when the path ends with `.story`, or adding `.story.md` when the base path has no extension—using targeted replacements implemented in the `getFixedStoryPath` and `reportInvalidStoryFormatWithFix` helpers. It does not change directories, infer new story names, or modify any surrounding comment text or whitespace, in line with Story 008.0; more advanced path normalization strategies and selective toggles to enable or disable specific auto-fix behaviors are not yet implemented.
89
+ Description: Validates that all traceability annotations (`@story`, `@req`) follow the correct JSDoc or inline comment format. When run with `--fix`, the rule limits changes to safe `@story` path suffix normalization only—for example, adding `.md` when the path ends with `.story`, or adding `.story.md` when the base path has no extension—using targeted replacements implemented in the `getFixedStoryPath` and `reportInvalidStoryFormatWithFix` helpers. It does not change directories, infer new story names, or modify any surrounding comment text or whitespace, in line with Story 008.0. Selective disabling of this suffix-normalization auto-fix behavior is available via the `autoFix` option, which defaults to `true` for backward compatibility.
87
90
 
88
91
  Options:
89
92
 
90
93
  This rule accepts an optional configuration object. The primary configuration shape is **nested**:
91
94
 
92
95
  - `story` (object, optional) – Configuration for `@story` values.
93
- - `pattern` (string, optional) – A JavaScript regular expression **source** (without leading and trailing `/`) that all `@story` values must match. If provided, the rule validates each `@story` against this pattern in addition to its built‑in structural checks. By default, the plugin uses a pattern equivalent to `^docs/stories/.*\.story\.md$`, which matches a typical project convention such as `docs/stories/<name>.story.md`; you can override this to match however your own project organizes story files.
94
- - `example` (string, optional) – A short example `@story` path shown in error messages when `story.pattern` is configured. The built-in default example is `"docs/stories/001.0-EXAMPLE.story.md"`, intended as a generic illustration of a project story file, and does not refer to this plugin’s internal documentation.
96
+ - `pattern` (string, optional) – A JavaScript regular expression **source** (without leading and trailing `/`) that all `@story` values must match. If provided, the rule validates each `@story` against this pattern in addition to its built‑in structural checks. By default, the plugin uses a pattern equivalent to `^docs/stories/[0-9]+\.[0-9]+-DEV-[\w-]+\.story\.md$`, which matches typical project conventions such as `docs/stories/005.0-DEV-EXAMPLE.story.md`; you can override this to match however your own project organizes story files.
97
+ - `example` (string, optional) – A short example `@story` path shown in error messages when `story.pattern` is configured. The built-in default example is `"docs/stories/005.0-DEV-EXAMPLE.story.md"`, intended as a generic illustration of a project story file, and does not refer to this plugin’s internal documentation.
95
98
  - `req` (object, optional) – Configuration for `@req` values.
96
- - `pattern` (string, optional) – A JavaScript regular expression **source** (without leading and trailing `/`) that all `@req` values must match. If provided, the rule validates each `@req` identifier against this pattern. Defaults to the value returned by `getDefaultReqPattern()`, which is equivalent to `^REQ-[A-Z0-9_-]+$`, matching IDs such as `REQ-USER-AUTH` or `REQ-1234`.
97
- - `example` (string, optional) – A short example requirement ID shown in error messages when `req.pattern` is configured. Defaults to the value returned by `getDefaultReqExample()`, `"REQ-USER-AUTH"`. This value is used **only** for guidance and does not affect validation.
99
+ - `pattern` (string, optional) – A JavaScript regular expression **source** (without leading and trailing `/`) that all `@req` values must match. If provided, the rule validates each `@req` identifier against this pattern. Defaults to the value returned by `getDefaultReqPattern()`, which is equivalent to `^REQ-[A-Z0-9-]+$`, matching IDs such as `REQ-USER-AUTH` or `REQ-1234`.
100
+ - `example` (string, optional) – A short example requirement ID shown in error messages when `req.pattern` is configured. Defaults to the value returned by `getDefaultReqExample()`, `"REQ-EXAMPLE"`. This value is used **only** for guidance and does not affect validation.
101
+ - `autoFix` (boolean, optional) – When set to `false`, disables all automatic suffix-normalization fixes while keeping validation and error messages intact. When omitted or `true`, the rule continues to apply safe `@story` suffix-only auto-fixes in `--fix` mode.
98
102
 
99
103
  For backward compatibility, the rule also supports **flat shorthand** fields that map directly to the nested properties:
100
104
 
@@ -109,6 +113,8 @@ Behavior notes:
109
113
  - When options are omitted, the rule behaves exactly as in earlier versions, relying on its built‑in defaults and path‑suffix normalization logic only.
110
114
  - The pattern checks are additional validation; they do not change the existing auto‑fix behavior, which remains limited to safe `@story` suffix normalization described above.
111
115
 
116
+ You can customize these validations to match your own naming conventions by overriding `story.pattern`/`storyPathPattern` and `req.pattern`/`requirementIdPattern`. This is useful when you store stories outside `docs/stories`, avoid `DEV` in filenames, or use a different requirement ID scheme instead of the default `REQ-...` format. Any custom values must still be valid JavaScript regular expression **sources** (without surrounding `/` characters).
117
+
112
118
  #### Migration and mixed usage
113
119
 
114
120
  The `valid-annotation-format` rule is intentionally **backward compatible** with existing code that only uses `@story` and `@req`. You can:
@@ -203,19 +209,21 @@ Options:
203
209
 
204
210
  The rule accepts an optional configuration object:
205
211
 
206
- - `testFilePatterns` (string[], optional) – Glob-style patterns (relative to the project root) used to identify test files. Only files matching at least one pattern are checked by this rule. Defaults to `["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)"]`.
212
+ - `testFilePatterns` (string[], optional) – **Path-substring patterns** used to identify test files. For each file, the rule normalizes the file path to use forward slashes and then checks whether it contains at least one of the configured pattern strings. This is intentionally simpler than full glob matching and avoids adding extra runtime dependencies. Defaults to `["/tests/", "/test/", "/__tests__", ".test.", ".spec."]`. For most projects, these defaults behave like "any file under a `tests` or `test` directory, or any file whose name includes `.test.` or `.spec.`". If you prefer a different layout, supply custom substrings that uniquely identify your test files.
207
213
  - `requireDescribeStory` (boolean, optional) – When `true` (default), requires that each top-level `describe` block include a story reference somewhere in its description text (for example, a path such as `docs/stories/010.0-PAYMENTS.story.md` or a shorter project-specific alias that your team uses consistently).
208
214
  - `requireTestReqPrefix` (boolean, optional) – When `true` (default), requires each `it`/`test` block name to begin with a requirement identifier in square brackets, such as `[REQ-PAYMENTS-REFUND]`. The exact `REQ-` pattern is shared with the `valid-annotation-format` rule’s requirement ID checks.
209
- - `describePattern` (string, optional) – A JavaScript regular expression **source** (without leading and trailing `/`) that the `describe` description text must match when `requireDescribeStory` is enabled. This lets you enforce a project-specific format such as requiring a canonical story path or a `STORY-` style identifier in the `describe` string. If omitted, a built-in default that loosely matches a typical story path (similar to `docs/stories/<name>.story.md`) is used.
215
+ - `describePattern` (string, optional) – A JavaScript regular expression **source** (without leading and trailing `/`) that the `describe` description text must match when `requireDescribeStory` is enabled. This lets you enforce a project-specific format such as requiring a canonical story path or a `STORY-` style identifier in the `describe` string. If omitted, the default is equivalent to `"Story [0-9]+\\.[0-9]+-"`, which expects the description to include a story label such as `"Story 021.0-DEV-TEST-TRACEABILITY"`. You can override this to instead require full story paths or whatever story-labeling convention your project prefers.
210
216
  - `autoFixTestTemplate` (boolean, optional) – When `true` (default), allows the rule’s `--fix` mode to insert a file-level `@supports` placeholder template at the top of test files that are missing it. The template is intentionally non-semantic and includes TODO-style guidance so humans can later replace it with a real story path and requirement IDs; disabling this option prevents the rule from inserting the template automatically.
211
217
  - `autoFixTestPrefixFormat` (boolean, optional) – When `true` (default), enables safe normalization of malformed `[REQ-XXX]` prefixes in `it`/`test` names during `--fix`. The rule only rewrites prefixes that already contain a recognizable requirement identifier and limits changes to formatting concerns (spacing, square brackets vs. parentheses, underscore and dash usage, and letter casing) without fabricating new IDs or guessing requirement names.
212
218
  - `testSupportsTemplate` (string, optional) – Overrides the default file-level `@supports` placeholder template used when `autoFixTestTemplate` is enabled. This string should be a complete JSDoc-style block (for example, including `/**`, `*`, and `*/`) that encodes your project’s preferred TODO guidance or placeholder story path; it is inserted verbatim at the top of matching test files that lack a `@supports` annotation, and is never interpreted or expanded by the rule.
213
219
 
220
+ You can tune these options to fit your own testing and naming conventions: adjust `testFilePatterns` to match your project’s test layout (including monorepos or non-standard folders), override `describePattern` if you prefer full `docs/stories/...` paths or a different story-labeling scheme in `describe` strings, and change `requireTestReqPrefix` and `autoFixTestPrefixFormat` if you want to relax, enforce, or customize the `[REQ-...]` prefix requirements for test names.
221
+
214
222
  Behavior notes:
215
223
 
216
- - The rule only analyzes files whose paths match `testFilePatterns`.
224
+ - The rule only analyzes files whose normalized paths contain at least one of the `testFilePatterns` substrings.
217
225
  - File-level `@supports` annotations are typically placed in a JSDoc block at the top of the file; the rule checks that at least one `@supports` tag is present and that it includes a story/requirement reference (for example, `@supports docs/stories/010.0-PAYMENTS.story.md#REQ-PAYMENTS-REFUND`).
218
- - Top-level `describe` calls (such as `describe("payments refunds docs/stories/010.0-PAYMENTS.story.md", ...)`) are inspected when `requireDescribeStory` is `true`. Their first argument must be a string literal that satisfies `describePattern`.
226
+ - Top-level `describe` calls (such as `describe("Story 010.0-DEV-PAYMENTS", ...)`) are inspected when `requireDescribeStory` is `true`. Their first argument must be a string literal that satisfies `describePattern`.
219
227
  - Test cases declared via `it(...)` or `test(...)` must use a string literal name beginning with a requirement prefix like `[REQ-PAYMENTS-REFUND]` when `requireTestReqPrefix` is `true`.
220
228
 
221
229
  Default Severity: `error`
@@ -238,6 +246,110 @@ describe("Refunds flow docs/stories/010.0-PAYMENTS.story.md", () => {
238
246
  });
239
247
  ```
240
248
 
249
+ ### traceability/prefer-implements-annotation
250
+
251
+ Description: An optional, opt-in migration helper that encourages converting legacy single‑story `@story` + `@req` JSDoc blocks into the newer multi‑story `@supports` format. The rule is **disabled by default** and is **not included in any built‑in preset**; you enable it explicitly and control its behavior entirely via ESLint severity (`"off" | "warn" | "error"`). It does not change what the core rules consider valid—it only adds migration recommendations and safe auto‑fixes on top of existing validation.
252
+
253
+ Options: None – this rule does not accept a configuration object. All tuning is done via the ESLint rule level (`"off"`, `"warn"`, `"error"`).
254
+
255
+ This rule focuses on **single‑story** legacy blocks where automatic migration is unambiguous. It inspects JSDoc comments attached to function‑like constructs and looks for the following patterns:
256
+
257
+ - A single `@story` annotation with one story path.
258
+ - One or more simple `@req` lines in the same block (each with a single requirement ID).
259
+ - No `@supports` annotations yet present in that block.
260
+
261
+ When these conditions are met, the rule recommends replacing the legacy block with a single `@supports` line that encodes the same relationship between the story and its requirements.
262
+
263
+ Main behaviors:
264
+
265
+ 1. **Single‑story legacy blocks → `preferImplements` (auto‑fixable)**
266
+ When a JSDoc block contains exactly one `@story` path and one or more simple `@req` identifiers, and no `@supports` tags, the rule reports a `preferImplements` diagnostic. In `--fix` mode, and when it is safe to do so, it rewrites the block to a consolidated `@supports` annotation of the form:
267
+
268
+ ```js
269
+ /**
270
+ * @supports docs/stories/010.0-PAYMENTS.story.md#REQ-PAYMENTS-REFUND REQ-PAYMENTS-EDGE
271
+ */
272
+ ```
273
+
274
+ Conceptually, the auto‑fix:
275
+
276
+ - Extracts the single `@story` value.
277
+ - Collects the requirement IDs from each `@req` line in that block.
278
+ - Emits a single `@supports story-path#REQ-1 REQ-2 ...` line (or your project’s equivalent anchor scheme).
279
+
280
+ All legacy `@story` and `@req` tags in that block are removed as part of the fix, since their meaning is now captured by the `@supports` line. The fix is only applied when the story path and requirement IDs are straightforward to parse; complex or ambiguous shapes are left for manual migration.
281
+
282
+ 2. **Mixed usage with existing `@supports` → `cannotAutoFix` (manual migration)**
283
+ If a JSDoc block already contains at least one `@supports` annotation **and** still has legacy `@story`/`@req` tags, the rule treats this as a mixed‑style block. In this case, it reports a `cannotAutoFix` diagnostic that includes a human‑readable `reason` explaining that the block already uses `@supports` and must be cleaned up manually.
284
+
285
+ The rule **does not** attempt to merge or rewrite mixed blocks automatically, to avoid guessing your intended story/requirement grouping. All annotations in such blocks are left unchanged; you are expected to convert them to your preferred `@supports` shape by hand.
286
+
287
+ 3. **Multiple distinct `@story` paths → `multiStoryDetected` (manual migration)**
288
+ When the same JSDoc block contains **multiple different `@story` paths**, the rule reports a `multiStoryDetected` diagnostic and leaves the block unchanged. This scenario usually indicates integration code that implements requirements from several stories, and the correct multi-story `@supports` representation depends on how your project organizes those relationships.
289
+
290
+ Because there is no universally safe way to automatically group requirements across multiple stories, the rule does **not** attempt any auto‑fix in this case. Instead, it highlights the block so humans can migrate it to one or more explicit `@supports` annotations following your multi‑story conventions.
291
+
292
+ Deliberate non‑targets and ignored comments:
293
+
294
+ - JSDoc blocks that contain **only** `@story`, **only** `@req`, or **only** `@supports` are **not** modified by this rule. They remain valid and continue to be governed solely by the core rules such as `require-story-annotation`, `require-req-annotation`, and `valid-annotation-format`.
295
+ - Inline or line comments like `// @story ...`, `// @req ...`, or `// @supports ...` are intentionally ignored by this migration helper; they are still checked by the underlying validation rules where applicable.
296
+ - Any block that does not match the “single story + simple requirements, no supports” shape is treated conservatively: the rule may report a diagnostic to flag the legacy/mixed pattern, but it will not rewrite comments unless it is clearly safe.
297
+
298
+ Interaction with other rules:
299
+
300
+ - Enabling this rule does **not** change what is required or permitted by:
301
+ - `traceability/valid-annotation-format`
302
+ - `traceability/valid-req-reference`
303
+ - `traceability/require-story-annotation`
304
+ - `traceability/require-req-annotation`
305
+ - All existing `@story` + `@req` blocks that pass those rules are still valid when this rule is off. Turning it on simply adds a migration layer that nudges you toward the consolidated `@supports` style and, where unambiguous, performs structural rewrites on your behalf.
306
+
307
+ Example: single‑story auto‑fix
308
+
309
+ Given this legacy JSDoc block:
310
+
311
+ ```js
312
+ /**
313
+ * @story docs/stories/010.0-PAYMENTS.story.md
314
+ * @req REQ-PAYMENTS-REFUND
315
+ * @req REQ-PAYMENTS-REFUND-EDGE
316
+ */
317
+ function issueRefund() {
318
+ // ...
319
+ }
320
+ ```
321
+
322
+ With `traceability/prefer-implements-annotation` enabled and ESLint run with `--fix`, the rule rewrites it to:
323
+
324
+ ```js
325
+ /**
326
+ * @supports docs/stories/010.0-PAYMENTS.story.md#REQ-PAYMENTS-REFUND REQ-PAYMENTS-REFUND-EDGE
327
+ */
328
+ function issueRefund() {
329
+ // ...
330
+ }
331
+ ```
332
+
333
+ All other function‑level rules (such as `require-story-annotation`, `require-req-annotation`, and `valid-annotation-format`) continue to validate the resulting `@supports` annotation according to your existing configuration.
334
+
335
+ Configuration example (opt‑in at `"warn"`):
336
+
337
+ ```js
338
+ // eslint.config.js (flat config)
339
+ import js from "@eslint/js";
340
+ import traceability from "eslint-plugin-traceability";
341
+
342
+ export default [
343
+ js.configs.recommended,
344
+ traceability.configs.recommended,
345
+ {
346
+ rules: {
347
+ "traceability/prefer-implements-annotation": "warn"
348
+ }
349
+ }
350
+ ];
351
+ ```
352
+
241
353
  ## Configuration Presets
242
354
 
243
355
  The plugin provides two built-in presets for easy configuration:
@@ -570,5 +682,4 @@ If `--from` or `--to` is missing, the CLI prints an error, shows the help text,
570
682
  In CI:
571
683
 
572
684
  ```bash
573
- npm run traceability:verify
574
- ```
685
+ npm run traceability:verify
@@ -72,3 +72,44 @@ Then run:
72
72
  ```bash
73
73
  npm run lint:trace
74
74
  ```
75
+
76
+ ## 5. Test Traceability Example
77
+
78
+ This example complements the `traceability/require-test-traceability` rule and matches its default expectations for how stories and requirements are referenced from tests.
79
+
80
+ Create a Jest test file, for example `tests/dev-test-traceability.spec.ts`:
81
+
82
+ ```ts
83
+ /**
84
+ * @supports docs/stories/021.0-DEV-TEST-TRACEABILITY.story.md#REQ-TEST-TRACEABILITY
85
+ */
86
+
87
+ describe("Story 021.0-DEV-TEST-TRACEABILITY", () => {
88
+ it("[REQ-TEST-TRACEABILITY] should handle the primary test scenario", () => {
89
+ // Arrange
90
+ const input = "happy-path";
91
+
92
+ // Act
93
+ const result = performOperation(input);
94
+
95
+ // Assert
96
+ expect(result).toBe("ok");
97
+ });
98
+
99
+ it("[REQ-TEST-TRACEABILITY-EDGE] should handle the edge-case scenario", () => {
100
+ // Arrange
101
+ const input = "edge-case";
102
+
103
+ // Act
104
+ const result = performOperation(input);
105
+
106
+ // Assert
107
+ expect(result).toBe("edge-ok");
108
+ });
109
+ });
110
+
111
+ // Example implementation under test (normally imported from your source code)
112
+ function performOperation(input: string): string {
113
+ if (input === "edge-case") return "edge-ok";
114
+ return "ok";
115
+ }
@@ -73,8 +73,41 @@ For teams that want to gradually migrate from `@story` + `@req` to `@supports`,
73
73
  }
74
74
  ```
75
75
 
76
- - When enabled, it offers **conservative auto-fixes** that rewrite eligible `@story` + `@req` combinations into equivalent `@supports` lines, without attempting risky or ambiguous transformations.
77
- - Detailed behavior, limitations, and examples are documented in the project’s internal rule documentation, which is primarily intended for maintainers; most users can rely on this guide and the API reference for day-to-day usage.
76
+ This rule is an **optional migration aid**, not a deprecation notice. `@story` and `@req` remain fully supported, and there is no hard requirement or deadline to migrate existing annotations. Use the rule only where `@supports` gives you clearer, multi-story traceability.
77
+
78
+ When enabled, it offers **conservative auto-fixes** that rewrite eligible `@story` + `@req` combinations into equivalent `@supports` lines, without attempting risky or ambiguous transformations. It intentionally refuses to modify comments that are even slightly unclear, and will instead surface diagnostics that explain what needs manual attention.
79
+
80
+ Aligned with the internal rule behavior, the key cases are:
81
+
82
+ - **Simple, single-story JSDoc blocks**
83
+ For comments that contain exactly one `@story` path and one or more simple `@req` lines, the rule:
84
+ - Reports a recommendation to consolidate them, and
85
+ - In `--fix` mode, converts them into a single `@supports` line that keeps the same story path and requirement IDs.
86
+
87
+ - **Mixed `@story` / `@req` plus existing `@supports`**
88
+ For comments that already contain one or more `@supports` lines alongside `@story` and/or `@req`, the rule:
89
+ - Reports a diagnostic explaining that mixed usage cannot be auto-fixed safely, and
90
+ - Leaves the comment unchanged so you can decide how to migrate it manually.
91
+
92
+ - **Multiple distinct `@story` paths**
93
+ For comments that refer to more than one different `@story` path, the rule:
94
+ - Reports that multiple stories were detected, and
95
+ - Requires you to manually convert them into separate `@supports` lines (one per story path, each followed by the appropriate requirement IDs).
96
+
97
+ - **Intentionally ignored comments**
98
+ The following are **ignored** by this rule and remain valid:
99
+ - Comments that contain only `@story` lines,
100
+ - Comments that contain only `@req` lines,
101
+ - Comments that contain only `@supports` lines, and
102
+ - Line comments such as `// @story ...`.
103
+
104
+ These forms are still supported by the plugin and are not modified by `traceability/prefer-implements-annotation`.
105
+
106
+ A typical migration path is:
107
+
108
+ - Start with the rule set to `"off"` while you introduce `@supports` in new or refactored code.
109
+ - Enable it as `"warn"` to get non-breaking guidance and auto-fixes for straightforward cases.
110
+ - Optionally move to `"error"` once you want to strictly enforce `@supports` usage for all JSDoc blocks that are eligible for safe conversion.
78
111
 
79
112
  #### When to keep `@story` + `@req`
80
113
 
@@ -171,4 +204,4 @@ Production dependency guarantees are enforced by CI scripts that run `npm audit
171
204
 
172
205
  ---
173
206
 
174
- If you encounter any issues during migration, please file an issue at https://github.com/voder-ai/eslint-plugin-traceability/issues.
207
+ If you encounter any issues during migration, please file an issue at https://github.com/voder-ai/eslint-plugin-traceability/issues.