hex-audit 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. package/DEMO.md +13 -0
  2. package/README.md +60 -6
  3. package/dashboard/.next/BUILD_ID +1 -1
  4. package/dashboard/.next/app-build-manifest.json +100 -89
  5. package/dashboard/.next/app-path-routes-manifest.json +1 -1
  6. package/dashboard/.next/build-manifest.json +14 -14
  7. package/dashboard/.next/next-server.js.nft.json +1 -1
  8. package/dashboard/.next/prerender-manifest.js +1 -1
  9. package/dashboard/.next/prerender-manifest.json +1 -1
  10. package/dashboard/.next/react-loadable-manifest.json +118 -118
  11. package/dashboard/.next/routes-manifest.json +1 -1
  12. package/dashboard/.next/server/app/_not-found/page.js +1 -1
  13. package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/dashboard/.next/server/app/access/page.js +1 -1
  15. package/dashboard/.next/server/app/access/page.js.nft.json +1 -1
  16. package/dashboard/.next/server/app/access/page_client-reference-manifest.js +1 -1
  17. package/dashboard/.next/server/app/calls/page.js +1 -1
  18. package/dashboard/.next/server/app/calls/page.js.nft.json +1 -1
  19. package/dashboard/.next/server/app/calls/page_client-reference-manifest.js +1 -1
  20. package/dashboard/.next/server/app/changes/page.js +20 -0
  21. package/dashboard/.next/server/app/changes/page.js.nft.json +1 -0
  22. package/dashboard/.next/server/app/changes/page_client-reference-manifest.js +1 -0
  23. package/dashboard/.next/server/app/conformance/page.js +1 -1
  24. package/dashboard/.next/server/app/conformance/page_client-reference-manifest.js +1 -1
  25. package/dashboard/.next/server/app/diagram/page.js +1 -1
  26. package/dashboard/.next/server/app/diagram/page_client-reference-manifest.js +1 -1
  27. package/dashboard/.next/server/app/flows/page.js +1 -1
  28. package/dashboard/.next/server/app/flows/page_client-reference-manifest.js +1 -1
  29. package/dashboard/.next/server/app/functions/page.js +1 -1
  30. package/dashboard/.next/server/app/functions/page.js.nft.json +1 -1
  31. package/dashboard/.next/server/app/functions/page_client-reference-manifest.js +1 -1
  32. package/dashboard/.next/server/app/issues/page.js +6 -6
  33. package/dashboard/.next/server/app/issues/page_client-reference-manifest.js +1 -1
  34. package/dashboard/.next/server/app/notes/page.js +3 -3
  35. package/dashboard/.next/server/app/notes/page_client-reference-manifest.js +1 -1
  36. package/dashboard/.next/server/app/page.js +2 -2
  37. package/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
  38. package/dashboard/.next/server/app/progress/page.js +1 -1
  39. package/dashboard/.next/server/app/progress/page_client-reference-manifest.js +1 -1
  40. package/dashboard/.next/server/app/report/page.js +1 -1
  41. package/dashboard/.next/server/app/report/page_client-reference-manifest.js +1 -1
  42. package/dashboard/.next/server/app/stats/page.js +1 -1
  43. package/dashboard/.next/server/app/stats/page.js.nft.json +1 -1
  44. package/dashboard/.next/server/app/stats/page_client-reference-manifest.js +1 -1
  45. package/dashboard/.next/server/app-paths-manifest.json +9 -8
  46. package/dashboard/.next/server/chunks/42.js +1 -1
  47. package/dashboard/.next/server/chunks/530.js +1 -1
  48. package/dashboard/.next/server/chunks/649.js +1 -1
  49. package/dashboard/.next/server/chunks/939.js +1 -0
  50. package/dashboard/.next/server/functions-config-manifest.json +1 -1
  51. package/dashboard/.next/server/middleware-build-manifest.js +1 -1
  52. package/dashboard/.next/server/middleware-react-loadable-manifest.js +1 -1
  53. package/dashboard/.next/server/next-font-manifest.js +1 -1
  54. package/dashboard/.next/server/next-font-manifest.json +1 -1
  55. package/dashboard/.next/server/pages/500.html +1 -1
  56. package/dashboard/.next/server/pages-manifest.json +1 -1
  57. package/dashboard/.next/server/server-reference-manifest.js +1 -1
  58. package/dashboard/.next/server/server-reference-manifest.json +1 -1
  59. package/dashboard/.next/static/chunks/{1.8868c4d131111be7.js → 1.a666047ea18866fb.js} +2 -2
  60. package/dashboard/.next/static/chunks/1015.39008440ab15e196.js +226 -0
  61. package/dashboard/.next/static/chunks/1151.497fa63c5b9eba52.js +1 -0
  62. package/dashboard/.next/static/chunks/1199.f30cbfa151e56076.js +148 -0
  63. package/dashboard/.next/static/chunks/1375.64c20f1064a38a10.js +43 -0
  64. package/dashboard/.next/static/chunks/1799.8dc56017eede704e.js +9 -0
  65. package/dashboard/.next/static/chunks/20154aaa.e87f69fe10483f8b.js +1 -0
  66. package/dashboard/.next/static/chunks/2077.5603adeb156c7d10.js +1 -0
  67. package/dashboard/.next/static/chunks/2166.9f6592b9399eadd8.js +215 -0
  68. package/dashboard/.next/static/chunks/{2291.85a70cb0c228157b.js → 2291.584b42ccad079b99.js} +1 -1
  69. package/dashboard/.next/static/chunks/2325.7decd077edfb81d9.js +24 -0
  70. package/dashboard/.next/static/chunks/{2383.62c035a052272594.js → 2383.ca81f980ce6528a4.js} +1 -1
  71. package/dashboard/.next/static/chunks/2694.7dfa5fef28851903.js +1 -0
  72. package/dashboard/.next/static/chunks/275.38af87389c1d33d7.js +34 -0
  73. package/dashboard/.next/static/chunks/2781.fba46046dbf2693b.js +93 -0
  74. package/dashboard/.next/static/chunks/2805.35b4cd8a94978aaf.js +1 -0
  75. package/dashboard/.next/static/chunks/{2879.51436986f93981d9.js → 2879.74d65e33e60505ee.js} +1 -1
  76. package/dashboard/.next/static/chunks/3017.4a5312e3c20a173f.js +1 -0
  77. package/dashboard/.next/static/chunks/3205-47d09be47325709f.js +2 -0
  78. package/dashboard/.next/static/chunks/3236.eac9855778a54518.js +1 -0
  79. package/dashboard/.next/static/chunks/3480.853a445a3784642a.js +1 -0
  80. package/dashboard/.next/static/chunks/3626.c5dacee11c8fbc4d.js +64 -0
  81. package/dashboard/.next/static/chunks/3865.5e6d2d501380e03b.js +90 -0
  82. package/dashboard/.next/static/chunks/3887.073cece834a4eae2.js +1 -0
  83. package/dashboard/.next/static/chunks/3924-88d849290406ee6f.js +1 -0
  84. package/dashboard/.next/static/chunks/3948.74201b9f0672234d.js +287 -0
  85. package/dashboard/.next/static/chunks/4728.e69372b5e5b61b8d.js +24 -0
  86. package/dashboard/.next/static/chunks/4787.821a6ad2816cdc60.js +23 -0
  87. package/dashboard/.next/static/chunks/5060.47402abc10273699.js +1 -0
  88. package/dashboard/.next/static/chunks/5284.334c7c0587d5d47a.js +1 -0
  89. package/dashboard/.next/static/chunks/5715.e16b1230cc4b4652.js +115 -0
  90. package/dashboard/.next/static/chunks/6014.641a2c53ba506241.js +104 -0
  91. package/dashboard/.next/static/chunks/6024.f099c15f75aa6722.js +79 -0
  92. package/dashboard/.next/static/chunks/{6052.033a6f1013c666eb.js → 6052.3001318955e5b36c.js} +2 -2
  93. package/dashboard/.next/static/chunks/6177.a01cf0a03734cf09.js +1 -0
  94. package/dashboard/.next/static/chunks/618f8807-69fc7bb97c2b87c1.js +1 -0
  95. package/dashboard/.next/static/chunks/6434.f560693253fea8de.js +1 -0
  96. package/dashboard/.next/static/chunks/6468.976d89ba133185f1.js +77 -0
  97. package/dashboard/.next/static/chunks/6540.6f3c4f2c6877ed89.js +1 -0
  98. package/dashboard/.next/static/chunks/6549.e3c4c1766cff1449.js +1 -0
  99. package/dashboard/.next/static/chunks/690f35d0.ab57e02a04c7e9e0.js +119 -0
  100. package/dashboard/.next/static/chunks/{7020.831e16e26d91abc1.js → 7020.b718b1b9cea36e60.js} +2 -2
  101. package/dashboard/.next/static/chunks/7397-37adf76cad543297.js +1 -0
  102. package/dashboard/.next/static/chunks/7498-d1814d68ba346d13.js +1 -0
  103. package/dashboard/.next/static/chunks/7802.f0134c792fccd382.js +80 -0
  104. package/dashboard/.next/static/chunks/7973.e34032723285a616.js +79 -0
  105. package/dashboard/.next/static/chunks/{7a04ac15.1c6cea694301806c.js → 7a04ac15.e49de94ece135900.js} +1 -1
  106. package/dashboard/.next/static/chunks/8216.1138ec313908a708.js +5 -0
  107. package/dashboard/.next/static/chunks/{8233babc.780b8e272eda298f.js → 8233babc.09872dcb3ff44064.js} +1 -1
  108. package/dashboard/.next/static/chunks/{8452-e616b5f43bceb95f.js → 8452-6d77fa353402422c.js} +2 -2
  109. package/dashboard/.next/static/chunks/8645.98a43217d406500e.js +1 -0
  110. package/dashboard/.next/static/chunks/8928-fc049decdfbdaa6d.js +1 -0
  111. package/dashboard/.next/static/chunks/9173.a7160f7d0b685fa7.js +1 -0
  112. package/dashboard/.next/static/chunks/9178.998a8c49996de8e4.js +1 -0
  113. package/dashboard/.next/static/chunks/9466.a914ce0de7d3bb84.js +1 -0
  114. package/dashboard/.next/static/chunks/9660.b1c8deae2c449d14.js +1 -0
  115. package/dashboard/.next/static/chunks/{9717.6cf5c8c89403b651.js → 9717.bba51b78ebd8fd29.js} +1 -1
  116. package/dashboard/.next/static/chunks/9720.d63a0696776bcc60.js +1 -0
  117. package/dashboard/.next/static/chunks/9811.2993c4cbd28e8d1b.js +1 -0
  118. package/dashboard/.next/static/chunks/app/_not-found/page-c299b935209993df.js +1 -0
  119. package/dashboard/.next/static/chunks/app/access/page-f8403cbdfc1c176b.js +1 -0
  120. package/dashboard/.next/static/chunks/app/calls/page-41f20d01e12382ef.js +1 -0
  121. package/dashboard/.next/static/chunks/app/changes/page-82bf8b6f48cdc506.js +1 -0
  122. package/dashboard/.next/static/chunks/app/conformance/page-6bb8e3b372e38098.js +1 -0
  123. package/dashboard/.next/static/chunks/app/diagram/page-469cd7a6f183efba.js +1 -0
  124. package/dashboard/.next/static/chunks/app/flows/page-7872dd9141ba0b07.js +1 -0
  125. package/dashboard/.next/static/chunks/app/functions/page-5847bcb77a8e7edf.js +1 -0
  126. package/dashboard/.next/static/chunks/app/issues/page-1ffc64fe40439002.js +1 -0
  127. package/dashboard/.next/static/chunks/app/layout-6c6d2a0fd7c989d3.js +1 -0
  128. package/dashboard/.next/static/chunks/app/notes/page-8bcaa52304500098.js +1 -0
  129. package/dashboard/.next/static/chunks/app/page-d63800ddb072b77b.js +1 -0
  130. package/dashboard/.next/static/chunks/app/progress/page-e26554f655a62eef.js +1 -0
  131. package/dashboard/.next/static/chunks/app/report/page-18c04fb2f193b020.js +1 -0
  132. package/dashboard/.next/static/chunks/app/stats/page-67ff59fd69bed651.js +1 -0
  133. package/dashboard/.next/static/chunks/{b7167ec1.7afbab6f609e3326.js → b7167ec1.708a3d61698ca2e6.js} +1 -1
  134. package/dashboard/.next/static/chunks/c7ea4e13.3073a2f551aa5ac8.js +1 -0
  135. package/dashboard/.next/static/chunks/framework-a117d81bf1b91f9a.js +33 -0
  136. package/dashboard/.next/static/chunks/main-app-5662c64b50ba40d1.js +1 -0
  137. package/dashboard/.next/static/chunks/main-cc3a889b25e9aa68.js +1 -0
  138. package/dashboard/.next/static/chunks/pages/_app-308fef0bf9b328f2.js +1 -0
  139. package/dashboard/.next/static/chunks/pages/_error-c91b5eabd7ac9382.js +1 -0
  140. package/dashboard/.next/static/chunks/webpack-4de0e79bdd6a0418.js +1 -0
  141. package/dashboard/.next/static/css/1112cea2260b3926.css +3 -0
  142. package/dashboard/.next/static/media/39f449c8730c2295-s.woff2 +0 -0
  143. package/dashboard/.next/static/media/86f65e8637cc94e3-s.woff2 +0 -0
  144. package/dashboard/.next/static/media/8760c4774489e4ba-s.p.woff2 +0 -0
  145. package/dashboard/.next/static/media/9fabb9c65b63d798-s.woff2 +0 -0
  146. package/dashboard/.next/static/media/a1f87af3f44fadbb-s.woff2 +0 -0
  147. package/dashboard/.next/static/media/f9e1dbe9676d9bb6-s.woff2 +0 -0
  148. package/dashboard/.next/static/z5XBev05xDAkDrxWxAjNu/_buildManifest.js +1 -0
  149. package/dashboard/app/changes/ChangesClient.tsx +464 -0
  150. package/dashboard/app/changes/page.tsx +36 -0
  151. package/dashboard/app/issues/IssuesBoardClient.tsx +11 -1
  152. package/dashboard/app/layout.tsx +13 -1
  153. package/dashboard/app/notes/NotesClient.tsx +5 -0
  154. package/dashboard/app/page.tsx +42 -0
  155. package/dashboard/components/DashboardLayout.tsx +43 -18
  156. package/dist/analysis/code-model.d.ts +113 -0
  157. package/dist/analysis/code-model.d.ts.map +1 -0
  158. package/dist/analysis/code-model.js +529 -0
  159. package/dist/analysis/code-model.js.map +1 -0
  160. package/dist/analysis/diff.d.ts +64 -0
  161. package/dist/analysis/diff.d.ts.map +1 -0
  162. package/dist/analysis/diff.js +644 -0
  163. package/dist/analysis/diff.js.map +1 -0
  164. package/dist/commands/analyze.d.ts.map +1 -1
  165. package/dist/commands/analyze.js +18 -2
  166. package/dist/commands/analyze.js.map +1 -1
  167. package/dist/commands/diff.d.ts +26 -0
  168. package/dist/commands/diff.d.ts.map +1 -0
  169. package/dist/commands/diff.js +218 -0
  170. package/dist/commands/diff.js.map +1 -0
  171. package/dist/commands/init.d.ts.map +1 -1
  172. package/dist/commands/init.js +72 -9
  173. package/dist/commands/init.js.map +1 -1
  174. package/dist/commands/issue.d.ts.map +1 -1
  175. package/dist/commands/issue.js +4 -4
  176. package/dist/commands/issue.js.map +1 -1
  177. package/dist/commands/note.d.ts.map +1 -1
  178. package/dist/commands/note.js +30 -2
  179. package/dist/commands/note.js.map +1 -1
  180. package/dist/core/config.d.ts +9 -0
  181. package/dist/core/config.d.ts.map +1 -1
  182. package/dist/core/config.js +18 -0
  183. package/dist/core/config.js.map +1 -1
  184. package/dist/core/errors.d.ts +1 -1
  185. package/dist/core/errors.d.ts.map +1 -1
  186. package/dist/core/errors.js +16 -0
  187. package/dist/core/errors.js.map +1 -1
  188. package/dist/core/git.d.ts +24 -0
  189. package/dist/core/git.d.ts.map +1 -0
  190. package/dist/core/git.js +115 -0
  191. package/dist/core/git.js.map +1 -0
  192. package/dist/core/issues.d.ts +4 -2
  193. package/dist/core/issues.d.ts.map +1 -1
  194. package/dist/core/issues.js +67 -28
  195. package/dist/core/issues.js.map +1 -1
  196. package/dist/core/notes.d.ts +25 -1
  197. package/dist/core/notes.d.ts.map +1 -1
  198. package/dist/core/notes.js +34 -2
  199. package/dist/core/notes.js.map +1 -1
  200. package/dist/core/schema.d.ts +750 -53
  201. package/dist/core/schema.d.ts.map +1 -1
  202. package/dist/core/schema.js +153 -1
  203. package/dist/core/schema.js.map +1 -1
  204. package/dist/core/skills.d.ts +10 -4
  205. package/dist/core/skills.d.ts.map +1 -1
  206. package/dist/core/skills.js +100 -37
  207. package/dist/core/skills.js.map +1 -1
  208. package/dist/index.js +2 -0
  209. package/dist/index.js.map +1 -1
  210. package/dist/skills/ai-audit/LICENSE +21 -0
  211. package/dist/skills/ai-audit/SKILL.md +476 -0
  212. package/dist/skills/ai-audit/UPSTREAM.md +46 -0
  213. package/dist/skills/ai-audit/references/agent-prompts.md +133 -0
  214. package/dist/skills/ai-audit/references/assemble.sh +357 -0
  215. package/dist/skills/ai-audit/references/dedup-and-assembly.md +420 -0
  216. package/dist/skills/ai-audit/references/hacking-agents/access-control-agent.md +27 -0
  217. package/dist/skills/ai-audit/references/hacking-agents/asymmetry-agent.md +77 -0
  218. package/dist/skills/ai-audit/references/hacking-agents/boundary-agent.md +79 -0
  219. package/dist/skills/ai-audit/references/hacking-agents/economic-security-agent.md +35 -0
  220. package/dist/skills/ai-audit/references/hacking-agents/execution-trace-agent.md +33 -0
  221. package/dist/skills/ai-audit/references/hacking-agents/first-principles-agent.md +36 -0
  222. package/dist/skills/ai-audit/references/hacking-agents/flow-gap-agent.md +49 -0
  223. package/dist/skills/ai-audit/references/hacking-agents/invariant-agent.md +44 -0
  224. package/dist/skills/ai-audit/references/hacking-agents/math-precision-agent.md +48 -0
  225. package/dist/skills/ai-audit/references/hacking-agents/numerical-gap-agent.md +46 -0
  226. package/dist/skills/ai-audit/references/hacking-agents/periphery-agent.md +27 -0
  227. package/dist/skills/ai-audit/references/hacking-agents/shared-rules.md +61 -0
  228. package/dist/skills/ai-audit/references/hacking-agents/trust-gap-agent.md +40 -0
  229. package/dist/skills/ai-audit/references/hex-board.md +223 -0
  230. package/dist/skills/ai-audit/references/hex-export.sh +71 -0
  231. package/dist/skills/ai-audit/references/judging.md +75 -0
  232. package/dist/skills/ai-audit/references/report-formatting.md +385 -0
  233. package/dist/skills/ai-audit/references/report-language.md +151 -0
  234. package/dist/skills/ai-audit/references/senior-auditor-sop.md +63 -0
  235. package/dist/skills/generate-report.md +9 -3
  236. package/dist/skills/ingest-aa-report.md +11 -2
  237. package/dist/skills/init-audit.md +104 -2
  238. package/dist/skills/validate-all-findings.md +1 -1
  239. package/dist/skills/validate-finding.md +12 -7
  240. package/dist/skills/write-finding.md +8 -6
  241. package/dist/types/index.d.ts +7 -1
  242. package/dist/types/index.d.ts.map +1 -1
  243. package/package.json +2 -1
  244. package/dashboard/.next/server/app/_not-found.html +0 -1
  245. package/dashboard/.next/server/app/_not-found.meta +0 -6
  246. package/dashboard/.next/server/app/_not-found.rsc +0 -12
  247. package/dashboard/.next/server/app/diagram.html +0 -1
  248. package/dashboard/.next/server/app/diagram.meta +0 -5
  249. package/dashboard/.next/server/app/diagram.rsc +0 -10
  250. package/dashboard/.next/server/app/flows.html +0 -1
  251. package/dashboard/.next/server/app/flows.meta +0 -5
  252. package/dashboard/.next/server/app/flows.rsc +0 -10
  253. package/dashboard/.next/server/chunks/44.js +0 -1
  254. package/dashboard/.next/server/pages/404.html +0 -1
  255. package/dashboard/.next/static/ZYqkgvjnS38aMxfanyctA/_buildManifest.js +0 -1
  256. package/dashboard/.next/static/chunks/1015.3ab89142e5f44120.js +0 -226
  257. package/dashboard/.next/static/chunks/1151.b6ef5c786e587ed7.js +0 -1
  258. package/dashboard/.next/static/chunks/1199.a072929dbec89965.js +0 -148
  259. package/dashboard/.next/static/chunks/1375.d4d2f7fc9c9c2ff1.js +0 -43
  260. package/dashboard/.next/static/chunks/1799.83206776abbbf1fc.js +0 -9
  261. package/dashboard/.next/static/chunks/20154aaa.ccc347c04ab5ad4a.js +0 -1
  262. package/dashboard/.next/static/chunks/2077.7011a570c87aa7b1.js +0 -1
  263. package/dashboard/.next/static/chunks/2166.cc0fabeb2e89b840.js +0 -215
  264. package/dashboard/.next/static/chunks/2325.2c55cb9a6282ae3f.js +0 -24
  265. package/dashboard/.next/static/chunks/2694.92bbe252063e4786.js +0 -1
  266. package/dashboard/.next/static/chunks/275.0d761aa0e5b030b8.js +0 -34
  267. package/dashboard/.next/static/chunks/2781.8536b644a480aede.js +0 -93
  268. package/dashboard/.next/static/chunks/2805.a8d71d2f92bb6ba9.js +0 -1
  269. package/dashboard/.next/static/chunks/3017.e55781da9dd32d37.js +0 -1
  270. package/dashboard/.next/static/chunks/3205-728c260fbb4f89c6.js +0 -2
  271. package/dashboard/.next/static/chunks/3236.dff44fa7961d9d5e.js +0 -1
  272. package/dashboard/.next/static/chunks/3480.9451396ad7ee7613.js +0 -1
  273. package/dashboard/.next/static/chunks/3626.ba1cf848a9f2e93d.js +0 -64
  274. package/dashboard/.next/static/chunks/3865.a432a7910a2f5281.js +0 -90
  275. package/dashboard/.next/static/chunks/3887.c22cbfa3f095826c.js +0 -1
  276. package/dashboard/.next/static/chunks/3924-4a05057b5450abe1.js +0 -1
  277. package/dashboard/.next/static/chunks/3948.fe3c7d758568d98b.js +0 -287
  278. package/dashboard/.next/static/chunks/4728.07d87640a3e7dd0d.js +0 -24
  279. package/dashboard/.next/static/chunks/4787.4e5f6a0e0e40a583.js +0 -23
  280. package/dashboard/.next/static/chunks/5060.baca226af35ed016.js +0 -1
  281. package/dashboard/.next/static/chunks/5284.f949ac90c95ff143.js +0 -1
  282. package/dashboard/.next/static/chunks/5715.1524bcc9591e180b.js +0 -115
  283. package/dashboard/.next/static/chunks/6014.700ae4969b64d728.js +0 -104
  284. package/dashboard/.next/static/chunks/6024.4d23707c65514679.js +0 -79
  285. package/dashboard/.next/static/chunks/6177.e5c84cfc4c0dea51.js +0 -1
  286. package/dashboard/.next/static/chunks/618f8807-547c5614e1318888.js +0 -1
  287. package/dashboard/.next/static/chunks/6434.9481771c33195d29.js +0 -1
  288. package/dashboard/.next/static/chunks/6468.f4a3e8fa6accc6da.js +0 -77
  289. package/dashboard/.next/static/chunks/6540.86f367d7390738d4.js +0 -1
  290. package/dashboard/.next/static/chunks/6549.4d0d472df96429a5.js +0 -1
  291. package/dashboard/.next/static/chunks/690f35d0.3e40ca0930e4bbdb.js +0 -119
  292. package/dashboard/.next/static/chunks/7397-f6f4dddc7a20bfc1.js +0 -1
  293. package/dashboard/.next/static/chunks/7498-ea83cb9e30ec5491.js +0 -1
  294. package/dashboard/.next/static/chunks/7802.89aec9ee11680850.js +0 -80
  295. package/dashboard/.next/static/chunks/7973.8b526f589aca5d84.js +0 -79
  296. package/dashboard/.next/static/chunks/8216.1bead812eb126c35.js +0 -5
  297. package/dashboard/.next/static/chunks/8645.a5ca76f11edc9633.js +0 -1
  298. package/dashboard/.next/static/chunks/8928-60c623ee89d2e6ad.js +0 -1
  299. package/dashboard/.next/static/chunks/9173.2486ffca31131ec5.js +0 -1
  300. package/dashboard/.next/static/chunks/9178.469341860bf8caec.js +0 -1
  301. package/dashboard/.next/static/chunks/9466.e904660d38c03eea.js +0 -1
  302. package/dashboard/.next/static/chunks/9660.84a85811380c5f33.js +0 -1
  303. package/dashboard/.next/static/chunks/9720.67d4d0d15a96d691.js +0 -1
  304. package/dashboard/.next/static/chunks/9811.65e1d080c2d256af.js +0 -1
  305. package/dashboard/.next/static/chunks/app/_not-found/page-548ab392d0e890d1.js +0 -1
  306. package/dashboard/.next/static/chunks/app/access/page-3668562e7464eb5d.js +0 -1
  307. package/dashboard/.next/static/chunks/app/calls/page-d07f5b8664cc8303.js +0 -1
  308. package/dashboard/.next/static/chunks/app/conformance/page-2fede1d7b5f9265d.js +0 -1
  309. package/dashboard/.next/static/chunks/app/diagram/page-b228444265546495.js +0 -1
  310. package/dashboard/.next/static/chunks/app/flows/page-fa67783d8cd79cab.js +0 -1
  311. package/dashboard/.next/static/chunks/app/functions/page-686f0296639133a3.js +0 -1
  312. package/dashboard/.next/static/chunks/app/issues/page-98a298e1c1045c91.js +0 -1
  313. package/dashboard/.next/static/chunks/app/layout-49f2496c7637d931.js +0 -1
  314. package/dashboard/.next/static/chunks/app/notes/page-17af94c67ba79c00.js +0 -1
  315. package/dashboard/.next/static/chunks/app/page-24bac51dfe007c66.js +0 -1
  316. package/dashboard/.next/static/chunks/app/progress/page-427fb18da3afb061.js +0 -1
  317. package/dashboard/.next/static/chunks/app/report/page-796f2f4a8a5ac8f7.js +0 -1
  318. package/dashboard/.next/static/chunks/app/stats/page-db81f600a086f252.js +0 -1
  319. package/dashboard/.next/static/chunks/c7ea4e13.5effeeba6618bdb7.js +0 -1
  320. package/dashboard/.next/static/chunks/framework-cf6f5bdca6ba0184.js +0 -33
  321. package/dashboard/.next/static/chunks/main-63ff429eab01f5bf.js +0 -1
  322. package/dashboard/.next/static/chunks/main-app-9d2f6b8a47133e9b.js +0 -1
  323. package/dashboard/.next/static/chunks/pages/_app-6ad2b50514c24ab4.js +0 -1
  324. package/dashboard/.next/static/chunks/pages/_error-d5eb11c5c4626811.js +0 -1
  325. package/dashboard/.next/static/chunks/webpack-08869f2b18792e51.js +0 -1
  326. package/dashboard/.next/static/css/4a38d8f6f6b7a68f.css +0 -3
  327. package/dashboard/.next/static/media/438aa629764e75f3-s.woff2 +0 -0
  328. package/dashboard/.next/static/media/4c9affa5bc8f420e-s.p.woff2 +0 -0
  329. package/dashboard/.next/static/media/51251f8b9793cdb3-s.woff2 +0 -0
  330. package/dashboard/.next/static/media/875ae681bfde4580-s.woff2 +0 -0
  331. package/dashboard/.next/static/media/cc978ac5ee68c2b6-s.woff2 +0 -0
  332. package/dashboard/.next/static/media/e857b654a2caa584-s.woff2 +0 -0
  333. /package/dashboard/.next/static/{ZYqkgvjnS38aMxfanyctA → z5XBev05xDAkDrxWxAjNu}/_ssgManifest.js +0 -0
@@ -0,0 +1,385 @@
1
+ # Report Formatting
2
+
3
+ ## The one rule
4
+
5
+ **A report must not overstate its own coverage.** Every other rule in this file serves that
6
+ one. The report may print **less** than the scan found — a mistyped marker, a dead agent, a
7
+ pass that never ran — and when it does it says so in words. It may never claim to print
8
+ **more**. A report that shows 14 findings and reads as if it showed all of them is the defect
9
+ this whole design exists to kill.
10
+
11
+ ## Who reads this file
12
+
13
+ Nothing composes a report from this template any more. There are two readers:
14
+
15
+ - **SKILL.md Turn 4 step 5a** — the pass writing its findings into `run-K.md`. It uses the
16
+ **finding block** shape below: title line, location line, `**Description**`, diff `**Fix**`
17
+ block. Those bytes are pasted straight through into the report, so they are written in the
18
+ report's own shape while the pass still has context to spare.
19
+ - **`references/assemble.sh`** — the assembler. Everything below the finding block — the
20
+ banner, the Scope table, the ordering, the Findings List, the Leads section, "Known from
21
+ earlier scans", the disclaimer — is what the assembler emits.
22
+
23
+ **This file settles the shape. `report-language.md` settles the words.** Every sentence a
24
+ human reads in the report — the finding title, the Description, the Lead description, the
25
+ Lead's code smells — is written in Simplified Technical English, and that file holds the rules.
26
+ It is read by the same Turn 4 step 5a that writes the block, and it is in all twelve agent
27
+ bundles. It never reaches the diff in a **Fix** block, the bug-class label inside a key, or an
28
+ identifier on a location line: those three are data, and it says so.
29
+
30
+ **The template is the contract the assembler emits, not a shape a model imitates.** A later
31
+ editor must not re-teach the orchestrator to write it. The orchestrator under context pressure
32
+ is the thing that failed; the step that must not lose a finding holds no model judgment.
33
+
34
+ ## Report Path
35
+
36
+ **Every scan assembles `.hex/ai-audit/runs/{stamp}/full-report.md`** — the whole report,
37
+ banner line down to the disclaimer — at any pass count, with or without flags. That file is
38
+ the report. There is exactly one producer of it, and it is the assembler.
39
+
40
+ `--file-output` makes a **copy** of that file into the current working directory as
41
+ `{project-name}-hex-ai-audit-report-{stamp}.md`, where `{project-name}` is the repo root
42
+ basename and `{stamp}` is `YYYYMMDD-HHMMSS` at scan time. A copy, not a second build —
43
+ nothing regenerates, so the flag cannot collapse the report the way the terminal once did. The
44
+ flag never causes a report to be produced; it only decides whether a copy lands where the
45
+ runner can see it.
46
+
47
+ The `run-K.md` files stay in `.hex/ai-audit/runs/{stamp}/` under the same stamp, so a
48
+ report and the runs that produced it are tied together by eye. They are never copied into the
49
+ working directory — they are memory, not reports.
50
+
51
+ ## Output Format
52
+
53
+ This is what the assembler emits.
54
+
55
+ ````
56
+ # 🔐 Security Review — <ContractName or repo name>
57
+
58
+ ---
59
+
60
+ ## Scope
61
+
62
+ | | |
63
+ | --- | --- |
64
+ | **Mode** | ALL / default / filename |
65
+ | **Files reviewed** | `File1.sol` · `File2.sol`<br>`File3.sol` · `File4.sol` | <!-- every file, 3 per line -->
66
+ | **Confidence threshold (1-100)** | N |
67
+ | **Passes** | 3 | <!-- only when passes > 1 -->
68
+ | **Memory** | 12 records before this scan · 14 after · `a1b2c3d` | <!-- only when memory is on -->
69
+ | **Run files** | ⚠️ 2 findings marked, 1 readable. 1 could not be read. | <!-- only when the structure check disagrees -->
70
+
71
+ ---
72
+
73
+ ## Findings
74
+
75
+ [95] **1. <Title>**
76
+
77
+ `ContractName.functionName` · Confidence: 95 · seen in 2/3 runs · KNOWN (4 scans) <!-- runs segment only when passes > 1; memory segment only when memory is on -->
78
+
79
+ **Description**
80
+ <The vulnerable code pattern and why it is exploitable, in 1 short sentence>
81
+
82
+ **Fix**
83
+
84
+ ```diff
85
+ - vulnerable line(s)
86
+ + fixed line(s)
87
+ ```
88
+
89
+ ---
90
+
91
+ [82] **2. <Title>**
92
+
93
+ `ContractName.functionName` · Confidence: 82
94
+
95
+ **Description**
96
+ <The vulnerable code pattern and why it is exploitable, in 1 short sentence>
97
+
98
+ **Fix**
99
+
100
+ ```diff
101
+ - vulnerable line(s)
102
+ + fixed line(s)
103
+ ```
104
+
105
+ ---
106
+
107
+ < ... all above-threshold findings >
108
+
109
+ ---
110
+
111
+ [60] **3. <Title>**
112
+
113
+ `ContractName.functionName` · Confidence: 60
114
+
115
+ **Description**
116
+ <The vulnerable code pattern and why it is exploitable, in 1 short sentence>
117
+
118
+ ---
119
+
120
+ < ... all below-threshold findings (description only, no Fix block) >
121
+
122
+ ---
123
+
124
+ Findings List
125
+
126
+ | # | Confidence | Title |
127
+ |---|---|---|
128
+ | 1 | [95] | <title> |
129
+ | 2 | [82] | <title> |
130
+ | 3 | [75] | <title> |
131
+ | | | **Below Confidence Threshold** |
132
+ | 4 | [60] | <title> |
133
+
134
+ ---
135
+
136
+ ## Leads
137
+
138
+ _Vulnerability trails with concrete code smells where the full exploit path could not be completed in one analysis pass. These are not false positives — they are high-signal leads for manual review. Not scored._
139
+
140
+ - **<Title>** — `Contract.function` · NEW — Code smells: <missing guard, unsafe arithmetic, etc.> — <1-2 sentence description of the trail and what remains unverified> <!-- memory segment only when memory is on -->
141
+ - **<Title>** — `Contract.function` · seen in 2/3 runs · KNOWN (2 scans) — Code smells: <...> — <1-2 sentence description> <!-- runs segment only when passes > 1 -->
142
+
143
+ ---
144
+
145
+ ## Known from earlier scans
146
+
147
+ <!-- only when memory is on AND the ledger held at least one record — see Memory in the report -->
148
+
149
+ _Recorded by earlier scans of this repo, not raised again by this one. Not re-checked — a record here may be fixed, or may still be live and missed. `.hex/ai-audit/memory.tsv`._
150
+
151
+ | Scans | Kind | Location | Title |
152
+ |---|---|---|---|
153
+ | 4 | FINDING | `Router.swap` | Swap trusts a spot price as an oracle |
154
+ | 2 | LEAD | `Vault.sweep` | Sweep lets the owner take user deposits |
155
+
156
+ ---
157
+
158
+ > ⚠️ This review was performed by an AI assistant. AI analysis can never verify the complete absence of vulnerabilities and no guarantee of security is given. Team security reviews, bug bounty programs, and on-chain monitoring are strongly recommended.
159
+
160
+ ````
161
+
162
+ **Rules describing the output**, all of them held by the assembler and none of them addressed
163
+ to a model:
164
+
165
+ - Findings are sorted by confidence, highest first.
166
+ - A finding at or above the threshold carries a **Description** and a diff **Fix** block. One
167
+ below carries the **Description** only. Nothing in the run file marks which side of the line
168
+ a finding sits on — it is re-derived from the confidence, so there is one source of truth.
169
+ - The **Below Confidence Threshold** separator row is printed whenever at least one finding
170
+ falls below the threshold, and left out when none does. Without it the table runs 1, 2, 3
171
+ with nothing to mark the boundary, so a reader of the table alone cannot tell which findings
172
+ carry no **Fix** block.
173
+ - **Empty cases say so in words, never with an empty table**: `_None — this scan raised no
174
+ findings._` in place of the Findings List, `_None._` under Leads, `**Body missing** — pass K
175
+ raised this finding and wrote no description.` in place of a body.
176
+ - **A `Run files` row appears only when the structure check disagrees.** The model types the
177
+ markers that bound each finding in a run file, so it can mistype one. The assembler counts
178
+ open markers against close markers against readable blocks, and prints the disagreement as a
179
+ Scope row naming how many findings could not be read. Everything readable is still printed
180
+ and the assembler never stops. That row is the one rule at the top made mechanical.
181
+ - **The Scope table's column padding is not part of the shape.** Markdown renders
182
+ `| **Mode** | default |` and a space-padded form identically, and the padding above is for
183
+ reading this file. Content and order are the contract; character widths are not.
184
+
185
+ **The threshold is 75**, set in `judging.md` and printed in the Scope row above. It is named
186
+ in `judging.md` and nowhere else; this file reads it from there. A finding at 75 or above gets
187
+ a description and a **Fix** block, one below 75 gets the description only. A promoted lead
188
+ lands at exactly 75, so it clears — that is why the number is 75.
189
+
190
+ ## The size trigger
191
+
192
+ **More than 20 findings.** At 20 the terminal prints the assembled file word for word; at 21
193
+ it stops printing findings. Findings only — above and below the threshold together. **Leads
194
+ are excluded from the trigger count**, so a scan with 18 findings and 40 leads prints in full.
195
+
196
+ The trigger is on **size, not on flags**. A plain scan of a small contract is unchanged; a
197
+ plain scan of a big one gets the new shape.
198
+
199
+ **Above the trigger the terminal prints four things:** the banner, the Scope table unchanged,
200
+ a **Findings List holding the top 3 findings**, and the path to the full report — then the
201
+ disclaimer. About fifteen lines.
202
+
203
+ The full report is unaffected. Above the trigger, as below it, `full-report.md` holds every
204
+ finding in the shape above — only the terminal changes.
205
+
206
+ **The slice is honest because it is counted.** The table's header reads
207
+ `Findings List — top 3 of {F}`, and that `{F}` is the whole rule:
208
+
209
+ - **A report may print less than the scan found. It may never look like it printed more.**
210
+ A bare list of three findings breaks that — a reader cannot tell a truncated list from a
211
+ complete one. `top 3 of 52` cannot be misread.
212
+ - **The total goes in the header, not a footnote.** A reader who sees the table sees the
213
+ total in the same glance. This is not a style choice; a footnote can be scrolled past.
214
+ - **Three rows, and nothing else is enumerated.** No Leads, no "Known from earlier scans",
215
+ no findings past the third.
216
+
217
+ > **This replaces the older "nothing is enumerated above the trigger" rule**, which forbade
218
+ > every top-N slice. That rule was right that bare truncation lies and wrong to conclude no
219
+ > slice can be honest; a counted one is. A later editor must not restore the blanket ban by
220
+ > citing the half of the argument that survived.
221
+
222
+ **The rows are extracted by shell, never typed.** One `awk` over the assembled file — which is
223
+ already sorted highest-confidence first, so no sort happens in the terminal step. The
224
+ orchestrator has read dozens of findings by then and is the least reliable thing in the room;
225
+ the extractor cannot mis-rank, mis-quote a function name or invent a confidence. The command
226
+ is in `dedup-and-assembly.md` Turn 5 step 3b.
227
+
228
+ **The `Seen` column appears only when the `Passes` row does** — that is, when the pass count is
229
+ above 1. A plain scan's location line carries no `seen in k/N runs`, so the column is dropped
230
+ from the header, the separator and the rows together. A five-column header over four-column
231
+ rows draws as a broken table.
232
+
233
+ **There is no counts summary.** The `{F} findings, {L} leads` line and the
234
+ `100-90 / 89-75 / below 75` split are not printed. `top 3 of {F}` carries the only total the
235
+ moment needs, and the bucket split stood between the reader and the path. The buckets are still
236
+ **computed** as a self-check — `A + B + C` must equal `F`, in every mode, or the assembled file
237
+ is malformed and the scan says so instead of printing a slice of it.
238
+
239
+ The path line names `.hex/ai-audit/runs/{stamp}/full-report.md`, or — when `--file-output`
240
+ was passed — the **copy** and only the copy. Never both: two paths to identical bytes answer a
241
+ question the runner did not ask at the moment they want one filename. That line is the only
242
+ part of the block a flag changes.
243
+
244
+ The exact wording, spacing and order of the block are in `dedup-and-assembly.md` Turn 5 step
245
+ 3b, which is where the terminal is printed.
246
+
247
+ ## The freeze
248
+
249
+ **A small scan with no flags prints what it printed before any of this existed.** Below the
250
+ trigger the terminal prints `full-report.md` word for word — every byte, nothing added,
251
+ nothing cut, no preface — so the freeze is a property of the assembled file.
252
+
253
+ The freeze is a **diff against `golden/plain-full-report.md`**, the frozen plain-path report,
254
+ and it covers the report's **content and order, not its column padding** and not what lands on
255
+ disk. Byte-identity against "today" was tried and is unmeetable: no captured report exists
256
+ anywhere, and today's bytes were composed by a model from a template that contradicted itself.
257
+ The golden file is what replaced it.
258
+
259
+ What the freeze does **not** cover: writing files. Every scan now writes a runs directory and
260
+ assembles a report there, at any pass count. Writing a file is not printing, and the freeze is
261
+ on printed output.
262
+
263
+ ## Memory in the report
264
+
265
+ Everything in this section is printed **only when memory is on** (`--memory`, or a pass count
266
+ above 1). With memory off the assembled file carries no extra rows, no extra segments, no
267
+ extra sections and no dangling `·`, and below the trigger it still diffs clean against the
268
+ golden file.
269
+
270
+ **Segment order on the meta line.** One dot-separated chain, in a fixed order:
271
+
272
+ ```
273
+ `ContractName.functionName` · Confidence: 95 · seen in 2/3 runs · KNOWN (4 scans)
274
+ ```
275
+
276
+ location · confidence · runs · memory. **A segment appears only when it carries information** —
277
+ `seen in k/N runs` needs more than one run, `KNOWN (n scans)` / `NEW` needs memory on. So:
278
+
279
+ | Scan | Meta line |
280
+ |---|---|
281
+ | 1 pass, no flags | `` `Vault.withdraw` · Confidence: 95 `` |
282
+ | 1 pass, `--memory` | `` … · Confidence: 95 · KNOWN (4 scans) `` |
283
+ | 3 passes | `` … · Confidence: 95 · seen in 2/3 runs · KNOWN (4 scans) `` |
284
+
285
+ `KNOWN (4 scans)` and `NEW` are the ledger's own two words, so the report and the file say the
286
+ same thing. **`n` counts this scan.** The tag is derived by the assembler from
287
+ `memory-before.tsv` — the pre-scan photocopy — and `n` is that row's `scans` **plus one**: the
288
+ scan that is printing has just found it again, and the ledger already holds that same number.
289
+ Printing the stored count instead would show a report one behind its own ledger. `NEW` carries
290
+ no count. The tag is **not** carried in the run-file marker: one source, so the report and the
291
+ ledger cannot disagree.
292
+
293
+ The `Scans` column of "Known from earlier scans" is the opposite case and is printed **as
294
+ stored**: this scan did not raise those records, so nothing about them counts up. The
295
+ **Findings List** table is unchanged — it stays `# | Confidence | Title`.
296
+
297
+ Leads carry the same segments as findings, on their own line, because a Lead is a full ledger
298
+ record.
299
+
300
+ **The `Memory` row in Scope.** `<records in the ledger before this scan> records before this
301
+ scan · <records after the merge> after · `<sha>``. The SHA is the one every row of this scan
302
+ wrote; `none` when the repo has no commits. The row states the whole ledger state in one line,
303
+ so the two counts show at a glance what the scan added.
304
+
305
+ **The "before" count is the count after the prune** — the row count of `memory-before.tsv` as
306
+ the merge reads it, not the row count of the file the scan opened. On a scan where the prune
307
+ drops records the two differ, and using the pre-prune number makes the row's own arithmetic
308
+ wrong: a scan that opened 4 records, pruned 1 and added 12 would read `4 records before this
309
+ scan · 15 after`, and a reader counting 4 + 12 gets 16. The prune is already reported on its
310
+ own line (`Pruned N records …`), so the Scope row does not restate it and must not contradict
311
+ it.
312
+
313
+ **Building "Known from earlier scans".** These are the records the ledger already held that
314
+ this scan did **not** raise again. It is **not** a filter on the `status` column — `status`
315
+ stays `KNOWN` once set and never marks the not-found-again case.
316
+
317
+ **The `comm` block that used to sit here is now in `assemble.sh`**, under
318
+ `# Known from earlier scans`. It reads two inputs Turn 5 copies into the runs directory:
319
+ `memory-before.tsv`, the pruned photocopy, and `source-names.tsv`. The keys this scan raised
320
+ come from the assembler's own index of the run files, so no `run-keys.tsv` or `scan-rows.tsv`
321
+ is carried in — the run files are the record. It is computed once per scan, scoped to the
322
+ whole scan and not to the last run, so a bug found in run 1 but not in run 3 does not appear
323
+ here.
324
+
325
+ Each key `comm` returns is one row: `Scans`, `Kind` and `Title` come straight from its row in
326
+ `memory-before.tsv`. `Location` is rebuilt from the key's first two segments, which are stored
327
+ normalised (lower case, hyphenated) and cannot be printed as they are — each segment is looked
328
+ up in `source-names.tsv` and printed as the source spells it, or printed as stored when it is
329
+ not in the map, which happens on a named-file scan where the contract was never assembled into
330
+ `source.md`.
331
+
332
+ Three states, and no fourth:
333
+
334
+ - The ledger held records this scan did not raise → the table above.
335
+ - The ledger held records and this scan raised **every one** → `_None — every record in the
336
+ ledger was raised again by this scan._`
337
+ - Memory is off, or the ledger is empty (first-ever scan) → **no section at all.** A plain
338
+ scan grows no empty headings.
339
+
340
+ The italic line under the heading is load-bearing and is printed verbatim: these records are
341
+ **not re-checked**. A reader must not take the section as "still open", and must not take it
342
+ as "fixed".
343
+
344
+ ## Loop mode in the report
345
+
346
+ Everything in this section is printed **only when the pass count is above 1**. One pass prints
347
+ none of it.
348
+
349
+ **One report per scan.** However many passes ran, the runner sees one combined list. The
350
+ per-pass output is one summary line each (SKILL.md Turn 4 step 5b) and one `run-K.md` in
351
+ `.hex/ai-audit/runs/{stamp}/` — neither is a report.
352
+
353
+ **`seen in k/N runs`.** `k` is how many of this scan's runs raised that group key; `N` is how
354
+ many passes produced a run file. A pass that collapsed produced none, so it is not in `N` — a
355
+ report must not claim a run that never happened. The segment sits between confidence and the
356
+ memory tag, and it is printed on Leads exactly as it is on findings, because a Lead is a full
357
+ ledger record.
358
+
359
+ **`seen in k/N runs` and `KNOWN (n scans)` count different things and must never be mixed.**
360
+ `k/N` counts runs inside **this** scan and is never written to the ledger. `n` counts scans and
361
+ comes from the ledger. A finding first raised by pass 1 of this scan is `NEW` in pass 3 — it is
362
+ this scan's work, however many of its runs saw it.
363
+
364
+ **Which write-up survives the merge.** One winner per key: strongest kind, then highest
365
+ confidence, then the later pass — a later pass read the ledger every earlier pass wrote, so it
366
+ is the better-informed write-up. **Confidence is untouched by the merge.** A finding three runs
367
+ saw keeps the number the runs gave it; repetition is reported on the line, never scored, and
368
+ `seen in 3/3 runs` is there for the reader to weigh.
369
+
370
+ **The `Passes` row in Scope** is composed by the assembler from recorded facts, never written
371
+ as prose. It carries degradation text whenever the scan did not run whole — a report claiming
372
+ 3 passes when one of them ran three-quarters of its agents overstates its own coverage:
373
+
374
+ ```
375
+ | **Passes** | 3 |
376
+ | **Passes** | 3 (pass 2 ran 11/12 agents) |
377
+ | **Passes** | 2 of 3 (pass 3 failed) |
378
+ | **Passes** | 2 of 3 (pass 1 ran 11/12 agents, pass 3 failed) |
379
+ ```
380
+
381
+ The `R of P` prefix comes from counting run files. The dead agent's **name** never appears
382
+ here — it stays in the run file, in the sentence under the `<!--RUN-->` marker.
383
+
384
+ On a 1-pass scan this row is suppressed, so a pass 1 that produced nothing is reported by the
385
+ `Run files` row instead: `⚠️ No pass produced a run file. This scan reviewed nothing.`
@@ -0,0 +1,151 @@
1
+ # Report language — Simplified Technical English
2
+
3
+ Every sentence a human reads in the report obeys this file. The rules are ASD-STE100
4
+ (Simplified Technical English), reduced to the part an audit finding needs.
5
+
6
+ ## Why
7
+
8
+ A report is read by the developer who must fix the code, often at speed, often not in their
9
+ first language. A sentence they must decode twice costs the fix, and the bug stays in the
10
+ code. The scan is only as good as the sentence that delivers it.
11
+
12
+ Short words do not make a finding less rigorous. The proof is the diff in the **Fix** block
13
+ and the location on the meta line. The sentence exists to say what breaks and who breaks it.
14
+
15
+ ## What this covers
16
+
17
+ Four pieces of text, and no others:
18
+
19
+ - the finding **title**
20
+ - the **Description** sentence
21
+ - the **Lead** description
22
+ - the **code smells** list on a Lead
23
+
24
+ ## What it must never touch
25
+
26
+ These are data, not prose. Rewriting one of them for readability breaks the scan:
27
+
28
+ - **Solidity identifiers** — contract, function, variable and event names. They are printed as
29
+ the source spells them. `withdrawToNativeChain` is never softened to `withdraw to chain`.
30
+ - **The diff inside a Fix block.** It is code. It is pasted verbatim from the agent that wrote
31
+ it, and `judging.md` and `dedup-and-assembly.md` both forbid paraphrase there.
32
+ - **The bug-class label** (`zero-abort-address`). It is the third segment of a memory key.
33
+ The same bug under a plainer word is a second ledger record, so memory remembers it twice
34
+ and recognises it never. Labels are chosen by the rules in `dedup-and-assembly.md` step 1,
35
+ never by this file.
36
+ - **Fixed strings the assembler prints** — the banner, the Scope table headers, the italic
37
+ lines under Leads and "Known from earlier scans", the disclaimer. They are in
38
+ `assemble.sh` and they are already written.
39
+
40
+ ## The rules
41
+
42
+ 1. **One sentence, one idea.** A Description is one sentence. A Lead description is one or
43
+ two. Never three.
44
+ 2. **Twenty-five words is the ceiling.** Count them. Over the ceiling means two ideas in one
45
+ sentence — cut it or split it.
46
+ 3. **Active voice, and name the actor.** Who does this? Write that word first.
47
+ - No: `Funds can be drained due to a missing check.`
48
+ - Yes: `Any caller can take all the tokens, because the function checks no caller.`
49
+ 4. **Simple present tense.** The code does this today. Not `would be able to`, not
50
+ `could potentially`. If the path is uncertain it is a Lead, and the Lead says which step
51
+ is unproven.
52
+ 5. **No `-ing` clauses.** They hide the actor and the order of events. Use `that`, `so`, or a
53
+ second sentence.
54
+ - No: `Missing access control allowing anyone to drain the vault.`
55
+ - Yes: `The function has no access control, so any caller can take all the tokens.`
56
+ 6. **Keep the articles.** `the`, `a`, `an`. Telegraphic style — `Function reverts on zero
57
+ amount` — is not shorter to read, only shorter to type.
58
+ 7. **Three nouns in a row is the limit.** Break a longer stack with `of`, `for` or `in`.
59
+ - No: `cross-chain message replay protection gap`
60
+ - Yes: `the contract does not stop a replay of a cross-chain message`
61
+ 8. **One word for one thing, every time.** Pick `token`, or pick `asset`, and use that word
62
+ in the title, the Description and the fix. A synonym reads as a second thing.
63
+ 9. **No metaphor, no idiom, no slang.** See the table below. A metaphor is a word the reader
64
+ must translate before they can act.
65
+ 10. **Say what happens, not how bad it is.** `catastrophic`, `critical`, `severe` and
66
+ `trivially` carry no information — the confidence number and the Fix block carry it. Write
67
+ the effect: `the caller keeps the tokens and the pool keeps the debt`.
68
+ 11. **Positive statements. No double negatives.** `The check is absent` beats `the check is
69
+ not present`.
70
+ 12. **Event order is sentence order.** Cause, then effect. `The price comes from the pool
71
+ balance, so an attacker who moves the balance moves the price.`
72
+ 13. **A title is one clause, twelve words or fewer,** present tense, active, and it names the
73
+ defect or its effect. `Swap trusts a spot price as an oracle.`
74
+ Not `Oracle manipulation vulnerability in swap functionality`.
75
+
76
+ ## Words to replace
77
+
78
+ Left column: the wording to keep out of the report. Right column: what the report prints.
79
+
80
+ | Do not write | Write |
81
+ | --- | --- |
82
+ | burns the funds | sends the tokens to an address that cannot spend them |
83
+ | bricks the contract | makes the function fail for every caller, forever |
84
+ | rug / rugpull | the owner takes the user deposits |
85
+ | griefing | an attacker makes the function fail for other users |
86
+ | footgun | (delete the word and name the defect) |
87
+ | silently swallows the error | ignores the error |
88
+ | DoS / denial of service | blocks every caller |
89
+ | attack surface / attack vector | path |
90
+ | malicious actor / bad actor | an attacker |
91
+ | leverages / utilizes | uses |
92
+ | is able to | can |
93
+ | in order to | to |
94
+ | arbitrary value | any value the caller chooses |
95
+ | stale price | old price |
96
+ | sanity check | check |
97
+ | happy path | the normal path |
98
+ | atomically | in one transaction |
99
+ | trustlessly / permissionlessly | (delete, or name who may call) |
100
+ | non-zero | more than zero |
101
+ | cascading failures | (name each failure) |
102
+ | exponentially / trivially / catastrophically | (delete) |
103
+ | edge case | (name the input or the state) |
104
+
105
+ ## Technical names stay
106
+
107
+ STE-100 keeps technical names, and a security report cannot work without them:
108
+ `reentrancy`, `slippage`, `oracle`, `revert`, `overflow`, `rounding`, `allowance`, `nonce`,
109
+ `slot`, `delegatecall`. Use them. They are precise and the reader who fixes Solidity knows
110
+ them.
111
+
112
+ The rule is what goes **around** them: name the mechanism once with its technical name, then
113
+ say in plain words what the attacker gets.
114
+
115
+ - No: `Classic CEI violation enabling reentrant drainage of the vault.`
116
+ - Yes: `The function sends ETH before it lowers the balance, so a reentrant call withdraws
117
+ the same deposit twice.`
118
+
119
+ ## Worked examples
120
+
121
+ Before, and after. The code the sentence describes did not change.
122
+
123
+ **One**
124
+
125
+ - Before: `Improper validation of the abort address results in a catastrophic loss of user
126
+ funds via burning to the zero address.`
127
+ - After: `The function accepts a zero abort address, so a failed transfer sends the tokens to
128
+ an address that nobody controls.`
129
+
130
+ **Two**
131
+
132
+ - Before: `Lack of slippage protection in the swap path exposes users to sandwich attacks,
133
+ potentially leading to significant value extraction by MEV searchers.`
134
+ - After: `The swap sets the minimum output to zero, so an attacker who trades before and
135
+ after the victim keeps most of the output.`
136
+
137
+ **Three — a Lead**
138
+
139
+ - Before: `Potential accounting inconsistency stemming from asymmetric fee handling on
140
+ deposit/withdraw flows warranting further investigation.`
141
+ - After: `The deposit takes the fee from the amount, and the withdrawal takes it from the
142
+ balance. We did not find the input that makes the two disagree.`
143
+
144
+ ## Self-check before you write the block
145
+
146
+ Four questions. Any `no` means rewrite the sentence, not the code:
147
+
148
+ - Does the sentence name **who** acts and **what** they get?
149
+ - Is it one sentence, twenty-five words or fewer, with no `-ing` clause?
150
+ - Is every word in it a word the reader does not have to translate?
151
+ - Are the identifiers, the label and the diff exactly as the source and the agent wrote them?
@@ -0,0 +1,63 @@
1
+ # Senior Auditor's Mindset
2
+
3
+ This is how a senior auditor thinks. Pattern-matching catches the obvious bugs — your specialty file teaches that. The high-value bugs, the ones everyone else misses, come from HOW you reason about code, not from WHAT bugs you know.
4
+
5
+ The senior auditor's edge is not "knowing more bug patterns" — it is having internalized mental tools they reach for instinctively when something feels off, when a path seems clean, or when a conclusion comes too quickly.
6
+
7
+ This file gives you three tools. They are not steps. You reach for the right one the moment the trigger fires. They are how you think, not text you write: do not put them in your reply, which holds only your FINDING and LEAD blocks. Use them. Trust your discomfort.
8
+
9
+ A finding is not real until you've traced the attack with concrete values. You are an attacker, not a defender — when you find a bug, deepen the attack; never argue yourself out of one.
10
+
11
+ ---
12
+
13
+ ## 1. The Feynman test (FIRST — use it before anything else)
14
+
15
+ **This is the first tool. Apply it the moment you open any new function or contract — before you reason about anything else.** Code you have not Feynman'd is code you have not actually understood.
16
+
17
+ When you read code, STOP and ask: "Can I explain what this function does to someone who doesn't know Solidity?"
18
+
19
+ Try it. In plain words. The places where your explanation gets fuzzy — where you reach for Solidity jargon instead of plain meaning — are where you're papering over an assumption. That's where bugs hide.
20
+
21
+ Example: you read `_handleFeeTransfer(zrc20, fee)` and your explanation comes out as "it transfers the fee." That's not Feynman. Feynman is: "it picks up the protocol's commission off the user's payment and moves it to the treasury wallet." Now keep going: what if the payment is in ETH and the function uses an ERC20 method? Your plain-English explanation breaks. Bug.
22
+
23
+ A senior auditor doesn't trust their understanding until they can explain it without the safety net of technical vocabulary.
24
+
25
+ ---
26
+
27
+ ## 2. Socratic questioning
28
+
29
+ For every line of code, ask: why is this here? What does it assume? What happens if the assumption breaks?
30
+
31
+ Don't accept "because that's how it's written" as an answer. Don't accept "the function name says so" as an answer. Drill until you reach the implicit belief the code rests on. The first answer is usually a restatement. The actual assumption is two or three "whys" deeper.
32
+
33
+ Example: `if (zrc20 != _ETH_ADDRESS_) IERC20(zrc20).transferFrom(msg.sender, address(this), amount);`
34
+ - Why is `zrc20 != _ETH_ADDRESS_` checked? → because ETH isn't transferable via transferFrom.
35
+ - Why is there no else branch? → because the developer assumed ETH arrives via `msg.value`.
36
+ - Where is `msg.value` enforced to equal `amount` for the ETH path? → **nowhere**. Bug.
37
+
38
+ A senior auditor accepts no "because" without examining it.
39
+
40
+ ---
41
+
42
+ ## 3. Inversion
43
+
44
+ Every clean path gets a backward pass. After you understand what the code IS supposed to do, ask: how would I make it NOT do that?
45
+
46
+ Same code, attacker's eye instead of developer's eye. The developer asks "does this work?" The attacker asks "how do I break this?" Read every check and ask "what value slips past it?" Read every state update and ask "what state am I in just before this?"
47
+
48
+ A senior auditor never reads code only forward.
49
+
50
+ ---
51
+
52
+ ## When to reach for which tool
53
+
54
+ You don't apply these in order — except Feynman, which is always first. You reach for what the moment calls for:
55
+
56
+ - Opening any new function or contract → **Feynman** (always — before anything else)
57
+ - Trying to understand a line you don't yet → **Socratic**
58
+ - Something looks too clean → **Inversion**
59
+ - You reached a "bug" conclusion → amplify the attack (chain it, find more victims, lower the precondition cost — do NOT refute it)
60
+
61
+ The tools are how you keep yourself honest. Without them, you fall into the trap of every junior auditor: trusting your first read, accepting code that "looks right," moving on when something feels off.
62
+
63
+ Trust your discomfort. Reach for the tool. Don't stop until the discomfort has a name.
@@ -56,8 +56,8 @@ Each section has a defined **input signature** — the exact set of data it deri
56
56
 
57
57
  | Section | Input signature (hash over) |
58
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` |
59
+ | `executive_summary` | severity + resolution histograms, `stats.totals.nsloc`, all `settings.report.*` fields, and the `overview.md` bytes (the synopsis derives from it); differential: also `diff.json` `base_commit` / `head_commit` / `summary` |
60
+ | `audited_files` | the per-file LoC results for every `project.scope` file (differential: every changed file, with its +/- counts), `repository_url`, `initial_commit` |
61
61
  | `summary_of_findings` | the ordered synced-findings list: `(id, title, severity, resolution)` each |
62
62
  | `system_overview` | `overview.md`, `access-control.json`, `deps.json` bytes |
63
63
  | `findings` | the synced-findings full content: `(title, severity, description, code blocks, recommendation, resolution, update_from_client, root_cause.locations)` each |
@@ -85,7 +85,7 @@ Read `<output_dir>/config.json`. Look under `settings.report.*` for:
85
85
  - `final_commit` — commit hash after fixes (defaults to `initial_commit` if no remediation cycle).
86
86
  - `initial_report_date` — date the initial report was delivered (e.g. `May 22, 2026`).
87
87
  - `final_report_date` — date the final report was delivered (defaults to `initial_report_date`).
88
- - `audit_type` — defaults to `Security Review`.
88
+ - `audit_type` — defaults to `Security Review`. A differential audit (`project.mode: "diff"`) is initialized with `Differential Review`.
89
89
  - `doc_assessment` — `High` / `Medium` / `Low`.
90
90
  - `test_assessment` — `High` / `Medium` / `Low`.
91
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.
@@ -138,6 +138,8 @@ Style hints:
138
138
 
139
139
  Write to `executive_summary.txt` **and** `01-executive-summary.tex`.
140
140
 
141
+ **Differential audit** (`config.json` → `project.mode` is `diff`): the review covers the changes between two commits, and the first paragraph must say so. Use `<SCOPE_DESCRIPTION>` = `changes to <scope description> between commit \href{<REPOSITORY_URL>/commit/<BASE_COMMIT>}{\texttt{<BASE_SHORT>}} and commit \href{<REPOSITORY_URL>/commit/<HEAD_COMMIT>}{\texttt{<HEAD_SHORT>}}` (commits from `.hex/diff.json`, short = first 7 characters). Replace the `<TOTAL_NSLOC>` sentence with the size of the change: `\textbf{The audit comprises} <ADDITIONS> added and <DELETIONS> removed lines of Solidity code across <FILES_CHANGED> files` (from `diff.json` `summary`). Everything else in the section is unchanged.
142
+
141
143
  ```latex
142
144
  \pagebreak \vspace*{0cm}
143
145
  \sectioncolor
@@ -222,6 +224,8 @@ Substitutions:
222
224
 
223
225
  Write to `audited_files.txt` **and** `02-audited-files.tex`.
224
226
 
227
+ **Differential audit:** the rows are the files in `.hex/diff.json` `files` with status `added`, `modified` or `renamed` (not `deleted`), counted at the head commit, instead of every `project.scope` file. Keep the same columns; the table still describes the audited files at head. `<INITIAL_COMMIT>` in the links is the head commit.
228
+
225
229
  Compute per-file line counts from each scope file. For each in-scope file in `config.json.project.scope`:
226
230
 
227
231
  - Read the file. Count:
@@ -392,6 +396,8 @@ If the finding has multiple `root_cause.locations[]`, list them in the **File(s)
392
396
 
393
397
  **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
398
 
399
+ Finding descriptions are authored already backticked and structured (identifiers in backticks, functions as `` `name(...)` `` which the markdown→LaTeX rule turns into `\texttt{name(...)}`, and short expected/flaw/impact paragraphs). Preserve that: render the paragraph breaks as-is (blank lines between paragraphs), do not collapse a multi-paragraph description into one block.
400
+
395
401
  **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
402
  - No specific source line numbers ("line 56", "on lines 43, 55") in `description` / `recommendation` — code is shown via `snippet` instead.
397
403
  - No cross-references to other findings by hex id (`H-NNN`) or number/title — each finding stands alone; report readers have no hex ids.