eslint-plugin-traceability 1.7.0 → 1.8.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.
- package/CHANGELOG.md +82 -0
- package/README.md +73 -32
- package/docs/ci-cd-pipeline.md +224 -0
- package/docs/cli-integration.md +22 -0
- package/docs/code-quality-refactor-opportunities-2025-12-03.md +78 -0
- package/docs/config-presets.md +38 -0
- package/docs/conventional-commits-guide.md +185 -0
- package/docs/custom-rules-development-guide.md +659 -0
- package/docs/decisions/0001-allow-dynamic-require-for-built-plugins.md +26 -0
- package/docs/decisions/001-typescript-for-eslint-plugin.accepted.md +111 -0
- package/docs/decisions/002-jest-for-eslint-testing.accepted.md +137 -0
- package/docs/decisions/003-code-quality-ratcheting-plan.md +48 -0
- package/docs/decisions/004-automated-version-bumping-for-ci-cd.md +196 -0
- package/docs/decisions/005-github-actions-validation-tooling.accepted.md +144 -0
- package/docs/decisions/006-semantic-release-for-automated-publishing.accepted.md +227 -0
- package/docs/decisions/007-github-releases-over-changelog.accepted.md +216 -0
- package/docs/decisions/008-ci-audit-flags.accepted.md +60 -0
- package/docs/decisions/009-security-focused-lint-rules.accepted.md +64 -0
- package/docs/decisions/010-implements-annotation-for-multi-story-requirements.proposed.md +184 -0
- package/docs/decisions/adr-0001-console-usage-for-cli-guards.md +190 -0
- package/docs/decisions/adr-accept-dev-dep-risk-glob.md +40 -0
- package/docs/decisions/adr-commit-branch-tests.md +54 -0
- package/docs/decisions/adr-maintenance-cli-interface.md +140 -0
- package/docs/decisions/adr-pre-push-parity.md +112 -0
- package/docs/decisions/code-quality-ratcheting-plan.md +53 -0
- package/docs/dependency-health.md +238 -0
- package/docs/eslint-9-setup-guide.md +517 -0
- package/docs/eslint-plugin-development-guide.md +487 -0
- package/docs/functionality-coverage-2025-12-03.md +250 -0
- package/docs/jest-testing-guide.md +100 -0
- package/docs/rules/prefer-implements-annotation.md +219 -0
- package/docs/rules/require-branch-annotation.md +71 -0
- package/docs/rules/require-req-annotation.md +203 -0
- package/docs/rules/require-story-annotation.md +159 -0
- package/docs/rules/valid-annotation-format.md +418 -0
- package/docs/rules/valid-req-reference.md +153 -0
- package/docs/rules/valid-story-reference.md +120 -0
- package/docs/security-incidents/2025-11-17-glob-cli-incident.md +45 -0
- package/docs/security-incidents/2025-11-18-brace-expansion-redos.md +45 -0
- package/docs/security-incidents/2025-11-18-bundled-dev-deps-accepted-risk.md +93 -0
- package/docs/security-incidents/2025-11-18-tar-race-condition.md +43 -0
- package/docs/security-incidents/2025-12-03-dependency-health-review.md +58 -0
- package/docs/security-incidents/SECURITY-INCIDENT-2025-11-18-semantic-release-bundled-npm.known-error.md +104 -0
- package/docs/security-incidents/SECURITY-INCIDENT-TEMPLATE.md +37 -0
- package/docs/security-incidents/dependency-override-rationale.md +57 -0
- package/docs/security-incidents/dev-deps-high.json +116 -0
- package/docs/security-incidents/handling-procedure.md +54 -0
- package/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md +92 -0
- package/docs/stories/002.0-DEV-ESLINT-CONFIG.story.md +82 -0
- package/docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md +112 -0
- package/docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md +153 -0
- package/docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md +138 -0
- package/docs/stories/006.0-DEV-FILE-VALIDATION.story.md +144 -0
- package/docs/stories/007.0-DEV-ERROR-REPORTING.story.md +163 -0
- package/docs/stories/008.0-DEV-AUTO-FIX.story.md +150 -0
- package/docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md +117 -0
- package/docs/stories/010.0-DEV-DEEP-VALIDATION.story.md +124 -0
- package/docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md +149 -0
- package/docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md +216 -0
- package/docs/stories/010.3-DEV-MIGRATE-TO-IMPLEMENTS.story.md +236 -0
- package/docs/stories/developer-story.map.md +120 -0
- package/docs/ts-jest-presets-guide.md +548 -0
- package/lib/src/index.d.ts +2 -2
- package/lib/src/index.js +2 -0
- package/lib/src/maintenance/batch.d.ts +5 -0
- package/lib/src/maintenance/batch.js +5 -0
- package/lib/src/maintenance/cli.js +34 -212
- package/lib/src/maintenance/commands.d.ts +32 -0
- package/lib/src/maintenance/commands.js +139 -0
- package/lib/src/maintenance/detect.d.ts +2 -0
- package/lib/src/maintenance/detect.js +4 -0
- package/lib/src/maintenance/flags.d.ts +99 -0
- package/lib/src/maintenance/flags.js +121 -0
- package/lib/src/maintenance/report.d.ts +2 -0
- package/lib/src/maintenance/report.js +2 -0
- package/lib/src/maintenance/update.d.ts +4 -0
- package/lib/src/maintenance/update.js +4 -0
- package/lib/src/rules/helpers/require-story-io.d.ts +3 -0
- package/lib/src/rules/helpers/require-story-io.js +20 -6
- package/lib/src/rules/helpers/valid-annotation-format-internal.d.ts +30 -0
- package/lib/src/rules/helpers/valid-annotation-format-internal.js +36 -0
- package/lib/src/rules/helpers/valid-annotation-options.js +15 -4
- package/lib/src/rules/helpers/valid-annotation-utils.js +5 -0
- package/lib/src/rules/helpers/valid-implements-utils.d.ts +75 -0
- package/lib/src/rules/helpers/valid-implements-utils.js +149 -0
- package/lib/src/rules/helpers/valid-story-reference-helpers.d.ts +3 -4
- package/lib/src/rules/prefer-implements-annotation.d.ts +39 -0
- package/lib/src/rules/prefer-implements-annotation.js +276 -0
- package/lib/src/rules/valid-annotation-format.js +87 -28
- package/lib/src/rules/valid-req-reference.js +71 -0
- package/lib/src/utils/reqAnnotationDetection.d.ts +4 -1
- package/lib/src/utils/reqAnnotationDetection.js +43 -15
- package/lib/tests/maintenance/cli.test.js +89 -0
- package/lib/tests/plugin-default-export-and-configs.test.js +3 -0
- package/lib/tests/rules/prefer-implements-annotation.test.d.ts +1 -0
- package/lib/tests/rules/prefer-implements-annotation.test.js +84 -0
- package/lib/tests/rules/require-req-annotation.test.js +8 -1
- package/lib/tests/rules/require-story-annotation.test.js +9 -4
- package/lib/tests/rules/valid-annotation-format.test.js +78 -0
- package/lib/tests/rules/valid-req-reference.test.js +34 -0
- package/lib/tests/utils/ts-language-options.d.ts +1 -7
- package/lib/tests/utils/ts-language-options.js +8 -5
- package/package.json +7 -3
- package/user-docs/api-reference.md +507 -0
- package/user-docs/eslint-9-setup-guide.md +639 -0
- package/user-docs/examples.md +74 -0
- package/user-docs/migration-guide.md +158 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: "proposed"
|
|
3
|
+
date: 2025-12-03
|
|
4
|
+
decision-makers: [Development Team]
|
|
5
|
+
consulted: [dry-aged-deps codebase patterns, JSDoc conventions]
|
|
6
|
+
informed: [Plugin Users, Project Contributors]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Introduce @implements Annotation for Multi-Story Requirements
|
|
10
|
+
|
|
11
|
+
## Context and Problem Statement
|
|
12
|
+
|
|
13
|
+
The current traceability annotation system uses `@story` to reference a story file and `@req` to reference requirement IDs within that story. This works well for functions that implement a single story, but breaks down for integration functions that combine functionality from multiple stories. For example, `apply-filters.js` calls both `filterByAge()` (from story 003) and `filterBySecurity()` (from story 004), needing to reference requirements from both stories.
|
|
14
|
+
|
|
15
|
+
The current `valid-req-reference` rule only validates `@req` annotations against the **first** `@story` annotation, causing false-positive linting errors when a function legitimately implements requirements from multiple stories. This blocks code quality validation and forces developers to either suppress linting or remove valid traceability annotations.
|
|
16
|
+
|
|
17
|
+
## Decision Drivers
|
|
18
|
+
|
|
19
|
+
- Integration functions naturally combine functionality from multiple stories
|
|
20
|
+
- Current single-story validation prevents legitimate multi-story traceability
|
|
21
|
+
- Need backwards compatibility with existing `@story` + `@req` annotations
|
|
22
|
+
- Requirement IDs should be unique only within their story file (scoping)
|
|
23
|
+
- Clear, explicit mapping between requirements and their source stories
|
|
24
|
+
- Minimal disruption to existing codebases
|
|
25
|
+
- Natural semantics that match developer mental models
|
|
26
|
+
|
|
27
|
+
## Considered Options
|
|
28
|
+
|
|
29
|
+
1. Multiple `@story` support - Allow multiple `@story` tags, validate `@req` against any
|
|
30
|
+
2. Transitive references - Only reference primary story, infer requirements from called functions
|
|
31
|
+
3. Integration story pattern - Create integration story files that duplicate requirements
|
|
32
|
+
4. Flatten requirements - Remove `@req` validation entirely
|
|
33
|
+
5. Namespaced requirements - Use aliases like `@story ... as alias` / `@req alias:REQ-ID`
|
|
34
|
+
6. Inline story reference - `@req REQ-ID from path/to/story.md`
|
|
35
|
+
7. New `@implements` annotation - `@implements story-path REQ-ID1 REQ-ID2 ...`
|
|
36
|
+
|
|
37
|
+
## Decision Outcome
|
|
38
|
+
|
|
39
|
+
Chosen option: "New `@implements` annotation", because it provides clear, explicit mapping between requirements and stories, enables requirement ID scoping, maintains full backwards compatibility with existing annotations, and uses semantically meaningful terminology.
|
|
40
|
+
|
|
41
|
+
### Consequences
|
|
42
|
+
|
|
43
|
+
- Good, because `@implements` clearly expresses "this code implements these requirements from this story"
|
|
44
|
+
- Good, because requirement IDs only need to be unique within their story file (scoping)
|
|
45
|
+
- Good, because all requirements from one story can be listed on a single line
|
|
46
|
+
- Good, because completely backwards compatible - existing `@story` + `@req` code continues working
|
|
47
|
+
- Good, because no ambiguity in multi-story scenarios
|
|
48
|
+
- Good, because reduced annotation overhead compared to separate `@story` tags
|
|
49
|
+
- Good, because story paths appear once per story (grouped requirements)
|
|
50
|
+
- Neutral, because introduces a new annotation tag (but semantically clear)
|
|
51
|
+
- Neutral, because both annotation styles can coexist during migration
|
|
52
|
+
- Bad, because requires plugin enhancement to support new annotation
|
|
53
|
+
- Bad, because requires documentation updates and user communication
|
|
54
|
+
|
|
55
|
+
### Confirmation
|
|
56
|
+
|
|
57
|
+
Implementation compliance will be confirmed through:
|
|
58
|
+
|
|
59
|
+
- Plugin parses `@implements story-path REQ-ID1 REQ-ID2 ...` format correctly
|
|
60
|
+
- Each requirement ID is validated against its specified story file
|
|
61
|
+
- Existing `@story` + `@req` annotations continue to work unchanged
|
|
62
|
+
- Mixed usage (both styles in same codebase) works correctly
|
|
63
|
+
- Error messages clearly indicate which story was checked for each requirement
|
|
64
|
+
- Tests cover single-story, multi-story, and mixed annotation patterns
|
|
65
|
+
- Documentation includes migration guide and examples
|
|
66
|
+
|
|
67
|
+
## Pros and Cons of the Options
|
|
68
|
+
|
|
69
|
+
### New `@implements` annotation
|
|
70
|
+
|
|
71
|
+
Introduces a new annotation tag that combines story reference with requirement IDs.
|
|
72
|
+
|
|
73
|
+
- Good, because semantically clear ("implements requirements from story")
|
|
74
|
+
- Good, because explicit story-to-requirement mapping (no inference needed)
|
|
75
|
+
- Good, because requirements grouped by story (readable, organized)
|
|
76
|
+
- Good, because enables requirement ID scoping to story files
|
|
77
|
+
- Good, because backwards compatible (existing code unchanged)
|
|
78
|
+
- Good, because story paths not duplicated per requirement
|
|
79
|
+
- Good, because natural for both single-story and multi-story cases
|
|
80
|
+
- Neutral, because new annotation to learn (but intuitive naming)
|
|
81
|
+
- Bad, because requires plugin changes to support new tag
|
|
82
|
+
- Bad, because migration effort for existing codebases (though optional)
|
|
83
|
+
|
|
84
|
+
**Example usage:**
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
/**
|
|
88
|
+
* Apply age and security filters to rows.
|
|
89
|
+
* @implements prompts/003.0-DEV-IDENTIFY-OUTDATED.md REQ-AGE-THRESHOLD REQ-OUTPUT
|
|
90
|
+
* @implements prompts/004.0-DEV-FILTER-VULNERABLE-VERSIONS.md REQ-AUDIT-CHECK REQ-SAFE-ONLY
|
|
91
|
+
*/
|
|
92
|
+
export async function applyFilters(rows, options) {
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Legacy format (still supported):**
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
/**
|
|
99
|
+
* @story docs/stories/003.0-DEV-EXAMPLE.story.md
|
|
100
|
+
* @req REQ-FUNCTION-VALIDATION
|
|
101
|
+
*/
|
|
102
|
+
export function legacyFunction() {
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Multiple `@story` support
|
|
106
|
+
|
|
107
|
+
Allow multiple `@story` annotations, validate `@req` against any referenced story.
|
|
108
|
+
|
|
109
|
+
- Good, because extends current annotation model incrementally
|
|
110
|
+
- Good, because explicit story listing provides context
|
|
111
|
+
- Neutral, because maintains separation of stories and requirements
|
|
112
|
+
- Bad, because unclear which `@req` maps to which `@story`
|
|
113
|
+
- Bad, because doesn't enable requirement ID scoping
|
|
114
|
+
- Bad, because story paths repeated if requirements intermixed
|
|
115
|
+
|
|
116
|
+
### Namespaced requirements
|
|
117
|
+
|
|
118
|
+
Use story aliases like `@story path as alias` / `@req alias:REQ-ID`.
|
|
119
|
+
|
|
120
|
+
- Good, because clear story-to-requirement mapping via namespace
|
|
121
|
+
- Good, because story paths appear once
|
|
122
|
+
- Neutral, because requires learning namespace syntax
|
|
123
|
+
- Bad, because alias management adds cognitive overhead
|
|
124
|
+
- Bad, because unconventional for JSDoc
|
|
125
|
+
|
|
126
|
+
### Inline story reference
|
|
127
|
+
|
|
128
|
+
Format: `@req REQ-ID from path/to/story.md`
|
|
129
|
+
|
|
130
|
+
- Good, because very explicit per-requirement
|
|
131
|
+
- Good, because no aliasing needed
|
|
132
|
+
- Bad, because verbose (story path repeated per requirement)
|
|
133
|
+
- Bad, because harder to refactor story paths
|
|
134
|
+
- Bad, because doesn't enable requirement ID scoping
|
|
135
|
+
|
|
136
|
+
### Transitive references
|
|
137
|
+
|
|
138
|
+
Infer requirements from called functions automatically.
|
|
139
|
+
|
|
140
|
+
- Good, because minimal annotation overhead
|
|
141
|
+
- Bad, because requires complex static analysis
|
|
142
|
+
- Bad, because fragile (refactoring breaks validation)
|
|
143
|
+
- Bad, because implicit (not backwards compatible)
|
|
144
|
+
|
|
145
|
+
### Integration story pattern
|
|
146
|
+
|
|
147
|
+
Create integration story files that duplicate requirements.
|
|
148
|
+
|
|
149
|
+
- Good, because single `@story` still works
|
|
150
|
+
- Bad, because duplicates requirements across stories
|
|
151
|
+
- Bad, because high maintenance overhead
|
|
152
|
+
- Bad, because doesn't scale
|
|
153
|
+
|
|
154
|
+
## More Information
|
|
155
|
+
|
|
156
|
+
This decision addresses the limitation discovered when fixing systematic linting suppression in dry-aged-deps, where 80% of files had `eslint-disable traceability/*` due to multi-story integration functions.
|
|
157
|
+
|
|
158
|
+
The `@implements` annotation name was chosen because:
|
|
159
|
+
|
|
160
|
+
- It's semantically accurate - code implements requirements
|
|
161
|
+
- It's familiar from interface implementation in many languages
|
|
162
|
+
- It clearly conveys purpose without abbreviation
|
|
163
|
+
- It differentiates from `@story` (context) vs implementation scope
|
|
164
|
+
|
|
165
|
+
**Migration strategy:**
|
|
166
|
+
|
|
167
|
+
1. Plugin supports both `@story`+`@req` and `@implements` simultaneously
|
|
168
|
+
2. Existing code continues working without changes
|
|
169
|
+
3. New code can use either format based on preference
|
|
170
|
+
4. Multi-story code should migrate to `@implements` to fix validation
|
|
171
|
+
5. Single-story code can optionally migrate for consistency
|
|
172
|
+
|
|
173
|
+
**Validation behavior:**
|
|
174
|
+
|
|
175
|
+
- `@implements story-path REQ-1 REQ-2`: Validate REQ-1 and REQ-2 exist in story-path
|
|
176
|
+
- `@story path` + `@req REQ-1`: Validate REQ-1 exists in path (legacy)
|
|
177
|
+
- Mixed: Both formats can coexist, validated independently
|
|
178
|
+
|
|
179
|
+
This decision should be implemented in eslint-plugin-traceability story 011.0-DEV-MULTI-STORY-SUPPORT or similar.
|
|
180
|
+
|
|
181
|
+
Related resources:
|
|
182
|
+
|
|
183
|
+
- eslint-plugin-traceability story 010.0-DEV-DEEP-VALIDATION (requirement validation)
|
|
184
|
+
- eslint-plugin-traceability story 003.0-DEV-FUNCTION-ANNOTATIONS (current @req validation)
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# ADR-0001: Console Usage for CLI Guards, Helpers, and Plugin Bootstrap
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted
|
|
6
|
+
|
|
7
|
+
## Date
|
|
8
|
+
|
|
9
|
+
2025-11-22
|
|
10
|
+
|
|
11
|
+
## Context
|
|
12
|
+
|
|
13
|
+
This project includes:
|
|
14
|
+
|
|
15
|
+
- Command-line interface (CLI) entry points
|
|
16
|
+
- Helper scripts invoked in CI (e.g., validation, formatting, pre-publish checks)
|
|
17
|
+
- Plugin/bootstrap code that wires rules, schemas, and configuration into host environments
|
|
18
|
+
|
|
19
|
+
These components sometimes need to communicate directly with users or CI logs. At the same time, the core rule logic and runtime validation paths must remain deterministic, testable, and free of incidental logging side effects.
|
|
20
|
+
|
|
21
|
+
Unrestricted use of `console.*` makes it harder to:
|
|
22
|
+
|
|
23
|
+
- Keep CI logs focused and readable
|
|
24
|
+
- Distinguish genuine errors from noisy diagnostics
|
|
25
|
+
- Treat the library/rules as embeddable components in other tools
|
|
26
|
+
- Assert on behavior without having to mock or suppress console output
|
|
27
|
+
- Maintain a clear and intentional debugging story
|
|
28
|
+
|
|
29
|
+
We therefore need a clear policy on where and how console logging is allowed.
|
|
30
|
+
|
|
31
|
+
## Decision
|
|
32
|
+
|
|
33
|
+
### 1. Allowed: `console.error` and `console.warn` in CLI/CI/helper/bootstrapping layers
|
|
34
|
+
|
|
35
|
+
It is acceptable and encouraged to use `console.error` and `console.warn` **only** in the following layers:
|
|
36
|
+
|
|
37
|
+
1. **CLI entry points / top-level commands**
|
|
38
|
+
- Example: `bin/*`, `cli.ts`, or similar top-level command handlers.
|
|
39
|
+
- Purpose:
|
|
40
|
+
- Report user-facing failures (e.g., invalid flags, failed file operations, configuration errors).
|
|
41
|
+
- Surface deprecation notices that must be visible to users.
|
|
42
|
+
- Provide actionable messages when the process will exit with a failing code.
|
|
43
|
+
|
|
44
|
+
2. **CI/helper scripts**
|
|
45
|
+
- Example: scripts run in CI pipelines, pre-commit, or release workflows.
|
|
46
|
+
- Purpose:
|
|
47
|
+
- Report errors and warnings that should be visible in CI logs.
|
|
48
|
+
- Indicate misconfiguration, missing environment variables, or unexpected states that require human attention.
|
|
49
|
+
|
|
50
|
+
3. **Plugin bootstrap / initialization code**
|
|
51
|
+
- Example: modules that register rules, schemas, or integrations with other tools.
|
|
52
|
+
- Purpose:
|
|
53
|
+
- Report misconfiguration, incompatibility, or missing peer dependencies.
|
|
54
|
+
- Warn about deprecated configuration patterns or features at startup.
|
|
55
|
+
|
|
56
|
+
Within these layers:
|
|
57
|
+
|
|
58
|
+
- Prefer `console.error` for conditions that are expected to cause failure or require immediate action.
|
|
59
|
+
- Prefer `console.warn` for non-fatal, but noteworthy, conditions.
|
|
60
|
+
- Ensure messages are:
|
|
61
|
+
- Concise and actionable.
|
|
62
|
+
- Clearly identify the originating tool/plugin where possible.
|
|
63
|
+
- Avoid leaking sensitive information (tokens, file contents, etc.).
|
|
64
|
+
|
|
65
|
+
### 2. Disallowed by default: Incidental logging in core rule logic and runtime validation
|
|
66
|
+
|
|
67
|
+
The **core rule logic** and **runtime validation paths** must **not** emit incidental console output:
|
|
68
|
+
|
|
69
|
+
- **Disallowed by default (unless gated, see §3):**
|
|
70
|
+
- `console.debug`
|
|
71
|
+
- `console.info`
|
|
72
|
+
- `console.log`
|
|
73
|
+
- `console.warn`
|
|
74
|
+
- `console.error`
|
|
75
|
+
|
|
76
|
+
These paths include, but are not limited to:
|
|
77
|
+
|
|
78
|
+
- Rule implementations and their helpers.
|
|
79
|
+
- Core validation pipelines and evaluators.
|
|
80
|
+
- Schema or configuration validation logic that runs during normal tool operation.
|
|
81
|
+
- Any code intended to be reusable as a library, imported by other tools, or executed repeatedly as part of analysis passes.
|
|
82
|
+
|
|
83
|
+
Rationale:
|
|
84
|
+
|
|
85
|
+
- These components are expected to be:
|
|
86
|
+
- Pure (or side-effect minimal) in normal execution.
|
|
87
|
+
- Suitable for use in environments where console output is tightly controlled (CI, IDE integrations, language servers, etc.).
|
|
88
|
+
- Testable without requiring suppression or mocking of the console.
|
|
89
|
+
|
|
90
|
+
If a rule or validation component must report an exceptional condition, it should do so by:
|
|
91
|
+
|
|
92
|
+
- Returning structured error objects, diagnostics, or result codes to the caller.
|
|
93
|
+
- Throwing well-typed errors (where appropriate) that are handled and surfaced at higher layers (e.g., CLI, plugin bootstrap), which then decide whether to log via `console.error`/`console.warn`.
|
|
94
|
+
|
|
95
|
+
### 3. Optional: Debug logging behind an explicit, documented debug flag
|
|
96
|
+
|
|
97
|
+
Debug logging inside rule logic or validation paths is allowed **only** when all of the following conditions are met:
|
|
98
|
+
|
|
99
|
+
1. **Explicit opt-in flag**
|
|
100
|
+
- There is a documented configuration option or environment variable (e.g., `MY_TOOL_DEBUG=true`, `--debug-rules`) that clearly indicates the user is opting into verbose debug output.
|
|
101
|
+
|
|
102
|
+
2. **Single, centralized control**
|
|
103
|
+
- Debug logging behavior is routed through a small, centralized abstraction (e.g., `debugLogger.debug(...)`) that:
|
|
104
|
+
- Checks the flag.
|
|
105
|
+
- Decides whether to call `console.debug`/`console.info` (or similar).
|
|
106
|
+
- Rule and validation code must not call `console.*` directly; they call the abstraction instead.
|
|
107
|
+
|
|
108
|
+
3. **Documented behavior**
|
|
109
|
+
- The debug option is documented in:
|
|
110
|
+
- User-facing CLI help (e.g., `--help` output) and/or
|
|
111
|
+
- Project documentation / README.
|
|
112
|
+
- The documentation explains:
|
|
113
|
+
- How to enable it.
|
|
114
|
+
- What kind of additional output to expect.
|
|
115
|
+
- That it is intended for development/troubleshooting, not regular operation.
|
|
116
|
+
|
|
117
|
+
4. **No change to functional semantics**
|
|
118
|
+
- Enabling or disabling debug logging must not alter:
|
|
119
|
+
- Rule evaluation semantics.
|
|
120
|
+
- Validation results.
|
|
121
|
+
- Exit codes.
|
|
122
|
+
- Data returned from public APIs.
|
|
123
|
+
- Only side-effect should be additional console output.
|
|
124
|
+
|
|
125
|
+
If these requirements cannot be satisfied, then debug logging must **not** be added to core rule or validation logic.
|
|
126
|
+
|
|
127
|
+
### 4. Current state of the codebase
|
|
128
|
+
|
|
129
|
+
As of this ADR:
|
|
130
|
+
|
|
131
|
+
- The **current codebase has no debug logging** (`console.debug`/`console.info`/`console.log`) inside:
|
|
132
|
+
- Rule implementations.
|
|
133
|
+
- Core validation logic.
|
|
134
|
+
- Normal runtime evaluation paths.
|
|
135
|
+
|
|
136
|
+
Existing console usage is limited to acceptable locations (e.g., CLI helpers, CI scripts, bootstrap code), or will be refactored to conform to this ADR as needed.
|
|
137
|
+
|
|
138
|
+
### 5. Requirements for future changes
|
|
139
|
+
|
|
140
|
+
Any future additions or modifications must follow these rules:
|
|
141
|
+
|
|
142
|
+
1. **New CLI or CI helper behavior**
|
|
143
|
+
- May use `console.error` and `console.warn` to report user-/operator-facing issues.
|
|
144
|
+
- Must keep messages focused and actionable.
|
|
145
|
+
|
|
146
|
+
2. **New plugin/bootstrap code**
|
|
147
|
+
- May use `console.error` and `console.warn` to report misconfiguration, deprecation, or failure to initialize.
|
|
148
|
+
- Must not emit continuous noisy logs during normal operation.
|
|
149
|
+
|
|
150
|
+
3. **New rule or validation logic**
|
|
151
|
+
- Must **not** introduce direct `console.*` calls.
|
|
152
|
+
- Any need for surfaced messages must be handled via return values, errors, or diagnostics passed upward.
|
|
153
|
+
|
|
154
|
+
4. **New debug-logging needs**
|
|
155
|
+
- Must implement or reuse a centrally controlled debug abstraction, gated behind a documented flag (see §3).
|
|
156
|
+
- Must keep debug logging off by default.
|
|
157
|
+
- Must ensure tests remain stable regardless of debug flag state (except tests explicitly verifying debug behavior).
|
|
158
|
+
|
|
159
|
+
5. **Code review expectations**
|
|
160
|
+
- Any use of `console.*` in PRs must be reviewed against this ADR.
|
|
161
|
+
- Reviewers should:
|
|
162
|
+
- Confirm that console usage is in an allowed layer (CLI/CI/helper/bootstrap) or behind a proper debug abstraction.
|
|
163
|
+
- Request refactoring if console usage appears in rule logic or runtime validation not gated as per §3.
|
|
164
|
+
|
|
165
|
+
## Consequences
|
|
166
|
+
|
|
167
|
+
- **Positive**
|
|
168
|
+
- Clear separation between user-visible errors/warnings and internal debugging.
|
|
169
|
+
- Cleaner CI logs and more predictable tool integration behavior.
|
|
170
|
+
- Easier testing and reasoning about core logic, without noise from incidental console output.
|
|
171
|
+
- A consistent, documented approach to opt-in debug logging.
|
|
172
|
+
|
|
173
|
+
- **Negative / Trade-offs**
|
|
174
|
+
- Slightly more effort to add debug logging, due to the need for a central abstraction and debug flag.
|
|
175
|
+
- Contributors must understand and respect the separation between CLI/bootstrapping and core logic.
|
|
176
|
+
|
|
177
|
+
## Alternatives Considered
|
|
178
|
+
|
|
179
|
+
- **Allow unrestricted `console.*` usage everywhere**
|
|
180
|
+
- Rejected: leads to noisy logs, poor embeddability, and harder testing.
|
|
181
|
+
|
|
182
|
+
- **Disallow `console.*` entirely**
|
|
183
|
+
- Rejected: unhelpful for CLI/CI/bootstrapping components, where direct console output is appropriate and expected.
|
|
184
|
+
|
|
185
|
+
- **Use a third-party logging framework everywhere**
|
|
186
|
+
- Rejected for now: adds dependency and complexity; current needs are satisfied by disciplined use of console and an optional light abstraction for debug logging.
|
|
187
|
+
|
|
188
|
+
## Notes
|
|
189
|
+
|
|
190
|
+
This ADR governs only JavaScript/TypeScript-style `console.*` usage. Other languages or runtimes used in this project should follow analogous principles (i.e., restrict incidental stdout/stderr usage in core logic; allow explicit logging in top-level tooling and bootstrap code; gate debug logging behind an explicit debug configuration).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# ADR: Accept residual risk for glob/npm high-severity transitive dev dependency
|
|
2
|
+
|
|
3
|
+
Status: accepted
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
The CI dev dependency audit (ci/npm-audit.json) reports a high-severity advisory for `glob` and `npm` transitively required by `@semantic-release/npm`. Fixes are available upstream but require coordination and may not be immediately possible without an update to semantic-release or npm bundled tooling.
|
|
8
|
+
|
|
9
|
+
## Decision
|
|
10
|
+
|
|
11
|
+
We accept the residual risk in development dependencies for the current release while tracking the issue in a scheduled reassessment. This ADR documents the rationale and mitigations.
|
|
12
|
+
|
|
13
|
+
## Consequences and mitigations
|
|
14
|
+
|
|
15
|
+
- Owner: DevOps/Release Engineer (team)
|
|
16
|
+
- Reassessment: Weekly during dependency-health scheduled workflow runs
|
|
17
|
+
- Mitigations:
|
|
18
|
+
- Do not ship production code that depends on vulnerable dev-time tooling
|
|
19
|
+
- CI pipeline uses `npm ci` and runs production `npm audit` which must pass for releases
|
|
20
|
+
- `ci-safety-deps.js` now produces a best-effort `dry-aged-deps`-style JSON report even when `dry-aged-deps` is unavailable, falling back to an empty `packages` list while still emitting a syntactically valid report for review
|
|
21
|
+
- `ci-audit.js` runs `npm audit` in JSON mode and always writes the full result to `ci/npm-audit.json` without failing the build, ensuring advisory visibility without blocking CI
|
|
22
|
+
- The JSON artifacts generated by `ci-safety-deps.js` and `ci-audit.js` (including `ci/npm-audit.json`) are ignored in `.gitignore` and are only retained as CI artifacts for security review and dependency-health analysis, not committed to the repository
|
|
23
|
+
- The residual `glob`/`npm` dev dependency risks are covered by these updated CI scripts, which ensure visibility into advisories, plus strict production `npm audit` gates that must pass before a release
|
|
24
|
+
- Develop a plan to upgrade `@semantic-release/npm` to a version that avoids bundling vulnerable `glob`/`npm` when safe
|
|
25
|
+
|
|
26
|
+
## References
|
|
27
|
+
|
|
28
|
+
- Vulnerability details: see ci/npm-audit.json stored in CI artifacts
|
|
29
|
+
|
|
30
|
+
Created autonomously by voder.ai
|
|
31
|
+
|
|
32
|
+
## Current Dependency Health (2025-12-03)
|
|
33
|
+
|
|
34
|
+
`npm audit --omit=dev --audit-level=high` currently reports 0 high-severity (or higher) vulnerabilities for production dependencies, and `npm run deps:maturity -- --format=json` reports `totalOutdated: 0` and `safeUpdates: 0`, indicating that there are no dry-aged-safe upgrade candidates at this time for the dev-time semantic-release toolchain.
|
|
35
|
+
|
|
36
|
+
## Using dry-aged-deps in this project
|
|
37
|
+
|
|
38
|
+
Contributors should use `npm run deps:maturity -- --format=json` as the canonical way to invoke dry-aged-deps, both locally and in CI. This command writes its JSON report to stdout. In CI, `npm run safety:deps` additionally persists the latest report to `ci/dry-aged-deps.json` for later inspection as a build artifact.
|
|
39
|
+
|
|
40
|
+
Run dry-aged-deps before proposing dependency bumps, during scheduled dependency-health reviews, and whenever investigating security or maintenance issues related to packages. Only dependency versions that dry-aged-deps marks as safe and that have been published for at least 7 days should be considered for upgrades, to reduce the risk of adopting unstable or compromised releases.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# ADR: Add CI lint-plugin check and targeted branch tests
|
|
2
|
+
|
|
3
|
+
Date: 2025-11-20
|
|
4
|
+
|
|
5
|
+
Status: Accepted
|
|
6
|
+
|
|
7
|
+
Context
|
|
8
|
+
|
|
9
|
+
- CI currently runs a large, monolithic pipeline for every push/PR. This results in long feedback cycles and increased compute cost.
|
|
10
|
+
- Inconsistent commit messages and branch names reduce traceability and can cause problems for automated tooling (release automation, changelogs).
|
|
11
|
+
- Some tests are expensive and only relevant to certain branches (e.g., release or platform-specific branches), while most feature work only needs a smaller, targeted test subset.
|
|
12
|
+
- Contributors and maintainers want faster, reliable feedback on changes without sacrificing quality gates.
|
|
13
|
+
|
|
14
|
+
Decision
|
|
15
|
+
|
|
16
|
+
- Add a CI check that runs a lint-plugin against commits/PRs to enforce commit message format and branch naming rules. The lint-plugin will be integrated into the PR pipeline and fail the build on violations.
|
|
17
|
+
- Implement targeted branch tests:
|
|
18
|
+
- For feature and routine PR branches: run a focused subset of tests (unit tests, fast integration tests, and any tests related to changed files) to provide quick feedback.
|
|
19
|
+
- For release, main, or explicitly labeled branches (e.g., "release/_", "main", "hotfix/_"): run the full test suite.
|
|
20
|
+
- Allow explicit overrides (e.g., PR label or commit tag) to trigger full runs when desired.
|
|
21
|
+
- Document the rules that determine which tests run and how to opt into full runs.
|
|
22
|
+
|
|
23
|
+
Rationale
|
|
24
|
+
|
|
25
|
+
- Lint-plugin for commits/branches enforces consistency and prevents human errors that complicate downstream automation (releases, changelogs, CI heuristics).
|
|
26
|
+
- Targeted tests reduce median CI turnaround time for everyday contributions, improving developer productivity and reducing wasted compute.
|
|
27
|
+
- Running the full suite only on critical branches preserves confidence for releases while keeping developer feedback loops short.
|
|
28
|
+
- Explicit override mechanism balances automation with developer control when a full run is necessary.
|
|
29
|
+
|
|
30
|
+
Consequences
|
|
31
|
+
|
|
32
|
+
- Positive:
|
|
33
|
+
- Faster PR feedback for most contributions.
|
|
34
|
+
- Improved commit/branch hygiene and stronger automation compatibility.
|
|
35
|
+
- Lower CI costs for routine development.
|
|
36
|
+
- Full confidence preserved for release and critical branches.
|
|
37
|
+
- Negative / Trade-offs:
|
|
38
|
+
- Additional maintenance: rules for mapping changes to targeted tests must be maintained and updated.
|
|
39
|
+
- Risk of missed regressions if test selection logic is incorrect or incomplete. Mitigated by defaulting to full runs on protected branches and providing an easy override.
|
|
40
|
+
- Contributors will need to conform to enforced commit/branch rules; documentation and examples will be required.
|
|
41
|
+
|
|
42
|
+
Alternatives considered
|
|
43
|
+
|
|
44
|
+
- Always run full CI on every PR: simple but slow and costly.
|
|
45
|
+
- No lint-plugin enforcement: lower friction but greater chance of inconsistent metadata and automation failures.
|
|
46
|
+
- Run only full suite for releases and minimal checks for everything else without targeted selection: simpler but less efficient in catching relevant regressions early.
|
|
47
|
+
|
|
48
|
+
Implementation notes (high-level)
|
|
49
|
+
|
|
50
|
+
- Add lint-plugin step to CI config; fail on violations and provide clear error messages with remediation.
|
|
51
|
+
- Implement test-selection logic using file-change analysis and branch name rules; fall back to a safe default (full run for protected branches).
|
|
52
|
+
- Provide CONTRIBUTING and CI docs detailing commit message format, branch naming conventions, and how to force full CI runs.
|
|
53
|
+
|
|
54
|
+
This ADR is intended to be revisited after observing CI performance and quality metrics for one quarter post-rollout.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# ADR: Maintenance CLI Interface for Traceability Annotations
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted
|
|
6
|
+
|
|
7
|
+
## Date
|
|
8
|
+
|
|
9
|
+
2025-11-23
|
|
10
|
+
|
|
11
|
+
## Context
|
|
12
|
+
|
|
13
|
+
Story `docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md` introduces maintenance tools that help keep `@story` and `@req` annotations accurate as story files are moved, renamed, or removed.
|
|
14
|
+
|
|
15
|
+
We already have programmatic utilities under `src/maintenance/`:
|
|
16
|
+
|
|
17
|
+
- `detectStaleAnnotations(codebasePath)`
|
|
18
|
+
- `updateAnnotationReferences(codebasePath, oldPath, newPath)`
|
|
19
|
+
- `batchUpdateAnnotations(codebasePath, mappings)`
|
|
20
|
+
- `verifyAnnotations(codebasePath)`
|
|
21
|
+
- `generateMaintenanceReport(codebasePath)`
|
|
22
|
+
|
|
23
|
+
These are well-tested but only accessible from code. The story's acceptance criteria and implementation notes explicitly call out **CLI tools** and a **clear user experience**:
|
|
24
|
+
|
|
25
|
+
- Detect and update annotation references when story files are moved or renamed.
|
|
26
|
+
- Provide clear feedback about what changed.
|
|
27
|
+
- Handle edge cases (e.g., permission issues) gracefully.
|
|
28
|
+
|
|
29
|
+
Without a small, well-defined CLI layer, developers must write ad-hoc scripts to use the maintenance API, which undermines the goal of "helper tools" and makes it harder to adopt maintenance workflows consistently across projects.
|
|
30
|
+
|
|
31
|
+
## Decision
|
|
32
|
+
|
|
33
|
+
We will introduce a small Node CLI, published with the plugin, that wraps the existing maintenance utilities with a minimal, safe interface.
|
|
34
|
+
|
|
35
|
+
### 1. CLI entrypoint
|
|
36
|
+
|
|
37
|
+
- **Binary name**: `traceability-maint`
|
|
38
|
+
- **Implementation**: TypeScript module `src/maintenance/cli.ts` compiled to `lib/src/maintenance/cli.js`.
|
|
39
|
+
- **Package wiring**:
|
|
40
|
+
- Add a `bin` entry to `package.json` pointing `traceability-maint` to `lib/src/maintenance/cli.js`.
|
|
41
|
+
- Keep `files: ["lib", "README.md", "LICENSE"]` so the compiled CLI is included automatically.
|
|
42
|
+
- **Shebang**: `#!/usr/bin/env node` at the top of the compiled script so it is directly executable.
|
|
43
|
+
|
|
44
|
+
The CLI module will export a `runMaintenanceCli(argv: string[]): number` function for tests, and execute it when invoked as the main module.
|
|
45
|
+
|
|
46
|
+
### 2. Supported commands (initial scope)
|
|
47
|
+
|
|
48
|
+
The initial CLI will support the following subcommands:
|
|
49
|
+
|
|
50
|
+
1. `detect`
|
|
51
|
+
- Usage: `traceability-maint detect [--root <dir>] [--json]`
|
|
52
|
+
- Behavior:
|
|
53
|
+
- Uses `detectStaleAnnotations(root)` to find stale `@story` references.
|
|
54
|
+
- Prints either:
|
|
55
|
+
- Plain text: one stale story path per line plus a short summary, or
|
|
56
|
+
- JSON: `{ "root": "...", "stale": ["..."] }` when `--json` is provided.
|
|
57
|
+
- **Exit codes**:
|
|
58
|
+
- `0` when no stale annotations are found.
|
|
59
|
+
- `1` when one or more stale annotations are found.
|
|
60
|
+
- `2` for invalid arguments or unexpected errors.
|
|
61
|
+
|
|
62
|
+
2. `verify`
|
|
63
|
+
- Usage: `traceability-maint verify [--root <dir>]`
|
|
64
|
+
- Behavior:
|
|
65
|
+
- Uses `verifyAnnotations(root)` (and/or `detectStaleAnnotations`) to check overall health.
|
|
66
|
+
- Prints a short human-readable summary indicating whether annotations are valid.
|
|
67
|
+
- **Exit codes**:
|
|
68
|
+
- `0` when all annotations under `root` are valid.
|
|
69
|
+
- `1` when stale annotations exist.
|
|
70
|
+
- `2` for invalid arguments or unexpected errors.
|
|
71
|
+
|
|
72
|
+
3. `report`
|
|
73
|
+
- Usage: `traceability-maint report [--root <dir>] [--format text|json]`
|
|
74
|
+
- Behavior (initially):
|
|
75
|
+
- Uses maintenance detection utilities to produce a **human-readable report** of stale annotations.
|
|
76
|
+
- At a minimum, lists stale story paths and the workspace root.
|
|
77
|
+
- In follow-up work (same story), the report will be enhanced to include **file and line** locations for each stale annotation.
|
|
78
|
+
- **Exit codes**:
|
|
79
|
+
- `0` on successful report generation (even if stale annotations exist).
|
|
80
|
+
- `2` for invalid arguments or unexpected errors.
|
|
81
|
+
|
|
82
|
+
4. `update`
|
|
83
|
+
- Usage: `traceability-maint update --root <dir> --from <oldPath> --to <newPath> [--dry-run] [--json]`
|
|
84
|
+
- Behavior (initially):
|
|
85
|
+
- Uses `updateAnnotationReferences(root, oldPath, newPath)` to update `@story` references.
|
|
86
|
+
- Prints how many annotations were updated.
|
|
87
|
+
- When `--dry-run` is passed, it will **plan** changes and report what would be updated without modifying files (implemented via small helpers in `src/maintenance/update.ts`).
|
|
88
|
+
- **Exit codes**:
|
|
89
|
+
- `0` when the operation completes successfully.
|
|
90
|
+
- `2` for invalid arguments or unexpected errors.
|
|
91
|
+
|
|
92
|
+
The CLI will also support `--help` / `-h` or no subcommand to print usage.
|
|
93
|
+
|
|
94
|
+
### 3. Safety and error handling
|
|
95
|
+
|
|
96
|
+
- The CLI will:
|
|
97
|
+
- Validate arguments and print clear error messages for misuse (e.g., missing `--from` / `--to`).
|
|
98
|
+
- Catch unexpected errors at the top level, log a concise diagnostic to stderr, and exit with a non-zero code.
|
|
99
|
+
- Treat normal findings (e.g., stale annotations found) as **controlled outcomes** with predictable exit codes, not unhandled exceptions.
|
|
100
|
+
- Core maintenance utilities (`src/maintenance/*.ts`) will remain free of `console.*` calls; only the CLI layer will write to stdout/stderr, per ADR-0001.
|
|
101
|
+
|
|
102
|
+
### 4. Defaults and configuration
|
|
103
|
+
|
|
104
|
+
- `--root` defaults to the current working directory (`.`) when omitted.
|
|
105
|
+
- All paths are treated as workspace-relative to the process CWD, consistent with existing maintenance helpers.
|
|
106
|
+
- No additional configuration files are introduced for the CLI in this story; future enhancements (e.g., a JSON config) would be separate stories.
|
|
107
|
+
|
|
108
|
+
### 5. Testing strategy
|
|
109
|
+
|
|
110
|
+
- Add dedicated Jest tests under `tests/maintenance/cli.test.ts` that:
|
|
111
|
+
- Import and call `runMaintenanceCli([...])` directly (no need to spawn a new Node process).
|
|
112
|
+
- Use temporary directories under `os.tmpdir()` with cleanup in `afterAll`/`finally` blocks.
|
|
113
|
+
- Assert on:
|
|
114
|
+
- Exit codes for `detect`, `verify`, `report`, and `update`.
|
|
115
|
+
- Key substrings in console output (captured via Jest spies on `console.log` / `console.error`).
|
|
116
|
+
- Include `@story` / `@req` annotations referencing `docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md`.
|
|
117
|
+
|
|
118
|
+
## Consequences
|
|
119
|
+
|
|
120
|
+
### Positive
|
|
121
|
+
|
|
122
|
+
- Developers gain a simple, documented CLI for common maintenance operations, without needing to write custom scripts.
|
|
123
|
+
- The CLI design keeps safety and reversibility in mind (dry-run support, clear exit codes).
|
|
124
|
+
- The CLI remains thin: it delegates all real work to the existing, tested maintenance utilities.
|
|
125
|
+
- Tests target the CLI behavior directly, while keeping it easy to evolve.
|
|
126
|
+
|
|
127
|
+
### Negative / Trade-offs
|
|
128
|
+
|
|
129
|
+
- Adding a CLI introduces a small surface area of user-facing behavior that must be maintained and versioned.
|
|
130
|
+
- The initial `report` and `update --dry-run` implementations will be relatively simple; richer reporting (file/line details, machine-readable change logs) will require incremental enhancements.
|
|
131
|
+
|
|
132
|
+
## Future Work (within Story 009.0)
|
|
133
|
+
|
|
134
|
+
The following improvements are planned as part of fully satisfying Story 009.0 but are not required to introduce the CLI itself:
|
|
135
|
+
|
|
136
|
+
- Enhance maintenance reporting to include **file and line** locations for each stale annotation, both programmatically and in the CLI `report` output.
|
|
137
|
+
- Improve error handling for edge cases such as permission-denied directories by making traversal utilities more resilient and surfacing issues via the CLI in a controlled way.
|
|
138
|
+
- Extend documentation in `user-docs/` and `README.md` to cover the maintenance CLI with examples and safety notes (dry-run, backups).
|
|
139
|
+
|
|
140
|
+
These changes will be implemented incrementally with dedicated tests and, where appropriate, additional ADRs or updates to this document.
|