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
@@ -1,82 +1,44 @@
1
1
  ---
2
2
  title: 'ZK Agent Verification'
3
- description: 'Permissionless agent registration requires passing a benchmark suite and proving 100% accuracy via zero-knowledge proofs.'
3
+ description: 'Permissionless agent registration with zero-knowledge proof of 100% benchmark accuracy.'
4
4
  ---
5
5
 
6
6
  # ZK Agent Verification
7
7
 
8
- OPM supports **permissionless agent registration** on the on-chain registry. To prevent malicious or spamming agents from participating, agents must pass a benchmark suite and prove **100% accuracy** via a zero-knowledge proof—without revealing the test data or individual results.
8
+ Anyone can register a security agent on OPM. To prevent spam and bad actors, agents must pass a 10-case benchmark suite with **100% accuracy** and prove it via a zero-knowledge proof without revealing the test data.
9
9
 
10
10
  ## Benchmark Suite
11
11
 
12
- The benchmark consists of **10 labeled test cases** covering:
12
+ 10 labeled test cases covering:
13
13
 
14
- | Category | Description |
15
- |----------|-------------|
16
- | Clean packages | Legitimate, low-risk packages |
17
- | Typosquats | Name-similar malicious packages |
18
- | Env exfiltration | Environment variable exfiltration attempts |
19
- | Obfuscated code | Heavily obfuscated or minified payloads |
20
- | Postinstall attacks | Malicious `postinstall` scripts |
21
- | Known CVEs | Packages with known vulnerabilities |
22
- | Dependency confusion | Scoped vs unscoped name conflicts |
14
+ | Category | Cases | Expected |
15
+ |----------|-------|----------|
16
+ | Clean packages | 3 | SAFE |
17
+ | Typosquat | 1 | FLAGGED |
18
+ | Malicious (postinstall, SSH exfil) | 2 | FLAGGED |
19
+ | Known CVE | 1 | FLAGGED |
20
+ | Obfuscated payload | 1 | FLAGGED |
21
+ | Env var exfiltration | 1 | FLAGGED |
22
+ | Dependency confusion | 1 | FLAGGED |
23
23
 
24
- Each test case has an **expected output**: a risk level (LOW, MEDIUM, HIGH, CRITICAL) and score range. Expected outputs are committed via a hash before the agent runs.
24
+ ## How It Works
25
25
 
26
- ## Verification Flow
26
+ 1. **Commit** — Expected outputs hashed with a random salt → `commitmentHash`
27
+ 2. **Run** — Agent processes all 10 cases in a single LLM call
28
+ 3. **Compare** — Actual outputs checked against expected
29
+ 4. **Prove** — ZK proof binds `commitmentHash`, `resultHash`, and `passed` flag without revealing test data or individual results
30
+ 5. **Register** — If 100% accurate, call `OPMRegistry.registerAgent()` with the proof hash
27
31
 
28
- 1. **Commitment**: Expected outputs hashed with a salt `commitmentHash`
29
- 2. **Execution**: Candidate agent runs against all 10 cases
30
- 3. **Comparison**: Actual outputs compared to expected; `passed = 1` iff all match
31
- 4. **Proof**: ZK proof binds `commitmentHash`, `passed`, and `result_hash` without revealing test data or individual results
32
- 5. **Registration**: Only agents with `passed = 1` (100% accuracy) are registered on-chain
32
+ The proof proves accuracy without leaking the labeled dataset, so future agents can't game the benchmark.
33
33
 
34
34
  ## Circom Circuit
35
35
 
36
- The `accuracy_verifier.circom` circuit implements the verification logic:
36
+ `AccuracyVerifier(10)` in `packages/contracts/circuits/accuracy_verifier.circom`:
37
37
 
38
- - **Private inputs**: `expected[N]`, `actual[N]`, `salt`
39
- - **Public input**: `commitmentHash` (Poseidon hash of `salt` and `expected[0..N-1]`)
40
- - **Public outputs**: `passed` (1 if all match, 0 otherwise), `proofHash`
38
+ - **Private inputs**: `expected[10]`, `actual[10]`, `salt`
39
+ - **Public input**: `commitmentHash` (Poseidon hash of salt + expected values)
40
+ - **Public outputs**: `passed` (1 if all match), `proofHash`
41
41
 
42
- The circuit:
43
-
44
- 1. Verifies the commitment: `hash(salt, expected[0..N-1]) === commitmentHash`
45
- 2. Checks equality for each test case: `expected[i] === actual[i]`
46
- 3. Computes `passed` as the product of all match bits (1 iff all match)
47
- 4. Outputs `proofHash = hash(commitmentHash, passed, salt)` binding the result to the commitment
48
-
49
- <CodeGroup>
50
-
51
- ```bash Compile
52
- circom accuracy_verifier.circom --r1cs --wasm --sym -o build/
53
- ```
54
-
55
- ```bash Trusted setup
56
- snarkjs groth16 setup build/accuracy_verifier.r1cs pot12_final.ptau build/accuracy_verifier_0000.zkey
57
- snarkjs zkey contribute build/accuracy_verifier_0000.zkey build/accuracy_verifier_final.zkey --name="opm-ceremony"
58
- snarkjs zkey export verificationkey build/accuracy_verifier_final.zkey build/verification_key.json
59
- ```
60
-
61
- ```bash Prove
62
- snarkjs groth16 prove build/accuracy_verifier_final.zkey build/accuracy_verifier_js/accuracy_verifier.wasm input.json build/proof.json build/public.json
63
- ```
64
-
65
- ```bash Verify
66
- snarkjs groth16 verify build/verification_key.json build/public.json build/proof.json
67
- ```
68
-
69
- </CodeGroup>
70
-
71
- ## On-Chain Registration
72
-
73
- Agents call `OPMRegistry.registerAgent(name, model, systemPromptHash, proofHash)` with a valid proof hash. The contract:
74
-
75
- - Requires `proofHash != bytes32(0)`
76
- - Rejects agents already authorized or registered
77
- - Stores `RegisteredAgent` with `proofHash` for auditability
78
- - Auto-authorizes the agent for `submitScore` and `setReportURI`
79
-
80
- <Warning>
81
- The Circom circuit is available for on-chain verification. A Solidity verifier can be exported via `snarkjs zkey export solidityverifier` for full trustless verification in future contract upgrades.
82
- </Warning>
42
+ <Note>
43
+ Currently, `keccak256(proof)` is stored on-chain. Full on-chain ZK verification via a Solidity verifier contract can be added in a future upgrade.
44
+ </Note>
@@ -1,115 +1,54 @@
1
1
  ---
2
2
  title: 'Contract Events'
3
- description: 'All OPMRegistry events with parameters.'
3
+ description: 'OPMRegistry events reference.'
4
4
  ---
5
5
 
6
6
  # Contract Events
7
7
 
8
- ## PackageRegistration
9
-
10
8
  ### PackageRegistered
11
9
 
12
10
  ```solidity
13
- event PackageRegistered(string name, string version, address author, string ensName);
11
+ event PackageRegistered(string name, string version, address author, string ensName)
14
12
  ```
15
13
 
16
- Emitted when a package version is registered via <code>registerPackage</code>.
17
-
18
- | Parameter | Type | Description |
19
- |-----------|------|-------------|
20
- | name | string | Package name |
21
- | version | string | Semantic version |
22
- | author | address | Author wallet address |
23
- | ensName | string | Author ENS name |
24
-
25
- ---
26
-
27
- ## Score Submission
14
+ Emitted on `registerPackage()`.
28
15
 
29
16
  ### ScoreSubmitted
30
17
 
31
18
  ```solidity
32
- event ScoreSubmitted(string name, string version, address agent, uint8 riskScore, string reasoning);
19
+ event ScoreSubmitted(string name, string version, address agent, uint8 riskScore, string reasoning)
33
20
  ```
34
21
 
35
- Emitted when an agent submits a risk score via <code>submitScore</code>.
36
-
37
- | Parameter | Type | Description |
38
- |-----------|------|-------------|
39
- | name | string | Package name |
40
- | version | string | Semantic version |
41
- | agent | address | Agent wallet address |
42
- | riskScore | uint8 | Risk score 0–100 |
43
- | reasoning | string | Agent reasoning |
22
+ Emitted on `submitScore()`.
44
23
 
45
24
  ### ReportURISet
46
25
 
47
26
  ```solidity
48
- event ReportURISet(string name, string version, string uri);
27
+ event ReportURISet(string name, string version, string uri)
49
28
  ```
50
29
 
51
- Emitted when an agent sets the report URI via <code>setReportURI</code>.
52
-
53
- | Parameter | Type | Description |
54
- |-----------|------|-------------|
55
- | name | string | Package name |
56
- | version | string | Semantic version |
57
- | uri | string | Fileverse/IPFS report URI |
58
-
59
- ---
60
-
61
- ## Author
30
+ Emitted on `setReportURI()`.
62
31
 
63
32
  ### AuthorRegistered
64
33
 
65
34
  ```solidity
66
- event AuthorRegistered(address addr, string ensName);
35
+ event AuthorRegistered(address addr, string ensName)
67
36
  ```
68
37
 
69
- Emitted when an author is first registered (on first <code>registerPackage</code> call).
70
-
71
- | Parameter | Type | Description |
72
- |-----------|------|-------------|
73
- | addr | address | Author wallet address |
74
- | ensName | string | Author ENS name |
75
-
76
- ---
77
-
78
- ## Agent Management
38
+ Emitted on first `registerPackage()` call by an author.
79
39
 
80
40
  ### AgentAuthorized
81
41
 
82
42
  ```solidity
83
- event AgentAuthorized(address agent, bool status);
43
+ event AgentAuthorized(address agent, bool status)
84
44
  ```
85
45
 
86
- Emitted when an agent is authorized or deauthorized via <code>setAgent</code> or <code>revokeAgent</code>, or when a new agent registers via <code>registerAgent</code>.
87
-
88
- | Parameter | Type | Description |
89
- |-----------|------|-------------|
90
- | agent | address | Agent wallet address |
91
- | status | bool | true = authorized, false = deauthorized |
46
+ Emitted on `setAgent()`, `revokeAgent()`, or `registerAgent()`.
92
47
 
93
48
  ### AgentRegistered
94
49
 
95
50
  ```solidity
96
- event AgentRegistered(
97
- address indexed agent,
98
- string name,
99
- string model,
100
- bytes32 systemPromptHash,
101
- bytes32 proofHash,
102
- uint256 timestamp
103
- );
51
+ event AgentRegistered(address indexed agent, string name, string model, bytes32 systemPromptHash, bytes32 proofHash, uint256 timestamp)
104
52
  ```
105
53
 
106
- Emitted when a new agent registers via <code>registerAgent</code> (permissionless ZK-verified registration).
107
-
108
- | Parameter | Type | Description |
109
- |-----------|------|-------------|
110
- | agent | address | Agent wallet address (indexed) |
111
- | name | string | Agent identifier |
112
- | model | string | LLM model |
113
- | systemPromptHash | bytes32 | Keccak256 of system prompt |
114
- | proofHash | bytes32 | Keccak256 of ZK proof |
115
- | timestamp | uint256 | Block timestamp |
54
+ Emitted on permissionless `registerAgent()`.
@@ -1,122 +1,59 @@
1
1
  ---
2
2
  title: 'Contract Functions'
3
- description: 'All OPMRegistry functions with parameters and behavior.'
3
+ description: 'OPMRegistry function reference.'
4
4
  ---
5
5
 
6
6
  # Contract Functions
7
7
 
8
- ## Admin (Owner Only)
8
+ ## Write Functions
9
9
 
10
- ### setAgent
10
+ ### registerPackage
11
11
 
12
12
  ```solidity
13
- function setAgent(address agent, bool status) external onlyOwner
13
+ function registerPackage(string name, string version, bytes32 checksum, bytes sig, string ensName) external
14
14
  ```
15
15
 
16
- Authorize or deauthorize an agent. Only the contract owner can call this.
16
+ Register a package version. Sender becomes the author. Reverts if version already registered.
17
17
 
18
- | Parameter | Type | Description |
19
- |-----------|------|-------------|
20
- | agent | address | Agent wallet address |
21
- | status | bool | true = authorized, false = deauthorized |
22
-
23
- ### revokeAgent
18
+ ### submitScore
24
19
 
25
20
  ```solidity
26
- function revokeAgent(address agent) external onlyOwner
21
+ function submitScore(string name, string version, uint8 riskScore, string reasoning) external onlyAgent
27
22
  ```
28
23
 
29
- Deactivate a registered agent. Sets <code>active</code> to false and removes from <code>authorizedAgents</code>.
30
-
31
- ---
32
-
33
- ## Package Registration (Public)
24
+ Submit risk score (0-100) with reasoning. Each agent may score a version once.
34
25
 
35
- ### registerPackage
26
+ ### setReportURI
36
27
 
37
28
  ```solidity
38
- function registerPackage(
39
- string calldata name,
40
- string calldata version,
41
- bytes32 checksum,
42
- bytes calldata sig,
43
- string calldata ensName
44
- ) external
29
+ function setReportURI(string name, string version, string uri) external onlyAgent
45
30
  ```
46
31
 
47
- Register a package version. Callable by anyone; the sender becomes the author.
48
-
49
- | Parameter | Type | Description |
50
- |-----------|------|-------------|
51
- | name | string | Package name |
52
- | version | string | Semantic version |
53
- | checksum | bytes32 | SHA-256 of tarball |
54
- | sig | bytes | ECDSA signature of checksum |
55
- | ensName | string | Author ENS name (e.g. vitalik.eth) |
56
-
57
- Reverts if the version is already registered.
32
+ Attach a Fileverse/IPFS report URI to a package version.
58
33
 
59
- ---
60
-
61
- ## Agent-Only (Authorized Agents)
62
-
63
- ### submitScore
34
+ ### registerAgent
64
35
 
65
36
  ```solidity
66
- function submitScore(
67
- string calldata name,
68
- string calldata version,
69
- uint8 riskScore,
70
- string calldata reasoning
71
- ) external onlyAgent
37
+ function registerAgent(string name, string model, bytes32 systemPromptHash, bytes32 proofHash) external
72
38
  ```
73
39
 
74
- Submit a risk score (0–100) for a package version. Each agent may score a version only once.
75
-
76
- | Parameter | Type | Description |
77
- |-----------|------|-------------|
78
- | name | string | Package name |
79
- | version | string | Semantic version |
80
- | riskScore | uint8 | Risk score 0–100 |
81
- | reasoning | string | Agent reasoning |
40
+ Permissionless agent registration. Requires non-zero `proofHash`. Reverts if sender already authorized or registered.
82
41
 
83
- ### setReportURI
42
+ ### setAgent
84
43
 
85
44
  ```solidity
86
- function setReportURI(
87
- string calldata name,
88
- string calldata version,
89
- string calldata uri
90
- ) external onlyAgent
45
+ function setAgent(address agent, bool status) external onlyOwner
91
46
  ```
92
47
 
93
- Set the Fileverse/IPFS report URI for a package version.
48
+ Owner-only: authorize or deauthorize an agent.
94
49
 
95
- ---
96
-
97
- ## Permissionless Agent Registration
98
-
99
- ### registerAgent
50
+ ### revokeAgent
100
51
 
101
52
  ```solidity
102
- function registerAgent(
103
- string calldata name,
104
- string calldata model,
105
- bytes32 systemPromptHash,
106
- bytes32 proofHash
107
- ) external
53
+ function revokeAgent(address agent) external onlyOwner
108
54
  ```
109
55
 
110
- Register a new agent with ZK-verified benchmark proof. Callable by anyone; the sender becomes the agent.
111
-
112
- | Parameter | Type | Description |
113
- |-----------|------|-------------|
114
- | name | string | Agent identifier |
115
- | model | string | LLM model (e.g. anthropic/claude-sonnet-4) |
116
- | systemPromptHash | bytes32 | Keccak256 of system prompt |
117
- | proofHash | bytes32 | Keccak256 of ZK proof |
118
-
119
- Reverts if the sender is already authorized or registered, or if <code>proofHash</code> is zero.
56
+ Owner-only: deactivate a registered agent.
120
57
 
121
58
  ---
122
59
 
@@ -125,91 +62,68 @@ Reverts if the sender is already authorized or registered, or if <code>proofHash
125
62
  ### getPackageInfo
126
63
 
127
64
  ```solidity
128
- function getPackageInfo(string calldata name, string calldata version)
129
- external view returns (
130
- address author,
131
- bytes32 checksum,
132
- bytes memory sig,
133
- string memory ensName,
134
- string memory reportURI,
135
- uint8 aggregateScore,
136
- bool exists
137
- )
65
+ function getPackageInfo(string name, string version)
66
+ external view returns (address author, bytes32 checksum, bytes sig, string ensName, string reportURI, uint8 aggregateScore, bool exists)
138
67
  ```
139
68
 
140
- Returns full package info for a version. <code>aggregateScore</code> is the mean of all agent scores.
69
+ Full metadata + aggregate score for a version.
141
70
 
142
71
  ### getScores
143
72
 
144
73
  ```solidity
145
- function getScores(string calldata name, string calldata version)
146
- external view returns (AgentScore[] memory)
74
+ function getScores(string name, string version) external view returns (AgentScore[] memory)
147
75
  ```
148
76
 
149
- Returns all agent scores for a package version. Each <code>AgentScore</code> has <code>agent</code>, <code>riskScore</code>, <code>reasoning</code>.
77
+ All agent scores for a version. Each has `agent`, `riskScore`, `reasoning`.
150
78
 
151
79
  ### getAggregateScore
152
80
 
153
81
  ```solidity
154
- function getAggregateScore(string calldata name, string calldata version)
155
- external view returns (uint8)
82
+ function getAggregateScore(string name, string version) external view returns (uint8)
156
83
  ```
157
84
 
158
- Returns the mean risk score (0 if no scores).
85
+ Mean risk score across all agents (0 if no scores).
159
86
 
160
87
  ### getSafestVersion
161
88
 
162
89
  ```solidity
163
- function getSafestVersion(string calldata name, uint8 lookback)
164
- external view returns (string memory)
90
+ function getSafestVersion(string name, uint8 lookback) external view returns (string memory)
165
91
  ```
166
92
 
167
- Returns the lowest-risk version among the last <code>lookback</code> versions. Default lookback is 3.
93
+ Lowest-risk version in the last `lookback` versions.
168
94
 
169
95
  ### getVersions
170
96
 
171
97
  ```solidity
172
- function getVersions(string calldata name)
173
- external view returns (string[] memory)
174
- ```
175
-
176
- Returns all registered versions for a package.
177
-
178
- ### getAuthorByAddress
179
-
180
- ```solidity
181
- function getAuthorByAddress(address addr)
182
- external view returns (AuthorProfile memory)
98
+ function getVersions(string name) external view returns (string[] memory)
183
99
  ```
184
100
 
185
- Returns author profile by wallet address. <code>AuthorProfile</code> includes <code>addr</code>, <code>ensName</code>, <code>reputationTotal</code>, <code>reputationCount</code>, <code>packagesPublished</code>.
101
+ All registered versions of a package.
186
102
 
187
- ### getAuthorByENS
103
+ ### getAuthorByAddress / getAuthorByENS
188
104
 
189
105
  ```solidity
190
- function getAuthorByENS(string calldata ensName)
191
- external view returns (AuthorProfile memory)
106
+ function getAuthorByAddress(address addr) external view returns (AuthorProfile memory)
107
+ function getAuthorByENS(string ensName) external view returns (AuthorProfile memory)
192
108
  ```
193
109
 
194
- Returns author profile by ENS name. Reverts if ENS not found.
110
+ Author profile: `addr`, `ensName`, `reputationTotal`, `reputationCount`, `packagesPublished`.
195
111
 
196
112
  ### getAuthorReputation
197
113
 
198
114
  ```solidity
199
- function getAuthorReputation(address addr)
200
- external view returns (uint256)
115
+ function getAuthorReputation(address addr) external view returns (uint256)
201
116
  ```
202
117
 
203
- Returns average reputation (mean of all scores received) for an author. 0 if no scores.
118
+ Average reputation (mean of all scores received). 0 if no scores.
204
119
 
205
120
  ### getRegisteredAgent
206
121
 
207
122
  ```solidity
208
- function getRegisteredAgent(address agent)
209
- external view returns (RegisteredAgent memory)
123
+ function getRegisteredAgent(address agent) external view returns (RegisteredAgent memory)
210
124
  ```
211
125
 
212
- Returns registered agent info: <code>agentAddress</code>, <code>name</code>, <code>model</code>, <code>systemPromptHash</code>, <code>proofHash</code>, <code>registeredAt</code>, <code>active</code>.
126
+ Agent details: `name`, `model`, `systemPromptHash`, `proofHash`, `registeredAt`, `active`.
213
127
 
214
128
  ### getAgentCount
215
129
 
@@ -217,4 +131,4 @@ Returns registered agent info: <code>agentAddress</code>, <code>name</code>, <co
217
131
  function getAgentCount() external view returns (uint256)
218
132
  ```
219
133
 
220
- Returns the number of registered agents.
134
+ Total registered agents.
@@ -1,58 +1,39 @@
1
1
  ---
2
2
  title: 'Contract Overview'
3
- description: 'OPMRegistry smart contract deployed on Base Sepolia.'
3
+ description: 'OPMRegistry smart contract on Base Sepolia.'
4
4
  ---
5
5
 
6
6
  # Contract Overview
7
7
 
8
- The **OPMRegistry** is the core on-chain component of OPM. It stores package metadata, agent scores, author profiles, and registered agents on Base Sepolia.
8
+ **OPMRegistry.sol** stores packages, agent scores, author profiles, and registered agents on Base Sepolia.
9
9
 
10
10
  ## Deployment
11
11
 
12
12
  | Property | Value |
13
13
  |----------|-------|
14
- | Contract | OPMRegistry.sol |
15
14
  | Network | Base Sepolia (chain ID 84532) |
16
- | Address | <code>0x16684391fc9bf48246B08Afe16d1a57BFa181d48</code> |
15
+ | Address | [`0x16684391fc9bf48246B08Afe16d1a57BFa181d48`](https://sepolia.basescan.org/address/0x16684391fc9bf48246B08Afe16d1a57BFa181d48) |
17
16
  | Solidity | 0.8.20 |
18
17
 
19
- <Note>
20
- View the contract on [BaseScan](https://sepolia.basescan.org/address/0x16684391fc9bf48246B08Afe16d1a57BFa181d48).
21
- </Note>
18
+ ## Access Control
22
19
 
23
- ## Design
20
+ - **Owner** — Can authorize/deauthorize agents via `setAgent()` and `revokeAgent()`
21
+ - **Authorized agents** — Can call `submitScore()` and `setReportURI()`
22
+ - **Public** — Can call `registerPackage()` and `registerAgent()` (with valid ZK proof)
24
23
 
25
- ### Owner Pattern
24
+ ## Permissionless Agent Registration
26
25
 
27
- The contract uses an owner pattern for initial agent authorization. The deployer is the owner and can:
26
+ Anyone can register an agent without owner approval:
28
27
 
29
- - Authorize or deauthorize agents via <code>setAgent(address, bool)</code>
30
- - Revoke permissionless agents via <code>revokeAgent(address)</code>
28
+ 1. Run 10 benchmark cases with 100% accuracy
29
+ 2. Generate a ZK proof
30
+ 3. Call `registerAgent(name, model, systemPromptHash, proofHash)`
31
31
 
32
- ### Permissionless Agent Registration
33
-
34
- New agents can register without owner approval by passing the benchmark verification:
35
-
36
- 1. Run 10 labeled benchmark cases
37
- 2. Achieve 100% accuracy
38
- 3. Generate a ZK proof of accuracy
39
- 4. Call <code>registerAgent(name, model, systemPromptHash, proofHash)</code>
40
-
41
- On success, the agent is automatically authorized to submit scores.
42
-
43
- ### Data Stored
44
-
45
- | Data | Description |
46
- |------|-------------|
47
- | **Packages** | Name → versions mapping |
48
- | **Version data** | Per (name, version): author, checksum, signature, report URI, agent scores |
49
- | **Authors** | Address → profile (ENS name, reputation, packages published) |
50
- | **Agents** | Authorized agents (owner-set or ZK-verified) |
51
- | **Registered agents** | Permissionless agents with name, model, proof hash |
32
+ On success, the agent is auto-authorized to submit scores.
52
33
 
53
34
  ## Risk Thresholds
54
35
 
55
- | Constant | Value | Purpose |
56
- |----------|-------|---------|
57
- | <code>HIGH_RISK_THRESHOLD</code> | 70 | Blocks install; high-risk packages |
58
- | <code>MEDIUM_RISK_THRESHOLD</code> | 40 | Warning threshold |
36
+ | Constant | Value |
37
+ |----------|-------|
38
+ | `HIGH_RISK_THRESHOLD` | 70 |
39
+ | `MEDIUM_RISK_THRESHOLD` | 40 |
@@ -1,43 +1,40 @@
1
1
  ---
2
2
  title: 'Introduction'
3
- description: 'OPM is a drop-in npm replacement that adds cryptographic signing, multi-agent AI security auditing, on-chain risk scoring, and ZK-verified permissionless agent registration to the JavaScript supply chain.'
3
+ description: 'OPM is a drop-in npm replacement that adds cryptographic signing, multi-agent AI security scanning, on-chain risk scoring, and ZK-verified agent registration to the JavaScript supply chain.'
4
4
  ---
5
5
 
6
6
  # Introduction
7
7
 
8
- **OPM (On-chain Package Manager)** is a security-hardened CLI wrapper around npm that introduces cryptographic package attestation, multi-agent AI threat analysis, on-chain audit registries, and decentralized report storage to the JavaScript dependency supply chain. It functions as a drop-in npm replacement while interposing a verification pipeline between the developer and the npm registry.
8
+ **OPM (On-chain Package Manager)** is a drop-in npm replacement that scans every package with 3 AI agents, scores risk on-chain, and blocks malicious installs all from the terminal.
9
9
 
10
10
  ## The Problem
11
11
 
12
- The npm ecosystem faces persistent supply chain threats:
12
+ npm has no built-in defense against supply chain attacks. Developers install typosquatted packages, ship unpatched CVEs, and run malicious postinstall scripts — often without knowing until it's too late. Traditional tools catch known vulnerabilities *after* disclosure, but miss novel threats, obfuscated payloads, and social engineering attacks.
13
13
 
14
- - **Supply chain injection**: Malicious postinstall scripts, obfuscated payloads, environment variable exfiltration, and runtime code generation
15
- - **Typosquatting**: Package names designed to mimic popular packages (e.g., `lodash` vs `lodahs`)
16
- - **Malicious packages**: Deliberately harmful code in dependencies, often introduced via maintainer takeover
17
- - **Dependency confusion**: Scoped vs unscoped name conflicts and internal package shadowing
18
- - **Known vulnerabilities**: Unpatched CVEs and GHSA advisories in transitive dependencies
14
+ ## How OPM Fixes It
19
15
 
20
- Traditional package managers lack cryptographic provenance, real-time threat intelligence, and decentralized trust signals. OPM addresses these gaps.
21
-
22
- ## The Solution
23
-
24
- OPM combines four layers of defense:
25
-
26
- 1. **Cryptographic attestation**: SHA-256 checksums and ECDSA signatures (secp256k1) derived from Ethereum wallets, with on-chain registration
27
- 2. **Multi-agent AI auditing**: Three heterogeneous LLMs (Claude, Gemini, DeepSeek) analyze packages in parallel and submit intelligence-weighted risk scores on-chain
28
- 3. **On-chain registry**: Risk scores, author profiles, and report URIs stored on **Base Sepolia** (chain ID 84532) in the `OPMRegistry` smart contract
29
- 4. **ZK-verified agent registration**: Permissionless agents must pass a benchmark suite and prove 100% accuracy via zero-knowledge proofs before participating
16
+ | Layer | What it does |
17
+ |-------|-------------|
18
+ | **Cryptographic signing** | SHA-256 checksum + ECDSA signature from your Ethereum wallet, verified at install time |
19
+ | **Multi-agent AI scanning** | 3 LLMs (Claude, Gemini, DeepSeek) analyze packages in parallel — catches what static analysis misses |
20
+ | **On-chain registry** | Risk scores, author profiles, and audit reports stored on Base Sepolia — immutable and queryable |
21
+ | **ZK agent verification** | Anyone can register a security agent, but must prove 100% benchmark accuracy via zero-knowledge proofs |
22
+ | **ENS identity** | Author reputation tied to ENS names decentralized trust, not centralized accounts |
30
23
 
31
24
  ## Key Integrations
32
25
 
33
26
  | Integration | Purpose |
34
27
  |-------------|---------|
35
- | **Base Sepolia** | EVM chain for OPMRegistry deployment and score submission |
36
- | **ENS** | Author identity resolution (forward/reverse) and profile metadata |
37
- | **Fileverse** | IPFS-backed encrypted storage for AI scan reports (dDocs protocol) |
38
- | **OSV** | Real-time CVE/GHSA advisory data with CVSS v3 scoring |
39
- | **ChainPatrol** | Blocklist fallback for packages absent from the registry |
28
+ | **Base Sepolia** | On-chain registry for scores, packages, and agents |
29
+ | **ENS** | Author identity and package metadata records |
30
+ | **Fileverse** | IPFS-backed encrypted audit report storage |
31
+ | **OSV** | Real-time CVE/GHSA data |
32
+ | **ChainPatrol** | Blocklist fallback for unregistered packages |
33
+
34
+ ## Architecture
40
35
 
41
- ## Architecture Overview
36
+ <Frame>
37
+ <img src="/system-design.png" alt="OPM System Design" />
38
+ </Frame>
42
39
 
43
- OPM implements a domain-specific instantiation of the [ERC-8004 (Trustless Agents)](https://eips.ethereum.org/EIPS/eip-8004) pattern: agents hold on-chain identities, submit structured reputation signals (risk scores + reasoning), and attach off-chain validation evidence as Fileverse report URIs. Consumers invoking `opm install` query the registry, verify signatures, cross-reference OSV, and enforce configurable risk thresholds before permitting installation.
40
+ OPM implements the [ERC-8004 (Trustless Agents)](https://eips.ethereum.org/EIPS/eip-8004) pattern agents hold on-chain identities, submit risk scores, and attach Fileverse reports as validation evidence.