hex-audit 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dashboard/.next/BUILD_ID +1 -1
  2. package/dashboard/.next/app-build-manifest.json +20 -20
  3. package/dashboard/.next/app-path-routes-manifest.json +1 -1
  4. package/dashboard/.next/build-manifest.json +2 -2
  5. package/dashboard/.next/next-server.js.nft.json +1 -1
  6. package/dashboard/.next/prerender-manifest.js +1 -1
  7. package/dashboard/.next/prerender-manifest.json +1 -1
  8. package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  9. package/dashboard/.next/server/app/_not-found.html +1 -1
  10. package/dashboard/.next/server/app/_not-found.rsc +1 -1
  11. package/dashboard/.next/server/app/access/page_client-reference-manifest.js +1 -1
  12. package/dashboard/.next/server/app/calls/page_client-reference-manifest.js +1 -1
  13. package/dashboard/.next/server/app/conformance/page_client-reference-manifest.js +1 -1
  14. package/dashboard/.next/server/app/diagram/page_client-reference-manifest.js +1 -1
  15. package/dashboard/.next/server/app/diagram.html +1 -1
  16. package/dashboard/.next/server/app/diagram.rsc +1 -1
  17. package/dashboard/.next/server/app/flows/page_client-reference-manifest.js +1 -1
  18. package/dashboard/.next/server/app/flows.html +1 -1
  19. package/dashboard/.next/server/app/flows.rsc +1 -1
  20. package/dashboard/.next/server/app/functions/page_client-reference-manifest.js +1 -1
  21. package/dashboard/.next/server/app/issues/page_client-reference-manifest.js +1 -1
  22. package/dashboard/.next/server/app/notes/page_client-reference-manifest.js +1 -1
  23. package/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
  24. package/dashboard/.next/server/app/progress/page_client-reference-manifest.js +1 -1
  25. package/dashboard/.next/server/app/report/page_client-reference-manifest.js +1 -1
  26. package/dashboard/.next/server/app/stats/page_client-reference-manifest.js +1 -1
  27. package/dashboard/.next/server/app-paths-manifest.json +8 -8
  28. package/dashboard/.next/server/chunks/530.js +1 -1
  29. package/dashboard/.next/server/functions-config-manifest.json +1 -1
  30. package/dashboard/.next/server/middleware-build-manifest.js +1 -1
  31. package/dashboard/.next/server/pages/404.html +1 -1
  32. package/dashboard/.next/server/pages/500.html +1 -1
  33. package/dashboard/.next/server/server-reference-manifest.js +1 -1
  34. package/dashboard/.next/server/server-reference-manifest.json +1 -1
  35. package/dist/commands/init.d.ts.map +1 -1
  36. package/dist/commands/init.js +10 -0
  37. package/dist/commands/init.js.map +1 -1
  38. package/dist/skills/generate-report.md +117 -25
  39. package/dist/skills/ingest-aa-report.md +2 -2
  40. package/dist/skills/init-audit.md +2 -0
  41. package/dist/skills/validate-finding.md +8 -0
  42. package/dist/skills/write-finding.md +8 -0
  43. package/package.json +1 -1
  44. /package/dashboard/.next/static/{hU4ffTc1ImuXgNi8GX6_t → ZYqkgvjnS38aMxfanyctA}/_buildManifest.js +0 -0
  45. /package/dashboard/.next/static/{hU4ffTc1ImuXgNi8GX6_t → ZYqkgvjnS38aMxfanyctA}/_ssgManifest.js +0 -0
@@ -18,7 +18,7 @@ Seven report sections in `<output_dir>/report/`, each emitted in **two forms** (
18
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
19
  5. **Issues** (§6) — one `\subsection{[Sev] title}\label{issue:N}` per synced finding, with description, code blocks, recommendation, status, client update.
20
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`.
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
22
 
23
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
24
 
@@ -40,6 +40,42 @@ The `.txt` and `.tex` bodies are byte-identical. The `.txt` copies power the das
40
40
 
41
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
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
+
43
79
  ## Phase 0 — Gather report metadata
44
80
 
45
81
  Read `<output_dir>/config.json`. Look under `settings.report.*` for:
@@ -231,7 +267,7 @@ Render the table:
231
267
 
232
268
  Write to `summary_of_findings.txt` **and** `03-summary-of-findings.tex`.
233
269
 
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`.
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`. Rows link via this sequential label, never via the hex id. Titles are emitted verbatim, so a title must not contain a hex id (`H-NNN`) or a line number.
235
271
 
236
272
  ```latex
237
273
  %\pagebreak \vspace*{0cm}
@@ -340,7 +376,7 @@ Each per-finding block:
340
376
 
341
377
  \textbf{Description}: <description converted from markdown to LaTeX>
342
378
 
343
- <each code block from description rendered as \begin{minted}[linenos,firstnumber=1]{solidity} ... \end{minted}>
379
+ <render every fenced code block embedded in the description as \begin{minted}[linenos,firstnumber=1]{solidity} ... \end{minted}; also render any non-empty root_cause.locations[].snippet the same way (present only on findings materialized from a source that carried code)>
344
380
 
345
381
  \textbf{Recommendation(s)}: <recommendation converted from markdown to LaTeX>
346
382
 
@@ -352,7 +388,16 @@ Each per-finding block:
352
388
 
353
389
  ```
354
390
 
355
- If the finding has multiple `root_cause.locations[]`, list them as `\href{...}{...}, \href{...}{...}` comma-separated.
391
+ If the finding has multiple `root_cause.locations[]`, list them in the **File(s)** line as `\href{...}{...}, \href{...}{...}` comma-separated (file paths only, never with `#Lnn` line anchors).
392
+
393
+ **A finding shows the relevant code as a fenced code block, not a line reference.** Authors embed a minimal ` ```solidity ` block in the description illustrating the issue; the report renders those (and any `root_cause.locations[].snippet` that a materialized finding happens to carry) as `minted` blocks.
394
+
395
+ **Content the report must NOT contain** (enforced upstream at authoring time — the report renders synced GitHub content verbatim and does not rewrite it, so it must arrive clean):
396
+ - No specific source line numbers ("line 56", "on lines 43, 55") in `description` / `recommendation` — code is shown via `snippet` instead.
397
+ - No cross-references to other findings by hex id (`H-NNN`) or number/title — each finding stands alone; report readers have no hex ids.
398
+ - No references to the proof-of-concept test or its file path.
399
+
400
+ If a synced finding still carries any of these (a legacy finding authored before this rule), leave the prose as-is here and flag it in the Phase 11 summary so the auditor re-runs `/validate-finding` (which normalizes it) and `/sync-issues`. Do not silently rewrite GitHub-canonical text.
356
401
 
357
402
  ### Markdown → LaTeX conversion rules
358
403
 
@@ -391,15 +436,47 @@ Determine what documentation was available:
391
436
  - Kick-off call: only if `settings.report.kickoff_call` is set (append its text as the focus).
392
437
  - Client availability: `settings.report.client_availability` if set, otherwise the standard closing sentence.
393
438
 
394
- Emit the exact `tcolorbox` wrapper (from gauss `documentation-eval.md`):
439
+ This section has two parts: a **fixed boilerplate preamble** that is identical in every Nethermind report, followed by the **client-specific `tcolorbox`** remarks.
440
+
441
+ 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:
395
442
 
396
443
  ```latex
397
444
  \pagebreak \vspace*{0cm}
445
+
446
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
398
447
  \sectioncolor
399
448
  \section{Documentation Evaluation}
400
449
  \black
450
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451
+
452
+ 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.
453
+ %
454
+ 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.
455
+ %
456
+ Smart contracts can use various types of software documentation. Some of the most common types include:
457
+
458
+ \begin{itemize}
459
+ \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;
460
+
461
+ \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;
462
+
463
+ \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;
464
+
465
+ \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;
466
+
467
+ \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;
468
+
469
+ \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.
470
+
471
+ \end{itemize}
472
+
473
+ 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.
474
+ ```
401
475
 
402
- \begin{tcolorbox}[colback=blue!5,colframe=blue!50!black!70,title=Remarks about <CLIENT> <PRODUCT> documentation]
476
+ Then, after the preamble, emit the client-specific `tcolorbox` (this part IS AI-written and must follow the writing style):
477
+
478
+ ```latex
479
+ \begin{tcolorbox}[colback=blue!5,colframe=blue!50!black!70,title=Remarks about <CLIENT> documentation]
403
480
  <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
481
  \vspace{0.3em}
405
482
 
@@ -410,8 +487,7 @@ Emit the exact `tcolorbox` wrapper (from gauss `documentation-eval.md`):
410
487
  \end{tcolorbox}
411
488
  ```
412
489
 
413
- - `<CLIENT>` ← client/org name (derive from `repository_url` org or `project.name`).
414
- - `<PRODUCT>` ← `config.json.project.name`.
490
+ - `<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.
415
491
  - Do not include full file paths when referring to a file — use the basename.
416
492
  - Keep it factual: do not claim documentation exists that the analysis does not support.
417
493
 
@@ -419,14 +495,16 @@ Emit the exact `tcolorbox` wrapper (from gauss `documentation-eval.md`):
419
495
 
420
496
  Write to `test_suite.txt` **and** `08-test-suite.tex`.
421
497
 
422
- Read `stats.json.test_coverage`.
498
+ **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):
499
+ - 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.
500
+ - Hardhat (a `hardhat.config.*` exists): `npx hardhat test`; parse the mocha `N passing / M failing / K pending` summary.
501
+ - 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.
423
502
 
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`).
503
+ Keep totals only: passed, failed, skipped, and the number of suites/files. Do not paste the full stdout.
427
504
 
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.
505
+ **Step 2 — read coverage** from `stats.json.test_coverage`:
506
+ - `status === "available"`: use `overall_line_pct`, `overall_branch_pct`, and `per_contract[]`.
507
+ - `status !== "available"` (`failed` / `skipped` / null): state plainly that coverage could not be collected (include `failure_reason` if present) and lean on the qualitative read.
430
508
 
431
509
  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
510
 
@@ -436,7 +514,18 @@ Always close with an automated-tools paragraph: manual analysis plus automated t
436
514
  \section{Test Suite Evaluation}
437
515
  \black
438
516
 
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.>
517
+ <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.>
518
+
519
+ \begin{table}[H]
520
+ \centering
521
+ \begin{footnotesize}
522
+ \begin{tabular}{|p{6cm}|p{2cm}|p{2cm}|p{2cm}|}
523
+ \hline
524
+ \textbf{Test Result} & \textbf{Passed} & \textbf{Failed} & \textbf{Skipped} \\ \hline
525
+ \texttt{forge test} & <passed> & <failed> & <skipped> \\ \hline
526
+ \end{tabular}
527
+ \end{footnotesize}
528
+ \end{table}
440
529
 
441
530
  \begin{table}[H]
442
531
  \centering
@@ -453,21 +542,22 @@ Always close with an automated-tools paragraph: manual analysis plus automated t
453
542
  <automated-tools paragraph: manual review + automated analysis; name Nethermind AuditAgent if a scan id is configured.>
454
543
  ```
455
544
 
456
- (Omit the coverage table entirely when coverage is unavailable.)
545
+ - Replace `forge test` in the results table with the command actually run (e.g. `npx hardhat test`).
546
+ - 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.
457
547
 
458
548
  ## Phase 11 — Final report
459
549
 
460
- After writing all sections, print:
550
+ After writing, print a per-section status so the auditor sees what a rerun actually touched (`updated` / `new` / `unchanged`, per the Incremental regeneration rules):
461
551
 
462
552
  ```
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
553
+ Report sections in <output_dir>/report/ (each as .txt + numbered .tex):
554
+ §1 Executive Summary executive_summary.txt [<status>]
555
+ §2 Audited Files audited_files.txt [<status>]
556
+ §3 Summary of Issues summary_of_findings.txt [<status>]
557
+ §4 System Overview system_overview.txt [<status>]
558
+ §6 Issues findings.txt [<status>]
559
+ §7 Documentation Eval documentation_eval.txt [<status>]
560
+ §8 Test Suite Evaluation test_suite.txt [<status>]
471
561
 
472
562
  Synced findings included: <count>
473
563
  Critical=<C> High=<H> Medium=<M> Low=<L> Info=<I>
@@ -482,6 +572,8 @@ Nethermind Overleaf main.tex. Sections 5 (risk methodology) and 9 (conclusion) a
482
572
  ## What this skill does NOT do
483
573
 
484
574
  - Does not compile LaTeX (no `pdflatex` invocation).
575
+ - 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.
576
+ - Does not rewrite sections whose inputs are unchanged (see Incremental regeneration) unless invoked with `--force` / `all`.
485
577
  - Does not generate §5 (risk rating methodology) or §9 (conclusion) — those are static in the Overleaf template.
486
578
  - Does not modify any file outside `<output_dir>/report/` and (with permission) `config.json` under `settings.report.*`.
487
579
  - Does not push to Overleaf, GitHub, or any remote — output is local plain-text.
@@ -63,9 +63,9 @@ Parse the AuditAgent output (markdown with severity-tagged sections per finding)
63
63
  "tool": "auditagent",
64
64
  "title": "<finding title>",
65
65
  "severity": "Critical | High | Medium | Low | Info",
66
- "description": "<concise description — what it is, why it exists, the impact; trim AuditAgent's verbosity. The verbatim original stays in raw-output.md>",
66
+ "description": "<concise description — what it is, why it exists, the impact; trim AuditAgent's verbosity. The verbatim original stays in raw-output.md. Report-facing: no source line numbers (put code in affected_code[].snippet), no cross-references to other findings by id, no PoC mentions>",
67
67
  "affected_code": [
68
- { "file": "<path>", "snippet": "<relevant code if present>" }
68
+ { "file": "<path>", "snippet": "<relevant code if present — this materializes into root_cause.locations[].snippet and is rendered in the report>" }
69
69
  ],
70
70
  "confidence": "high | medium | low",
71
71
  "category": "<auditor-style category, e.g., Access Control, Math/Rounding>",
@@ -235,6 +235,8 @@ Write `.hex/spec-conformance.json`:
235
235
  }
236
236
  ```
237
237
 
238
+ The `finding` text becomes a board card's description when the item is materialized (Phase 6) and can be synced to the client's report, so write it to the same report-facing standard as a `/write-finding` finding: flat prose, no banned words / AI giveaways, and specifically **no source line numbers** ("line 56"), **no cross-references** to other items by id, and **no PoC mentions**. If code is needed to illustrate the deviation, embed a minimal fenced ```` ```solidity ```` block in the `finding` and refer to it by function/variable name. The precise line range stays in `code_location` for internal navigation only — do not transcribe it into the `finding` prose.
239
+
238
240
  Also write a human-readable `.hex/spec-conformance.md` rendering the same data grouped by status (DEVIATES first, CONFORMS last).
239
241
 
240
242
  ## Phase 6 — Materialize conformance items onto the board
@@ -122,6 +122,14 @@ Combine the two axes — correctness (Step 2) and security relevance (Step 2.5):
122
122
 
123
123
  Any description you write must be **flat prose** (plus a fenced code block only when a snippet is genuinely needed) — no markdown headings or header-like section labels (`Summary`/`Details`/`Impact`/`Affected code`); weave impact into the prose. **Keep it concise** — a single tight paragraph covering what the issue is, why it exists, and its impact, plus a 1–2 sentence hedged recommendation; trim anything that doesn't drive the point home. This matches the finding template used by the dashboard copy and the GitHub issue body. If the affected files are missing or wrong, set them with `--file` (repeatable) rather than narrating them in the description: `npx hex issue patch <id> --file src/Foo.sol [--file src/Bar.sol]`.
124
124
 
125
+ **A conformance-sourced (or auditagent/github) finding must be rewritten to the exact same standard as a manual `/write-finding` finding** — do not pass the raw source text through. Specifically, the prose you land must obey the report-facing content rules:
126
+ - **Recommendation tone:** hedged (`Consider...`, `One option is...`), never prescriptive (`Replace X with Y`, `You must...`). Follow the project writing style (no em dashes, no banned words / AI giveaways).
127
+ - **No line numbers — show the code.** Never cite specific source lines ("line 56"); line numbers drift. Instead embed a minimal fenced ```` ```solidity ```` block in the description file showing the relevant code, and refer to it by function/variable name. Do not transcribe line numbers from the conformance item's `code_location` into the prose (that field stays internal, for navigation only).
128
+ - **Stand alone — no cross-references** to other findings by Hex id (`H-NNN`) or number/title.
129
+ - **No PoC references** in the description or recommendation.
130
+
131
+ **Normalizing legacy findings:** if you are re-run on a finding whose stored description still contains line numbers, `H-NNN` cross-references, or PoC mentions (authored before these rules), rewrite it now: replace line references with a fenced ```` ```solidity ```` block, drop the id/PoC references, and re-land the cleaned prose via `--description-file`. This (followed by `/sync-issues`) is how an already-synced finding gets cleaned; the report never rewrites GitHub-canonical prose itself.
132
+
125
133
  Hex does not write `@audit-issue` comments into the client's source files — the board and finding record are the only place the issue lives.
126
134
 
127
135
  6. Use **AskUserQuestion** to ask:
@@ -97,6 +97,14 @@ The finding is rendered as a flat template (`## [Severity] Title`, then `**Descr
97
97
  - Affected file paths belong in `--file` (the File(s) line), not in an "Affected code" section in the description.
98
98
  - **Be concise.** Prefer a single tight paragraph: what the issue is, why it exists, and its impact — just enough to drive the point home. Don't restate the title, don't pad with background the reader doesn't need, and don't repeat the recommendation. There's no hard word count; brevity is the goal.
99
99
 
100
+ ### Report-facing content (STRICT)
101
+
102
+ The description, recommendation, and title end up verbatim in the client's published report. Keep them free of anything that only makes sense inside Hex or that rots when the code moves:
103
+
104
+ - **Stand alone — no cross-references to other findings.** Never point at another issue by its Hex id (`H-NNN`) or by its number/title ("see H-005", "as in the previous finding"). Report readers have no Hex ids and sections get reordered. If two issues share a mechanism, describe that mechanism inline in each.
105
+ - **No line numbers — show the code.** Do not cite specific source lines ("line 56", "on lines 43, 55"). Line numbers drift the moment code or comments change. Instead embed a minimal fenced ```` ```solidity ```` block in the description showing the relevant code, and refer to it by function or variable name in the prose. (The report renders those blocks; it also renders `root_cause.locations[].snippet` when a materialized finding carries one.)
106
+ - **No PoC references.** Do not name or link the proof-of-concept test or its path. The PoC belongs in the validation memo (`poc.validation_memo`), which the report never renders.
107
+
100
108
  ## Code Block Formatting Rules (STRICT)
101
109
 
102
110
  When including code snippets in the finding:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hex-audit",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "type": "module",
5
5
  "description": "CLI toolkit for Solidity smart contract auditors",
6
6
  "bin": {