@oracle-agent/oracle 0.35.20 → 0.35.21

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.
@@ -97,11 +97,17 @@ does not prove npm users receive it. A locally hosted model/data/policy loop doe
97
97
  a bundled signer. A merged feature is not public until the npm artifact containing it is
98
98
  published and inspected.
99
99
 
100
- **Candidate release in this source tree:** public package `@oracle-agent/oracle@0.35.20`
100
+ **Candidate release in this source tree:** public package `@oracle-agent/oracle@0.35.21`
101
101
  ships the encrypted local vault + short-lived loopback signer. Hosted/keyless
102
- Oracle cannot hold keys or move funds. 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.
102
+ Oracle cannot hold keys or move funds. Self-hosting with `oracle sign init` or
103
+ `oracle sign import --kind evm --key-file <0600 file>` writes an encrypted vault and marks
104
+ the signer ARMED/ready. `allowed` remains false. An explicit command asks for confirmation
105
+ before signing, executing, or broadcasting. The only same-turn shortcut is to say `quick
106
+ transaction` and explicitly confirm in the same sentence. An explicitly configured autonomous
107
+ grant, such as a shadow-profit promotion rule, is the separate exception. Signing still
108
+ requires a sealed policy plus a short-lived signer session. Public follows Administrator
109
+ execution behavior but charges the disclosed fee card; Administrator (`@oracle-agent/agent`,
110
+ never on npm) stays zero-fee with DEMI's keys.
105
111
 
106
112
  Public signer families are **EVM, Solana, Bitcoin only** — not separate HL/Poly
107
113
  account surfaces. Do not resurrect Tread.fi OEMS/API protocol interaction; TradFi
@@ -114,18 +120,18 @@ matches the intended release and the packed tarball was secret-scanned. Never ac
114
120
 
115
121
  Detail: `references/public-admin-parity.md`.
116
122
 
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.
123
+ **Current signer provisioning contract (verify this stays wired).** `oracle sign init` creates
124
+ an encrypted EVM keyring. `oracle sign import --kind evm|btc|sol --key-file <0600 file>`
125
+ imports protected key material into the same vault. The passphrase comes from a hidden TTY or
126
+ `--passphrase-file <0600 file>`, and the encrypted keyring is stored at
127
+ `<config>/signer/vault.json`. Importing marks the signer ARMED/ready, but it does not sign,
128
+ execute, submit, trade, or broadcast. An explicit command asks for confirmation; execution
129
+ starts only after confirmation. The only same-turn shortcut is `quick transaction` plus an
130
+ explicit confirm in the same sentence. An explicit autonomous grant and its configured trigger
131
+ are the separate exception. A signer can act only after `oracle sign policy --policy-file <0600
132
+ JSON file>` seals nonempty allowlists and a short-lived signer session starts. Never accept
133
+ private keys in arguments, environment variables, chat, or app UI. Trace provision, vault
134
+ resolution, policy, session, and receipt end to end before claiming the signer works.
129
135
 
130
136
  The gap found 2026-08-09: agent enforced only its own env caps (`ORACLE_MAX_NOTIONAL_USD`, …)
131
137
  and NEVER read the app's `agent-policy.json` — two B walls that could drift (app UI noLimits
@@ -332,7 +338,7 @@ authorized recipient auditable.
332
338
  - `references/agent-policy-nolimits.md` — noLimits / API actions
333
339
  - `references/agent-parity.md` — agent=admin variant parity diff, shared-policy hash fix, merge-vs-remote-CI-shape-tests technique
334
340
  - `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
341
+ - `references/public-admin-parity.md` — public vs Admin: whose keys, fees, vault provisioning vs arming, EVM/SOL/BTC-only signer, no Tread OEMS
336
342
 
337
343
  ## Related
338
344
 
@@ -89,30 +89,25 @@ oracle mcp watchdog --once # one-shot health check
89
89
  ## Wallet setup
90
90
 
91
91
  ```bash
92
- oracle init --apply # generates fresh wallet at ~/.config/oracle/keys/evm.json (0600)
93
- oracle sign import # interactive: paste existing private key (hidden input)
94
- oracle sign import --keyfile <path> # import from file (auto-shreds temp file after import)
92
+ oracle sign init [--passphrase-file <0600 file>]
93
+ oracle sign import --kind evm --key-file <0600 file> [--passphrase-file <0600 file>]
94
+ oracle sign import --kind btc --key-file <0600 file> [--passphrase-file <0600 file>]
95
+ oracle sign import --kind sol --key-file <0600 file> [--passphrase-file <0600 file>]
96
+ oracle sign policy --policy-file <0600 JSON file>
97
+ oracle sign status
98
+ oracle sign doctor
95
99
  ```
96
100
 
97
- Both `oracle sign import` paths **auto-arm** — importing a key sets `ORACLE_EXEC_ENABLED=1`
98
- in `~/.config/oracle/exec.env`. No separate `oracle exec arm` step needed.
99
- The intent is the signal: pasting a private key means the user wants to trade immediately.
100
-
101
- **Rationale:** The user explicitly chose to import their private key and wire the exec MCP.
102
- Adding a mandatory \"arm\" step on top is unnecessary friction. Import = armed.
103
-
104
- **Safety boundary:** The key never leaves the local machine. Oracle's wallet is like a
105
- CLI-native MetaMask — key on disk at 0600, MCP process local to the machine, same trust model.
106
-
107
- The interactive prompt reassures users:
108
- ```
109
- Your key stays local — Oracle never sends it anywhere.
110
- Paste your EVM private key (0x...):
111
- >
112
- ```
113
- Key goes to stdin, never to shell history. Saved at 0600 permissions.
114
-
115
- Never use `echo "0xKEY"` or `--key 0x...` — private keys must never hit shell history.
101
+ The passphrase comes from a hidden TTY prompt or an owner-only file. Key material comes only
102
+ from `--key-file`; Oracle refuses private keys in arguments and inherited environment variables.
103
+ The encrypted keyring lives at `<config>/signer/vault.json`. Importing marks the signer
104
+ ARMED/ready, but `allowed` remains false. An explicit command asks for confirmation before
105
+ signing, executing, or broadcasting. The only same-turn shortcut is to say `quick transaction`
106
+ and explicitly confirm in the same sentence. An explicitly configured autonomous grant, such
107
+ as a shadow-profit promotion rule, is the separate exception. Signing still requires a sealed
108
+ policy with nonempty allowlists and a short-lived signer session. Public follows Administrator
109
+ execution behavior and applies the disclosed public fees.
110
+ Never ask users to paste private keys into chat, app UI, or shell arguments.
116
111
 
117
112
  ## Print mode
118
113
  ```
@@ -97,23 +97,26 @@ Cover, in this order:
97
97
  need to know they can evaluate the thing before handing over credentials.
98
98
  Hyperliquid reads are keyless; Polymarket market data is keyless.
99
99
  3. **Per-venue credential shape**, because they differ structurally:
100
- - **Hyperliquid issues no API key.** You authorize with an Ethereum private
101
- key — use an **API wallet** (`app.hyperliquid.xyz/API`) that can trade but
102
- **cannot withdraw**. Say that explicitly; it is the single most important
103
- safety fact for an agent.
100
+ - **Hyperliquid issues no API key.** An owner-local signer authorizes requests
101
+ with a dedicated **API wallet** (`app.hyperliquid.xyz/API`) that can trade but
102
+ **cannot withdraw**. The key stays in the protected local signer vault and is
103
+ never passed through chat, prompts, arguments, or inherited environment.
104
104
  - **Polymarket needs two different things**: L2 API credentials
105
- (`API_KEY`/`API_SECRET`/`API_PASSPHRASE`) for CLOB order posting, *and* the
106
- Polygon private key that owns the funds. Conflating them wastes an hour.
107
- 4. **Storage, worst → best**, with the honest tradeoff at each tier: env vars
108
- (visible in `ps`, inherited by children), a `0600` key file, an encrypted
109
- vault. Include the `chmod`/`printf` commands so nobody invents their own.
105
+ (`API_KEY`/`API_SECRET`/`API_PASSPHRASE`) for CLOB order posting, *and* an
106
+ owner-local signer for the Polygon wallet that owns the funds. Conflating
107
+ them wastes an hour; neither credential belongs in model context.
108
+ 4. **Storage is owner-local and fail closed.** Use the documented protected `0600`
109
+ key-file and encrypted signer-vault workflow. Never print, paste, or interpolate
110
+ key material into shell commands, chat, prompts, or process arguments.
110
111
  5. **What the encryption does NOT protect.** A vault defends backups, cloud sync,
111
112
  and stolen disks at rest; it does **not** defend malware running as the user
112
113
  while the process is unlocked. Overselling a file-level scheme is worse than
113
114
  shipping none, because it changes behaviour.
114
115
  6. **Both trade paths side by side** — non-custodial (Oracle prepares, user's
115
- wallet signs) and agentic (Oracle holds a key and submits) — so the reader
116
- picks deliberately rather than defaulting into custody.
116
+ wallet signs) and automated owner-local execution (the signer submits only
117
+ after the user's explicit bounded authorization, including an explicitly
118
+ configured shadow-profit promotion rule) — so the reader picks deliberately
119
+ rather than defaulting into custody.
117
120
 
118
121
  Also state where credentials travel: pinned provider endpoints, key dropped
119
122
  rather than forwarded when a `baseUrl` is redirected or downgraded to `http://`.
@@ -21,27 +21,28 @@ A wallet signature proves address control, not operator/admin authority.
21
21
 
22
22
  An open preview may accept any signed wallet only when every money-moving action remains self-custodial and backend live submission is absent from the build.
23
23
 
24
- ## Arming posture: key present = armed, user asks = it runs
24
+ ## Arming posture: key present = armed, confirmation = it runs
25
25
 
26
26
  **DEMI correction — do not gate each capability behind its own env flag.**
27
27
 
28
28
  ```
29
29
  Key present -> capability is ARMED
30
- User asks for it -> it RUNS
30
+ User commands it -> ask for CONFIRMATION
31
+ User confirms it -> it RUNS
32
+ Quick transaction + confirm in one sentence -> it RUNS
31
33
  Autonomous mode -> the ONLY separate opt-in
32
34
  ```
33
35
 
34
- Supplying a signing key **is** the authorization decision. Making someone who
35
- already handed over a key hunt down a second and third `ORACLE_X_ENABLED=1` to
36
- buy an NFT is friction, not security — and it teaches people to set every flag,
37
- which is strictly worse than one coherent default. What actually protects the
38
- user is that every action is **user-initiated** and **bounded by caps at the
39
- moment it runs**.
36
+ Installing the owner-local signer vault is the readiness/arming decision, not an
37
+ execution instruction. Making someone with an armed signer hunt down a second
38
+ and third `ORACLE_X_ENABLED=1` to buy an NFT is friction, not security, and it
39
+ teaches people to set every flag. What protects the user is that every action is
40
+ **user-initiated**, **confirmed**, and **bounded by caps at the moment it runs**.
40
41
 
41
42
  Autonomous/unattended trading is the sole exception, because it is the only mode
42
- where the agent initiates value movement without being asked. An agent that
43
- trades while you sleep is a different risk class from one that buys the NFT you
44
- just named.
43
+ where the agent initiates value movement without a new instruction. It requires
44
+ an explicit autonomous grant, including any configured promotion rule that runs
45
+ only after the strategy's shadow-profit condition passes.
45
46
 
46
47
  Keep an `execute: true` marker at the call site (it stops a send happening as a
47
48
  side effect of a read path) but do not add an env arm beside it. `armed` and
@@ -89,9 +90,9 @@ Report each gate separately. `agent:execute=true` does not mean "trading": an un
89
90
 
90
91
  ### Chat-leaked burner keys are still burn-only
91
92
 
92
- If a user pastes a Solana secret key, BTC WIF, seed phrase, or Xverse seed into chat, do **not** import or use it, even when they say it is only a burner. Treat the key as compromised, tell them to generate/import a fresh burner directly on the machine that will sign, and accept only the public address in chat. Long base58 Solana strings are often secret keys; validate by reading the public address only. For Bitcoin inscriptions, prefer a fresh local WIF file that pays commit/reveal fees while inscribing **to** a separate ordinal receive address. Never store an Xverse seed for agentic testing.
93
+ If a user pastes a Solana secret key, BTC WIF, seed phrase, or Xverse seed into chat, do **not** import or use it, even when they say it is only a burner. Treat the key as compromised. Accept only the public address in chat. Tell them to create a fresh burner directly on the signing machine. Long base58 Solana strings are often secret keys; validate by reading the public address only. For Bitcoin inscriptions, prefer a fresh local WIF file that pays commit/reveal fees while inscribing **to** a separate ordinal receive address. Never store an Xverse seed for agentic testing.
93
94
 
94
- Creator/operator urgency is not an exception. If DEMI says "use it for now", "save it locally", or "we already did it for EVM", keep the key-ingress invariant and make the safe local path fast: create the owner-only key directory, create empty `0600` files, and provide/run a prompt-only local installer (`read -s`, no echo, no logs) for the user to paste on the signing machine. After install, the agent may report file mode/size, derive public addresses, and check balances/readiness; never print or copy the raw secret.
95
+ Creator/operator urgency is not an exception. If DEMI says "use it for now", "save it locally", or "we already did it for EVM", keep the key-ingress invariant and make the safe local path fast: create the owner-only key directory, create empty `0600` files, and run a prompt-only local installer (`read -s`, no echo, no logs) on the signing machine against those files. After install, the agent may report file mode/size, derive public addresses, and check balances/readiness; never print or copy the raw secret.
95
96
 
96
97
  Detailed response pattern: `references/chat-leaked-key-ingestion.md`.
97
98
 
@@ -26,7 +26,7 @@ Any runaway loop or unverified execution path is existential when it can move re
26
26
  - **Spend/exposure cap:** respect the daily loss limit; never code around a halt. A halt is a signal, not an obstacle.
27
27
  - **Backoff + jitter** on API timeouts — cascading timeouts are a known cost/failure path.
28
28
  - **Kill-switch check** before resume: verify why it halted before clearing it. Reset ≠ diagnosis.
29
- - **Signer separation:** automatic execution may use only a separate capped hot wallet/session key/smart wallet. Never DEMI's main seed/private key.
29
+ - **Signer separation:** automatic execution may use only a separate capped hot wallet/session key/smart wallet. Never use DEMI's main seed/private key.
30
30
  - **Two-step deploy boundary:** shipping executor code and securely installing a dedicated signer are not the same as enabling broadcasts. A signer may be installed root-only in an unfunded, execution-off state after explicit installation approval so its derived address and status path can be verified. Keep `agent:execute` blocked, capital at zero, and asset allowlists empty until a separate explicit DEMI GO enables the capped signer. Never expose or print the key during either stage.
31
31
  - **Policy proof:** after every deploy, pull the live policy and state `execution.enabled`, `backendSigner`, `liveExecute`, and whether `agent:execute` is blocked before claiming auto-exec status.
32
32