@buildaureon/sdk 0.1.2 → 0.1.8

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.
@@ -127,7 +127,7 @@ sequenceDiagram
127
127
 
128
128
  - **Capital Book** — gateway portfolio used for weight math (`syncPortfolio`).
129
129
  - **Vault balances** — on-chain capital Automatic restores trade against.
130
- - Empty vault ⇒ Automatic restores cannot meaningfully settle on-chain even if policy exists.
130
+ - Empty vault ⇒ Automatic restore returns 409. It does not stage a fake success or edit the capital book.
131
131
 
132
132
  ---
133
133
 
@@ -184,16 +184,18 @@ flowchart TD
184
184
 
185
185
  ---
186
186
 
187
- ## 8. Network (early access testnet)
187
+ ## 8. Network
188
188
 
189
- | Item | Value |
190
- | --- | --- |
191
- | Chain | Robinhood Chain testnet |
192
- | Chain ID | `46630` |
193
- | API | `https://api.aureonlabs.network` |
194
- | Explorer | Configure via product / env (`AUREON_EXPLORER_BASE`) |
189
+ Default omitted SDK/MCP options are the **isolated mainnet stack** (4663 + local 8788). Public `api.aureonlabs.network` is still **testnet 46630**.
190
+
191
+ | Item | Mainnet (default) | Testnet (opt-in) |
192
+ | --- | --- | --- |
193
+ | Chain | Robinhood Chain mainnet | Robinhood Chain testnet |
194
+ | Chain ID | `4663` | `46630` |
195
+ | API | `http://127.0.0.1:8788` | `https://api.aureonlabs.network` |
196
+ | Explorer | `https://robinhoodchain.blockscout.com` | `https://explorer.testnet.chain.robinhood.com` |
195
197
 
196
- Confirm live addresses and allowlisted symbols from the operator utility and API responses do not hardcode stale addresses in agents.
198
+ Production does **not** already sync 4663. Confirm live addresses from the API you actually call.
197
199
 
198
200
  ---
199
201
 
package/docs/auth.md CHANGED
@@ -40,8 +40,9 @@ Control-plane calls (sync, objectives, health, restore, vault reads, prepare-*)
40
40
  import { createAureonClient } from "@buildaureon/sdk";
41
41
 
42
42
  const aureon = createAureonClient({
43
- baseUrl: "https://api.aureonlabs.network",
44
43
  apiKey: process.env.AUREON_API_KEY!, // issued key from Developers
44
+ // omit network → mainnet 4663 / http://127.0.0.1:8788
45
+ // network: "testnet" → public host (still 46630)
45
46
  });
46
47
 
47
48
  const me = await aureon.me();
@@ -88,7 +89,7 @@ import { createAureonClient, createSessionTokenProvider } from "@buildaureon/sdk
88
89
 
89
90
  const session = createSessionTokenProvider(null);
90
91
  const aureon = createAureonClient({
91
- baseUrl: "https://api.aureonlabs.network",
92
+ network: "testnet", // public host, still chain 46630
92
93
  apiKey: process.env.AUREON_API_KEY,
93
94
  getAccessToken: session.getAccessToken,
94
95
  });
@@ -143,7 +144,8 @@ session.clear();
143
144
  | Variable | Required | Description |
144
145
  | --- | --- | --- |
145
146
  | `AUREON_API_KEY` | Recommended | Issued developer key |
146
- | `AUREON_API_URL` | No | Defaults to `https://api.aureonlabs.network` |
147
+ | `AUREON_NETWORK` | No | Omit for mainnet 4663 / `http://127.0.0.1:8788`. Set `testnet` for the public host (still 46630). |
148
+ | `AUREON_API_URL` | No | Optional override. Must match `AUREON_NETWORK` if both are set. |
147
149
  | `AUREON_TOKEN` | No | Optional Bearer for CLI / scripts |
148
150
 
149
151
  CLI example:
@@ -32,7 +32,8 @@ import {
32
32
  } from "@buildaureon/sdk";
33
33
 
34
34
  const aureon = createAureonClient({
35
- // baseUrl defaults to https://api.aureonlabs.network
35
+ // network defaults to mainnet (4663 / http://127.0.0.1:8788)
36
+ // network: "testnet" → public host (still chain 46630)
36
37
  apiKey: process.env.AUREON_API_KEY,
37
38
  getAccessToken: () => sessionToken,
38
39
  timeoutMs: 30_000,
@@ -44,7 +45,8 @@ const aureon = createAureonClient({
44
45
 
45
46
  | Option | Required | Default | Description |
46
47
  |--------|----------|---------|-------------|
47
- | `baseUrl` | no | `https://api.aureonlabs.network` | Absolute `http://` or `https://` URL. |
48
+ | `network` | no | `mainnet` | `mainnet` = 4663 / `http://127.0.0.1:8788`. `testnet` = public host (still 46630). |
49
+ | `baseUrl` | no | mainnet local API | Absolute `http://` or `https://` URL. Wins when set; mismatch with `network` throws. |
48
50
  | `apiKey` | SDK / CLI | N/A | Sent as `X-Aureon-Api-Key`. Issued developer keys also identify the bound wallet (no Bearer required). Env bootstrap keys are product-gate only. Utility uses wallet Bearer only. |
49
51
  | `getAccessToken` | no | N/A | Optional Bearer getter. Wins over API-key identity when present. |
50
52
  | `authToken` | no | N/A | Static Bearer string when `getAccessToken` is omitted. |
@@ -59,8 +61,12 @@ const aureon = createAureonClient({
59
61
 
60
62
  | Rule | Behavior |
61
63
  |------|----------|
62
- | Omitted `baseUrl` | Uses production default |
64
+ | Omitted `network` and `baseUrl` | Local mainnet `http://127.0.0.1:8788`, chain 4663 |
65
+ | `network: "testnet"` | Public `https://api.aureonlabs.network` (still 46630) |
66
+ | Explicit `baseUrl` | Wins; infer network from known hosts |
67
+ | `network` + disagreeing `baseUrl` | Throws |
63
68
  | Invalid `baseUrl` scheme | Throws via `assertBaseUrl` |
69
+ | `aureon.network` / `aureon.chainId` | Resolved bundle |
64
70
  | Both `authToken` and `getAccessToken` | Transport uses `getAccessToken` only |
65
71
  | `aureon.baseUrl` getter | Returns resolved base (no trailing slash) |
66
72
 
@@ -365,6 +371,172 @@ async getOverview(): Promise<DashboardOverview>
365
371
  | HTTP | `GET /overview` |
366
372
  | Contains | Health counts, global score, 24h portfolio change (daily snapshots), evaluation schedule, recent executions + events |
367
373
 
374
+ ### `getAllocationVsTarget()`
375
+
376
+ ```ts
377
+ async getAllocationVsTarget(): Promise<{
378
+ rows: AllocationComparisonRow[];
379
+ paradox: PlanParadoxResult;
380
+ overview: DashboardOverview;
381
+ }>
382
+ ```
383
+
384
+ | | |
385
+ |--|--|
386
+ | Auth | Required |
387
+ | HTTP | Composite — parallel `GET /overview`, `GET /objectives`, `GET /health` |
388
+ | Returns | Per-objective current vs target weights plus a green-book/off-plan paradox flag |
389
+ | Use | demo — objective vs actual portfolio without stitching JSON yourself |
390
+
391
+ Helpers `buildAllocationComparison()` and `detectPlanParadox()` are exported for custom integrators. See `pnpm example:green-vs-plan`.
392
+
393
+ ### `applyFinancialIntent(intent)`
394
+
395
+ ```ts
396
+ async applyFinancialIntent(intent: FinancialIntent): Promise<ObjectivePortfolioFlow>
397
+ ```
398
+
399
+ | | |
400
+ |--|--|
401
+ | Auth | Required |
402
+ | HTTP | Composite — `POST /objectives` + watchdog refresh + `GET /health` + `GET /portfolio` |
403
+ | Returns | Intent summary, created objective, health, portfolio snapshot, teaching message |
404
+ | Use | AI → objective → portfolio in one call |
405
+
406
+ ### `getObjectivePortfolioFlow(objectiveId?)`
407
+
408
+ ```ts
409
+ async getObjectivePortfolioFlow(objectiveId?: string): Promise<ObjectivePortfolioFlow[]>
410
+ ```
411
+
412
+ | | |
413
+ |--|--|
414
+ | Auth | Required |
415
+ | HTTP | Composite — objectives + health + portfolio |
416
+ | Returns | Flow snapshots for active objectives (or one id) |
417
+
418
+ Helpers `parseFinancialIntent()`, `resolveObjectiveFromIntent()`, and `buildObjectivePortfolioFlow()` are exported. See `pnpm example:ai-to-objective-to-portfolio`.
419
+
420
+ ### `runDriftRestoreDemo()`
421
+
422
+ ```ts
423
+ async runDriftRestoreDemo(): Promise<DriftRestoreFlow>
424
+ ```
425
+
426
+ | | |
427
+ |--|--|
428
+ | Auth | Required |
429
+ | HTTP | Composite — portfolio seed, objective create, market event (`autoRestore: false`), restore plan, manual restore |
430
+ | Returns | Three-beat `DriftRestoreFlow` — aligned → drift → restored |
431
+ | Use | drift → detection → restore teaching demo |
432
+
433
+ ### `getDriftRestoreFlow(objectiveId?)`
434
+
435
+ ```ts
436
+ async getDriftRestoreFlow(objectiveId?: string): Promise<DriftRestoreFlow[]>
437
+ ```
438
+
439
+ | | |
440
+ |--|--|
441
+ | Auth | Required |
442
+ | HTTP | Composite — objectives + health + allocation + executions (+ restore plan when off-plan) |
443
+ | Returns | Inferred drift-restore flows for active objectives |
444
+
445
+ Helpers `buildDriftRestoreFlow()`, `buildDriftRestoreFlowFromSnapshot()`, and `inferDriftPhase()` are exported. See `pnpm example:drift-detect-restore`.
446
+
447
+ ### `runReceiptVerificationDemo()`
448
+
449
+ ```ts
450
+ async runReceiptVerificationDemo(): Promise<ReceiptVerificationFlow>
451
+ ```
452
+
453
+ | | |
454
+ |--|--|
455
+ | Auth | Required |
456
+ | HTTP | Composite — `runDriftRestoreDemo()` + local validation + settlement lookup + timeline |
457
+ | Returns | Three-beat `ReceiptVerificationFlow` — claim → validate → verify |
458
+ | Use | receipt → verification teaching demo |
459
+
460
+ ### `getReceiptVerificationFlow(executionId?)`
461
+
462
+ ```ts
463
+ async getReceiptVerificationFlow(executionId?: string): Promise<ReceiptVerificationFlow[]>
464
+ ```
465
+
466
+ | | |
467
+ |--|--|
468
+ | Auth | Required |
469
+ | HTTP | Composite — executions + validation + settlement + timeline |
470
+ | Returns | Verification flows for recent or specified execution(s) |
471
+
472
+ Helpers `buildReceiptVerificationFlow()`, `inferProofTier()`, and `validateExecutionReceipt()` are exported. See `pnpm example:receipt-verification`.
473
+
474
+ ### `runPortfolioWatchDemo(input?)`
475
+
476
+ ```ts
477
+ async runPortfolioWatchDemo(input?: {
478
+ brief?: string;
479
+ host?: "cursor" | "claude" | "mcp";
480
+ }): Promise<PortfolioWatchFlow>
481
+ ```
482
+
483
+ | | |
484
+ |--|--|
485
+ | Auth | Required |
486
+ | HTTP | Composite — `applyFinancialIntent` + market event (`autoRestore: true`) + timeline |
487
+ | Returns | Portfolio watch flow — register → while away → return briefing |
488
+ | Use | agent-in-host demo |
489
+
490
+ ### `getPortfolioWatchFlow(input?)`
491
+
492
+ ```ts
493
+ async getPortfolioWatchFlow(input?: {
494
+ objectiveId?: string;
495
+ brief?: string;
496
+ host?: "cursor" | "claude" | "mcp";
497
+ }): Promise<PortfolioWatchFlow[]>
498
+ ```
499
+
500
+ | | |
501
+ |--|--|
502
+ | Auth | Required |
503
+ | HTTP | Composite — Automatic objectives + health + allocation + timeline |
504
+ | Returns | Read-only briefing for active Automatic objectives |
505
+
506
+ Helpers `buildPortfolioWatchFlow()`, `DEFAULT_PORTFOLIO_WATCH_BRIEF`, and `inferPortfolioWatchPhase()` are exported. See `pnpm example:portfolio-watch`.
507
+
508
+ ### `runFullAureonLoopDemo(input?)`
509
+
510
+ ```ts
511
+ async runFullAureonLoopDemo(input?: {
512
+ brief?: string;
513
+ }): Promise<FullAureonLoopFlow>
514
+ ```
515
+
516
+ | | |
517
+ |--|--|
518
+ | Auth | Required |
519
+ | HTTP | Composite — intent + allocation paradox + restore (`autoRestore: false`) + receipt verification |
520
+ | Returns | Full loop — intent → plan check → restore → verify |
521
+ | Use | Content Arc — full AUREON loop positioning demo |
522
+
523
+ ### `getFullAureonLoopFlow(input?)`
524
+
525
+ ```ts
526
+ async getFullAureonLoopFlow(input?: {
527
+ objectiveId?: string;
528
+ brief?: string;
529
+ }): Promise<FullAureonLoopFlow[]>
530
+ ```
531
+
532
+ | | |
533
+ |--|--|
534
+ | Auth | Required |
535
+ | HTTP | Composite — objectives + allocation + latest receipt + validation |
536
+ | Returns | Read-only full-loop flows for active objectives with receipts |
537
+
538
+ Helpers `buildFullAureonLoopFlow()`, `DEFAULT_FULL_LOOP_BRIEF`, and `inferFullAureonLoopPhase()` are exported. See `pnpm example:full-aureon-loop`.
539
+
368
540
  ---
369
541
 
370
542
  ## 6. Vault
@@ -478,7 +650,7 @@ async applyMarketEvent(input: ApplyMarketEventInput): Promise<{
478
650
  |--|--|
479
651
  | Auth | Required |
480
652
  | HTTP | `POST /market/events` |
481
- | Normalization | Uppercases symbol; `autoRestore` defaults **true** |
653
+ | Normalization | Uppercases symbol; `autoRestore` defaults **false** (must opt in to restore) |
482
654
  | Validation | Symbol required; finite `priceChangeRatio`; rejects extreme ≤ -0.95 |
483
655
 
484
656
  ### `getRestorePlan(objectiveId)`
@@ -578,6 +750,17 @@ session.clear();
578
750
  | `syncPortfolio` | POST | `/portfolio/sync` | **yes** |
579
751
  | `refreshWatchdog` | POST | `/watchdog/refresh` | **yes** |
580
752
  | `getOverview` | GET | `/overview` | **yes** |
753
+ | `getAllocationVsTarget` | composite | overview + objectives + health | **yes** |
754
+ | `applyFinancialIntent` | composite | create objective + health + portfolio | **yes** |
755
+ | `getObjectivePortfolioFlow` | composite | objectives + health + portfolio | **yes** |
756
+ | `runDriftRestoreDemo` | composite | seed + drift + manual restore | **yes** |
757
+ | `getDriftRestoreFlow` | composite | objectives + health + allocation + executions | **yes** |
758
+ | `runReceiptVerificationDemo` | composite | drift-restore + validate + settlement | **yes** |
759
+ | `getReceiptVerificationFlow` | composite | executions + validation + settlement | **yes** |
760
+ | `runPortfolioWatchDemo` | composite | intent + auto-restore market event + briefing | **yes** |
761
+ | `getPortfolioWatchFlow` | composite | Automatic objectives + health + timeline | **yes** |
762
+ | `runFullAureonLoopDemo` | composite | intent + plan paradox + restore + verify | **yes** |
763
+ | `getFullAureonLoopFlow` | composite | objectives + allocation + receipt validation | **yes** |
581
764
  | `listMarketPresets` | GET | `/market/presets` | **yes** |
582
765
  | `applyMarketEvent` | POST | `/market/events` | **yes** |
583
766
  | `getRestorePlan` | GET | `/objectives/:id/restore-plan` | **yes** |
@@ -402,14 +402,84 @@ export interface ExecutionReceipt {
402
402
  result: string;
403
403
  createdAt: string;
404
404
  confirmedAt: string | null;
405
- /**
406
- * vault represents keeper rebalances on the Robinhood Chain.
407
- * staged represents simulated/book-only ledger updates.
408
- */
409
- settlement?: "staged" | "vault";
405
+ /** Required. vault = on-chain keeper path; staged = capital-book update only. */
406
+ settlement: "staged" | "vault";
407
+ /** Block explorer link when vault tx is confirmed (`0x…`); null for staged. */
408
+ explorerUrl?: string | null;
409
+ /** Present when the objective is registered on ObjectiveRegistry. */
410
+ registryRef?: RegistryRef;
411
+ /** True when a settlement record exists for this execution (vault only). */
412
+ verifiedOnChain?: boolean;
413
+ /** Populated when `verifiedOnChain` is true. */
414
+ settlementRecord?: SettlementRecord;
410
415
  }
411
416
  ```
412
417
 
418
+ ### SettlementRecord (Day 8)
419
+
420
+ Independent on-chain proof from AureonVault `Rebalanced` events:
421
+
422
+ ```ts
423
+ export interface SettlementRecord {
424
+ id: string;
425
+ executionId: string | null;
426
+ objectiveId: string | null;
427
+ walletAddress: string;
428
+ settlement: "vault";
429
+ transactionHash: string;
430
+ blockNumber: number;
431
+ logIndex: number;
432
+ vaultAddress: string;
433
+ tokenSell: string;
434
+ tokenBuy: string;
435
+ amountIn: string;
436
+ amountOut: string;
437
+ explorerUrl: string;
438
+ verifiedAt: string;
439
+ status: "confirmed" | "orphan";
440
+ registryRef?: RegistryRef;
441
+ }
442
+ ```
443
+
444
+ Client methods: `getExecutionSettlement`, `listSettlements`, `confirmExecutionSettlement`.
445
+
446
+ ---
447
+
448
+ ## 6.1 Receipt validation (Day 9)
449
+
450
+ Validate receipts locally before trusting them in automation:
451
+
452
+ ```ts
453
+ import {
454
+ validateExecutionReceipt,
455
+ assertValidExecutionReceipt,
456
+ } from "@buildaureon/sdk";
457
+
458
+ const result = validateExecutionReceipt(receipt);
459
+ if (!result.valid) {
460
+ console.error(result.issues);
461
+ }
462
+
463
+ assertValidExecutionReceipt(receipt); // throws AureonValidationError
464
+ ```
465
+
466
+ `ReceiptValidationResult`:
467
+
468
+ ```ts
469
+ export type ReceiptValidationIssue = {
470
+ code: string;
471
+ message: string;
472
+ path?: string;
473
+ };
474
+
475
+ export type ReceiptValidationResult = {
476
+ valid: boolean;
477
+ issues: ReceiptValidationIssue[];
478
+ };
479
+ ```
480
+
481
+ Enforces required fields, `vault` vs `staged` honesty, explorer rules, and `verifiedOnChain` / `settlementRecord` consistency. See [receipt-validation.md](./receipt-validation.md).
482
+
413
483
  #### JSON Representation Example
414
484
  ```json
415
485
  {
@@ -422,7 +492,12 @@ export interface ExecutionReceipt {
422
492
  "result": "Exchanged stock tokens for 3750.0 USDG on Robinhood Chain",
423
493
  "createdAt": "2026-07-15T22:46:00.000Z",
424
494
  "confirmedAt": "2026-07-15T22:46:05.000Z",
425
- "settlement": "vault"
495
+ "settlement": "vault",
496
+ "explorerUrl": "https://explorer.testnet.chain.robinhood.com/tx/0xe295c2763f0d4681a8b54dfd38a0f8bfd21051515fcd9185a494ff3c8a99478f",
497
+ "registryRef": {
498
+ "objectiveKey": "0xabc…",
499
+ "contractAddress": "0x76d8f088d2abba3c73ff93f92308f8b59b250ea5"
500
+ }
426
501
  }
427
502
  ```
428
503
 
@@ -134,7 +134,7 @@ flowchart TD
134
134
  | --- | --- |
135
135
  | Invalid / paused key | Stop loop; operator rotates Developers key |
136
136
  | Bootstrap key alone | Switch to issued key |
137
- | Vault empty on restore | Prepare deposit broadcast sync retry |
137
+ | Vault empty on restore | Expected first use. Call `prepareVaultDeposit`, return unsigned steps, wait for the **user/host** to broadcast. Agents do not fund the vault. |
138
138
  | Locked field on update | Recreate objective |
139
139
  | Conflict mid-restore | Back off; read timeline / executions |
140
140
  | Staged settlement returned | Do not treat as on-chain success |
@@ -186,7 +186,7 @@ import {
186
186
 
187
187
  test("empty objective name fails validation", async () => {
188
188
  const client = createAureonClient({
189
- baseUrl: "https://api.aureonlabs.network",
189
+ network: "testnet",
190
190
  apiKey: "test",
191
191
  });
192
192
 
@@ -11,8 +11,11 @@ Integrate `@buildaureon/sdk` into server-side agents and automated rebalancing l
11
11
  ```mermaid
12
12
  flowchart TD
13
13
  Init[1_issued_API_key_client] --> Sync[2_sync_Capital_Book]
14
- Sync --> Fund[3_fund_vault_if_empty]
15
- Fund --> Obj[4_create_Auto_objective]
14
+ Sync --> Empty{vault empty?}
15
+ Empty -->|yes| FourOhNine[restore 409]
16
+ FourOhNine --> Prep[prepareVaultDeposit unsigned]
17
+ Prep --> User[user/host signs when they use it]
18
+ Empty -->|no| Obj[create Auto objective]
16
19
  Obj --> Loop[5_watchdog_heartbeat]
17
20
  Loop -->|breach| Plan[6_restore_plan]
18
21
  Plan --> Restore[7_restoreObjective]
@@ -22,10 +25,12 @@ flowchart TD
22
25
  ### Step 1 — Client
23
26
 
24
27
  ```ts
25
- import { createAureonClient } from "@buildaureon/sdk";
28
+ import { createAureonClient, resolveAureonNetworkFromEnv } from "@buildaureon/sdk";
26
29
 
30
+ const resolved = resolveAureonNetworkFromEnv();
27
31
  export const aureon = createAureonClient({
28
- baseUrl: process.env.AUREON_API_URL || "https://api.aureonlabs.network",
32
+ network: resolved.network,
33
+ baseUrl: resolved.baseUrl,
29
34
  apiKey: process.env.AUREON_API_KEY!, // issued Developers key
30
35
  timeoutMs: 30_000,
31
36
  maxRetries: 2,
@@ -39,11 +44,17 @@ console.log("operating as", me.walletAddress);
39
44
  Optional Bearer (usually unnecessary with an issued key):
40
45
 
41
46
  ```ts
42
- import { createAureonClient, createSessionTokenProvider } from "@buildaureon/sdk";
47
+ import {
48
+ createAureonClient,
49
+ createSessionTokenProvider,
50
+ resolveAureonNetworkFromEnv,
51
+ } from "@buildaureon/sdk";
43
52
 
53
+ const resolved = resolveAureonNetworkFromEnv();
44
54
  const session = createSessionTokenProvider(process.env.AUREON_TOKEN ?? null);
45
55
  export const aureon = createAureonClient({
46
- baseUrl: process.env.AUREON_API_URL || "https://api.aureonlabs.network",
56
+ network: resolved.network,
57
+ baseUrl: resolved.baseUrl,
47
58
  apiKey: process.env.AUREON_API_KEY ?? null,
48
59
  getAccessToken: session.getAccessToken,
49
60
  });
@@ -62,28 +73,19 @@ console.log({
62
73
 
63
74
  Prefer `syncPortfolio()` over hand-seeded books in production. Use `setPortfolio` only for controlled rehearsals.
64
75
 
65
- ### Step 3 — Fund vault when needed
76
+ ### Step 3 — Empty vault is first use (do not fund for the user)
66
77
 
67
- Automatic restores require vault capital. Prepare returns **unsigned** steps your host signs and broadcasts.
78
+ Automatic restore on an empty vault must **409**. That is the same path as testnet. The SDK/MCP process does **not** broadcast a deposit. When the user actually uses the product, their host wallet signs `prepareVaultDeposit` steps.
68
79
 
69
80
  ```ts
70
81
  import type { VaultPrepareResult } from "@buildaureon/sdk";
71
82
 
72
- async function ensureVaultFunded(
73
- symbol: string,
74
- amount: string,
75
- broadcast: (step: VaultPrepareResult["steps"][number]) => Promise<string>
76
- ) {
77
- const status = await aureon.getVaultStatus();
78
- if (!status.empty && status.canRestore) return status;
79
-
80
- const prep = await aureon.prepareVaultDeposit({ symbol, amount });
81
- for (const step of prep.steps) {
82
- const hash = await broadcast(step);
83
- console.log(step.label, hash);
84
- }
85
-
86
- return aureon.getVaultStatus();
83
+ const status = await aureon.getVaultStatus();
84
+ if (status.empty) {
85
+ // restoreObjective must 409 here — do not treat that as a bug
86
+ const prep = await aureon.prepareVaultDeposit({ symbol: "USDG", amount: "0.05" });
87
+ // prep.steps are UNSIGNED. Return them. The user broadcasts when they fund.
88
+ return prep;
87
89
  }
88
90
  ```
89
91
 
@@ -163,7 +165,147 @@ Start with one Automatic `balanced_portfolio` objective and a funded vault befor
163
165
 
164
166
  ---
165
167
 
166
- ## 3. Daemon runners
168
+ ## 2b. Green vs plan paradox demo (Update 2)
169
+
170
+ Most dashboards celebrate green PnL. AUREON separates book performance from plan adherence:
171
+
172
+ ```ts
173
+ // Baseline
174
+ const before = await aureon.getAllocationVsTarget();
175
+ console.log(before.rows); // current vs target per objective
176
+
177
+ // Controlled shock — keep violation visible
178
+ await aureon.applyMarketEvent({
179
+ symbol: "NVDA",
180
+ priceChangeRatio: 0.45,
181
+ autoRestore: false,
182
+ });
183
+
184
+ const after = await aureon.getAllocationVsTarget();
185
+ console.log(after.paradox.message);
186
+ // "Book is up (5.0%), but 1 objective is off-plan."
187
+ ```
188
+
189
+ Run the full script: `pnpm example:green-vs-plan` (requires `AUREON_API_KEY`).
190
+
191
+ ---
192
+
193
+ ## 2c. AI → objective → portfolio (Update 3)
194
+
195
+ Most AI agents can transact but forget what the user wanted. AUREON registers intent as a persistent objective, then reads the portfolio through that policy:
196
+
197
+ ```ts
198
+ const flow = await aureon.applyFinancialIntent({
199
+ brief: "Keep about 20% of the portfolio in stable assets",
200
+ kind: "stable_allocation",
201
+ targetWeight: 0.2,
202
+ tolerance: 0.02,
203
+ });
204
+
205
+ console.log(flow.intent.policySummary);
206
+ console.log(flow.objective.id);
207
+ console.log(flow.health?.state);
208
+ console.log(flow.message);
209
+ ```
210
+
211
+ For demos, `parseFinancialIntent(brief)` converts a user sentence into structured fields (rule-based, not production NLU).
212
+
213
+ Run the full script: `pnpm example:ai-to-objective-to-portfolio`.
214
+
215
+ Then use `getAllocationVsTarget()` (Update 2) to compare objective vs actual over time.
216
+
217
+ ---
218
+
219
+ ## 2d. Drift → detection → restore (Update 4)
220
+
221
+ Update 2 stops at the paradox — book up, plan off-target, no restore. Update 4 closes the loop:
222
+
223
+ ```ts
224
+ const flow = await aureon.runDriftRestoreDemo();
225
+
226
+ console.log(flow.rule.summary);
227
+ console.log(flow.phases.aligned.health.state);
228
+ console.log(flow.phases.drift.health.state);
229
+ console.log(flow.phases.restored?.receipt?.settlement);
230
+ console.log(flow.message);
231
+ ```
232
+
233
+ For read-only monitoring without mutating the book, use `getDriftRestoreFlow()` — it joins objectives, health, allocation rows, restore plans (when off-plan), and the latest execution receipt.
234
+
235
+ Run the full script: `pnpm example:drift-detect-restore`.
236
+
237
+ ---
238
+
239
+ ## 2e. Receipt → verification (Update 5)
240
+
241
+ Update 4 returns a receipt after restore. Update 5 teaches that **"transaction successful" is a claim**, not proof:
242
+
243
+ ```ts
244
+ const flow = await aureon.runReceiptVerificationDemo();
245
+
246
+ console.log(flow.phases.claimed.result);
247
+ console.log(flow.phases.validation.valid);
248
+ console.log(flow.proofTier);
249
+ console.log(flow.phases.settlement?.verifiedOnChain);
250
+ console.log(flow.message);
251
+ ```
252
+
253
+ Proof tiers: **claim_only** (validation failed) → **schema_valid** (honest receipt shape) → **chain_verified** (independent settlement record for vault).
254
+
255
+ For read-only checks on existing executions, use `getReceiptVerificationFlow(executionId?)`.
256
+
257
+ Run the full script: `pnpm example:receipt-verification`.
258
+
259
+ Forward link: Update 6 — Claude/Cursor + AUREON agent-in-host demo.
260
+
261
+ ---
262
+
263
+ ## 2f. Portfolio watch while away (Update 6)
264
+
265
+ Consumer hook: *“Imagine telling your AI: watch my portfolio while I'm away.”*
266
+
267
+ ```ts
268
+ const flow = await aureon.runPortfolioWatchDemo({ host: "cursor" });
269
+
270
+ console.log(flow.userBrief);
271
+ console.log(flow.phases.register.automationMode);
272
+ console.log(flow.phases.whileAway?.autoRestored);
273
+ for (const line of flow.phases.briefing.summaryLines) {
274
+ console.log(line);
275
+ }
276
+ ```
277
+
278
+ Update 4 uses `autoRestore: false` (manual restore demo). Update 6 uses **`autoRestore: true`** — Automatic mode acts while the operator is away.
279
+
280
+ For read-only briefing on existing Automatic objectives: `getPortfolioWatchFlow()`.
281
+
282
+ Run the full script: `pnpm example:portfolio-watch`.
283
+
284
+ Forward link: Update 7 — full AUREON loop.
285
+
286
+ ---
287
+
288
+ ## 2g. Full AUREON loop (Update 7)
289
+
290
+ Positioning hook: *"We're not building another portfolio tracker."*
291
+
292
+ ```ts
293
+ const flow = await aureon.runFullAureonLoopDemo();
294
+
295
+ console.log(flow.phases.intent.policySummary);
296
+ console.log(flow.phases.planCheck.afterShock.paradox.detected);
297
+ console.log(flow.phases.driftRestore.settlement);
298
+ console.log(flow.phases.verification.proofTier);
299
+ console.log(flow.message);
300
+ ```
301
+
302
+ One composite closes the content arc: **intent → plan check → restore → receipt verification**. A tracker stops at marks; AUREON registers policy, exposes green-vs-plan failure (`autoRestore: false`), restores, then validates the receipt.
303
+
304
+ For read-only joins on existing objectives with receipts: `getFullAureonLoopFlow()`.
305
+
306
+ Run the full script: `pnpm example:full-aureon-loop`.
307
+
308
+ ---
167
309
 
168
310
  ### PM2
169
311
 
@@ -177,7 +319,8 @@ module.exports = {
177
319
  autorestart: true,
178
320
  env: {
179
321
  NODE_ENV: "production",
180
- AUREON_API_URL: "https://api.aureonlabs.network",
322
+ // omit AUREON_API_URL for local mainnet 8788 / 4663
323
+ // AUREON_NETWORK: "testnet" // public host, still 46630
181
324
  // AUREON_API_KEY from secret store / PM2 ecosystem secrets
182
325
  },
183
326
  },
@@ -240,7 +383,7 @@ Never log API keys, Bearer tokens, or private keys.
240
383
  | --- | --- | --- |
241
384
  | 401 invalid key | Wrong / paused / revoked key | Rotate in Developers |
242
385
  | 401 need issued key | Env bootstrap key alone | Use an issued Developers key |
243
- | Vault empty / cannot restore | No vault capital | `prepareVaultDeposit` broadcast sync |
386
+ | Vault empty / cannot restore | First use no user deposit yet | `prepareVaultDeposit` (unsigned). User/host broadcasts when they fund. Agents do not. |
244
387
  | Update rejects symbol/mode | Locked at create | Recreate objective |
245
388
  | Restore receipt `staged` | Ledger-local path | Do not claim on-chain |
246
389
  | Health still violated after restore | Prices / sizing / liquidity | Re-read plan, vault balances, timeline |