hex-audit 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +105 -0
- package/DEMO.md +141 -0
- package/README.md +378 -0
- package/dashboard/.next/BUILD_ID +1 -0
- package/dashboard/.next/app-build-manifest.json +99 -0
- package/dashboard/.next/app-path-routes-manifest.json +1 -0
- package/dashboard/.next/build-manifest.json +32 -0
- package/dashboard/.next/cache/.tsbuildinfo +1 -0
- package/dashboard/.next/cache/webpack/client-production/0.pack +0 -0
- package/dashboard/.next/cache/webpack/client-production/index.pack +0 -0
- package/dashboard/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/dashboard/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/dashboard/.next/cache/webpack/server-production/0.pack +0 -0
- package/dashboard/.next/cache/webpack/server-production/1.pack +0 -0
- package/dashboard/.next/cache/webpack/server-production/2.pack +0 -0
- package/dashboard/.next/cache/webpack/server-production/index.pack +0 -0
- package/dashboard/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/dashboard/.next/export-marker.json +1 -0
- package/dashboard/.next/images-manifest.json +1 -0
- package/dashboard/.next/next-minimal-server.js.nft.json +1 -0
- package/dashboard/.next/next-server.js.nft.json +1 -0
- package/dashboard/.next/package.json +1 -0
- package/dashboard/.next/prerender-manifest.js +1 -0
- package/dashboard/.next/prerender-manifest.json +1 -0
- package/dashboard/.next/react-loadable-manifest.json +300 -0
- package/dashboard/.next/required-server-files.json +1 -0
- package/dashboard/.next/routes-manifest.json +1 -0
- package/dashboard/.next/server/app/_not-found/page.js +1 -0
- package/dashboard/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/_not-found.html +1 -0
- package/dashboard/.next/server/app/_not-found.meta +6 -0
- package/dashboard/.next/server/app/_not-found.rsc +12 -0
- package/dashboard/.next/server/app/access/page.js +1 -0
- package/dashboard/.next/server/app/access/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/access/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/access.html +1 -0
- package/dashboard/.next/server/app/access.meta +5 -0
- package/dashboard/.next/server/app/access.rsc +8 -0
- package/dashboard/.next/server/app/api/code/route.js +1 -0
- package/dashboard/.next/server/app/api/code/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/flows/route.js +1 -0
- package/dashboard/.next/server/app/api/flows/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/flows.body +1 -0
- package/dashboard/.next/server/app/api/flows.meta +1 -0
- package/dashboard/.next/server/app/api/github-status/route.js +1 -0
- package/dashboard/.next/server/app/api/github-status/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/issues/[id]/move/route.js +1 -0
- package/dashboard/.next/server/app/api/issues/[id]/move/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/issues/[id]/route.js +1 -0
- package/dashboard/.next/server/app/api/issues/[id]/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/mermaid/route.js +1 -0
- package/dashboard/.next/server/app/api/mermaid/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/progress/route.js +1 -0
- package/dashboard/.next/server/app/api/progress/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/watch/route.js +3 -0
- package/dashboard/.next/server/app/api/watch/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/calls/page.js +1 -0
- package/dashboard/.next/server/app/calls/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/calls/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/calls.html +1 -0
- package/dashboard/.next/server/app/calls.meta +5 -0
- package/dashboard/.next/server/app/calls.rsc +8 -0
- package/dashboard/.next/server/app/conformance/page.js +1 -0
- package/dashboard/.next/server/app/conformance/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/conformance/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/conformance.html +1 -0
- package/dashboard/.next/server/app/conformance.meta +5 -0
- package/dashboard/.next/server/app/conformance.rsc +8 -0
- package/dashboard/.next/server/app/diagram/page.js +1 -0
- package/dashboard/.next/server/app/diagram/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/diagram/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/diagram.html +1 -0
- package/dashboard/.next/server/app/diagram.meta +5 -0
- package/dashboard/.next/server/app/diagram.rsc +10 -0
- package/dashboard/.next/server/app/flows/page.js +1 -0
- package/dashboard/.next/server/app/flows/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/flows/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/flows.html +1 -0
- package/dashboard/.next/server/app/flows.meta +5 -0
- package/dashboard/.next/server/app/flows.rsc +10 -0
- package/dashboard/.next/server/app/functions/page.js +1 -0
- package/dashboard/.next/server/app/functions/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/functions/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/functions.html +1 -0
- package/dashboard/.next/server/app/functions.meta +5 -0
- package/dashboard/.next/server/app/functions.rsc +8 -0
- package/dashboard/.next/server/app/icon.svg/route.js +12 -0
- package/dashboard/.next/server/app/icon.svg/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/icon.svg.body +18 -0
- package/dashboard/.next/server/app/icon.svg.meta +1 -0
- package/dashboard/.next/server/app/index.html +1 -0
- package/dashboard/.next/server/app/index.meta +5 -0
- package/dashboard/.next/server/app/index.rsc +9 -0
- package/dashboard/.next/server/app/issues/page.js +1 -0
- package/dashboard/.next/server/app/issues/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/issues/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/issues.html +1 -0
- package/dashboard/.next/server/app/issues.meta +5 -0
- package/dashboard/.next/server/app/issues.rsc +8 -0
- package/dashboard/.next/server/app/page.js +20 -0
- package/dashboard/.next/server/app/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/progress/page.js +1 -0
- package/dashboard/.next/server/app/progress/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/progress/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/progress.html +1 -0
- package/dashboard/.next/server/app/progress.meta +5 -0
- package/dashboard/.next/server/app/progress.rsc +8 -0
- package/dashboard/.next/server/app/stats/page.js +1 -0
- package/dashboard/.next/server/app/stats/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/stats/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/stats.html +1 -0
- package/dashboard/.next/server/app/stats.meta +5 -0
- package/dashboard/.next/server/app/stats.rsc +8 -0
- package/dashboard/.next/server/app-paths-manifest.json +22 -0
- package/dashboard/.next/server/chunks/431.js +1 -0
- package/dashboard/.next/server/chunks/557.js +1 -0
- package/dashboard/.next/server/chunks/645.js +6 -0
- package/dashboard/.next/server/chunks/649.js +2 -0
- package/dashboard/.next/server/chunks/665.js +13 -0
- package/dashboard/.next/server/chunks/786.js +12 -0
- package/dashboard/.next/server/chunks/818.js +6 -0
- package/dashboard/.next/server/chunks/916.js +2 -0
- package/dashboard/.next/server/chunks/font-manifest.json +1 -0
- package/dashboard/.next/server/font-manifest.json +1 -0
- package/dashboard/.next/server/functions-config-manifest.json +1 -0
- package/dashboard/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/dashboard/.next/server/middleware-build-manifest.js +1 -0
- package/dashboard/.next/server/middleware-manifest.json +6 -0
- package/dashboard/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/dashboard/.next/server/next-font-manifest.js +1 -0
- package/dashboard/.next/server/next-font-manifest.json +1 -0
- package/dashboard/.next/server/pages/404.html +1 -0
- package/dashboard/.next/server/pages/500.html +1 -0
- package/dashboard/.next/server/pages/_app.js +1 -0
- package/dashboard/.next/server/pages/_app.js.nft.json +1 -0
- package/dashboard/.next/server/pages/_document.js +1 -0
- package/dashboard/.next/server/pages/_document.js.nft.json +1 -0
- package/dashboard/.next/server/pages/_error.js +1 -0
- package/dashboard/.next/server/pages/_error.js.nft.json +1 -0
- package/dashboard/.next/server/pages-manifest.json +1 -0
- package/dashboard/.next/server/server-reference-manifest.js +1 -0
- package/dashboard/.next/server/server-reference-manifest.json +1 -0
- package/dashboard/.next/server/webpack-runtime.js +1 -0
- package/dashboard/.next/static/0IZAlhEwk5-v4myUvWKBd/_buildManifest.js +1 -0
- package/dashboard/.next/static/0IZAlhEwk5-v4myUvWKBd/_ssgManifest.js +1 -0
- package/dashboard/.next/static/chunks/1.8868c4d131111be7.js +36 -0
- package/dashboard/.next/static/chunks/1015.3ab89142e5f44120.js +226 -0
- package/dashboard/.next/static/chunks/1151.b6ef5c786e587ed7.js +1 -0
- package/dashboard/.next/static/chunks/1199.a072929dbec89965.js +148 -0
- package/dashboard/.next/static/chunks/1375.d4d2f7fc9c9c2ff1.js +43 -0
- package/dashboard/.next/static/chunks/1799.83206776abbbf1fc.js +9 -0
- package/dashboard/.next/static/chunks/20154aaa.ccc347c04ab5ad4a.js +1 -0
- package/dashboard/.next/static/chunks/2077.7011a570c87aa7b1.js +1 -0
- package/dashboard/.next/static/chunks/2166.cc0fabeb2e89b840.js +215 -0
- package/dashboard/.next/static/chunks/2291.85a70cb0c228157b.js +29 -0
- package/dashboard/.next/static/chunks/2325.2c55cb9a6282ae3f.js +24 -0
- package/dashboard/.next/static/chunks/2383.62c035a052272594.js +1 -0
- package/dashboard/.next/static/chunks/2694.92bbe252063e4786.js +1 -0
- package/dashboard/.next/static/chunks/275.0d761aa0e5b030b8.js +34 -0
- package/dashboard/.next/static/chunks/2781.8536b644a480aede.js +93 -0
- package/dashboard/.next/static/chunks/2805.a8d71d2f92bb6ba9.js +1 -0
- package/dashboard/.next/static/chunks/2879.51436986f93981d9.js +1 -0
- package/dashboard/.next/static/chunks/3017.e55781da9dd32d37.js +1 -0
- package/dashboard/.next/static/chunks/3205-728c260fbb4f89c6.js +2 -0
- package/dashboard/.next/static/chunks/3236.dff44fa7961d9d5e.js +1 -0
- package/dashboard/.next/static/chunks/3480.9451396ad7ee7613.js +1 -0
- package/dashboard/.next/static/chunks/3626.ba1cf848a9f2e93d.js +64 -0
- package/dashboard/.next/static/chunks/3865.a432a7910a2f5281.js +90 -0
- package/dashboard/.next/static/chunks/3887.c22cbfa3f095826c.js +1 -0
- package/dashboard/.next/static/chunks/3924-4a05057b5450abe1.js +1 -0
- package/dashboard/.next/static/chunks/3948.fe3c7d758568d98b.js +287 -0
- package/dashboard/.next/static/chunks/4728.07d87640a3e7dd0d.js +24 -0
- package/dashboard/.next/static/chunks/4787.4e5f6a0e0e40a583.js +23 -0
- package/dashboard/.next/static/chunks/5060.baca226af35ed016.js +1 -0
- package/dashboard/.next/static/chunks/5284.f949ac90c95ff143.js +1 -0
- package/dashboard/.next/static/chunks/5715.1524bcc9591e180b.js +115 -0
- package/dashboard/.next/static/chunks/6014.700ae4969b64d728.js +104 -0
- package/dashboard/.next/static/chunks/6024.4d23707c65514679.js +79 -0
- package/dashboard/.next/static/chunks/6052.033a6f1013c666eb.js +141 -0
- package/dashboard/.next/static/chunks/6177.e5c84cfc4c0dea51.js +1 -0
- package/dashboard/.next/static/chunks/618f8807-547c5614e1318888.js +1 -0
- package/dashboard/.next/static/chunks/6434.9481771c33195d29.js +1 -0
- package/dashboard/.next/static/chunks/6468.f4a3e8fa6accc6da.js +77 -0
- package/dashboard/.next/static/chunks/6540.86f367d7390738d4.js +1 -0
- package/dashboard/.next/static/chunks/6549.4d0d472df96429a5.js +1 -0
- package/dashboard/.next/static/chunks/690f35d0.3e40ca0930e4bbdb.js +119 -0
- package/dashboard/.next/static/chunks/7020.831e16e26d91abc1.js +166 -0
- package/dashboard/.next/static/chunks/7397-f6f4dddc7a20bfc1.js +1 -0
- package/dashboard/.next/static/chunks/7498-ea83cb9e30ec5491.js +1 -0
- package/dashboard/.next/static/chunks/7802.89aec9ee11680850.js +80 -0
- package/dashboard/.next/static/chunks/7973.8b526f589aca5d84.js +79 -0
- package/dashboard/.next/static/chunks/7a04ac15.1c6cea694301806c.js +62 -0
- package/dashboard/.next/static/chunks/8216.1bead812eb126c35.js +5 -0
- package/dashboard/.next/static/chunks/8233babc.780b8e272eda298f.js +92 -0
- package/dashboard/.next/static/chunks/8452-e616b5f43bceb95f.js +13 -0
- package/dashboard/.next/static/chunks/8645.a5ca76f11edc9633.js +1 -0
- package/dashboard/.next/static/chunks/8928-60c623ee89d2e6ad.js +1 -0
- package/dashboard/.next/static/chunks/9173.2486ffca31131ec5.js +1 -0
- package/dashboard/.next/static/chunks/9178.469341860bf8caec.js +1 -0
- package/dashboard/.next/static/chunks/9466.e904660d38c03eea.js +1 -0
- package/dashboard/.next/static/chunks/9660.84a85811380c5f33.js +1 -0
- package/dashboard/.next/static/chunks/9717.6cf5c8c89403b651.js +1 -0
- package/dashboard/.next/static/chunks/9720.67d4d0d15a96d691.js +1 -0
- package/dashboard/.next/static/chunks/9811.65e1d080c2d256af.js +1 -0
- package/dashboard/.next/static/chunks/app/_not-found/page-548ab392d0e890d1.js +1 -0
- package/dashboard/.next/static/chunks/app/access/page-3668562e7464eb5d.js +1 -0
- package/dashboard/.next/static/chunks/app/calls/page-d07f5b8664cc8303.js +1 -0
- package/dashboard/.next/static/chunks/app/conformance/page-2fede1d7b5f9265d.js +1 -0
- package/dashboard/.next/static/chunks/app/diagram/page-b228444265546495.js +1 -0
- package/dashboard/.next/static/chunks/app/flows/page-fa67783d8cd79cab.js +1 -0
- package/dashboard/.next/static/chunks/app/functions/page-686f0296639133a3.js +1 -0
- package/dashboard/.next/static/chunks/app/issues/page-dc110d4cc0a5c398.js +1 -0
- package/dashboard/.next/static/chunks/app/layout-e7b50543ba216d12.js +1 -0
- package/dashboard/.next/static/chunks/app/page-a0f25953d4457935.js +1 -0
- package/dashboard/.next/static/chunks/app/progress/page-f07ac39d1d27b480.js +1 -0
- package/dashboard/.next/static/chunks/app/stats/page-db81f600a086f252.js +1 -0
- package/dashboard/.next/static/chunks/b7167ec1.7afbab6f609e3326.js +153 -0
- package/dashboard/.next/static/chunks/c7ea4e13.5effeeba6618bdb7.js +1 -0
- package/dashboard/.next/static/chunks/framework-cf6f5bdca6ba0184.js +33 -0
- package/dashboard/.next/static/chunks/main-70c6d841ad572657.js +1 -0
- package/dashboard/.next/static/chunks/main-app-9d2f6b8a47133e9b.js +1 -0
- package/dashboard/.next/static/chunks/pages/_app-6ad2b50514c24ab4.js +1 -0
- package/dashboard/.next/static/chunks/pages/_error-d5eb11c5c4626811.js +1 -0
- package/dashboard/.next/static/chunks/polyfills-78c92fac7aa8fdd8.js +1 -0
- package/dashboard/.next/static/chunks/webpack-08869f2b18792e51.js +1 -0
- package/dashboard/.next/static/css/e6cb67f77f13ae8e.css +3 -0
- package/dashboard/.next/static/media/0aa834ed78bf6d07-s.woff2 +0 -0
- package/dashboard/.next/static/media/438aa629764e75f3-s.woff2 +0 -0
- package/dashboard/.next/static/media/4c9affa5bc8f420e-s.p.woff2 +0 -0
- package/dashboard/.next/static/media/51251f8b9793cdb3-s.woff2 +0 -0
- package/dashboard/.next/static/media/67957d42bae0796d-s.woff2 +0 -0
- package/dashboard/.next/static/media/875ae681bfde4580-s.woff2 +0 -0
- package/dashboard/.next/static/media/886030b0b59bc5a7-s.woff2 +0 -0
- package/dashboard/.next/static/media/939c4f875ee75fbb-s.woff2 +0 -0
- package/dashboard/.next/static/media/bb3ef058b751a6ad-s.p.woff2 +0 -0
- package/dashboard/.next/static/media/cc978ac5ee68c2b6-s.woff2 +0 -0
- package/dashboard/.next/static/media/e857b654a2caa584-s.woff2 +0 -0
- package/dashboard/.next/static/media/f911b923c6adde36-s.woff2 +0 -0
- package/dashboard/.next/trace +80 -0
- package/dashboard/.next/types/app/access/page.ts +79 -0
- package/dashboard/.next/types/app/api/code/route.ts +343 -0
- package/dashboard/.next/types/app/api/flows/route.ts +343 -0
- package/dashboard/.next/types/app/api/github-status/route.ts +343 -0
- package/dashboard/.next/types/app/api/issues/[id]/move/route.ts +343 -0
- package/dashboard/.next/types/app/api/issues/[id]/route.ts +343 -0
- package/dashboard/.next/types/app/api/mermaid/route.ts +343 -0
- package/dashboard/.next/types/app/api/progress/route.ts +343 -0
- package/dashboard/.next/types/app/api/watch/route.ts +343 -0
- package/dashboard/.next/types/app/calls/page.ts +79 -0
- package/dashboard/.next/types/app/conformance/page.ts +79 -0
- package/dashboard/.next/types/app/diagram/page.ts +79 -0
- package/dashboard/.next/types/app/flows/page.ts +79 -0
- package/dashboard/.next/types/app/functions/page.ts +79 -0
- package/dashboard/.next/types/app/issues/page.ts +79 -0
- package/dashboard/.next/types/app/page.ts +79 -0
- package/dashboard/.next/types/app/progress/page.ts +79 -0
- package/dashboard/.next/types/app/stats/page.ts +79 -0
- package/dashboard/.next/types/package.json +1 -0
- package/dashboard/app/access/AccessClient.tsx +402 -0
- package/dashboard/app/access/ReadOnlyFunctions.tsx +114 -0
- package/dashboard/app/access/page.tsx +118 -0
- package/dashboard/app/api/code/route.ts +35 -0
- package/dashboard/app/api/flows/route.ts +28 -0
- package/dashboard/app/api/github-status/route.ts +23 -0
- package/dashboard/app/api/issues/[id]/move/route.ts +74 -0
- package/dashboard/app/api/issues/[id]/route.ts +109 -0
- package/dashboard/app/api/mermaid/route.ts +25 -0
- package/dashboard/app/api/progress/route.ts +36 -0
- package/dashboard/app/api/watch/route.ts +52 -0
- package/dashboard/app/calls/CallsClient.tsx +170 -0
- package/dashboard/app/calls/page.tsx +50 -0
- package/dashboard/app/conformance/ConformanceTable.tsx +214 -0
- package/dashboard/app/conformance/page.tsx +179 -0
- package/dashboard/app/diagram/page.tsx +65 -0
- package/dashboard/app/flows/page.tsx +102 -0
- package/dashboard/app/functions/FunctionsClient.tsx +167 -0
- package/dashboard/app/functions/page.tsx +171 -0
- package/dashboard/app/globals.css +157 -0
- package/dashboard/app/icon.svg +18 -0
- package/dashboard/app/issues/IssuesBoardClient.tsx +636 -0
- package/dashboard/app/issues/page.tsx +239 -0
- package/dashboard/app/layout.tsx +40 -0
- package/dashboard/app/page.tsx +259 -0
- package/dashboard/app/progress/ProgressClient.tsx +333 -0
- package/dashboard/app/progress/page.tsx +118 -0
- package/dashboard/app/stats/StatsClient.tsx +452 -0
- package/dashboard/app/stats/page.tsx +43 -0
- package/dashboard/components/AutoRefresh.tsx +37 -0
- package/dashboard/components/CodeReference.tsx +129 -0
- package/dashboard/components/CommandPalette.tsx +135 -0
- package/dashboard/components/ConfidenceBadge.tsx +53 -0
- package/dashboard/components/DashboardLayout.tsx +450 -0
- package/dashboard/components/FilterableTable.tsx +293 -0
- package/dashboard/components/LiveStatus.tsx +99 -0
- package/dashboard/components/MarkdownRenderer.tsx +40 -0
- package/dashboard/components/MermaidViewer.tsx +267 -0
- package/dashboard/components/NotYetGenerated.tsx +32 -0
- package/dashboard/components/SeverityBadge.tsx +28 -0
- package/dashboard/components/SignalBars.tsx +27 -0
- package/dashboard/components/SortableTable.tsx +122 -0
- package/dashboard/lib/conformance-tokens.ts +49 -0
- package/dashboard/lib/data.ts +102 -0
- package/dashboard/lib/watcher.ts +45 -0
- package/dashboard/next-env.d.ts +5 -0
- package/dashboard/next.config.mjs +9 -0
- package/dashboard/postcss.config.cjs +6 -0
- package/dashboard/tailwind.config.ts +79 -0
- package/dashboard/tsconfig.json +21 -0
- package/dist/analysis/access-control.d.ts +24 -0
- package/dist/analysis/access-control.d.ts.map +1 -0
- package/dist/analysis/access-control.js +378 -0
- package/dist/analysis/access-control.js.map +1 -0
- package/dist/analysis/attack-surface.d.ts +51 -0
- package/dist/analysis/attack-surface.d.ts.map +1 -0
- package/dist/analysis/attack-surface.js +206 -0
- package/dist/analysis/attack-surface.js.map +1 -0
- package/dist/analysis/constraint-extraction.d.ts +25 -0
- package/dist/analysis/constraint-extraction.d.ts.map +1 -0
- package/dist/analysis/constraint-extraction.js +398 -0
- package/dist/analysis/constraint-extraction.js.map +1 -0
- package/dist/analysis/context-assembler.d.ts +16 -0
- package/dist/analysis/context-assembler.d.ts.map +1 -0
- package/dist/analysis/context-assembler.js +88 -0
- package/dist/analysis/context-assembler.js.map +1 -0
- package/dist/analysis/dependency-graph.d.ts +31 -0
- package/dist/analysis/dependency-graph.d.ts.map +1 -0
- package/dist/analysis/dependency-graph.js +223 -0
- package/dist/analysis/dependency-graph.js.map +1 -0
- package/dist/analysis/erc-detection.d.ts +16 -0
- package/dist/analysis/erc-detection.d.ts.map +1 -0
- package/dist/analysis/erc-detection.js +81 -0
- package/dist/analysis/erc-detection.js.map +1 -0
- package/dist/analysis/external-calls.d.ts +8 -0
- package/dist/analysis/external-calls.d.ts.map +1 -0
- package/dist/analysis/external-calls.js +124 -0
- package/dist/analysis/external-calls.js.map +1 -0
- package/dist/analysis/nsloc.d.ts +46 -0
- package/dist/analysis/nsloc.d.ts.map +1 -0
- package/dist/analysis/nsloc.js +106 -0
- package/dist/analysis/nsloc.js.map +1 -0
- package/dist/analysis/pattern-detection.d.ts +20 -0
- package/dist/analysis/pattern-detection.d.ts.map +1 -0
- package/dist/analysis/pattern-detection.js +236 -0
- package/dist/analysis/pattern-detection.js.map +1 -0
- package/dist/analysis/state-variables.d.ts +33 -0
- package/dist/analysis/state-variables.d.ts.map +1 -0
- package/dist/analysis/state-variables.js +179 -0
- package/dist/analysis/state-variables.js.map +1 -0
- package/dist/commands/access.d.ts +3 -0
- package/dist/commands/access.d.ts.map +1 -0
- package/dist/commands/access.js +99 -0
- package/dist/commands/access.js.map +1 -0
- package/dist/commands/ai-status.d.ts +3 -0
- package/dist/commands/ai-status.d.ts.map +1 -0
- package/dist/commands/ai-status.js +172 -0
- package/dist/commands/ai-status.js.map +1 -0
- package/dist/commands/analyze.d.ts +3 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +101 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/calls.d.ts +3 -0
- package/dist/commands/calls.d.ts.map +1 -0
- package/dist/commands/calls.js +92 -0
- package/dist/commands/calls.js.map +1 -0
- package/dist/commands/claude.d.ts +3 -0
- package/dist/commands/claude.d.ts.map +1 -0
- package/dist/commands/claude.js +42 -0
- package/dist/commands/claude.js.map +1 -0
- package/dist/commands/constraints.d.ts +3 -0
- package/dist/commands/constraints.d.ts.map +1 -0
- package/dist/commands/constraints.js +32 -0
- package/dist/commands/constraints.js.map +1 -0
- package/dist/commands/context.d.ts +3 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +57 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/dashboard.d.ts +3 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +95 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/deps.d.ts +3 -0
- package/dist/commands/deps.d.ts.map +1 -0
- package/dist/commands/deps.js +67 -0
- package/dist/commands/deps.js.map +1 -0
- package/dist/commands/doctor.d.ts +17 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +154 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +330 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/patterns.d.ts +3 -0
- package/dist/commands/patterns.d.ts.map +1 -0
- package/dist/commands/patterns.js +40 -0
- package/dist/commands/patterns.js.map +1 -0
- package/dist/commands/state.d.ts +3 -0
- package/dist/commands/state.d.ts.map +1 -0
- package/dist/commands/state.js +92 -0
- package/dist/commands/state.js.map +1 -0
- package/dist/commands/stats.d.ts +3 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +347 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/surface.d.ts +3 -0
- package/dist/commands/surface.d.ts.map +1 -0
- package/dist/commands/surface.js +45 -0
- package/dist/commands/surface.js.map +1 -0
- package/dist/commands/update-skills.d.ts +3 -0
- package/dist/commands/update-skills.d.ts.map +1 -0
- package/dist/commands/update-skills.js +40 -0
- package/dist/commands/update-skills.js.map +1 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +157 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/core/config.d.ts +24 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +70 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/errors.d.ts +17 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +113 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/external-tools.d.ts +39 -0
- package/dist/core/external-tools.d.ts.map +1 -0
- package/dist/core/external-tools.js +151 -0
- package/dist/core/external-tools.js.map +1 -0
- package/dist/core/logger.d.ts +16 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +22 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/output.d.ts +13 -0
- package/dist/core/output.d.ts.map +1 -0
- package/dist/core/output.js +45 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/paths.d.ts +21 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +32 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/progress.d.ts +34 -0
- package/dist/core/progress.d.ts.map +1 -0
- package/dist/core/progress.js +119 -0
- package/dist/core/progress.js.map +1 -0
- package/dist/core/schema.d.ts +3197 -0
- package/dist/core/schema.d.ts.map +1 -0
- package/dist/core/schema.js +420 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/skills.d.ts +28 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +82 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/lcov.d.ts +27 -0
- package/dist/parsers/lcov.d.ts.map +1 -0
- package/dist/parsers/lcov.js +68 -0
- package/dist/parsers/lcov.js.map +1 -0
- package/dist/parsers/slither.d.ts +63 -0
- package/dist/parsers/slither.d.ts.map +1 -0
- package/dist/parsers/slither.js +160 -0
- package/dist/parsers/slither.js.map +1 -0
- package/dist/parsers/solc.d.ts +19 -0
- package/dist/parsers/solc.d.ts.map +1 -0
- package/dist/parsers/solc.js +43 -0
- package/dist/parsers/solc.js.map +1 -0
- package/dist/parsers/solidity-parser.d.ts +77 -0
- package/dist/parsers/solidity-parser.d.ts.map +1 -0
- package/dist/parsers/solidity-parser.js +357 -0
- package/dist/parsers/solidity-parser.js.map +1 -0
- package/dist/skills/generate-overleaf.md +326 -0
- package/dist/skills/generate-poc.md +186 -0
- package/dist/skills/ingest-aa-report.md +172 -0
- package/dist/skills/init-audit.md +271 -0
- package/dist/skills/sync-issues.md +266 -0
- package/dist/skills/validate-issue.md +149 -0
- package/dist/skills/write-finding.md +142 -0
- package/dist/types/index.d.ts +30 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Generate the four LaTeX section files for the final audit report (Overleaf-ready)"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Skill: Generate Overleaf
|
|
6
|
+
|
|
7
|
+
**Recommended model:** Sonnet
|
|
8
|
+
|
|
9
|
+
This skill produces the four LaTeX section files an auditor uploads into the Nethermind Overleaf template at the end of an engagement. It runs after all findings have been verified or rejected on the dashboard's Issues board.
|
|
10
|
+
|
|
11
|
+
## What it writes
|
|
12
|
+
|
|
13
|
+
Four `.txt` files in `<output_dir>/overleaf/`:
|
|
14
|
+
|
|
15
|
+
1. `executive_summary.txt` — `\section{Executive Summary}` body with project synopsis, severity histogram, status histogram, summary table of audit metadata.
|
|
16
|
+
2. `audited_files.txt` — `\section{Audited Files}` body with a LaTeX table of in-scope files (LoC, comments, ratio, blank, total).
|
|
17
|
+
3. `summary_of_findings.txt` — `\section{Summary of Issues}` body with hyperlinked finding rows.
|
|
18
|
+
4. `findings.txt` — `\section{Issues}` body with one `\subsection{[Sev] title}\label{issue:N}` per verified finding, including description, code blocks, recommendation, status, client update.
|
|
19
|
+
|
|
20
|
+
Output is plain `.txt` so the auditor pastes content into the matching Overleaf template slots. The skill does NOT compile LaTeX itself.
|
|
21
|
+
|
|
22
|
+
## Phase 0 — Gather report metadata
|
|
23
|
+
|
|
24
|
+
Read `<output_dir>/config.json`. Look under `settings.report.*` for:
|
|
25
|
+
|
|
26
|
+
- `repository_url` — e.g. `https://github.com/mellow-finance/flexible-vaults`. Required for hyperref links in the audited files table and per-finding file links.
|
|
27
|
+
- `initial_commit` — commit hash for the initial report scope.
|
|
28
|
+
- `final_commit` — commit hash after fixes (defaults to `initial_commit` if no remediation cycle).
|
|
29
|
+
- `initial_report_date` — date the initial report was delivered (e.g. `May 22, 2026`).
|
|
30
|
+
- `final_report_date` — date the final report was delivered (defaults to `initial_report_date`).
|
|
31
|
+
- `audit_type` — defaults to `Security Review`.
|
|
32
|
+
- `doc_assessment` — `High` / `Medium` / `Low`.
|
|
33
|
+
- `test_assessment` — `High` / `Medium` / `Low`.
|
|
34
|
+
|
|
35
|
+
For each missing field, use **AskUserQuestion** to prompt the auditor. After collection, persist all values back to `config.json` under `settings.report.*` so re-runs don't re-prompt.
|
|
36
|
+
|
|
37
|
+
If `repository_url` is not set, also offer to derive it from the project's git remote (`git -C <project_dir> remote get-url origin`).
|
|
38
|
+
|
|
39
|
+
## Phase 1 — Compute the histograms and counts
|
|
40
|
+
|
|
41
|
+
Read `<output_dir>/findings.json` and `<output_dir>/tracking.json`.
|
|
42
|
+
|
|
43
|
+
**Verified findings** are findings whose tracking entry has `status: "verified"`. These are the ones that go in the report. Sort by severity (Critical → High → Medium → Low → Info), then by id within each severity.
|
|
44
|
+
|
|
45
|
+
Severity histogram (count of verified findings per severity):
|
|
46
|
+
```
|
|
47
|
+
{ "Critical": N, "High": N, "Medium": N, "Low": N, "Undetermined": 0, "Info": N, "Best Practices": 0 }
|
|
48
|
+
```
|
|
49
|
+
(`Undetermined` and `Best Practices` are not currently in Hex's severity model — render them as 0 to match the Nethermind template.)
|
|
50
|
+
|
|
51
|
+
Resolution histogram (count of verified findings per `resolution` field):
|
|
52
|
+
```
|
|
53
|
+
{ "Fixed": N, "Acknowledged": N, "Mitigated": N, "Not Fixed": 0, "Unresolved": N }
|
|
54
|
+
```
|
|
55
|
+
Findings without a `resolution` field count as `Unresolved`.
|
|
56
|
+
|
|
57
|
+
## Phase 2 — Build the protocol synopsis paragraph
|
|
58
|
+
|
|
59
|
+
Read `<output_dir>/overview.md`. Produce a roughly half-page (~120-180 words) plain-language summary of what the protocol does and the security-relevant mechanics. This becomes the second paragraph of `executive_summary.txt`. Match the tone of the Nethermind example:
|
|
60
|
+
|
|
61
|
+
- Open with one sentence on the project's purpose and the in-scope contract(s).
|
|
62
|
+
- Use a short `\begin{itemize}[leftmargin=*,itemsep=4pt] ... \end{itemize}` to list 2-3 of the security-relevant axes (e.g., access-control gates, asset-flow surfaces, upgradeability boundaries).
|
|
63
|
+
- Close with one or two sentences on any notable edge cases the auditor wants to flag generally (an entry point that bypasses a typical gate, a non-obvious permission, etc.).
|
|
64
|
+
|
|
65
|
+
Style hints:
|
|
66
|
+
- Refer to contracts as `\texttt{ContractName}`, role constants as `\texttt{ROLE\_NAME}`, function names as `\texttt{name(...)}`.
|
|
67
|
+
- Bold key terms with `\textbf{...}`.
|
|
68
|
+
- No code blocks in this paragraph — those belong in the per-finding sections.
|
|
69
|
+
|
|
70
|
+
## Phase 3 — Write `executive_summary.txt`
|
|
71
|
+
|
|
72
|
+
```latex
|
|
73
|
+
\pagebreak \vspace*{0cm}
|
|
74
|
+
\sectioncolor
|
|
75
|
+
\section{Executive Summary}
|
|
76
|
+
\black
|
|
77
|
+
This document presents the results of the security review conducted by \href{https://www.nethermind.io/smart-contract-audits}{Nethermind Security} for <PROJECT_NAME>'s <SCOPE_DESCRIPTION>.
|
|
78
|
+
|
|
79
|
+
<AI-GENERATED PROTOCOL SYNOPSIS PARAGRAPH FROM PHASE 2>
|
|
80
|
+
|
|
81
|
+
\textbf{The audit comprises <TOTAL_NSLOC>} lines of Solidity code. \textbf{The audit was performed using} (a)~manual analysis of the codebase, and (b)~automated analysis tools.
|
|
82
|
+
|
|
83
|
+
\textbf{Along this document, we report} <ISSUE_COUNT_PHRASE>.
|
|
84
|
+
%
|
|
85
|
+
The issues are summarized in Fig.~1.
|
|
86
|
+
|
|
87
|
+
\textbf{This document is organized as follows.}
|
|
88
|
+
%
|
|
89
|
+
{Section~2} presents the files in the scope.
|
|
90
|
+
%
|
|
91
|
+
{Section~3} presents the summary of issues.
|
|
92
|
+
%
|
|
93
|
+
{Section~4} presents the System Overview.
|
|
94
|
+
%
|
|
95
|
+
{Section~5} discusses the risk rating methodology.
|
|
96
|
+
%
|
|
97
|
+
{Section~6} details the issues.
|
|
98
|
+
%
|
|
99
|
+
{Section~7} discusses the documentation provided by the client for this audit.
|
|
100
|
+
%
|
|
101
|
+
{Section~8} presents the test suite evaluation and automated tools used.
|
|
102
|
+
%
|
|
103
|
+
{Section~9} concludes the document.
|
|
104
|
+
\color{black}
|
|
105
|
+
|
|
106
|
+
\begin{figure}[H]
|
|
107
|
+
\centering
|
|
108
|
+
\subfigure[]
|
|
109
|
+
{
|
|
110
|
+
\includegraphics[trim=0cm 0cm 0cm 0cm, clip=true, width=0.45\textwidth]{img/Severity.pdf}
|
|
111
|
+
\label{fig:severity}
|
|
112
|
+
}
|
|
113
|
+
\subfigure[]
|
|
114
|
+
{
|
|
115
|
+
\includegraphics[trim=0cm 0cm 0cm 0cm, clip=true, width=0.45\textwidth]{img/Status.pdf}
|
|
116
|
+
\label{fig:status}
|
|
117
|
+
}
|
|
118
|
+
\label{fig:trapezio}
|
|
119
|
+
\end{figure}
|
|
120
|
+
\begin{center}
|
|
121
|
+
\begin{footnotesize}
|
|
122
|
+
\textbf{Fig.~1: Distribution of issues:} \textbf{Critical}~(<C>), \textbf{High}~(<H>), \textbf{Medium}~(<M>), \textbf{Low}~(<L>), \textbf{Undetermined}~(0), \textbf{Informational}~(<I>), \textbf{Best Practices}~(0).\\
|
|
123
|
+
\textbf{Distribution of status:} \textbf{Fixed}~(<F>), \textbf{Acknowledged}~(<A>), \textbf{Mitigated}~(<MI>), \textbf{Unresolved}~(<U>)
|
|
124
|
+
\end{footnotesize}
|
|
125
|
+
\end{center}
|
|
126
|
+
|
|
127
|
+
\color{black}
|
|
128
|
+
|
|
129
|
+
\begin{longtable}[c]{ll}
|
|
130
|
+
\caption*{\textbf{Summary of the Audit}} \\ \hline
|
|
131
|
+
\textbf{Audit Type} & <AUDIT_TYPE> \\
|
|
132
|
+
\textbf{Initial Report} & <INITIAL_REPORT_DATE> \\
|
|
133
|
+
\textbf{Final Report} & <FINAL_REPORT_DATE> \\
|
|
134
|
+
\textbf{Initial Commit} & \href{<REPOSITORY_URL>/blob/<INITIAL_COMMIT>/<FIRST_SCOPE_FILE>}{<INITIAL_COMMIT_SHORT>} \\
|
|
135
|
+
\textbf{Final Commit} & \href{<REPOSITORY_URL>/commit/<FINAL_COMMIT>}{<FINAL_COMMIT_SHORT>} \\
|
|
136
|
+
\textbf{Documentation Assessment} & <DOC_ASSESSMENT> \\
|
|
137
|
+
\textbf{Test Suite Assessment} & <TEST_ASSESSMENT> \\ \hline
|
|
138
|
+
\end{longtable>
|
|
139
|
+
\color{black}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Substitutions:
|
|
143
|
+
- `<PROJECT_NAME>` ← `config.json.project.name`.
|
|
144
|
+
- `<SCOPE_DESCRIPTION>` ← if a single in-scope file, `\texttt{<filename without extension>}` followed by a single-clause description from the overview; if many, `the contracts listed in Section~2`.
|
|
145
|
+
- `<TOTAL_NSLOC>` ← `stats.json.totals.nsloc`.
|
|
146
|
+
- `<ISSUE_COUNT_PHRASE>` ← something like "five points of attention, where one is classified as `\texttt{Low}`, and four are classified as `\texttt{Informational}` severity." Build dynamically from the severity histogram. If 0 verified findings: "no points of attention requiring remediation." If 1: "one point of attention, classified as `\texttt{<severity>}` severity." Pluralize properly.
|
|
147
|
+
- `<C><H><M><L><I>` ← severity histogram counts.
|
|
148
|
+
- `<F><A><MI><U>` ← resolution histogram counts.
|
|
149
|
+
- `<INITIAL_COMMIT_SHORT>` ← first 7 chars of the commit hash.
|
|
150
|
+
- `<FIRST_SCOPE_FILE>` ← relative path of the first file in `config.json.project.scope` (for the initial commit hyperref, which the template anchors to a specific file).
|
|
151
|
+
|
|
152
|
+
## Phase 4 — Write `audited_files.txt`
|
|
153
|
+
|
|
154
|
+
Compute per-file line counts from each scope file. For each in-scope file in `config.json.project.scope`:
|
|
155
|
+
|
|
156
|
+
- Read the file. Count:
|
|
157
|
+
- `code` lines (non-blank, non-comment).
|
|
158
|
+
- `comments` (lines starting with `//` or `#`, or any line inside a `/* ... */` block).
|
|
159
|
+
- `blank` (empty after `.strip()`).
|
|
160
|
+
- `total` = sum of the three.
|
|
161
|
+
- `ratio` = `round(comments * 100 / max(code, 1), 0)` followed by `\%`.
|
|
162
|
+
|
|
163
|
+
Render the table:
|
|
164
|
+
|
|
165
|
+
```latex
|
|
166
|
+
\pagebreak \vspace*{0cm}
|
|
167
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
168
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
169
|
+
\sectioncolor
|
|
170
|
+
\section{Audited Files}
|
|
171
|
+
\black
|
|
172
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
173
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
174
|
+
|
|
175
|
+
\begin{table}[H]
|
|
176
|
+
\centering
|
|
177
|
+
\begin{footnotesize}
|
|
178
|
+
\begin{tabular}{|p{.5cm}|p{9cm}|p{1cm}|p{1.5cm}|p{1cm}|p{1cm}|p{1cm}|}
|
|
179
|
+
\hline
|
|
180
|
+
&\textbf{Contract} & \textbf{LoC} & \textbf{Comments} & \textbf{Ratio} & \textbf{Blank} & \textbf{Total} \\ \hline
|
|
181
|
+
<N> & \href{<REPOSITORY_URL>/blob/<INITIAL_COMMIT>/<FILE_PATH>}{ \texttt{<FILENAME>}} & <code> & <comments> & <ratio>\% & <blank> & <total> \\ \hline
|
|
182
|
+
...
|
|
183
|
+
& \textbf{Total} & \textbf{<sum-code>} & \textbf{<sum-comments>} & \textbf{<aggregate-ratio>\%} & \textbf{<sum-blank>} & \textbf{<sum-total>} \\ \hline
|
|
184
|
+
%%
|
|
185
|
+
\end{tabular}
|
|
186
|
+
\end{footnotesize}
|
|
187
|
+
\end{table}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
- `<FILENAME>` is the basename, LaTeX-escaped (no extension processing — show e.g., `ThreeFModule.sol`).
|
|
191
|
+
- `<FILE_PATH>` is the path relative to the project root (`src/utils/ThreeFModule.sol`).
|
|
192
|
+
- Number rows sequentially `1, 2, 3 ...`.
|
|
193
|
+
- Aggregate ratio = `round(sum-comments * 100 / max(sum-code, 1), 0)`.
|
|
194
|
+
|
|
195
|
+
## Phase 5 — Write `summary_of_findings.txt`
|
|
196
|
+
|
|
197
|
+
For each verified finding in severity-sorted order (Critical → Info), assign a sequential `issue:N` label starting at `issue:0`. This same label is used in `findings.txt` for the `\hyperref`.
|
|
198
|
+
|
|
199
|
+
```latex
|
|
200
|
+
%\pagebreak \vspace*{0cm}
|
|
201
|
+
|
|
202
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
203
|
+
%%%%%%%%%%%% H E A D E R 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
204
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
205
|
+
\sectioncolor
|
|
206
|
+
\section{Summary of Issues}
|
|
207
|
+
\black
|
|
208
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
209
|
+
\begin{table}[H]
|
|
210
|
+
\centering
|
|
211
|
+
\begin{footnotesize}
|
|
212
|
+
\begin{tabular}{|p{1cm}|p{11cm}|p{2.1cm}|p{2.1cm}|}
|
|
213
|
+
\hline
|
|
214
|
+
& \textbf{Finding} & \textbf{Severity} & \textbf{Update} \\ \hline
|
|
215
|
+
<N>&\hyperref[issue:<I>]{<title-LaTeX-escaped>} &<Severity-display> & <Resolution-display>\\ \hline
|
|
216
|
+
%
|
|
217
|
+
\end{tabular}
|
|
218
|
+
\end{footnotesize}
|
|
219
|
+
\end{table}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
- `<N>` is the 1-based row counter.
|
|
223
|
+
- `<I>` matches the `\label{issue:N}` index used in `findings.txt`.
|
|
224
|
+
- `<Severity-display>` maps `Info` → `Info`, others use their name as-is.
|
|
225
|
+
- `<Resolution-display>` maps the `resolution` field directly (`Fixed`, `Acknowledged`, `Mitigated`, `Not Fixed`); blank/`Unresolved` shows `Unresolved`.
|
|
226
|
+
|
|
227
|
+
## Phase 6 — Write `findings.txt`
|
|
228
|
+
|
|
229
|
+
For each verified finding in the same order (severity-sorted), render one subsection. Use the index `i` (0-based) matching `summary_of_findings.txt`.
|
|
230
|
+
|
|
231
|
+
```latex
|
|
232
|
+
\pagebreak \vspace*{0cm}
|
|
233
|
+
|
|
234
|
+
\sectioncolor
|
|
235
|
+
\section{Issues}
|
|
236
|
+
\black
|
|
237
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
238
|
+
|
|
239
|
+
<per-finding block>
|
|
240
|
+
|
|
241
|
+
<per-finding block>
|
|
242
|
+
|
|
243
|
+
...
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Each per-finding block:
|
|
247
|
+
|
|
248
|
+
```latex
|
|
249
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
250
|
+
%%%%%%%%%%%% H E A D E R 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
251
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
252
|
+
\subsubsectioncolor
|
|
253
|
+
\subsection{[<Severity-display>] <title-LaTeX-escaped>}\label{issue:<i>}
|
|
254
|
+
\begin{footnotesize} \black
|
|
255
|
+
|
|
256
|
+
\textbf{File(s)}: \href{<REPOSITORY_URL>/blob/<INITIAL_COMMIT>/<FILE_PATH>}{ \texttt{<FILE_PATH>}}
|
|
257
|
+
|
|
258
|
+
\textbf{Description}: <description converted from markdown to LaTeX>
|
|
259
|
+
|
|
260
|
+
<each code block from description rendered as \begin{minted}[linenos,firstnumber=1]{solidity} ... \end{minted}>
|
|
261
|
+
|
|
262
|
+
\textbf{Recommendation(s)}: <recommendation converted from markdown to LaTeX>
|
|
263
|
+
|
|
264
|
+
\textbf{Status}: <Resolution-display or "Unresolved">
|
|
265
|
+
|
|
266
|
+
\textbf{Update from the client}: <update_from_client, LaTeX-escaped>
|
|
267
|
+
|
|
268
|
+
\end{footnotesize}
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
If the finding has multiple `root_cause.locations[]`, list them as `\href{...}{...}, \href{...}{...}` comma-separated.
|
|
273
|
+
|
|
274
|
+
### Markdown → LaTeX conversion rules
|
|
275
|
+
|
|
276
|
+
Apply to `description`, `recommendation`, and `update_from_client` (in that order, on non-code-block text only — first split out fenced code blocks, then convert the prose):
|
|
277
|
+
|
|
278
|
+
| Markdown | LaTeX |
|
|
279
|
+
|---|---|
|
|
280
|
+
| `` `text` `` | ` \texttt{text}` (leading space intentional, matches Nethermind template) |
|
|
281
|
+
| `**text**` | ` \textbf{text}` |
|
|
282
|
+
| `[label](url)` | ` \href{url}{label}` — if `label` contains `#`, replace with `/#` (anchors break in LaTeX otherwise) |
|
|
283
|
+
| `_` (literal underscore in prose) | `\_` |
|
|
284
|
+
| `^` | `\^{}` |
|
|
285
|
+
| `%` (only when no `](` was present on the line — to avoid mangling URLs) | `\%` |
|
|
286
|
+
| Numbered list `1. text` | `\begin{enumerate}\n \def\labelenumi{\arabic{enumi}.} \tightlist\n\item text;\n...\end{enumerate}` |
|
|
287
|
+
| Bulleted list `- text` | `\begin{itemize}\n\tightlist\n\item text;\n...\end{itemize}` |
|
|
288
|
+
| Fenced code block ` ```solidity ` | `\begin{minted}[linenos,firstnumber=1]{solidity}` ... `\end{minted}` — also support `python`, `typescript`, `javascript`, `cairo` (use `python` lexer), `diff`, `shell`, `rust` |
|
|
289
|
+
|
|
290
|
+
End list items with `;` (replace trailing `.` with `;`). Last item still ends with `;`.
|
|
291
|
+
|
|
292
|
+
The markdown-to-LaTeX logic matches the spirit of the Python script `create-section-findings.py` referenced by the auditor — port that semantically into the skill's instructions rather than calling it.
|
|
293
|
+
|
|
294
|
+
### Severity-display mapping
|
|
295
|
+
- `Critical` → `Critical`
|
|
296
|
+
- `High` → `High`
|
|
297
|
+
- `Medium` → `Medium`
|
|
298
|
+
- `Low` → `Low`
|
|
299
|
+
- `Info` → `Info` (the Nethermind template uses `Info` in the subsection headers and `Informational` in the histogram caption)
|
|
300
|
+
|
|
301
|
+
## Phase 7 — Final report
|
|
302
|
+
|
|
303
|
+
After writing all four files, print:
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
Wrote 4 LaTeX section files to <output_dir>/overleaf/:
|
|
307
|
+
- executive_summary.txt (<N> bytes)
|
|
308
|
+
- audited_files.txt (<N> bytes)
|
|
309
|
+
- summary_of_findings.txt (<N> bytes)
|
|
310
|
+
- findings.txt (<N> bytes)
|
|
311
|
+
|
|
312
|
+
Verified findings included: <count>
|
|
313
|
+
Critical=<C> High=<H> Medium=<M> Low=<L> Info=<I>
|
|
314
|
+
|
|
315
|
+
Status distribution:
|
|
316
|
+
Fixed=<F> Acknowledged=<A> Mitigated=<MI> Unresolved=<U>
|
|
317
|
+
|
|
318
|
+
Upload these into your Overleaf project's Section 1 / 2 / 3 / 6 slots respectively.
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## What this skill does NOT do
|
|
322
|
+
|
|
323
|
+
- Does not compile LaTeX (no `pdflatex` invocation).
|
|
324
|
+
- Does not modify any file outside `<output_dir>/overleaf/` and (with permission) `config.json` under `settings.report.*`.
|
|
325
|
+
- Does not push to Overleaf, GitHub, or any remote — output is local plain-text.
|
|
326
|
+
- Does not include `rejected`, `duplicate`, `pending_validation`, or `unverified` findings. Only `verified` makes the cut.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Validate an issue and generate a proof-of-concept test"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Skill: Generate Proof of Concept
|
|
6
|
+
|
|
7
|
+
**Recommended model:** Opus
|
|
8
|
+
|
|
9
|
+
## Context Assembly
|
|
10
|
+
|
|
11
|
+
Read:
|
|
12
|
+
- The issue description provided by the auditor
|
|
13
|
+
- Run: `npx hex context --target <relevant_contract>` for focused context
|
|
14
|
+
- `<output_dir>/state-vars.json` — for relevant state variable info
|
|
15
|
+
- `<output_dir>/access-control.json` — for access restrictions
|
|
16
|
+
- `<output_dir>/external-calls.json` — for external call surface (if relevant)
|
|
17
|
+
|
|
18
|
+
## Step 0: Understand the Project's Test Infrastructure
|
|
19
|
+
|
|
20
|
+
**CRITICAL: You MUST complete Step 0 before writing any test code.** Do not proceed to Step 2 until you have identified the base test contract (if any), the deployment fixture/setup, and how tokens are dealt and accounts impersonated. Failure to reuse existing test infrastructure is the #1 cause of PoC failures.
|
|
21
|
+
|
|
22
|
+
Before writing any test code, inspect the project's existing test setup:
|
|
23
|
+
|
|
24
|
+
1. Look at the test directory structure (`test/`, `tests/`, etc.)
|
|
25
|
+
2. Read 2-3 existing test files to understand:
|
|
26
|
+
- Which test framework is used (Foundry, Hardhat/Mocha, Brownie, etc.)
|
|
27
|
+
- How contracts are deployed in tests (direct deploy, factory, fork, etc.)
|
|
28
|
+
- Existing base test contracts or test helpers (e.g., `BaseTest.sol`, `TestSetup.sol`)
|
|
29
|
+
- How tokens are dealt, accounts are impersonated, etc.
|
|
30
|
+
- Fork configuration (RPC URL, block number) if applicable
|
|
31
|
+
3. Read the project config (`foundry.toml`, `hardhat.config.ts`, etc.) for test settings
|
|
32
|
+
|
|
33
|
+
**CRITICAL:** Reuse existing test infrastructure. If the project has a `BaseTest.sol` that deploys the full system, inherit from it. Do NOT recreate deployment logic that already exists.
|
|
34
|
+
|
|
35
|
+
## Step 1: Validate by Reasoning
|
|
36
|
+
|
|
37
|
+
Before writing any code, reason through:
|
|
38
|
+
|
|
39
|
+
1. **Is this actually exploitable?** Trace the exact execution path step by step.
|
|
40
|
+
2. **What are the preconditions?** What state must the system be in? What does the attacker need?
|
|
41
|
+
3. **What would the impact be?** Quantify if possible (fund loss amount, DoS duration, etc.)
|
|
42
|
+
4. **Are there existing protections?** Check for:
|
|
43
|
+
- Reentrancy guards
|
|
44
|
+
- Access control that prevents the attack path
|
|
45
|
+
- Input validation that blocks required preconditions
|
|
46
|
+
- Economic constraints that make the attack unprofitable
|
|
47
|
+
|
|
48
|
+
If you conclude the issue is **NOT valid**, explain why clearly and stop. Still write the validation memo.
|
|
49
|
+
|
|
50
|
+
## Step 2: Write PoC (only if Step 1 validates)
|
|
51
|
+
|
|
52
|
+
### Foundry Project
|
|
53
|
+
```solidity
|
|
54
|
+
// SPDX-License-Identifier: MIT
|
|
55
|
+
pragma solidity ^0.8.20;
|
|
56
|
+
|
|
57
|
+
import {BaseTest} from "../BaseTest.sol"; // or whatever the project uses
|
|
58
|
+
|
|
59
|
+
contract F001_Description_PoC is BaseTest {
|
|
60
|
+
function setUp() public override {
|
|
61
|
+
super.setUp();
|
|
62
|
+
// Only add PoC-specific setup here
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function test_poc_description() public {
|
|
66
|
+
// Step 1: Set up initial state
|
|
67
|
+
// Step 2: Execute attack
|
|
68
|
+
// Step 3: Assert impact
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Hardhat/TypeScript Project
|
|
74
|
+
```typescript
|
|
75
|
+
import { expect } from "chai";
|
|
76
|
+
import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
|
|
77
|
+
import { deployFixture } from "../helpers/deploy";
|
|
78
|
+
|
|
79
|
+
describe("F001 - Description", function () {
|
|
80
|
+
it("should demonstrate the vulnerability", async function () {
|
|
81
|
+
// Reuse project fixtures
|
|
82
|
+
// Step-by-step attack
|
|
83
|
+
// Assert impact
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Requirements:
|
|
89
|
+
- Match the project's coding style and conventions
|
|
90
|
+
- Inherit from / reuse existing test base contracts or fixtures
|
|
91
|
+
- Add descriptive comments for each step
|
|
92
|
+
- End with clear assertions that demonstrate the impact
|
|
93
|
+
- Name the file: `test/hex-pocs/<finding_id>_<short_name>.t.sol` (Foundry) or `test/hex-pocs/<finding_id>_<short_name>.test.ts` (Hardhat)
|
|
94
|
+
- Create the `test/hex-pocs/` directory if it doesn't exist
|
|
95
|
+
|
|
96
|
+
### Economic Impact Logging (REQUIRED)
|
|
97
|
+
|
|
98
|
+
Every PoC MUST log economic impact with before/after balance snapshots:
|
|
99
|
+
|
|
100
|
+
```solidity
|
|
101
|
+
// Before exploit
|
|
102
|
+
uint256 attackerBalanceBefore = token.balanceOf(attacker);
|
|
103
|
+
uint256 victimBalanceBefore = token.balanceOf(address(vault));
|
|
104
|
+
|
|
105
|
+
// ... execute exploit steps ...
|
|
106
|
+
|
|
107
|
+
// After exploit
|
|
108
|
+
uint256 attackerBalanceAfter = token.balanceOf(attacker);
|
|
109
|
+
uint256 profit = attackerBalanceAfter - attackerBalanceBefore;
|
|
110
|
+
uint256 victimLoss = victimBalanceBefore - token.balanceOf(address(vault));
|
|
111
|
+
|
|
112
|
+
console.log("Attacker profit: %s tokens (%s decimals)", profit, token.decimals());
|
|
113
|
+
console.log("Victim loss: %s tokens", victimLoss);
|
|
114
|
+
// If price oracle available in tests:
|
|
115
|
+
// uint256 priceUsd = oracle.latestAnswer();
|
|
116
|
+
// console.log("Profit in USD: $%s", (profit * priceUsd) / (10 ** token.decimals()));
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Descriptive Assertions
|
|
120
|
+
|
|
121
|
+
Use assertion messages that explain the exploit impact, not just pass/fail:
|
|
122
|
+
|
|
123
|
+
```solidity
|
|
124
|
+
assertGt(attackerBalanceAfter, attackerBalanceBefore, "Exploit should be profitable for attacker");
|
|
125
|
+
assertLt(token.balanceOf(address(vault)), victimBalanceBefore, "Vault should have lost funds");
|
|
126
|
+
assertEq(profit, victimLoss, "Attacker profit should equal vault loss (no external source)");
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Rounding Error PoCs
|
|
130
|
+
|
|
131
|
+
For rounding/precision vulnerabilities, demonstrate BOTH per-transaction and cumulative impact:
|
|
132
|
+
|
|
133
|
+
```solidity
|
|
134
|
+
// Per-transaction loss
|
|
135
|
+
uint256 before = token.balanceOf(address(vault));
|
|
136
|
+
// ... single operation ...
|
|
137
|
+
uint256 singleLoss = before - token.balanceOf(address(vault));
|
|
138
|
+
console.log("Loss per transaction: %s wei", singleLoss);
|
|
139
|
+
|
|
140
|
+
// Cumulative impact over realistic timeframe
|
|
141
|
+
uint256 cumulativeLoss = 0;
|
|
142
|
+
for (uint256 i = 0; i < 1000; i++) {
|
|
143
|
+
uint256 b = token.balanceOf(address(vault));
|
|
144
|
+
// ... repeat operation ...
|
|
145
|
+
cumulativeLoss += b - token.balanceOf(address(vault));
|
|
146
|
+
}
|
|
147
|
+
console.log("Cumulative loss over 1000 transactions: %s tokens", cumulativeLoss);
|
|
148
|
+
console.log("Average loss per transaction: %s wei", cumulativeLoss / 1000);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
This pattern is critical for rounding bugs where per-transaction loss seems negligible but compounds to significant value over time.
|
|
152
|
+
|
|
153
|
+
## Step 3: Run and Verify
|
|
154
|
+
|
|
155
|
+
Run the test:
|
|
156
|
+
- Foundry: `forge test --match-test test_poc_description -vvv`
|
|
157
|
+
- Hardhat: `npx hardhat test test/hex-pocs/<file> --grep "poc_description"`
|
|
158
|
+
|
|
159
|
+
If it fails, debug and fix. Iterate until the PoC passes.
|
|
160
|
+
|
|
161
|
+
## Output
|
|
162
|
+
|
|
163
|
+
**Always produce a validation memo** at `<output_dir>/validations/<finding_id_or_short_name>_memo.md`:
|
|
164
|
+
|
|
165
|
+
```markdown
|
|
166
|
+
# Validation Memo: <Title>
|
|
167
|
+
|
|
168
|
+
**Verdict:** Valid / Invalid / Uncertain
|
|
169
|
+
**Date:** <YYYY-MM-DD>
|
|
170
|
+
|
|
171
|
+
## Reasoning
|
|
172
|
+
[Step-by-step reasoning from Step 1]
|
|
173
|
+
|
|
174
|
+
## Execution Path
|
|
175
|
+
[Traced call path: function1() -> function2() -> ...]
|
|
176
|
+
|
|
177
|
+
## Protections Considered
|
|
178
|
+
[Existing guards, checks, or mitigations evaluated and why they don't prevent the issue]
|
|
179
|
+
|
|
180
|
+
## Conclusion
|
|
181
|
+
[If valid: summary of exploit + pointer to PoC file]
|
|
182
|
+
[If invalid: clear explanation of why not exploitable]
|
|
183
|
+
[If uncertain: specific questions for manual investigation]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
If valid, also write the test file to the project's test directory.
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Ingest a completed Nethermind AuditAgent scan into the board and dedup against existing issues"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Skill: Ingest AuditAgent Report
|
|
6
|
+
|
|
7
|
+
**Recommended model:** Sonnet
|
|
8
|
+
|
|
9
|
+
This skill is the single point of integration with Nethermind's AuditAgent. It does **not** start scans — the auditor starts a scan separately (e.g. via the Nethermind portal or `aa scan ...` from the command line) and passes the resulting scan ID into this skill. The skill fetches the results, normalizes them into the board, and inline-dedupes against everything already there.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
|
|
13
|
+
After you have a scan ID for a completed (or running) AuditAgent scan and want its findings on the dashboard's Issues board. Typical sequence:
|
|
14
|
+
|
|
15
|
+
1. Auditor starts a scan elsewhere: `aa scan --quality auditor <files>`, copies the scan ID printed by the CLI.
|
|
16
|
+
2. Auditor invokes `/ingest-aa-report` with that ID.
|
|
17
|
+
|
|
18
|
+
## Step 1 — Resolve the scan ID
|
|
19
|
+
|
|
20
|
+
Try in order:
|
|
21
|
+
|
|
22
|
+
1. The free-text argument passed with the invocation (e.g., `/ingest-aa-report abc123def`).
|
|
23
|
+
2. `settings.ai.auditagent_scan_id` in `<output_dir>/config.json`.
|
|
24
|
+
3. **Ask the auditor** via AskUserQuestion: "Paste the AuditAgent scan ID, or type `cancel` to stop."
|
|
25
|
+
|
|
26
|
+
When a scan ID is resolved, persist it to `config.json` under `settings.ai.auditagent_scan_id` (so re-runs work without re-asking) and to `<output_dir>/ai-status.json` under `tools.auditagent.scan_id` (so `hex ai-status --watch` can poll it).
|
|
27
|
+
|
|
28
|
+
## Step 2 — Check scan status
|
|
29
|
+
|
|
30
|
+
Run:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
aa scan --status <scan_id>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Interpret the output:
|
|
37
|
+
|
|
38
|
+
- Status indicates **pending / running / in progress** → print `Scan <scan_id> is still <status>. Come back once it completes — you can run \`hex ai-status --watch\` in another terminal to be notified.` Update `ai-status.json` with `status: "pending_scan"`. **Exit cleanly** — do NOT block.
|
|
39
|
+
- Status indicates **failed** or `aa` exits non-zero → print the error, update `ai-status.json` with `status: "failed"` and `error: <message>`. Exit non-zero.
|
|
40
|
+
- Status indicates **completed** → continue to Step 3.
|
|
41
|
+
|
|
42
|
+
Never invoke `aa scan` to start a new scan. If the auditor has no scan ID, instruct them to start one externally.
|
|
43
|
+
|
|
44
|
+
## Step 3 — Fetch findings
|
|
45
|
+
|
|
46
|
+
Run:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
aa scan --report <scan_id>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
(Or the equivalent results-fetch command exposed by the installed `aa` version — check `aa scan --help` if `--report` is not supported.)
|
|
53
|
+
|
|
54
|
+
Capture the raw output to `<output_dir>/ai-results/auditagent/raw-output.md`.
|
|
55
|
+
|
|
56
|
+
## Step 4 — Normalize into findings.json
|
|
57
|
+
|
|
58
|
+
Parse the AuditAgent output (markdown with severity-tagged sections per finding) and convert each finding into the schema:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"id": "AA-<NNN>",
|
|
63
|
+
"tool": "auditagent",
|
|
64
|
+
"title": "<finding title>",
|
|
65
|
+
"severity": "Critical | High | Medium | Low | Info",
|
|
66
|
+
"description": "<full description from the report>",
|
|
67
|
+
"affected_code": [
|
|
68
|
+
{ "file": "<path>", "snippet": "<relevant code if present>" }
|
|
69
|
+
],
|
|
70
|
+
"confidence": "high | medium | low",
|
|
71
|
+
"category": "<auditor-style category, e.g., Access Control, Math/Rounding>",
|
|
72
|
+
"raw_category": "<the raw category string from auditagent, preserved verbatim>"
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Write the full array under:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"tool": "auditagent",
|
|
81
|
+
"ran_at": "<ISO timestamp of this ingest>",
|
|
82
|
+
"duration_seconds": null,
|
|
83
|
+
"total_findings": <count>,
|
|
84
|
+
"findings": [ ... ]
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
to `<output_dir>/ai-results/auditagent/findings.json`. Also write a small `metadata.json` next to it:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"scan_id": "<scan_id>",
|
|
93
|
+
"ingested_at": "<ISO>",
|
|
94
|
+
"report_status": "completed",
|
|
95
|
+
"total_findings": <count>
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Step 5 — Materialize tracking entries
|
|
100
|
+
|
|
101
|
+
For each AuditAgent finding, append (or update if id already exists) a tracking entry in `<output_dir>/tracking.json`:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"id": "AA-<NNN>",
|
|
106
|
+
"title": "<title>",
|
|
107
|
+
"severity": "<severity>",
|
|
108
|
+
"source": "auditagent",
|
|
109
|
+
"status": "unverified",
|
|
110
|
+
"poc_status": "not_started",
|
|
111
|
+
"poc_file": null,
|
|
112
|
+
"duplicates": [],
|
|
113
|
+
"notes": "scan_id=<scan_id>"
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
These appear on the board as Potential cards.
|
|
118
|
+
|
|
119
|
+
## Step 6 — Inline dedup
|
|
120
|
+
|
|
121
|
+
Read all existing tracking entries (manual, conformance, github, and any previously ingested auditagent runs). For each **new** auditagent entry, run a semantic comparison against each existing entry on these axes:
|
|
122
|
+
|
|
123
|
+
| Signal | How to compare |
|
|
124
|
+
|---|---|
|
|
125
|
+
| **contract** (boolean) | Does the affected contract name match? |
|
|
126
|
+
| **function** (boolean) | Does the affected function name match? |
|
|
127
|
+
| **root_cause** | `same` / `overlapping` / `different` — judge the technical mechanism (e.g. "reentrancy on external call before state update" is `same` as "missing CEI pattern around external call"). |
|
|
128
|
+
| **attack_vector** | `same` / `overlapping` / `different` — judge what an attacker actually does to exploit it. |
|
|
129
|
+
|
|
130
|
+
A match is **at least one of**:
|
|
131
|
+
- `root_cause = same` AND `function = true`, or
|
|
132
|
+
- `root_cause = same` AND `contract = true` AND `attack_vector = same`, or
|
|
133
|
+
- `root_cause = overlapping` AND `function = true` AND `attack_vector = same`.
|
|
134
|
+
|
|
135
|
+
On match, **flip the new auditagent entry** to `status: "duplicate"` (the canonical is the existing entry — the auditor already filed or already has it from another source) and set `duplicate_of: "<existing-entry-id>"`. Append to `<output_dir>/comparison.json` under `duplicates`:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"ai_finding": "AA-<NNN>",
|
|
140
|
+
"matches": "<existing-entry-id>",
|
|
141
|
+
"confidence": "high | medium | low",
|
|
142
|
+
"match_signals": { "contract": true, "function": true, "root_cause": "same", "attack_vector": "same" },
|
|
143
|
+
"reasoning": "<one short sentence: which signals carried the call>"
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
If `comparison.json` doesn't exist, create it with `{ "duplicates": [], "novel": [], "rejected": [] }`.
|
|
148
|
+
|
|
149
|
+
For entries that don't match anything, leave them as `status: "unverified"` (the auditor will run `/validate-issue AA-<NNN>` on them).
|
|
150
|
+
|
|
151
|
+
## Step 7 — Report
|
|
152
|
+
|
|
153
|
+
Print a one-paragraph summary:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
Ingested N AuditAgent findings (scan <scan_id>).
|
|
157
|
+
- M new on the Potential column
|
|
158
|
+
- K flagged as Duplicate of existing entries
|
|
159
|
+
- 0 errors
|
|
160
|
+
|
|
161
|
+
Run /validate-issue <id> on any new finding to confirm and promote it to Verified.
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Outputs (recap)
|
|
165
|
+
|
|
166
|
+
- `<output_dir>/ai-results/auditagent/raw-output.md`
|
|
167
|
+
- `<output_dir>/ai-results/auditagent/findings.json`
|
|
168
|
+
- `<output_dir>/ai-results/auditagent/metadata.json`
|
|
169
|
+
- `<output_dir>/ai-status.json` (updated)
|
|
170
|
+
- `<output_dir>/tracking.json` (appended)
|
|
171
|
+
- `<output_dir>/comparison.json` (appended)
|
|
172
|
+
- `<output_dir>/config.json` — `settings.ai.auditagent_scan_id` persisted if new
|