@oracle-agent/oracle 0.24.1 → 0.24.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/assets/skills/chain/SKILL.md +34 -0
  2. package/dist/assets/skills/chain-defi-ecosystem-analysis/SKILL.md +181 -0
  3. package/dist/assets/skills/chain-ecosystem-gap-analysis/SKILL.md +162 -0
  4. package/dist/assets/skills/cross-chain-twap-execution/SKILL.md +125 -0
  5. package/dist/assets/skills/defi-protocol-pmf-assessment/SKILL.md +332 -0
  6. package/dist/assets/skills/evm-contract-research.md +8 -3
  7. package/dist/assets/skills/multi-venue-prepare-only-ranking/SKILL.md +93 -0
  8. package/dist/assets/skills/oracle-access-control/SKILL.md +71 -0
  9. package/dist/assets/skills/oracle-action-arming/SKILL.md +99 -0
  10. package/dist/assets/skills/oracle-airdrop-calculator/SKILL.md +111 -0
  11. package/dist/assets/skills/oracle-desk-product/SKILL.md +341 -0
  12. package/dist/assets/skills/oracle-evm/SKILL.md +55 -0
  13. package/dist/assets/skills/oracle-harness/SKILL.md +41 -0
  14. package/dist/assets/skills/oracle-mcp-install/SKILL.md +140 -0
  15. package/dist/assets/skills/oracle-multichain-convert/SKILL.md +87 -0
  16. package/dist/assets/skills/oracle-native-harness/SKILL.md +32 -0
  17. package/dist/assets/skills/oracle-ownership-gate/SKILL.md +42 -0
  18. package/dist/assets/skills/oracle-public-product-ux/SKILL.md +114 -0
  19. package/dist/assets/skills/oracle-tailscale/SKILL.md +32 -0
  20. package/dist/assets/skills/oracle-thin-client/SKILL.md +47 -0
  21. package/dist/assets/skills/perp-venue-funding-research/SKILL.md +161 -0
  22. package/dist/assets/skills/polymarket/SKILL.md +160 -0
  23. package/dist/assets/skills/protocol-api-key-integration/SKILL.md +141 -0
  24. package/dist/assets/skills/self-custodial-onchain-execution/SKILL.md +1284 -0
  25. package/dist/assets/skills/setup/SKILL.md +40 -0
  26. package/dist/assets/skills/stable-launch-ops/SKILL.md +89 -0
  27. package/dist/assets/skills/trade-loop-circuit-breaker/SKILL.md +441 -0
  28. package/dist/assets/skills/venue-capability-boundaries/SKILL.md +32 -0
  29. package/dist/bin/desk-server.mjs +16 -16
  30. package/dist/bin/oracle-data-mcp.mjs +1 -1
  31. package/dist/bin/oracle-equities.mjs +1 -1
  32. package/dist/bin/oracle-init.mjs +9 -9
  33. package/dist/cli/commands/bootstrap.mjs +1 -1
  34. package/dist/cli/commands/chat.mjs +78 -77
  35. package/dist/cli/commands/doctor.mjs +8 -6
  36. package/dist/cli/commands/eval.mjs +1 -1
  37. package/dist/cli/commands/harness.mjs +6 -6
  38. package/dist/cli/commands/model.mjs +82 -81
  39. package/dist/cli/commands/receipt.mjs +5 -0
  40. package/dist/cli/commands/setup.mjs +1 -1
  41. package/dist/cli/commands/venues.mjs +3 -0
  42. package/dist/cli/commands/watch.mjs +16 -0
  43. package/dist/equities/index.mjs +1 -1
  44. package/dist/index.mjs +1 -1
  45. package/package.json +1 -1
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: oracle-airdrop-calculator
3
+ description: Use when scanning a wallet for airdrop eligibility.
4
+ ---
5
+
6
+ > Oracle native tools: `oracle_cli` (read/prepare), `vault_status`, `signer_status`, `signer_execute` (needs human confirmationNonce), `skill_load`. No generic shell. No fleet SSH.
7
+
8
+
9
+ # Airdrop calculator (Oracle)
10
+
11
+ Use when DEMI asks to check a wallet's airdrop eligibility, scan for potential drops, or check "what airdrops am I qualified for." General-purpose — not tied to any single campaign.
12
+
13
+ ## Architecture (shipped 2026-08-06)
14
+
15
+ ```
16
+ Oracle app API
17
+ → GET /api/oracle/airdrop?wallet=0x...&format=summary|full
18
+ → scanner.ts Blockscout V2 multi-chain activity profiler
19
+ → campaign.ts known-campaign registry (12 programs, 8 ecosystems)
20
+ → scorer.ts eligibility matching engine
21
+ ```
22
+
23
+ Code roots in `~/projects/oracle-app/`:
24
+ - `lib/oracle/airdrop/scanner.ts` — parallel Blockscout V2 scan
25
+ - `lib/oracle/airdrop/campaigns.ts` — campaign criteria registry
26
+ - `lib/oracle/airdrop/scorer.ts` — scoring engine
27
+ - `app/api/oracle/airdrop/route.ts` — API route
28
+
29
+ ## How it works
30
+
31
+ **Scanner** profiles a wallet across all supported EVM chains using public Blockscout V2 APIs:
32
+ - `GET /api/v2/addresses/{wallet}/counters` → `transactions_count`
33
+ - `GET /api/v2/addresses/{wallet}` → `coin_balance` + `exchange_rate`
34
+ - `GET /api/v2/addresses/{wallet}/transactions` → age + protocol interactions (5s timeout, optional)
35
+ - `GET /api/v2/addresses/{wallet}/token-balances` → USD-denominated holdings
36
+
37
+ Chains are scanned in parallel (3 at a time). Transactions fetch has a 5s timeout — on huge wallets it times out gracefully and returns counters-only data.
38
+
39
+ **Campaign registry** holds 12 known programs with explicit criteria:
40
+ - Confirmed: Hyperliquid Points, HL Perps, Locals→STABLE
41
+ - Likely: HyperEVM Ecosystem, DeFi Power User
42
+ - Speculative: Base, Arbitrum, Optimism, Polygon, Abstract, LI.FI Loyalty, Across Bridge
43
+
44
+ **Scorer** compares wallet profile against each campaign's criteria, producing:
45
+ - `eligibility` 0-100%
46
+ - `verdict`: eligible / partial / ineligible / unknown
47
+ - `matchedCriteria` + `missedCriteria` lists
48
+ - Per-criterion detail logs
49
+
50
+ ## API
51
+
52
+ ```
53
+ # Summary (fast, overview only)
54
+ GET /api/oracle/airdrop?wallet=0x...&format=summary
55
+
56
+ # Full (campaign-by-campaign detail)
57
+ GET /api/oracle/airdrop?wallet=0x...&format=full
58
+ ```
59
+
60
+ Response includes `totalTx`, `totalVolumeUsd`, `chainCount`, `isMultiChain`, `walletAgeDays`, and per-campaign scores.
61
+
62
+ ## Adding campaigns
63
+
64
+ Edit `lib/oracle/airdrop/campaigns.ts` — add an entry to the `CAMPAIGNS` array:
65
+ ```ts
66
+ {
67
+ id: "unique-id",
68
+ name: "Human Name",
69
+ token: "TICKER",
70
+ chainId: "base",
71
+ status: "active" | "upcoming" | "completed" | "rumored",
72
+ confidence: "confirmed" | "likely" | "speculative",
73
+ criteria: [
74
+ { kind: "tx_count", min: 10, description: "10+ tx" },
75
+ { kind: "volume_usd", min: 1000, description: "$1k+ volume" },
76
+ { kind: "chain_used", chainId: "base", description: "Activity on Base" },
77
+ { kind: "protocol_used", contract: "0x...", chainId: 8453, label: "Protocol Name" },
78
+ { kind: "wallet_age_days", min: 30, description: "30+ days old" },
79
+ { kind: "nft_held", contract: "0x...", chainId: 999, label: "NFT Name" },
80
+ { kind: "points_eligible", program: "hyperliquid", description: "Points program" },
81
+ ],
82
+ source: "https://official.source",
83
+ allocationEstimate: "Range or methodology description",
84
+ }
85
+ ```
86
+
87
+ `nft_held` and `points_eligible` criteria are skipped in scoring (require dedicated APIs). All other criteria are checkable from Blockscout data alone.
88
+
89
+ ## Blockscout V2 API quirks
90
+
91
+ - **Counters endpoint is `/counters`** not `/addresses/{wallet}` for tx count — the address endpoint does NOT include `tx_count`
92
+ - **`transactions_count` is a string**, not a number — parseInt it
93
+ - **Transactions `to` field** is `{ hash: "0x..." }` not a flat string
94
+ - **Token balances** nest: `{ token: { exchange_rate, decimals }, value }` — not flat
95
+ - **`coin_balance`** is in wei (divide by 1e18)
96
+ - **`exchange_rate`** is a USD string on the address object
97
+
98
+ ## Performance design
99
+
100
+ - Parallel scan (3 chains at a time) avoids rate-limiting
101
+ - Transaction fetch has 5s timeout — skips gracefully on huge wallets
102
+ - 0 tx on a chain = early return, skip remaining fetches
103
+ - Summary mode skips per-campaign detail for fast response
104
+
105
+ ## Pitfalls
106
+
107
+ - Blockscout instances vary by chain — URLs are hardcoded per chain in `blockscoutUrl()`
108
+ - Chains without Blockscout return `error: "no explorer available"`
109
+ - A wallet with 0 tx everywhere returns `ineligible` for all campaigns — not an error
110
+ - `nft_held` and `points_eligible` criteria always return "unknown" — they need dedicated API integration
111
+ - The `totalVolumeUsd` is based on current token holdings, not historical trade volume — it's a lower bound
@@ -0,0 +1,341 @@
1
+ ---
2
+ name: oracle-desk-product
3
+ description: Use for Oracle product law, self-host C+B, NL confirm/arm.
4
+ ---
5
+
6
+ > Oracle native tools: `oracle_cli` (read/prepare), `vault_status`, `signer_status`, `signer_execute` (needs human confirmationNonce), `skill_load`. No generic shell. No fleet SSH.
7
+
8
+
9
+ # Oracle desk product
10
+
11
+ Class-level product law for the Oracle multichain agent desk (app + CLI self-host).
12
+
13
+ ## One-line definition
14
+
15
+ **Oracle = multi-chain, self-custodial, locally hosted agent harness.**
16
+
17
+ | Word | Meaning |
18
+ |---|---|
19
+ | Multi-chain | EVM + Sol + BTC + HL/RH/Stable |
20
+ | Self-custodial | Keys on user machine or user wallet — never house cloud |
21
+ | Locally hosted | Desk/exec/policy on 127.0.0.1 / their box by default |
22
+ | Agent harness | NL chat → quote → confirm/arm → policy → sign → receipt |
23
+
24
+ ## C + B (custody + rails)
25
+
26
+ | Layer | |
27
+ |---|---|
28
+ | **C** | `oracle sign init` on **their** disk. **Never paste seed in app UI.** |
29
+ | **B** | `~/.config/oracle/agent-policy.json` — $/trade, $/day, chains, slip, TTL, arm/disarm, **`noLimits`** |
30
+
31
+ ### Policy-file integrity — RESOLVED (2026-08-08, multi-model audit 5/5 HIGH)
32
+ `agent-policy.json` now carries a **SHA-256 `integrity` field** over its canonical
33
+ body (fixed field order in `canonicalPolicyBody`). `loadAgentPolicy` fails CLOSED:
34
+ a file edited outside `saveAgentPolicy` (e.g. `echo '{"noLimits":true}' >
35
+ agent-policy.json`) no longer hashes to its own integrity → loads as **DISARMED**,
36
+ never as a broader grant. Save re-signs every write (mode 0600). Rules:
37
+ - Never let a tampered file WIDEN caps — always disarmed.
38
+ - Missing `integrity` on an existing file is tolerated (pre-upgrade files still
39
+ load), but any present-yet-mismatched integrity disarms.
40
+ - Unit check before shipping changes: valid passes, tampered fails, missing fails.
41
+ - Legacy `unlimited` key still maps to `noLimits` for compat.
42
+
43
+ ### Policy modes
44
+
45
+ - **With limits** — enforce before agent sign; daily ledger
46
+ - **No limits** — skip caps; **Disarm still kills**; all-EVM preset
47
+ - API: `POST /api/oracle/agent/policy` actions `no_limits` \| `with_limits` \| `arm` \| `disarm`
48
+
49
+ DEMI Mac often: noLimits + armed + all EVM.
50
+
51
+ ### Agent parity — the admin/no-fees variant shares ONE policy source (RESOLVED 2026-08-09)
52
+
53
+ There are TWO packages, NOT one:
54
+ - `@oracle-agent/oracle` — public npm. Prepare-only by default/hosted; self-hosters get
55
+ encrypted local vault + loopback signer for **their** keys, with public fees
56
+ (`~/projects/oracle`).
57
+ - `@oracle-agent/agent` — ADMIN variant, same capability, **zero** Oracle fees; DEMI's
58
+ local signer/key vault (`~/projects/oracle-agent`, SEPARATE repo). One-way dep:
59
+ agent pins `oracle`; oracle never imports agent. Separate repos/releases.
60
+
61
+ **Naming LAW (DEMI 2026-08-09): the word "operator" is GONE from the product surface.**
62
+ It is the AGENT everywhere. The old npm name ``@oracle-agent/agent` (private, never npm)` was **fully
63
+ unpublished 2026-08-09 (now E404)** — deprecation was only the stopgap; the tarball is
64
+ gone and the name must never be published again. Bins renamed: `oracle-operator` →
65
+ `oracle-agent`, `oracle-operator-caps` → `oracle-agent-caps`. Repo+dir renamed
66
+ `oracle-operator` → `oracle-agent`. When touching copy/docs/code: never reintroduce
67
+ "operator" for the product role. KEEP the EVM-standard homonym "operator"
68
+ (setApprovalForAll/approve — the approved address) and the comparison-operator identifier
69
+ in action-runner; those are unrelated to the product role and must stay. If a doc/code
70
+ audit turns up a product-role "operator", rename it to "agent" (see
71
+ `references/agent-rename-and-npm.md`).
72
+
73
+ **Renames are not done when the source is clean — they are done when the SHIPPED
74
+ ARTIFACT is clean.** A rename landed in source can still reach users through stale
75
+ build output: a packaged desktop runtime kept telling users to
76
+ `npm i -g @oracle-agent/oracle` (a package that no longer exists)
77
+ because cached content-hashed chunks rode along in the artifact. After any product-surface
78
+ rename, grep the packaged runtime for the old token, not just the repo.
79
+
80
+ Parity trigger = product-version (product law changes like custody semantics), NOT repo-version.
81
+ "Similar" is not "verified identical" — when asked if the two are in parity, DIFF the security
82
+ surfaces, don't assume.
83
+
84
+ ### Public local signer: product law vs shipped fact (DEMI law; verify every claim)
85
+ DEMI's intended public product is **self-hosted Oracle + a loopback local signer for the
86
+ user's own keys**. The private `@oracle-agent/agent` remains the ADMIN/no-fees vault and is
87
+ never published. The split is about WHOSE keys, not whether self-hosting is allowed.
88
+
89
+ Do **not** turn the product target into a shipped-capability claim. Before answering "does
90
+ public have a local signer?", verify these three surfaces independently:
91
+ 1. `origin/main` public package: signer commands/modules and custody-boundary tests.
92
+ 2. Published npm `latest`: version and packed artifact, not merely source main.
93
+ 3. This machine's deployment: active binary path plus loopback signer service/port.
94
+
95
+ Report them separately. A private deployment having `oracle-signer` active on `127.0.0.1`
96
+ does not prove npm users receive it. A locally hosted model/data/policy loop does not imply
97
+ a bundled signer. A merged feature is not public until the npm artifact containing it is
98
+ published and inspected.
99
+
100
+ **Current verified state as of 2026-08-12:** public npm `@oracle-agent/oracle@0.24.0`
101
+ ships the optional encrypted local vault + short-lived loopback signer. Hosted/default
102
+ Oracle stays prepare-only. Self-host after `oracle sign init|import` is **auto-armed**
103
+ for user-initiated actions. Public still charges the disclosed fee card; Administrator
104
+ (`@oracle-agent/agent`, never on npm) stays zero-fee with DEMI's keys.
105
+
106
+ Public signer families are **EVM, Solana, Bitcoin only** — not separate HL/Poly
107
+ account surfaces. Do not resurrect Tread.fi OEMS/API protocol interaction; TradFi
108
+ algorithms (TWAP/VWAP/POV/iceberg/IS) are native Oracle planners, not an external
109
+ broker.
110
+
111
+ A merged PR is still not "shipped" until `npm view @oracle-agent/oracle version`
112
+ matches the intended release and the packed tarball was secret-scanned. Never accept
113
+ "key file exists" or "service is active" as proof that public onboarding works.
114
+
115
+ Detail: `references/public-admin-parity.md`.
116
+
117
+ **Key-path wiring bug found + fixed 2026-08-09 (verify this stays wired).** `oracle sign
118
+ import` wrote the key to `<config>/keys/evm.json` and armed `exec.env`, but the loopback
119
+ signer daemon resolves key material from the vault path written by `oracle sign import`.
120
+ A freshly imported key was **silently
121
+ never picked up** by `oracle signer` — import reported success, signing just never found
122
+ it. Fix: import now also writes `signer.env` pointing both vars at the file it created,
123
+ preserving other entries (`wireSignerKeyEnv` in `src/cli/commands/sign.mjs`; regression
124
+ test in `test/cli-signplane.test.mjs` asserts key material, shred, arm, AND env wiring).
125
+ Lesson for this class: "the key file exists on disk" is NOT proof the signer can sign —
126
+ trace provision → env → daemon resolution end to end before claiming a signer works.
127
+ Note `sign.mjs` is ESM: helpers need `await import("node:fs"/"node:path")`, and `join`
128
+ scoped inside a verb block is not visible to a module-level helper.
129
+
130
+ The gap found 2026-08-09: agent enforced only its own env caps (`ORACLE_MAX_NOTIONAL_USD`, …)
131
+ and NEVER read the app's `agent-policy.json` — two B walls that could drift (app UI noLimits
132
+ while signer still enforced env caps; env raised while app route still capped). Fixed:
133
+ - `src/agent-policy-file.mjs` reads the SAME `~/.config/oracle/agent-policy.json` with the SAME
134
+ SHA-256 integrity algorithm (`oracle-agent-policy:v1:` + canonical 10-field body). Verified
135
+ hash-for-hash identical to the app — a file signed by the app verifies on the signer.
136
+ - Tampered/corrupt/no-integrity policy → signer DISARMS regardless of env (a disarmed app must
137
+ mean a disarmed signer; no split-brain escape hatch).
138
+ - Valid file merges maxUsdPerTrade/maxUsdPerDay as the cap FLOOR; env caps may only TIGHTEN.
139
+ - Valid noLimits lifts file dollar caps but env caps stay authoritative.
140
+ - KEEP the hash algorithm byte-identical across both sides — a mismatch silently disarms.
141
+
142
+ Detail + the full parity diff table: `references/agent-parity.md`.
143
+
144
+ ## Chat trade flow (required UX)
145
+
146
+ ```
147
+ user: swap .1 eth to base
148
+ app: Prepared · not signed
149
+ user: confirm | arm | yes | go
150
+ app: policy → execute → tx hash
151
+ user: cancel
152
+ app: drop quote
153
+ ```
154
+
155
+ - Parse `swap .1 eth to base` → ETH→**USDC** on **Base** (leading-dot amounts OK).
156
+ - Primary = **conversational** confirm/arm; buttons secondary.
157
+ - Default: **confirm each trade** until auto-within-rails is explicit.
158
+ - Chat `arm` = execute **pending quote**. Settings Arm = kill-switch allow execute. Disambiguate.
159
+
160
+ ### Arm disambiguation — RESOLVED (2026-08-08, multi-model audit consensus 5/5)
161
+ The two `arm` surfaces are now labeled differently in the UI:
162
+ - **Settings global kill-switch**: button **"Enable execution" / "Disable execution"**, status
163
+ pill **"execution on" / "execution off"** (never "armed"). Copy: *"Global kill-switch ·
164
+ distinct from chat 'arm' (one trade)"* and *"Chat 'arm' still requires this kill-switch on."*
165
+ - **Chat `arm`**: unchanged — executes ONE pending quote via `parseConfirmIntent`. It fails
166
+ closed when the Settings kill-switch is off (`checkAgentPolicy` `disarmed` gate).
167
+ - Internal `agent-policy.json` field stays `armed` (API compat) — the change is UI-label only
168
+ in `AgentPolicySettings.tsx`. Keep these labels distinct; do not collapse them back to one
169
+ "arm" word.
170
+
171
+ ### Receipt discipline in the UI — RESOLVED (2026-08-08, multi-model audit consensus 4/5)
172
+ - Celebration overlay fires ONLY when `trade.status === "done" && trade.txHash` — no receipt
173
+ hash, no fireworks. "Done" without a hash is a UI claim, not proof.
174
+ - Agent path with no txHash says: *"Submitted — no receipt hash returned. Verify on-chain
175
+ before treating as settled."* Never print bare "Done." without a hash.
176
+ - Per-trade confirm is structurally enforced via `confirmToken` even under `noLimits` — the
177
+ "no dollar cap but still confirm" invariant holds at the chat layer.
178
+
179
+ ### Confirm-token one-time consume — RESOLVED (2026-08-09, Grok 4.5 red-team leg)
180
+ Grok 4.5 (6th auditor) found: owner confirm tokens were verified by HMAC + 3-min TTL only,
181
+ with NO spent-nonce tracking — the same token could replay the identical intent within the
182
+ TTL window. Fix: `lib/oracle/confirm-nonce.ts` (`tryConsumeNonce`) — a shared atomic
183
+ spent-nonce registry consumed by BOTH owner-exec routes (`owner/swap`, `trade/quote`). A
184
+ second use of any token fails "already used — re-quote". Rules:
185
+ - Token mints bind 14 intent fields (nonce, chainId, tokenIn, amountIn, txTo, source, ...)
186
+ — replaying a token against different intent fields fails HMAC anyway.
187
+ - Strategy/shadow modules must have ZERO edges to owner-exec (verified clean).
188
+ - Keep the consume check inside verify, right after TTL check, before returning ok.
189
+ - Regression tests: `test/confirm-nonce.test.mjs`.
190
+
191
+ Code: `lib/oracle/confirm-nonce.ts`, `app/api/oracle/owner/swap/route.ts`, `app/api/oracle/trade/quote/route.ts`.
192
+
193
+ Code: `lib/oracle/swap-intent.ts`, `ChatDeskPane`, `/api/oracle/trade/quote`.
194
+
195
+ ## Sessions persist, and they are scoped BY CHAIN (DEMI law 2026-08-09)
196
+
197
+ DEMI: *"oracle should also have sessions on the side so when you go back to chat
198
+ you dont lose where you left off IE, building something and if you were on a
199
+ chain it should seperate sessions by chain."*
200
+
201
+ - The chat surface is **not stateless**. Returning to chat resumes exactly where
202
+ the last session stopped — mid-build, mid-comparison, mid-prepare.
203
+ - Sessions are **partitioned by chain**. Work begun while pinned to a chain
204
+ belongs to that chain's thread; `/chain` switches thread, and switching back
205
+ restores that chain's in-flight context instead of starting cold or bleeding
206
+ another chain's state into it.
207
+ - `~/.config/oracle/active-chain.json` already tracks the pinned chain and is
208
+ the natural partition key.
209
+ - "Which chain was I on" and "what was I doing" are the SAME lookup. Losing
210
+ either is the failure this exists to prevent.
211
+ - Session state carries build/trade context ONLY. **Oracle never holds the
212
+ keys** — never persist passphrases, tokens, or key material into a session.
213
+
214
+ ## Custody honesty
215
+
216
+ - Wallet path: address only + wallet popup sign.
217
+ - Agent path: local agent key via CLI, not app paste.
218
+ - B-alone (Permit2 session) ≠ “sign every time”; product is **C+B**.
219
+
220
+ ## Self-host surfaces
221
+
222
+ - `/api/oracle/selfhost/status|init` — local desk URLs, no keys
223
+ - Onboarding: Your machine. Your agent. Your keys.
224
+ - Downloaders ≠ Arch Tailscale default (DEMI thin-client is ops-only)
225
+
226
+ ## Portfolio
227
+
228
+ - Coin list primary; Swap/Send prefill
229
+ - **TokenLogo** on holdings when picture exists
230
+ - Stable ERC-20 (FEFER): watch-token probe
231
+
232
+ ## Navigation + rail (audit-consensus decisions, 2026-08-08)
233
+
234
+ - **Tab labels describe function, never repeat the brand.** Primary chat tab is
235
+ **"Desk"** (NOT "Oracle" — the audit called brand-name tabs a same-brand
236
+ collision; the product mark in the header stays "Oracle"). Swap tab is
237
+ **"Simulate"** (dry-run sandbox naming; the NL harness lives in Desk, so
238
+ Prepare/confirm/sign are NOT a separate stage tab).
239
+ - **Portfolio rail defaults OPEN on desktop ≥1280px**, closed on smaller
240
+ viewports, and the user's explicit collapse/expand persists to
241
+ `localStorage("oracle-rail-open")`. The default is applied in a mounted
242
+ effect (SSR-safe — initial state is always false, so no hydration mismatch).
243
+ - **Every mono figure uses tabular-nums + lining-nums** (globals.css on
244
+ `.font-mono`, `.font-mono-ui`, code/kbd) — JB Mono digits align vertically;
245
+ this is what makes a financial desk font a financial desk font.
246
+
247
+ ## Evals
248
+
249
+ - Existing: `packages/oracle/test`, `adversarial-bench.mjs`, Hermes `skill_eval.py`
250
+ - Desired desk suite: parse → quote → policy → confirm/arm → receipt (fixture RPC)
251
+
252
+ ## Fees — MINIMAL, disclosed, and pinned (DEMI law 2026-08-09)
253
+
254
+ DEMI's standing preference: **"whats our bps fees they should be minimal."**
255
+ When a change makes a fee legible, do not recite the code comment as if it
256
+ settled the rate — state the real numbers from source and propose one.
257
+
258
+ Current rate card (all OFF unless a recipient is configured; holders pay zero):
259
+
260
+ | Rail | bps |
261
+ |---|---|
262
+ | swap | 5 |
263
+ | bridge | 5 |
264
+ | perps / nft | 0 |
265
+ | HL builder codes | perp 2 · spot 1 · hip3 1 · hip4 1 (cap 10) |
266
+
267
+ **One flat rate beats per-action tiers.** Bridge was 15 bps until 2026-08-09 on
268
+ a "longer settlement, more failure modes" rationale — that prices OUR effort,
269
+ not user value, on a heavily comparison-shopped action. It was also
270
+ structurally self-defeating: only `lifi`/`paraswap` apply the integrator fee
271
+ while bridge candidates are `lifi`/`relay`/`across`, so once the router began
272
+ subtracting our own fee from `netOut`, the high tier handicapped the one venue
273
+ that charged it — collecting almost nothing while making an identical bridge
274
+ cost different amounts depending on which venue won. A per-venue accident is
275
+ not a pricing tier.
276
+
277
+ Three invariants to keep:
278
+
279
+ - **A cost we charge is a cost we rank on.** Subtract the fee before ranking
280
+ routes, including on the degraded/gross path — a fee taken off the output is
281
+ exactly known even when gas is not. Otherwise "cheapest" is a number the user
282
+ never receives, breaking hard rule 0.
283
+ - **Disclosure must reach a user, not just exist.** `describeFee()` sat with
284
+ zero production callers for a whole release: defined, unit-tested, rendered
285
+ nowhere. A disclosure function nobody calls is an unenforced invariant. Grep
286
+ for CALLERS outside the module and its tests before believing a fee is shown.
287
+ - **Never stack rails.** perps/nft carry a 0 bps integrator tier precisely so a
288
+ Hyperliquid trade is charged only by its builder code. This is now pinned by
289
+ a test — if either tier goes nonzero, one action gets billed twice.
290
+
291
+ **Pin every beneficiary of a value transfer.** Both paying addresses
292
+ (`ORACLE_INTEGRATOR_FEE_RECIPIENT` and `ORACLE_HL_BUILDER_ADDRESS`) were
293
+ shape-validated only (`0x` + 40 hex), so anything that could write an env var —
294
+ a shell rc, a CI var, a stray `.env`, an npm postinstall — silently redirected
295
+ user money. Both now check `~/.config/oracle/fee-recipient` (0600, one file for
296
+ both rails so they cannot disagree) and fail **CLOSED to ZERO fee** on
297
+ mismatch, never to "charge anyway to an unverified address." Unpinned installs
298
+ are unchanged, so it is opt-in. Be honest about scope in the code comment: the
299
+ pin does not stop code that can also rewrite the pin file — it raises the bar
300
+ from "any env write anywhere" to "write this specific file" and makes the
301
+ authorized recipient auditable.
302
+
303
+ ## Audit discipline (DEMI preference, corrected 2026-08-09)
304
+
305
+ - **After a multi-model audit, apply EVERY recommendation.** Do not list
306
+ "kept intentionally" dissent items as the default outcome — DEMI reads that
307
+ as unfinished work ("i thought we fixed all") and will say "keep what you
308
+ recommend", meaning fix them. Only truly user-directed keeps survive, and
309
+ only with explicit sign-off per item.
310
+ - When a red-team/audit finding says "must verify in-repo", verify it against
311
+ the tree BEFORE reporting — a red-team claim is a hypothesis, not a fact.
312
+ - Report the verdict count as N/M across auditors (e.g. 5/6 ship-with-fixes)
313
+ and name which auditor dissented.
314
+ - 7-auditor roster: deepseek-v4-pro · deepseek-v4-flash · gpt-5.6-sol · opus-5 ·
315
+ opus-4-8 · fable-5 · grok-4.5 (xai-oauth). Both DeepSeek legs route through
316
+ **`nous-direct`** (`deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash`) —
317
+ the bare `deepseek` provider has an empty credential pool and its
318
+ `No usable credentials` error does NOT mean the model is unavailable. Harness:
319
+ `~/.hermes/profiles/oracle/scripts/oracle-multimodel-audit.sh`, brief refreshed
320
+ to current state before each run. Full procedure: `multi-model-product-audit`.
321
+
322
+ ## Pitfalls
323
+
324
+ - Electron fake-home can hide `~/.config/oracle` / force execute off — use `ORACLE_REAL_HOME`.
325
+ - Never claim house signs for downloaders.
326
+ - Do not auto-broadcast on quote.
327
+ - Overlap: `oracle-public-product-ux` (chrome/themes); this skill owns product definition + confirm/arm + noLimits.
328
+
329
+ ## References
330
+
331
+ - `references/nl-confirm-arm.md` — chat confirm/arm parse + arm disambiguation
332
+ - `references/agent-policy-nolimits.md` — noLimits / API actions
333
+ - `references/agent-parity.md` — agent=admin variant parity diff, shared-policy hash fix, merge-vs-remote-CI-shape-tests technique
334
+ - `references/agent-rename-and-npm.md` — the 2026-08-09 operator→agent rename procedure + npm unpublish/deprecate/2FA knowledge
335
+ - `references/public-admin-parity.md` — public vs Admin: whose keys, fees, auto-arm, EVM/SOL/BTC-only signer, no Tread OEMS
336
+
337
+ ## Related
338
+
339
+ - `oracle-public-product-ux` — app chrome, themes (overlaps; curator may merge later)
340
+ - `oracle-action-semantics` — watch vs arm planes
341
+ - `oracle-fleet-desk-wiring` — DEMI Mac→Arch
@@ -0,0 +1,55 @@
1
+ ---
2
+ name: oracle-evm
3
+ description: Use for any EVM chain desk work — ETH, Base, Arb, OP, Polygon, BSC, Avalanche, HyperEVM, Abstract, Stable, RH, or a registered extra chain.
4
+ ---
5
+
6
+ > Oracle native tools: `oracle_cli` (read/prepare), `vault_status`, `signer_status`, `signer_execute` (needs human confirmationNonce), `skill_load`. No generic shell. No fleet SSH.
7
+
8
+ # Oracle EVM desk
9
+
10
+ Same agent, same vault, same key. Different `chainId`.
11
+
12
+ Do **not** treat Robinhood (4663) or HyperEVM (999) as the only EVM surfaces.
13
+ If the token’s home chain is Base / Arb / ETH / …, work there.
14
+
15
+ ## Shipped registry (`src/chains.mjs`)
16
+
17
+ | key | chainId | name |
18
+ |---|---|---|
19
+ | ethereum | 1 | Ethereum |
20
+ | optimism | 10 | OP Mainnet |
21
+ | bsc | 56 | BNB Smart Chain |
22
+ | polygon | 137 | Polygon |
23
+ | abstract | 2741 | Abstract |
24
+ | base | 8453 | Base |
25
+ | hyperevm | 999 | HyperEVM |
26
+ | stable | 988 | Stable Mainnet |
27
+ | avalanche | 43114 | Avalanche C-Chain |
28
+ | arbitrum | 42161 | Arbitrum One |
29
+ | robinhood | 4663 | Robinhood Chain |
30
+
31
+ Unknown chain → `oracle chain list`, then DexScreener via `oracle_cli` `data call dex-screener …`. If still ambiguous, ask. Never guess a chainId.
32
+
33
+ A new EVM chain can be registered at runtime (`registerChain`). Unsupported = `UNAVAILABLE`, not fake coverage.
34
+
35
+ ## How to work a request
36
+
37
+ 1. Resolve home chain first (`dex_search` / `dex_token`).
38
+ 2. Pin: `oracle chain use <key>` (or `argv ['chain','use','base']` via `oracle_cli` is not allowed — chain use is a CLI pin; in native chat use `/chain`).
39
+ 3. Quote net of gas: `oracle_cli` `route swap` / `route bridge`. Rank on **net received**.
40
+ 4. Prepare unsigned. Confirm is human. `signer_execute` needs a confirmationNonce.
41
+ 5. Receipt or it did not happen.
42
+
43
+ ## Surfaces (all EVM)
44
+
45
+ - swap / bridge / approve / mint
46
+ - token + contract research
47
+ - meme scan (`evm_token_sniper_scan` is the same scanner on every supported EVM)
48
+ - NFT mint gas-war caps
49
+ - RFQ / tokenized assets when the venue exists on that chain
50
+
51
+ Solana and Bitcoin are separate signer families. HL L1 perps and Polymarket are data/prepare venues, not extra EVM signer families.
52
+
53
+ ## Related
54
+
55
+ `chain` · `evm-contract-research` · `oracle-best-execution` · `oracle-meme-token-sniper` · `oracle-multichain-convert` · `venue-capability-boundaries`
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: oracle-harness
3
+ description: Use when deciding what Oracle native absorbs from Hermes, Claude, Codex, or other clients.
4
+ ---
5
+
6
+ # Oracle is the harness
7
+
8
+ Oracle native (`oracle chat`) is the product loop. Other clients are **feature sources** and optional engines, not the home.
9
+
10
+ ## Absorb (public)
11
+
12
+ From Hermes / Claude / Codex / Cursor-class agents, ship the **desk capabilities**, not the brand:
13
+
14
+ | Capability | Oracle surface |
15
+ |---|---|
16
+ | Agent loop + tools | standalone client (16–50 steps) |
17
+ | Skills | packaged + `~/.config/oracle/skills/<name>/SKILL.md` |
18
+ | Memory / cron / todos / session | native tools |
19
+ | Web fetch + search | `web_fetch` / `web_search` |
20
+ | Bounded browser + vision | `browser_exec` / `vision_analyze` |
21
+ | MCP in and out | `mcp_list` / `mcp_call` + `oracle mcp install` |
22
+ | Plugins | `oracle plugins install` |
23
+ | Multi-model | `oracle setup model` / `/model` |
24
+ | Attach another engine | `oracle chat --backend hermes\|claude\|codex` |
25
+ | Quote / route / prepare | `oracle_cli` |
26
+ | Local sign | vault + loopback `signer_execute` (human nonce) |
27
+ | All shipped EVM | `oracle-evm` — same vault, different chainId |
28
+ | Your desk across your machines | `oracle-thin-client` / `oracle-tailscale` placeholders |
29
+
30
+ ## Do not absorb into public
31
+
32
+ - Fleet SSH / Kanban / Orca / Pop-PC2
33
+ - GitHub admin packs (Admin overlay only)
34
+ - Someone else's Tailnet or thin-client `desk.json`
35
+ - Generic unrestricted shell / desktop CUA on the signer box
36
+ - House executor wallets
37
+
38
+ ## Rule
39
+
40
+ If a feature makes the **crypto desk** better and stays fail-closed, take it.
41
+ If it only exists to operate DEMI's machines, leave it on Admin Hermes.