@xenos1996/usa 2.0.1 → 2.3.2

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 (81) hide show
  1. package/README.md +44 -33
  2. package/USA.md +9 -9
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +194 -7
  5. package/dist/cli.js.map +1 -1
  6. package/dist/config.d.ts +1 -1
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +31 -0
  9. package/dist/config.js.map +1 -1
  10. package/dist/engine/audit.d.ts.map +1 -1
  11. package/dist/engine/audit.js +42 -4
  12. package/dist/engine/audit.js.map +1 -1
  13. package/dist/engine/automatability.d.ts +32 -0
  14. package/dist/engine/automatability.d.ts.map +1 -0
  15. package/dist/engine/automatability.js +81 -0
  16. package/dist/engine/automatability.js.map +1 -0
  17. package/dist/engine/catalogues.d.ts +43 -0
  18. package/dist/engine/catalogues.d.ts.map +1 -0
  19. package/dist/engine/catalogues.js +109 -0
  20. package/dist/engine/catalogues.js.map +1 -0
  21. package/dist/engine/diff.d.ts +14 -0
  22. package/dist/engine/diff.d.ts.map +1 -1
  23. package/dist/engine/diff.js +59 -36
  24. package/dist/engine/diff.js.map +1 -1
  25. package/dist/engine/evaluate.d.ts +2 -1
  26. package/dist/engine/evaluate.d.ts.map +1 -1
  27. package/dist/engine/evaluate.js +125 -3
  28. package/dist/engine/evaluate.js.map +1 -1
  29. package/dist/engine/gate.d.ts +33 -0
  30. package/dist/engine/gate.d.ts.map +1 -1
  31. package/dist/engine/gate.js +116 -0
  32. package/dist/engine/gate.js.map +1 -1
  33. package/dist/engine/loader.d.ts.map +1 -1
  34. package/dist/engine/loader.js +92 -4
  35. package/dist/engine/loader.js.map +1 -1
  36. package/dist/engine/review.d.ts +49 -0
  37. package/dist/engine/review.d.ts.map +1 -0
  38. package/dist/engine/review.js +128 -0
  39. package/dist/engine/review.js.map +1 -0
  40. package/dist/engine/suppression.d.ts +52 -0
  41. package/dist/engine/suppression.d.ts.map +1 -0
  42. package/dist/engine/suppression.js +91 -0
  43. package/dist/engine/suppression.js.map +1 -0
  44. package/dist/index.d.ts +6 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +6 -0
  47. package/dist/index.js.map +1 -1
  48. package/dist/report/json.d.ts +48 -0
  49. package/dist/report/json.d.ts.map +1 -0
  50. package/dist/report/json.js +60 -0
  51. package/dist/report/json.js.map +1 -0
  52. package/dist/report/markdown.d.ts.map +1 -1
  53. package/dist/report/markdown.js +110 -17
  54. package/dist/report/markdown.js.map +1 -1
  55. package/dist/report/sarif.d.ts +84 -0
  56. package/dist/report/sarif.d.ts.map +1 -0
  57. package/dist/report/sarif.js +129 -0
  58. package/dist/report/sarif.js.map +1 -0
  59. package/dist/report/signature.d.ts +76 -0
  60. package/dist/report/signature.d.ts.map +1 -0
  61. package/dist/report/signature.js +206 -0
  62. package/dist/report/signature.js.map +1 -0
  63. package/dist/types.d.ts +115 -0
  64. package/dist/types.d.ts.map +1 -1
  65. package/dist/types.js +2 -1
  66. package/dist/types.js.map +1 -1
  67. package/dist/util/project.d.ts.map +1 -1
  68. package/dist/util/project.js +23 -1
  69. package/dist/util/project.js.map +1 -1
  70. package/dist/util/site.d.ts +13 -0
  71. package/dist/util/site.d.ts.map +1 -0
  72. package/dist/util/site.js +24 -0
  73. package/dist/util/site.js.map +1 -0
  74. package/package.json +9 -1
  75. package/rules/catalogues.yaml +109 -0
  76. package/rules/core/provenance-attestation.yaml +65 -0
  77. package/rules/core/provenance-cosign.yaml +110 -0
  78. package/rules/index.yaml +2 -0
  79. package/rules/profiles/maturity.yaml +1 -1
  80. package/templates/AGENTS.audit.md +135 -0
  81. package/templates/AUDIT_REPORT.md +155 -0
@@ -0,0 +1,110 @@
1
+ id: core/provenance-cosign
2
+ title: Provenance Chain Verification (cosign)
3
+ section: S3
4
+ section_title: Supply Chain & Build Provenance
5
+ description: >
6
+ Production-half chain verification for release provenance: these controls
7
+ cryptographically verify release artifacts against committed Sigstore
8
+ bundles and keys with a local `cosign` binary. They complement the
9
+ beta-level existence checks (SUP-013 commit signing, SUP-014 SBOM,
10
+ SUP-015 attestation): beta proves the material exists, production proves
11
+ the chain verifies. Aligned with SLSA v1.2.
12
+ Verify, never mint (ADR-0011): USA checks signatures, it never signs.
13
+ Command checks are UNKNOWN without --allow-commands — that is the honest
14
+ assist posture — and every command fails closed on a missing binary, key,
15
+ or bundle (FAIL or UNKNOWN with a loud message, never PASS).
16
+ version: '1.0'
17
+
18
+ rules:
19
+ - id: SUP-018
20
+ title: Release blob signatures verify with cosign (chain verification)
21
+ section: S3
22
+ section_title: Supply Chain & Build Provenance
23
+ severity: HIGH
24
+ class: supply-chain
25
+ applies_when: { fact: 'maturity:production' }
26
+ check:
27
+ kind: command
28
+ run: >-
29
+ command -v cosign >/dev/null 2>&1 || { echo "FAIL-CLOSED SUP-018: cosign binary not found in PATH, so release blob signatures cannot be verified. Install sigstore/cosign and re-run with --allow-commands."; exit 1; };
30
+ key="";
31
+ for k in cosign.pub .cosign/cosign.pub keys/cosign.pub; do if [ -f "$k" ]; then key="$k"; break; fi; done;
32
+ [ -n "$key" ] || { echo "FAIL-CLOSED SUP-018: no cosign public key committed (looked for cosign.pub, .cosign/cosign.pub, keys/cosign.pub), so there is nothing trustworthy to verify against."; exit 1; };
33
+ bundles=$(find . \( -path "*/node_modules*" -o -path "./.git*" \) -prune -o \( -name "*.sigstore.json" -o -name "*.bundle" \) -print 2>/dev/null);
34
+ [ -n "$bundles" ] || { echo "FAIL-CLOSED SUP-018: no Sigstore bundles (*.sigstore.json, *.bundle) committed, so no release signature chain exists to verify."; exit 1; };
35
+ echo "$bundles" | while IFS= read -r bundle; do
36
+ [ -n "$bundle" ] || continue;
37
+ case "$bundle" in
38
+ *.sigstore.json) blob="${bundle%.sigstore.json}";;
39
+ *.bundle) blob="${bundle%.bundle}";;
40
+ *) blob="$bundle";;
41
+ esac;
42
+ [ -f "$blob" ] || { echo "FAIL SUP-018: bundle $bundle has no matching artifact blob (expected $blob). The signature chain is incomplete."; exit 1; };
43
+ cosign verify-blob --key "$key" --bundle "$bundle" "$blob" >/dev/null 2>&1 || { echo "FAIL SUP-018: cosign verify-blob failed for artifact $blob (bundle $bundle, key $key)."; exit 1; };
44
+ done || exit 1;
45
+ echo "SUP-018: cosign verify-blob succeeded for every committed bundle against $key.";
46
+ expect_exit: 0
47
+ evidence: 'cosign verify-blob success output for every committed bundle, or the fail-closed reason above.'
48
+ why: 'A signature nobody verifies is decoration. At production, every release blob must verify against a committed key and bundle — otherwise anyone with publish access ships anything.'
49
+ remediation: 'Commit cosign.pub and a Sigstore bundle per release blob, then run with --allow-commands so `cosign verify-blob --key <key> --bundle <bundle> <blob>` succeeds for each pair.'
50
+ references: ['SLSA-v1.2', 'SLSA-Build-L2', 'OpenSSF-Scorecard:Signed-Releases']
51
+
52
+ - id: SUP-019
53
+ title: SLSA attestation bundles verify with cosign (chain verification)
54
+ section: S3
55
+ section_title: Supply Chain & Build Provenance
56
+ severity: MEDIUM
57
+ class: supply-chain
58
+ applies_when: { fact: 'maturity:production' }
59
+ check:
60
+ kind: command
61
+ run: >-
62
+ command -v cosign >/dev/null 2>&1 || { echo "FAIL-CLOSED SUP-019: cosign binary not found in PATH, so SLSA attestation bundles cannot be verified. Install sigstore/cosign and re-run with --allow-commands."; exit 1; };
63
+ key="";
64
+ for k in cosign.pub .cosign/cosign.pub keys/cosign.pub; do if [ -f "$k" ]; then key="$k"; break; fi; done;
65
+ [ -n "$key" ] || { echo "FAIL-CLOSED SUP-019: no cosign public key committed (looked for cosign.pub, .cosign/cosign.pub, keys/cosign.pub), so there is nothing trustworthy to verify against."; exit 1; };
66
+ atts=$(find . \( -path "*/node_modules*" -o -path "./.git*" \) -prune -o \( -name "*.intoto.jsonl" -o -name "*.intoto.json" -o -name "*provenance*.json" \) ! -name "*.sigstore.json" ! -name "*.bundle" -print 2>/dev/null);
67
+ [ -n "$atts" ] || { echo "FAIL-CLOSED SUP-019: no SLSA provenance or in-toto attestation files (*.intoto.jsonl, *.intoto.json, *provenance*.json) committed, so no attestation chain exists to verify."; exit 1; };
68
+ echo "$atts" | while IFS= read -r att; do
69
+ [ -n "$att" ] || continue;
70
+ bundle="";
71
+ for cand in "$att.sigstore.json" "$att.bundle"; do if [ -f "$cand" ]; then bundle="$cand"; break; fi; done;
72
+ [ -n "$bundle" ] || { echo "FAIL SUP-019: attestation $att has no Sigstore bundle ($att.sigstore.json or $att.bundle missing). The attestation chain is incomplete."; exit 1; };
73
+ cosign verify-blob --key "$key" --bundle "$bundle" "$att" >/dev/null 2>&1 || { echo "FAIL SUP-019: cosign verify-blob failed for attestation $att (bundle $bundle, key $key)."; exit 1; };
74
+ done || exit 1;
75
+ echo "SUP-019: cosign verify-blob succeeded for every committed attestation against $key.";
76
+ expect_exit: 0
77
+ evidence: 'cosign verify-blob success output for every committed attestation, or the fail-closed reason above.'
78
+ why: 'Provenance that does not verify answers nothing when an artifact is compromised. At production, each committed attestation must carry a bundle that verifies — otherwise "built by us, from this source" is a claim, not evidence.'
79
+ remediation: 'Commit SLSA/in-toto attestations with a Sigstore bundle per file (<attestation>.sigstore.json), then run with --allow-commands so each pair verifies.'
80
+ references: ['SLSA-v1.2', 'SLSA-Build-L2', 'OpenSSF-Scorecard:Signed-Releases']
81
+
82
+ - id: SUP-020
83
+ title: Every release artifact ships a Sigstore bundle (chain completeness)
84
+ section: S3
85
+ section_title: Supply Chain & Build Provenance
86
+ severity: MEDIUM
87
+ class: supply-chain
88
+ applies_when: { fact: 'maturity:production' }
89
+ check:
90
+ kind: command
91
+ run: >-
92
+ command -v cosign >/dev/null 2>&1 || { echo "FAIL-CLOSED SUP-020: cosign binary not found in PATH, so the release signature chain cannot be checked. Install sigstore/cosign and re-run with --allow-commands."; exit 1; };
93
+ n=0;
94
+ for dir in dist artifacts releases; do
95
+ [ -d "$dir" ] || continue;
96
+ for art in "$dir"/*; do
97
+ [ -f "$art" ] || continue;
98
+ case "$art" in
99
+ *.sigstore.json|*.bundle|*.sig|*.pem|*.pub|SHA256SUMS*|*.sbom.*|*.spdx*|*.intoto.*) continue;;
100
+ esac;
101
+ if [ -f "$art.sigstore.json" ] || [ -f "$art.bundle" ]; then n=$((n + 1)); else echo "FAIL SUP-020: release artifact $art has no Sigstore bundle ($art.sigstore.json or $art.bundle missing). Every release artifact must ship a verifiable signature."; exit 1; fi;
102
+ done;
103
+ done;
104
+ [ "$n" -gt 0 ] || { echo "FAIL-CLOSED SUP-020: no release artifacts found under dist/, artifacts/ or releases/, so there is no signature chain to judge. Publish artifacts with Sigstore bundles."; exit 1; };
105
+ echo "SUP-020: every release artifact under dist/, artifacts/ or releases/ has a Sigstore bundle.";
106
+ expect_exit: 0
107
+ evidence: 'The per-artifact bundle listing above, or the fail-closed reason.'
108
+ why: 'One unverified artifact is the one the attacker picks. SUP-018 proves the signatures that exist; this rule proves none are missing — coverage of the chain, not just its links.'
109
+ remediation: 'Add a Sigstore bundle (<artifact>.sigstore.json) beside every file published from dist/, artifacts/ or releases/, then run with --allow-commands.'
110
+ references: ['SLSA-Build-L2', 'SLSA-v1.2', 'OpenSSF-Scorecard:Signed-Releases']
package/rules/index.yaml CHANGED
@@ -13,6 +13,8 @@ packs:
13
13
  - core/repo.yaml
14
14
  - core/security.yaml
15
15
  - core/supply-chain.yaml
16
+ - core/provenance-cosign.yaml
17
+ - core/provenance-attestation.yaml
16
18
  - core/architecture.yaml
17
19
  - core/code-quality.yaml
18
20
  - core/testing.yaml
@@ -129,7 +129,7 @@ profiles:
129
129
  focus:
130
130
  - Inventory EOL dependencies and pin a replacement date for each
131
131
  - Confirm backups restore, and that someone still knows how
132
- - Keep the lights on: monitoring, alerting, and an owner per service
132
+ - 'Keep the lights on: monitoring, alerting, and an owner per service'
133
133
  - Document the system well enough to hand over or retire
134
134
  defer:
135
135
  - Rewrites without a strangler plan, framework migrations for their own sake
@@ -0,0 +1,135 @@
1
+ # AGENTS.md — auditing this repository with USA
2
+
3
+ > Paste this into any repository you want an agent to audit with USA.
4
+ > Generated by `usa init`, or copy from
5
+ > [`templates/AGENTS.audit.md`](https://github.com/Er-Sajan-PLG/universal-software-auditor/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 USA
55
+
56
+ USA 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
+ usa 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 `.usa.yaml`.
67
+
68
+ ## Step 2 — Deterministic pass
69
+
70
+ ```bash
71
+ usa 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 report output template in `USA.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
+ > USA's CLI emits this structure automatically (`usa 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 : USA [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 `usa diff` works on it:
131
+
132
+ ````markdown
133
+ <!-- USA:TRAILER:BEGIN -->
134
+
135
+ ```yaml
136
+ schema: usa-report-v1
137
+ generated_at: 2026-09-08T00:00:00.000Z
138
+ usa_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
+ <!-- USA:TRAILER:END -->
155
+ ````