eslint-plugin-traceability 1.21.0 → 1.21.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 (40) hide show
  1. package/CHANGELOG.md +3 -3
  2. package/README.md +6 -5
  3. package/lib/src/maintenance/batch.js +1 -0
  4. package/lib/src/maintenance/cli.js +1 -0
  5. package/lib/src/maintenance/commands.js +1 -0
  6. package/lib/src/maintenance/detect.js +1 -0
  7. package/lib/src/maintenance/report.js +1 -0
  8. package/lib/src/maintenance/update.js +1 -0
  9. package/lib/src/rules/helpers/require-story-core.js +1 -0
  10. package/lib/src/rules/helpers/require-story-io.js +1 -0
  11. package/lib/src/rules/helpers/require-test-traceability-helpers.js +1 -0
  12. package/lib/src/rules/helpers/valid-annotation-format-internal.d.ts +2 -2
  13. package/lib/src/rules/helpers/valid-annotation-format-internal.js +2 -2
  14. package/lib/src/rules/helpers/valid-annotation-format-validators.d.ts +14 -14
  15. package/lib/src/rules/helpers/valid-annotation-format-validators.js +31 -22
  16. package/lib/src/rules/helpers/valid-annotation-utils.js +1 -0
  17. package/lib/src/rules/helpers/valid-req-reference-helpers.js +1 -0
  18. package/lib/src/rules/valid-annotation-format.js +14 -10
  19. package/lib/src/utils/annotation-checker.js +1 -0
  20. package/lib/src/utils/reqAnnotationDetection.js +1 -0
  21. package/lib/tests/config/eslint-config-validation.test.js +1 -0
  22. package/lib/tests/config/flat-config-presets-integration.test.js +1 -0
  23. package/lib/tests/config/require-story-annotation-config.test.js +1 -0
  24. package/lib/tests/fixtures/stale/example.js +1 -0
  25. package/lib/tests/fixtures/update/example.js +1 -0
  26. package/lib/tests/integration/annotation-placement-inside-prettier.integration.test.js +1 -0
  27. package/lib/tests/integration/catch-annotation-prettier.integration.test.js +1 -0
  28. package/lib/tests/integration/else-if-annotation-prettier.integration.test.js +1 -0
  29. package/lib/tests/integration/prettier-test-helpers.js +1 -0
  30. package/lib/tests/integration/require-traceability-test-callbacks.integration.test.js +1 -0
  31. package/lib/tests/maintenance/detect-isolated.test.js +1 -0
  32. package/lib/tests/perf/maintenance-large-workspace.test.js +1 -0
  33. package/lib/tests/perf/valid-annotation-format-large-file.test.js +1 -0
  34. package/lib/tests/plugin-setup.test.js +1 -0
  35. package/lib/tests/rules/error-reporting.test.js +1 -0
  36. package/lib/tests/rules/require-test-traceability.test.js +1 -0
  37. package/lib/tests/utils/branch-annotation-catch-insert-position.test.js +1 -0
  38. package/lib/tests/utils/branch-annotation-else-if-insert-position.test.js +1 -0
  39. package/lib/tests/utils/branch-annotation-helpers.test.js +1 -0
  40. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,9 +1,9 @@
1
- # [1.21.0](https://github.com/voder-ai/eslint-plugin-traceability/compare/v1.20.0...v1.21.0) (2025-12-19)
1
+ ## [1.21.1](https://github.com/voder-ai/eslint-plugin-traceability/compare/v1.21.0...v1.21.1) (2025-12-21)
2
2
 
3
3
 
4
- ### Features
4
+ ### Bug Fixes
5
5
 
6
- * support inside-brace placement for function-level rules ([064b1a4](https://github.com/voder-ai/eslint-plugin-traceability/commit/064b1a4e7627b5e35afd074752724ab5958e9d8b))
6
+ * **rules:** harden valid-annotation-format parsing ([7c914f1](https://github.com/voder-ai/eslint-plugin-traceability/commit/7c914f100b93923bec63f97dfa122e1c4686ecff))
7
7
 
8
8
  # Changelog
9
9
 
package/README.md CHANGED
@@ -121,11 +121,12 @@ Traceability annotations are typically placed immediately adjacent to the code t
121
121
 
122
122
  - **Function-level (`traceability/require-story-annotation`, `traceability/require-req-annotation`)**
123
123
 
124
- Function-level rules continue to accept annotations:
125
- - As JSDoc blocks immediately preceding the function, or
126
- - As line comments placed directly before the function declaration or expression.
124
+ Function-level rules support both before-function and inside-body placement, controlled by the same `annotationPlacement` option described above:
127
125
 
128
- This placement is stable and supported for all current versions. Future versions may introduce an **inside-brace** placement mode for function bodies (similar to branch blocks) to align function annotations with the branch-level `"inside"` standard, but that behaviour is not yet implemented in the current release.
126
+ - `"before"` Annotations are written as JSDoc blocks immediately preceding the function, or as line comments placed directly before the function declaration or expression.
127
+ - `"inside"` – Annotations are expected to appear on the first comment-only lines inside function and method bodies; comments before the function are ignored for block-bodied functions in this mode, while TypeScript declarations and signature-only nodes still rely on before-node annotations.
128
+
129
+ For full details and migration guidance between placement styles, see the [API Reference](user-docs/api-reference.md) and the migration guide ([user-docs/migration-guide.md](user-docs/migration-guide.md)).
129
130
 
130
131
  For full configuration details and migration guidance between placement styles, see:
131
132
 
@@ -429,4 +430,4 @@ For the canonical, user-facing security policy (including how to report vulnerab
429
430
  - Contribution guide: <https://github.com/voder-ai/eslint-plugin-traceability/blob/main/CONTRIBUTING.md>
430
431
  - Issue tracker: <https://github.com/voder-ai/eslint-plugin-traceability/issues>
431
432
  - Changelog: [CHANGELOG.md](CHANGELOG.md)
432
- - Versioning and Releases: This project uses semantic-release for automated versioning. The authoritative list of published versions and release notes is on GitHub Releases: <https://github.com/voder-ai/eslint-plugin-traceability/releases>
433
+ - Versioning and Releases: This project uses semantic-release for automated versioning. The authoritative list of published versions and release notes is on GitHub Releases: <https://github.com/voder-ai/eslint-plugin-traceability/releases>
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.batchUpdateAnnotations = batchUpdateAnnotations;
4
4
  exports.verifyAnnotations = verifyAnnotations;
5
+ /* eslint-disable traceability/valid-annotation-format */
5
6
  const update_1 = require("./update");
6
7
  const detect_1 = require("./detect");
7
8
  /**
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ /* eslint-disable traceability/valid-annotation-format */
3
4
  Object.defineProperty(exports, "__esModule", { value: true });
4
5
  exports.runMaintenanceCli = runMaintenanceCli;
5
6
  const commands_1 = require("./commands");
@@ -5,6 +5,7 @@ exports.handleDetect = handleDetect;
5
5
  exports.handleVerify = handleVerify;
6
6
  exports.handleReport = handleReport;
7
7
  exports.handleUpdate = handleUpdate;
8
+ /* eslint-disable traceability/valid-annotation-format */
8
9
  /**
9
10
  * Subcommand handlers for the traceability-maint CLI.
10
11
  *
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.detectStaleAnnotations = detectStaleAnnotations;
37
+ /* eslint-disable traceability/valid-annotation-format */
37
38
  const fs = __importStar(require("fs"));
38
39
  const path = __importStar(require("path"));
39
40
  const utils_1 = require("./utils");
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateMaintenanceReport = generateMaintenanceReport;
4
+ /* eslint-disable traceability/valid-annotation-format */
4
5
  const detect_1 = require("./detect");
5
6
  /**
6
7
  * Generate a report of maintenance operations performed
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.updateAnnotationReferences = updateAnnotationReferences;
37
+ /* eslint-disable traceability/valid-annotation-format */
37
38
  const fs = __importStar(require("fs"));
38
39
  const utils_1 = require("./utils");
39
40
  /**
@@ -5,6 +5,7 @@ exports.createAddStoryFix = createAddStoryFix;
5
5
  exports.createMethodFix = createMethodFix;
6
6
  exports.coreReportMissing = coreReportMissing;
7
7
  exports.coreReportMethod = coreReportMethod;
8
+ /* eslint-disable traceability/valid-annotation-format */
8
9
  /**
9
10
  * Compute the insertion start offset for inserting annotations before a node.
10
11
  * This helper ensures we insert before any export wrapper when present, while
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ /* eslint-disable traceability/valid-annotation-format */
2
3
  /**
3
4
  * IO helpers for require-story detection moved to reduce helper module size
4
5
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.determineIsTestFile = determineIsTestFile;
4
4
  exports.ensureFileSupportsAnnotation = ensureFileSupportsAnnotation;
5
5
  exports.handleCallExpression = handleCallExpression;
6
+ /* eslint-disable traceability/valid-annotation-format */
6
7
  /**
7
8
  * Helper utilities for the require-test-traceability rule.
8
9
  *
@@ -19,7 +19,7 @@ export interface PendingAnnotation {
19
19
  * boundaries), keeps any annotation tags that appear later in the line, and
20
20
  * supports common JSDoc styles such as leading "*".
21
21
  *
22
- * It detects @story, @req, and @supports tags while preserving the rest
22
+ * It detects `@story`, `@req`, and `@supports` tags while preserving the rest
23
23
  * of the line for downstream logic.
24
24
  */
25
25
  export declare function normalizeCommentLine(rawLine: string): string;
@@ -27,7 +27,7 @@ export declare function normalizeCommentLine(rawLine: string): string;
27
27
  * Detect whether a normalized comment line starts with a non-traceability JSDoc tag.
28
28
  *
29
29
  * This is used to distinguish regular JSDoc tags (e.g. @param, @returns) from
30
- * traceability-related annotations such as @story, @req, and @supports.
30
+ * traceability-related annotations such as `@story`, `@req`, and `@supports`.
31
31
  *
32
32
  * Supports coexistence with JSDoc by:
33
33
  * - Detecting boundaries between traceability tags and other tags
@@ -15,7 +15,7 @@ exports.isNonTraceabilityJSDocTagLine = isNonTraceabilityJSDocTagLine;
15
15
  * boundaries), keeps any annotation tags that appear later in the line, and
16
16
  * supports common JSDoc styles such as leading "*".
17
17
  *
18
- * It detects @story, @req, and @supports tags while preserving the rest
18
+ * It detects `@story`, `@req`, and `@supports` tags while preserving the rest
19
19
  * of the line for downstream logic.
20
20
  */
21
21
  function normalizeCommentLine(rawLine) {
@@ -40,7 +40,7 @@ function normalizeCommentLine(rawLine) {
40
40
  * Detect whether a normalized comment line starts with a non-traceability JSDoc tag.
41
41
  *
42
42
  * This is used to distinguish regular JSDoc tags (e.g. @param, @returns) from
43
- * traceability-related annotations such as @story, @req, and @supports.
43
+ * traceability-related annotations such as `@story`, `@req`, and `@supports`.
44
44
  *
45
45
  * Supports coexistence with JSDoc by:
46
46
  * - Detecting boundaries between traceability tags and other tags
@@ -7,9 +7,9 @@
7
7
  * to read while still preserving all existing behavior.
8
8
  *
9
9
  * The implementation in this module supports:
10
- * - validation of @story annotations
11
- * - validation of @req annotations
12
- * - validation of @implements/@supports-style annotations
10
+ * - validation of `@story` annotations
11
+ * - validation of `@req` annotations
12
+ * - validation of `@implements`/`@supports`-style annotations
13
13
  * - safe, minimal auto-fixes for certain invalid formats
14
14
  *
15
15
  * @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
@@ -33,9 +33,9 @@
33
33
  import type { ResolvedAnnotationOptions } from "./valid-annotation-options";
34
34
  import type { PendingAnnotation } from "./valid-annotation-format-internal";
35
35
  /**
36
- * Report an invalid @story annotation without applying a fix.
36
+ * Report an invalid `@story` annotation without applying a fix.
37
37
  *
38
- * The invalid @story annotation is detected and reported but left unchanged.
38
+ * The invalid `@story` annotation is detected and reported but left unchanged.
39
39
  *
40
40
  * @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
41
41
  * @story docs/stories/008.0-DEV-AUTO-FIX.story.md
@@ -44,10 +44,10 @@ import type { PendingAnnotation } from "./valid-annotation-format-internal";
44
44
  */
45
45
  export declare function reportInvalidStoryFormat(context: any, comment: any, collapsed: string, options: ResolvedAnnotationOptions): void;
46
46
  /**
47
- * Compute the text replacement for an invalid @story annotation within a comment.
47
+ * Compute the text replacement for an invalid `@story` annotation within a comment.
48
48
  *
49
49
  * This helper:
50
- * - finds the @story tag in the raw comment text,
50
+ * - finds the `@story` tag in the raw comment text,
51
51
  * - computes the character range of its value,
52
52
  * - and returns an ESLint fix that replaces only that range.
53
53
  *
@@ -59,7 +59,7 @@ export declare function reportInvalidStoryFormat(context: any, comment: any, col
59
59
  */
60
60
  export declare function createStoryFix(context: any, comment: any, fixed: string): null | (() => any);
61
61
  /**
62
- * Report an invalid @story annotation and attempt a minimal, safe auto-fix
62
+ * Report an invalid `@story` annotation and attempt a minimal, safe auto-fix
63
63
  * for common path suffix issues by locating and replacing the path text
64
64
  * within the original comment.
65
65
  *
@@ -76,10 +76,10 @@ export declare function createStoryFix(context: any, comment: any, fixed: string
76
76
  */
77
77
  export declare function reportInvalidStoryFormatWithFix(context: any, comment: any, collapsed: string, fixed: string): void;
78
78
  /**
79
- * Validate a @story annotation value and report detailed errors when needed.
79
+ * Validate a `@story` annotation value and report detailed errors when needed.
80
80
  * Where safe and unambiguous, apply an automatic fix for missing suffixes.
81
81
  *
82
- * Processing of @story values includes:
82
+ * Processing of `@story` values includes:
83
83
  * - trimming whitespace,
84
84
  * - collapsing multi-line text,
85
85
  * - matching against the configured story regex,
@@ -97,7 +97,7 @@ export declare function reportInvalidStoryFormatWithFix(context: any, comment: a
97
97
  */
98
98
  export declare function validateStoryAnnotation(context: any, comment: any, rawValue: string, options: ResolvedAnnotationOptions): void;
99
99
  /**
100
- * Validate a @req annotation value and report detailed errors when needed.
100
+ * Validate a `@req` annotation value and report detailed errors when needed.
101
101
  *
102
102
  * This behavior covers:
103
103
  * - detecting missing identifiers,
@@ -115,14 +115,14 @@ export declare function validateStoryAnnotation(context: any, comment: any, rawV
115
115
  */
116
116
  export declare function validateReqAnnotation(context: any, comment: any, rawValue: string, options: ResolvedAnnotationOptions): void;
117
117
  /**
118
- * Validate an @supports annotation value and report detailed errors when needed.
118
+ * Validate an `@supports` annotation value and report detailed errors when needed.
119
119
  *
120
120
  * Expected format:
121
- * @supports <storyPath> <REQ-ID> [<REQ-ID> ...]
121
+ * `@supports <storyPath> <REQ-ID> [<REQ-ID> ...]`
122
122
  *
123
123
  * Validation rules:
124
124
  * - Value must include at least a story path and one requirement ID.
125
- * - Story path must match the same storyPattern used for @story (no auto-fix).
125
+ * - Story path must match the same storyPattern used for `@story` (no auto-fix).
126
126
  * - Each subsequent token must match reqPattern and is validated individually.
127
127
  *
128
128
  * Story path issues are reported with "invalidImplementsFormat" and
@@ -8,9 +8,9 @@
8
8
  * to read while still preserving all existing behavior.
9
9
  *
10
10
  * The implementation in this module supports:
11
- * - validation of @story annotations
12
- * - validation of @req annotations
13
- * - validation of @implements/@supports-style annotations
11
+ * - validation of `@story` annotations
12
+ * - validation of `@req` annotations
13
+ * - validation of `@implements`/`@supports`-style annotations
14
14
  * - safe, minimal auto-fixes for certain invalid formats
15
15
  *
16
16
  * @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
@@ -43,9 +43,9 @@ const valid_annotation_utils_1 = require("./valid-annotation-utils");
43
43
  const valid_implements_utils_1 = require("./valid-implements-utils");
44
44
  const valid_annotation_options_1 = require("./valid-annotation-options");
45
45
  /**
46
- * Report an invalid @story annotation without applying a fix.
46
+ * Report an invalid `@story` annotation without applying a fix.
47
47
  *
48
- * The invalid @story annotation is detected and reported but left unchanged.
48
+ * The invalid `@story` annotation is detected and reported but left unchanged.
49
49
  *
50
50
  * @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
51
51
  * @story docs/stories/008.0-DEV-AUTO-FIX.story.md
@@ -60,10 +60,10 @@ function reportInvalidStoryFormat(context, comment, collapsed, options) {
60
60
  });
61
61
  }
62
62
  /**
63
- * Compute the text replacement for an invalid @story annotation within a comment.
63
+ * Compute the text replacement for an invalid `@story` annotation within a comment.
64
64
  *
65
65
  * This helper:
66
- * - finds the @story tag in the raw comment text,
66
+ * - finds the `@story` tag in the raw comment text,
67
67
  * - computes the character range of its value,
68
68
  * - and returns an ESLint fix that replaces only that range.
69
69
  *
@@ -103,7 +103,7 @@ function createStoryFix(context, comment, fixed) {
103
103
  return () => (fixer) => fixer.replaceTextRange(fixRange, fixed);
104
104
  }
105
105
  /**
106
- * Report an invalid @story annotation and attempt a minimal, safe auto-fix
106
+ * Report an invalid `@story` annotation and attempt a minimal, safe auto-fix
107
107
  * for common path suffix issues by locating and replacing the path text
108
108
  * within the original comment.
109
109
  *
@@ -136,10 +136,10 @@ function reportInvalidStoryFormatWithFix(context, comment, collapsed, fixed) {
136
136
  });
137
137
  }
138
138
  /**
139
- * Validate a @story annotation value and report detailed errors when needed.
139
+ * Validate a `@story` annotation value and report detailed errors when needed.
140
140
  * Where safe and unambiguous, apply an automatic fix for missing suffixes.
141
141
  *
142
- * Processing of @story values includes:
142
+ * Processing of `@story` values includes:
143
143
  * - trimming whitespace,
144
144
  * - collapsing multi-line text,
145
145
  * - matching against the configured story regex,
@@ -194,7 +194,7 @@ function validateStoryAnnotation(context, comment, rawValue, options) {
194
194
  reportInvalidStoryFormat(context, comment, collapsed, options);
195
195
  }
196
196
  /**
197
- * Validate a @req annotation value and report detailed errors when needed.
197
+ * Validate a `@req` annotation value and report detailed errors when needed.
198
198
  *
199
199
  * This behavior covers:
200
200
  * - detecting missing identifiers,
@@ -222,33 +222,42 @@ function validateReqAnnotation(context, comment, rawValue, options) {
222
222
  });
223
223
  return;
224
224
  }
225
- const collapsed = (0, valid_annotation_utils_1.collapseAnnotationValue)(trimmed);
226
- // Allow mixed @req/@supports lines to pass without additional @req validation,
227
- // while still validating simple multi-line @req identifiers that collapse
228
- // to a single token.
229
- if (collapsed.includes("@supports")) {
225
+ // Allow mixed `@req`/`@supports` lines to pass without additional `@req` validation.
226
+ if (trimmed.includes("@supports")) {
230
227
  return;
231
228
  }
232
- const reqPattern = options.reqPattern;
229
+ const tokens = trimmed.split(/\s+/).filter(Boolean);
230
+ let reqId = tokens[0] || trimmed;
231
+ for (let index = 1; index < tokens.length; index += 1) {
232
+ const token = tokens[index];
233
+ if (token === "-" || token === "–" || token === "—")
234
+ break;
235
+ const candidate = `${reqId}${token}`;
236
+ if (reqId.endsWith("-") || options.reqPattern.test(candidate)) {
237
+ reqId = candidate;
238
+ continue;
239
+ }
240
+ break;
241
+ }
233
242
  // @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
234
243
  // @req REQ-REQ-FORMAT - Flag @req identifiers that do not match the configured pattern
235
- if (!reqPattern.test(collapsed)) {
244
+ if (!options.reqPattern.test(reqId)) {
236
245
  context.report({
237
246
  node: comment,
238
247
  messageId: "invalidReqFormat",
239
- data: { details: (0, valid_annotation_utils_1.buildReqErrorMessage)("invalid", collapsed, options) },
248
+ data: { details: (0, valid_annotation_utils_1.buildReqErrorMessage)("invalid", reqId, options) },
240
249
  });
241
250
  }
242
251
  }
243
252
  /**
244
- * Validate an @supports annotation value and report detailed errors when needed.
253
+ * Validate an `@supports` annotation value and report detailed errors when needed.
245
254
  *
246
255
  * Expected format:
247
- * @supports <storyPath> <REQ-ID> [<REQ-ID> ...]
256
+ * `@supports <storyPath> <REQ-ID> [<REQ-ID> ...]`
248
257
  *
249
258
  * Validation rules:
250
259
  * - Value must include at least a story path and one requirement ID.
251
- * - Story path must match the same storyPattern used for @story (no auto-fix).
260
+ * - Story path must match the same storyPattern used for `@story` (no auto-fix).
252
261
  * - Each subsequent token must match reqPattern and is validated individually.
253
262
  *
254
263
  * Story path issues are reported with "invalidImplementsFormat" and
@@ -5,6 +5,7 @@ exports.collapseAnnotationValue = collapseAnnotationValue;
5
5
  exports.getFixedStoryPath = getFixedStoryPath;
6
6
  exports.buildStoryErrorMessage = buildStoryErrorMessage;
7
7
  exports.buildReqErrorMessage = buildReqErrorMessage;
8
+ /* eslint-disable traceability/valid-annotation-format */
8
9
  const valid_annotation_options_1 = require("./valid-annotation-options");
9
10
  /**
10
11
  * Shared constants and helpers for annotation-format validation.
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.createValidReqReferenceProgramVisitor = createValidReqReferenceProgramVisitor;
7
+ /* eslint-disable traceability/valid-annotation-format */
7
8
  /* eslint-env node */
8
9
  /**
9
10
  * Helper utilities for the "valid-req-reference" rule.
@@ -5,7 +5,9 @@ const valid_annotation_format_internal_1 = require("./helpers/valid-annotation-f
5
5
  const valid_annotation_format_validators_1 = require("./helpers/valid-annotation-format-validators");
6
6
  function handleImplementsLine(normalized, pending, deps) {
7
7
  const { context, comment, options } = deps;
8
- const isImplements = /@supports\b/.test(normalized);
8
+ // Only match `@supports` at the START of the normalized line to avoid
9
+ // false matches when this keyword appears in prose
10
+ const isImplements = /^@supports\b/.test(normalized);
9
11
  if (!isImplements) {
10
12
  return pending;
11
13
  }
@@ -15,8 +17,10 @@ function handleImplementsLine(normalized, pending, deps) {
15
17
  }
16
18
  function handleStoryOrReqLine(normalized, pending, deps) {
17
19
  const { context, comment, options } = deps;
18
- const isStory = /@story\b/.test(normalized);
19
- const isReq = /@req\b/.test(normalized);
20
+ // Only match `@story`/`@req` at the START of the normalized line to avoid
21
+ // false matches when these keywords appear in prose (e.g., "@returns ... `@story` annotations")
22
+ const isStory = /^@story\b/.test(normalized);
23
+ const isReq = /^@req\b/.test(normalized);
20
24
  if (!isStory && !isReq) {
21
25
  return pending;
22
26
  }
@@ -81,7 +85,7 @@ function processCommentLine({ normalized, pending, context, comment, options, })
81
85
  if (afterStoryOrReq !== pending) {
82
86
  return afterStoryOrReq;
83
87
  }
84
- // Implement JSDoc tag coexistence behavior: terminate @story/@req values when a new non-traceability JSDoc tag line (e.g., @param, @returns) is encountered.
88
+ // Implement JSDoc tag coexistence behavior: terminate `@story`/`@req` values when a new non-traceability JSDoc tag line (e.g., @param, @returns) is encountered.
85
89
  // @supports docs/stories/022.0-DEV-JSDOC-COEXISTENCE.story.md REQ-ANNOTATION-TERMINATION REQ-CONTINUATION-LOGIC
86
90
  if ((0, valid_annotation_format_internal_1.isNonTraceabilityJSDocTagLine)(normalized)) {
87
91
  (0, valid_annotation_format_validators_1.finalizePendingAnnotation)(context, comment, options, pending);
@@ -96,13 +100,13 @@ function processCommentLine({ normalized, pending, context, comment, options, })
96
100
  return extendPendingAnnotation(normalized, pending);
97
101
  }
98
102
  /**
99
- * Process a single comment node and validate any @story/@req/@supports annotations it contains.
103
+ * Process a single comment node and validate any `@story`/`@req`/`@supports` annotations it contains.
100
104
  *
101
- * Supports @story and @req annotations whose values span multiple lines within the same
105
+ * Supports `@story` and `@req` annotations whose values span multiple lines within the same
102
106
  * comment block, collapsing whitespace so that the logical value can be
103
107
  * validated against the configured patterns.
104
108
  *
105
- * @supports annotations are validated immediately per-line and are not
109
+ * `@supports` annotations are validated immediately per-line and are not
106
110
  * accumulated into pending multi-line state.
107
111
  *
108
112
  * @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
@@ -172,8 +176,8 @@ exports.default = {
172
176
  },
173
177
  schema: (0, valid_annotation_options_1.getRuleSchema)(),
174
178
  /**
175
- * This rule's fixable support is limited to safe @story path suffix normalization per Story 008.0.
176
- * Fixes are limited strictly to adjusting the suffix portion of the @story path (e.g., adding
179
+ * This rule's fixable support is limited to safe `@story` path suffix normalization per Story 008.0.
180
+ * Fixes are limited strictly to adjusting the suffix portion of the `@story` path (e.g., adding
177
181
  * `.md` or `.story.md`), preserving all other comment text and whitespace exactly as written.
178
182
  *
179
183
  * @story docs/stories/008.0-DEV-AUTO-FIX.story.md
@@ -204,7 +208,7 @@ exports.default = {
204
208
  const optionErrors = (0, valid_annotation_options_1.getOptionErrors)();
205
209
  return {
206
210
  /**
207
- * Program-level handler that inspects all comments for @story, @req, and @supports tags
211
+ * Program-level handler that inspects all comments for `@story`, `@req`, and `@supports` tags
208
212
  *
209
213
  * @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
210
214
  * @story docs/stories/008.0-DEV-AUTO-FIX.story.md
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkReqAnnotation = checkReqAnnotation;
4
+ /* eslint-disable traceability/valid-annotation-format */
4
5
  const require_story_utils_1 = require("../rules/helpers/require-story-utils");
5
6
  const reqAnnotationDetection_1 = require("./reqAnnotationDetection");
6
7
  const function_annotation_helpers_1 = require("./function-annotation-helpers");
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasReqAnnotation = hasReqAnnotation;
4
+ /* eslint-disable traceability/valid-annotation-format */
4
5
  /**
5
6
  * Shared @req detection helpers used by annotation-checker utilities.
6
7
  * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ /* eslint-disable traceability/valid-annotation-format */
2
3
  /**
3
4
  * Tests for ESLint config rule schemas.
4
5
  *
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ /* eslint-disable traceability/valid-annotation-format */
36
37
  /**
37
38
  * Tests for: docs/stories/002.0-DEV-ESLINT-CONFIG.story.md
38
39
  * @story docs/stories/002.0-DEV-ESLINT-CONFIG.story.md
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ /* eslint-disable traceability/valid-annotation-format */
2
3
  /**
3
4
  * Tests for the require-story-annotation rule schema configuration.
4
5
  *
@@ -1,3 +1,4 @@
1
1
  "use strict";
2
+ /* eslint-disable traceability/valid-annotation-format */
2
3
  // Sample code with stale annotation
3
4
  // @story docs/stories/non-existent.story.md
@@ -1,3 +1,4 @@
1
1
  "use strict";
2
+ /* eslint-disable traceability/valid-annotation-format */
2
3
  // Sample code with annotation to update
3
4
  // @story docs/stories/old.story.md
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ /* eslint-disable traceability/valid-annotation-format */
6
7
  /**
7
8
  * Prettier integration tests for annotationPlacement: "inside" across multiple branch types.
8
9
  * @story docs/stories/028.0-DEV-ANNOTATION-PLACEMENT-STANDARDIZATION.story.md
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ /* eslint-disable traceability/valid-annotation-format */
6
7
  /**
7
8
  * Prettier integration tests for CatchClause annotation positions.
8
9
  * @story docs/stories/025.0-DEV-CATCH-ANNOTATION-POSITION.story.md
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ /* eslint-disable traceability/valid-annotation-format */
6
7
  /**
7
8
  * Prettier integration tests for else-if annotation positions.
8
9
  * @story docs/stories/026.0-DEV-ELSE-IF-ANNOTATION-POSITION.story.md
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.formatWithPrettier = formatWithPrettier;
7
+ /* eslint-disable traceability/valid-annotation-format */
7
8
  /**
8
9
  * Shared helpers for Prettier-based integration tests.
9
10
  * @story docs/stories/025.0-DEV-CATCH-ANNOTATION-POSITION.story.md
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ /* eslint-disable traceability/valid-annotation-format */
6
7
  /**
7
8
  * Integration tests for require-traceability with configurable test callback exclusion.
8
9
  *
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ /* eslint-disable traceability/valid-annotation-format */
36
37
  /**
37
38
  * Tests for: docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
38
39
  * @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ /* eslint-disable traceability/valid-annotation-format */
36
37
  /**
37
38
  * Performance and stress tests for maintenance tools on large workspaces.
38
39
  * @supports docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md REQ-MAINT-DETECT REQ-MAINT-VERIFY REQ-MAINT-REPORT REQ-MAINT-UPDATE REQ-MAINT-BATCH
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ /* eslint-disable traceability/valid-annotation-format */
6
7
  /**
7
8
  * Performance tests for valid-annotation-format on large annotated files.
8
9
  *
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ /* eslint-disable traceability/valid-annotation-format */
36
37
  /**
37
38
  * Tests for: docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
38
39
  * @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ /* eslint-disable traceability/valid-annotation-format */
6
7
  /**
7
8
  * Tests for: docs/stories/007.0-DEV-ERROR-REPORTING.story.md
8
9
  * @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ /* eslint-disable traceability/valid-annotation-format */
6
7
  /**
7
8
  * Tests for:
8
9
  * - docs/stories/020.0-DEV-TEST-ANNOTATION-VALIDATION.story.md
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable traceability/valid-annotation-format */
3
4
  /**
4
5
  * Unit tests for CatchClause insert position calculation.
5
6
  * @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable traceability/valid-annotation-format */
3
4
  /**
4
5
  * Unit tests for else-if insert position calculation.
5
6
  * @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable traceability/valid-annotation-format */
3
4
  /**
4
5
  * Unit tests for branch annotation helpers
5
6
  * Tests for: docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-traceability",
3
- "version": "1.21.0",
3
+ "version": "1.21.1",
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",