@xenos1996/usa 2.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 (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +335 -0
  3. package/USA.md +597 -0
  4. package/dist/bootstrap/catalog.d.ts +46 -0
  5. package/dist/bootstrap/catalog.d.ts.map +1 -0
  6. package/dist/bootstrap/catalog.js +312 -0
  7. package/dist/bootstrap/catalog.js.map +1 -0
  8. package/dist/bootstrap/index.d.ts +36 -0
  9. package/dist/bootstrap/index.d.ts.map +1 -0
  10. package/dist/bootstrap/index.js +177 -0
  11. package/dist/bootstrap/index.js.map +1 -0
  12. package/dist/cli.d.ts +5 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +706 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/config.d.ts +7 -0
  17. package/dist/config.d.ts.map +1 -0
  18. package/dist/config.js +88 -0
  19. package/dist/config.js.map +1 -0
  20. package/dist/detect/index.d.ts +58 -0
  21. package/dist/detect/index.d.ts.map +1 -0
  22. package/dist/detect/index.js +329 -0
  23. package/dist/detect/index.js.map +1 -0
  24. package/dist/engine/audit.d.ts +32 -0
  25. package/dist/engine/audit.d.ts.map +1 -0
  26. package/dist/engine/audit.js +366 -0
  27. package/dist/engine/audit.js.map +1 -0
  28. package/dist/engine/diff.d.ts +24 -0
  29. package/dist/engine/diff.d.ts.map +1 -0
  30. package/dist/engine/diff.js +136 -0
  31. package/dist/engine/diff.js.map +1 -0
  32. package/dist/engine/evaluate.d.ts +19 -0
  33. package/dist/engine/evaluate.d.ts.map +1 -0
  34. package/dist/engine/evaluate.js +377 -0
  35. package/dist/engine/evaluate.js.map +1 -0
  36. package/dist/engine/gate.d.ts +19 -0
  37. package/dist/engine/gate.d.ts.map +1 -0
  38. package/dist/engine/gate.js +47 -0
  39. package/dist/engine/gate.js.map +1 -0
  40. package/dist/engine/loader.d.ts +37 -0
  41. package/dist/engine/loader.d.ts.map +1 -0
  42. package/dist/engine/loader.js +388 -0
  43. package/dist/engine/loader.js.map +1 -0
  44. package/dist/engine/maturity.d.ts +20 -0
  45. package/dist/engine/maturity.d.ts.map +1 -0
  46. package/dist/engine/maturity.js +157 -0
  47. package/dist/engine/maturity.js.map +1 -0
  48. package/dist/engine/score.d.ts +19 -0
  49. package/dist/engine/score.d.ts.map +1 -0
  50. package/dist/engine/score.js +141 -0
  51. package/dist/engine/score.js.map +1 -0
  52. package/dist/engine/sections.d.ts +14 -0
  53. package/dist/engine/sections.d.ts.map +1 -0
  54. package/dist/engine/sections.js +50 -0
  55. package/dist/engine/sections.js.map +1 -0
  56. package/dist/evolution/benchmark.d.ts +12 -0
  57. package/dist/evolution/benchmark.d.ts.map +1 -0
  58. package/dist/evolution/benchmark.js +107 -0
  59. package/dist/evolution/benchmark.js.map +1 -0
  60. package/dist/evolution/capability.d.ts +22 -0
  61. package/dist/evolution/capability.d.ts.map +1 -0
  62. package/dist/evolution/capability.js +69 -0
  63. package/dist/evolution/capability.js.map +1 -0
  64. package/dist/evolution/coverage.d.ts +15 -0
  65. package/dist/evolution/coverage.d.ts.map +1 -0
  66. package/dist/evolution/coverage.js +65 -0
  67. package/dist/evolution/coverage.js.map +1 -0
  68. package/dist/evolution/gap.d.ts +10 -0
  69. package/dist/evolution/gap.d.ts.map +1 -0
  70. package/dist/evolution/gap.js +52 -0
  71. package/dist/evolution/gap.js.map +1 -0
  72. package/dist/evolution/propose.d.ts +50 -0
  73. package/dist/evolution/propose.d.ts.map +1 -0
  74. package/dist/evolution/propose.js +188 -0
  75. package/dist/evolution/propose.js.map +1 -0
  76. package/dist/evolution/queue.d.ts +64 -0
  77. package/dist/evolution/queue.d.ts.map +1 -0
  78. package/dist/evolution/queue.js +192 -0
  79. package/dist/evolution/queue.js.map +1 -0
  80. package/dist/evolution/release.d.ts +11 -0
  81. package/dist/evolution/release.d.ts.map +1 -0
  82. package/dist/evolution/release.js +55 -0
  83. package/dist/evolution/release.js.map +1 -0
  84. package/dist/evolution/run.d.ts +88 -0
  85. package/dist/evolution/run.d.ts.map +1 -0
  86. package/dist/evolution/run.js +258 -0
  87. package/dist/evolution/run.js.map +1 -0
  88. package/dist/evolution/schedule.d.ts +59 -0
  89. package/dist/evolution/schedule.d.ts.map +1 -0
  90. package/dist/evolution/schedule.js +77 -0
  91. package/dist/evolution/schedule.js.map +1 -0
  92. package/dist/evolution/types.d.ts +174 -0
  93. package/dist/evolution/types.d.ts.map +1 -0
  94. package/dist/evolution/types.js +8 -0
  95. package/dist/evolution/types.js.map +1 -0
  96. package/dist/index.d.ts +36 -0
  97. package/dist/index.d.ts.map +1 -0
  98. package/dist/index.js +30 -0
  99. package/dist/index.js.map +1 -0
  100. package/dist/learn/index.d.ts +27 -0
  101. package/dist/learn/index.d.ts.map +1 -0
  102. package/dist/learn/index.js +196 -0
  103. package/dist/learn/index.js.map +1 -0
  104. package/dist/report/markdown.d.ts +16 -0
  105. package/dist/report/markdown.d.ts.map +1 -0
  106. package/dist/report/markdown.js +488 -0
  107. package/dist/report/markdown.js.map +1 -0
  108. package/dist/snapshot/index.d.ts +55 -0
  109. package/dist/snapshot/index.d.ts.map +1 -0
  110. package/dist/snapshot/index.js +76 -0
  111. package/dist/snapshot/index.js.map +1 -0
  112. package/dist/store/index.d.ts +31 -0
  113. package/dist/store/index.d.ts.map +1 -0
  114. package/dist/store/index.js +69 -0
  115. package/dist/store/index.js.map +1 -0
  116. package/dist/types.d.ts +287 -0
  117. package/dist/types.d.ts.map +1 -0
  118. package/dist/types.js +16 -0
  119. package/dist/types.js.map +1 -0
  120. package/dist/util/glob.d.ts +11 -0
  121. package/dist/util/glob.d.ts.map +1 -0
  122. package/dist/util/glob.js +86 -0
  123. package/dist/util/glob.js.map +1 -0
  124. package/dist/util/project.d.ts +90 -0
  125. package/dist/util/project.d.ts.map +1 -0
  126. package/dist/util/project.js +636 -0
  127. package/dist/util/project.js.map +1 -0
  128. package/dist/util/yaml.d.ts +28 -0
  129. package/dist/util/yaml.d.ts.map +1 -0
  130. package/dist/util/yaml.js +48 -0
  131. package/dist/util/yaml.js.map +1 -0
  132. package/package.json +94 -0
  133. package/rules/core/architecture.yaml +190 -0
  134. package/rules/core/cicd.yaml +212 -0
  135. package/rules/core/code-quality.yaml +261 -0
  136. package/rules/core/dependencies.yaml +132 -0
  137. package/rules/core/documentation.yaml +119 -0
  138. package/rules/core/future-readiness.yaml +91 -0
  139. package/rules/core/release.yaml +131 -0
  140. package/rules/core/repo.yaml +313 -0
  141. package/rules/core/security.yaml +496 -0
  142. package/rules/core/supply-chain.yaml +357 -0
  143. package/rules/core/testing.yaml +266 -0
  144. package/rules/detectors.yaml +2028 -0
  145. package/rules/index.yaml +42 -0
  146. package/rules/profiles/maturity.yaml +135 -0
  147. package/rules/stacks/ai-era.yaml +193 -0
  148. package/rules/stacks/api-backend.yaml +121 -0
  149. package/rules/stacks/cli.yaml +105 -0
  150. package/rules/stacks/compliance.yaml +157 -0
  151. package/rules/stacks/containers.yaml +124 -0
  152. package/rules/stacks/data.yaml +165 -0
  153. package/rules/stacks/go.yaml +134 -0
  154. package/rules/stacks/iac.yaml +128 -0
  155. package/rules/stacks/jvm.yaml +150 -0
  156. package/rules/stacks/ml-ai.yaml +140 -0
  157. package/rules/stacks/mobile.yaml +121 -0
  158. package/rules/stacks/node-typescript.yaml +166 -0
  159. package/rules/stacks/python.yaml +175 -0
  160. package/rules/stacks/rust.yaml +129 -0
  161. package/rules/stacks/solidity.yaml +139 -0
  162. package/rules/stacks/swift.yaml +100 -0
  163. package/rules/stacks/web-frontend.yaml +159 -0
@@ -0,0 +1,131 @@
1
+ id: core/release
2
+ title: Release & Change Management
3
+ section: S9
4
+ section_title: Release & Change Management
5
+ description: >
6
+ How a merged commit becomes a version someone else depends on. This section
7
+ is what separates "we deploy" from "we ship".
8
+ version: '1.0'
9
+
10
+ rules:
11
+ - id: REL-001
12
+ title: Versioning is semantic and consistent
13
+ section: S9
14
+ section_title: Release & Change Management
15
+ severity: MEDIUM
16
+ class: maintainability
17
+ applies_when:
18
+ not: { fact: 'maturity:prototype' }
19
+ check: { kind: manual }
20
+ evidence: 'Current version, and whether MAJOR/MINOR/PATCH changes match SemVer in practice.'
21
+ why: 'Consumers (including your future self) need to know whether upgrading is safe.'
22
+ remediation: 'Adopt SemVer; automate version bumps from Conventional Commits (Changesets, semantic-release).'
23
+ references: ['SemVer', 'OpenSSF-Scorecard:Signed-Releases']
24
+
25
+ - id: REL-002
26
+ title: Releases are tagged in version control
27
+ section: S9
28
+ section_title: Release & Change Management
29
+ severity: MEDIUM
30
+ class: operations
31
+ applies_when:
32
+ not: { fact: 'maturity:prototype' }
33
+ check: { kind: manual }
34
+ evidence: '`git tag --list` output, or the release automation config that creates tags.'
35
+ why: 'Without tags, "what is running in production?" has no answer you can look up.'
36
+ remediation: 'Tag every release (v1.2.3) and deploy from the tag, not from a branch tip.'
37
+ references: ['SLSA-Source', 'OpenSSF-Scorecard:Signed-Releases']
38
+
39
+ - id: REL-003
40
+ title: Release notes are published
41
+ section: S9
42
+ section_title: Release & Change Management
43
+ severity: LOW
44
+ class: documentation
45
+ applies_when:
46
+ not: { fact: 'maturity:prototype' }
47
+ check:
48
+ kind: grep_present
49
+ pattern: '(semantic-release|release-drafter|changesets|changeset version|generate-notes|release_notes|changelog)'
50
+ include:
51
+ [
52
+ '.github/workflows/*.yml',
53
+ '.github/workflows/*.yaml',
54
+ '.github/release.yml',
55
+ 'package.json',
56
+ '.changeset/config.json',
57
+ 'Makefile',
58
+ ]
59
+ flags: i
60
+ why: 'A tag with no notes makes every upgrade an archaeology project for your users.'
61
+ remediation: 'Generate notes from commit scope; hand-edit the breaking-changes section.'
62
+ references: ['Keep-a-Changelog']
63
+
64
+ - id: REL-004
65
+ title: Risky changes sit behind a feature flag
66
+ section: S9
67
+ section_title: Release & Change Management
68
+ severity: LOW
69
+ class: operations
70
+ applies_when:
71
+ any:
72
+ - { fact: 'maturity:production' }
73
+ - { fact: 'maturity:beta' }
74
+ check:
75
+ kind: grep_present
76
+ pattern: '(launchdarkly|unleash|flagsmith|growthbook|posthog|openfeature|isFeatureEnabled|featureFlag|useFlag|flipper)'
77
+ include: ['**/*.{ts,tsx,js,jsx,py,go,rs,java,kt,rb}']
78
+ exclude: ['**/*.test.*', '**/node_modules/**']
79
+ flags: i
80
+ why: 'Deploy and release are different verbs. Flags let you deploy on Tuesday and release on Thursday.'
81
+ remediation: 'Wrap new behaviour in a flag with a default-off rollout and a documented kill switch.'
82
+ references: ['DORA', 'Progressive-Delivery']
83
+
84
+ - id: REL-005
85
+ title: Database migrations run forward and are reversible
86
+ section: S9
87
+ section_title: Release & Change Management
88
+ severity: HIGH
89
+ class: correctness
90
+ applies_when: { fact: 'has:database' }
91
+ check: { kind: manual }
92
+ evidence: 'Migration tool in use, and for the last destructive migration: the expand/contract or down-migration plan.'
93
+ why: 'A migration you cannot reverse is a one-way door taken during a deploy, usually at the worst moment.'
94
+ remediation: 'Use expand/contract: add column → backfill → switch reads → drop later. Keep down-migrations tested for everything else.'
95
+ references: ['NIST-SSDF-PO.5']
96
+
97
+ - id: REL-006
98
+ title: Migrations are separated from application deploys
99
+ section: S9
100
+ section_title: Release & Change Management
101
+ severity: MEDIUM
102
+ class: correctness
103
+ applies_when: { fact: 'has:database' }
104
+ check: { kind: manual }
105
+ evidence: 'Deploy order: does the schema change ship before the code that requires it?'
106
+ why: 'Deploying code and schema simultaneously means the old code briefly runs against the new schema.'
107
+ remediation: 'Run migrations as a separate, first step; keep every change backward-compatible with the currently deployed version.'
108
+ references: ['Expand-Contract']
109
+
110
+ - id: REL-007
111
+ title: There is a documented incident/runbook path
112
+ section: S9
113
+ section_title: Release & Change Management
114
+ severity: MEDIUM
115
+ class: operations
116
+ applies_when: { fact: 'maturity:production' }
117
+ check:
118
+ kind: any_file
119
+ patterns:
120
+ [
121
+ '**/RUNBOOK*',
122
+ '**/runbook*',
123
+ 'docs/runbooks/**',
124
+ 'runbooks/**',
125
+ 'docs/on-call*',
126
+ 'docs/incident*',
127
+ 'INCIDENT.md',
128
+ ]
129
+ why: 'The middle of an incident is the worst possible time to discover nobody wrote down how to restart the queue.'
130
+ remediation: 'One runbook per service: how to check health, restart, roll back, escalate, and who owns it.'
131
+ references: ['NIST-SSDF-RV.2', 'Google-SRE']
@@ -0,0 +1,313 @@
1
+ id: core/repo
2
+ title: Repository & Project Structure
3
+ section: S1
4
+ section_title: Repository & Project Structure
5
+ description: >
6
+ Root hygiene, the essential-files baseline, and version-control quality.
7
+ Cheap to fix, expensive to ignore — this is where most leaked credentials
8
+ and most onboarding pain originate.
9
+ version: '1.0'
10
+
11
+ rules:
12
+ - id: REPO-001
13
+ title: .gitignore is present
14
+ section: S1
15
+ section_title: Repository & Project Structure
16
+ severity: CRITICAL
17
+ class: security
18
+ check: { kind: file_exists, files: ['.gitignore'] }
19
+ why: >
20
+ Without a .gitignore the next `git add -A` commits node_modules, build
21
+ output, and — sooner or later — a .env file.
22
+ remediation: 'Add a .gitignore for your stack (github/gitignore has templates).'
23
+ references: ['CWE-540', 'OpenSSF-Scorecard:Binary-Artifacts']
24
+
25
+ - id: REPO-002
26
+ title: No environment/secret files committed
27
+ section: S1
28
+ section_title: Repository & Project Structure
29
+ severity: CRITICAL
30
+ class: security
31
+ check:
32
+ kind: tracked_absent
33
+ patterns:
34
+ [
35
+ '.env',
36
+ '.env.*',
37
+ '*.env',
38
+ '*.pem',
39
+ '*.key',
40
+ '*.p12',
41
+ '*.pfx',
42
+ 'id_rsa*',
43
+ 'credentials*',
44
+ 'secrets/**',
45
+ '.npmrc',
46
+ '.pypirc',
47
+ ]
48
+ why: 'A committed .env is a published credential. Rotating is the only fix.'
49
+ remediation: 'Remove from the index, rotate every value in the file, purge history (git filter-repo / BFG), add to .gitignore.'
50
+ references: ['CWE-798', 'ASVS-14.3.2', 'OpenSSF-Scorecard:Binary-Artifacts']
51
+
52
+ - id: REPO-003
53
+ title: No secrets in git history
54
+ section: S1
55
+ section_title: Repository & Project Structure
56
+ severity: CRITICAL
57
+ class: security
58
+ check:
59
+ kind: command
60
+ # NOTE: stage 1 allows one optional quote: most real secrets in history
61
+ # are quoted (`"token": "abc…"`, `key = "abc…"`), and a rule blind to
62
+ # them is decorative. Stage 2 drops only unquoted type-annotation
63
+ # shapes (`privateKey: NIOSSLPrivateKey`, `token: String`) — a bare
64
+ # capitalized identifier after a colon is a type, not a value. Exit
65
+ # algebra: the first grep runs WITHOUT -q so lines flow; only the
66
+ # final grep is quiet (matches must never reach CI logs). -v exits 1
67
+ # (→ PASS) only when every match was a declaration; any other hit
68
+ # exits 0 (→ FAIL). Quoted values and `=` assignments are never
69
+ # excluded — recall first for a CRITICAL history scan.
70
+ run: '! git log -p --all | grep -iE "(api[_-]?key|secret|password|passwd|token|private[_-]?key)[[:space:]]*[:=][[:space:]]*[\"'']?[A-Za-z0-9/+_-]{16,}" | grep -qiEv "(api[_-]?key|secret|password|passwd|token|private[_-]?key)[[:space:]]*:[[:space:]]*[A-Z][A-Za-z0-9_]*[[:space:]]*[,);]*[[:space:]]*\{?[[:space:]]*$"'
71
+ expect_exit: 0
72
+ why: 'Deleting a secret from HEAD does not delete it from history. Anyone who cloned the repo still has it.'
73
+ evidence: 'Command output, or a manual `gitleaks detect --log-opts=--all` run.'
74
+ remediation: 'Rotate the exposed values and rewrite history with git-filter-repo. Rotation first: assume it is already public.'
75
+ references: ['CWE-798', 'ASVS-14.3.2']
76
+
77
+ - id: REPO-004
78
+ title: README present
79
+ section: S1
80
+ section_title: Repository & Project Structure
81
+ severity: HIGH
82
+ class: documentation
83
+ check:
84
+ kind: any_file
85
+ patterns: ['README.md', 'readme.md', 'README.rst', 'README.txt', 'README']
86
+ why: 'The README is the front door. Without it, every new contributor needs a human guided tour.'
87
+ remediation: 'Write: what this is, how to install, how to run it, how to contribute. Four headings, one page.'
88
+ references: ['CII-Best-Practices']
89
+
90
+ - id: REPO-005
91
+ title: LICENSE present
92
+ section: S1
93
+ section_title: Repository & Project Structure
94
+ severity: HIGH
95
+ class: compliance
96
+ check:
97
+ kind: any_file
98
+ patterns: ['LICENSE*', 'COPYING*']
99
+ why: 'No license means "all rights reserved" by default. Nobody can legally use it, including you, later.'
100
+ remediation: 'Add MIT / Apache-2.0 / GPL-3.0 as appropriate. Choose at choosealicense.com.'
101
+ references: ['OpenSSF-Scorecard:License', 'SPDX']
102
+
103
+ - id: REPO-006
104
+ title: .env.example documents required configuration
105
+ section: S1
106
+ section_title: Repository & Project Structure
107
+ severity: HIGH
108
+ class: maintainability
109
+ applies_when:
110
+ any:
111
+ - { fact: 'has:database' }
112
+ - { fact: 'platform:server' }
113
+ - { fact: 'auth:jwt' }
114
+ - { fact: 'auth:apikey' }
115
+ - { fact: 'auth:oauth' }
116
+ check:
117
+ kind: any_file
118
+ patterns: ['.env.example', '.env.sample', '.env.template', 'env.example', 'config.example.*']
119
+ why: 'Undocumented required env vars turn setup into archaeology.'
120
+ remediation: 'Add .env.example listing every variable the app reads, with safe placeholder values and a comment per var.'
121
+ references: ['ASVS-14.3.2']
122
+
123
+ - id: REPO-007
124
+ title: Build artifacts and dependencies are not committed
125
+ section: S1
126
+ section_title: Repository & Project Structure
127
+ severity: HIGH
128
+ class: maintainability
129
+ check:
130
+ kind: tracked_absent
131
+ patterns:
132
+ [
133
+ 'dist/**',
134
+ 'build/**',
135
+ 'out/**',
136
+ 'node_modules/**',
137
+ 'target/**',
138
+ '.venv/**',
139
+ 'venv/**',
140
+ '*.egg-info/**',
141
+ '__pycache__/**',
142
+ 'coverage/**',
143
+ '.next/**',
144
+ ]
145
+ why: 'Committed build output bloats the repo, guarantees merge conflicts, and hides the real source in review noise.'
146
+ remediation: 'Untrack (git rm -r --cached) and add the paths to .gitignore.'
147
+ references: ['OpenSSF-Scorecard:Binary-Artifacts']
148
+
149
+ - id: REPO-008
150
+ title: Large binaries are not committed directly
151
+ section: S1
152
+ section_title: Repository & Project Structure
153
+ severity: MEDIUM
154
+ class: maintainability
155
+ check:
156
+ kind: tracked_absent
157
+ patterns:
158
+ [
159
+ '*.mp4',
160
+ '*.mov',
161
+ '*.zip',
162
+ '*.tar.gz',
163
+ '*.tgz',
164
+ '*.exe',
165
+ '*.dll',
166
+ '*.so',
167
+ '*.dylib',
168
+ '*.jar',
169
+ '*.war',
170
+ '*.psd',
171
+ '*.sketch',
172
+ ]
173
+ why: 'Git stores every revision of every binary forever. Use Git LFS or object storage.'
174
+ remediation: 'Move binaries to LFS or object storage; rewrite history if the repo has already grown past ~200 MB.'
175
+ references: ['OpenSSF-Scorecard:Binary-Artifacts']
176
+
177
+ - id: REPO-009
178
+ title: SECURITY.md published
179
+ section: S1
180
+ section_title: Repository & Project Structure
181
+ severity: HIGH
182
+ class: security
183
+ applies_when:
184
+ not: { fact: 'maturity:prototype' }
185
+ check:
186
+ kind: any_file
187
+ patterns: ['SECURITY.md', '.github/SECURITY.md', 'docs/SECURITY.md']
188
+ why: 'Without a disclosure route, researchers either stay silent or post publicly. Neither helps you.'
189
+ remediation: 'Add SECURITY.md with supported versions and a report address. GitHub surfaces it in the Security tab.'
190
+ references: ['OpenSSF-Scorecard:Security-Policy', 'NIST-SSDF-RV.1.1']
191
+
192
+ - id: REPO-010
193
+ title: CHANGELOG maintained
194
+ section: S1
195
+ section_title: Repository & Project Structure
196
+ severity: MEDIUM
197
+ class: documentation
198
+ applies_when:
199
+ not: { fact: 'maturity:prototype' }
200
+ check:
201
+ kind: any_file
202
+ patterns: ['CHANGELOG*', 'CHANGES*', 'HISTORY.md']
203
+ why: 'Users and downstream maintainers need to know what changed and whether it will break them.'
204
+ remediation: 'Adopt Keep a Changelog, or generate it from Conventional Commits / Changesets.'
205
+ references: ['Keep-a-Changelog']
206
+
207
+ - id: REPO-011
208
+ title: CONTRIBUTING guide present
209
+ section: S1
210
+ section_title: Repository & Project Structure
211
+ severity: LOW
212
+ class: documentation
213
+ applies_when:
214
+ not: { fact: 'maturity:prototype' }
215
+ check: { kind: any_file, patterns: ['CONTRIBUTING*', 'docs/CONTRIBUTING*'] }
216
+ why: 'Turns "how do I run the tests?" from an interruption into a link.'
217
+ remediation: 'Setup, test/lint commands, branch naming, commit convention, review expectations.'
218
+ references: ['CII-Best-Practices']
219
+
220
+ - id: REPO-012
221
+ title: Code of conduct present
222
+ section: S1
223
+ section_title: Repository & Project Structure
224
+ severity: LOW
225
+ class: compliance
226
+ applies_when:
227
+ not: { fact: 'maturity:prototype' }
228
+ check: { kind: any_file, patterns: ['CODE_OF_CONDUCT*', 'docs/CODE_OF_CONDUCT*'] }
229
+ why: 'Sets the floor for interaction and gives maintainers something to point at.'
230
+ remediation: 'Adopt the Contributor Covenant.'
231
+ references: ['CII-Best-Practices']
232
+
233
+ - id: REPO-013
234
+ title: .editorconfig present
235
+ section: S1
236
+ section_title: Repository & Project Structure
237
+ severity: LOW
238
+ class: style
239
+ check: { kind: file_exists, files: ['.editorconfig'] }
240
+ why: 'Kills tabs-vs-spaces diffs before they start, across every editor.'
241
+ remediation: 'Add a 6-line .editorconfig (charset, EOL, indent style/size, trailing whitespace, final newline).'
242
+
243
+ - id: REPO-014
244
+ title: CODEOWNERS assigns review responsibility
245
+ section: S1
246
+ section_title: Repository & Project Structure
247
+ severity: MEDIUM
248
+ class: operations
249
+ applies_when: { fact: 'metric:contributors', op: 'gt', value: 2 }
250
+ check: { kind: any_file, patterns: ['.github/CODEOWNERS', 'CODEOWNERS', 'docs/CODEOWNERS'] }
251
+ why: 'With more than two contributors, unreviewed-by-default becomes the default.'
252
+ remediation: 'Add .github/CODEOWNERS mapping paths to teams; require review from code owners on the default branch.'
253
+ references: ['OpenSSF-Scorecard:Code-Review']
254
+
255
+ - id: REPO-015
256
+ title: Commit history is meaningful
257
+ section: S1
258
+ section_title: Repository & Project Structure
259
+ severity: LOW
260
+ class: maintainability
261
+ check: { kind: manual }
262
+ why: >-
263
+ Commit messages are the only history most projects ever write down. "fix stuff" costs the next person an afternoon.
264
+ evidence: 'Last 20 commit messages. Are they descriptive and consistently formatted?'
265
+ remediation: 'Adopt Conventional Commits; enforce with commitlint in CI.'
266
+
267
+ - id: REPO-016
268
+ title: Branch strategy is defined and stale branches pruned
269
+ section: S1
270
+ section_title: Repository & Project Structure
271
+ severity: LOW
272
+ class: maintainability
273
+ applies_when: { fact: 'metric:branches', op: 'gt', value: 3 }
274
+ check: { kind: manual }
275
+ why: >-
276
+ A branching strategy nobody wrote down is a branching strategy nobody follows, and stale branches hide work.
277
+ evidence: 'Branch list and age of the oldest non-default branch.'
278
+ remediation: 'Document trunk-based or Git Flow in CONTRIBUTING; delete merged branches; protect the default branch.'
279
+
280
+ - id: REPO-017
281
+ title: Concern separation at the root
282
+ section: S1
283
+ section_title: Repository & Project Structure
284
+ severity: MEDIUM
285
+ class: maintainability
286
+ check:
287
+ kind: any_file
288
+ patterns: ['src/**', 'app/**', 'lib/**', 'pkg/**', 'internal/**', 'packages/**']
289
+ why: 'A flat root of 40 files makes ownership and navigation guesswork.'
290
+ remediation: 'Group by concern (src/, tests/, docs/, scripts/, config/). Monorepos: packages/ or apps/.'
291
+
292
+ - id: REPO-018
293
+ title: Agent instruction file present (AGENTS.md / CLAUDE.md)
294
+ section: S1
295
+ section_title: Repository & Project Structure
296
+ severity: LOW
297
+ class: documentation
298
+ check:
299
+ kind: any_file
300
+ patterns:
301
+ [
302
+ 'AGENTS.md',
303
+ 'CLAUDE.md',
304
+ '.cursorrules',
305
+ '.github/copilot-instructions.md',
306
+ 'codex.md',
307
+ '.windsurfrules',
308
+ ]
309
+ why: >
310
+ Coding agents perform measurably better when the repo tells them how to
311
+ build, test, and what not to touch. It also stops them inventing commands.
312
+ remediation: 'Add AGENTS.md: setup, build/test/lint commands, conventions, and explicit no-go areas.'
313
+ references: ['Agent-Skills']