@buildaureon/sdk 0.1.2 → 0.1.7
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.
- package/LICENSE +21 -21
- package/README.md +15 -0
- package/config/network.json +10 -10
- package/dist/index.d.ts +646 -92
- package/dist/index.js +1723 -204
- package/dist/index.js.map +1 -1
- package/docs/architecture.md +1 -1
- package/docs/client-api.md +178 -1
- package/docs/data-contracts.md +81 -6
- package/docs/integration-guide.md +141 -1
- package/docs/receipt-validation.md +63 -0
- package/examples/ai-to-objective-to-portfolio/main.ts +127 -0
- package/examples/audit-trail/main.ts +53 -0
- package/examples/drift-detect-restore/main.ts +96 -0
- package/examples/full-aureon-loop/main.ts +83 -0
- package/examples/green-vs-plan/main.ts +139 -0
- package/examples/market-event/main.ts +2 -0
- package/examples/portfolio-watch/main.ts +84 -0
- package/examples/receipt-verification/main.ts +87 -0
- package/fixtures/reference-objectives.json +18 -18
- package/fixtures/reference-portfolio.json +10 -10
- package/package.json +68 -61
package/docs/architecture.md
CHANGED
|
@@ -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
|
|
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
|
|
package/docs/client-api.md
CHANGED
|
@@ -365,6 +365,172 @@ async getOverview(): Promise<DashboardOverview>
|
|
|
365
365
|
| HTTP | `GET /overview` |
|
|
366
366
|
| Contains | Health counts, global score, 24h portfolio change (daily snapshots), evaluation schedule, recent executions + events |
|
|
367
367
|
|
|
368
|
+
### `getAllocationVsTarget()`
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
async getAllocationVsTarget(): Promise<{
|
|
372
|
+
rows: AllocationComparisonRow[];
|
|
373
|
+
paradox: PlanParadoxResult;
|
|
374
|
+
overview: DashboardOverview;
|
|
375
|
+
}>
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
| | |
|
|
379
|
+
|--|--|
|
|
380
|
+
| Auth | Required |
|
|
381
|
+
| HTTP | Composite — parallel `GET /overview`, `GET /objectives`, `GET /health` |
|
|
382
|
+
| Returns | Per-objective current vs target weights plus a green-book/off-plan paradox flag |
|
|
383
|
+
| Use | demo — objective vs actual portfolio without stitching JSON yourself |
|
|
384
|
+
|
|
385
|
+
Helpers `buildAllocationComparison()` and `detectPlanParadox()` are exported for custom integrators. See `pnpm example:green-vs-plan`.
|
|
386
|
+
|
|
387
|
+
### `applyFinancialIntent(intent)`
|
|
388
|
+
|
|
389
|
+
```ts
|
|
390
|
+
async applyFinancialIntent(intent: FinancialIntent): Promise<ObjectivePortfolioFlow>
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
| | |
|
|
394
|
+
|--|--|
|
|
395
|
+
| Auth | Required |
|
|
396
|
+
| HTTP | Composite — `POST /objectives` + watchdog refresh + `GET /health` + `GET /portfolio` |
|
|
397
|
+
| Returns | Intent summary, created objective, health, portfolio snapshot, teaching message |
|
|
398
|
+
| Use | AI → objective → portfolio in one call |
|
|
399
|
+
|
|
400
|
+
### `getObjectivePortfolioFlow(objectiveId?)`
|
|
401
|
+
|
|
402
|
+
```ts
|
|
403
|
+
async getObjectivePortfolioFlow(objectiveId?: string): Promise<ObjectivePortfolioFlow[]>
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
| | |
|
|
407
|
+
|--|--|
|
|
408
|
+
| Auth | Required |
|
|
409
|
+
| HTTP | Composite — objectives + health + portfolio |
|
|
410
|
+
| Returns | Flow snapshots for active objectives (or one id) |
|
|
411
|
+
|
|
412
|
+
Helpers `parseFinancialIntent()`, `resolveObjectiveFromIntent()`, and `buildObjectivePortfolioFlow()` are exported. See `pnpm example:ai-to-objective-to-portfolio`.
|
|
413
|
+
|
|
414
|
+
### `runDriftRestoreDemo()`
|
|
415
|
+
|
|
416
|
+
```ts
|
|
417
|
+
async runDriftRestoreDemo(): Promise<DriftRestoreFlow>
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
| | |
|
|
421
|
+
|--|--|
|
|
422
|
+
| Auth | Required |
|
|
423
|
+
| HTTP | Composite — portfolio seed, objective create, market event (`autoRestore: false`), restore plan, manual restore |
|
|
424
|
+
| Returns | Three-beat `DriftRestoreFlow` — aligned → drift → restored |
|
|
425
|
+
| Use | drift → detection → restore teaching demo |
|
|
426
|
+
|
|
427
|
+
### `getDriftRestoreFlow(objectiveId?)`
|
|
428
|
+
|
|
429
|
+
```ts
|
|
430
|
+
async getDriftRestoreFlow(objectiveId?: string): Promise<DriftRestoreFlow[]>
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
| | |
|
|
434
|
+
|--|--|
|
|
435
|
+
| Auth | Required |
|
|
436
|
+
| HTTP | Composite — objectives + health + allocation + executions (+ restore plan when off-plan) |
|
|
437
|
+
| Returns | Inferred drift-restore flows for active objectives |
|
|
438
|
+
|
|
439
|
+
Helpers `buildDriftRestoreFlow()`, `buildDriftRestoreFlowFromSnapshot()`, and `inferDriftPhase()` are exported. See `pnpm example:drift-detect-restore`.
|
|
440
|
+
|
|
441
|
+
### `runReceiptVerificationDemo()`
|
|
442
|
+
|
|
443
|
+
```ts
|
|
444
|
+
async runReceiptVerificationDemo(): Promise<ReceiptVerificationFlow>
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
| | |
|
|
448
|
+
|--|--|
|
|
449
|
+
| Auth | Required |
|
|
450
|
+
| HTTP | Composite — `runDriftRestoreDemo()` + local validation + settlement lookup + timeline |
|
|
451
|
+
| Returns | Three-beat `ReceiptVerificationFlow` — claim → validate → verify |
|
|
452
|
+
| Use | receipt → verification teaching demo |
|
|
453
|
+
|
|
454
|
+
### `getReceiptVerificationFlow(executionId?)`
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
async getReceiptVerificationFlow(executionId?: string): Promise<ReceiptVerificationFlow[]>
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
| | |
|
|
461
|
+
|--|--|
|
|
462
|
+
| Auth | Required |
|
|
463
|
+
| HTTP | Composite — executions + validation + settlement + timeline |
|
|
464
|
+
| Returns | Verification flows for recent or specified execution(s) |
|
|
465
|
+
|
|
466
|
+
Helpers `buildReceiptVerificationFlow()`, `inferProofTier()`, and `validateExecutionReceipt()` are exported. See `pnpm example:receipt-verification`.
|
|
467
|
+
|
|
468
|
+
### `runPortfolioWatchDemo(input?)`
|
|
469
|
+
|
|
470
|
+
```ts
|
|
471
|
+
async runPortfolioWatchDemo(input?: {
|
|
472
|
+
brief?: string;
|
|
473
|
+
host?: "cursor" | "claude" | "mcp";
|
|
474
|
+
}): Promise<PortfolioWatchFlow>
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
| | |
|
|
478
|
+
|--|--|
|
|
479
|
+
| Auth | Required |
|
|
480
|
+
| HTTP | Composite — `applyFinancialIntent` + market event (`autoRestore: true`) + timeline |
|
|
481
|
+
| Returns | Portfolio watch flow — register → while away → return briefing |
|
|
482
|
+
| Use | agent-in-host demo |
|
|
483
|
+
|
|
484
|
+
### `getPortfolioWatchFlow(input?)`
|
|
485
|
+
|
|
486
|
+
```ts
|
|
487
|
+
async getPortfolioWatchFlow(input?: {
|
|
488
|
+
objectiveId?: string;
|
|
489
|
+
brief?: string;
|
|
490
|
+
host?: "cursor" | "claude" | "mcp";
|
|
491
|
+
}): Promise<PortfolioWatchFlow[]>
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
| | |
|
|
495
|
+
|--|--|
|
|
496
|
+
| Auth | Required |
|
|
497
|
+
| HTTP | Composite — Automatic objectives + health + allocation + timeline |
|
|
498
|
+
| Returns | Read-only briefing for active Automatic objectives |
|
|
499
|
+
|
|
500
|
+
Helpers `buildPortfolioWatchFlow()`, `DEFAULT_PORTFOLIO_WATCH_BRIEF`, and `inferPortfolioWatchPhase()` are exported. See `pnpm example:portfolio-watch`.
|
|
501
|
+
|
|
502
|
+
### `runFullAureonLoopDemo(input?)`
|
|
503
|
+
|
|
504
|
+
```ts
|
|
505
|
+
async runFullAureonLoopDemo(input?: {
|
|
506
|
+
brief?: string;
|
|
507
|
+
}): Promise<FullAureonLoopFlow>
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
| | |
|
|
511
|
+
|--|--|
|
|
512
|
+
| Auth | Required |
|
|
513
|
+
| HTTP | Composite — intent + allocation paradox + restore (`autoRestore: false`) + receipt verification |
|
|
514
|
+
| Returns | Full loop — intent → plan check → restore → verify |
|
|
515
|
+
| Use | Content Arc — full AUREON loop positioning demo |
|
|
516
|
+
|
|
517
|
+
### `getFullAureonLoopFlow(input?)`
|
|
518
|
+
|
|
519
|
+
```ts
|
|
520
|
+
async getFullAureonLoopFlow(input?: {
|
|
521
|
+
objectiveId?: string;
|
|
522
|
+
brief?: string;
|
|
523
|
+
}): Promise<FullAureonLoopFlow[]>
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
| | |
|
|
527
|
+
|--|--|
|
|
528
|
+
| Auth | Required |
|
|
529
|
+
| HTTP | Composite — objectives + allocation + latest receipt + validation |
|
|
530
|
+
| Returns | Read-only full-loop flows for active objectives with receipts |
|
|
531
|
+
|
|
532
|
+
Helpers `buildFullAureonLoopFlow()`, `DEFAULT_FULL_LOOP_BRIEF`, and `inferFullAureonLoopPhase()` are exported. See `pnpm example:full-aureon-loop`.
|
|
533
|
+
|
|
368
534
|
---
|
|
369
535
|
|
|
370
536
|
## 6. Vault
|
|
@@ -478,7 +644,7 @@ async applyMarketEvent(input: ApplyMarketEventInput): Promise<{
|
|
|
478
644
|
|--|--|
|
|
479
645
|
| Auth | Required |
|
|
480
646
|
| HTTP | `POST /market/events` |
|
|
481
|
-
| Normalization | Uppercases symbol; `autoRestore` defaults **
|
|
647
|
+
| Normalization | Uppercases symbol; `autoRestore` defaults **false** (must opt in to restore) |
|
|
482
648
|
| Validation | Symbol required; finite `priceChangeRatio`; rejects extreme ≤ -0.95 |
|
|
483
649
|
|
|
484
650
|
### `getRestorePlan(objectiveId)`
|
|
@@ -578,6 +744,17 @@ session.clear();
|
|
|
578
744
|
| `syncPortfolio` | POST | `/portfolio/sync` | **yes** |
|
|
579
745
|
| `refreshWatchdog` | POST | `/watchdog/refresh` | **yes** |
|
|
580
746
|
| `getOverview` | GET | `/overview` | **yes** |
|
|
747
|
+
| `getAllocationVsTarget` | composite | overview + objectives + health | **yes** |
|
|
748
|
+
| `applyFinancialIntent` | composite | create objective + health + portfolio | **yes** |
|
|
749
|
+
| `getObjectivePortfolioFlow` | composite | objectives + health + portfolio | **yes** |
|
|
750
|
+
| `runDriftRestoreDemo` | composite | seed + drift + manual restore | **yes** |
|
|
751
|
+
| `getDriftRestoreFlow` | composite | objectives + health + allocation + executions | **yes** |
|
|
752
|
+
| `runReceiptVerificationDemo` | composite | drift-restore + validate + settlement | **yes** |
|
|
753
|
+
| `getReceiptVerificationFlow` | composite | executions + validation + settlement | **yes** |
|
|
754
|
+
| `runPortfolioWatchDemo` | composite | intent + auto-restore market event + briefing | **yes** |
|
|
755
|
+
| `getPortfolioWatchFlow` | composite | Automatic objectives + health + timeline | **yes** |
|
|
756
|
+
| `runFullAureonLoopDemo` | composite | intent + plan paradox + restore + verify | **yes** |
|
|
757
|
+
| `getFullAureonLoopFlow` | composite | objectives + allocation + receipt validation | **yes** |
|
|
581
758
|
| `listMarketPresets` | GET | `/market/presets` | **yes** |
|
|
582
759
|
| `applyMarketEvent` | POST | `/market/events` | **yes** |
|
|
583
760
|
| `getRestorePlan` | GET | `/objectives/:id/restore-plan` | **yes** |
|
package/docs/data-contracts.md
CHANGED
|
@@ -402,14 +402,84 @@ export interface ExecutionReceipt {
|
|
|
402
402
|
result: string;
|
|
403
403
|
createdAt: string;
|
|
404
404
|
confirmedAt: string | null;
|
|
405
|
-
/**
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
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
|
|
|
@@ -163,7 +163,147 @@ Start with one Automatic `balanced_portfolio` objective and a funded vault befor
|
|
|
163
163
|
|
|
164
164
|
---
|
|
165
165
|
|
|
166
|
-
##
|
|
166
|
+
## 2b. Green vs plan paradox demo (Update 2)
|
|
167
|
+
|
|
168
|
+
Most dashboards celebrate green PnL. AUREON separates book performance from plan adherence:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
// Baseline
|
|
172
|
+
const before = await aureon.getAllocationVsTarget();
|
|
173
|
+
console.log(before.rows); // current vs target per objective
|
|
174
|
+
|
|
175
|
+
// Controlled shock — keep violation visible
|
|
176
|
+
await aureon.applyMarketEvent({
|
|
177
|
+
symbol: "NVDA",
|
|
178
|
+
priceChangeRatio: 0.45,
|
|
179
|
+
autoRestore: false,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const after = await aureon.getAllocationVsTarget();
|
|
183
|
+
console.log(after.paradox.message);
|
|
184
|
+
// "Book is up (5.0%), but 1 objective is off-plan."
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Run the full script: `pnpm example:green-vs-plan` (requires `AUREON_API_KEY`).
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 2c. AI → objective → portfolio (Update 3)
|
|
192
|
+
|
|
193
|
+
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:
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
const flow = await aureon.applyFinancialIntent({
|
|
197
|
+
brief: "Keep about 20% of the portfolio in stable assets",
|
|
198
|
+
kind: "stable_allocation",
|
|
199
|
+
targetWeight: 0.2,
|
|
200
|
+
tolerance: 0.02,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
console.log(flow.intent.policySummary);
|
|
204
|
+
console.log(flow.objective.id);
|
|
205
|
+
console.log(flow.health?.state);
|
|
206
|
+
console.log(flow.message);
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
For demos, `parseFinancialIntent(brief)` converts a user sentence into structured fields (rule-based, not production NLU).
|
|
210
|
+
|
|
211
|
+
Run the full script: `pnpm example:ai-to-objective-to-portfolio`.
|
|
212
|
+
|
|
213
|
+
Then use `getAllocationVsTarget()` (Update 2) to compare objective vs actual over time.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## 2d. Drift → detection → restore (Update 4)
|
|
218
|
+
|
|
219
|
+
Update 2 stops at the paradox — book up, plan off-target, no restore. Update 4 closes the loop:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
const flow = await aureon.runDriftRestoreDemo();
|
|
223
|
+
|
|
224
|
+
console.log(flow.rule.summary);
|
|
225
|
+
console.log(flow.phases.aligned.health.state);
|
|
226
|
+
console.log(flow.phases.drift.health.state);
|
|
227
|
+
console.log(flow.phases.restored?.receipt?.settlement);
|
|
228
|
+
console.log(flow.message);
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
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.
|
|
232
|
+
|
|
233
|
+
Run the full script: `pnpm example:drift-detect-restore`.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## 2e. Receipt → verification (Update 5)
|
|
238
|
+
|
|
239
|
+
Update 4 returns a receipt after restore. Update 5 teaches that **"transaction successful" is a claim**, not proof:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
const flow = await aureon.runReceiptVerificationDemo();
|
|
243
|
+
|
|
244
|
+
console.log(flow.phases.claimed.result);
|
|
245
|
+
console.log(flow.phases.validation.valid);
|
|
246
|
+
console.log(flow.proofTier);
|
|
247
|
+
console.log(flow.phases.settlement?.verifiedOnChain);
|
|
248
|
+
console.log(flow.message);
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Proof tiers: **claim_only** (validation failed) → **schema_valid** (honest receipt shape) → **chain_verified** (independent settlement record for vault).
|
|
252
|
+
|
|
253
|
+
For read-only checks on existing executions, use `getReceiptVerificationFlow(executionId?)`.
|
|
254
|
+
|
|
255
|
+
Run the full script: `pnpm example:receipt-verification`.
|
|
256
|
+
|
|
257
|
+
Forward link: Update 6 — Claude/Cursor + AUREON agent-in-host demo.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 2f. Portfolio watch while away (Update 6)
|
|
262
|
+
|
|
263
|
+
Consumer hook: *“Imagine telling your AI: watch my portfolio while I'm away.”*
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
const flow = await aureon.runPortfolioWatchDemo({ host: "cursor" });
|
|
267
|
+
|
|
268
|
+
console.log(flow.userBrief);
|
|
269
|
+
console.log(flow.phases.register.automationMode);
|
|
270
|
+
console.log(flow.phases.whileAway?.autoRestored);
|
|
271
|
+
for (const line of flow.phases.briefing.summaryLines) {
|
|
272
|
+
console.log(line);
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Update 4 uses `autoRestore: false` (manual restore demo). Update 6 uses **`autoRestore: true`** — Automatic mode acts while the operator is away.
|
|
277
|
+
|
|
278
|
+
For read-only briefing on existing Automatic objectives: `getPortfolioWatchFlow()`.
|
|
279
|
+
|
|
280
|
+
Run the full script: `pnpm example:portfolio-watch`.
|
|
281
|
+
|
|
282
|
+
Forward link: Update 7 — full AUREON loop.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## 2g. Full AUREON loop (Update 7)
|
|
287
|
+
|
|
288
|
+
Positioning hook: *"We're not building another portfolio tracker."*
|
|
289
|
+
|
|
290
|
+
```ts
|
|
291
|
+
const flow = await aureon.runFullAureonLoopDemo();
|
|
292
|
+
|
|
293
|
+
console.log(flow.phases.intent.policySummary);
|
|
294
|
+
console.log(flow.phases.planCheck.afterShock.paradox.detected);
|
|
295
|
+
console.log(flow.phases.driftRestore.settlement);
|
|
296
|
+
console.log(flow.phases.verification.proofTier);
|
|
297
|
+
console.log(flow.message);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
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.
|
|
301
|
+
|
|
302
|
+
For read-only joins on existing objectives with receipts: `getFullAureonLoopFlow()`.
|
|
303
|
+
|
|
304
|
+
Run the full script: `pnpm example:full-aureon-loop`.
|
|
305
|
+
|
|
306
|
+
---
|
|
167
307
|
|
|
168
308
|
### PM2
|
|
169
309
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Receipt validation
|
|
2
|
+
|
|
3
|
+
Phase 2 receipts must follow honest settlement rules. Use the SDK validator after every restore or when ingesting receipts from logs.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Quick example
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import {
|
|
11
|
+
createAureonClient,
|
|
12
|
+
validateExecutionReceipt,
|
|
13
|
+
assertValidExecutionReceipt,
|
|
14
|
+
} from "@buildaureon/sdk";
|
|
15
|
+
|
|
16
|
+
const client = createAureonClient({
|
|
17
|
+
baseUrl: process.env.AUREON_API_URL!,
|
|
18
|
+
apiKey: process.env.AUREON_API_KEY!,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const receipt = await client.restoreObjective("obj_abc123");
|
|
22
|
+
|
|
23
|
+
const check = validateExecutionReceipt(receipt);
|
|
24
|
+
if (!check.valid) {
|
|
25
|
+
for (const issue of check.issues) {
|
|
26
|
+
console.error(issue.code, issue.path, issue.message);
|
|
27
|
+
}
|
|
28
|
+
throw new Error("Receipt failed validation");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Or throw in one step:
|
|
32
|
+
assertValidExecutionReceipt(receipt);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
List recent receipts and validate each:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
for (const receipt of await client.listExecutions()) {
|
|
39
|
+
assertValidExecutionReceipt(receipt);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## What gets checked
|
|
46
|
+
|
|
47
|
+
| Rule | Fail code (examples) |
|
|
48
|
+
|------|----------------------|
|
|
49
|
+
| Required fields present | `MISSING_FIELD` |
|
|
50
|
+
| `settlement` is `vault` or `staged` | `INVALID_SETTLEMENT` |
|
|
51
|
+
| Staged: no explorer, not verified | `STAGED_WITH_EXPLORER`, `STAGED_VERIFIED_ON_CHAIN` |
|
|
52
|
+
| Vault with real `0x` tx: explorer required | `VAULT_MISSING_EXPLORER` |
|
|
53
|
+
| `verifiedOnChain: true` needs matching record | `VERIFIED_WITHOUT_RECORD` |
|
|
54
|
+
| Registry ref hex shape | `INVALID_REGISTRY_REF` |
|
|
55
|
+
|
|
56
|
+
The validator does **not** re-query the chain — it checks shape and honesty only.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Related
|
|
61
|
+
|
|
62
|
+
- [Data contracts](./data-contracts.md) — receipt and settlement fields
|
|
63
|
+
- [Integration guide](./integration-guide.md) — agent restore loop
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Update 3 demo — AI → objective → portfolio.
|
|
3
|
+
*
|
|
4
|
+
* Env:
|
|
5
|
+
* AUREON_API_KEY issued developer key (required)
|
|
6
|
+
* AUREON_API_URL optional (default https://api.aureonlabs.network)
|
|
7
|
+
*
|
|
8
|
+
* pnpm example:ai-to-objective-to-portfolio
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
createAureonClient,
|
|
13
|
+
DEFAULT_API_BASE_URL,
|
|
14
|
+
formatWeight,
|
|
15
|
+
isAureonError,
|
|
16
|
+
parseFinancialIntent,
|
|
17
|
+
type PortfolioPositionInput,
|
|
18
|
+
} from "../../src/index.js";
|
|
19
|
+
|
|
20
|
+
const DEMO_POSITIONS: PortfolioPositionInput[] = [
|
|
21
|
+
{
|
|
22
|
+
symbol: "USDG",
|
|
23
|
+
name: "Paxos USDG",
|
|
24
|
+
category: "stable",
|
|
25
|
+
quantity: 24_000,
|
|
26
|
+
markPriceUsd: 1,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
symbol: "NVDA",
|
|
30
|
+
name: "NVIDIA Stock Token",
|
|
31
|
+
category: "stock_token",
|
|
32
|
+
quantity: 45,
|
|
33
|
+
markPriceUsd: 920,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
symbol: "AAPL",
|
|
37
|
+
name: "Apple Stock Token",
|
|
38
|
+
category: "stock_token",
|
|
39
|
+
quantity: 80,
|
|
40
|
+
markPriceUsd: 210,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
symbol: "ETH",
|
|
44
|
+
name: "Ether",
|
|
45
|
+
category: "gas",
|
|
46
|
+
quantity: 8.5,
|
|
47
|
+
markPriceUsd: 3400,
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
async function main(): Promise<void> {
|
|
52
|
+
const apiKey = process.env.AUREON_API_KEY?.trim();
|
|
53
|
+
if (!apiKey) {
|
|
54
|
+
throw new Error("Set AUREON_API_KEY to an issued developer key.");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const aureon = createAureonClient({
|
|
58
|
+
baseUrl: process.env.AUREON_API_URL?.trim() || DEFAULT_API_BASE_URL,
|
|
59
|
+
apiKey,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const userBrief =
|
|
63
|
+
"I want to keep about 20% of my portfolio in stable assets.";
|
|
64
|
+
|
|
65
|
+
console.log("\n=== AUREON Update 3 — AI → objective → portfolio ===\n");
|
|
66
|
+
console.log("USER (simulated agent input):");
|
|
67
|
+
console.log(` "${userBrief}"\n`);
|
|
68
|
+
|
|
69
|
+
console.log("AI — structured intent:");
|
|
70
|
+
const intent = parseFinancialIntent(userBrief);
|
|
71
|
+
console.log(
|
|
72
|
+
JSON.stringify(
|
|
73
|
+
{
|
|
74
|
+
kind: intent.kind,
|
|
75
|
+
targetWeight: intent.targetWeight,
|
|
76
|
+
tolerance: intent.tolerance,
|
|
77
|
+
},
|
|
78
|
+
null,
|
|
79
|
+
2
|
|
80
|
+
)
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
console.log("\n1. Seed capital book…");
|
|
84
|
+
await aureon.setPortfolio(DEMO_POSITIONS);
|
|
85
|
+
|
|
86
|
+
console.log("2. Apply financial intent → create objective…");
|
|
87
|
+
const flow = await aureon.applyFinancialIntent(intent);
|
|
88
|
+
|
|
89
|
+
console.log("\n--- Intent ---");
|
|
90
|
+
console.log(` Brief: ${flow.intent.brief}`);
|
|
91
|
+
console.log(` Policy: ${flow.intent.policySummary}`);
|
|
92
|
+
|
|
93
|
+
console.log("\n--- Objective ---");
|
|
94
|
+
console.log(` ID: ${flow.objective.id}`);
|
|
95
|
+
console.log(` Kind: ${flow.objective.kind}`);
|
|
96
|
+
console.log(` Mode: ${flow.objective.automationMode}`);
|
|
97
|
+
console.log(
|
|
98
|
+
` Target: ${formatWeight(flow.objective.policy.targetWeight)}`
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
console.log("\n--- Portfolio ---");
|
|
102
|
+
console.log(
|
|
103
|
+
` Book: $${flow.portfolio.totalNotionalUsd.toLocaleString()}`
|
|
104
|
+
);
|
|
105
|
+
console.log(
|
|
106
|
+
` Stables: ${formatWeight(flow.portfolio.stableWeight)}`
|
|
107
|
+
);
|
|
108
|
+
if (flow.health) {
|
|
109
|
+
console.log(
|
|
110
|
+
` Health: ${flow.health.state} — current ${formatWeight(flow.health.currentMetric)} vs target ${formatWeight(flow.health.targetMetric)}`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log(`\n${flow.message}`);
|
|
115
|
+
console.log(
|
|
116
|
+
"\nThe portfolio now has a reason — not just positions.\n"
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
main().catch((error) => {
|
|
121
|
+
if (isAureonError(error)) {
|
|
122
|
+
console.error(`${error.code}: ${error.message}`);
|
|
123
|
+
} else {
|
|
124
|
+
console.error(error);
|
|
125
|
+
}
|
|
126
|
+
process.exitCode = 1;
|
|
127
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Phase 2 audit trail export — objective → proof.
|
|
3
|
+
*
|
|
4
|
+
* Env:
|
|
5
|
+
* AUREON_API_KEY issued developer key (required)
|
|
6
|
+
* AUREON_API_URL optional
|
|
7
|
+
* AUREON_OBJECTIVE_ID optional (defaults to first objective)
|
|
8
|
+
*
|
|
9
|
+
* pnpm example:audit-trail
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
createAureonClient,
|
|
14
|
+
DEFAULT_API_BASE_URL,
|
|
15
|
+
formatAuditTrailLines,
|
|
16
|
+
isAureonError,
|
|
17
|
+
} from "../../src/index.js";
|
|
18
|
+
|
|
19
|
+
async function main(): Promise<void> {
|
|
20
|
+
const apiKey = process.env.AUREON_API_KEY?.trim();
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
throw new Error("Set AUREON_API_KEY to an issued developer key.");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const aureon = createAureonClient({
|
|
26
|
+
baseUrl: process.env.AUREON_API_URL?.trim() || DEFAULT_API_BASE_URL,
|
|
27
|
+
apiKey,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const requested = process.env.AUREON_OBJECTIVE_ID?.trim();
|
|
31
|
+
const objectiveId =
|
|
32
|
+
requested || (await aureon.listObjectives())[0]?.id;
|
|
33
|
+
if (!objectiveId) {
|
|
34
|
+
throw new Error("No objectives on this wallet. Create one first.");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const trail = await aureon.getAuditTrail(objectiveId);
|
|
38
|
+
|
|
39
|
+
console.log("\n=== AUREON Phase 2 — Financial audit trail ===\n");
|
|
40
|
+
for (const line of formatAuditTrailLines(trail)) {
|
|
41
|
+
console.log(line);
|
|
42
|
+
}
|
|
43
|
+
console.log("");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
main().catch((error) => {
|
|
47
|
+
if (isAureonError(error)) {
|
|
48
|
+
console.error(`${error.code}: ${error.message}`);
|
|
49
|
+
} else {
|
|
50
|
+
console.error(error);
|
|
51
|
+
}
|
|
52
|
+
process.exitCode = 1;
|
|
53
|
+
});
|