
Security News
RubyGems Adds Cooldown Feature to Bundler for Newly Published Gems
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.
eslint-plugin-traceability
Advanced tools
A customizable ESLint plugin that enforces traceability annotations in your code, ensuring each implementation is linked to its requirement or test case.
An ESLint plugin that creates searchable verification indices in your code, enabling systematic validation of requirement-to-code mapping.
The Core Value: Transforms an impossible question ("Does code exist somewhere that should support requirement X?") into a tractable question ("Does this annotated code actually support the requirement it claims to?").
The plugin requires @supports annotations at key verification points (functions and control flow branches), creating direct checkpoints where each annotation is a verifiable claim you can search, find, and verify locally without needing to understand the broader codebase context.
Created autonomously by voder.ai.
Prerequisites: Node.js 18.18.x, 20.x, 22.14.x, or 24.x and ESLint v9+.
For detailed setup with ESLint v9, see the ESLint v9 Setup Guide.
Add the plugin to your ESLint configuration and enable the rules.
Additional ESLint v9 configuration guidance:
Example eslint.config.js (ESLint v9 flat config):
This example shows the recommended starting point using the plugin's recommended preset alongside ESLint's recommended config:
// eslint.config.js
import js from "@eslint/js";
import traceability from "eslint-plugin-traceability";
export default [
js.configs.recommended,
{
plugins: {
traceability,
},
},
...traceability.configs.recommended,
];
For function-level checks, traceability/require-traceability is the canonical rule. It ensures that in-scope functions and methods have both story coverage and requirement coverage, and it understands both the modern @supports format and the legacy @story / @req pairs.
The older rule keys:
traceability/require-story-annotationtraceability/require-req-annotationremain available as backward-compatible aliases that are wired to the same underlying engine. Existing configurations that reference these legacy keys will continue to behave as before. New configurations should normally prefer the unified traceability/require-traceability rule and treat the legacy keys as compatibility shims or for gradual migration.
A concise flat-config example that enables the unified function-level rule and commonly used supporting rules explicitly:
// eslint.config.js
import traceability from "eslint-plugin-traceability";
export default [
{
plugins: {
traceability,
},
rules: {
// Canonical function-level rule (preferred for new configs)
"traceability/require-traceability": "error",
// Common supporting rules
"traceability/require-branch-annotation": "warn",
"traceability/valid-annotation-format": "error",
"traceability/valid-story-reference": "error",
"traceability/valid-req-reference": "error",
// Optional: enforce test traceability conventions
"traceability/require-test-traceability": "warn",
},
},
];
Traceability annotations are typically placed immediately adjacent to the code they index. The plugin exposes explicit placement options for branch-level rules and a stable, conventional placement for function-level rules.
Branch-level (traceability/require-branch-annotation)
require-branch-annotation supports an annotationPlacement option:
"before" – Annotation appears immediately before the branch statement (default)."inside" – Annotation appears as the first comment-only lines inside the branch block.In "inside" mode, the rule expects the annotation to be the first meaningful content inside blocks for if / else / loops / try / catch / finally / switch cases.
Example (if statement):
// annotationPlacement: "before"
// @supports docs/stories/auth.md REQ-AUTH-VALIDATION
if (isValidUser(user)) {
performLogin(user);
}
// annotationPlacement: "inside"
if (isValidUser(user)) {
// @supports docs/stories/auth.md REQ-AUTH-VALIDATION
performLogin(user);
}
The annotationPlacement option is also supported by the function-level rules (traceability/require-story-annotation and traceability/require-req-annotation) when you configure them directly. In "inside" mode, these rules treat only the first comment-only lines inside function and method bodies as satisfying the annotation requirement; JSDoc and before-function comments are ignored for block-bodied functions and methods, while TypeScript declarations and signature-only nodes continue to use before-node annotations.
Function-level (traceability/require-story-annotation, traceability/require-req-annotation)
Function-level rules support both before-function and inside-body placement, controlled by the same annotationPlacement option described above:
"before" – Annotations are written as JSDoc blocks immediately preceding the function, or as line comments placed directly before the function declaration or expression."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.For full details and migration guidance between placement styles, see the API Reference and the migration guide (user-docs/migration-guide.md).
For full configuration details and migration guidance between placement styles, see:
traceability/require-branch-annotation rule docs: docs/rules/require-branch-annotation.mdThe plugin exposes several rules. For new configurations, the unified function-level rule and @supports annotations are the canonical choice; the @story and @req forms remain available primarily for backward compatibility and gradual migration.
traceability/require-traceability – Unified function-level verification rule. Ensures every function has a verification checkpoint. Without this, functions could exist without explaining their purpose, breaking verification completeness. Accepts either @supports (preferred for new code) or legacy @story / @req annotations and is enabled by default in the plugin's recommended and strict presets.
traceability/require-story-annotation – Legacy function-level rule key that focuses on the story side of function-level verification. It is kept for backward compatibility and is wired to the same underlying engine as traceability/require-traceability. New configurations should normally rely on traceability/require-traceability instead.
traceability/require-req-annotation – Legacy function-level rule key that focuses on the requirement side of function-level verification. Like traceability/require-story-annotation, it is retained for backward compatibility. New configurations can usually rely on the unified rule alone unless you have specific reasons to tune the legacy keys separately.
traceability/require-branch-annotation – Creates verification checkpoints at every branch (if/else/switch/try/catch). This enables local verification - you can check each branch independently without understanding the entire function. Without branch annotations, you must read entire functions to find branch logic. With branch annotations, you can verify each branch by searching for the requirement ID. Branch annotations can use @supports (preferred) or the older @story/@req pair for backward compatibility.
traceability/valid-annotation-format – Ensures annotations are searchable with consistent patterns. Verification workflows depend on being able to search for requirement IDs reliably. Enforces correct format of traceability annotations, including @supports (preferred), @story, and @req.
traceability/valid-story-reference – Validates story file references to ensure verification checkpoints point to real documentation. Validates that story references (whether written via @story or embedded in @supports) point to existing story files.
traceability/valid-req-reference – Validates requirement identifiers to ensure verification checkpoints reference valid requirements. Validates that requirement identifiers (whether written via @req or embedded in @supports) point to existing requirement IDs in your story files.
traceability/require-test-traceability – Enforces verification conventions in test files by requiring file-level @supports annotations, story references in describe blocks, and [REQ-...] prefixes in it/test names. This ensures tests are traceable back to requirements for comprehensive verification coverage.
traceability/no-redundant-annotation – Removes annotations on simple statements already covered by enclosing scope. These don't create useful verification checkpoints (no branches to verify), so removing them reduces noise without hurting verifiability. It is enabled at severity warn in both the recommended and strict presets by default; consumers can override its severity or disable it explicitly.
traceability/prefer-supports-annotation – Optional migration helper that recommends converting legacy single-story @story/@req JSDoc blocks and inline comments into the newer @supports format for better verification trails. It is disabled by default and must be explicitly enabled. The legacy rule name traceability/prefer-implements-annotation remains available as a deprecated alias.
Configuration options: For detailed per-rule options (such as scopes, branch types, and story directory settings), see the individual rule docs in the plugin's user guide and the consolidated API Reference.
For development and contribution guidelines, see the contribution guide in the repository.
Traceability annotations enable systematic requirement verification through a simple three-step process:
grep -r "REQ-AUTH-VALIDATION" src/Each annotation creates a local verification checkpoint:
This enables you to verify requirements systematically rather than trying to remember which code should implement what.
switch (severity) {
// @supports docs/stories/logging.md REQ-SEVERITY-LEVELS
case "low":
logLevel = "info";
break;
// @supports docs/stories/logging.md REQ-SEVERITY-LEVELS
case "moderate":
logLevel = "warn";
break;
// @supports docs/stories/logging.md REQ-SEVERITY-LEVELS
case "high":
logLevel = "error";
break;
}
Verification process:
Without explicit annotations:
eslint.config.js):// eslint.config.js
import traceability from "eslint-plugin-traceability";
export default [
{
plugins: {
traceability,
},
},
...traceability.configs.recommended,
];
/**
* @supports docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md REQ-ANNOTATION-REQUIRED
* // Prefer @supports for new implementations; @story/@req remain supported for
* // legacy and simple single-story code paths.
*/
function initAuth() {
// implementation...
}
@supports is the canonical format for new, multi-story integrations and richer traceability. The legacy @story and @req forms are kept for backward compatibility and remain appropriate for simple, single-story functions or where a gradual migration is preferred.
npx eslint "src/**/*.js"
Reality: The apparent redundancy is intentional indexing. Each annotation is a separate verification checkpoint. When the same requirement appears in multiple branches, each annotation creates an independent checkpoint that can be verified in ~30 seconds without understanding the broader code structure.
Removing "duplicate" annotations would break the verification workflow by forcing reviewers to trace through code structure instead of verifying local claims.
Reality: The plugin is specifically designed for codebases where manual review is impractical. Small codebases could use manual review; larger ones need systematic, searchable verification indices to make requirement validation tractable.
Reality: These are verification indices, not documentation. The goal is searchability and local verification, not explaining code. Documentation aims to reduce redundancy; verification indices intentionally create checkpoints for independent validation.
Reality: Inheritance would break verification tractability. When you search for a requirement, you need to find every place that implements it - not find a parent annotation and manually trace what inherits from it. Direct, explicit annotations at each implementation point enable grep-based verification.
For detailed verification workflows, examples, and best practices, see the Verification Workflow Guide.
Detailed API specification and configuration options can be found in the API Reference.
Practical usage examples and sample configurations are available in the Examples document.
The traceability-maint CLI provides a batch update tool for maintaining @story and @supports annotation references when you reorganize story files.
Note: Detection and verification of stale references are already handled by ESLint rules (valid-story-reference, valid-req-reference) during normal linting. The maintenance CLI's primary value is the update command, which can batch-update references across your codebase when story files are moved or renamed - something ESLint's auto-fix cannot do.
update – Batch update @story and @supports annotations when a story file is renamed or moved (the key feature ESLint cannot provide)The CLI also includes detect, verify, and report commands for historical compatibility, but these largely duplicate what ESLint already provides during normal linting:
detect – Scan for @story annotations referencing missing files (ESLint rules already do this)verify – Check for stale annotations (ESLint rules already do this)report – Generate reports of stale references (ESLint output already provides this)Primary use case - batch update references:
# Update references when a story file is renamed
npx traceability-maint update \
--root . \
--from "stories/feature-authentication.story.md" \
--to "stories/feature-auth-v2.story.md"
# Preview changes first with --dry-run
npx traceability-maint update \
--root . \
--from "stories/old.story.md" \
--to "stories/new.story.md" \
--dry-run
# Update with ignore patterns to skip generated code
npx traceability-maint update \
--root . \
--from "stories/old.story.md" \
--to "stories/new.story.md" \
--ignore-pattern dist
Supporting commands (largely redundant with ESLint, but available):
# Show help and all options
npx traceability-maint --help
# Detect stale story references (ESLint already does this during linting)
npx traceability-maint detect --root .
# Detect with ESLint-style ignore patterns
npx traceability-maint detect --root . --ignore-pattern node_modules --ignore-pattern dist
# Verify that annotations are valid (ESLint already does this during linting)
npx traceability-maint verify --root .
# Generate a report (ESLint output already provides this information)
npx traceability-maint report --root . --format json
--root <path> – Workspace root directory (defaults to current directory)--json – Output results in JSON format--format <text|json> – Report format (for report command)--from <path> – Source story path (for update command)--to <path> – Destination story path (for update command)--dry-run – Preview changes without modifying files (for update command)--ignore-pattern <pattern> – Path or directory to ignore (can be specified multiple times)The maintenance tools support --ignore-pattern flags to skip directories when performing batch updates:
dist, build)node_modules)Multiple patterns can be specified:
npx traceability-maint update \
--from old.story.md \
--to new.story.md \
--ignore-pattern node_modules \
--ignore-pattern dist \
--ignore-pattern coverage
Use the maintenance CLI when:
Use ESLint for:
The maintenance CLI is a manual refactoring aid, not an automated validation tool. ESLint handles validation automatically during your normal development workflow.
For a full description of options and JSON payloads, see the Maintenance API and CLI section in the API Reference.
You can validate the plugin by running ESLint CLI with the plugin on a sample file:
# Validate missing function-level traceability (should report an error)
npx eslint --no-eslintrc --config eslint.config.js sample.js --rule 'traceability/require-traceability:error'
If you have existing configurations that reference the legacy function-level keys, you can also validate them directly by enabling traceability/require-story-annotation and traceability/require-req-annotation instead.
This command runs ESLint with the plugin, pointing at eslint.config.js flat config.
Replace sample.js with your JavaScript or TypeScript file.
You can run tests and quality checks locally using the npm scripts provided:
# Run all tests with coverage
npm test
# Run linting with zero tolerance for warnings
npm run lint -- --max-warnings=0
# Check code formatting
npm run format:check
# Check duplication threshold
npm run duplication
Coverage reports will be generated in the coverage/ directory.
Integration tests for the ESLint CLI plugin are included in the Jest test suite under tests/integration/cli-integration.test.ts.
To run only the CLI integration tests:
npm test -- tests/integration/cli-integration.test.ts
Or run the full test suite:
npm test
These tests verify end-to-end behavior of the plugin via the ESLint CLI.
For the canonical, user-facing security policy (including how to report vulnerabilities), see SECURITY.md. Internal implementation details and deeper discussion live in the project’s internal documentation and decision records, which are intended for maintainers rather than end users.
eslint-plugin-traceability package is intended to ship only with production dependencies that have no known high‑severity vulnerabilities at release time.npm audit --omit=dev --audit-level=high – this checks only the runtime (prod) dependency graph and fails if any high‑severity issues are reported.npm install eslint-plugin-traceability.dry-aged-deps and npm audit work togetherdry-aged-deps
dry-aged-deps (via npm run deps:maturity and npm run safety:deps) to enforce basic “maturity” constraints on dependency updates.npm audit
npm audit --omit=dev --audit-level=high is run on the production dependency tree to catch known high‑severity issues before release.dry-aged-deps controls which versions we are willing to upgrade to (age + no‑known‑vulns).npm audit validates that the current, locked set of production dependencies is free from known high‑severity vulnerabilities.npm/glob/brace-expansion.eslint-plugin-traceability package you install or use in your own projects.FAQs
A customizable ESLint plugin that enforces traceability annotations in your code, ensuring each implementation is linked to its requirement or test case.
We found that eslint-plugin-traceability demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.

Security News
Federal audit finds NIST lacked a plan to clear the NVD backlog, wasted funds on duplicate work, and delayed use of CISA data.