opmsec 0.1.3 → 0.1.5

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 (166) hide show
  1. package/.env.example +1 -0
  2. package/.husky/pre-commit +1 -0
  3. package/README.md +71 -275
  4. package/bun.lock +5 -5
  5. package/docs/architecture/agents.mdx +11 -59
  6. package/docs/architecture/benchmarks.mdx +20 -46
  7. package/docs/architecture/overview.mdx +31 -38
  8. package/docs/architecture/scanner.mdx +11 -37
  9. package/docs/cli/audit.mdx +9 -12
  10. package/docs/cli/check.mdx +12 -26
  11. package/docs/cli/fix.mdx +10 -30
  12. package/docs/cli/info.mdx +12 -19
  13. package/docs/cli/install.mdx +27 -39
  14. package/docs/cli/push.mdx +40 -57
  15. package/docs/cli/register-agent.mdx +21 -53
  16. package/docs/cli/view.mdx +12 -29
  17. package/docs/concepts/ens-records.mdx +44 -0
  18. package/docs/concepts/multi-agent-consensus.mdx +18 -36
  19. package/docs/concepts/on-chain-registry.mdx +22 -49
  20. package/docs/concepts/security-model.mdx +20 -52
  21. package/docs/concepts/zk-agent-verification.mdx +26 -64
  22. package/docs/contract/events.mdx +13 -74
  23. package/docs/contract/functions.mdx +40 -126
  24. package/docs/contract/overview.mdx +17 -36
  25. package/docs/introduction.mdx +22 -25
  26. package/docs/mint.json +3 -2
  27. package/docs/quickstart.mdx +34 -70
  28. package/docs/system-design.png +0 -0
  29. package/package.json +7 -6
  30. package/packages/cli/src/commands/author-view.tsx +87 -2
  31. package/packages/cli/src/commands/check.tsx +18 -5
  32. package/packages/cli/src/commands/fix.tsx +25 -12
  33. package/packages/cli/src/commands/info.tsx +92 -4
  34. package/packages/cli/src/commands/install.tsx +327 -23
  35. package/packages/cli/src/commands/push.tsx +112 -0
  36. package/packages/cli/src/commands/register-agent.tsx +72 -31
  37. package/packages/cli/src/index.tsx +7 -5
  38. package/packages/cli/src/services/ens-records.ts +525 -0
  39. package/packages/cli/src/services/version.ts +156 -5
  40. package/packages/core/src/benchmarks.ts +116 -0
  41. package/packages/core/src/constants.ts +18 -6
  42. package/packages/core/src/model-rankings.ts +40 -15
  43. package/packages/core/src/types.ts +10 -0
  44. package/packages/core/src/utils.ts +136 -1
  45. package/packages/scanner/src/index.ts +2 -1
  46. package/packages/scanner/src/queue/memory-queue.ts +7 -2
  47. package/packages/scanner/src/services/benchmark-runner.ts +86 -1
  48. package/packages/scanner/src/services/fileverse.ts +61 -12
  49. package/packages/scanner/src/services/openrouter.ts +18 -7
  50. package/packages/web/.next/BUILD_ID +1 -0
  51. package/packages/web/.next/app-path-routes-manifest.json +4 -0
  52. package/packages/web/.next/diagnostics/build-diagnostics.json +6 -0
  53. package/packages/web/.next/diagnostics/framework.json +1 -0
  54. package/packages/web/.next/export-marker.json +6 -0
  55. package/packages/web/.next/images-manifest.json +58 -0
  56. package/packages/web/.next/next-minimal-server.js.nft.json +1 -0
  57. package/packages/web/.next/next-server.js.nft.json +1 -0
  58. package/packages/web/.next/prerender-manifest.json +54 -4
  59. package/packages/web/.next/required-server-files.json +320 -0
  60. package/packages/web/.next/routes-manifest.json +53 -1
  61. package/packages/web/.next/server/app/_not-found/page.js +2 -0
  62. package/packages/web/.next/server/app/_not-found/page.js.nft.json +1 -0
  63. package/packages/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  64. package/packages/web/.next/server/app/_not-found.html +1 -0
  65. package/packages/web/.next/server/app/_not-found.meta +8 -0
  66. package/packages/web/.next/server/app/_not-found.rsc +18 -0
  67. package/packages/web/.next/server/app/index.html +6 -0
  68. package/packages/web/.next/server/app/index.meta +7 -0
  69. package/packages/web/.next/server/app/index.rsc +22 -0
  70. package/packages/web/.next/server/app/page.js +24 -24
  71. package/packages/web/.next/server/app/page.js.nft.json +1 -0
  72. package/packages/web/.next/server/app/page_client-reference-manifest.js +1 -1
  73. package/packages/web/.next/server/chunks/611.js +6 -0
  74. package/packages/web/.next/server/chunks/778.js +30 -0
  75. package/packages/web/.next/server/functions-config-manifest.json +4 -0
  76. package/packages/web/.next/server/interception-route-rewrite-manifest.js +1 -1
  77. package/packages/web/.next/server/next-font-manifest.js +1 -1
  78. package/packages/web/.next/server/next-font-manifest.json +1 -1
  79. package/packages/web/.next/server/pages/404.html +1 -0
  80. package/packages/web/.next/server/pages/500.html +1 -0
  81. package/packages/web/.next/server/pages/_app.js +1 -0
  82. package/packages/web/.next/server/pages/_app.js.nft.json +1 -0
  83. package/packages/web/.next/server/pages/_document.js +1 -0
  84. package/packages/web/.next/server/pages/_document.js.nft.json +1 -0
  85. package/packages/web/.next/server/pages/_error.js +19 -0
  86. package/packages/web/.next/server/pages/_error.js.nft.json +1 -0
  87. package/packages/web/.next/server/webpack-runtime.js +2 -2
  88. package/packages/web/.next/static/0esGzFBCzREfVwijEGDfL/_buildManifest.js +1 -0
  89. package/packages/web/.next/static/0esGzFBCzREfVwijEGDfL/_ssgManifest.js +1 -0
  90. package/packages/web/.next/static/chunks/174-5b5efcb3b8efcc01.js +1 -0
  91. package/packages/web/.next/static/chunks/255-0dc49b7a6e8e5c05.js +1 -0
  92. package/packages/web/.next/static/chunks/4bd1b696-382748cc942d8a14.js +1 -0
  93. package/packages/web/.next/static/chunks/app/_not-found/page-0da542be7eb33a64.js +1 -0
  94. package/packages/web/.next/static/chunks/app/layout-de8e841104500505.js +1 -0
  95. package/packages/web/.next/static/chunks/app/layout.js +37 -7
  96. package/packages/web/.next/static/chunks/app/page-7e086379698b9fb0.js +1 -0
  97. package/packages/web/.next/static/chunks/app/page.js +297 -1
  98. package/packages/web/.next/static/chunks/framework-ac73abd125e371fe.js +1 -0
  99. package/packages/web/.next/static/chunks/main-4e8d71b5ef7ee7e3.js +1 -0
  100. package/packages/web/.next/static/chunks/main-app-dd261207182e5a23.js +1 -0
  101. package/packages/web/.next/static/chunks/pages/_app-7d307437aca18ad4.js +1 -0
  102. package/packages/web/.next/static/chunks/pages/_error-cb2a52f75f2162e2.js +1 -0
  103. package/packages/web/.next/static/chunks/webpack-0dcd67569eb46132.js +1 -0
  104. package/packages/web/.next/static/chunks/webpack.js +2 -2
  105. package/packages/web/.next/static/css/102562cf2d0ae9b0.css +3 -0
  106. package/packages/web/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  107. package/packages/web/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  108. package/packages/web/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  109. package/packages/web/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  110. package/packages/web/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  111. package/packages/web/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  112. package/packages/web/.next/static/webpack/16f18baa938a434c.webpack.hot-update.json +1 -0
  113. package/packages/web/.next/static/webpack/5fe9fe8578f9c3d2.webpack.hot-update.json +1 -0
  114. package/packages/web/.next/static/webpack/73c7d02260cc80e4.webpack.hot-update.json +1 -0
  115. package/packages/web/.next/static/webpack/a2d85d19aa028de1.webpack.hot-update.json +1 -0
  116. package/packages/web/.next/static/webpack/app/{layout.73e341375c8d429e.hot-update.js → layout.16f18baa938a434c.hot-update.js} +1 -1
  117. package/packages/web/.next/static/webpack/app/{layout.6fee6306e0f98869.hot-update.js → layout.5fe9fe8578f9c3d2.hot-update.js} +1 -1
  118. package/packages/web/.next/static/webpack/app/layout.653e365406c0d9ac.hot-update.js +22 -0
  119. package/packages/web/.next/static/webpack/app/layout.6800169a899e3a8b.hot-update.js +22 -0
  120. package/packages/web/.next/static/webpack/app/layout.73c7d02260cc80e4.hot-update.js +22 -0
  121. package/packages/web/.next/static/webpack/app/layout.a2d85d19aa028de1.hot-update.js +22 -0
  122. package/packages/web/.next/static/webpack/app/page.653e365406c0d9ac.hot-update.js +22 -0
  123. package/packages/web/.next/static/webpack/app/page.6800169a899e3a8b.hot-update.js +22 -0
  124. package/packages/web/.next/static/webpack/app/page.73c7d02260cc80e4.hot-update.js +22 -0
  125. package/packages/web/.next/static/webpack/app/page.a2d85d19aa028de1.hot-update.js +22 -0
  126. package/packages/web/.next/static/webpack/{webpack.6fee6306e0f98869.hot-update.js → webpack.16f18baa938a434c.hot-update.js} +2 -2
  127. package/packages/web/.next/static/webpack/{webpack.73e341375c8d429e.hot-update.js → webpack.5fe9fe8578f9c3d2.hot-update.js} +2 -2
  128. package/packages/web/.next/static/webpack/webpack.653e365406c0d9ac.hot-update.js +12 -0
  129. package/packages/web/.next/static/webpack/webpack.6800169a899e3a8b.hot-update.js +12 -0
  130. package/packages/web/.next/static/webpack/webpack.73c7d02260cc80e4.hot-update.js +12 -0
  131. package/packages/web/.next/static/webpack/webpack.a2d85d19aa028de1.hot-update.js +12 -0
  132. package/packages/web/.next/trace +2 -5
  133. package/packages/web/app/globals.css +197 -51
  134. package/packages/web/app/layout.tsx +6 -3
  135. package/packages/web/app/page.tsx +791 -309
  136. package/packages/web/bun.lock +66 -105
  137. package/packages/web/next.config.ts +8 -1
  138. package/packages/web/package.json +5 -2
  139. package/packages/web/postcss.config.mjs +2 -2
  140. package/packages/web/public/apple-icon.png +1 -0
  141. package/packages/web/public/dependency-bottleneck.png +0 -0
  142. package/packages/web/public/icon-dark-32x32.png +1 -0
  143. package/packages/web/public/icon-light-32x32.png +1 -0
  144. package/packages/web/public/icon.svg +1 -0
  145. package/packages/web/public/nextjs-cve-announcement.png +0 -0
  146. package/packages/web/public/phantomraven-npm-attack.png +0 -0
  147. package/packages/web/public/placeholder-logo.png +1 -0
  148. package/packages/web/public/placeholder-logo.svg +1 -0
  149. package/packages/web/public/placeholder-user.jpg +1 -0
  150. package/packages/web/public/placeholder.jpg +1 -0
  151. package/packages/web/public/placeholder.svg +1 -0
  152. package/packages/web/public/react-cve-meme.png +0 -0
  153. package/packages/web/public/wallet-drain-exploit.png +0 -0
  154. package/packages/web/styles/globals.css +125 -0
  155. package/packages/web/.next/server/vendor-chunks/@swc.js +0 -55
  156. package/packages/web/.next/server/vendor-chunks/next.js +0 -3010
  157. package/packages/web/.next/static/chunks/app-pages-internals.js +0 -182
  158. package/packages/web/.next/static/chunks/main-app.js +0 -1882
  159. package/packages/web/.next/static/css/app/layout.css +0 -1237
  160. package/packages/web/.next/static/webpack/633457081244afec._.hot-update.json +0 -1
  161. package/packages/web/.next/static/webpack/app/page.6fee6306e0f98869.hot-update.js +0 -22
  162. package/packages/web/.next/static/webpack/app/page.73e341375c8d429e.hot-update.js +0 -22
  163. package/packages/web/tailwind.config.ts +0 -48
  164. /package/packages/web/.next/static/chunks/{polyfills.js → polyfills-42372ed130431b0a.js} +0 -0
  165. /package/packages/web/.next/static/webpack/{6fee6306e0f98869.webpack.hot-update.json → 653e365406c0d9ac.webpack.hot-update.json} +0 -0
  166. /package/packages/web/.next/static/webpack/{73e341375c8d429e.webpack.hot-update.json → 6800169a899e3a8b.webpack.hot-update.json} +0 -0
package/docs/cli/push.mdx CHANGED
@@ -1,37 +1,11 @@
1
1
  ---
2
2
  title: 'opm push'
3
- description: 'Sign, scan, publish, and register a package on-chain.'
3
+ description: 'Sign, scan, publish, register on-chain, write ENS records.'
4
4
  ---
5
5
 
6
6
  # opm push
7
7
 
8
- Sign, scan, publish, and register a package on-chain. The full verification pipeline runs before publishing to npm and registering on the OPMRegistry.
9
-
10
- ## What It Does
11
-
12
- <Steps>
13
- <Step title="Pack tarball">
14
- Creates an npm tarball via <code>npm pack</code> and computes SHA-256 checksum over the packed file.
15
- </Step>
16
- <Step title="Sign checksum">
17
- Signs the checksum with ECDSA (secp256k1) using your <code>OPM_SIGNING_KEY</code>.
18
- </Step>
19
- <Step title="Resolve ENS">
20
- Resolves your wallet address to an ENS name (Base Sepolia, then Ethereum Mainnet fallback).
21
- </Step>
22
- <Step title="Security scan">
23
- Runs 3 AI agents in parallel (Claude, Gemini, DeepSeek) to analyze the package. Each agent submits a risk score (0–100) and reasoning on-chain.
24
- </Step>
25
- <Step title="Risk check">
26
- If aggregate score ≥ 80 or risk level is CRITICAL, publishing is blocked.
27
- </Step>
28
- <Step title="Publish to npm">
29
- Publishes the tarball to the npm registry (uses <code>--token</code> or <code>NPM_TOKEN</code> for automation).
30
- </Step>
31
- <Step title="Register on-chain">
32
- Calls <code>OPMRegistry.registerPackage()</code> with package name, version, checksum, signature, and ENS name.
33
- </Step>
34
- </Steps>
8
+ The full publish pipeline: sign your package, scan with 3 AI agents, publish to npm, register on-chain, upload audit report, and write ENS text records.
35
9
 
36
10
  ## Usage
37
11
 
@@ -51,49 +25,58 @@ opm push --otp <code>
51
25
 
52
26
  </CodeGroup>
53
27
 
28
+ ## What Happens
29
+
30
+ <Steps>
31
+ <Step title="Pack & sign">
32
+ Creates tarball via `npm pack`, computes SHA-256 checksum, signs with ECDSA using `OPM_SIGNING_KEY`.
33
+ </Step>
34
+ <Step title="Resolve ENS">
35
+ Resolves your wallet to an ENS name (Sepolia → Mainnet fallback).
36
+ </Step>
37
+ <Step title="AI scan">
38
+ 3 agents (Claude, Gemini, DeepSeek) analyze in parallel. Each submits a risk score on-chain.
39
+ </Step>
40
+ <Step title="Risk gate">
41
+ Aggregate score ≥ 80 or CRITICAL → **publish blocked**.
42
+ </Step>
43
+ <Step title="Publish to npm">
44
+ Publishes tarball to the npm registry.
45
+ </Step>
46
+ <Step title="Register on-chain">
47
+ Calls `OPMRegistry.registerPackage()` with checksum, signature, ENS name.
48
+ </Step>
49
+ <Step title="Upload report">
50
+ Formatted markdown report uploaded to Fileverse (IPFS-backed, encrypted).
51
+ </Step>
52
+ <Step title="Write ENS records">
53
+ Sets `opm.version`, `opm.checksum`, `opm.fileverse`, `opm.risk_score`, and more on your ENS name. Creates package subname (e.g. `express.djpai.eth`) if you own the parent. Sets contenthash to Fileverse IPFS CID.
54
+ </Step>
55
+ </Steps>
56
+
54
57
  ## Required Environment Variables
55
58
 
56
59
  | Variable | Purpose |
57
60
  |----------|---------|
58
- | `OPM_SIGNING_KEY` | Ethereum private key for package signing (ECDSA) |
59
- | `OPENROUTER_API_KEY` or `OPENAI_API_KEY` | At least one required for AI agent scanning |
60
- | `AGENT_PRIVATE_KEY` | Agent wallet for submitting scores on-chain (must hold Base Sepolia ETH for gas) |
61
+ | `OPM_SIGNING_KEY` | Ethereum private key for ECDSA signing |
62
+ | `OPENROUTER_API_KEY` or `OPENAI_API_KEY` | AI agent scanning |
63
+ | `AGENT_PRIVATE_KEY` | Agent wallet for on-chain score submission (needs Base Sepolia ETH) |
61
64
 
62
- ## Optional Environment Variables
65
+ ## Optional
63
66
 
64
67
  | Variable | Purpose |
65
68
  |----------|---------|
66
- | `NPM_TOKEN` | npm automation token (alternative to <code>--token</code> flag) |
67
- | `FILEVERSE_API_KEY` | Upload audit report to IPFS via Fileverse |
68
-
69
- ## Risk Blocking
69
+ | `NPM_TOKEN` | npm automation token (alternative to `--token` flag) |
70
+ | `FILEVERSE_API_KEY` | Audit report uploads |
70
71
 
71
72
  <Warning>
72
- Packages with **risk score ≥ 80** or **CRITICAL** level are blocked from publishing. The scan step fails, npm publish is skipped, and on-chain registration does not occur.
73
+ Packages with **risk score ≥ 80** are blocked. The scan fails, npm publish is skipped, and no on-chain registration occurs.
73
74
  </Warning>
74
75
 
75
- When blocked, the CLI shows which agents scored the package and the aggregate risk. Fix the issues and run <code>opm push</code> again.
76
-
77
- ## What Gets Stored On-Chain
78
-
79
- After a successful push, the following data is recorded on the OPMRegistry:
80
-
81
- | Data | Description |
82
- |------|-------------|
83
- | Package name | From <code>package.json</code> |
84
- | Version | Semantic version |
85
- | Checksum | SHA-256 hash of the tarball |
86
- | Signature | ECDSA signature of the checksum |
87
- | ENS name | Author identity (e.g. <code>vitalik.eth</code>) |
88
- | Agent scores | Per-agent risk scores and reasoning |
89
- | Report URI | Fileverse/IPFS link to the full audit report |
90
-
91
76
  ## Output
92
77
 
93
- - **Etherscan links** for every transaction: score submissions (one per agent) and package registration
94
- - **Report URI** link when uploaded to Fileverse
95
- - **npm package URL** on successful publish
78
+ Every transaction shows a clickable BaseScan link: score submissions, package registration, ENS record writes. Plus the Fileverse report URI and npm package URL.
96
79
 
97
80
  <Note>
98
- If 2FA is enabled on your npm account, use <code>opm push --otp &lt;code&gt;</code> or an npm automation token with "bypass 2FA" enabled.
81
+ See [ENS Text Records](/concepts/ens-records) for the full list of records written during push.
99
82
  </Note>
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: 'opm register-agent'
3
- description: 'Register a new security agent with ZK-verified benchmarks.'
3
+ description: 'Register a new AI security agent with ZK-verified benchmarks.'
4
4
  ---
5
5
 
6
6
  # opm register-agent
7
7
 
8
- Register a new security agent with ZK-verified benchmarks. Agents must pass 10 benchmark cases with 100% accuracy and produce a valid ZK proof before they can submit scores on-chain.
8
+ Register your own security agent. Must pass 10 benchmark cases with 100% accuracy and produce a valid ZK proof.
9
9
 
10
10
  ## Usage
11
11
 
@@ -15,66 +15,34 @@ opm register-agent --name <name> --model <model> [--system-prompt <prompt>]
15
15
 
16
16
  | Flag | Required | Description |
17
17
  |------|----------|-------------|
18
- | <code>--name</code> | Yes | Agent identifier (e.g. <code>my-security-agent</code>) |
19
- | <code>--model</code> | Yes | LLM model (e.g. <code>anthropic/claude-sonnet-4-20250514</code>) |
20
- | <code>--system-prompt</code> | No | Custom system prompt (defaults to OPM security auditor prompt) |
18
+ | `--name` | Yes | Agent identifier |
19
+ | `--model` | Yes | LLM model (e.g. `anthropic/claude-sonnet-4-20250514`) |
20
+ | `--system-prompt` | No | Custom system prompt (defaults to OPM security auditor) |
21
+
22
+ ## Process
23
+
24
+ 1. **Validate** — Checks agent name, model, env vars
25
+ 2. **Benchmark** — Sends 10 labeled cases in a single LLM call (3 clean, 7 malicious)
26
+ 3. **ZK proof** — Generates proof of 100% accuracy without revealing test data
27
+ 4. **Register** — Calls `OPMRegistry.registerAgent()` with name, model, system prompt hash, proof hash
21
28
 
22
29
  ## Required Environment Variables
23
30
 
24
31
  | Variable | Purpose |
25
32
  |----------|---------|
26
- | <code>AGENT_PRIVATE_KEY</code> | Wallet that becomes the agent identity; must hold Base Sepolia ETH for gas |
27
- | <code>OPENROUTER_API_KEY</code> or <code>OPENAI_API_KEY</code> | Required to run benchmark LLM calls |
28
-
29
- ## Process
33
+ | `AGENT_PRIVATE_KEY` | Wallet that becomes the agent identity (needs Base Sepolia ETH) |
34
+ | `OPENROUTER_API_KEY` or `OPENAI_API_KEY` | LLM access for benchmark calls |
30
35
 
31
- <Steps>
32
- <Step title="Validate configuration">
33
- Checks agent name, model, and required env vars.
34
- </Step>
35
- <Step title="Run benchmark suite">
36
- Executes 10 labeled test cases across categories: clean, typosquat, malicious, cve, obfuscated, exfiltration, dependency_confusion.
37
- </Step>
38
- <Step title="Generate ZK proof">
39
- Produces a zero-knowledge proof that the agent achieved 100% accuracy without revealing test data or expected outputs.
40
- </Step>
41
- <Step title="Register on-chain">
42
- Calls <code>OPMRegistry.registerAgent()</code> with name, model, system prompt hash, and proof hash.
43
- </Step>
44
- </Steps>
36
+ ## On Success
45
37
 
46
- ## Benchmark Categories
38
+ - BaseScan transaction link shown
39
+ - Agent authorized to submit scores
40
+ - Participates in all future package scans
47
41
 
48
- | Category | Count | Description |
49
- |----------|-------|-------------|
50
- | clean | 3 | Legitimate packages (string utils, math, validator) |
51
- | typosquat | 1 | Typosquat with credential exfiltration |
52
- | malicious | 2 | Postinstall shell, SSH key exfiltration |
53
- | cve | 1 | Known prototype pollution CVE |
54
- | obfuscated | 1 | Obfuscated reverse shell |
55
- | exfiltration | 1 | Env var exfiltration on import |
56
- | dependency_confusion | 1 | Internal scope shadowing + exfiltration |
42
+ ## On Failure
57
43
 
58
- ## Requirements
44
+ Shows which cases were misclassified, expected vs actual verdict, and rejection reason.
59
45
 
60
46
  <Warning>
61
- **100% accuracy** is required. The agent must pass all 10 benchmark cases. Each case is evaluated by score range and risk level ordinal.
47
+ **100% accuracy required.** No partial passes. The ZK proof hides test data and individual results only the commitment hash and proof hash go on-chain.
62
48
  </Warning>
63
-
64
- <Note>
65
- The ZK proof hides test data and individual results. Only the commitment hash and proof hash are stored on-chain.
66
- </Note>
67
-
68
- ## Success
69
-
70
- On success:
71
- - Etherscan transaction link is shown
72
- - Agent is authorized to submit scores
73
- - Agent participates in the next package scan alongside existing agents
74
-
75
- ## Failure
76
-
77
- On failure, the CLI shows:
78
- - Which benchmark cases failed and why
79
- - Expected vs actual risk level and score
80
- - Rejection reason (e.g. "Agent achieved 90% accuracy (100% required)")
package/docs/cli/view.mdx CHANGED
@@ -1,52 +1,35 @@
1
1
  ---
2
2
  title: 'opm view / opm whois'
3
- description: 'Author profile and published packages.'
3
+ description: 'Author profile, reputation, and published packages.'
4
4
  ---
5
5
 
6
6
  # opm view / opm whois
7
7
 
8
- Show author profile and published packages. Resolves ENS identity and displays on-chain reputation.
8
+ Look up an author's ENS profile, OPM reputation, and published packages.
9
9
 
10
10
  ## Usage
11
11
 
12
12
  <CodeGroup>
13
13
 
14
- ```bash View by ENS name
15
- opm view vitalik.eth
14
+ ```bash By ENS name
15
+ opm view djpai.eth
16
16
  ```
17
17
 
18
18
  ```bash Whois (auto-appends .eth)
19
- opm whois vitalik
19
+ opm whois djpai
20
20
  ```
21
21
 
22
22
  </CodeGroup>
23
23
 
24
24
  <Note>
25
- <code>opm view &lt;name.eth&gt;</code> shows author profile. <code>opm view &lt;pkg&gt;</code> (without <code>.eth</code>) delegates to <code>opm info</code>.
25
+ `opm view <name.eth>` shows author profile. `opm view <pkg>` (without `.eth`) delegates to `opm info`.
26
26
  </Note>
27
27
 
28
- ## Output
28
+ ## What It Shows
29
29
 
30
- ### Identity
30
+ - **Identity** — ENS name, wallet address, bio, URL, GitHub, Twitter, email, avatar
31
+ - **Author stats** — Packages published, average reputation score
32
+ - **OPM ENS records** — `opm.version`, `opm.fileverse`, `opm.risk_score`, `opm.packages`, contenthash
33
+ - **Published packages** — Name, version, risk score, checksum, signature status, report link
31
34
 
32
- - **ENS name** Resolved identity
33
- - **Address** — Wallet address
34
- - **Bio** — ENS description text record
35
- - **URL** — ENS url record
36
- - **GitHub** — <code>com.github</code> text record
37
- - **Twitter** — <code>com.twitter</code> text record
38
- - **Email** — ENS email record
39
- - **Avatar** — Rendered from ENS avatar record
40
-
41
- ### Author Stats
42
-
43
- - **Packages published** — Count from OPMRegistry
44
- - **Avg reputation** — Risk badge (lower = better)
45
-
46
- ### Published Packages
47
-
48
- For each package: name, version, risk score, checksum, signature status, and report URI link.
49
-
50
- <Note>
51
- No environment variables are required. ENS resolution uses public resolvers.
52
- </Note>
35
+ No environment variables required. Uses public ENS resolvers.
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: 'ENS Text Records'
3
+ description: 'Package metadata stored on ENS for decentralized discovery.'
4
+ ---
5
+
6
+ # ENS Text Records
7
+
8
+ When you publish via `opm push`, package metadata is written to your ENS name as text records — creating a decentralized discovery layer independent of the smart contract.
9
+
10
+ ## Record Keys
11
+
12
+ ### Author-Level (on `djpai.eth`)
13
+
14
+ | Key | Example |
15
+ |-----|---------|
16
+ | `opm.version` | `1.2.3` |
17
+ | `opm.checksum` | `0x8a3f...` |
18
+ | `opm.fileverse` | Fileverse report URI |
19
+ | `opm.risk_score` | `12` |
20
+ | `opm.signature` | ECDSA signature |
21
+ | `opm.contract` | Registry contract address |
22
+ | `opm.packages` | `express,lodash` |
23
+
24
+ ### Per-Package (namespaced)
25
+
26
+ `opm.pkg.<name>.version`, `opm.pkg.<name>.checksum`, `opm.pkg.<name>.fileverse`, etc.
27
+
28
+ ## Subnames
29
+
30
+ OPM creates ENS subnames like `express.djpai.eth` during `opm push` if you own the parent name. Each subname gets its own text records for per-package resolution.
31
+
32
+ ## Contenthash
33
+
34
+ The ENS `contenthash` is set to the Fileverse IPFS CID — read directly from the Fileverse Portal smart contract. This makes audit reports discoverable via standard ENS contenthash resolution.
35
+
36
+ ## When Records Are Used
37
+
38
+ - **`opm push`** — Writes all records after on-chain registration
39
+ - **`opm info`** / **`opm view`** — Reads and displays records alongside on-chain data
40
+ - **`opm install express@djpai.eth`** — Resolves the ENS author, reads metadata
41
+
42
+ <Note>
43
+ Writing records requires the signer (`OPM_SIGNING_KEY`) to own/manage the ENS name. Reading is permissionless.
44
+ </Note>
@@ -1,58 +1,40 @@
1
1
  ---
2
2
  title: 'Multi-Agent Consensus'
3
- description: 'Three LLMs run in parallel, submit scores on-chain, and aggregate via intelligence-weighted averaging.'
3
+ description: 'Three LLMs scan in parallel, submit scores on-chain, aggregate via intelligence-weighted averaging.'
4
4
  ---
5
5
 
6
6
  # Multi-Agent Consensus
7
7
 
8
- OPM uses **three heterogeneous AI agents** that run in parallel to analyze packages. Each agent independently evaluates source code, version history, and CVE data, then submits its risk score and reasoning on-chain. Scores are aggregated using **intelligence-weighted averaging** to produce a final risk assessment.
8
+ Three different AI models analyze every package in parallel. Each submits an independent risk score on-chain. Scores are aggregated using intelligence-weighted averaging.
9
9
 
10
- ## Agent Configuration
10
+ ## Agent Lineup
11
11
 
12
- | Agent | OpenRouter (preferred) | OpenAI (fallback) |
13
- |-------|------------------------|--------------------|
12
+ | Agent | OpenRouter | OpenAI fallback |
13
+ |-------|-----------|----------------|
14
14
  | agent-1 | Claude Sonnet 4 | GPT-4.1 |
15
15
  | agent-2 | Gemini 2.5 Flash | GPT-4.1 Mini |
16
16
  | agent-3 | DeepSeek Chat | GPT-4.1 Nano |
17
17
 
18
- Model diversity reduces single-model blind spots and improves consensus reliability. Override models via `AGENT1_MODEL`, `AGENT2_MODEL`, and `AGENT3_MODEL`.
18
+ Model diversity reduces single-model blind spots. Override via `AGENT1_MODEL`, `AGENT2_MODEL`, `AGENT3_MODEL`.
19
19
 
20
- ## Analysis Pipeline
20
+ ## What Each Agent Does
21
21
 
22
- Each agent receives:
22
+ 1. Receives package source, `package.json`, version history, and any known CVEs
23
+ 2. Produces structured JSON: risk score (0-100), risk level, reasoning, vulnerability list, supply chain indicators
24
+ 3. Submits score on-chain via `OPMRegistry.submitScore()`
23
25
 
24
- - Packed tarball contents (scannable extensions: `.js`, `.ts`, `.mjs`, `.cjs`, `.json`)
25
- - `package.json` and dependency metadata
26
- - Version history and changelog context
27
- - CVE/OSV advisory data when available
26
+ Each agent scores a version only once.
28
27
 
29
- Each agent produces structured JSON:
28
+ ## Intelligence-Weighted Scoring
30
29
 
31
- - **Risk score** (0–100) with categorical classification (LOW, MEDIUM, HIGH, CRITICAL)
32
- - **Vulnerability enumeration** with severity, category, file path, and evidence
33
- - **Supply chain indicators**: install scripts, native bindings, obfuscated code, network calls, filesystem access, process spawning, `eval` usage, environment variable access
34
- - **Version history analysis**: changelog risk, maintainer changes, dependency graph mutations
35
- - **Recommendation**: SAFE, CAUTION, WARN, or BLOCK
36
-
37
- ## On-Chain Submission
38
-
39
- Agent wallets call `OPMRegistry.submitScore(name, version, riskScore, reasoning)` for each package version. Each agent may submit only once per version. Scores are stored in the contract's `versionData` mapping.
40
-
41
- ## Intelligence-Weighted Aggregation
42
-
43
- Scores are aggregated using model weights from the **Artificial Analysis API**:
44
-
45
- - **Intelligence Index**: General reasoning and knowledge
46
- - **Coding Index**: Code generation and analysis capability
47
-
48
- Weights are applied to each agent's score before computing the mean. This favors higher-capability models when consensus is ambiguous.
30
+ When `ARTIFICIAL_ANALYSIS_API_KEY` is set, scores are weighted by each model's Intelligence Index and Coding Index from the Artificial Analysis API. Higher-capability models carry more weight in the final score.
49
31
 
50
32
  <Note>
51
- If `ARTIFICIAL_ANALYSIS_API_KEY` is unset or the API is unavailable, OPM falls back to **equal weighting** (simple arithmetic mean).
33
+ Without the API key, agents are weighted equally (simple mean).
52
34
  </Note>
53
35
 
54
- ## Fallback Behavior
36
+ ## Provider Routing
55
37
 
56
- - **Provider**: When `OPENROUTER_API_KEY` is set, OPM routes through OpenRouter. Otherwise it uses `OPENAI_API_KEY` with the GPT-4.1 family.
57
- - **Force provider**: Set `LLM_PROVIDER=openrouter` or `LLM_PROVIDER=openai` to override auto-detection.
58
- - **OpenAI models**: `gpt-4.1`, `gpt-4.1-mini`, `gpt-4.1-nano` for agent-1, agent-2, agent-3 respectively.
38
+ - `OPENROUTER_API_KEY` set routes through OpenRouter (multi-model)
39
+ - Only `OPENAI_API_KEY` falls back to GPT-4.1 family
40
+ - Force a provider: `LLM_PROVIDER=openrouter` or `LLM_PROVIDER=openai`
@@ -1,72 +1,45 @@
1
1
  ---
2
2
  title: 'On-chain Registry'
3
- description: 'OPMRegistry.sol stores packages, versions, author profiles, agent scores, and report URIs on Base Sepolia.'
3
+ description: 'OPMRegistry.sol on Base Sepolia packages, scores, authors, agents.'
4
4
  ---
5
5
 
6
6
  # On-chain Registry
7
7
 
8
- The **OPMRegistry** smart contract is the canonical on-chain store for package metadata, author profiles, agent scores, and report URIs. It implements a domain-specific form of the [ERC-8004 (Trustless Agents)](https://eips.ethereum.org/EIPS/eip-8004) three-registry architecture.
8
+ The **OPMRegistry** smart contract is the source of truth for package metadata, agent scores, author reputation, and registered agents.
9
9
 
10
10
  ## Deployment
11
11
 
12
12
  | Property | Value |
13
13
  |----------|-------|
14
- | **Chain** | Base Sepolia |
15
- | **Chain ID** | 84532 |
16
- | **Contract Address** | `0x16684391fc9bf48246B08Afe16d1a57BFa181d48` |
17
- | **Explorer** | [BaseScan](https://sepolia.basescan.org/address/0x16684391fc9bf48246B08Afe16d1a57BFa181d48) |
14
+ | **Chain** | Base Sepolia (84532) |
15
+ | **Address** | [`0x16684391fc9bf48246B08Afe16d1a57BFa181d48`](https://sepolia.basescan.org/address/0x16684391fc9bf48246B08Afe16d1a57BFa181d48) |
16
+ | **Solidity** | 0.8.20 |
18
17
 
19
- Override via `CONTRACT_ADDRESS` in your environment.
18
+ ## What It Stores
20
19
 
21
- ## Data Structures
20
+ | Data | Description |
21
+ |------|-------------|
22
+ | **Packages** | Name → version → checksum, signature, author, ENS name, report URI |
23
+ | **Agent scores** | Per-version risk scores (0-100) with reasoning from each agent |
24
+ | **Authors** | Wallet → ENS name, cumulative reputation, package count |
25
+ | **Agents** | Authorized agents (owner-set or ZK-verified) with name, model, proof hash |
22
26
 
23
- | Struct | Fields |
24
- |--------|--------|
25
- | `AuthorProfile` | `addr`, `ensName`, `reputationTotal`, `reputationCount`, `packagesPublished` |
26
- | `AgentScore` | `agent`, `riskScore`, `reasoning` |
27
- | `VersionData` | `author`, `checksum`, `signature`, `reportURI`, `scores[]`, `exists` |
28
- | `Package` | `name`, `versions[]`, `exists` |
29
- | `RegisteredAgent` | `agentAddress`, `name`, `model`, `systemPromptHash`, `proofHash`, `registeredAt`, `active` |
27
+ ## Key Operations
30
28
 
31
- ## Key Functions
29
+ - **`registerPackage`** — Store a new version with checksum, signature, and ENS binding
30
+ - **`submitScore`** — Agent submits risk score + reasoning (authorized agents only)
31
+ - **`setReportURI`** — Attach Fileverse/IPFS report link to a version
32
+ - **`registerAgent`** — Permissionless agent registration with ZK proof hash
33
+ - **`getSafestVersion`** — Get the lowest-risk version in a lookback window
34
+ - **`getPackageInfo`** — Full metadata + aggregate score for a version
32
35
 
33
- | Function | Access | Description |
34
- |----------|--------|-------------|
35
- | `registerPackage(name, version, checksum, sig, ensName)` | Public | Register a new package version with checksum, signature, and ENS binding |
36
- | `submitScore(name, version, riskScore, reasoning)` | Authorized agents | Submit a risk score (0–100) and reasoning for a package version |
37
- | `setReportURI(name, version, uri)` | Authorized agents | Attach a Fileverse report URI to a package version |
38
- | `getPackageInfo(name, version)` | View | Retrieve full metadata and aggregate score for a package version |
39
- | `getScores(name, version)` | View | Return all individual agent scores for a version |
40
- | `getAggregateScore(name, version)` | View | Compute mean risk score across all agent submissions |
41
- | `getSafestVersion(name, lookback)` | View | Return the lowest-risk version within a configurable lookback window |
42
- | `getVersions(name)` | View | List all registered versions of a package |
43
- | `getAuthorByAddress(addr)` | View | Retrieve author profile by Ethereum address |
44
- | `getAuthorByENS(ensName)` | View | Resolve author profile by ENS name |
45
- | `getAuthorReputation(addr)` | View | Compute author's mean risk score across all packages |
46
- | `registerAgent(name, model, systemPromptHash, proofHash)` | Public | Permissionless agent registration (requires valid ZK proof) |
47
-
48
- ## Events
49
-
50
- | Event | Parameters |
51
- |-------|------------|
52
- | `PackageRegistered` | `name`, `version`, `author`, `ensName` |
53
- | `ScoreSubmitted` | `name`, `version`, `agent`, `riskScore`, `reasoning` |
54
- | `ReportURISet` | `name`, `version`, `uri` |
55
- | `AuthorRegistered` | `addr`, `ensName` |
56
- | `AgentAuthorized` | `agent`, `status` |
57
- | `AgentRegistered` | `agent`, `name`, `model`, `systemPromptHash`, `proofHash`, `timestamp` |
36
+ See [Contract Functions](/contract/functions) for the complete API reference.
58
37
 
59
38
  ## Author Reputation
60
39
 
61
- Author reputation is computed as:
62
-
63
- ```
64
- reputation = reputationTotal / reputationCount
65
- ```
66
-
67
- Where `reputationTotal` accumulates each agent's score for every version of every package authored by that address. This provides a cumulative risk score average across all published packages.
40
+ Computed as `reputationTotal / reputationCount` — the average of all agent scores received across all packages published by an author. Lower is better.
68
41
 
69
- ## Risk Thresholds (Contract)
42
+ ## Risk Thresholds
70
43
 
71
44
  | Constant | Value |
72
45
  |----------|-------|
@@ -1,76 +1,44 @@
1
1
  ---
2
2
  title: 'Security Model'
3
- description: 'OPM defense-in-depth: cryptographic attestation, multi-agent AI, CVE integration, supply chain checks, and ENS-based trust.'
3
+ description: 'Five layers of defense: crypto, AI, CVEs, supply chain checks, and ENS trust.'
4
4
  ---
5
5
 
6
6
  # Security Model
7
7
 
8
- OPM employs a **defense-in-depth** architecture across five layers. No single layer is sufficient; together they mitigate supply chain injection, typosquatting, dependency confusion, maintainer takeover, and known vulnerability exploitation.
8
+ OPM layers five independent defenses. No single layer is sufficient together they catch supply chain injection, typosquatting, dependency confusion, maintainer takeover, and known CVEs.
9
9
 
10
- ## 1. Cryptographic Layer
10
+ ## 1. Cryptographic Signing
11
11
 
12
- - **SHA-256 checksum**: Computed over the packed tarball; stored on-chain and verified at install time
13
- - **ECDSA signature**: secp256k1 signature over the checksum, derived from the author's Ethereum private key
14
- - **On-chain registration**: Checksum, signature, and author binding stored in `OPMRegistry` on Base Sepolia
12
+ Every package gets a SHA-256 checksum and ECDSA signature (secp256k1) from the author's Ethereum wallet. Both are stored on-chain and verified at install time. Tampered tarballs are rejected.
15
13
 
16
- Installation is blocked if the tarball checksum does not match the on-chain value or if the signature verification fails.
14
+ ## 2. Multi-Agent AI Scanning
17
15
 
18
- ## 2. AI Layer
16
+ Three LLMs (Claude, Gemini, DeepSeek) analyze source code, dependency metadata, and version history in parallel. Each submits a risk score (0-100) on-chain. Scores are aggregated using intelligence-weighted averaging via the Artificial Analysis API.
19
17
 
20
- Three heterogeneous LLMs analyze packages in parallel:
18
+ Agents flag: install scripts, native bindings, obfuscated code, network calls, filesystem access, process spawning, `eval` usage, and env var access.
21
19
 
22
- - Static analysis of source code, dependency metadata, and version history
23
- - Each agent submits a risk score (0–100) and reasoning on-chain
24
- - **Intelligence-weighted aggregation** via the Artificial Analysis API (Intelligence Index, Coding Index)
25
- - Fallback to equal weighting if the API is unavailable
20
+ ## 3. CVE Detection
26
21
 
27
- <CardGroup cols={2}>
28
- <Card title="Agent 1" icon="robot">
29
- Claude Sonnet 4 (OpenRouter) / GPT-4.1 (OpenAI fallback)
30
- </Card>
31
- <Card title="Agent 2" icon="robot">
32
- Gemini 2.5 Flash (OpenRouter) / GPT-4.1 Mini (OpenAI fallback)
33
- </Card>
34
- <Card title="Agent 3" icon="robot">
35
- DeepSeek Chat (OpenRouter) / GPT-4.1 Nano (OpenAI fallback)
36
- </Card>
37
- </CardGroup>
22
+ Real-time lookup against the OSV database (CVE + GHSA advisories) with CVSS v3 severity scoring. CRITICAL CVEs block installation. HIGH CVEs trigger warnings with suggested fix versions.
38
23
 
39
- ## 3. CVE Layer
24
+ ## 4. Supply Chain Checks
40
25
 
41
- - **OSV (Open Source Vulnerabilities)**: Real-time CVE and GHSA advisory data
42
- - **GitHub Advisory Database**: Integrated via OSV API
43
- - **CVSS v3** base score computation for severity classification
44
- - **CRITICAL** severity: installation blocked
45
- - **HIGH** severity: warning with suggested fix version
26
+ | Check | How |
27
+ |-------|-----|
28
+ | Typosquatting | Levenshtein distance against top npm packages + AI name similarity assessment |
29
+ | Dependency confusion | Scoped vs unscoped name conflicts surfaced during `opm check` |
30
+ | ChainPatrol blocklist | Fallback for packages not in the on-chain registry |
46
31
 
47
- ## 4. Supply Chain Layer
32
+ ## 5. ENS Trust Layer
48
33
 
49
- | Check | Description |
50
- |-------|-------------|
51
- | **Typosquat detection** | Package names compared against npm search results and download-count differentials; AI agents assess name similarity |
52
- | **Dependency confusion** | Scoped vs unscoped name conflicts and internal package shadowing surfaced during `opm check` |
53
- | **ChainPatrol blocklist** | Fallback blocklist for packages absent from the on-chain registry (requires `CHAINPATROL_API_KEY`) |
54
-
55
- AI agents also flag: install scripts, native bindings, obfuscated code, network calls, filesystem access, process spawning, `eval` usage, and environment variable access.
56
-
57
- ## 5. Trust Layer
58
-
59
- - **ENS identity resolution**: Author addresses resolved to ENS names (Sepolia, Mainnet fallback)
60
- - **On-chain author reputation**: Cumulative risk score average across all published packages
61
- - **Author profiles**: ENS text records (avatar, description, URL, GitHub, Twitter, email) for human verification
34
+ Author addresses resolve to ENS names. Reputation is computed as the average risk score across all published packages. ENS text records (avatar, GitHub, Twitter) provide human-verifiable identity signals.
62
35
 
63
36
  ## Risk Thresholds
64
37
 
65
- | Range | Level | Effect |
66
- |-------|-------|--------|
38
+ | Score | Level | What happens |
39
+ |-------|-------|-------------|
67
40
  | 0–20 | LOW | Safe to install |
68
41
  | 21–40 | MEDIUM | Flagged for caution |
69
42
  | 41–70 | HIGH | Warnings triggered |
70
43
  | 71–100 | CRITICAL | High risk |
71
-
72
- | Threshold | Value | Behavior |
73
- |-----------|-------|----------|
74
- | Block threshold (CLI) | 80 | `opm push` blocks publication; `opm install` blocks installation |
75
- | `HIGH_RISK_THRESHOLD` (contract) | 70 | Packages above trigger warnings |
76
- | `MEDIUM_RISK_THRESHOLD` (contract) | 40 | Packages above flagged for caution |
44
+ | **≥ 80** | — | **Blocks `opm push` and `opm install`** |