@xenos1996/usat 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +335 -0
  3. package/USAT.md +596 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +438 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/config.d.ts +7 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +72 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/detect/index.d.ts +58 -0
  13. package/dist/detect/index.d.ts.map +1 -0
  14. package/dist/detect/index.js +329 -0
  15. package/dist/detect/index.js.map +1 -0
  16. package/dist/engine/audit.d.ts +21 -0
  17. package/dist/engine/audit.d.ts.map +1 -0
  18. package/dist/engine/audit.js +295 -0
  19. package/dist/engine/audit.js.map +1 -0
  20. package/dist/engine/diff.d.ts +24 -0
  21. package/dist/engine/diff.d.ts.map +1 -0
  22. package/dist/engine/diff.js +136 -0
  23. package/dist/engine/diff.js.map +1 -0
  24. package/dist/engine/evaluate.d.ts +19 -0
  25. package/dist/engine/evaluate.d.ts.map +1 -0
  26. package/dist/engine/evaluate.js +377 -0
  27. package/dist/engine/evaluate.js.map +1 -0
  28. package/dist/engine/gate.d.ts +19 -0
  29. package/dist/engine/gate.d.ts.map +1 -0
  30. package/dist/engine/gate.js +47 -0
  31. package/dist/engine/gate.js.map +1 -0
  32. package/dist/engine/loader.d.ts +22 -0
  33. package/dist/engine/loader.d.ts.map +1 -0
  34. package/dist/engine/loader.js +360 -0
  35. package/dist/engine/loader.js.map +1 -0
  36. package/dist/engine/maturity.d.ts +20 -0
  37. package/dist/engine/maturity.d.ts.map +1 -0
  38. package/dist/engine/maturity.js +157 -0
  39. package/dist/engine/maturity.js.map +1 -0
  40. package/dist/engine/score.d.ts +19 -0
  41. package/dist/engine/score.d.ts.map +1 -0
  42. package/dist/engine/score.js +141 -0
  43. package/dist/engine/score.js.map +1 -0
  44. package/dist/engine/sections.d.ts +14 -0
  45. package/dist/engine/sections.d.ts.map +1 -0
  46. package/dist/engine/sections.js +50 -0
  47. package/dist/engine/sections.js.map +1 -0
  48. package/dist/index.d.ts +23 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +17 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/report/markdown.d.ts +16 -0
  53. package/dist/report/markdown.d.ts.map +1 -0
  54. package/dist/report/markdown.js +488 -0
  55. package/dist/report/markdown.js.map +1 -0
  56. package/dist/types.d.ts +282 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +16 -0
  59. package/dist/types.js.map +1 -0
  60. package/dist/util/glob.d.ts +11 -0
  61. package/dist/util/glob.d.ts.map +1 -0
  62. package/dist/util/glob.js +86 -0
  63. package/dist/util/glob.js.map +1 -0
  64. package/dist/util/project.d.ts +72 -0
  65. package/dist/util/project.d.ts.map +1 -0
  66. package/dist/util/project.js +586 -0
  67. package/dist/util/project.js.map +1 -0
  68. package/dist/util/yaml.d.ts +28 -0
  69. package/dist/util/yaml.d.ts.map +1 -0
  70. package/dist/util/yaml.js +48 -0
  71. package/dist/util/yaml.js.map +1 -0
  72. package/docs/ARCHITECTURE.md +119 -0
  73. package/docs/README.md +27 -0
  74. package/docs/adr/0001-record-architecture-decisions.md +35 -0
  75. package/docs/adr/0002-typescript-engine-over-python.md +49 -0
  76. package/docs/adr/0003-rules-are-data-not-code.md +50 -0
  77. package/docs/adr/0004-markdown-only-output.md +41 -0
  78. package/docs/adr/0005-maturity-dampens-severity.md +56 -0
  79. package/docs/adr/0006-severity-status-two-axes.md +48 -0
  80. package/docs/adr/0007-suppressions-are-visible-and-expiring.md +46 -0
  81. package/docs/adr/0008-report-trailer-and-diff.md +48 -0
  82. package/docs/adr/0009-fail-closed-on-malformed-input.md +56 -0
  83. package/docs/adr/0010-detector-design.md +54 -0
  84. package/docs/adr/0011-coexist-with-deep-scanners.md +52 -0
  85. package/docs/adr/README.md +32 -0
  86. package/docs/agent-integration.md +129 -0
  87. package/docs/ci-integration.md +163 -0
  88. package/docs/concepts.md +196 -0
  89. package/docs/configuration.md +105 -0
  90. package/docs/detectors.md +186 -0
  91. package/docs/getting-started.md +99 -0
  92. package/docs/maturity-profiles.md +156 -0
  93. package/docs/reference/api.md +193 -0
  94. package/docs/reference/cli.md +412 -0
  95. package/docs/rule-packs.md +278 -0
  96. package/docs/standards-mapping.md +171 -0
  97. package/package.json +96 -0
  98. package/rules/core/architecture.yaml +190 -0
  99. package/rules/core/cicd.yaml +212 -0
  100. package/rules/core/code-quality.yaml +261 -0
  101. package/rules/core/dependencies.yaml +132 -0
  102. package/rules/core/documentation.yaml +119 -0
  103. package/rules/core/future-readiness.yaml +91 -0
  104. package/rules/core/release.yaml +131 -0
  105. package/rules/core/repo.yaml +303 -0
  106. package/rules/core/security.yaml +494 -0
  107. package/rules/core/supply-chain.yaml +357 -0
  108. package/rules/core/testing.yaml +260 -0
  109. package/rules/detectors.yaml +2255 -0
  110. package/rules/index.yaml +41 -0
  111. package/rules/profiles/maturity.yaml +135 -0
  112. package/rules/stacks/ai-era.yaml +193 -0
  113. package/rules/stacks/api-backend.yaml +121 -0
  114. package/rules/stacks/cli.yaml +105 -0
  115. package/rules/stacks/compliance.yaml +157 -0
  116. package/rules/stacks/containers.yaml +124 -0
  117. package/rules/stacks/data.yaml +165 -0
  118. package/rules/stacks/go.yaml +134 -0
  119. package/rules/stacks/iac.yaml +128 -0
  120. package/rules/stacks/jvm.yaml +150 -0
  121. package/rules/stacks/ml-ai.yaml +140 -0
  122. package/rules/stacks/mobile.yaml +121 -0
  123. package/rules/stacks/node-typescript.yaml +166 -0
  124. package/rules/stacks/python.yaml +175 -0
  125. package/rules/stacks/rust.yaml +129 -0
  126. package/rules/stacks/solidity.yaml +139 -0
  127. package/rules/stacks/web-frontend.yaml +159 -0
  128. package/templates/AGENTS.audit.md +135 -0
  129. package/templates/AUDIT_REPORT.md +155 -0
@@ -0,0 +1,159 @@
1
+ id: stacks/web-frontend
2
+ title: Web Frontend
3
+ section: S15
4
+ section_title: Platform-Specific
5
+ description: 'Activated for browser-facing applications. Covers Core Web Vitals, a11y, and bundle discipline.'
6
+ version: '1.0'
7
+ skip_when:
8
+ all:
9
+ - { fact: 'platform:web', op: 'absent' }
10
+ - { fact: 'fw:react', op: 'absent' }
11
+ - { fact: 'fw:vue', op: 'absent' }
12
+ - { fact: 'fw:svelte', op: 'absent' }
13
+ - { fact: 'fw:angular', op: 'absent' }
14
+ - { fact: 'fw:next', op: 'absent' }
15
+ - { fact: 'fw:nuxt', op: 'absent' }
16
+ - { fact: 'fw:sveltekit', op: 'absent' }
17
+ - { fact: 'fw:astro', op: 'absent' }
18
+
19
+ rules:
20
+ - id: WEB-001
21
+ title: Core Web Vitals are measured
22
+ section: S15
23
+ section_title: Platform-Specific
24
+ severity: MEDIUM
25
+ class: performance
26
+ check:
27
+ kind: grep_present
28
+ pattern: '(web-vitals|LCP|CLS|INP|lighthouse|next/web-vitals|useReportWebVitals|reportWebVitals)'
29
+ include:
30
+ ['**/*.{ts,tsx,js,jsx,html}', 'package.json', '.github/workflows/*.yml', 'lighthouse*']
31
+ exclude: ['**/node_modules/**']
32
+ flags: i
33
+ why: 'You cannot improve what you do not measure, and LCP/INP/CLS are what search and users actually judge.'
34
+ remediation: 'Report web-vitals to your analytics; add Lighthouse CI to catch regressions per PR.'
35
+ references: ['Web-Vitals']
36
+
37
+ - id: WEB-002
38
+ title: Code splitting / lazy loading is used
39
+ section: S15
40
+ section_title: Platform-Specific
41
+ severity: MEDIUM
42
+ class: performance
43
+ check:
44
+ kind: grep_present
45
+ pattern: '(React\.lazy|import\(\s*[''"]|dynamic\s*\(\s*\(\s*\)|defineAsyncComponent|loadable|next/dynamic|Suspense)'
46
+ include: ['**/*.{ts,tsx,js,jsx,vue,svelte}']
47
+ exclude: ['**/node_modules/**', '**/*.test.*']
48
+ why: 'A single 2 MB bundle means every user pays for the heaviest route on first load.'
49
+ remediation: 'Route-level code splitting first, then lazy-load anything behind a tab, modal, or fold.'
50
+ references: ['Web-Vitals:LCP']
51
+
52
+ - id: WEB-003
53
+ title: Images are optimised
54
+ section: S15
55
+ section_title: Platform-Specific
56
+ severity: MEDIUM
57
+ class: performance
58
+ check:
59
+ kind: grep_present
60
+ pattern: '(loading\s*=\s*[''"]lazy|next/image|next/font|<Image|webp|avif|decoding\s*=\s*[''"]async)'
61
+ include: ['**/*.{ts,tsx,js,jsx,vue,svelte,html,astro}']
62
+ exclude: ['**/node_modules/**']
63
+ flags: i
64
+ why: 'Images are usually 60%+ of page weight. AVIF/WebP plus lazy loading is the single biggest win available.'
65
+ remediation: 'Serve WebP/AVIF at the rendered size; lazy-load below the fold; set width/height to avoid CLS.'
66
+ references: ['Web-Vitals:LCP', 'Web-Vitals:CLS']
67
+
68
+ - id: WEB-004
69
+ title: Accessibility basics are in place
70
+ section: S15
71
+ section_title: Platform-Specific
72
+ severity: MEDIUM
73
+ class: compliance
74
+ check: { kind: manual }
75
+ evidence: 'Lighthouse/axe accessibility score, or evidence of: semantic landmarks, labelled form inputs, visible focus, and alt text on meaningful images.'
76
+ why: 'Roughly 1 in 4 adults has a disability. Accessibility bugs are also, almost always, plain bugs.'
77
+ remediation: 'Add eslint-plugin-jsx-a11y; run axe in CI; test keyboard-only navigation end to end.'
78
+ references: ['WCAG-2.2-AA', 'EN-301-549', 'ADA']
79
+
80
+ - id: WEB-005
81
+ title: Bundle size is monitored
82
+ section: S15
83
+ section_title: Platform-Specific
84
+ severity: LOW
85
+ class: performance
86
+ check:
87
+ kind: grep_present
88
+ pattern: '(size-limit|bundlesize|rollup-plugin-visualizer|webpack-bundle-analyzer|bundlephobia|build\.analyze|"size-limit")'
89
+ include:
90
+ [
91
+ 'package.json',
92
+ '.github/workflows/*.yml',
93
+ 'vite.config.*',
94
+ 'next.config.*',
95
+ 'webpack.config.*',
96
+ ]
97
+ exclude: ['**/node_modules/**']
98
+ flags: i
99
+ why: 'Bundle size grows by 5% a sprint and nobody notices until it is 3 MB.'
100
+ remediation: 'Add size-limit with a per-entry budget; fail CI when the budget is exceeded.'
101
+ references: ['Web-Vitals']
102
+
103
+ - id: WEB-006
104
+ title: Error boundaries exist around risky UI
105
+ section: S15
106
+ section_title: Platform-Specific
107
+ severity: MEDIUM
108
+ class: correctness
109
+ applies_when:
110
+ any:
111
+ - { fact: 'fw:react' }
112
+ - { fact: 'fw:next' }
113
+ check:
114
+ kind: grep_present
115
+ pattern: '(ErrorBoundary|componentDidCatch|error\.tsx|error-boundary|useErrorBoundary)'
116
+ include: ['**/*.{ts,tsx,js,jsx}']
117
+ exclude: ['**/node_modules/**', '**/*.test.*']
118
+ why: 'One throw inside a render and the user gets a blank white page.'
119
+ remediation: 'Wrap route segments in an ErrorBoundary with a retry and a report-to-Sentry path.'
120
+ references: ['React-Error-Boundaries']
121
+
122
+ - id: WEB-007
123
+ title: No secrets in client-side bundles
124
+ section: S15
125
+ section_title: Platform-Specific
126
+ severity: CRITICAL
127
+ class: security
128
+ check:
129
+ kind: grep_wrong
130
+ pattern: '(NEXT_PUBLIC_.*(SECRET|KEY|TOKEN|PASSWORD)|VITE_.*(SECRET|PRIVATE|PASSWORD)|process\.env\.[A-Z_]*(SECRET|PRIVATE_KEY|PASSWORD)[A-Z_]*)'
131
+ include: ['**/*.{ts,tsx,js,jsx,vue,svelte}']
132
+ exclude: ['**/node_modules/**', '**/*.test.*', '**/server/**', '**/api/**']
133
+ why: 'Anything bundled for the browser is public. NEXT_PUBLIC_/VITE_ variables are shipped verbatim.'
134
+ remediation: 'Move the call server-side (API route, server action, BFF) and keep the secret out of the bundle.'
135
+ references: ['CWE-798', 'ASVS-14.3.2']
136
+
137
+ - id: WEB-008
138
+ title: Forms validate and expose errors accessibly
139
+ section: S15
140
+ section_title: Platform-Specific
141
+ severity: MEDIUM
142
+ class: compliance
143
+ check: { kind: manual }
144
+ evidence: 'A form with: a validation schema, error text linked via aria-describedby, and focus moved to the first error.'
145
+ why: 'An error message only sighted users can see (or only sighted users can find) is not an error message.'
146
+ remediation: 'Use a schema validator, render errors next to the field, and set aria-invalid / aria-describedby.'
147
+ references: ['WCAG-3.3.1', 'WCAG-3.3.3']
148
+
149
+ - id: WEB-009
150
+ title: An offline/PWA story exists
151
+ section: S15
152
+ section_title: Platform-Specific
153
+ severity: FUTURE
154
+ class: performance
155
+ check: { kind: manual }
156
+ evidence: 'Service worker, offline fallback page, or an explicit decision that offline support is not required.'
157
+ why: 'Mobile networks fail. Deciding not to support offline is fine; discovering it during an outage is not.'
158
+ remediation: 'At minimum, add a custom offline page. Full PWA only if the use case justifies it.'
159
+ references: ['Web-Vitals']
@@ -0,0 +1,135 @@
1
+ # AGENTS.md — auditing this repository with USAT
2
+
3
+ > Paste this into any repository you want an agent to audit with USAT.
4
+ > Generated by `usat init`, or copy from
5
+ > [`templates/AGENTS.audit.md`](https://github.com/Er-Sajan-PLG/software-auditing-template/blob/master/templates/AGENTS.audit.md).
6
+
7
+ ---
8
+
9
+ ## What this repository is
10
+
11
+ <!-- Fill this in. One paragraph. An agent that knows what the project is
12
+ audits it far better than one that has to guess. -->
13
+
14
+ TODO: describe the project in two sentences.
15
+
16
+ ## Commands
17
+
18
+ ```bash
19
+ # TODO: replace with this project's real commands
20
+ npm install
21
+ npm run lint
22
+ npm test
23
+ npm run build
24
+ ```
25
+
26
+ ## Layout
27
+
28
+ <!-- Where things live. Delete what does not apply. -->
29
+
30
+ ```
31
+ src/ application code
32
+ tests/ test suite
33
+ docs/ documentation
34
+ scripts/ one-off utilities
35
+ ```
36
+
37
+ ## Conventions
38
+
39
+ - TODO: naming, module boundaries, error-handling style, what belongs where.
40
+
41
+ ## Do not
42
+
43
+ <!-- Explicit denylists beat implicit trust. Agents follow these literally. -->
44
+
45
+ - Do not force-push or rewrite published history.
46
+ - Do not read, print, or commit `.env*` files, credentials, or tokens.
47
+ - Do not run destructive commands (`rm -rf`, `git clean -fdx`, `DROP TABLE`) without
48
+ explicit approval.
49
+ - Do not disable tests, linters, or type checks to make something pass.
50
+ - Do not commit secrets, even in tests or fixtures.
51
+
52
+ ---
53
+
54
+ # Auditing with USAT
55
+
56
+ USAT is a two-part framework. **The tool settles what is mechanically checkable; you
57
+ settle the rest.** Do not re-do the tool's work.
58
+
59
+ ## Step 1 — Detect
60
+
61
+ ```bash
62
+ usat detect .
63
+ ```
64
+
65
+ Confirm the facts against what you see. If detection is wrong, say so; the operator
66
+ can assert facts with `--fact has:database` or in `.usat.yaml`.
67
+
68
+ ## Step 2 — Deterministic pass
69
+
70
+ ```bash
71
+ usat audit . --out AUDIT.md --depth standard
72
+ ```
73
+
74
+ This produces findings with locations and a score. **Treat these as settled.** Do not
75
+ re-grep for a rule the tool already resolved to ✅ or 🚫.
76
+
77
+ ## Step 3 — Work the Judgement Queue
78
+
79
+ The report's _Judgement Queue_ lists every check that cannot be settled by reading a
80
+ file. Each row states what to look for and what evidence to record.
81
+
82
+ For each item:
83
+
84
+ 1. Find the relevant code.
85
+ 2. Decide: `PASS` · `WRONG` · `MISSING` · `UNKNOWN`.
86
+ 3. Record `file:line` **and** one sentence of reasoning.
87
+ 4. If you cannot determine it, answer `UNKNOWN` and say what you would need.
88
+
89
+ ## Step 4 — Report
90
+
91
+ Follow the Section 14 template in `USAT.md`:
92
+
93
+ 1. CRITICAL and security-HIGH findings first — with location and fix
94
+ 2. Section-by-section findings
95
+ 3. Judgement queue with your recorded evidence
96
+ 4. Roadmap: sprint 0 / sprint 1 / sprint 2 / backlog
97
+
98
+ ## The ten rules
99
+
100
+ | # | Rule |
101
+ | --- | ------------------------------------------------------------------- |
102
+ | 1 | Skip non-applicable sections silently. Do not write "N/A" 40 times. |
103
+ | 2 | Partially applicable ⇒ audit the applicable parts only. |
104
+ | 3 | CRITICAL findings always go first, above every summary. |
105
+ | 4 | **Never mark ✅ without evidence.** `file:line` or command output. |
106
+ | 5 | Every finding: location + severity + why + fix. |
107
+ | 6 | Score sections 0–10 from the share of applicable checks that pass. |
108
+ | 7 | Never assume. A file you did not find is 🚫 MISSING. |
109
+ | 8 | Audit what is absent as well as what is present. |
110
+ | 9 | ⚠️ WRONG is worse than 🚫 MISSING. Surface it. |
111
+ | 10 | Priority: Security > Correctness > Maintainability > Style. |
112
+
113
+ ## Status vocabulary
114
+
115
+ | | Status | Meaning |
116
+ | --- | ------------ | ---------------------------------------- |
117
+ | ✅ | GOOD | Verified present and correct |
118
+ | 🧪 | EXPERIMENTAL | Present, unvalidated |
119
+ | 💀 | DEPRECATED | Present, EOL |
120
+ | ⚠️ | WRONG | Present but implemented incorrectly |
121
+ | 🚫 | MISSING | Required and absent |
122
+ | ❓ | NEEDS REVIEW | Cannot be determined from the code alone |
123
+
124
+ Severity: 🔴 CRITICAL · 🟠 HIGH · 🟡 MEDIUM · 🟢 LOW · 🔵 FUTURE
125
+
126
+ ## Two things agents get wrong
127
+
128
+ **Guessing instead of saying UNKNOWN.** An audit that invents a passing result is worse
129
+ than one that admits uncertainty. `UNKNOWN` lowers the report's _confidence_, which is
130
+ the honest signal. Guessing corrupts the _score_, which is not.
131
+
132
+ **Re-escalating dampened findings.** If a finding says
133
+ _"Downgraded HIGH → MEDIUM by the MVP profile"_, that is the framework doing its job —
134
+ the project is an MVP and the calendar is a real constraint. Leave it alone. The one
135
+ exception is 🔴 CRITICAL, which is **never** dampened at any stage.
@@ -0,0 +1,155 @@
1
+ # Audit report template
2
+
3
+ > USAT's CLI emits this structure automatically (`usat audit .`).
4
+ > Use this file when you are writing a report by hand — or when an agent is
5
+ > producing one without the tool. Matching the structure is what makes reports
6
+ > diffable and comparable across time and teams.
7
+
8
+ ---
9
+
10
+ ```
11
+ ══════════════════════════════════════════════════════════
12
+ UNIVERSAL SOFTWARE AUDIT REPORT
13
+ ══════════════════════════════════════════════════════════
14
+ Project : [name]
15
+ Repository : [url]
16
+ Commit : [sha] ([ref])
17
+ Audited by : USAT [version] + [agent / human]
18
+ Date : [ISO-8601]
19
+ Detected type: [auto-detected]
20
+ Platform : [auto-detected]
21
+ Stack : [auto-detected]
22
+ Maturity : [Prototype / MVP / Beta / Production / Legacy]
23
+ Depth : [quick | standard | deep]
24
+
25
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
26
+ EXECUTIVE SUMMARY
27
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
28
+ Overall Health Score : [X/100]
29
+ Expected band for [maturity]: [lo]–[hi] → [verdict]
30
+
31
+ Dimension Score Confidence
32
+ S1 Repository & Structure X/10 N%
33
+ S2 Security X/10 N%
34
+ S3 Supply Chain & Provenance X/10 N%
35
+ S4 Architecture & Design X/10 N%
36
+ S5 Code Quality X/10 N%
37
+ S6 Data & Database X/10 N%
38
+ S7 Testing & Quality Assurance X/10 N%
39
+ S8 CI/CD, Infrastructure & Obs. X/10 N%
40
+ S9 Release & Change Management X/10 N%
41
+ S10 Dependencies & Third-Party X/10 N%
42
+ S11 Performance & Resilience X/10 N%
43
+ S12 Documentation & Knowledge X/10 N%
44
+ S13 Accessibility, i18n & Compliance X/10 N%
45
+ S14 AI / LLM-Era Risks X/10 N%
46
+ S15 Platform-Specific X/10 N%
47
+ S16 Future Readiness X/10 N%
48
+
49
+ Automation coverage: N% (the rest is in the judgement queue)
50
+
51
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
52
+ FINDINGS SUMMARY
53
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
54
+ ✅ GOOD : N 🔴 CRITICAL : N
55
+ ⚠️ WRONG : N 🟠 HIGH : N
56
+ 🚫 MISSING : N 🟡 MEDIUM : N
57
+ 💀 DEPRECATED : N 🟢 LOW : N
58
+ 🧪 EXPERIMENTAL: N 🔵 FUTURE : N
59
+ ❓ TO REVIEW : N
60
+
61
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
62
+ IMMEDIATE ACTION REQUIRED
63
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
64
+ 1. 🔴 [Finding] → [file:line] → [why] → [fix]
65
+ 2. 🟠 [Finding] → [file:line] → [why] → [fix]
66
+ (No CRITICAL/HIGH? Say so, plainly.)
67
+
68
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
69
+ SECTION-BY-SECTION FINDINGS
70
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
71
+ [S1] Repository & Structure → X/10
72
+ 🔴 [finding] → [location] → [fix]
73
+ 🚫 [finding] → [location] → [fix]
74
+ ✅ [N checks passing]
75
+
76
+ [S2] Security → X/10
77
+ ...
78
+
79
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
80
+ JUDGEMENT QUEUE
81
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
82
+ | Rule | Section | Severity | What to look for | Evidence to record |
83
+ |------|---------|----------|------------------|--------------------|
84
+ | SEC-015 | S2 | 🟠 HIGH | Authorization per resource | file:line of the ownership check |
85
+
86
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
87
+ ACCEPTED RISK
88
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
89
+ | Rule | Severity | Reason | Until |
90
+ |------|----------|--------|-------|
91
+ | PERF-005 | 🟡 MEDIUM | Known N+1 in the admin panel; 40 rows max. | 2026-12-31 |
92
+
93
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
94
+ RECOMMENDED ROADMAP
95
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
96
+ SPRINT 0 (now) : CRITICAL + security HIGH
97
+ SPRINT 1 (1–2 weeks) : remaining HIGH
98
+ SPRINT 2 (1 month) : MEDIUM
99
+ BACKLOG : LOW + FUTURE
100
+ DEFERRED (this stage): what the maturity profile says to ignore
101
+
102
+ WHAT MATTERS AT [STAGE]:
103
+ - [focus item from the maturity profile]
104
+ - [focus item]
105
+
106
+ ══════════════════════════════════════════════════════════
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Rules for filling this in
112
+
113
+ 1. **Every finding carries location + severity + why + fix.** A finding without a
114
+ location is an opinion.
115
+ 2. **CRITICAL first, always.** Above the summary, above the score.
116
+ 3. **No ✅ without evidence.** `file:line`, a command output, or a doc link.
117
+ 4. **Skip non-applicable sections without comment.** Do not write "N/A: not a web app".
118
+ 5. **Surface ⚠️ WRONG above 🚫 MISSING** within a severity band. Wrong is worse than
119
+ absent because it looks finished.
120
+ 6. **Record UNKNOWNs in the judgement queue**, not as silent passes. They are what
121
+ confidence measures.
122
+ 7. **The roadmap is the deliverable.** A score nobody acts on is a number; a sprint
123
+ list is a plan.
124
+
125
+ ## Rendering notes
126
+
127
+ - Use the emoji tags consistently — they are what makes a long report skimmable.
128
+ - Keep the section order fixed (S1 → S16) so two reports can be compared line by line.
129
+ - If you are an agent writing this by hand, end the file with the machine-readable
130
+ trailer so `usat diff` works on it:
131
+
132
+ ````markdown
133
+ <!-- USAT:TRAILER:BEGIN -->
134
+
135
+ ```yaml
136
+ schema: usat-report-v1
137
+ generated_at: 2026-09-08T00:00:00.000Z
138
+ usat_version: 1.0.0
139
+ overall: 71.4
140
+ sections:
141
+ S1: { score: 8.4, open: 2, review: 2 }
142
+ S2: { score: 6.2, open: 3, review: 1 }
143
+ severity_totals:
144
+ CRITICAL: 0
145
+ HIGH: 3
146
+ MEDIUM: 4
147
+ LOW: 6
148
+ FUTURE: 2
149
+ rules:
150
+ SEC-001: { status: PASS, severity: CRITICAL, section: S2 }
151
+ SEC-015: { status: UNKNOWN, severity: HIGH, section: S2 }
152
+ ```
153
+
154
+ <!-- USAT:TRAILER:END -->
155
+ ````