eslint-plugin-traceability 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/.env.example +6 -0
  2. package/.github/workflows/ci-cd.yml +56 -0
  3. package/.husky/pre-commit +1 -0
  4. package/.husky/pre-push +1 -0
  5. package/.prettierignore +23 -0
  6. package/.prettierrc +4 -0
  7. package/.voder/history.md +164 -0
  8. package/.voder/implementation-progress.md +145 -0
  9. package/.voder/last-action.md +106 -0
  10. package/.voder/plan.md +15 -0
  11. package/.voder/progress-chart.png +0 -0
  12. package/.voder/progress-log-areas.csv +34 -0
  13. package/.voder/progress-log.csv +33 -0
  14. package/.voder/traceability/docs-stories-001.0-DEV-PLUGIN-SETUP.story.xml +17 -0
  15. package/.voder/traceability/docs-stories-002.0-DEV-ESLINT-CONFIG.story.xml +13 -0
  16. package/.voder/traceability/docs-stories-003.0-DEV-FUNCTION-ANNOTATIONS.story.xml +9 -0
  17. package/.voder/traceability/docs-stories-004.0-DEV-BRANCH-ANNOTATIONS.story.xml +9 -0
  18. package/.voder/traceability/docs-stories-005.0-DEV-ANNOTATION-VALIDATION.story.xml +9 -0
  19. package/.voder/traceability/docs-stories-006.0-DEV-FILE-VALIDATION.story.xml +9 -0
  20. package/.voder/traceability/docs-stories-007.0-DEV-ERROR-REPORTING.story.xml +9 -0
  21. package/.voder/traceability/docs-stories-008.0-DEV-AUTO-FIX.story.xml +9 -0
  22. package/.voder/traceability/docs-stories-009.0-DEV-MAINTENANCE-TOOLS.story.xml +16 -0
  23. package/.voder/traceability/docs-stories-010.0-DEV-DEEP-VALIDATION.story.xml +11 -0
  24. package/CHANGELOG.md +31 -0
  25. package/CONTRIBUTING.md +97 -0
  26. package/LICENSE +21 -0
  27. package/README.md +159 -0
  28. package/cli-integration.js +157 -0
  29. package/docs/cli-integration.md +103 -0
  30. package/docs/config-presets.md +38 -0
  31. package/docs/decisions/001-typescript-for-eslint-plugin.accepted.md +111 -0
  32. package/docs/decisions/002-jest-for-eslint-testing.accepted.md +137 -0
  33. package/docs/decisions/003-code-quality-ratcheting-plan.md +48 -0
  34. package/docs/eslint-9-setup-guide.md +517 -0
  35. package/docs/eslint-plugin-development-guide.md +483 -0
  36. package/docs/jest-testing-guide.md +100 -0
  37. package/docs/rules/require-branch-annotation.md +34 -0
  38. package/docs/rules/require-req-annotation.md +39 -0
  39. package/docs/rules/require-story-annotation.md +36 -0
  40. package/docs/rules/valid-annotation-format.md +52 -0
  41. package/docs/rules/valid-req-reference.md +58 -0
  42. package/docs/rules/valid-story-reference.md +47 -0
  43. package/docs/security-incidents/unresolved-vulnerabilities.md +11 -0
  44. package/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md +82 -0
  45. package/docs/stories/002.0-DEV-ESLINT-CONFIG.story.md +82 -0
  46. package/docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md +85 -0
  47. package/docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md +107 -0
  48. package/docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md +119 -0
  49. package/docs/stories/006.0-DEV-FILE-VALIDATION.story.md +127 -0
  50. package/docs/stories/007.0-DEV-ERROR-REPORTING.story.md +89 -0
  51. package/docs/stories/008.0-DEV-AUTO-FIX.story.md +104 -0
  52. package/docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md +104 -0
  53. package/docs/stories/010.0-DEV-DEEP-VALIDATION.story.md +110 -0
  54. package/docs/stories/developer-story.map.md +118 -0
  55. package/eslint.config.js +146 -0
  56. package/jest.config.js +21 -0
  57. package/lib/index.d.ts +26 -0
  58. package/lib/index.js +11 -0
  59. package/lib/src/index.d.ts +80 -0
  60. package/lib/src/index.js +58 -0
  61. package/lib/src/maintenance/batch.d.ts +16 -0
  62. package/lib/src/maintenance/batch.js +28 -0
  63. package/lib/src/maintenance/detect.d.ts +6 -0
  64. package/lib/src/maintenance/detect.js +69 -0
  65. package/lib/src/maintenance/index.d.ts +14 -0
  66. package/lib/src/maintenance/index.js +22 -0
  67. package/lib/src/maintenance/report.d.ts +7 -0
  68. package/lib/src/maintenance/report.js +17 -0
  69. package/lib/src/maintenance/update.d.ts +6 -0
  70. package/lib/src/maintenance/update.js +67 -0
  71. package/lib/src/maintenance/utils.d.ts +6 -0
  72. package/lib/src/maintenance/utils.js +64 -0
  73. package/lib/src/rules/require-branch-annotation.d.ts +7 -0
  74. package/lib/src/rules/require-branch-annotation.js +111 -0
  75. package/lib/src/rules/require-req-annotation.d.ts +7 -0
  76. package/lib/src/rules/require-req-annotation.js +38 -0
  77. package/lib/src/rules/require-story-annotation.d.ts +7 -0
  78. package/lib/src/rules/require-story-annotation.js +50 -0
  79. package/lib/src/rules/valid-annotation-format.d.ts +10 -0
  80. package/lib/src/rules/valid-annotation-format.js +60 -0
  81. package/lib/src/rules/valid-req-reference.d.ts +3 -0
  82. package/lib/src/rules/valid-req-reference.js +104 -0
  83. package/lib/src/rules/valid-story-reference.d.ts +3 -0
  84. package/lib/src/rules/valid-story-reference.js +168 -0
  85. package/lib/tests/basic.test.d.ts +1 -0
  86. package/lib/tests/basic.test.js +51 -0
  87. package/lib/tests/fixtures/stale/example.d.ts +0 -0
  88. package/lib/tests/fixtures/stale/example.js +3 -0
  89. package/lib/tests/fixtures/update/example.d.ts +0 -0
  90. package/lib/tests/fixtures/update/example.js +3 -0
  91. package/lib/tests/fixtures/valid-annotations/example.d.ts +0 -0
  92. package/lib/tests/fixtures/valid-annotations/example.js +3 -0
  93. package/lib/tests/index.test.d.ts +1 -0
  94. package/lib/tests/index.test.js +68 -0
  95. package/lib/tests/integration/file-validation.test.d.ts +1 -0
  96. package/lib/tests/integration/file-validation.test.js +60 -0
  97. package/lib/tests/integration/plugin-validation.test.d.ts +1 -0
  98. package/lib/tests/integration/plugin-validation.test.js +77 -0
  99. package/lib/tests/maintenance/batch.test.d.ts +1 -0
  100. package/lib/tests/maintenance/batch.test.js +79 -0
  101. package/lib/tests/maintenance/detect-isolated.test.d.ts +1 -0
  102. package/lib/tests/maintenance/detect-isolated.test.js +90 -0
  103. package/lib/tests/maintenance/detect.test.d.ts +1 -0
  104. package/lib/tests/maintenance/detect.test.js +23 -0
  105. package/lib/tests/maintenance/report.test.d.ts +1 -0
  106. package/lib/tests/maintenance/report.test.js +67 -0
  107. package/lib/tests/maintenance/update-isolated.test.d.ts +1 -0
  108. package/lib/tests/maintenance/update-isolated.test.js +66 -0
  109. package/lib/tests/maintenance/update.test.d.ts +1 -0
  110. package/lib/tests/maintenance/update.test.js +26 -0
  111. package/lib/tests/rules/require-branch-annotation.test.d.ts +1 -0
  112. package/lib/tests/rules/require-branch-annotation.test.js +251 -0
  113. package/lib/tests/rules/require-req-annotation.test.d.ts +1 -0
  114. package/lib/tests/rules/require-req-annotation.test.js +41 -0
  115. package/lib/tests/rules/require-story-annotation.test.d.ts +1 -0
  116. package/lib/tests/rules/require-story-annotation.test.js +35 -0
  117. package/lib/tests/rules/valid-annotation-format.test.d.ts +1 -0
  118. package/lib/tests/rules/valid-annotation-format.test.js +58 -0
  119. package/lib/tests/rules/valid-req-reference.test.d.ts +1 -0
  120. package/lib/tests/rules/valid-req-reference.test.js +87 -0
  121. package/lib/tests/rules/valid-story-reference.test.d.ts +1 -0
  122. package/lib/tests/rules/valid-story-reference.test.js +69 -0
  123. package/package.json +67 -0
  124. package/src/index.ts +56 -0
  125. package/src/maintenance/batch.ts +29 -0
  126. package/src/maintenance/detect.ts +42 -0
  127. package/src/maintenance/index.ts +14 -0
  128. package/src/maintenance/report.ts +15 -0
  129. package/src/maintenance/update.ts +40 -0
  130. package/src/maintenance/utils.ts +28 -0
  131. package/src/rules/require-branch-annotation.ts +114 -0
  132. package/src/rules/require-req-annotation.ts +36 -0
  133. package/src/rules/require-story-annotation.ts +52 -0
  134. package/src/rules/valid-annotation-format.ts +62 -0
  135. package/src/rules/valid-req-reference.ts +114 -0
  136. package/src/rules/valid-story-reference.ts +213 -0
  137. package/tests/basic.test.ts +17 -0
  138. package/tests/fixtures/stale/example.ts +2 -0
  139. package/tests/fixtures/story_bullet.md +6 -0
  140. package/tests/fixtures/update/example.ts +2 -0
  141. package/tests/fixtures/valid-annotations/example.ts +2 -0
  142. package/tests/index.test.ts +46 -0
  143. package/tests/integration/file-validation.test.ts +67 -0
  144. package/tests/integration/plugin-validation.test.ts +79 -0
  145. package/tests/maintenance/batch.test.ts +55 -0
  146. package/tests/maintenance/detect-isolated.test.ts +61 -0
  147. package/tests/maintenance/detect.test.ts +19 -0
  148. package/tests/maintenance/report.test.ts +37 -0
  149. package/tests/maintenance/update-isolated.test.ts +39 -0
  150. package/tests/maintenance/update.test.ts +21 -0
  151. package/tests/rules/require-branch-annotation.test.ts +248 -0
  152. package/tests/rules/require-req-annotation.test.ts +38 -0
  153. package/tests/rules/require-story-annotation.test.ts +32 -0
  154. package/tests/rules/valid-annotation-format.test.ts +55 -0
  155. package/tests/rules/valid-req-reference.test.ts +85 -0
  156. package/tests/rules/valid-story-reference.test.ts +66 -0
  157. package/tsconfig.json +15 -0
  158. package/user-docs/api-reference.md +135 -0
  159. package/user-docs/examples.md +73 -0
@@ -0,0 +1,483 @@
1
+ # ESLint Plugin Development Guidance
2
+
3
+ This document provides comprehensive guidance for developing ESLint plugins, specifically tailored for the eslint-plugin-traceability project. It's based on the official [ESLint plugin documentation](https://eslint.org/docs/latest/extend/plugins) and includes project-specific considerations.
4
+
5
+ ## Plugin Structure Overview
6
+
7
+ An ESLint plugin is a JavaScript object that exposes specific properties to ESLint:
8
+
9
+ - `meta` - information about the plugin
10
+ - `configs` - an object containing named configurations
11
+ - `rules` - an object containing custom rule definitions
12
+ - `processors` - an object containing named processors
13
+
14
+ ## Basic Plugin Template
15
+
16
+ ```typescript
17
+ // src/index.ts
18
+ const plugin = {
19
+ meta: {
20
+ name: "eslint-plugin-traceability",
21
+ version: "1.0.0",
22
+ namespace: "traceability",
23
+ },
24
+ configs: {},
25
+ rules: {},
26
+ processors: {},
27
+ };
28
+
29
+ // for ESM source (compiled to CommonJS)
30
+ export default plugin;
31
+ ```
32
+
33
+ ## Meta Data Requirements
34
+
35
+ ### Essential Meta Properties
36
+
37
+ Every plugin should include meta information for debugging and caching:
38
+
39
+ ```typescript
40
+ const plugin = {
41
+ meta: {
42
+ name: "eslint-plugin-traceability", // npm package name
43
+ version: "1.0.0", // npm package version
44
+ namespace: "traceability", // prefix for rules/configs
45
+ },
46
+ // ... other properties
47
+ };
48
+ ```
49
+
50
+ ### Reading from package.json
51
+
52
+ For maintainability, read name and version from package.json:
53
+
54
+ ```typescript
55
+ import fs from "fs";
56
+ import { fileURLToPath } from "url";
57
+ import { dirname, join } from "path";
58
+
59
+ const __filename = fileURLToPath(import.meta.url);
60
+ const __dirname = dirname(__filename);
61
+
62
+ const pkg = JSON.parse(
63
+ fs.readFileSync(join(__dirname, "../package.json"), "utf8"),
64
+ );
65
+
66
+ const plugin = {
67
+ meta: {
68
+ name: pkg.name,
69
+ version: pkg.version,
70
+ namespace: "traceability",
71
+ },
72
+ // ... other properties
73
+ };
74
+ ```
75
+
76
+ ## Rule Development
77
+
78
+ ### Rule Structure
79
+
80
+ Rules are the core functionality of an ESLint plugin:
81
+
82
+ ```typescript
83
+ const plugin = {
84
+ meta: {
85
+ name: "eslint-plugin-traceability",
86
+ version: "1.0.0",
87
+ namespace: "traceability",
88
+ },
89
+ rules: {
90
+ "require-story-annotation": {
91
+ meta: {
92
+ type: "problem",
93
+ docs: {
94
+ description: "require @story annotations on functions",
95
+ category: "Traceability",
96
+ recommended: true,
97
+ },
98
+ schema: [
99
+ {
100
+ type: "object",
101
+ properties: {
102
+ // rule options
103
+ },
104
+ additionalProperties: false,
105
+ },
106
+ ],
107
+ messages: {
108
+ missingStory: "Function '{{name}}' is missing @story annotation",
109
+ invalidStoryFormat: "@story annotation format is invalid: {{format}}",
110
+ },
111
+ },
112
+ create(context) {
113
+ return {
114
+ FunctionDeclaration(node) {
115
+ // rule implementation
116
+ },
117
+ };
118
+ },
119
+ },
120
+ },
121
+ };
122
+ ```
123
+
124
+ ### Rule Implementation Guidelines
125
+
126
+ 1. **Use TypeScript for type safety**: Leverage @typescript-eslint/utils for AST manipulation
127
+ 2. **Clear error messages**: Provide helpful, actionable error messages
128
+ 3. **Configurable options**: Allow users to customize rule behavior
129
+ 4. **Performance**: Avoid expensive operations in visitors
130
+ 5. **Testing**: Use ESLint's RuleTester for comprehensive testing
131
+
132
+ ### AST Node Handling
133
+
134
+ When working with AST nodes, use TypeScript for safety:
135
+
136
+ ```typescript
137
+ import { TSESTree } from "@typescript-eslint/utils";
138
+
139
+ function checkFunctionAnnotation(node: TSESTree.FunctionDeclaration) {
140
+ // Type-safe AST manipulation
141
+ if (node.id?.name) {
142
+ // Check for @story annotation in comments
143
+ }
144
+ }
145
+ ```
146
+
147
+ ## Configuration Presets
148
+
149
+ ### Recommended Configuration
150
+
151
+ Provide a recommended configuration for common use cases:
152
+
153
+ ```typescript
154
+ const plugin = {
155
+ // ... meta and rules
156
+ configs: {},
157
+ };
158
+
159
+ // Assign configs after plugin definition to reference plugin
160
+ Object.assign(plugin.configs, {
161
+ recommended: [
162
+ {
163
+ plugins: {
164
+ traceability: plugin,
165
+ },
166
+ rules: {
167
+ "traceability/require-story-annotation": "error",
168
+ "traceability/require-req-annotation": "error",
169
+ "traceability/valid-story-reference": "error",
170
+ "traceability/valid-req-reference": "error",
171
+ },
172
+ },
173
+ ],
174
+ strict: [
175
+ {
176
+ plugins: {
177
+ traceability: plugin,
178
+ },
179
+ rules: {
180
+ "traceability/require-story-annotation": "error",
181
+ "traceability/require-req-annotation": "error",
182
+ "traceability/valid-story-reference": "error",
183
+ "traceability/valid-req-reference": "error",
184
+ "traceability/require-branch-annotation": "error",
185
+ },
186
+ },
187
+ ],
188
+ });
189
+ ```
190
+
191
+ ### Configuration Usage
192
+
193
+ Users can extend configurations in their eslint.config.js:
194
+
195
+ ```javascript
196
+ // eslint.config.js
197
+ import { defineConfig } from "eslint/config";
198
+ import traceability from "eslint-plugin-traceability";
199
+
200
+ export default defineConfig([
201
+ {
202
+ files: ["src/**/*.{js,ts}"],
203
+ plugins: {
204
+ traceability,
205
+ },
206
+ extends: ["traceability/recommended"],
207
+ },
208
+ ]);
209
+ ```
210
+
211
+ ## Testing Strategy
212
+
213
+ ### Using ESLint's RuleTester
214
+
215
+ ```typescript
216
+ // tests/rules/require-story-annotation.test.ts
217
+ import { RuleTester } from "eslint";
218
+ import rule from "../../src/rules/require-story-annotation";
219
+
220
+ const ruleTester = new RuleTester({
221
+ parser: require.resolve("@typescript-eslint/parser"),
222
+ parserOptions: {
223
+ ecmaVersion: 2020,
224
+ sourceType: "module",
225
+ },
226
+ });
227
+
228
+ ruleTester.run("require-story-annotation", rule, {
229
+ valid: [
230
+ {
231
+ code: `
232
+ /**
233
+ * @story docs/stories/001.0-DEV-EXAMPLE.story.md
234
+ * @req REQ-EXAMPLE
235
+ */
236
+ function validFunction() {}
237
+ `,
238
+ },
239
+ ],
240
+ invalid: [
241
+ {
242
+ code: `function invalidFunction() {}`,
243
+ errors: [
244
+ {
245
+ messageId: "missingStory",
246
+ data: { name: "invalidFunction" },
247
+ },
248
+ ],
249
+ },
250
+ ],
251
+ });
252
+ ```
253
+
254
+ ### Test Organization
255
+
256
+ - **Unit tests**: Test individual rules in isolation
257
+ - **Integration tests**: Test plugin loading and configuration
258
+ - **File system tests**: Test file reference validation (use temporary directories)
259
+
260
+ ## Project-Specific Considerations
261
+
262
+ ### File System Integration
263
+
264
+ For validating @story references to actual files:
265
+
266
+ ```typescript
267
+ import fs from "fs/promises";
268
+ import path from "path";
269
+
270
+ async function validateStoryFile(
271
+ storyPath: string,
272
+ context: any,
273
+ ): Promise<boolean> {
274
+ try {
275
+ const fullPath = path.resolve(context.getCwd(), storyPath);
276
+
277
+ // Check file exists
278
+ await fs.access(fullPath);
279
+
280
+ // Check file extension
281
+ if (!fullPath.endsWith(".story.md")) {
282
+ return false;
283
+ }
284
+
285
+ return true;
286
+ } catch {
287
+ return false;
288
+ }
289
+ }
290
+ ```
291
+
292
+ ### Requirement Reference Validation
293
+
294
+ For validating @req references within story files:
295
+
296
+ ```typescript
297
+ async function validateRequirement(
298
+ storyPath: string,
299
+ reqId: string,
300
+ ): Promise<boolean> {
301
+ try {
302
+ const content = await fs.readFile(storyPath, "utf8");
303
+
304
+ // Look for requirement ID in story content
305
+ const reqPattern = new RegExp(`\\*\\*${reqId}\\*\\*:`, "g");
306
+ return reqPattern.test(content);
307
+ } catch {
308
+ return false;
309
+ }
310
+ }
311
+ ```
312
+
313
+ ### Configuration Options
314
+
315
+ Allow users to customize behavior:
316
+
317
+ ```typescript
318
+ interface RuleOptions {
319
+ storyFilePattern?: string; // Default: "**/*.story.md"
320
+ requirementPattern?: string; // Default: "REQ-*"
321
+ excludePatterns?: string[]; // Files to exclude
322
+ includePrivateFunctions?: boolean; // Default: false
323
+ }
324
+ ```
325
+
326
+ ## Build and Distribution
327
+
328
+ ### TypeScript Configuration
329
+
330
+ Configure TypeScript to output CommonJS for ESLint compatibility:
331
+
332
+ ```json
333
+ // tsconfig.json
334
+ {
335
+ "compilerOptions": {
336
+ "target": "ES2020",
337
+ "module": "commonjs",
338
+ "moduleResolution": "node",
339
+ "declaration": true,
340
+ "outDir": "./lib",
341
+ "strict": true
342
+ },
343
+ "include": ["src/**/*"],
344
+ "exclude": ["node_modules", "lib", "tests"]
345
+ }
346
+ ```
347
+
348
+ ### Package.json Configuration
349
+
350
+ Essential package.json settings for ESLint plugins:
351
+
352
+ ```json
353
+ {
354
+ "name": "eslint-plugin-traceability",
355
+ "version": "1.0.0",
356
+ "description": "ESLint plugin for enforcing code traceability annotations",
357
+ "main": "lib/index.js",
358
+ "types": "lib/index.d.ts",
359
+ "keywords": ["eslint", "eslintplugin", "eslint-plugin", "traceability"],
360
+ "peerDependencies": {
361
+ "eslint": ">=9.0.0"
362
+ },
363
+ "engines": {
364
+ "node": ">=18.0.0"
365
+ }
366
+ }
367
+ ```
368
+
369
+ ## Development Workflow
370
+
371
+ ### Local Testing
372
+
373
+ 1. **Link locally**: Use `npm link` for local development
374
+ 2. **Test project**: Create a test project to verify plugin behavior
375
+ 3. **Rule tester**: Use ESLint's RuleTester for individual rule testing
376
+ 4. **Integration testing**: Test complete plugin configuration
377
+
378
+ ### Quality Checks
379
+
380
+ Recommended linting for the plugin itself:
381
+
382
+ ```javascript
383
+ // eslint.config.js (for the plugin project)
384
+ import js from "@eslint/js";
385
+ import typescript from "@typescript-eslint/eslint-plugin";
386
+ import eslintPlugin from "eslint-plugin-eslint-plugin";
387
+
388
+ export default [
389
+ js.configs.recommended,
390
+ {
391
+ plugins: {
392
+ "@typescript-eslint": typescript,
393
+ "eslint-plugin": eslintPlugin,
394
+ },
395
+ rules: {
396
+ // Plugin-specific linting rules
397
+ },
398
+ },
399
+ ];
400
+ ```
401
+
402
+ ## Performance Considerations
403
+
404
+ ### Efficient AST Traversal
405
+
406
+ - **Minimal visitors**: Only register for needed node types
407
+ - **Early returns**: Exit early when conditions aren't met
408
+ - **Caching**: Cache expensive operations (file reads, regex compilation)
409
+ - **Async handling**: Use proper async patterns for file operations
410
+
411
+ ### Memory Management
412
+
413
+ - **Avoid global state**: Keep rule instances isolated
414
+ - **Clean up resources**: Properly handle file handles and timers
415
+ - **Limit recursion**: Avoid deep recursive operations
416
+
417
+ ## Documentation Requirements
418
+
419
+ ### Rule Documentation
420
+
421
+ Each rule should have comprehensive documentation:
422
+
423
+ ```typescript
424
+ const rule = {
425
+ meta: {
426
+ docs: {
427
+ description: "require @story annotations on functions",
428
+ category: "Traceability",
429
+ recommended: true,
430
+ url: "https://github.com/voder-ai/eslint-plugin-traceability#require-story-annotation",
431
+ },
432
+ // ... other meta properties
433
+ },
434
+ // ... rule implementation
435
+ };
436
+ ```
437
+
438
+ ### README Structure
439
+
440
+ Include in the plugin README:
441
+
442
+ 1. **Installation instructions**
443
+ 2. **Configuration examples**
444
+ 3. **Rule documentation**
445
+ 4. **Usage examples**
446
+ 5. **Troubleshooting guide**
447
+
448
+ ## Security Considerations
449
+
450
+ ### File System Access
451
+
452
+ - **Validate paths**: Prevent directory traversal attacks
453
+ - **Sanitize input**: Validate user-provided file patterns
454
+ - **Limit scope**: Restrict file access to project directory
455
+
456
+ ### Input Validation
457
+
458
+ - **Schema validation**: Use JSON Schema for rule options
459
+ - **Type checking**: Leverage TypeScript for compile-time safety
460
+ - **Runtime checks**: Validate configuration at runtime
461
+
462
+ ## Maintenance Guidelines
463
+
464
+ ### Version Management
465
+
466
+ - **Semantic versioning**: Follow semver for releases
467
+ - **Breaking changes**: Document breaking changes clearly
468
+ - **Migration guides**: Provide upgrade instructions
469
+
470
+ ### Community Support
471
+
472
+ - **Issue templates**: Provide clear bug report templates
473
+ - **Contributing guide**: Document contribution process
474
+ - **Code of conduct**: Establish community guidelines
475
+
476
+ ---
477
+
478
+ ## Related Resources
479
+
480
+ - [ESLint Plugin Development Guide](https://eslint.org/docs/latest/extend/plugins)
481
+ - [ESLint Custom Rules](https://eslint.org/docs/latest/extend/custom-rules)
482
+ - [@typescript-eslint/utils](https://typescript-eslint.io/packages/utils/)
483
+ - [ESLint RuleTester](https://eslint.org/docs/latest/integrate/nodejs-api#ruletester)
@@ -0,0 +1,100 @@
1
+ # Jest Testing Guide
2
+
3
+ This guide covers testing practices and configuration for the eslint-plugin-traceability project.
4
+
5
+ ## Traceability in Test Output
6
+
7
+ ### Viewing Story and Requirement References
8
+
9
+ By default, Jest's standard output only shows file-level test results without displaying individual test descriptions or traceability annotations. To see the full traceability information including story references and requirement IDs, you must use the `--verbose` option.
10
+
11
+ **Standard output (limited visibility):**
12
+
13
+ ```bash
14
+ npm test
15
+ ```
16
+
17
+ Shows only:
18
+
19
+ ```
20
+ PASS tests/maintenance/batch.test.ts
21
+ PASS tests/rules/require-branch-annotation.test.ts
22
+ ```
23
+
24
+ **Verbose output (full traceability):**
25
+
26
+ ```bash
27
+ npm test -- --verbose
28
+ ```
29
+
30
+ Shows detailed test descriptions with traceability annotations:
31
+
32
+ ```
33
+ PASS tests/maintenance/batch.test.ts
34
+ batchUpdateAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)
35
+ ✓ [REQ-MAINT-BATCH] should return 0 when no mappings applied (6 ms)
36
+ verifyAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)
37
+ ✓ [REQ-MAINT-VERIFY] should return true when annotations are valid
38
+
39
+ PASS tests/rules/require-branch-annotation.test.ts
40
+ Require Branch Annotation Rule (Story 004.0-DEV-BRANCH-ANNOTATIONS)
41
+ require-branch-annotation
42
+ valid
43
+ ✓ [REQ-BRANCH-DETECTION] valid if-statement with annotations (4 ms)
44
+ ```
45
+
46
+ ### Test Structure Requirements
47
+
48
+ All tests in this project follow a specific structure to support traceability:
49
+
50
+ 1. **File-level annotations** at the top of each test file:
51
+
52
+ ```typescript
53
+ /**
54
+ * Tests for: docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
55
+ * @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
56
+ * @req REQ-MAINT-BATCH - Perform batch updates
57
+ * @req REQ-MAINT-VERIFY - Verify annotation references
58
+ */
59
+ ```
60
+
61
+ 2. **Describe blocks** that reference the story:
62
+
63
+ ```typescript
64
+ describe('batchUpdateAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)', () => {
65
+ ```
66
+
67
+ 3. **Test cases** that reference specific requirements:
68
+ ```typescript
69
+ it('[REQ-MAINT-BATCH] should return 0 when no mappings applied', () => {
70
+ ```
71
+
72
+ ### Running Tests for Traceability Review
73
+
74
+ When reviewing test coverage for specific stories or requirements:
75
+
76
+ - **For development/debugging**: Use `npm test -- --verbose` to see all traceability information
77
+ - **For CI/CD pipelines**: Standard `npm test` provides sufficient pass/fail information
78
+ - **For coverage analysis**: Both modes provide the same coverage statistics
79
+
80
+ ### Best Practices
81
+
82
+ 1. **Always include story references** in describe blocks to make them visible in verbose output
83
+ 2. **Prefix test descriptions with requirement IDs** in square brackets (e.g., `[REQ-MAINT-BATCH]`)
84
+ 3. **Use meaningful test descriptions** that clearly indicate what requirement is being tested
85
+ 4. **Run with --verbose during development** to verify traceability annotations are properly displayed
86
+
87
+ ## Configuration
88
+
89
+ The project's Jest configuration is defined in `jest.config.js` and includes:
90
+
91
+ - Coverage reporting
92
+ - TypeScript support via ts-jest
93
+ - Test file patterns
94
+ - CI-friendly options (--ci --bail --coverage)
95
+
96
+ ## Related Documentation
97
+
98
+ - [Story Files](stories/) - User story definitions
99
+ - [ESLint Plugin Development Guide](eslint-plugin-development-guide.md) - General development practices
100
+ - [Decision Records](decisions/) - Architectural decisions including Jest adoption
@@ -0,0 +1,34 @@
1
+ # require-branch-annotation
2
+
3
+ Ensures that significant code branches (if/else, switch cases, loops, try/catch) have `@story` and `@req` annotations for traceability.
4
+
5
+ @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
6
+ @req REQ-BRANCH-DETECTION - Detect significant code branches for traceability annotations
7
+
8
+ ## Rule Details
9
+
10
+ This rule checks for JSDoc or inline comments immediately preceding significant code branches and ensures both `@story` and `@req` annotations are present.
11
+
12
+ ### Options Schema
13
+
14
+ This rule does not accept any options (schema is `[]`).
15
+
16
+ ### Examples
17
+
18
+ #### Correct
19
+
20
+ ```js
21
+ // @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
22
+ // @req REQ-BRANCH-DETECTION
23
+ if (error) {
24
+ handleError();
25
+ }
26
+ ```
27
+
28
+ #### Incorrect
29
+
30
+ ```js
31
+ if (error) {
32
+ handleError();
33
+ }
34
+ ```
@@ -0,0 +1,39 @@
1
+ # require-req-annotation
2
+
3
+ Enforces the presence of `@req` annotations on function declarations to ensure each function maps to a specific requirement ID.
4
+
5
+ @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
6
+ @req REQ-ANNOTATION-REQUIRED - Require `@req` annotation on functions
7
+
8
+ ## Rule Details
9
+
10
+ This rule validates that every function declaration has a JSDoc comment containing an `@req` annotation.
11
+
12
+ ### Options Schema
13
+
14
+ This rule does not accept any options (schema is `[]`).
15
+
16
+ ### Examples
17
+
18
+ #### Correct
19
+
20
+ ```js
21
+ /**
22
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
23
+ * @req REQ-ANNOTATION-REQUIRED
24
+ */
25
+ function initAuth() {
26
+ // authentication logic
27
+ }
28
+ ```
29
+
30
+ #### Incorrect
31
+
32
+ ```js
33
+ /**
34
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
35
+ */
36
+ function initAuth() {
37
+ // authentication logic
38
+ }
39
+ ```
@@ -0,0 +1,36 @@
1
+ # require-story-annotation
2
+
3
+ Enforces the presence of `@story` annotations on function declarations to ensure traceability from code to user stories.
4
+
5
+ @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
6
+ @req REQ-ANNOTATION-REQUIRED - Require `@story` annotation on functions
7
+
8
+ ## Rule Details
9
+
10
+ This rule validates that every function declaration has a JSDoc comment containing an `@story` annotation pointing to the relevant story file.
11
+
12
+ ### Options Schema
13
+
14
+ This rule does not accept any options (schema is `[]`).
15
+
16
+ ### Examples
17
+
18
+ #### Correct
19
+
20
+ ```js
21
+ /**
22
+ * @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
23
+ * @req REQ-ANNOTATION-REQUIRED
24
+ */
25
+ function initAuth() {
26
+ // authentication logic
27
+ }
28
+ ```
29
+
30
+ #### Incorrect
31
+
32
+ ```js
33
+ function initAuth() {
34
+ // authentication logic
35
+ }
36
+ ```