hex-audit 0.5.6 → 0.6.1
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/DEMO.md +15 -12
- package/README.md +16 -13
- package/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/app-build-manifest.json +11 -11
- package/dashboard/.next/app-path-routes-manifest.json +1 -1
- package/dashboard/.next/build-manifest.json +4 -4
- package/dashboard/.next/next-server.js.nft.json +1 -1
- package/dashboard/.next/prerender-manifest.js +1 -1
- package/dashboard/.next/prerender-manifest.json +1 -1
- package/dashboard/.next/routes-manifest.json +1 -1
- package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/_not-found.html +1 -1
- package/dashboard/.next/server/app/_not-found.rsc +4 -4
- package/dashboard/.next/server/app/access/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/calls/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/conformance/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/diagram/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/diagram.html +1 -1
- package/dashboard/.next/server/app/diagram.rsc +4 -4
- package/dashboard/.next/server/app/flows/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/flows.html +1 -1
- package/dashboard/.next/server/app/flows.rsc +4 -4
- package/dashboard/.next/server/app/functions/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/issues/page.js +1 -1
- package/dashboard/.next/server/app/issues/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/notes/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/progress/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/report/page.js +1 -0
- package/dashboard/.next/server/app/report/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/stats/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app-paths-manifest.json +10 -10
- package/dashboard/.next/server/chunks/530.js +1 -1
- package/dashboard/.next/server/functions-config-manifest.json +1 -1
- package/dashboard/.next/server/middleware-build-manifest.js +1 -1
- package/dashboard/.next/server/pages/404.html +1 -1
- package/dashboard/.next/server/pages/500.html +1 -1
- package/dashboard/.next/server/server-reference-manifest.js +1 -1
- package/dashboard/.next/server/server-reference-manifest.json +1 -1
- package/dashboard/.next/static/chunks/app/issues/{page-d1607f57783782ae.js → page-98a298e1c1045c91.js} +1 -1
- package/dashboard/.next/static/chunks/app/{layout-a95b696089e278c3.js → layout-49f2496c7637d931.js} +1 -1
- package/dashboard/.next/static/chunks/app/report/page-796f2f4a8a5ac8f7.js +1 -0
- package/dashboard/.next/static/chunks/{main-9a811c95265dbd11.js → main-63ff429eab01f5bf.js} +1 -1
- package/dashboard/app/issues/IssuesBoardClient.tsx +1 -1
- package/dashboard/app/{overleaf/OverleafClient.tsx → report/ReportClient.tsx} +15 -7
- package/dashboard/app/report/page.tsx +35 -0
- package/dashboard/components/DashboardLayout.tsx +1 -1
- package/dist/commands/init.js +2 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/core/schema.d.ts +14 -0
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +2 -0
- package/dist/core/schema.js.map +1 -1
- package/dist/skills/generate-report.md +571 -0
- package/dist/skills/init-audit.md +1 -1
- package/dist/skills/sync-issues.md +1 -1
- package/dist/skills/validate-all-findings.md +1 -1
- package/dist/skills/validate-finding.md +1 -1
- package/package.json +1 -1
- package/dashboard/.next/server/app/overleaf/page.js +0 -1
- package/dashboard/.next/server/app/overleaf/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/static/chunks/app/overleaf/page-bcea12a80c97b92f.js +0 -1
- package/dashboard/app/overleaf/page.tsx +0 -32
- package/dist/skills/generate-overleaf.md +0 -334
- /package/dashboard/.next/server/app/{overleaf → report}/page.js.nft.json +0 -0
- /package/dashboard/.next/static/{hV9GBuhq9vm6hXiHOWEfE → mIJovZ5WuDGk7ZlzWBn03}/_buildManifest.js +0 -0
- /package/dashboard/.next/static/{hV9GBuhq9vm6hXiHOWEfE → mIJovZ5WuDGk7ZlzWBn03}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Generate the LaTeX report sections for the final audit report (Overleaf-ready)"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Skill: Generate Report
|
|
6
|
+
|
|
7
|
+
**Recommended model:** Sonnet
|
|
8
|
+
|
|
9
|
+
This skill produces the LaTeX section files an auditor assembles into the Nethermind Overleaf report template at the end of an engagement. It runs from the GitHub-synced issues (the report's source of truth), after findings have been pushed via /sync-issues, and reuses the analysis Hex already produced during /init-audit (`overview.md`, `stats.json`, `access-control.json`, `deps.json`).
|
|
10
|
+
|
|
11
|
+
## What it writes
|
|
12
|
+
|
|
13
|
+
Seven report sections in `<output_dir>/report/`, each emitted in **two forms** (see "Output convention"):
|
|
14
|
+
|
|
15
|
+
1. **Executive Summary** (§1) — project synopsis, severity histogram, status histogram, summary table of audit metadata.
|
|
16
|
+
2. **Audited Files** (§2) — a LaTeX table of in-scope files (LoC, comments, ratio, blank, total).
|
|
17
|
+
3. **Summary of Issues** (§3) — hyperlinked finding rows.
|
|
18
|
+
4. **System Overview** (§4) — descriptive protocol architecture: components, actors & roles, per-module or per-flow subsections. Built from `overview.md` + access-control/deps analysis.
|
|
19
|
+
5. **Issues** (§6) — one `\subsection{[Sev] title}\label{issue:N}` per synced finding, with description, code blocks, recommendation, status, client update.
|
|
20
|
+
6. **Documentation Evaluation** (§7) — a `tcolorbox` remarks paragraph about the client's documentation.
|
|
21
|
+
7. **Test Suite Evaluation** (§8) — the test-run result (passed/failed/skipped), coverage summary, and automated-tooling note, generated from a live test run plus `stats.json.test_coverage`.
|
|
22
|
+
|
|
23
|
+
The skill does NOT compile LaTeX itself. Sections §5 (risk methodology) and §9 (conclusion) are static in the Overleaf template and are not generated here.
|
|
24
|
+
|
|
25
|
+
## Output convention
|
|
26
|
+
|
|
27
|
+
Every section is generated **once** as a LaTeX string, then written to two paths in `<output_dir>/report/`:
|
|
28
|
+
|
|
29
|
+
| Section | `.txt` (dashboard viewer / copy-paste) | `.tex` (`\input{}` into `main.tex`) |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| §1 Executive Summary | `executive_summary.txt` | `01-executive-summary.tex` |
|
|
32
|
+
| §2 Audited Files | `audited_files.txt` | `02-audited-files.tex` |
|
|
33
|
+
| §3 Summary of Issues | `summary_of_findings.txt` | `03-summary-of-findings.tex` |
|
|
34
|
+
| §4 System Overview | `system_overview.txt` | `04-system-overview.tex` |
|
|
35
|
+
| §6 Issues | `findings.txt` | `06-issues.tex` |
|
|
36
|
+
| §7 Documentation Evaluation | `documentation_eval.txt` | `07-documentation-eval.tex` |
|
|
37
|
+
| §8 Test Suite Evaluation | `test_suite.txt` | `08-test-suite.tex` |
|
|
38
|
+
|
|
39
|
+
The `.txt` and `.tex` bodies are byte-identical. The `.txt` copies power the dashboard `/report` viewer (with copy buttons); the `.tex` copies drop straight into an Overleaf `main.tex` that `\input`s the numbered files.
|
|
40
|
+
|
|
41
|
+
All prose written by this skill must follow the project writing style (no em dashes, "Consider..." recommendations, banned-word list in the project CLAUDE.md).
|
|
42
|
+
|
|
43
|
+
## Incremental regeneration (reruns)
|
|
44
|
+
|
|
45
|
+
The skill is designed to be **re-run repeatedly** across an engagement: a finding gets validated, a client comment lands, an issue is marked fixed, the scope shifts. On each run, **only rewrite the sections whose inputs actually changed.** Sections whose inputs are unchanged are left exactly as they are on disk, which also preserves any hand-edits the auditor made to them (e.g. a polished System Overview).
|
|
46
|
+
|
|
47
|
+
Mechanism — a manifest at `<output_dir>/report/.manifest.json`:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{ "<section-key>": { "inputs_hash": "<sha256>", "written_at": "<iso8601>" } }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Section keys are the `.txt` basenames: `executive_summary`, `audited_files`, `summary_of_findings`, `system_overview`, `findings`, `documentation_eval`, `test_suite`.
|
|
54
|
+
|
|
55
|
+
Each section has a defined **input signature** — the exact set of data it derives from. Compute a stable `sha256` over a canonical (sorted-key) JSON of that section's inputs (a `sha256sum` shell one-liner over the serialized inputs is fine):
|
|
56
|
+
|
|
57
|
+
| Section | Input signature (hash over) |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `executive_summary` | severity + resolution histograms, `stats.totals.nsloc`, all `settings.report.*` fields, and the `overview.md` bytes (the synopsis derives from it) |
|
|
60
|
+
| `audited_files` | the per-file LoC results for every `project.scope` file, `repository_url`, `initial_commit` |
|
|
61
|
+
| `summary_of_findings` | the ordered synced-findings list: `(id, title, severity, resolution)` each |
|
|
62
|
+
| `system_overview` | `overview.md`, `access-control.json`, `deps.json` bytes |
|
|
63
|
+
| `findings` | the synced-findings full content: `(title, severity, description, code blocks, recommendation, resolution, update_from_client, root_cause.locations)` each |
|
|
64
|
+
| `documentation_eval` | `settings.report.{doc_assessment,kickoff_call,client_availability}`, `project.docs_url`, and the NatSpec-presence signal (`stats.totals.comment_lines`) |
|
|
65
|
+
| `test_suite` | the test-run summary (pass/fail/skip counts) and `stats.test_coverage`, `settings.report.test_assessment` |
|
|
66
|
+
|
|
67
|
+
Per-run algorithm:
|
|
68
|
+
1. Compute each section's current `inputs_hash`.
|
|
69
|
+
2. If the manifest has a matching hash for that section **and both** its `.txt` and `.tex` exist on disk, **skip** it (do not regenerate, do not rewrite) and report it as `unchanged`.
|
|
70
|
+
3. Otherwise regenerate the section (both `.txt` + `.tex`), update its manifest entry, and report it as `updated` (or `new` if there was no prior entry).
|
|
71
|
+
4. Write the manifest back at the end.
|
|
72
|
+
|
|
73
|
+
This is what makes a "found another issue, rerun" touch only `executive_summary` (counts changed), `summary_of_findings`, and `findings`, while `system_overview` and `audited_files` stay byte-identical and untouched. A client comment or a resolution change likewise only moves `findings`, `summary_of_findings` (Update column), and `executive_summary` (status histogram).
|
|
74
|
+
|
|
75
|
+
Skipping the expensive AI prose sections (`system_overview`, `documentation_eval`) when their inputs are unchanged is the point — do not re-run their generation just to discard the result.
|
|
76
|
+
|
|
77
|
+
**Force a full rebuild:** if the skill is invoked with `--force` / `all` (or the auditor asks to "regenerate everything"), ignore the manifest and rewrite all seven sections.
|
|
78
|
+
|
|
79
|
+
## Phase 0 — Gather report metadata
|
|
80
|
+
|
|
81
|
+
Read `<output_dir>/config.json`. Look under `settings.report.*` for:
|
|
82
|
+
|
|
83
|
+
- `repository_url` — e.g. `https://github.com/mellow-finance/flexible-vaults`. Required for hyperref links in the audited files table and per-finding file links.
|
|
84
|
+
- `initial_commit` — commit hash for the initial report scope.
|
|
85
|
+
- `final_commit` — commit hash after fixes (defaults to `initial_commit` if no remediation cycle).
|
|
86
|
+
- `initial_report_date` — date the initial report was delivered (e.g. `May 22, 2026`).
|
|
87
|
+
- `final_report_date` — date the final report was delivered (defaults to `initial_report_date`).
|
|
88
|
+
- `audit_type` — defaults to `Security Review`.
|
|
89
|
+
- `doc_assessment` — `High` / `Medium` / `Low`.
|
|
90
|
+
- `test_assessment` — `High` / `Medium` / `Low`.
|
|
91
|
+
- `kickoff_call` — optional focus note for the §7 kick-off sentence (e.g. "with a focus on the upgrade changes"). Empty means omit the kick-off sentence.
|
|
92
|
+
- `client_availability` — optional free-text for the §7 closing sentence. Empty falls back to the standard availability sentence.
|
|
93
|
+
|
|
94
|
+
For each missing field, use **AskUserQuestion** to prompt the auditor. After collection, persist all values back to `config.json` under `settings.report.*` so re-runs don't re-prompt.
|
|
95
|
+
|
|
96
|
+
If `repository_url` is not set, also offer to derive it from the project's git remote (`git -C <project_dir> remote get-url origin`).
|
|
97
|
+
|
|
98
|
+
## Phase 1 — Require synced issues (GitHub is the source of truth)
|
|
99
|
+
|
|
100
|
+
The report is generated **only** from issues that are synced to GitHub (`tracking.status === "synced"`). GitHub is the single source of truth for finding content; the local Potential/Verified columns are a staging area.
|
|
101
|
+
|
|
102
|
+
Before doing anything else:
|
|
103
|
+
- If `settings.github.repo` is not set, **abort**: "The report is generated from GitHub-synced issues. Configure `settings.github.repo` (or pass `--github-repo` to `hex init`) and run `/sync-issues` first."
|
|
104
|
+
- If there are zero `synced` findings, **abort**: "No synced issues found. Verify findings, then run `/sync-issues` to push them to GitHub before generating the report."
|
|
105
|
+
|
|
106
|
+
## Phase 2 — Compute the histograms and counts
|
|
107
|
+
|
|
108
|
+
Read `<output_dir>/findings.json` and `<output_dir>/tracking.json`.
|
|
109
|
+
|
|
110
|
+
**Report findings** are findings whose tracking entry has `status: "synced"`. These are the ones that go in the report. Sort by severity (Critical → High → Medium → Low → Info), then by id within each severity.
|
|
111
|
+
|
|
112
|
+
Severity histogram (count of synced findings per severity):
|
|
113
|
+
```
|
|
114
|
+
{ "Critical": N, "High": N, "Medium": N, "Low": N, "Undetermined": 0, "Info": N, "Best Practices": 0 }
|
|
115
|
+
```
|
|
116
|
+
(`Undetermined` and `Best Practices` are not currently in Hex's severity model — render them as 0 to match the Nethermind template.)
|
|
117
|
+
|
|
118
|
+
Resolution histogram (count of synced findings per `resolution` field):
|
|
119
|
+
```
|
|
120
|
+
{ "Fixed": N, "Acknowledged": N, "Mitigated": N, "Not Fixed": 0, "Unresolved": N }
|
|
121
|
+
```
|
|
122
|
+
Findings without a `resolution` field count as `Unresolved`.
|
|
123
|
+
|
|
124
|
+
## Phase 3 — Build the protocol synopsis paragraph
|
|
125
|
+
|
|
126
|
+
Read `<output_dir>/overview.md`. Produce a roughly half-page (~120-180 words) plain-language summary of what the protocol does and the security-relevant mechanics. This becomes the second paragraph of the Executive Summary. Match the tone of the Nethermind example:
|
|
127
|
+
|
|
128
|
+
- Open with one sentence on the project's purpose and the in-scope contract(s).
|
|
129
|
+
- Use a short `\begin{itemize}[leftmargin=*,itemsep=4pt] ... \end{itemize}` to list 2-3 of the security-relevant axes (e.g., access-control gates, asset-flow surfaces, upgradeability boundaries).
|
|
130
|
+
- Close with one or two sentences on any notable edge cases the auditor wants to flag generally (an entry point that bypasses a typical gate, a non-obvious permission, etc.).
|
|
131
|
+
|
|
132
|
+
Style hints:
|
|
133
|
+
- Refer to contracts as `\texttt{ContractName}`, role constants as `\texttt{ROLE\_NAME}`, function names as `\texttt{name(...)}`.
|
|
134
|
+
- Bold key terms with `\textbf{...}`.
|
|
135
|
+
- No code blocks in this paragraph — those belong in the per-finding sections.
|
|
136
|
+
|
|
137
|
+
## Phase 4 — Write the Executive Summary (§1)
|
|
138
|
+
|
|
139
|
+
Write to `executive_summary.txt` **and** `01-executive-summary.tex`.
|
|
140
|
+
|
|
141
|
+
```latex
|
|
142
|
+
\pagebreak \vspace*{0cm}
|
|
143
|
+
\sectioncolor
|
|
144
|
+
\section{Executive Summary}
|
|
145
|
+
\black
|
|
146
|
+
This document presents the results of the security review conducted by \href{https://www.nethermind.io/smart-contract-audits}{Nethermind Security} for <PROJECT_NAME>'s <SCOPE_DESCRIPTION>.
|
|
147
|
+
|
|
148
|
+
<AI-GENERATED PROTOCOL SYNOPSIS PARAGRAPH FROM PHASE 3>
|
|
149
|
+
|
|
150
|
+
\textbf{The audit comprises <TOTAL_NSLOC>} lines of Solidity code. \textbf{The audit was performed using} (a)~manual analysis of the codebase, and (b)~automated analysis tools.
|
|
151
|
+
|
|
152
|
+
\textbf{Along this document, we report} <ISSUE_COUNT_PHRASE>.
|
|
153
|
+
%
|
|
154
|
+
The issues are summarized in Fig.~1.
|
|
155
|
+
|
|
156
|
+
\textbf{This document is organized as follows.}
|
|
157
|
+
%
|
|
158
|
+
{Section~2} presents the files in the scope.
|
|
159
|
+
%
|
|
160
|
+
{Section~3} presents the summary of issues.
|
|
161
|
+
%
|
|
162
|
+
{Section~4} presents the System Overview.
|
|
163
|
+
%
|
|
164
|
+
{Section~5} discusses the risk rating methodology.
|
|
165
|
+
%
|
|
166
|
+
{Section~6} details the issues.
|
|
167
|
+
%
|
|
168
|
+
{Section~7} discusses the documentation provided by the client for this audit.
|
|
169
|
+
%
|
|
170
|
+
{Section~8} presents the test suite evaluation and automated tools used.
|
|
171
|
+
%
|
|
172
|
+
{Section~9} concludes the document.
|
|
173
|
+
\color{black}
|
|
174
|
+
|
|
175
|
+
\begin{figure}[H]
|
|
176
|
+
\centering
|
|
177
|
+
\subfigure[]
|
|
178
|
+
{
|
|
179
|
+
\includegraphics[trim=0cm 0cm 0cm 0cm, clip=true, width=0.45\textwidth]{img/Severity.pdf}
|
|
180
|
+
\label{fig:severity}
|
|
181
|
+
}
|
|
182
|
+
\subfigure[]
|
|
183
|
+
{
|
|
184
|
+
\includegraphics[trim=0cm 0cm 0cm 0cm, clip=true, width=0.45\textwidth]{img/Status.pdf}
|
|
185
|
+
\label{fig:status}
|
|
186
|
+
}
|
|
187
|
+
\label{fig:trapezio}
|
|
188
|
+
\end{figure}
|
|
189
|
+
\begin{center}
|
|
190
|
+
\begin{footnotesize}
|
|
191
|
+
\textbf{Fig.~1: Distribution of issues:} \textbf{Critical}~(<C>), \textbf{High}~(<H>), \textbf{Medium}~(<M>), \textbf{Low}~(<L>), \textbf{Undetermined}~(0), \textbf{Informational}~(<I>), \textbf{Best Practices}~(0).\\
|
|
192
|
+
\textbf{Distribution of status:} \textbf{Fixed}~(<F>), \textbf{Acknowledged}~(<A>), \textbf{Mitigated}~(<MI>), \textbf{Unresolved}~(<U>)
|
|
193
|
+
\end{footnotesize}
|
|
194
|
+
\end{center}
|
|
195
|
+
|
|
196
|
+
\color{black}
|
|
197
|
+
|
|
198
|
+
\begin{longtable}[c]{ll}
|
|
199
|
+
\caption*{\textbf{Summary of the Audit}} \\ \hline
|
|
200
|
+
\textbf{Audit Type} & <AUDIT_TYPE> \\
|
|
201
|
+
\textbf{Initial Report} & <INITIAL_REPORT_DATE> \\
|
|
202
|
+
\textbf{Final Report} & <FINAL_REPORT_DATE> \\
|
|
203
|
+
\textbf{Initial Commit} & \href{<REPOSITORY_URL>/blob/<INITIAL_COMMIT>/<FIRST_SCOPE_FILE>}{<INITIAL_COMMIT_SHORT>} \\
|
|
204
|
+
\textbf{Final Commit} & \href{<REPOSITORY_URL>/commit/<FINAL_COMMIT>}{<FINAL_COMMIT_SHORT>} \\
|
|
205
|
+
\textbf{Documentation Assessment} & <DOC_ASSESSMENT> \\
|
|
206
|
+
\textbf{Test Suite Assessment} & <TEST_ASSESSMENT> \\ \hline
|
|
207
|
+
\end{longtable}
|
|
208
|
+
\color{black}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Substitutions:
|
|
212
|
+
- `<PROJECT_NAME>` ← `config.json.project.name`.
|
|
213
|
+
- `<SCOPE_DESCRIPTION>` ← if a single in-scope file, `\texttt{<filename without extension>}` followed by a single-clause description from the overview; if many, `the contracts listed in Section~2`.
|
|
214
|
+
- `<TOTAL_NSLOC>` ← `stats.json.totals.nsloc`.
|
|
215
|
+
- `<ISSUE_COUNT_PHRASE>` ← something like "five points of attention, where one is classified as `\texttt{Low}`, and four are classified as `\texttt{Informational}` severity." Build dynamically from the severity histogram. If 0 synced findings: "no points of attention requiring remediation." If 1: "one point of attention, classified as `\texttt{<severity>}` severity." Pluralize properly.
|
|
216
|
+
- `<C><H><M><L><I>` ← severity histogram counts.
|
|
217
|
+
- `<F><A><MI><U>` ← resolution histogram counts.
|
|
218
|
+
- `<INITIAL_COMMIT_SHORT>` ← first 7 chars of the commit hash.
|
|
219
|
+
- `<FIRST_SCOPE_FILE>` ← relative path of the first file in `config.json.project.scope` (for the initial commit hyperref, which the template anchors to a specific file).
|
|
220
|
+
|
|
221
|
+
## Phase 5 — Write the Audited Files table (§2)
|
|
222
|
+
|
|
223
|
+
Write to `audited_files.txt` **and** `02-audited-files.tex`.
|
|
224
|
+
|
|
225
|
+
Compute per-file line counts from each scope file. For each in-scope file in `config.json.project.scope`:
|
|
226
|
+
|
|
227
|
+
- Read the file. Count:
|
|
228
|
+
- `code` lines (non-blank, non-comment).
|
|
229
|
+
- `comments` (lines starting with `//` or `#`, or any line inside a `/* ... */` block).
|
|
230
|
+
- `blank` (empty after `.strip()`).
|
|
231
|
+
- `total` = sum of the three.
|
|
232
|
+
- `ratio` = `round(comments * 100 / max(code, 1), 0)` followed by `\%`.
|
|
233
|
+
|
|
234
|
+
Render the table:
|
|
235
|
+
|
|
236
|
+
```latex
|
|
237
|
+
\pagebreak \vspace*{0cm}
|
|
238
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
239
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
240
|
+
\sectioncolor
|
|
241
|
+
\section{Audited Files}
|
|
242
|
+
\black
|
|
243
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
244
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
245
|
+
|
|
246
|
+
\begin{table}[H]
|
|
247
|
+
\centering
|
|
248
|
+
\begin{footnotesize}
|
|
249
|
+
\begin{tabular}{|p{.5cm}|p{9cm}|p{1cm}|p{1.5cm}|p{1cm}|p{1cm}|p{1cm}|}
|
|
250
|
+
\hline
|
|
251
|
+
&\textbf{Contract} & \textbf{LoC} & \textbf{Comments} & \textbf{Ratio} & \textbf{Blank} & \textbf{Total} \\ \hline
|
|
252
|
+
<N> & \href{<REPOSITORY_URL>/blob/<INITIAL_COMMIT>/<FILE_PATH>}{ \texttt{<FILENAME>}} & <code> & <comments> & <ratio>\% & <blank> & <total> \\ \hline
|
|
253
|
+
...
|
|
254
|
+
& \textbf{Total} & \textbf{<sum-code>} & \textbf{<sum-comments>} & \textbf{<aggregate-ratio>\%} & \textbf{<sum-blank>} & \textbf{<sum-total>} \\ \hline
|
|
255
|
+
%%
|
|
256
|
+
\end{tabular}
|
|
257
|
+
\end{footnotesize}
|
|
258
|
+
\end{table}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
- `<FILENAME>` is the basename, LaTeX-escaped (no extension processing — show e.g., `ThreeFModule.sol`).
|
|
262
|
+
- `<FILE_PATH>` is the path relative to the project root (`src/utils/ThreeFModule.sol`).
|
|
263
|
+
- Number rows sequentially `1, 2, 3 ...`.
|
|
264
|
+
- Aggregate ratio = `round(sum-comments * 100 / max(sum-code, 1), 0)`.
|
|
265
|
+
|
|
266
|
+
## Phase 6 — Write the Summary of Issues (§3)
|
|
267
|
+
|
|
268
|
+
Write to `summary_of_findings.txt` **and** `03-summary-of-findings.tex`.
|
|
269
|
+
|
|
270
|
+
For each synced finding in severity-sorted order (Critical → Info), assign a sequential `issue:N` label starting at `issue:0`. This same label is used in the Issues section for the `\hyperref`.
|
|
271
|
+
|
|
272
|
+
```latex
|
|
273
|
+
%\pagebreak \vspace*{0cm}
|
|
274
|
+
|
|
275
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
276
|
+
%%%%%%%%%%%% H E A D E R 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
277
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
278
|
+
\sectioncolor
|
|
279
|
+
\section{Summary of Issues}
|
|
280
|
+
\black
|
|
281
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
282
|
+
\begin{table}[H]
|
|
283
|
+
\centering
|
|
284
|
+
\begin{footnotesize}
|
|
285
|
+
\begin{tabular}{|p{1cm}|p{11cm}|p{2.1cm}|p{2.1cm}|}
|
|
286
|
+
\hline
|
|
287
|
+
& \textbf{Finding} & \textbf{Severity} & \textbf{Update} \\ \hline
|
|
288
|
+
<N>&\hyperref[issue:<I>]{<title-LaTeX-escaped>} &<Severity-display> & <Resolution-display>\\ \hline
|
|
289
|
+
%
|
|
290
|
+
\end{tabular}
|
|
291
|
+
\end{footnotesize}
|
|
292
|
+
\end{table}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
- `<N>` is the 1-based row counter.
|
|
296
|
+
- `<I>` matches the `\label{issue:N}` index used in the Issues section.
|
|
297
|
+
- `<Severity-display>` maps `Info` → `Info`, others use their name as-is.
|
|
298
|
+
- `<Resolution-display>` maps the `resolution` field directly (`Fixed`, `Acknowledged`, `Mitigated`, `Not Fixed`); blank/`Unresolved` shows `Unresolved`.
|
|
299
|
+
|
|
300
|
+
## Phase 7 — Write the System Overview (§4)
|
|
301
|
+
|
|
302
|
+
Write to `system_overview.txt` **and** `04-system-overview.tex`.
|
|
303
|
+
|
|
304
|
+
Primary source: `<output_dir>/overview.md` (produced by /init-audit — it already carries an intro, a `## Key Contracts` table, `## External Dependencies`, and `## Architecture Notes`). Enrich the actors/roles material from `<output_dir>/access-control.json` (roles, modifiers, gated functions) and cross-contract relationships from `<output_dir>/deps.json`.
|
|
305
|
+
|
|
306
|
+
**If `overview.md` is absent, abort**: "System Overview needs `<output_dir>/overview.md`. Run `/init-audit` first, then re-run `/generate-report`."
|
|
307
|
+
|
|
308
|
+
This section is descriptive only: no vulnerability observations (those live in Issues), no findings, no severities.
|
|
309
|
+
|
|
310
|
+
Structure the LaTeX:
|
|
311
|
+
|
|
312
|
+
```latex
|
|
313
|
+
\pagebreak \vspace*{0cm}
|
|
314
|
+
\sectioncolor
|
|
315
|
+
\section{System Overview}
|
|
316
|
+
\black
|
|
317
|
+
|
|
318
|
+
<intro paragraph(s): what the protocol does; if scope is a subset, focus on scope. State what each in-scope contract inherits from using \texttt{}.>
|
|
319
|
+
|
|
320
|
+
<a short paragraph or itemize listing the main components: one line each — \texttt{ContractName}: responsibility.>
|
|
321
|
+
|
|
322
|
+
\subsectioncolor
|
|
323
|
+
\subsection{Actors and Roles}
|
|
324
|
+
\black
|
|
325
|
+
<bullet list of actors, their permissions, the functions they can trigger, trust level. If there is a formal access-control system, name the library and explain the role model, using \texttt{ROLE\_NAME} for role constants.>
|
|
326
|
+
|
|
327
|
+
\subsectioncolor
|
|
328
|
+
\subsection{<Module or Flow Name>}
|
|
329
|
+
\black
|
|
330
|
+
<one subsection per module (Option A) or per flow (Option B). Choose per gauss's rule: if explaining each contract independently makes the system clear, use per-module; if the contracts only make sense together in motion, use per-flow. For each: entry points as a bullet list (functionName: one-line description), main internal flows, key state owned/mutated, how it interfaces with other modules. Use \begin{minted}[linenos]{solidity} ... \end{minted} for signature-only snippets when a flow depends on the parameters. Do not include full function bodies.>
|
|
331
|
+
|
|
332
|
+
... (repeat subsections) ...
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Formatting rules (from gauss `to-latex.md`):
|
|
336
|
+
- Each `\subsection{}` is preceded by `\subsectioncolor` and followed by `\black`. Subsection titles use title case.
|
|
337
|
+
- Contract / function / variable / interface names in `\texttt{}`. Hex values and constants in `\texttt{}`. Standard identifiers (ERC-1271, UUPS, etc.) as-is.
|
|
338
|
+
- Do not start a subsection with a bullet list — add an introductory sentence first.
|
|
339
|
+
- For a genuinely central formula, use an `equation` block. Do not do this for every calculation.
|
|
340
|
+
- Keep it under ~1 page for simple systems, up to ~2 pages for complex ones.
|
|
341
|
+
|
|
342
|
+
Apply the markdown → LaTeX conversion rules (below) to any prose carried over from `overview.md`.
|
|
343
|
+
|
|
344
|
+
## Phase 8 — Write the Issues section (§6)
|
|
345
|
+
|
|
346
|
+
Write to `findings.txt` **and** `06-issues.tex`.
|
|
347
|
+
|
|
348
|
+
For each synced finding in the same order (severity-sorted), render one subsection. Use the index `i` (0-based) matching the Summary of Issues.
|
|
349
|
+
|
|
350
|
+
```latex
|
|
351
|
+
\pagebreak \vspace*{0cm}
|
|
352
|
+
|
|
353
|
+
\sectioncolor
|
|
354
|
+
\section{Issues}
|
|
355
|
+
\black
|
|
356
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
357
|
+
|
|
358
|
+
<per-finding block>
|
|
359
|
+
|
|
360
|
+
<per-finding block>
|
|
361
|
+
|
|
362
|
+
...
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Each per-finding block:
|
|
366
|
+
|
|
367
|
+
```latex
|
|
368
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
369
|
+
%%%%%%%%%%%% H E A D E R 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
370
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
371
|
+
\subsubsectioncolor
|
|
372
|
+
\subsection{[<Severity-display>] <title-LaTeX-escaped>}\label{issue:<i>}
|
|
373
|
+
\begin{footnotesize} \black
|
|
374
|
+
|
|
375
|
+
\textbf{File(s)}: \href{<REPOSITORY_URL>/blob/<INITIAL_COMMIT>/<FILE_PATH>}{ \texttt{<FILE_PATH>}}
|
|
376
|
+
|
|
377
|
+
\textbf{Description}: <description converted from markdown to LaTeX>
|
|
378
|
+
|
|
379
|
+
<each code block from description rendered as \begin{minted}[linenos,firstnumber=1]{solidity} ... \end{minted}>
|
|
380
|
+
|
|
381
|
+
\textbf{Recommendation(s)}: <recommendation converted from markdown to LaTeX>
|
|
382
|
+
|
|
383
|
+
\textbf{Status}: <Resolution-display or "Unresolved">
|
|
384
|
+
|
|
385
|
+
\textbf{Update from the client}: <update_from_client, LaTeX-escaped>
|
|
386
|
+
|
|
387
|
+
\end{footnotesize}
|
|
388
|
+
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
If the finding has multiple `root_cause.locations[]`, list them as `\href{...}{...}, \href{...}{...}` comma-separated.
|
|
392
|
+
|
|
393
|
+
### Markdown → LaTeX conversion rules
|
|
394
|
+
|
|
395
|
+
Apply to `description`, `recommendation`, and `update_from_client` (in that order, on non-code-block text only — first split out fenced code blocks, then convert the prose):
|
|
396
|
+
|
|
397
|
+
| Markdown | LaTeX |
|
|
398
|
+
|---|---|
|
|
399
|
+
| `` `text` `` | ` \texttt{text}` (leading space intentional, matches Nethermind template) |
|
|
400
|
+
| `**text**` | ` \textbf{text}` |
|
|
401
|
+
| `[label](url)` | ` \href{url}{label}` — if `label` contains `#`, replace with `/#` (anchors break in LaTeX otherwise) |
|
|
402
|
+
| `_` (literal underscore in prose) | `\_` |
|
|
403
|
+
| `^` | `\^{}` |
|
|
404
|
+
| `%` (only when no `](` was present on the line — to avoid mangling URLs) | `\%` |
|
|
405
|
+
| Numbered list `1. text` | `\begin{enumerate}\n \def\labelenumi{\arabic{enumi}.} \tightlist\n\item text;\n...\end{enumerate}` |
|
|
406
|
+
| Bulleted list `- text` | `\begin{itemize}\n\tightlist\n\item text;\n...\end{itemize}` |
|
|
407
|
+
| Fenced code block ` ```solidity ` | `\begin{minted}[linenos,firstnumber=1]{solidity}` ... `\end{minted}` — also support `python`, `typescript`, `javascript`, `cairo` (use `python` lexer), `diff`, `shell`, `rust` |
|
|
408
|
+
|
|
409
|
+
End list items with `;` (replace trailing `.` with `;`). Last item still ends with `;`.
|
|
410
|
+
|
|
411
|
+
These conversion rules match the spirit of the Python script `create-section-findings.py` referenced by the auditor — port that semantically into these instructions rather than calling it. The same rules apply to the System Overview prose in Phase 7.
|
|
412
|
+
|
|
413
|
+
### Severity-display mapping
|
|
414
|
+
- `Critical` → `Critical`
|
|
415
|
+
- `High` → `High`
|
|
416
|
+
- `Medium` → `Medium`
|
|
417
|
+
- `Low` → `Low`
|
|
418
|
+
- `Info` → `Info` (the Nethermind template uses `Info` in the subsection headers and `Informational` in the histogram caption)
|
|
419
|
+
|
|
420
|
+
## Phase 9 — Write the Documentation Evaluation (§7)
|
|
421
|
+
|
|
422
|
+
Write to `documentation_eval.txt` **and** `07-documentation-eval.tex`.
|
|
423
|
+
|
|
424
|
+
Determine what documentation was available:
|
|
425
|
+
- NatSpec presence: infer from `stats.json.totals.comment_lines` (a high comment ratio suggests NatSpec) and by skimming 2-3 in-scope files from `config.json.project.scope`.
|
|
426
|
+
- README / external docs: `config.json.project.docs_url` if set, and any README in the repo describing the in-scope system.
|
|
427
|
+
- Kick-off call: only if `settings.report.kickoff_call` is set (append its text as the focus).
|
|
428
|
+
- Client availability: `settings.report.client_availability` if set, otherwise the standard closing sentence.
|
|
429
|
+
|
|
430
|
+
This section has two parts: a **fixed boilerplate preamble** that is identical in every Nethermind report, followed by the **client-specific `tcolorbox`** remarks.
|
|
431
|
+
|
|
432
|
+
Reproduce the preamble **verbatim** (do not paraphrase, do not restyle). It is fixed template text, so the project writing-style rules do NOT apply to it — it intentionally contains words like "Moreover" that are otherwise banned for AI-written prose:
|
|
433
|
+
|
|
434
|
+
```latex
|
|
435
|
+
\pagebreak \vspace*{0cm}
|
|
436
|
+
|
|
437
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
438
|
+
\sectioncolor
|
|
439
|
+
\section{Documentation Evaluation}
|
|
440
|
+
\black
|
|
441
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
442
|
+
|
|
443
|
+
Software documentation refers to the written or visual information that describes the functionality, architecture, design, and implementation of software. It provides a comprehensive overview of the software system and helps users, developers, and stakeholders understand how the software works, how to use it, and how to maintain it. Software documentation can take different forms, such as user manuals, system manuals, technical specifications, requirements documents, design documents, and code comments.
|
|
444
|
+
%
|
|
445
|
+
Software documentation is critical in software development, enabling effective communication between developers, testers, users, and other stakeholders. It helps to ensure that everyone involved in the development process has a shared understanding of the software system and its functionality. Moreover, software documentation can improve software maintenance by providing a clear and complete understanding of the software system, making it easier for developers to maintain, modify, and update the software over time.
|
|
446
|
+
%
|
|
447
|
+
Smart contracts can use various types of software documentation. Some of the most common types include:
|
|
448
|
+
|
|
449
|
+
\begin{itemize}
|
|
450
|
+
\item Technical whitepaper: A technical whitepaper is a comprehensive document describing the smart contract's design and technical details. It includes information about the purpose of the contract, its architecture, its components, and how they interact with each other;
|
|
451
|
+
|
|
452
|
+
\item User manual: A user manual is a document that provides information about how to use the smart contract. It includes step-by-step instructions on how to perform various tasks and explains the different features and functionalities of the contract;
|
|
453
|
+
|
|
454
|
+
\item Code documentation: Code documentation is a document that provides details about the code of the smart contract. It includes information about the functions, variables, and classes used in the code, as well as explanations of how they work;
|
|
455
|
+
|
|
456
|
+
\item API documentation: API documentation is a document that provides information about the API (Application Programming Interface) of the smart contract. It includes details about the methods, parameters, and responses that can be used to interact with the contract;
|
|
457
|
+
|
|
458
|
+
\item Testing documentation: Testing documentation is a document that provides information about how the smart contract was tested. It includes details about the test cases that were used, the results of the tests, and any issues that were identified during testing;
|
|
459
|
+
|
|
460
|
+
\item Audit documentation: Audit documentation includes reports, notes, and other materials related to the security audit of the smart contract. This type of documentation is critical in ensuring that the smart contract is secure and free from vulnerabilities.
|
|
461
|
+
|
|
462
|
+
\end{itemize}
|
|
463
|
+
|
|
464
|
+
These types of documentation are essential for smart contract development and maintenance. They help ensure that the contract is properly designed, implemented, and tested, and they provide a reference for developers who need to modify or maintain the contract in the future.
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
Then, after the preamble, emit the client-specific `tcolorbox` (this part IS AI-written and must follow the writing style):
|
|
468
|
+
|
|
469
|
+
```latex
|
|
470
|
+
\begin{tcolorbox}[colback=blue!5,colframe=blue!50!black!70,title=Remarks about <CLIENT> documentation]
|
|
471
|
+
<one paragraph describing the documentation actually provided — NatSpec, README/docs, and what the README covers (high-level overview, objectives, architecture). Only mention what exists and is relevant to the code in scope.>
|
|
472
|
+
\vspace{0.3em}
|
|
473
|
+
|
|
474
|
+
<kick-off call sentence, only if settings.report.kickoff_call is set. Example: "Additionally, the <CLIENT> team provided a general overview of the system during the kick-off call <kickoff_call>.">
|
|
475
|
+
\vspace{0.3em}
|
|
476
|
+
|
|
477
|
+
<closing sentence on team availability. Use settings.report.client_availability if set, else: "Moreover, the team addressed all questions and concerns raised by the Nethermind Security team, providing valuable insights and a comprehensive understanding of the project's technical aspects.">
|
|
478
|
+
\end{tcolorbox}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
- `<CLIENT>` ← the full client/product name, e.g. `Cardinal Trading`. Derive it from `project.name` (or the org in `repository_url`); use the complete name the client goes by, not a truncated token.
|
|
482
|
+
- Do not include full file paths when referring to a file — use the basename.
|
|
483
|
+
- Keep it factual: do not claim documentation exists that the analysis does not support.
|
|
484
|
+
|
|
485
|
+
## Phase 10 — Write the Test Suite Evaluation (§8)
|
|
486
|
+
|
|
487
|
+
Write to `test_suite.txt` **and** `08-test-suite.tex`.
|
|
488
|
+
|
|
489
|
+
**Step 1 — run the test suite and capture the output.** Detect the framework in `project.project_dir` and run the tests, capturing the summary (not the full verbose log):
|
|
490
|
+
- Foundry (a `foundry.toml` exists): `forge test` from the project dir. Parse the tail: the per-suite `Suite result: ok. N passed; M failed; K skipped` lines and the final `Ran N test suites ...: X tests passed, Y failed, Z skipped` totals.
|
|
491
|
+
- Hardhat (a `hardhat.config.*` exists): `npx hardhat test`; parse the mocha `N passing / M failing / K pending` summary.
|
|
492
|
+
- If neither is present, or the run cannot build, record that tests could not be executed (with the short reason) and continue — do not abort the whole report.
|
|
493
|
+
|
|
494
|
+
Keep totals only: passed, failed, skipped, and the number of suites/files. Do not paste the full stdout.
|
|
495
|
+
|
|
496
|
+
**Step 2 — read coverage** from `stats.json.test_coverage`:
|
|
497
|
+
- `status === "available"`: use `overall_line_pct`, `overall_branch_pct`, and `per_contract[]`.
|
|
498
|
+
- `status !== "available"` (`failed` / `skipped` / null): state plainly that coverage could not be collected (include `failure_reason` if present) and lean on the qualitative read.
|
|
499
|
+
|
|
500
|
+
Always close with an automated-tools paragraph: manual analysis plus automated tooling. If `config.json.settings.ai.auditagent_scan_id` is set, name Nethermind AuditAgent explicitly.
|
|
501
|
+
|
|
502
|
+
```latex
|
|
503
|
+
\pagebreak \vspace*{0cm}
|
|
504
|
+
\sectioncolor
|
|
505
|
+
\section{Test Suite Evaluation}
|
|
506
|
+
\black
|
|
507
|
+
|
|
508
|
+
<paragraph on the test suite: the test-run result (how many tests passed/failed/skipped, or the reason the suite could not be executed), the overall line/branch coverage (or why it is unavailable), and a qualitative read tied to the Test Suite Assessment grade.>
|
|
509
|
+
|
|
510
|
+
\begin{table}[H]
|
|
511
|
+
\centering
|
|
512
|
+
\begin{footnotesize}
|
|
513
|
+
\begin{tabular}{|p{6cm}|p{2cm}|p{2cm}|p{2cm}|}
|
|
514
|
+
\hline
|
|
515
|
+
\textbf{Test Result} & \textbf{Passed} & \textbf{Failed} & \textbf{Skipped} \\ \hline
|
|
516
|
+
\texttt{forge test} & <passed> & <failed> & <skipped> \\ \hline
|
|
517
|
+
\end{tabular}
|
|
518
|
+
\end{footnotesize}
|
|
519
|
+
\end{table}
|
|
520
|
+
|
|
521
|
+
\begin{table}[H]
|
|
522
|
+
\centering
|
|
523
|
+
\begin{footnotesize}
|
|
524
|
+
\begin{tabular}{|p{9cm}|p{2cm}|p{2cm}|}
|
|
525
|
+
\hline
|
|
526
|
+
\textbf{Contract} & \textbf{Line \%} & \textbf{Branch \%} \\ \hline
|
|
527
|
+
\texttt{<contract>} & <line_pct>\% & <branch_pct>\% \\ \hline
|
|
528
|
+
...
|
|
529
|
+
\end{tabular}
|
|
530
|
+
\end{footnotesize}
|
|
531
|
+
\end{table}
|
|
532
|
+
|
|
533
|
+
<automated-tools paragraph: manual review + automated analysis; name Nethermind AuditAgent if a scan id is configured.>
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
- Replace `forge test` in the results table with the command actually run (e.g. `npx hardhat test`).
|
|
537
|
+
- Omit the results table if the suite could not be executed; omit the coverage table if coverage is unavailable. State the reason in the paragraph in either case.
|
|
538
|
+
|
|
539
|
+
## Phase 11 — Final report
|
|
540
|
+
|
|
541
|
+
After writing, print a per-section status so the auditor sees what a rerun actually touched (`updated` / `new` / `unchanged`, per the Incremental regeneration rules):
|
|
542
|
+
|
|
543
|
+
```
|
|
544
|
+
Report sections in <output_dir>/report/ (each as .txt + numbered .tex):
|
|
545
|
+
§1 Executive Summary executive_summary.txt [<status>]
|
|
546
|
+
§2 Audited Files audited_files.txt [<status>]
|
|
547
|
+
§3 Summary of Issues summary_of_findings.txt [<status>]
|
|
548
|
+
§4 System Overview system_overview.txt [<status>]
|
|
549
|
+
§6 Issues findings.txt [<status>]
|
|
550
|
+
§7 Documentation Eval documentation_eval.txt [<status>]
|
|
551
|
+
§8 Test Suite Evaluation test_suite.txt [<status>]
|
|
552
|
+
|
|
553
|
+
Synced findings included: <count>
|
|
554
|
+
Critical=<C> High=<H> Medium=<M> Low=<L> Info=<I>
|
|
555
|
+
|
|
556
|
+
Status distribution:
|
|
557
|
+
Fixed=<F> Acknowledged=<A> Mitigated=<MI> Unresolved=<U>
|
|
558
|
+
|
|
559
|
+
Read the sections on the dashboard's /report page, or \input the NN-*.tex files into your
|
|
560
|
+
Nethermind Overleaf main.tex. Sections 5 (risk methodology) and 9 (conclusion) are template-static.
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
## What this skill does NOT do
|
|
564
|
+
|
|
565
|
+
- Does not compile LaTeX (no `pdflatex` invocation).
|
|
566
|
+
- Does run the project's test suite (`forge test` / `npx hardhat test`) read-only to capture §8 results; it does not modify tests or source.
|
|
567
|
+
- Does not rewrite sections whose inputs are unchanged (see Incremental regeneration) unless invoked with `--force` / `all`.
|
|
568
|
+
- Does not generate §5 (risk rating methodology) or §9 (conclusion) — those are static in the Overleaf template.
|
|
569
|
+
- Does not modify any file outside `<output_dir>/report/` and (with permission) `config.json` under `settings.report.*`.
|
|
570
|
+
- Does not push to Overleaf, GitHub, or any remote — output is local plain-text.
|
|
571
|
+
- Does not include `rejected`, `duplicate`, `pending_validation`, `unverified`, or `verified`-but-not-yet-synced findings. Only `synced` (on GitHub) makes the cut.
|
|
@@ -25,7 +25,7 @@ Ask the auditor for:
|
|
|
25
25
|
- **Commit hash** — the specific commit being audited (default: HEAD).
|
|
26
26
|
- **Chain** — target chain (default: ethereum).
|
|
27
27
|
- **Documentation URL** — if available.
|
|
28
|
-
- **GitHub repo** (optional) — the `owner/repo` the audit's findings sync to (e.g. `nethermind/audit-vaultx`). Pass it to `hex init --github-repo` so `/sync-issues` and `/generate-
|
|
28
|
+
- **GitHub repo** (optional) — the `owner/repo` the audit's findings sync to (e.g. `nethermind/audit-vaultx`). Pass it to `hex init --github-repo` so `/sync-issues` and `/generate-report` work later. Leave blank if the engagement isn't using GitHub.
|
|
29
29
|
|
|
30
30
|
### 1.2 Audit dependencies (BEFORE compiling)
|
|
31
31
|
|
|
@@ -10,7 +10,7 @@ Hex's GitHub Issues integration. Hex never authenticates with GitHub — you aut
|
|
|
10
10
|
|
|
11
11
|
## The model: GitHub is the source of truth, identity is the issue number
|
|
12
12
|
|
|
13
|
-
Once an issue is on GitHub it is **read-only in Hex** (status `synced`, locked on the board). Edits — severity, description, recommendation, status — happen on GitHub; this skill pulls them back into the local finding. `/generate-
|
|
13
|
+
Once an issue is on GitHub it is **read-only in Hex** (status `synced`, locked on the board). Edits — severity, description, recommendation, status — happen on GitHub; this skill pulls them back into the local finding. `/generate-report` reports **only** from synced issues.
|
|
14
14
|
|
|
15
15
|
**Identity is the GitHub issue number `#N`.** There is no hidden footer in the issue body (auditors create issues by hand, so a footer can't be relied on). Reconciliation matches a local finding to the issue number it has stored in `github.issue_number`. The body is exactly the five-field template, nothing hidden.
|
|
16
16
|
|
|
@@ -61,4 +61,4 @@ Validated N Potential issues:
|
|
|
61
61
|
→ Left for review (uncertain): U
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
Remind the auditor of the next steps: `/sync-issues` to push the Verified findings to GitHub, then `/generate-
|
|
64
|
+
Remind the auditor of the next steps: `/sync-issues` to push the Verified findings to GitHub, then `/generate-report` for the report.
|
|
@@ -204,4 +204,4 @@ The board reflects the new state automatically (the dashboard watches `tracking.
|
|
|
204
204
|
|
|
205
205
|
- Move on to the next Potential card.
|
|
206
206
|
- Run `/sync-issues` to push the newly Verified finding to GitHub if `settings.github.repo` is configured.
|
|
207
|
-
- Run `/generate-
|
|
207
|
+
- Run `/generate-report` once all verifications are done, to produce the LaTeX report sections.
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(()=>{var e={};e.id=529,e.ids=[529],e.modules={7849:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external")},2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},5403:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},4749:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},7561:e=>{"use strict";e.exports=require("node:fs")},9411:e=>{"use strict";e.exports=require("node:path")},1017:e=>{"use strict";e.exports=require("path")},7310:e=>{"use strict";e.exports=require("url")},7547:(e,t,r)=>{"use strict";r.r(t),r.d(t,{GlobalError:()=>i.a,__next_app__:()=>x,originalPathname:()=>u,pages:()=>c,routeModule:()=>m,tree:()=>d}),r(4636),r(819),r(2874);var a=r(7105),s=r(5265),n=r(157),i=r.n(n),o=r(4665),l={};for(let e in o)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(l[e]=()=>o[e]);r.d(t,l);let d=["",{children:["overleaf",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(r.bind(r,4636)),"/home/dx/Work/hex/dashboard/app/overleaf/page.tsx"]}]},{metadata:{icon:[async e=>(await Promise.resolve().then(r.bind(r,2950))).default(e)],apple:[],openGraph:[],twitter:[],manifest:void 0}}]},{layout:[()=>Promise.resolve().then(r.bind(r,819)),"/home/dx/Work/hex/dashboard/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(r.t.bind(r,2874,23)),"next/dist/client/components/not-found-error"],metadata:{icon:[async e=>(await Promise.resolve().then(r.bind(r,2950))).default(e)],apple:[],openGraph:[],twitter:[],manifest:void 0}}],c=["/home/dx/Work/hex/dashboard/app/overleaf/page.tsx"],u="/overleaf/page",x={require:r,loadChunk:()=>Promise.resolve()},m=new a.AppPageRouteModule({definition:{kind:s.x.APP_PAGE,page:"/overleaf/page",pathname:"/overleaf",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:d}})},6178:(e,t,r)=>{Promise.resolve().then(r.bind(r,6131))},6131:(e,t,r)=>{"use strict";r.d(t,{OverleafClient:()=>i});var a=r(9899),s=r(5507);let n=[{key:"executive_summary",label:"Executive Summary",file:"executive_summary.txt"},{key:"audited_files",label:"Audited Files",file:"audited_files.txt"},{key:"summary_of_findings",label:"Summary of Issues",file:"summary_of_findings.txt"},{key:"findings",label:"Issues",file:"findings.txt"}];function i({sections:e}){let[t,r]=(0,s.useState)("executive_summary"),[i,o]=(0,s.useState)(!1),l=e[t],d=async()=>{if(l)try{await navigator.clipboard.writeText(l),o(!0),setTimeout(()=>o(!1),1500)}catch{}};return(0,a.jsxs)("div",{children:[(0,a.jsxs)("header",{className:"mb-6",children:[a.jsx("h1",{className:"text-title font-semibold text-text-primary",children:"Overleaf"}),(0,a.jsxs)("p",{className:"mt-1 text-body text-text-secondary",children:["LaTeX report sections from ",a.jsx("span",{className:"font-mono text-caption",children:".hex/overleaf/"}),". Copy each into the matching slot of the Nethermind Overleaf template."]})]}),a.jsx("div",{className:"mb-4 flex flex-wrap gap-1.5",children:n.map(s=>{let n=s.key===t,i=!!e[s.key];return a.jsx("button",{type:"button",onClick:()=>r(s.key),className:`rounded-md px-3 py-1.5 text-caption font-medium ${n?"bg-accent text-surface-0":"bg-surface-2 text-text-secondary hover:text-text-primary"} ${i?"":"opacity-50"}`,children:s.label},s.key)})}),(0,a.jsxs)("div",{className:"rounded-lg border border-border-subtle bg-surface-1",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between border-b border-border-subtle px-4 py-2.5",children:[a.jsx("span",{className:"font-mono text-caption text-text-tertiary",children:n.find(e=>e.key===t)?.file}),a.jsx("button",{type:"button",onClick:d,disabled:!l,className:"rounded-md border border-border-default px-2.5 py-1 text-caption text-text-secondary hover:bg-surface-2 hover:text-text-primary disabled:opacity-50",children:i?"Copied!":"Copy"})]}),l?a.jsx("pre",{className:"max-h-[70vh] overflow-auto p-4 font-mono text-caption leading-relaxed text-text-secondary whitespace-pre-wrap break-words",children:l}):(0,a.jsxs)("p",{className:"p-4 text-body text-text-tertiary",children:["This section has not been generated yet. Run"," ",a.jsx("span",{className:"font-mono text-caption",children:"/generate-overleaf"}),"."]})]})]})}},4636:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>x,dynamic:()=>u});var a=r(5023),s=r(1720),n=r(446),i=r(2772);let o=(0,i.createProxy)(String.raw`/home/dx/Work/hex/dashboard/app/overleaf/OverleafClient.tsx`),{__esModule:l,$$typeof:d}=o;o.default;let c=(0,i.createProxy)(String.raw`/home/dx/Work/hex/dashboard/app/overleaf/OverleafClient.tsx#OverleafClient`),u="force-dynamic";function x(){let e={executive_summary:(0,s.ws)("overleaf/executive_summary.txt"),audited_files:(0,s.ws)("overleaf/audited_files.txt"),summary_of_findings:(0,s.ws)("overleaf/summary_of_findings.txt"),findings:(0,s.ws)("overleaf/findings.txt")};return Object.values(e).some(Boolean)?a.jsx(c,{sections:e}):(0,a.jsxs)("div",{children:[(0,a.jsxs)("header",{className:"mb-6",children:[a.jsx("h1",{className:"text-title font-semibold text-text-primary",children:"Overleaf"}),a.jsx("p",{className:"mt-1 text-body text-text-secondary",children:"LaTeX report sections, ready to paste into the Nethermind Overleaf template."})]}),a.jsx(n.v,{command:"/generate-overleaf"})]})}},446:(e,t,r)=>{"use strict";r.d(t,{v:()=>s});var a=r(5023);function s({command:e}){return(0,a.jsxs)("div",{className:"flex flex-col items-center justify-center border border-dashed border-border-default bg-surface-1 px-sp-5 py-sp-8 text-center",style:{borderRadius:"var(--radius-sm)"},children:[a.jsx("svg",{className:"mb-4 h-12 w-12 text-text-tertiary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:a.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m6.75 12H9.75m3 0H9.75m0 0v3m-3-6h1.5m-1.5 0v3m6-6h.008v.008H15V9.75Z"})}),a.jsx("h3",{className:"mb-2 text-heading font-medium text-text-primary",children:"Data not yet generated"}),a.jsx("p",{className:"mb-4 text-body text-text-secondary",children:"Run the following command to generate this data:"}),a.jsx("code",{className:"border border-border-default bg-surface-0 px-sp-4 py-sp-2 font-mono text-body text-accent",style:{borderRadius:"var(--radius-sm)"},children:e})]})}},1720:(e,t,r)=>{"use strict";r.d(t,{ki:()=>m,ZN:()=>p,J1:()=>f,gn:()=>c,ws:()=>u,V9:()=>h,au:()=>x});var a=r(7561),s=r.n(a),n=r(9411),i=r.n(n);let o=[".hex",".solaudit","solaudit-output"];function l(e){return e.replace(/\\/g,"/")}function d(){try{let e=function(e=process.cwd()){let t=i().resolve(e);for(;;){let e=function(e){for(let t of[...o.map(t=>i().join(e,t,"config.json")),i().join(e,"config.json")])if(s().existsSync(t))return l(t);return null}(t);if(e)return l(i().dirname(e));let r=i().dirname(t);if(r===t)return null;t=r}}(process.cwd());if(e)return e}catch{}return i().join(process.cwd(),".hex")}function c(e){try{let t=i().join(d(),e),r=s().readFileSync(t,"utf-8");return JSON.parse(r)}catch{return null}}function u(e){try{let t=i().join(d(),e);return s().readFileSync(t,"utf-8")}catch{return null}}function x(e,t){let r=i().join(d(),e);s().writeFileSync(r,JSON.stringify(t,null,2),"utf-8")}function m(e){try{let t=i().join(d(),e);return s().existsSync(t)}catch{return!1}}function p(){return d()}function f(e){try{let t=i().join(d(),e);if(!s().existsSync(t))return[];return s().readdirSync(t,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}function h(e){try{let t=i().join(d(),e),r=s().readFileSync(t,"utf-8");return JSON.parse(r)}catch{return null}}},2950:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>s});var a=r(1645);let s=e=>[{type:"image/svg+xml",sizes:"any",url:(0,a.fillMetadataSegment)(".",e.params,"icon.svg")+"?83fa4bf1ef0d214d"}]}};var t=require("../../webpack-runtime.js");t.C(e);var r=e=>t(t.s=e),a=t.X(0,[916,649,645,530],()=>r(7547));module.exports=a})();
|