hex-audit 0.5.6 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEMO.md +15 -12
- package/README.md +16 -13
- package/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/app-build-manifest.json +20 -20
- 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-overleaf.md → generate-report.md} +186 -32
- 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/dashboard/.next/server/app/{overleaf → report}/page.js.nft.json +0 -0
- /package/dashboard/.next/static/{hV9GBuhq9vm6hXiHOWEfE → hU4ffTc1ImuXgNi8GX6_t}/_buildManifest.js +0 -0
- /package/dashboard/.next/static/{hV9GBuhq9vm6hXiHOWEfE → hU4ffTc1ImuXgNi8GX6_t}/_ssgManifest.js +0 -0
|
@@ -1,23 +1,44 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Generate the
|
|
2
|
+
description: "Generate the LaTeX report sections for the final audit report (Overleaf-ready)"
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
# Skill: Generate
|
|
5
|
+
# Skill: Generate Report
|
|
6
6
|
|
|
7
7
|
**Recommended model:** Sonnet
|
|
8
8
|
|
|
9
|
-
This skill produces the
|
|
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
10
|
|
|
11
11
|
## What it writes
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Seven report sections in `<output_dir>/report/`, each emitted in **two forms** (see "Output convention"):
|
|
14
14
|
|
|
15
|
-
1.
|
|
16
|
-
2.
|
|
17
|
-
3.
|
|
18
|
-
4.
|
|
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) — coverage summary and automated-tooling note, generated from `stats.json.test_coverage`.
|
|
19
22
|
|
|
20
|
-
|
|
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).
|
|
21
42
|
|
|
22
43
|
## Phase 0 — Gather report metadata
|
|
23
44
|
|
|
@@ -31,12 +52,14 @@ Read `<output_dir>/config.json`. Look under `settings.report.*` for:
|
|
|
31
52
|
- `audit_type` — defaults to `Security Review`.
|
|
32
53
|
- `doc_assessment` — `High` / `Medium` / `Low`.
|
|
33
54
|
- `test_assessment` — `High` / `Medium` / `Low`.
|
|
55
|
+
- `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.
|
|
56
|
+
- `client_availability` — optional free-text for the §7 closing sentence. Empty falls back to the standard availability sentence.
|
|
34
57
|
|
|
35
58
|
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.
|
|
36
59
|
|
|
37
60
|
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`).
|
|
38
61
|
|
|
39
|
-
## Phase
|
|
62
|
+
## Phase 1 — Require synced issues (GitHub is the source of truth)
|
|
40
63
|
|
|
41
64
|
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.
|
|
42
65
|
|
|
@@ -44,7 +67,7 @@ Before doing anything else:
|
|
|
44
67
|
- 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."
|
|
45
68
|
- 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."
|
|
46
69
|
|
|
47
|
-
## Phase
|
|
70
|
+
## Phase 2 — Compute the histograms and counts
|
|
48
71
|
|
|
49
72
|
Read `<output_dir>/findings.json` and `<output_dir>/tracking.json`.
|
|
50
73
|
|
|
@@ -62,9 +85,9 @@ Resolution histogram (count of synced findings per `resolution` field):
|
|
|
62
85
|
```
|
|
63
86
|
Findings without a `resolution` field count as `Unresolved`.
|
|
64
87
|
|
|
65
|
-
## Phase
|
|
88
|
+
## Phase 3 — Build the protocol synopsis paragraph
|
|
66
89
|
|
|
67
|
-
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
|
|
90
|
+
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:
|
|
68
91
|
|
|
69
92
|
- Open with one sentence on the project's purpose and the in-scope contract(s).
|
|
70
93
|
- 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).
|
|
@@ -75,7 +98,9 @@ Style hints:
|
|
|
75
98
|
- Bold key terms with `\textbf{...}`.
|
|
76
99
|
- No code blocks in this paragraph — those belong in the per-finding sections.
|
|
77
100
|
|
|
78
|
-
## Phase
|
|
101
|
+
## Phase 4 — Write the Executive Summary (§1)
|
|
102
|
+
|
|
103
|
+
Write to `executive_summary.txt` **and** `01-executive-summary.tex`.
|
|
79
104
|
|
|
80
105
|
```latex
|
|
81
106
|
\pagebreak \vspace*{0cm}
|
|
@@ -84,7 +109,7 @@ Style hints:
|
|
|
84
109
|
\black
|
|
85
110
|
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>.
|
|
86
111
|
|
|
87
|
-
<AI-GENERATED PROTOCOL SYNOPSIS PARAGRAPH FROM PHASE
|
|
112
|
+
<AI-GENERATED PROTOCOL SYNOPSIS PARAGRAPH FROM PHASE 3>
|
|
88
113
|
|
|
89
114
|
\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.
|
|
90
115
|
|
|
@@ -143,7 +168,7 @@ The issues are summarized in Fig.~1.
|
|
|
143
168
|
\textbf{Final Commit} & \href{<REPOSITORY_URL>/commit/<FINAL_COMMIT>}{<FINAL_COMMIT_SHORT>} \\
|
|
144
169
|
\textbf{Documentation Assessment} & <DOC_ASSESSMENT> \\
|
|
145
170
|
\textbf{Test Suite Assessment} & <TEST_ASSESSMENT> \\ \hline
|
|
146
|
-
\end{longtable
|
|
171
|
+
\end{longtable}
|
|
147
172
|
\color{black}
|
|
148
173
|
```
|
|
149
174
|
|
|
@@ -157,7 +182,9 @@ Substitutions:
|
|
|
157
182
|
- `<INITIAL_COMMIT_SHORT>` ← first 7 chars of the commit hash.
|
|
158
183
|
- `<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).
|
|
159
184
|
|
|
160
|
-
## Phase
|
|
185
|
+
## Phase 5 — Write the Audited Files table (§2)
|
|
186
|
+
|
|
187
|
+
Write to `audited_files.txt` **and** `02-audited-files.tex`.
|
|
161
188
|
|
|
162
189
|
Compute per-file line counts from each scope file. For each in-scope file in `config.json.project.scope`:
|
|
163
190
|
|
|
@@ -200,9 +227,11 @@ Render the table:
|
|
|
200
227
|
- Number rows sequentially `1, 2, 3 ...`.
|
|
201
228
|
- Aggregate ratio = `round(sum-comments * 100 / max(sum-code, 1), 0)`.
|
|
202
229
|
|
|
203
|
-
## Phase
|
|
230
|
+
## Phase 6 — Write the Summary of Issues (§3)
|
|
204
231
|
|
|
205
|
-
|
|
232
|
+
Write to `summary_of_findings.txt` **and** `03-summary-of-findings.tex`.
|
|
233
|
+
|
|
234
|
+
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`.
|
|
206
235
|
|
|
207
236
|
```latex
|
|
208
237
|
%\pagebreak \vspace*{0cm}
|
|
@@ -228,13 +257,59 @@ For each synced finding in severity-sorted order (Critical → Info), assign a s
|
|
|
228
257
|
```
|
|
229
258
|
|
|
230
259
|
- `<N>` is the 1-based row counter.
|
|
231
|
-
- `<I>` matches the `\label{issue:N}` index used in
|
|
260
|
+
- `<I>` matches the `\label{issue:N}` index used in the Issues section.
|
|
232
261
|
- `<Severity-display>` maps `Info` → `Info`, others use their name as-is.
|
|
233
262
|
- `<Resolution-display>` maps the `resolution` field directly (`Fixed`, `Acknowledged`, `Mitigated`, `Not Fixed`); blank/`Unresolved` shows `Unresolved`.
|
|
234
263
|
|
|
235
|
-
## Phase
|
|
264
|
+
## Phase 7 — Write the System Overview (§4)
|
|
265
|
+
|
|
266
|
+
Write to `system_overview.txt` **and** `04-system-overview.tex`.
|
|
236
267
|
|
|
237
|
-
|
|
268
|
+
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`.
|
|
269
|
+
|
|
270
|
+
**If `overview.md` is absent, abort**: "System Overview needs `<output_dir>/overview.md`. Run `/init-audit` first, then re-run `/generate-report`."
|
|
271
|
+
|
|
272
|
+
This section is descriptive only: no vulnerability observations (those live in Issues), no findings, no severities.
|
|
273
|
+
|
|
274
|
+
Structure the LaTeX:
|
|
275
|
+
|
|
276
|
+
```latex
|
|
277
|
+
\pagebreak \vspace*{0cm}
|
|
278
|
+
\sectioncolor
|
|
279
|
+
\section{System Overview}
|
|
280
|
+
\black
|
|
281
|
+
|
|
282
|
+
<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{}.>
|
|
283
|
+
|
|
284
|
+
<a short paragraph or itemize listing the main components: one line each — \texttt{ContractName}: responsibility.>
|
|
285
|
+
|
|
286
|
+
\subsectioncolor
|
|
287
|
+
\subsection{Actors and Roles}
|
|
288
|
+
\black
|
|
289
|
+
<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.>
|
|
290
|
+
|
|
291
|
+
\subsectioncolor
|
|
292
|
+
\subsection{<Module or Flow Name>}
|
|
293
|
+
\black
|
|
294
|
+
<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.>
|
|
295
|
+
|
|
296
|
+
... (repeat subsections) ...
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Formatting rules (from gauss `to-latex.md`):
|
|
300
|
+
- Each `\subsection{}` is preceded by `\subsectioncolor` and followed by `\black`. Subsection titles use title case.
|
|
301
|
+
- Contract / function / variable / interface names in `\texttt{}`. Hex values and constants in `\texttt{}`. Standard identifiers (ERC-1271, UUPS, etc.) as-is.
|
|
302
|
+
- Do not start a subsection with a bullet list — add an introductory sentence first.
|
|
303
|
+
- For a genuinely central formula, use an `equation` block. Do not do this for every calculation.
|
|
304
|
+
- Keep it under ~1 page for simple systems, up to ~2 pages for complex ones.
|
|
305
|
+
|
|
306
|
+
Apply the markdown → LaTeX conversion rules (below) to any prose carried over from `overview.md`.
|
|
307
|
+
|
|
308
|
+
## Phase 8 — Write the Issues section (§6)
|
|
309
|
+
|
|
310
|
+
Write to `findings.txt` **and** `06-issues.tex`.
|
|
311
|
+
|
|
312
|
+
For each synced finding in the same order (severity-sorted), render one subsection. Use the index `i` (0-based) matching the Summary of Issues.
|
|
238
313
|
|
|
239
314
|
```latex
|
|
240
315
|
\pagebreak \vspace*{0cm}
|
|
@@ -297,7 +372,7 @@ Apply to `description`, `recommendation`, and `update_from_client` (in that orde
|
|
|
297
372
|
|
|
298
373
|
End list items with `;` (replace trailing `.` with `;`). Last item still ends with `;`.
|
|
299
374
|
|
|
300
|
-
|
|
375
|
+
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.
|
|
301
376
|
|
|
302
377
|
### Severity-display mapping
|
|
303
378
|
- `Critical` → `Critical`
|
|
@@ -306,16 +381,93 @@ The markdown-to-LaTeX logic matches the spirit of the Python script `create-sect
|
|
|
306
381
|
- `Low` → `Low`
|
|
307
382
|
- `Info` → `Info` (the Nethermind template uses `Info` in the subsection headers and `Informational` in the histogram caption)
|
|
308
383
|
|
|
309
|
-
## Phase
|
|
384
|
+
## Phase 9 — Write the Documentation Evaluation (§7)
|
|
385
|
+
|
|
386
|
+
Write to `documentation_eval.txt` **and** `07-documentation-eval.tex`.
|
|
387
|
+
|
|
388
|
+
Determine what documentation was available:
|
|
389
|
+
- 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`.
|
|
390
|
+
- README / external docs: `config.json.project.docs_url` if set, and any README in the repo describing the in-scope system.
|
|
391
|
+
- Kick-off call: only if `settings.report.kickoff_call` is set (append its text as the focus).
|
|
392
|
+
- Client availability: `settings.report.client_availability` if set, otherwise the standard closing sentence.
|
|
393
|
+
|
|
394
|
+
Emit the exact `tcolorbox` wrapper (from gauss `documentation-eval.md`):
|
|
395
|
+
|
|
396
|
+
```latex
|
|
397
|
+
\pagebreak \vspace*{0cm}
|
|
398
|
+
\sectioncolor
|
|
399
|
+
\section{Documentation Evaluation}
|
|
400
|
+
\black
|
|
401
|
+
|
|
402
|
+
\begin{tcolorbox}[colback=blue!5,colframe=blue!50!black!70,title=Remarks about <CLIENT> <PRODUCT> documentation]
|
|
403
|
+
<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.>
|
|
404
|
+
\vspace{0.3em}
|
|
405
|
+
|
|
406
|
+
<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>.">
|
|
407
|
+
\vspace{0.3em}
|
|
408
|
+
|
|
409
|
+
<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.">
|
|
410
|
+
\end{tcolorbox}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
- `<CLIENT>` ← client/org name (derive from `repository_url` org or `project.name`).
|
|
414
|
+
- `<PRODUCT>` ← `config.json.project.name`.
|
|
415
|
+
- Do not include full file paths when referring to a file — use the basename.
|
|
416
|
+
- Keep it factual: do not claim documentation exists that the analysis does not support.
|
|
417
|
+
|
|
418
|
+
## Phase 10 — Write the Test Suite Evaluation (§8)
|
|
419
|
+
|
|
420
|
+
Write to `test_suite.txt` **and** `08-test-suite.tex`.
|
|
421
|
+
|
|
422
|
+
Read `stats.json.test_coverage`.
|
|
423
|
+
|
|
424
|
+
If `test_coverage.status === "available"`:
|
|
425
|
+
- Report `overall_line_pct` and `overall_branch_pct`.
|
|
426
|
+
- Render a per-contract coverage table from `test_coverage.per_contract[]` (`contract`, `line_pct`, `branch_pct`).
|
|
427
|
+
|
|
428
|
+
If `test_coverage.status !== "available"` (`failed` / `skipped` / null):
|
|
429
|
+
- State plainly that automated coverage could not be collected (include `failure_reason` if present), and describe the test suite qualitatively, falling back to the `settings.report.test_assessment` grade.
|
|
430
|
+
|
|
431
|
+
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.
|
|
432
|
+
|
|
433
|
+
```latex
|
|
434
|
+
\pagebreak \vspace*{0cm}
|
|
435
|
+
\sectioncolor
|
|
436
|
+
\section{Test Suite Evaluation}
|
|
437
|
+
\black
|
|
438
|
+
|
|
439
|
+
<paragraph on the test suite: overall line/branch coverage, or the reason coverage is unavailable, plus a qualitative read tied to the Test Suite Assessment grade.>
|
|
440
|
+
|
|
441
|
+
\begin{table}[H]
|
|
442
|
+
\centering
|
|
443
|
+
\begin{footnotesize}
|
|
444
|
+
\begin{tabular}{|p{9cm}|p{2cm}|p{2cm}|}
|
|
445
|
+
\hline
|
|
446
|
+
\textbf{Contract} & \textbf{Line \%} & \textbf{Branch \%} \\ \hline
|
|
447
|
+
\texttt{<contract>} & <line_pct>\% & <branch_pct>\% \\ \hline
|
|
448
|
+
...
|
|
449
|
+
\end{tabular}
|
|
450
|
+
\end{footnotesize}
|
|
451
|
+
\end{table}
|
|
452
|
+
|
|
453
|
+
<automated-tools paragraph: manual review + automated analysis; name Nethermind AuditAgent if a scan id is configured.>
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
(Omit the coverage table entirely when coverage is unavailable.)
|
|
457
|
+
|
|
458
|
+
## Phase 11 — Final report
|
|
310
459
|
|
|
311
|
-
After writing all
|
|
460
|
+
After writing all sections, print:
|
|
312
461
|
|
|
313
462
|
```
|
|
314
|
-
Wrote
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
463
|
+
Wrote 7 report sections (14 files) to <output_dir>/report/:
|
|
464
|
+
§1 Executive Summary executive_summary.txt 01-executive-summary.tex
|
|
465
|
+
§2 Audited Files audited_files.txt 02-audited-files.tex
|
|
466
|
+
§3 Summary of Issues summary_of_findings.txt 03-summary-of-findings.tex
|
|
467
|
+
§4 System Overview system_overview.txt 04-system-overview.tex
|
|
468
|
+
§6 Issues findings.txt 06-issues.tex
|
|
469
|
+
§7 Documentation Eval documentation_eval.txt 07-documentation-eval.tex
|
|
470
|
+
§8 Test Suite Evaluation test_suite.txt 08-test-suite.tex
|
|
319
471
|
|
|
320
472
|
Synced findings included: <count>
|
|
321
473
|
Critical=<C> High=<H> Medium=<M> Low=<L> Info=<I>
|
|
@@ -323,12 +475,14 @@ Synced findings included: <count>
|
|
|
323
475
|
Status distribution:
|
|
324
476
|
Fixed=<F> Acknowledged=<A> Mitigated=<MI> Unresolved=<U>
|
|
325
477
|
|
|
326
|
-
|
|
478
|
+
Read the sections on the dashboard's /report page, or \input the NN-*.tex files into your
|
|
479
|
+
Nethermind Overleaf main.tex. Sections 5 (risk methodology) and 9 (conclusion) are template-static.
|
|
327
480
|
```
|
|
328
481
|
|
|
329
482
|
## What this skill does NOT do
|
|
330
483
|
|
|
331
484
|
- Does not compile LaTeX (no `pdflatex` invocation).
|
|
332
|
-
- Does not
|
|
485
|
+
- Does not generate §5 (risk rating methodology) or §9 (conclusion) — those are static in the Overleaf template.
|
|
486
|
+
- Does not modify any file outside `<output_dir>/report/` and (with permission) `config.json` under `settings.report.*`.
|
|
333
487
|
- Does not push to Overleaf, GitHub, or any remote — output is local plain-text.
|
|
334
488
|
- 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})();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST["/overleaf/page"]={"moduleLoading":{"prefix":"/_next/","crossOrigin":null},"ssrModuleMapping":{"9":{"*":{"id":"6131","name":"*","chunks":[],"async":false}},"1076":{"*":{"id":"9323","name":"*","chunks":[],"async":false}},"1187":{"*":{"id":"7918","name":"*","chunks":[],"async":false}},"1447":{"*":{"id":"5915","name":"*","chunks":[],"async":false}},"2024":{"*":{"id":"2857","name":"*","chunks":[],"async":false}},"2198":{"*":{"id":"9915","name":"*","chunks":[],"async":false}},"3297":{"*":{"id":"1611","name":"*","chunks":[],"async":false}},"3362":{"*":{"id":"5289","name":"*","chunks":[],"async":false}},"3443":{"*":{"id":"7406","name":"*","chunks":[],"async":false}},"3719":{"*":{"id":"526","name":"*","chunks":[],"async":false}},"4595":{"*":{"id":"1388","name":"*","chunks":[],"async":false}},"5268":{"*":{"id":"3817","name":"*","chunks":[],"async":false}},"5276":{"*":{"id":"820","name":"*","chunks":[],"async":false}},"7063":{"*":{"id":"618","name":"*","chunks":[],"async":false}},"7498":{"*":{"id":"696","name":"*","chunks":[],"async":false}},"7542":{"*":{"id":"9555","name":"*","chunks":[],"async":false}},"7701":{"*":{"id":"8530","name":"*","chunks":[],"async":false}},"7780":{"*":{"id":"8664","name":"*","chunks":[],"async":false}},"9487":{"*":{"id":"6844","name":"*","chunks":[],"async":false}},"9690":{"*":{"id":"2204","name":"*","chunks":[],"async":false}},"9745":{"*":{"id":"4136","name":"*","chunks":[],"async":false}},"9922":{"*":{"id":"8033","name":"*","chunks":[],"async":false}}},"edgeSSRModuleMapping":{},"clientModules":{"/home/dx/Work/hex/node_modules/next/dist/client/components/app-router.js":{"id":5268,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/esm/client/components/app-router.js":{"id":5268,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/client/components/client-page.js":{"id":1076,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/esm/client/components/client-page.js":{"id":1076,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/client/components/error-boundary.js":{"id":9690,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/esm/client/components/error-boundary.js":{"id":9690,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/client/components/layout-router.js":{"id":5276,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/esm/client/components/layout-router.js":{"id":5276,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/client/components/not-found-boundary.js":{"id":1447,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/esm/client/components/not-found-boundary.js":{"id":1447,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/client/components/render-from-template-context.js":{"id":3297,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/node_modules/next/dist/esm/client/components/render-from-template-context.js":{"id":3297,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/app/globals.css":{"id":3812,"name":"*","chunks":["7498","static/chunks/7498-ea83cb9e30ec5491.js","3185","static/chunks/app/layout-a95b696089e278c3.js"],"async":false},"/home/dx/Work/hex/dashboard/components/CommandPalette.tsx":{"id":2198,"name":"*","chunks":["7498","static/chunks/7498-ea83cb9e30ec5491.js","3185","static/chunks/app/layout-a95b696089e278c3.js"],"async":false},"/home/dx/Work/hex/dashboard/components/DashboardLayout.tsx":{"id":1187,"name":"*","chunks":["7498","static/chunks/7498-ea83cb9e30ec5491.js","3185","static/chunks/app/layout-a95b696089e278c3.js"],"async":false},"/home/dx/Work/hex/node_modules/next-themes/dist/index.mjs":{"id":4595,"name":"*","chunks":["7498","static/chunks/7498-ea83cb9e30ec5491.js","3185","static/chunks/app/layout-a95b696089e278c3.js"],"async":false},"/home/dx/Work/hex/node_modules/next/font/google/target.css?{\"path\":\"app/layout.tsx\",\"import\":\"Manrope\",\"arguments\":[{\"subsets\":[\"latin\"],\"variable\":\"--font-sans\",\"display\":\"swap\"}],\"variableName\":\"manrope\"}":{"id":8414,"name":"*","chunks":["7498","static/chunks/7498-ea83cb9e30ec5491.js","3185","static/chunks/app/layout-a95b696089e278c3.js"],"async":false},"/home/dx/Work/hex/node_modules/next/font/google/target.css?{\"path\":\"app/layout.tsx\",\"import\":\"JetBrains_Mono\",\"arguments\":[{\"subsets\":[\"latin\"],\"variable\":\"--font-mono\",\"display\":\"swap\"}],\"variableName\":\"jetbrainsMono\"}":{"id":5256,"name":"*","chunks":["7498","static/chunks/7498-ea83cb9e30ec5491.js","3185","static/chunks/app/layout-a95b696089e278c3.js"],"async":false},"/home/dx/Work/hex/dashboard/app/diagram/page.tsx":{"id":3719,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/app/flows/page.tsx":{"id":3443,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/app/access/AccessClient.tsx":{"id":9745,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/app/calls/CallsClient.tsx":{"id":3362,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/app/notes/NotesClient.tsx":{"id":2024,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/app/overleaf/OverleafClient.tsx":{"id":9,"name":"*","chunks":["529","static/chunks/app/overleaf/page-bcea12a80c97b92f.js"],"async":false},"/home/dx/Work/hex/dashboard/app/functions/FunctionsClient.tsx":{"id":7780,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/app/conformance/ConformanceTable.tsx":{"id":7542,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/app/stats/StatsClient.tsx":{"id":9922,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/app/progress/ProgressClient.tsx":{"id":7701,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/app/issues/IssuesBoardClient.tsx":{"id":7063,"name":"*","chunks":[],"async":false},"/home/dx/Work/hex/dashboard/components/MarkdownRenderer.tsx":{"id":9487,"name":"*","chunks":["7397","static/chunks/7397-f6f4dddc7a20bfc1.js","7498","static/chunks/7498-ea83cb9e30ec5491.js","1931","static/chunks/app/page-24bac51dfe007c66.js"],"async":false},"/home/dx/Work/hex/node_modules/next/dist/client/link.js":{"id":7498,"name":"*","chunks":["7397","static/chunks/7397-f6f4dddc7a20bfc1.js","7498","static/chunks/7498-ea83cb9e30ec5491.js","1931","static/chunks/app/page-24bac51dfe007c66.js"],"async":false},"/home/dx/Work/hex/node_modules/next/dist/esm/client/link.js":{"id":7498,"name":"*","chunks":["7397","static/chunks/7397-f6f4dddc7a20bfc1.js","7498","static/chunks/7498-ea83cb9e30ec5491.js","1931","static/chunks/app/page-24bac51dfe007c66.js"],"async":false}},"entryCSSFiles":{"/home/dx/Work/hex/dashboard/":[],"/home/dx/Work/hex/dashboard/app/layout":["static/css/4a38d8f6f6b7a68f.css"],"/home/dx/Work/hex/dashboard/app/page":[],"/home/dx/Work/hex/dashboard/app/overleaf/page":[]}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[529],{9531:function(e,t,a){Promise.resolve().then(a.bind(a,9))},9:function(e,t,a){"use strict";a.d(t,{OverleafClient:function(){return i}});var s=a(7821),r=a(8078);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(e){var t;let{sections:a}=e,[i,o]=(0,r.useState)("executive_summary"),[l,c]=(0,r.useState)(!1),d=a[i],x=async()=>{if(d)try{await navigator.clipboard.writeText(d),c(!0),setTimeout(()=>c(!1),1500)}catch(e){}};return(0,s.jsxs)("div",{children:[(0,s.jsxs)("header",{className:"mb-6",children:[(0,s.jsx)("h1",{className:"text-title font-semibold text-text-primary",children:"Overleaf"}),(0,s.jsxs)("p",{className:"mt-1 text-body text-text-secondary",children:["LaTeX report sections from ",(0,s.jsx)("span",{className:"font-mono text-caption",children:".hex/overleaf/"}),". Copy each into the matching slot of the Nethermind Overleaf template."]})]}),(0,s.jsx)("div",{className:"mb-4 flex flex-wrap gap-1.5",children:n.map(e=>{let t=e.key===i,r=!!a[e.key];return(0,s.jsx)("button",{type:"button",onClick:()=>o(e.key),className:"rounded-md px-3 py-1.5 text-caption font-medium ".concat(t?"bg-accent text-surface-0":"bg-surface-2 text-text-secondary hover:text-text-primary"," ").concat(r?"":"opacity-50"),children:e.label},e.key)})}),(0,s.jsxs)("div",{className:"rounded-lg border border-border-subtle bg-surface-1",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between border-b border-border-subtle px-4 py-2.5",children:[(0,s.jsx)("span",{className:"font-mono text-caption text-text-tertiary",children:null===(t=n.find(e=>e.key===i))||void 0===t?void 0:t.file}),(0,s.jsx)("button",{type:"button",onClick:x,disabled:!d,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:l?"Copied!":"Copy"})]}),d?(0,s.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:d}):(0,s.jsxs)("p",{className:"p-4 text-body text-text-tertiary",children:["This section has not been generated yet. Run"," ",(0,s.jsx)("span",{className:"font-mono text-caption",children:"/generate-overleaf"}),"."]})]})]})}}},function(e){e.O(0,[7115,3205,1744],function(){return e(e.s=9531)}),_N_E=e.O()}]);
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { readMarkdownFile } from '@/lib/data';
|
|
2
|
-
import { NotYetGenerated } from '@/components/NotYetGenerated';
|
|
3
|
-
import { OverleafClient, type OverleafSections } from './OverleafClient';
|
|
4
|
-
|
|
5
|
-
// Read .hex/overleaf/ at request time, not at build time.
|
|
6
|
-
export const dynamic = 'force-dynamic';
|
|
7
|
-
|
|
8
|
-
export default function OverleafPage() {
|
|
9
|
-
const sections: OverleafSections = {
|
|
10
|
-
executive_summary: readMarkdownFile('overleaf/executive_summary.txt'),
|
|
11
|
-
audited_files: readMarkdownFile('overleaf/audited_files.txt'),
|
|
12
|
-
summary_of_findings: readMarkdownFile('overleaf/summary_of_findings.txt'),
|
|
13
|
-
findings: readMarkdownFile('overleaf/findings.txt'),
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const anyPresent = Object.values(sections).some(Boolean);
|
|
17
|
-
if (!anyPresent) {
|
|
18
|
-
return (
|
|
19
|
-
<div>
|
|
20
|
-
<header className="mb-6">
|
|
21
|
-
<h1 className="text-title font-semibold text-text-primary">Overleaf</h1>
|
|
22
|
-
<p className="mt-1 text-body text-text-secondary">
|
|
23
|
-
LaTeX report sections, ready to paste into the Nethermind Overleaf template.
|
|
24
|
-
</p>
|
|
25
|
-
</header>
|
|
26
|
-
<NotYetGenerated command="/generate-overleaf" />
|
|
27
|
-
</div>
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return <OverleafClient sections={sections} />;
|
|
32
|
-
}
|
|
File without changes
|
/package/dashboard/.next/static/{hV9GBuhq9vm6hXiHOWEfE → hU4ffTc1ImuXgNi8GX6_t}/_buildManifest.js
RENAMED
|
File without changes
|
/package/dashboard/.next/static/{hV9GBuhq9vm6hXiHOWEfE → hU4ffTc1ImuXgNi8GX6_t}/_ssgManifest.js
RENAMED
|
File without changes
|