@xenos1996/usa 2.3.4 → 2.5.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/README.md +2 -2
- package/dist/agent/index.d.ts +9 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +2 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/providers.d.ts +56 -0
- package/dist/agent/providers.d.ts.map +1 -0
- package/dist/agent/providers.js +334 -0
- package/dist/agent/providers.js.map +1 -0
- package/dist/agent/types.d.ts +103 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +19 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +52 -0
- package/dist/cli.js.map +1 -1
- package/dist/engine/audit.d.ts.map +1 -1
- package/dist/engine/audit.js +22 -0
- package/dist/engine/audit.js.map +1 -1
- package/dist/engine/categories.d.ts +45 -0
- package/dist/engine/categories.d.ts.map +1 -0
- package/dist/engine/categories.js +148 -0
- package/dist/engine/categories.js.map +1 -0
- package/dist/engine/evaluate.d.ts.map +1 -1
- package/dist/engine/evaluate.js +1 -0
- package/dist/engine/evaluate.js.map +1 -1
- package/dist/foundation/interview.d.ts +63 -0
- package/dist/foundation/interview.d.ts.map +1 -0
- package/dist/foundation/interview.js +459 -0
- package/dist/foundation/interview.js.map +1 -0
- package/dist/foundation/loader.d.ts +22 -0
- package/dist/foundation/loader.d.ts.map +1 -0
- package/dist/foundation/loader.js +240 -0
- package/dist/foundation/loader.js.map +1 -0
- package/dist/foundation/types.d.ts +73 -0
- package/dist/foundation/types.d.ts.map +1 -0
- package/dist/foundation/types.js +55 -0
- package/dist/foundation/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/report/foundation.d.ts +44 -0
- package/dist/report/foundation.d.ts.map +1 -0
- package/dist/report/foundation.js +147 -0
- package/dist/report/foundation.js.map +1 -0
- package/dist/report/json.d.ts +1 -0
- package/dist/report/json.d.ts.map +1 -1
- package/dist/report/json.js +2 -0
- package/dist/report/json.js.map +1 -1
- package/dist/report/markdown.d.ts.map +1 -1
- package/dist/report/markdown.js +10 -0
- package/dist/report/markdown.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/rules/categories.yaml +124 -0
- package/rules/core/foundation.yaml +307 -0
- package/rules/core/testing-assurance.yaml +240 -0
- package/rules/index.yaml +2 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
id: core/foundation
|
|
2
|
+
title: Foundation Readiness
|
|
3
|
+
section: S3
|
|
4
|
+
section_title: Foundation Readiness
|
|
5
|
+
description: >
|
|
6
|
+
Deterministic repo-setup readiness checks across seven pillars — docs,
|
|
7
|
+
governance, AI-readiness, testing, environment, pipelines, and standards —
|
|
8
|
+
so a project can be audited, built, and extended by humans and agents alike.
|
|
9
|
+
Intent-gated rules apply only when the interview declares a matching intent;
|
|
10
|
+
without the foundation file those rules skip and the generic ones still apply.
|
|
11
|
+
version: '1.0'
|
|
12
|
+
|
|
13
|
+
rules:
|
|
14
|
+
- id: FND-001
|
|
15
|
+
title: A README exists at the top level
|
|
16
|
+
section: S3
|
|
17
|
+
section_title: Foundation Readiness
|
|
18
|
+
severity: MEDIUM
|
|
19
|
+
class: documentation
|
|
20
|
+
tags: ['pillar:docs']
|
|
21
|
+
check:
|
|
22
|
+
kind: any_file
|
|
23
|
+
patterns:
|
|
24
|
+
- 'README.md'
|
|
25
|
+
- 'README.rst'
|
|
26
|
+
- 'README.txt'
|
|
27
|
+
- 'README'
|
|
28
|
+
- 'readme.md'
|
|
29
|
+
- 'readme.txt'
|
|
30
|
+
- 'readme'
|
|
31
|
+
why: 'A repo without a README has no front door: neither a human nor an agent can learn what it is or how to start.'
|
|
32
|
+
remediation: 'Add a README with purpose, setup steps, and how to run the checks.'
|
|
33
|
+
references: ['CII-Best-Practices']
|
|
34
|
+
|
|
35
|
+
- id: FND-002
|
|
36
|
+
title: License, contribution, and security docs are present
|
|
37
|
+
section: S3
|
|
38
|
+
section_title: Foundation Readiness
|
|
39
|
+
severity: MEDIUM
|
|
40
|
+
class: compliance
|
|
41
|
+
tags: ['pillar:docs']
|
|
42
|
+
check:
|
|
43
|
+
kind: count_min
|
|
44
|
+
patterns:
|
|
45
|
+
- '**/LICENSE*'
|
|
46
|
+
- '**/LICENCE*'
|
|
47
|
+
- '**/COPYING*'
|
|
48
|
+
- '**/CONTRIBUTING*'
|
|
49
|
+
- '**/SECURITY*'
|
|
50
|
+
- '**/CODE_OF_CONDUCT*'
|
|
51
|
+
min: 2
|
|
52
|
+
why: 'Missing license, contribution, or security-contact docs turn every external contribution and disclosure into a judgement call.'
|
|
53
|
+
remediation: 'Commit a LICENSE plus at least one of CONTRIBUTING, SECURITY, or CODE_OF_CONDUCT.'
|
|
54
|
+
references: ['OpenSSF-Scorecard:License', 'OpenSSF-Scorecard:Security-Policy', 'SPDX']
|
|
55
|
+
|
|
56
|
+
- id: FND-003
|
|
57
|
+
title: A CODEOWNERS file assigns review ownership
|
|
58
|
+
section: S3
|
|
59
|
+
section_title: Foundation Readiness
|
|
60
|
+
severity: MEDIUM
|
|
61
|
+
class: compliance
|
|
62
|
+
tags: ['pillar:governance']
|
|
63
|
+
check:
|
|
64
|
+
kind: any_file
|
|
65
|
+
patterns:
|
|
66
|
+
- '**/CODEOWNERS'
|
|
67
|
+
why: 'Without declared owners, reviews fall to whoever happens to look, and critical paths go unreviewed.'
|
|
68
|
+
remediation: 'Add a CODEOWNERS file mapping critical paths to the teams that must review them.'
|
|
69
|
+
references: ['OpenSSF-Scorecard:Code-Review']
|
|
70
|
+
|
|
71
|
+
- id: FND-004
|
|
72
|
+
title: Branch-protection evidence lives in .github
|
|
73
|
+
section: S3
|
|
74
|
+
section_title: Foundation Readiness
|
|
75
|
+
severity: MEDIUM
|
|
76
|
+
class: compliance
|
|
77
|
+
tags: ['pillar:governance']
|
|
78
|
+
check:
|
|
79
|
+
kind: grep_present
|
|
80
|
+
pattern: '(branch-?protection|required_pull_request_reviews|required_status_checks|require_code_owner_reviews|dismiss_stale_reviews)'
|
|
81
|
+
include: ['.github/**/*']
|
|
82
|
+
exclude: ['**/node_modules/**']
|
|
83
|
+
flags: i
|
|
84
|
+
why: 'Branch protection configured only in the forge UI is invisible to audit; checked-in evidence keeps the control reviewable.'
|
|
85
|
+
remediation: 'Check in branch-protection evidence (e.g. a settings or policy file under .github) requiring reviews and status checks.'
|
|
86
|
+
references: ['OpenSSF-Scorecard:Branch-Protection', 'SLSA-Source']
|
|
87
|
+
|
|
88
|
+
- id: FND-005
|
|
89
|
+
title: Architecture decisions are recorded as ADRs
|
|
90
|
+
section: S3
|
|
91
|
+
section_title: Foundation Readiness
|
|
92
|
+
severity: LOW
|
|
93
|
+
class: documentation
|
|
94
|
+
tags: ['pillar:governance']
|
|
95
|
+
check:
|
|
96
|
+
kind: any_file
|
|
97
|
+
patterns:
|
|
98
|
+
- 'docs/adr/**'
|
|
99
|
+
- 'docs/adrs/**'
|
|
100
|
+
- 'doc/adr/**'
|
|
101
|
+
- 'adr/**'
|
|
102
|
+
- 'adrs/**'
|
|
103
|
+
- 'docs/decisions/**'
|
|
104
|
+
why: 'Decisions without records get re-litigated forever; ADRs preserve the context future changes need.'
|
|
105
|
+
remediation: 'Record significant decisions as ADRs under docs/adr.'
|
|
106
|
+
references: ['ADR-Nygard']
|
|
107
|
+
|
|
108
|
+
- id: FND-006
|
|
109
|
+
title: Agent instructions (AGENTS.md or llms.txt) exist
|
|
110
|
+
section: S3
|
|
111
|
+
section_title: Foundation Readiness
|
|
112
|
+
severity: MEDIUM
|
|
113
|
+
class: documentation
|
|
114
|
+
tags: ['pillar:ai-readiness']
|
|
115
|
+
check:
|
|
116
|
+
kind: any_file
|
|
117
|
+
patterns:
|
|
118
|
+
- 'AGENTS.md'
|
|
119
|
+
- 'agents.md'
|
|
120
|
+
- 'llms.txt'
|
|
121
|
+
why: 'Agents working without project instructions improvise conventions; a checked-in instruction file makes machine collaboration deterministic.'
|
|
122
|
+
remediation: 'Add an AGENTS.md (or llms.txt) with build, test, and contribution instructions for agents.'
|
|
123
|
+
references: ['Agent-Skills', 'Docs-as-Code']
|
|
124
|
+
|
|
125
|
+
- id: FND-007
|
|
126
|
+
title: Docs carry machine-readable markers
|
|
127
|
+
section: S3
|
|
128
|
+
section_title: Foundation Readiness
|
|
129
|
+
severity: LOW
|
|
130
|
+
class: documentation
|
|
131
|
+
tags: ['pillar:ai-readiness']
|
|
132
|
+
check:
|
|
133
|
+
kind: grep_present
|
|
134
|
+
pattern: '(usa:[a-z0-9:_-]+|machine-readable|llms\.txt|AGENTS\.md)'
|
|
135
|
+
include: ['**/*.md', '**/*.txt']
|
|
136
|
+
exclude: ['**/node_modules/**']
|
|
137
|
+
flags: i
|
|
138
|
+
why: 'Markers agents can parse (fact flags, machine-readable pointers) turn prose docs into instructions automation can follow.'
|
|
139
|
+
remediation: 'Reference AGENTS.md/llms.txt from the README and tag machine-actionable facts with usa: markers.'
|
|
140
|
+
references: ['Agent-Skills', 'Docs-as-Code']
|
|
141
|
+
|
|
142
|
+
- id: FND-008
|
|
143
|
+
title: A test directory exists
|
|
144
|
+
section: S3
|
|
145
|
+
section_title: Foundation Readiness
|
|
146
|
+
severity: MEDIUM
|
|
147
|
+
class: correctness
|
|
148
|
+
tags: ['pillar:testing']
|
|
149
|
+
check:
|
|
150
|
+
kind: any_file
|
|
151
|
+
patterns:
|
|
152
|
+
- 'tests/**'
|
|
153
|
+
- 'test/**'
|
|
154
|
+
- '__tests__/**'
|
|
155
|
+
- 'spec/**'
|
|
156
|
+
- 'e2e/**'
|
|
157
|
+
why: 'A conventional test location tells contributors and CI exactly where confidence lives.'
|
|
158
|
+
remediation: 'Create a tests (or test/__tests__/spec) directory and put the first happy-path test there.'
|
|
159
|
+
references: ['OpenSSF-Scorecard:CI-Tests', 'NIST-SSDF-RV.1.1']
|
|
160
|
+
|
|
161
|
+
- id: FND-009
|
|
162
|
+
title: A coverage configuration exists
|
|
163
|
+
section: S3
|
|
164
|
+
section_title: Foundation Readiness
|
|
165
|
+
severity: LOW
|
|
166
|
+
class: correctness
|
|
167
|
+
tags: ['pillar:testing']
|
|
168
|
+
check:
|
|
169
|
+
kind: any_file
|
|
170
|
+
patterns:
|
|
171
|
+
- '.codecov.yml'
|
|
172
|
+
- '.codecov.yaml'
|
|
173
|
+
- 'codecov.yml'
|
|
174
|
+
- 'codecov.yaml'
|
|
175
|
+
- '**/vitest.config.*'
|
|
176
|
+
- '**/jest.config.*'
|
|
177
|
+
- '**/vitest.coverage.*'
|
|
178
|
+
- '**/.nycrc*'
|
|
179
|
+
- '**/coveragerc'
|
|
180
|
+
- '**/.coveragerc'
|
|
181
|
+
- '**/coverage.config.*'
|
|
182
|
+
why: 'Coverage that is never configured is never collected; the config is the commitment that coverage runs somewhere.'
|
|
183
|
+
remediation: 'Add a coverage config (e.g. codecov.yml or coverage settings in your test runner config).'
|
|
184
|
+
references: ['NIST-SSDF-RV.1.1']
|
|
185
|
+
|
|
186
|
+
- id: FND-010
|
|
187
|
+
title: The runtime version is pinned
|
|
188
|
+
section: S3
|
|
189
|
+
section_title: Foundation Readiness
|
|
190
|
+
severity: MEDIUM
|
|
191
|
+
class: operations
|
|
192
|
+
tags: ['pillar:environment']
|
|
193
|
+
check:
|
|
194
|
+
kind: any_file
|
|
195
|
+
patterns:
|
|
196
|
+
- '.nvmrc'
|
|
197
|
+
- '.node-version'
|
|
198
|
+
- '.tool-versions'
|
|
199
|
+
- '.python-version'
|
|
200
|
+
- '.ruby-version'
|
|
201
|
+
- '.go-version'
|
|
202
|
+
- 'runtime.txt'
|
|
203
|
+
- 'go.mod'
|
|
204
|
+
- 'Cargo.toml'
|
|
205
|
+
- 'pom.xml'
|
|
206
|
+
- 'Package.swift'
|
|
207
|
+
- '.java-version'
|
|
208
|
+
why: 'An unpinned runtime means every machine builds with a different toolchain; "works on my machine" starts here.'
|
|
209
|
+
remediation: 'Pin the runtime with .nvmrc, .tool-versions, .python-version, or the ecosystem equivalent.'
|
|
210
|
+
references: ['NIST-SSDF-PS.3.2', 'Reproducible-Builds']
|
|
211
|
+
|
|
212
|
+
- id: FND-011
|
|
213
|
+
title: The environment is reproducible from checked-in files
|
|
214
|
+
section: S3
|
|
215
|
+
section_title: Foundation Readiness
|
|
216
|
+
severity: MEDIUM
|
|
217
|
+
class: operations
|
|
218
|
+
tags: ['pillar:environment']
|
|
219
|
+
check:
|
|
220
|
+
kind: count_min
|
|
221
|
+
patterns:
|
|
222
|
+
- '.env.example'
|
|
223
|
+
- '.env.sample'
|
|
224
|
+
- '.env.template'
|
|
225
|
+
- 'Dockerfile'
|
|
226
|
+
- 'Dockerfile.*'
|
|
227
|
+
- 'Containerfile'
|
|
228
|
+
- 'compose.yml'
|
|
229
|
+
- 'compose.yaml'
|
|
230
|
+
- 'docker-compose.yml'
|
|
231
|
+
- 'docker-compose.yaml'
|
|
232
|
+
- '.devcontainer/devcontainer.json'
|
|
233
|
+
- 'Vagrantfile'
|
|
234
|
+
min: 2
|
|
235
|
+
why: "Setup that lives in one person's shell history is not setup; an env example plus a container definition lets anyone boot the project."
|
|
236
|
+
remediation: 'Commit a .env.example and a Dockerfile (or compose/devcontainer definition) so setup is declarative.'
|
|
237
|
+
references: ['12-Factor:Config', '12-Factor:Dev-Prod-Parity']
|
|
238
|
+
|
|
239
|
+
- id: FND-012
|
|
240
|
+
title: A CI workflow exists
|
|
241
|
+
section: S3
|
|
242
|
+
section_title: Foundation Readiness
|
|
243
|
+
severity: MEDIUM
|
|
244
|
+
class: operations
|
|
245
|
+
tags: ['pillar:pipelines']
|
|
246
|
+
check:
|
|
247
|
+
kind: any_file
|
|
248
|
+
patterns:
|
|
249
|
+
- '.github/workflows/*.yml'
|
|
250
|
+
- '.github/workflows/*.yaml'
|
|
251
|
+
- '.gitlab-ci.yml'
|
|
252
|
+
- 'Jenkinsfile'
|
|
253
|
+
- '.circleci/config.yml'
|
|
254
|
+
- 'azure-pipelines.yml'
|
|
255
|
+
- '.buildkite/**'
|
|
256
|
+
- 'bitbucket-pipelines.yml'
|
|
257
|
+
why: 'Without CI, every quality gate is advisory; the workflow file is the proof the gates actually run.'
|
|
258
|
+
remediation: 'Add a CI workflow that runs build, tests, and lint on every pull request.'
|
|
259
|
+
references: ['OpenSSF-Scorecard:CI-Tests', 'DORA']
|
|
260
|
+
|
|
261
|
+
- id: FND-013
|
|
262
|
+
title: A local task runner captures common workflows
|
|
263
|
+
section: S3
|
|
264
|
+
section_title: Foundation Readiness
|
|
265
|
+
severity: LOW
|
|
266
|
+
class: operations
|
|
267
|
+
tags: ['pillar:pipelines']
|
|
268
|
+
check:
|
|
269
|
+
kind: any_file
|
|
270
|
+
patterns:
|
|
271
|
+
- 'Makefile'
|
|
272
|
+
- 'makefile'
|
|
273
|
+
- 'GNUmakefile'
|
|
274
|
+
- 'justfile'
|
|
275
|
+
- 'Justfile'
|
|
276
|
+
- '.justfile'
|
|
277
|
+
- 'Taskfile.yml'
|
|
278
|
+
- 'Taskfile.yaml'
|
|
279
|
+
- 'Taskfile.dist.yml'
|
|
280
|
+
- 'tasks.py'
|
|
281
|
+
why: 'Tribal "run these five commands" knowledge rots; a task runner makes setup, test, and lint one documented command each.'
|
|
282
|
+
remediation: 'Add a Makefile or justfile with setup, test, and lint targets.'
|
|
283
|
+
references: ['DORA']
|
|
284
|
+
|
|
285
|
+
- id: FND-014
|
|
286
|
+
title: A machine-readable API contract is checked in
|
|
287
|
+
section: S3
|
|
288
|
+
section_title: Foundation Readiness
|
|
289
|
+
severity: MEDIUM
|
|
290
|
+
class: compliance
|
|
291
|
+
tags: ['pillar:standards']
|
|
292
|
+
applies_when:
|
|
293
|
+
any:
|
|
294
|
+
- { fact: 'intent:api' }
|
|
295
|
+
- { fact: 'intent:service' }
|
|
296
|
+
check:
|
|
297
|
+
kind: any_file
|
|
298
|
+
patterns:
|
|
299
|
+
- '**/openapi.{json,yaml,yml}'
|
|
300
|
+
- '**/swagger.{json,yaml,yml}'
|
|
301
|
+
- '**/asyncapi.{json,yaml,yml}'
|
|
302
|
+
- '**/api/*.yaml'
|
|
303
|
+
- '**/api/*.yml'
|
|
304
|
+
- '**/api/*.json'
|
|
305
|
+
why: 'An API without a checked-in contract cannot be reviewed, mocked, or tested by machines; the spec is the interface under version control.'
|
|
306
|
+
remediation: 'Check in an OpenAPI (or AsyncAPI) document describing the service contract.'
|
|
307
|
+
references: ['OpenAPI']
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
id: core/testing-assurance
|
|
2
|
+
title: Testing Assurance Markers
|
|
3
|
+
section: S7
|
|
4
|
+
section_title: Testing & Quality Assurance
|
|
5
|
+
description: >
|
|
6
|
+
Deterministic presence-markers for the testing assurance program: unit,
|
|
7
|
+
integration, and system layouts; contract tests; coverage and mutation
|
|
8
|
+
evidence; retry/determinism guards; failure assertions; and test-data
|
|
9
|
+
isolation. Every rule asserts only that a marker exists — never that the
|
|
10
|
+
tests are good, sufficient, or green.
|
|
11
|
+
version: '1.0'
|
|
12
|
+
|
|
13
|
+
rules:
|
|
14
|
+
- id: TAS-001
|
|
15
|
+
title: A unit-test layout exists
|
|
16
|
+
section: S7
|
|
17
|
+
section_title: Testing & Quality Assurance
|
|
18
|
+
severity: MEDIUM
|
|
19
|
+
class: correctness
|
|
20
|
+
check:
|
|
21
|
+
kind: any_file
|
|
22
|
+
patterns:
|
|
23
|
+
- 'tests/unit/**'
|
|
24
|
+
- 'test/unit/**'
|
|
25
|
+
- 'unit/**'
|
|
26
|
+
- '**/*.unit.test.*'
|
|
27
|
+
- '**/*.unit.spec.*'
|
|
28
|
+
why: 'A conventional unit-test location tells contributors and CI exactly where confidence lives.'
|
|
29
|
+
remediation: 'Put unit tests under tests/unit (or mark them *.unit.test.*) and wire the directory into CI.'
|
|
30
|
+
references: ['Testing-Trophy', 'OpenSSF-Scorecard:CI-Tests']
|
|
31
|
+
|
|
32
|
+
- id: TAS-002
|
|
33
|
+
title: An integration-test layout exists
|
|
34
|
+
section: S7
|
|
35
|
+
section_title: Testing & Quality Assurance
|
|
36
|
+
severity: MEDIUM
|
|
37
|
+
class: correctness
|
|
38
|
+
check:
|
|
39
|
+
kind: any_file
|
|
40
|
+
patterns:
|
|
41
|
+
- 'tests/integration/**'
|
|
42
|
+
- 'test/integration/**'
|
|
43
|
+
- 'tests/integ/**'
|
|
44
|
+
- '**/*.integration.test.*'
|
|
45
|
+
- '**/*.integ.test.*'
|
|
46
|
+
- '**/*.int.test.*'
|
|
47
|
+
why: 'Unit tests with everything mocked verify the mock, not the seam; a named integration layout is where seam coverage lives.'
|
|
48
|
+
remediation: 'Add tests/integration with tests that exercise a real database, queue, or HTTP boundary.'
|
|
49
|
+
references: ['Testing-Trophy']
|
|
50
|
+
|
|
51
|
+
- id: TAS-003
|
|
52
|
+
title: A system/end-to-end test layout exists
|
|
53
|
+
section: S7
|
|
54
|
+
section_title: Testing & Quality Assurance
|
|
55
|
+
severity: MEDIUM
|
|
56
|
+
class: correctness
|
|
57
|
+
check:
|
|
58
|
+
kind: any_file
|
|
59
|
+
patterns:
|
|
60
|
+
- 'tests/e2e/**'
|
|
61
|
+
- 'test/e2e/**'
|
|
62
|
+
- 'e2e/**'
|
|
63
|
+
- 'tests/system/**'
|
|
64
|
+
- 'test/system/**'
|
|
65
|
+
- 'system-tests/**'
|
|
66
|
+
- '**/*.e2e.*'
|
|
67
|
+
why: 'Unit tests cannot tell you that checkout is broken because a button moved; a system-level layout is where journey coverage lives.'
|
|
68
|
+
remediation: 'Cover three journeys first: sign up/log in, the core money path, and the path that would lose data if it failed.'
|
|
69
|
+
references: ['Testing-Trophy']
|
|
70
|
+
|
|
71
|
+
- id: TAS-004
|
|
72
|
+
title: Contract tests are present
|
|
73
|
+
section: S7
|
|
74
|
+
section_title: Testing & Quality Assurance
|
|
75
|
+
severity: LOW
|
|
76
|
+
class: correctness
|
|
77
|
+
check:
|
|
78
|
+
kind: any_file
|
|
79
|
+
patterns:
|
|
80
|
+
- 'pacts/**'
|
|
81
|
+
- 'pact/**'
|
|
82
|
+
- '**/*.pact.*'
|
|
83
|
+
- 'tests/contracts/**'
|
|
84
|
+
- 'tests/contract/**'
|
|
85
|
+
- 'test/contracts/**'
|
|
86
|
+
- '**/*.contract.test.*'
|
|
87
|
+
- '**/*.contract.spec.*'
|
|
88
|
+
why: 'An API without checked-in consumer contracts can only be tested by hand; pact files and contract suites are the machine-checkable shadow of that agreement.'
|
|
89
|
+
remediation: 'Record consumer-driven contracts (e.g. Pact) or add a tests/contracts suite asserting request/response shapes.'
|
|
90
|
+
references: ['OpenAPI', 'Testing-Trophy']
|
|
91
|
+
|
|
92
|
+
- id: TAS-005
|
|
93
|
+
title: Coverage configuration or output is present
|
|
94
|
+
section: S7
|
|
95
|
+
section_title: Testing & Quality Assurance
|
|
96
|
+
severity: LOW
|
|
97
|
+
class: correctness
|
|
98
|
+
check:
|
|
99
|
+
kind: any_file
|
|
100
|
+
patterns:
|
|
101
|
+
- '.codecov.yml'
|
|
102
|
+
- 'codecov.yml'
|
|
103
|
+
- 'codecov.yaml'
|
|
104
|
+
- '.coveragerc'
|
|
105
|
+
- '.nycrc'
|
|
106
|
+
- '.nycrc.json'
|
|
107
|
+
- '.c8rc'
|
|
108
|
+
- '.c8rc.json'
|
|
109
|
+
- 'coverage/**'
|
|
110
|
+
- '**/lcov.info'
|
|
111
|
+
why: 'Unmeasured coverage drifts down silently; a coverage config or report artifact proves measurement was set up at least once.'
|
|
112
|
+
remediation: 'Turn on coverage reporting in the test runner and publish the number on every PR.'
|
|
113
|
+
references: ['NIST-SSDF-RV.1.1']
|
|
114
|
+
|
|
115
|
+
- id: TAS-006
|
|
116
|
+
title: A coverage threshold is pinned in the package.json-embedded jest config
|
|
117
|
+
section: S7
|
|
118
|
+
section_title: Testing & Quality Assurance
|
|
119
|
+
severity: LOW
|
|
120
|
+
class: correctness
|
|
121
|
+
check:
|
|
122
|
+
kind: json_path
|
|
123
|
+
file: 'package.json'
|
|
124
|
+
path: 'jest.coverageThreshold'
|
|
125
|
+
why: 'A gate stops the slide — but this check reads only the package.json-embedded jest config, the one JSON location with a stable schema. Thresholds kept in vitest.config, jest.config.js, or .nycrc are invisible to it.'
|
|
126
|
+
remediation: 'Set jest.coverageThreshold in package.json, or keep the threshold wherever the runner reads it and accept this marker as not-applicable.'
|
|
127
|
+
references: ['NIST-SSDF-RV.1.1']
|
|
128
|
+
|
|
129
|
+
- id: TAS-007
|
|
130
|
+
title: Mutation-testing evidence is present
|
|
131
|
+
section: S7
|
|
132
|
+
section_title: Testing & Quality Assurance
|
|
133
|
+
severity: FUTURE
|
|
134
|
+
class: correctness
|
|
135
|
+
check:
|
|
136
|
+
kind: any_file
|
|
137
|
+
patterns:
|
|
138
|
+
- 'reports/**/*mut*'
|
|
139
|
+
- 'reports/mutation/**'
|
|
140
|
+
- 'stryker.conf.*'
|
|
141
|
+
- '.stryker.conf.*'
|
|
142
|
+
- '.mutmut*'
|
|
143
|
+
- 'mutants/**'
|
|
144
|
+
why: 'Coverage tells you which lines ran, not whether the test would have failed if the line were wrong; a mutation config or report proves the question was asked.'
|
|
145
|
+
remediation: 'Run mutation testing on the highest-risk module first and keep the config or report in the repo.'
|
|
146
|
+
references: ['Mutation-Testing']
|
|
147
|
+
|
|
148
|
+
- id: TAS-008
|
|
149
|
+
title: A determinism guard is set in test config or CI
|
|
150
|
+
section: S7
|
|
151
|
+
section_title: Testing & Quality Assurance
|
|
152
|
+
severity: LOW
|
|
153
|
+
class: correctness
|
|
154
|
+
check:
|
|
155
|
+
kind: grep_present
|
|
156
|
+
pattern: '(forbidOnly|forbid-only|forbid_only|failOnConsole|fail-on-console)'
|
|
157
|
+
include:
|
|
158
|
+
[
|
|
159
|
+
'playwright.config.*',
|
|
160
|
+
'cypress.config.*',
|
|
161
|
+
'vitest.config.*',
|
|
162
|
+
'vitest.workspace.*',
|
|
163
|
+
'jest.config.*',
|
|
164
|
+
'package.json',
|
|
165
|
+
'.github/workflows/*.yml',
|
|
166
|
+
'.github/workflows/*.yaml',
|
|
167
|
+
'.gitlab-ci.yml',
|
|
168
|
+
]
|
|
169
|
+
why: 'Focused-test markers (.only) committed by accident silently skip the rest of the suite; a forbid-only guard string proves the leak was thought about.'
|
|
170
|
+
remediation: 'Set forbidOnly on CI (e.g. Playwright forbidOnly) so a stray .only fails the build instead of shrinking it.'
|
|
171
|
+
references: ['Google-Testing-Blog:Flaky']
|
|
172
|
+
|
|
173
|
+
- id: TAS-009
|
|
174
|
+
title: A test retry budget is declared
|
|
175
|
+
section: S7
|
|
176
|
+
section_title: Testing & Quality Assurance
|
|
177
|
+
severity: LOW
|
|
178
|
+
class: operations
|
|
179
|
+
check:
|
|
180
|
+
kind: grep_present
|
|
181
|
+
pattern: '(retries\s*:\s*[1-9]|"retries"\s*:\s*[1-9]|retries=[1-9]|--retries[ =][1-9]|rerun-failed|flaky-test-retry|retry-on-failure)'
|
|
182
|
+
include:
|
|
183
|
+
[
|
|
184
|
+
'playwright.config.*',
|
|
185
|
+
'cypress.config.*',
|
|
186
|
+
'vitest.config.*',
|
|
187
|
+
'jest.config.*',
|
|
188
|
+
'package.json',
|
|
189
|
+
'.github/workflows/*.yml',
|
|
190
|
+
'.github/workflows/*.yaml',
|
|
191
|
+
'.gitlab-ci.yml',
|
|
192
|
+
]
|
|
193
|
+
why: 'A retries setting proves the project pays for reruns; it proves nothing about whether the tests are flaky or stable — only that the budget exists.'
|
|
194
|
+
remediation: 'Declare an explicit retry budget (e.g. retries: 2 on CI) and track which tests consume it; quarantine chronic consumers.'
|
|
195
|
+
references: ['Google-Testing-Blog:Flaky']
|
|
196
|
+
|
|
197
|
+
- id: TAS-010
|
|
198
|
+
title: Tests assert failure paths
|
|
199
|
+
section: S7
|
|
200
|
+
section_title: Testing & Quality Assurance
|
|
201
|
+
severity: MEDIUM
|
|
202
|
+
class: correctness
|
|
203
|
+
check:
|
|
204
|
+
kind: grep_present
|
|
205
|
+
pattern: '(\.toThrow\(|\.rejects|pytest\.raises|assertRaises|assert\.rejects|ShouldThrow|assert\.throws)'
|
|
206
|
+
include:
|
|
207
|
+
[
|
|
208
|
+
'**/*.test.*',
|
|
209
|
+
'**/*.spec.*',
|
|
210
|
+
'**/test_*.py',
|
|
211
|
+
'**/*_test.*',
|
|
212
|
+
'tests/**',
|
|
213
|
+
'test/**',
|
|
214
|
+
'__tests__/**',
|
|
215
|
+
'spec/**',
|
|
216
|
+
]
|
|
217
|
+
why: 'A suite that only asserts happy paths never proves the error handling works; failure-assertion strings prove at least one test looks at the sad path.'
|
|
218
|
+
remediation: 'Add negative tests for every permission boundary and every error branch — 401/403 paths, validation rejections, and cross-tenant attempts.'
|
|
219
|
+
references: ['Testing-Patterns']
|
|
220
|
+
|
|
221
|
+
- id: TAS-011
|
|
222
|
+
title: Test-data and environment isolation markers exist
|
|
223
|
+
section: S7
|
|
224
|
+
section_title: Testing & Quality Assurance
|
|
225
|
+
severity: LOW
|
|
226
|
+
class: maintainability
|
|
227
|
+
check:
|
|
228
|
+
kind: any_file
|
|
229
|
+
patterns:
|
|
230
|
+
- 'tests/fixtures/**'
|
|
231
|
+
- 'test/fixtures/**'
|
|
232
|
+
- '**/__fixtures__/**'
|
|
233
|
+
- '**/factories/**'
|
|
234
|
+
- '**/__factories__/**'
|
|
235
|
+
- '.env.test'
|
|
236
|
+
- '.env.testing'
|
|
237
|
+
- 'tests/.env.test'
|
|
238
|
+
why: 'Hand-built object literals in 200 tests make every schema change a 200-file migration, and tests sharing the live environment leak state; fixtures, factories, and a dedicated test env file are the markers of isolation.'
|
|
239
|
+
remediation: 'Add a factory or fixtures directory and a .env.test so tests generate data and never touch the dev or prod environment.'
|
|
240
|
+
references: ['Testing-Patterns', '12-Factor:Config']
|
package/rules/index.yaml
CHANGED
|
@@ -13,11 +13,13 @@ packs:
|
|
|
13
13
|
- core/repo.yaml
|
|
14
14
|
- core/security.yaml
|
|
15
15
|
- core/supply-chain.yaml
|
|
16
|
+
- core/foundation.yaml
|
|
16
17
|
- core/provenance-cosign.yaml
|
|
17
18
|
- core/provenance-attestation.yaml
|
|
18
19
|
- core/architecture.yaml
|
|
19
20
|
- core/code-quality.yaml
|
|
20
21
|
- core/testing.yaml
|
|
22
|
+
- core/testing-assurance.yaml
|
|
21
23
|
- core/cicd.yaml
|
|
22
24
|
- core/release.yaml
|
|
23
25
|
- core/dependencies.yaml
|