eslint-plugin-traceability 1.8.0 → 1.8.2

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 (110) hide show
  1. package/CHANGELOG.md +5 -5
  2. package/README.md +28 -29
  3. package/SECURITY.md +135 -0
  4. package/lib/src/index.d.ts +6 -35
  5. package/lib/src/index.js +8 -5
  6. package/lib/src/maintenance/cli.js +12 -16
  7. package/lib/src/maintenance/detect.js +28 -1
  8. package/lib/src/rules/helpers/require-story-io.d.ts +2 -2
  9. package/lib/src/rules/helpers/require-story-io.js +13 -13
  10. package/lib/src/rules/helpers/valid-annotation-format-internal.d.ts +2 -2
  11. package/lib/src/rules/helpers/valid-annotation-format-internal.js +3 -3
  12. package/lib/src/rules/helpers/valid-annotation-utils.d.ts +5 -0
  13. package/lib/src/rules/helpers/valid-annotation-utils.js +43 -5
  14. package/lib/src/rules/helpers/valid-implements-utils.d.ts +11 -11
  15. package/lib/src/rules/helpers/valid-implements-utils.js +11 -11
  16. package/lib/src/rules/helpers/valid-story-reference-helpers.js +19 -0
  17. package/lib/src/rules/prefer-implements-annotation.d.ts +7 -7
  18. package/lib/src/rules/prefer-implements-annotation.js +21 -21
  19. package/lib/src/rules/valid-annotation-format.js +50 -24
  20. package/lib/src/rules/valid-req-reference.js +9 -9
  21. package/lib/src/utils/annotation-checker.js +3 -1
  22. package/lib/src/utils/reqAnnotationDetection.d.ts +2 -2
  23. package/lib/src/utils/reqAnnotationDetection.js +28 -28
  24. package/lib/tests/config/flat-config-presets-integration.test.d.ts +1 -0
  25. package/lib/tests/config/flat-config-presets-integration.test.js +75 -0
  26. package/lib/tests/maintenance/batch.test.js +11 -11
  27. package/lib/tests/maintenance/cli.test.js +34 -27
  28. package/lib/tests/maintenance/report.test.js +7 -7
  29. package/lib/tests/plugin-default-export-and-configs.test.js +0 -2
  30. package/lib/tests/rules/prefer-implements-annotation.test.js +48 -15
  31. package/lib/tests/rules/require-branch-annotation.test.js +15 -36
  32. package/lib/tests/rules/require-req-annotation.test.js +31 -104
  33. package/lib/tests/rules/require-story-annotation.test.js +3 -3
  34. package/lib/tests/rules/require-story-io-behavior.test.js +2 -7
  35. package/lib/tests/rules/require-story-io.edgecases.test.js +2 -7
  36. package/lib/tests/rules/require-story-visitors-edgecases.test.js +8 -8
  37. package/lib/tests/rules/valid-annotation-format.test.js +23 -23
  38. package/lib/tests/rules/valid-req-reference.test.js +9 -9
  39. package/lib/tests/rules/valid-story-reference.test.js +4 -43
  40. package/lib/tests/utils/annotation-checker.test.js +2 -6
  41. package/lib/tests/utils/fsTestHelpers.d.ts +7 -0
  42. package/lib/tests/utils/fsTestHelpers.js +26 -0
  43. package/lib/tests/utils/ioTestHelpers.d.ts +7 -0
  44. package/lib/tests/utils/ioTestHelpers.js +24 -0
  45. package/lib/tests/utils/temp-dir-helpers.d.ts +14 -0
  46. package/lib/tests/utils/temp-dir-helpers.js +61 -0
  47. package/package.json +8 -7
  48. package/user-docs/api-reference.md +37 -20
  49. package/user-docs/eslint-9-setup-guide.md +89 -6
  50. package/user-docs/migration-guide.md +37 -21
  51. package/docs/ci-cd-pipeline.md +0 -224
  52. package/docs/cli-integration.md +0 -22
  53. package/docs/code-quality-refactor-opportunities-2025-12-03.md +0 -78
  54. package/docs/config-presets.md +0 -38
  55. package/docs/conventional-commits-guide.md +0 -185
  56. package/docs/custom-rules-development-guide.md +0 -659
  57. package/docs/decisions/0001-allow-dynamic-require-for-built-plugins.md +0 -26
  58. package/docs/decisions/001-typescript-for-eslint-plugin.accepted.md +0 -111
  59. package/docs/decisions/002-jest-for-eslint-testing.accepted.md +0 -137
  60. package/docs/decisions/003-code-quality-ratcheting-plan.md +0 -48
  61. package/docs/decisions/004-automated-version-bumping-for-ci-cd.md +0 -196
  62. package/docs/decisions/005-github-actions-validation-tooling.accepted.md +0 -144
  63. package/docs/decisions/006-semantic-release-for-automated-publishing.accepted.md +0 -227
  64. package/docs/decisions/007-github-releases-over-changelog.accepted.md +0 -216
  65. package/docs/decisions/008-ci-audit-flags.accepted.md +0 -60
  66. package/docs/decisions/009-security-focused-lint-rules.accepted.md +0 -64
  67. package/docs/decisions/010-implements-annotation-for-multi-story-requirements.proposed.md +0 -184
  68. package/docs/decisions/adr-0001-console-usage-for-cli-guards.md +0 -190
  69. package/docs/decisions/adr-accept-dev-dep-risk-glob.md +0 -40
  70. package/docs/decisions/adr-commit-branch-tests.md +0 -54
  71. package/docs/decisions/adr-maintenance-cli-interface.md +0 -140
  72. package/docs/decisions/adr-pre-push-parity.md +0 -112
  73. package/docs/decisions/code-quality-ratcheting-plan.md +0 -53
  74. package/docs/dependency-health.md +0 -238
  75. package/docs/eslint-9-setup-guide.md +0 -517
  76. package/docs/eslint-plugin-development-guide.md +0 -487
  77. package/docs/functionality-coverage-2025-12-03.md +0 -250
  78. package/docs/jest-testing-guide.md +0 -100
  79. package/docs/rules/prefer-implements-annotation.md +0 -219
  80. package/docs/rules/require-branch-annotation.md +0 -71
  81. package/docs/rules/require-req-annotation.md +0 -203
  82. package/docs/rules/require-story-annotation.md +0 -159
  83. package/docs/rules/valid-annotation-format.md +0 -418
  84. package/docs/rules/valid-req-reference.md +0 -153
  85. package/docs/rules/valid-story-reference.md +0 -120
  86. package/docs/security-incidents/2025-11-17-glob-cli-incident.md +0 -45
  87. package/docs/security-incidents/2025-11-18-brace-expansion-redos.md +0 -45
  88. package/docs/security-incidents/2025-11-18-bundled-dev-deps-accepted-risk.md +0 -93
  89. package/docs/security-incidents/2025-11-18-tar-race-condition.md +0 -43
  90. package/docs/security-incidents/2025-12-03-dependency-health-review.md +0 -58
  91. package/docs/security-incidents/SECURITY-INCIDENT-2025-11-18-semantic-release-bundled-npm.known-error.md +0 -104
  92. package/docs/security-incidents/SECURITY-INCIDENT-TEMPLATE.md +0 -37
  93. package/docs/security-incidents/dependency-override-rationale.md +0 -57
  94. package/docs/security-incidents/dev-deps-high.json +0 -116
  95. package/docs/security-incidents/handling-procedure.md +0 -54
  96. package/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md +0 -92
  97. package/docs/stories/002.0-DEV-ESLINT-CONFIG.story.md +0 -82
  98. package/docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md +0 -112
  99. package/docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md +0 -153
  100. package/docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md +0 -138
  101. package/docs/stories/006.0-DEV-FILE-VALIDATION.story.md +0 -144
  102. package/docs/stories/007.0-DEV-ERROR-REPORTING.story.md +0 -163
  103. package/docs/stories/008.0-DEV-AUTO-FIX.story.md +0 -150
  104. package/docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md +0 -117
  105. package/docs/stories/010.0-DEV-DEEP-VALIDATION.story.md +0 -124
  106. package/docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md +0 -149
  107. package/docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md +0 -216
  108. package/docs/stories/010.3-DEV-MIGRATE-TO-IMPLEMENTS.story.md +0 -236
  109. package/docs/stories/developer-story.map.md +0 -120
  110. package/docs/ts-jest-presets-guide.md +0 -548
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runFallbackTextBeforeHasStoryDetectsStoryTest = runFallbackTextBeforeHasStoryDetectsStoryTest;
4
+ /**
5
+ * Shared IO helper tests for require-story-io behavior.
6
+ *
7
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
8
+ * @req REQ-TEST-UTILS-IO - Provide reusable helpers for IO-related edge case tests
9
+ */
10
+ function runFallbackTextBeforeHasStoryDetectsStoryTest(storyAnnotationOrFallbackFn = "@story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md", maybeFallbackFn) {
11
+ const isFirstArgFn = typeof storyAnnotationOrFallbackFn === "function";
12
+ const storyAnnotation = isFirstArgFn
13
+ ? "@story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md"
14
+ : storyAnnotationOrFallbackFn;
15
+ const fallbackFn = isFirstArgFn
16
+ ? storyAnnotationOrFallbackFn
17
+ : maybeFallbackFn;
18
+ const pre = `/* ${storyAnnotation} */\n`;
19
+ const rest = "function y() {}";
20
+ const full = pre + rest;
21
+ const fakeSource = { getText: () => full };
22
+ const node = { range: [full.indexOf("function"), full.length] };
23
+ expect(fallbackFn(fakeSource, node)).toBe(true);
24
+ }
@@ -0,0 +1,14 @@
1
+ export interface TempDirHandle {
2
+ /** The absolute path to the created temporary directory. */
3
+ readonly dir: string;
4
+ /** Remove the directory recursively; safe to call multiple times. */
5
+ cleanup(): void;
6
+ }
7
+ /**
8
+ * Create a temporary directory under the OS temp root with a common prefix.
9
+ *
10
+ * This helper centralizes the mkdtemp + rmSync pattern that appears in
11
+ * multiple maintenance tests so those tests can focus on behavior instead
12
+ * of filesystem plumbing.
13
+ */
14
+ export declare function createTempDir(prefix: string): TempDirHandle;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createTempDir = createTempDir;
37
+ /**
38
+ * Shared temp directory helpers for maintenance tests.
39
+ * @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
40
+ * @req REQ-MAINT-TEMP-HELPERS - Provide reusable OS tempdir setup/cleanup utilities for tests
41
+ */
42
+ const fs = __importStar(require("fs"));
43
+ const os = __importStar(require("os"));
44
+ const path = __importStar(require("path"));
45
+ /**
46
+ * Create a temporary directory under the OS temp root with a common prefix.
47
+ *
48
+ * This helper centralizes the mkdtemp + rmSync pattern that appears in
49
+ * multiple maintenance tests so those tests can focus on behavior instead
50
+ * of filesystem plumbing.
51
+ */
52
+ function createTempDir(prefix) {
53
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
54
+ return {
55
+ dir,
56
+ cleanup() {
57
+ // @implements docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-SAFE
58
+ fs.rmSync(dir, { recursive: true, force: true });
59
+ },
60
+ };
61
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-traceability",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "A customizable ESLint plugin that enforces traceability annotations in your code, ensuring each implementation is linked to its requirement or test case.",
5
5
  "main": "lib/src/index.js",
6
6
  "types": "lib/src/index.d.ts",
@@ -8,8 +8,8 @@
8
8
  "lib",
9
9
  "README.md",
10
10
  "LICENSE",
11
+ "SECURITY.md",
11
12
  "user-docs",
12
- "docs",
13
13
  "CHANGELOG.md"
14
14
  ],
15
15
  "directories": {
@@ -20,7 +20,8 @@
20
20
  },
21
21
  "scripts": {
22
22
  "build": "tsc -p tsconfig.json",
23
- "prepare": "husky install",
23
+ "prepare": "",
24
+ "postinstall": "husky",
24
25
  "type-check": "tsc --noEmit -p tsconfig.json",
25
26
  "check:traceability": "node scripts/traceability-check.js",
26
27
  "lint-plugin-check": "node scripts/lint-plugin-check.js",
@@ -67,8 +68,8 @@
67
68
  "@eslint/js": "^9.39.1",
68
69
  "@semantic-release/changelog": "^6.0.3",
69
70
  "@semantic-release/git": "^10.0.1",
70
- "@semantic-release/github": "^10.3.5",
71
- "@semantic-release/npm": "^10.0.6",
71
+ "@semantic-release/github": "12.0.2",
72
+ "@semantic-release/npm": "13.1.2",
72
73
  "@types/eslint": "^9.6.1",
73
74
  "@types/jest": "^30.0.0",
74
75
  "@types/node": "^24.10.1",
@@ -80,9 +81,9 @@
80
81
  "husky": "^9.1.7",
81
82
  "jest": "^30.2.0",
82
83
  "jscpd": "^4.0.5",
83
- "lint-staged": "^16.2.6",
84
+ "lint-staged": "^16.2.7",
84
85
  "prettier": "^3.6.2",
85
- "semantic-release": "^21.1.2",
86
+ "semantic-release": "25.0.2",
86
87
  "ts-jest": "^29.4.5",
87
88
  "typescript": "^5.9.3",
88
89
  "secretlint": "11.2.5",
@@ -11,13 +11,15 @@ Security and dependency hygiene for the published package are enforced by the sa
11
11
 
12
12
  Each rule enforces traceability conventions in your code. Below is a summary of each rule exposed by this plugin.
13
13
 
14
- In addition to the core `@story` and `@req` annotations, the plugin also understands `@implements` for code that fulfills requirements from multiple stories—for example:
15
- `@implements docs/stories/010.0-PAYMENTS.story.md#REQ-PAYMENTS-REFUND`.
16
- For a detailed explanation of `@implements` behavior and validation, see [`user-docs/migration-guide.md`](../user-docs/migration-guide.md) (section **3.1 Multi-story @implements annotations**) and the rule docs at [`docs/rules/valid-annotation-format.md`](../docs/rules/valid-annotation-format.md) and [`docs/rules/valid-req-reference.md`](../docs/rules/valid-req-reference.md).
14
+ In addition to the core `@story` and `@req` annotations, the plugin also understands `@supports` for code that fulfills requirements from multiple stories—for example, a consuming project might use a path like
15
+ `@supports docs/stories/010.0-PAYMENTS.story.md#REQ-PAYMENTS-REFUND`
16
+ to indicate that a given function supports a particular requirement from a payments story document within that project’s own `docs/stories` tree. For a detailed explanation of `@supports` behavior and validation, see [Migration Guide](migration-guide.md) (section **3.1 Multi-story @supports annotations**). Additional background on multi-story semantics is available in the project’s internal rule documentation, which is intended for maintainers rather than end users.
17
+
18
+ The `prefer-implements-annotation` rule is an **opt-in migration helper** that is disabled by default and **not** part of any built-in preset. It can be enabled and given a severity like `"warn"` or `"error"` using normal ESLint rule configuration when you want to gradually encourage multi-story `@supports` usage. Detailed behavior and migration guidance are documented in the project’s internal rule documentation, which is targeted at maintainers; typical end users can rely on the high-level guidance in this API reference and the [Migration Guide](migration-guide.md).
17
19
 
18
20
  ### traceability/require-story-annotation
19
21
 
20
- Description: Ensures every function declaration has a JSDoc comment with an `@story` annotation referencing the related user story. 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 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.
21
23
 
22
24
  Options:
23
25
 
@@ -39,7 +41,7 @@ function initAuth() {
39
41
 
40
42
  ### traceability/require-req-annotation
41
43
 
42
- Description: Ensures that function-like constructs consistently declare their linked requirement using an `@req` annotation in JSDoc. The rule targets the same function-like node types as `traceability/require-story-annotation` (standard function declarations, non-arrow function expressions used as callbacks or assignments, class/object methods, TypeScript declare functions, and interface method signatures), and enforces that each of them has at least one `@req` tag in the nearest associated JSDoc comment. Arrow functions (`ArrowFunctionExpression`) are not currently checked by this rule.
44
+ Description: Ensures that function-like constructs consistently declare their linked requirement using an `@req` annotation in JSDoc. The rule targets the same function-like node types as `traceability/require-story-annotation` (standard function declarations, non-arrow function expressions used as callbacks or assignments, class/object methods, TypeScript declare functions, and interface method signatures), and enforces that each of them has at least one `@req` tag in the nearest associated JSDoc comment. When you adopt multi-story `@supports` annotations, this rule also treats `@supports story-path REQ-ID...` tags as satisfying the requirement coverage check, although deep verification of requirement IDs continues to be handled by `traceability/valid-req-reference`. Arrow functions (`ArrowFunctionExpression`) are not currently checked by this rule.
43
45
 
44
46
  This rule is typically used alongside `traceability/require-story-annotation` so that each function-level traceability block includes both an `@story` and an `@req` annotation, but it can also be enabled independently if you only want to enforce requirement linkage. Unlike `traceability/require-story-annotation`, this rule does not currently provide an auto-fix mode for inserting placeholder `@req` annotations; it only reports missing or malformed requirement annotations on the configured scopes.
45
47
 
@@ -88,11 +90,11 @@ Options:
88
90
  This rule accepts an optional configuration object. The primary configuration shape is **nested**:
89
91
 
90
92
  - `story` (object, optional) – Configuration for `@story` values.
91
- - `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. Defaults to the value returned by `getDefaultStoryPattern()`, which is equivalent to `^docs/stories/.*\.story\.md$`, aligning with the standard `docs/stories/<name>.story.md` convention.
92
- - `example` (string, optional) – A short example `@story` path shown in error messages when `story.pattern` is configured. Defaults to the value returned by `getDefaultStoryExample()`, `"docs/stories/001.0-EXAMPLE.story.md"`. This value is used **only** for guidance and does not affect validation.
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.
93
95
  - `req` (object, optional) – Configuration for `@req` values.
94
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`.
95
- - `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 is purely informational and does not participate in matching.
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.
96
98
 
97
99
  For backward compatibility, the rule also supports **flat shorthand** fields that map directly to the nested properties:
98
100
 
@@ -112,13 +114,10 @@ Behavior notes:
112
114
  The `valid-annotation-format` rule is intentionally **backward compatible** with existing code that only uses `@story` and `@req`. You can:
113
115
 
114
116
  - Continue using `@story` + `@req` for single-story functions and modules.
115
- - Introduce `@implements` incrementally for integration code that implements requirements from multiple stories.
117
+ - Introduce `@supports` incrementally for integration code that implements requirements from multiple stories.
116
118
  - Mix both styles in the same comment block when needed; the rule validates the format of each annotation independently.
117
119
 
118
- Deep requirement checking for both `@req` and `@implements` is handled by `traceability/valid-req-reference`. For step-by-step guidance on when and how to migrate, see:
119
-
120
- - **Migration guide:** [`user-docs/migration-guide.md`](../user-docs/migration-guide.md) (section **3.1 Multi-story `@implements` annotations**)
121
- - **Rule docs:** [`docs/rules/valid-annotation-format.md`](../docs/rules/valid-annotation-format.md), [`docs/rules/valid-req-reference.md`](../docs/rules/valid-req-reference.md)
120
+ Deep requirement checking for both `@req` and `@supports` is handled by the `valid-req-reference` rule in the plugin's internal docs. Advanced edge cases and internal semantics are mainly of interest to maintainers; typical end users can rely on the options and examples in this API reference when configuring the rule for their projects.
122
121
 
123
122
  Default Severity: `error`
124
123
  Example:
@@ -196,9 +195,12 @@ The plugin provides two built-in presets for easy configuration:
196
195
 
197
196
  ### recommended
198
197
 
199
- Enables the core traceability rules with severities tuned for common usage (most at `error`, with
200
- `traceability/valid-annotation-format` at `warn` to reduce noise):
201
- This `warn` level for `traceability/valid-annotation-format` is intentional to keep early adoption noise low, but you can safely raise it to `error` in projects that want strict enforcement of annotation formatting.
198
+ Enables the **six core traceability rules** with severities tuned for common usage (most at `error`, with
199
+ `traceability/valid-annotation-format` at `warn` to reduce noise). This `warn` level for `traceability/valid-annotation-format` is intentional to keep early adoption noise low, but you can safely raise it to `error` in projects that want strict enforcement of annotation formatting.
200
+
201
+ The `prefer-implements-annotation` migration rule is **not included** in this (or any) preset and remains disabled by default. If you want to encourage or enforce multi-story `@supports` annotations, you must enable `traceability/prefer-implements-annotation` explicitly in your ESLint configuration and choose an appropriate severity (for example, `"warn"` during migration or `"error"` once fully adopted).
202
+
203
+ Core rules enabled by the `recommended` preset:
202
204
 
203
205
  - `traceability/require-story-annotation`: `error`
204
206
  - `traceability/require-req-annotation`: `error`
@@ -218,7 +220,8 @@ export default [js.configs.recommended, traceability.configs.recommended];
218
220
 
219
221
  ### strict
220
222
 
221
- Currently mirrors the **recommended** preset, reserved for future stricter policies.
223
+ Currently mirrors the **recommended** preset, reserved for future stricter policies. As with the `recommended` preset, the `traceability/prefer-implements-annotation` rule is **not** enabled here by default and must be configured manually if desired.
224
+
222
225
  Usage:
223
226
 
224
227
  ```javascript
@@ -234,16 +237,30 @@ The plugin exposes a small maintenance API and a companion CLI, `traceability-ma
234
237
 
235
238
  ### Programmatic Maintenance API
236
239
 
237
- All functions are exported from the plugin’s maintenance module:
240
+ The maintenance functions are available via the plugin’s `maintenance` export. You can either import the named `maintenance` export directly and destructure the functions you need, or import the default plugin export and access the same functions from `traceability.maintenance`:
238
241
 
239
242
  ```ts
240
- import {
243
+ // Option 1: Named `maintenance` export
244
+ import { maintenance } from "eslint-plugin-traceability";
245
+
246
+ const {
241
247
  detectStaleAnnotations,
242
248
  updateAnnotationReferences,
243
249
  batchUpdateAnnotations,
244
250
  verifyAnnotations,
245
251
  generateMaintenanceReport,
246
- } from "eslint-plugin-traceability/maintenance";
252
+ } = maintenance;
253
+
254
+ // Option 2: Default plugin export
255
+ import traceability from "eslint-plugin-traceability";
256
+
257
+ const {
258
+ detectStaleAnnotations: detectStaleAnnotations2,
259
+ updateAnnotationReferences: updateAnnotationReferences2,
260
+ batchUpdateAnnotations: batchUpdateAnnotations2,
261
+ verifyAnnotations: verifyAnnotations2,
262
+ generateMaintenanceReport: generateMaintenanceReport2,
263
+ } = traceability.maintenance;
247
264
  ```
248
265
 
249
266
  The current maintenance API operates on a **single workspace root** and scans all files beneath that directory. It does not yet accept include/exclude globs or explicit story/requirement lists.
@@ -28,6 +28,9 @@ npm install --save-dev eslint@^9.39.1
28
28
  # Recommended configurations
29
29
  npm install --save-dev @eslint/js@^9.39.1
30
30
 
31
+ # Traceability plugin
32
+ npm install --save-dev eslint-plugin-traceability@^1.0.0
33
+
31
34
  # For TypeScript projects
32
35
  npm install --save-dev @typescript-eslint/parser@^8.0.0
33
36
  npm install --save-dev @typescript-eslint/utils@^8.0.0
@@ -67,13 +70,48 @@ export default [
67
70
 
68
71
  ### 4. Enable Traceability Plugin
69
72
 
70
- To integrate the traceability plugin, update your `eslint.config.js` to include its recommended configuration:
73
+ To integrate the traceability plugin with its **recommended** preset, update your `eslint.config.js`:
74
+
75
+ ```javascript
76
+ import js from "@eslint/js";
77
+ import traceability from "eslint-plugin-traceability";
78
+
79
+ export default [
80
+ js.configs.recommended,
81
+ {
82
+ plugins: {
83
+ traceability,
84
+ },
85
+ },
86
+ ...traceability.configs.recommended,
87
+ ];
88
+ ```
89
+
90
+ To use the **strict** preset instead:
71
91
 
72
92
  ```javascript
73
93
  import js from "@eslint/js";
74
94
  import traceability from "eslint-plugin-traceability";
75
95
 
76
- export default [js.configs.recommended, traceability.configs.recommended];
96
+ export default [
97
+ js.configs.recommended,
98
+ {
99
+ plugins: {
100
+ traceability,
101
+ },
102
+ },
103
+ ...traceability.configs.strict,
104
+ ];
105
+ ```
106
+
107
+ Note: The `traceability.configs.recommended` and `traceability.configs.strict` presets define rule severities only. They expect the plugin to be registered in a preceding flat-config object via:
108
+
109
+ ```javascript
110
+ {
111
+ plugins: {
112
+ traceability,
113
+ },
114
+ }
77
115
  ```
78
116
 
79
117
  ## Configuration File Format
@@ -137,9 +175,16 @@ Both forms are supported by ESLint 9 as long as the file extension and `package.
137
175
  ```javascript
138
176
  // eslint.config.js
139
177
  import js from "@eslint/js";
178
+ import traceability from "eslint-plugin-traceability";
140
179
 
141
180
  export default [
142
181
  js.configs.recommended,
182
+ {
183
+ plugins: {
184
+ traceability,
185
+ },
186
+ },
187
+ ...traceability.configs.recommended,
143
188
  {
144
189
  files: ["**/*.js", "**/*.mjs"],
145
190
  languageOptions: {
@@ -163,9 +208,16 @@ export default [
163
208
  // eslint.config.js
164
209
  import js from "@eslint/js";
165
210
  import typescriptParser from "@typescript-eslint/parser";
211
+ import traceability from "eslint-plugin-traceability";
166
212
 
167
213
  export default [
168
214
  js.configs.recommended,
215
+ {
216
+ plugins: {
217
+ traceability,
218
+ },
219
+ },
220
+ ...traceability.configs.recommended,
169
221
  {
170
222
  files: ["**/*.ts", "**/*.tsx"],
171
223
  languageOptions: {
@@ -197,9 +249,16 @@ export default [
197
249
  // eslint.config.js
198
250
  import js from "@eslint/js";
199
251
  import typescriptParser from "@typescript-eslint/parser";
252
+ import traceability from "eslint-plugin-traceability";
200
253
 
201
254
  export default [
202
255
  js.configs.recommended,
256
+ {
257
+ plugins: {
258
+ traceability,
259
+ },
260
+ },
261
+ ...traceability.configs.recommended,
203
262
  {
204
263
  files: ["**/*.{js,jsx,ts,tsx}"],
205
264
  languageOptions: {
@@ -282,9 +341,16 @@ export default [
282
341
  // eslint.config.js
283
342
  import js from "@eslint/js";
284
343
  import typescriptParser from "@typescript-eslint/parser";
344
+ import traceability from "eslint-plugin-traceability";
285
345
 
286
346
  export default [
287
347
  js.configs.recommended,
348
+ {
349
+ plugins: {
350
+ traceability,
351
+ },
352
+ },
353
+ ...traceability.configs.recommended,
288
354
  {
289
355
  // Lint all packages in a monorepo/workspace
290
356
  files: ["packages/*/src/**/*.{js,ts,tsx}"],
@@ -479,9 +545,16 @@ Solution: Use combined file patterns or separate override blocks, and import the
479
545
  // eslint.config.js
480
546
  import js from "@eslint/js";
481
547
  import typescriptParser from "@typescript-eslint/parser";
548
+ import traceability from "eslint-plugin-traceability";
482
549
 
483
550
  export default [
484
551
  js.configs.recommended,
552
+ {
553
+ plugins: {
554
+ traceability,
555
+ },
556
+ },
557
+ ...traceability.configs.recommended,
485
558
  {
486
559
  files: ["**/*.{js,jsx,ts,tsx}"],
487
560
  languageOptions: {
@@ -512,6 +585,7 @@ Here's a complete working configuration for a TypeScript ESLint plugin project:
512
585
  // eslint.config.js
513
586
  import js from "@eslint/js";
514
587
  import typescriptParser from "@typescript-eslint/parser";
588
+ import traceability from "eslint-plugin-traceability";
515
589
 
516
590
  // Conditional plugin loading (for plugin development)
517
591
  let plugin;
@@ -524,6 +598,15 @@ try {
524
598
 
525
599
  export default [
526
600
  js.configs.recommended,
601
+ {
602
+ // Register the traceability plugin for subsequent presets/rules
603
+ plugins: {
604
+ traceability,
605
+ ...(plugin.rules ? { traceabilityDev: plugin } : {}),
606
+ },
607
+ },
608
+ // Apply the recommended preset for the published plugin
609
+ ...traceability.configs.recommended,
527
610
  {
528
611
  // Node.js config files (CommonJS)
529
612
  files: ["*.config.js", "*.config.mjs", "jest.config.js"],
@@ -554,7 +637,7 @@ export default [
554
637
  },
555
638
  },
556
639
  plugins: {
557
- ...(plugin.rules ? { traceability: plugin } : {}),
640
+ ...(plugin.rules ? { traceabilityDev: plugin } : {}),
558
641
  },
559
642
  rules: {
560
643
  "@typescript-eslint/no-unused-vars": "error",
@@ -568,7 +651,7 @@ export default [
568
651
  sourceType: "module",
569
652
  },
570
653
  plugins: {
571
- ...(plugin.rules ? { traceability: plugin } : {}),
654
+ ...(plugin.rules ? { traceabilityDev: plugin } : {}),
572
655
  },
573
656
  },
574
657
  {
@@ -621,6 +704,7 @@ export default [
621
704
  "@typescript-eslint/parser": "^8.46.4",
622
705
  "@typescript-eslint/utils": "^8.46.4",
623
706
  "eslint": "^9.39.1",
707
+ "eslint-plugin-traceability": "^1.0.0",
624
708
  "typescript": "^5.9.3"
625
709
  }
626
710
  }
@@ -635,5 +719,4 @@ export default [
635
719
  5. **Use file patterns** instead of CLI `--ext` flags
636
720
  6. **Structure as array of objects**, each targeting specific file types
637
721
  7. **Use `ignores`** instead of `.eslintignore` files
638
-
639
- This setup provides a solid foundation for ESLint 9 that works reliably across different project types and environments.
722
+ 8. **Register plugins explicitly** in flat config before spreading their presets
@@ -37,25 +37,44 @@ export default [traceability.configs.recommended];
37
37
  - `valid-req-reference` rejects path traversal (`../`) and absolute paths (`/etc/passwd`).
38
38
  - `valid-annotation-format` enforces correct JSDoc traceability annotation syntax (`@story` and `@req` tags).
39
39
 
40
- Review and update your existing annotations accordingly:
40
+ The following diff shows a typical migration in **your own project**, where `docs/stories/001.0-DEV-PLUGIN-SETUP.story.md` is an example of a story file path from your documentation tree:
41
41
 
42
42
  ```diff
43
43
  - /** @story docs/stories/001.0-DEV-PLUGIN-SETUP.md */
44
44
  + /** @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md */
45
45
  ```
46
46
 
47
- ### 3.1 Multi-story `@implements` annotations
47
+ ### 3.1 Multi-story `@supports` annotations
48
48
 
49
- Starting in v1.x, `eslint-plugin-traceability` supports an additional annotation form for integration code that implements requirements from multiple stories:
49
+ Starting in v1.x, `eslint-plugin-traceability` supports an additional annotation form for integration code that implements requirements from multiple stories in a consuming project. The following snippet shows one example of how you might structure such an annotation in **your** codebase:
50
50
 
51
51
  ```js
52
52
  /**
53
- * @implements docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md REQ-IMPLEMENTS-PARSE REQ-IMPLEMENTS-VALIDATE
53
+ * @supports docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md REQ-IMPLEMENTS-PARSE REQ-IMPLEMENTS-VALIDATE
54
54
  */
55
55
  function integrate() {}
56
56
  ```
57
57
 
58
- You **do not** need to change existing, single-story annotations that already use `@story` and `@req`. Migration to `@implements` is only recommended when a function or module genuinely implements requirements from more than one story file.
58
+ You **do not** need to change existing, single-story annotations that already use `@story` and `@req`. Migration to `@supports` is only recommended when a function or module genuinely implements requirements from more than one story file.
59
+
60
+ #### Optional `prefer-implements-annotation` migration rule
61
+
62
+ For teams that want to gradually migrate from `@story` + `@req` to `@supports`, the plugin provides an optional rule: `traceability/prefer-implements-annotation`.
63
+
64
+ - This rule is **disabled by default** and is **not** included in any built-in presets.
65
+ - You can enable it with any standard ESLint severity (`"off"`, `"warn"`, or `"error"`) in your config, for example:
66
+
67
+ ```js
68
+ // excerpt from eslint.config.js
69
+ {
70
+ rules: {
71
+ "traceability/prefer-implements-annotation": "warn",
72
+ },
73
+ }
74
+ ```
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.
59
78
 
60
79
  #### When to keep `@story` + `@req`
61
80
 
@@ -65,7 +84,7 @@ Keep your current annotations if:
65
84
  - All relevant requirements live in that story file.
66
85
  - You do not need to distinguish which story a particular requirement ID comes from.
67
86
 
68
- Example (no migration required):
87
+ Example (no migration required). Here, `docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md` is an illustrative path representing a typical story file location in **your** documentation structure:
69
88
 
70
89
  ```js
71
90
  /**
@@ -77,15 +96,15 @@ export function initAuth() {
77
96
  }
78
97
  ```
79
98
 
80
- #### When to introduce `@implements`
99
+ #### When to introduce `@supports`
81
100
 
82
- Adopt `@implements` for **multi-story integration** code, especially when:
101
+ Adopt `@supports` for **multi-story integration** code, especially when:
83
102
 
84
103
  - The function combines behavior governed by **multiple** stories.
85
104
  - Requirement IDs are reused across stories (for example, `REQ-SHARED-ID` appears in more than one story file).
86
105
  - You want deep validation (via `valid-req-reference`) to know **which story file** each requirement came from.
87
106
 
88
- Before (single-story annotations trying to describe multi-story behavior):
107
+ Before (single-story annotations trying to describe multi-story behavior). The story path shown here is an example of how you might name and organize a story file in your own project:
89
108
 
90
109
  ```js
91
110
  /**
@@ -99,7 +118,7 @@ export async function applyFilters(rows, options) {
99
118
  }
100
119
  ```
101
120
 
102
- After (multi-story `@implements`), aligned with Story 010.2:
121
+ After (multi-story `@supports`), using illustrative story paths that represent typical files in your project’s documentation tree (they are examples, not files provided by this plugin):
103
122
 
104
123
  ```js
105
124
  /**
@@ -108,8 +127,8 @@ After (multi-story `@implements`), aligned with Story 010.2:
108
127
  * @req REQ-AGE-THRESHOLD
109
128
  * @req REQ-OUTPUT
110
129
  *
111
- * @implements docs/stories/003.0-DEV-IDENTIFY-OUTDATED.story.md REQ-AGE-THRESHOLD REQ-OUTPUT
112
- * @implements docs/stories/004.0-DEV-FILTER-VULNERABLE-VERSIONS.story.md REQ-AUDIT-CHECK REQ-SAFE-ONLY
130
+ * @supports docs/stories/003.0-DEV-IDENTIFY-OUTDATED.story.md REQ-AGE-THRESHOLD REQ-OUTPUT
131
+ * @supports docs/stories/004.0-DEV-FILTER-VULNERABLE-VERSIONS.story.md REQ-AUDIT-CHECK REQ-SAFE-ONLY
113
132
  */
114
133
  export async function applyFilters(rows, options) {
115
134
  // combined behavior
@@ -118,22 +137,19 @@ export async function applyFilters(rows, options) {
118
137
 
119
138
  In the "after" example:
120
139
 
121
- - `valid-annotation-format` ensures the `@implements` lines use a valid story path and requirement ID format.
122
- - `valid-req-reference` validates that each requirement listed after `@implements` exists in the corresponding story file.
140
+ - `valid-annotation-format` ensures the `@supports` lines use a valid story path and requirement ID format.
141
+ - `valid-req-reference` validates that each requirement listed after `@supports` exists in the corresponding story file.
123
142
 
124
143
  #### Mixed usage during migration
125
144
 
126
- You can introduce `@implements` gradually without breaking existing code:
145
+ You can introduce `@supports` gradually without breaking existing code:
127
146
 
128
147
  1. Leave existing `@story` and `@req` annotations in place.
129
- 2. Add `@implements` lines that group requirements by story file.
148
+ 2. Add `@supports` lines that group requirements by story file.
130
149
  3. Run ESLint with `traceability/valid-annotation-format` and `traceability/valid-req-reference` enabled to confirm everything passes.
131
- 4. Optionally, once you are comfortable, standardize on using `@implements` for multi-story integration functions while keeping `@story` + `@req` for simple, single-story code.
132
-
133
- For detailed semantics and edge cases (path validation, scoped requirement IDs, and multi-story fixtures), see:
150
+ 4. Optionally, once you are comfortable, standardize on using `@supports` for multi-story integration functions while keeping `@story` + `@req` for simple, single-story code.
134
151
 
135
- - Rule docs: [`docs/rules/valid-annotation-format.md`](../docs/rules/valid-annotation-format.md), [`docs/rules/valid-req-reference.md`](../docs/rules/valid-req-reference.md)
136
- - Story: [`docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md`](../docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md)
152
+ Detailed semantics and edge cases (path validation, scoped requirement IDs, and multi-story fixtures) are ultimately governed by your own stories and requirements. For typical migrations, this guide together with the plugin’s API reference is sufficient.
137
153
 
138
154
  ## 4. Test and Validate
139
155