@stelis/say-ur-intent 0.0.0
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 -0
- package/README.md +425 -0
- package/docs/AGENT_BEHAVIOR.md +462 -0
- package/docs/AGENT_DEVELOPMENT_POLICY.md +740 -0
- package/docs/FRONTEND_POLICY.md +234 -0
- package/docs/LOCAL_DB_ARCHITECTURE.md +85 -0
- package/docs/MCP_SETUP.md +496 -0
- package/docs/MCP_TOOLS.md +893 -0
- package/docs/SDK_API.md +116 -0
- package/docs/SIGNABLE_ADAPTER_CONTRACT.md +358 -0
- package/docs/TRANSACTION_ACTIVITY_LOG.md +182 -0
- package/docs/UTILITY_INDEX.md +180 -0
- package/docs/WALLET_IDENTITY.md +194 -0
- package/docs/golden-scenarios/BEHAVIOR_MATRIX.md +169 -0
- package/docs/golden-scenarios/INTENT_EVIDENCE_GOLDEN_ANSWERS.md +161 -0
- package/docs/golden-scenarios/INTENT_EVIDENCE_MATRIX.md +254 -0
- package/package.json +73 -0
- package/protocols/deepbook-margin.md +15 -0
- package/protocols/deepbook-v3.md +24 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Utility Index
|
|
2
|
+
|
|
3
|
+
Utilities are reusable state inspection or reporting surfaces for AI agents, maintainers, and local development.
|
|
4
|
+
|
|
5
|
+
This document owns manual utility and script boundaries. It distinguishes source-checkout utilities from MCP tools and packaged product commands.
|
|
6
|
+
|
|
7
|
+
Tool behavior references live in `docs/MCP_TOOLS.md`. Installation and client setup live in `docs/MCP_SETUP.md`.
|
|
8
|
+
|
|
9
|
+
Rows that name MCP tools describe existing product tools.
|
|
10
|
+
|
|
11
|
+
Rows that name `npm` commands or `scripts/` files describe manual utility surfaces only.
|
|
12
|
+
|
|
13
|
+
Source-checkout scripts are not packaged product commands, MCP tools, review-time simulation, transaction builders, signing readiness signals, or wallet authorization evidence.
|
|
14
|
+
|
|
15
|
+
## Implemented
|
|
16
|
+
|
|
17
|
+
| Utility | Command / Tool | Status | Notes |
|
|
18
|
+
| --- | --- | --- | --- |
|
|
19
|
+
| DeepBook registry generation | `npm run generate:deepbook-registry` | Implemented | Generates ignored mainnet metadata from `@mysten/deepbook-v3@1.3.6` constants. |
|
|
20
|
+
| MCP server status | `read.get_server_status` | Implemented | Reports package version, evidence policy version, runtime, `implementedToolsCount`, resources, prompts, and implementation limits. |
|
|
21
|
+
| Supported protocol list | `read.list_supported_protocols` | Implemented | Reports product support levels. |
|
|
22
|
+
| DeepBook pool list | `read.list_deepbook_pools` | Implemented | Reads pinned SDK mainnet pool metadata. |
|
|
23
|
+
| DeepBook token list | `read.list_deepbook_tokens` | Implemented | Reads pinned SDK mainnet token metadata, registry pool references, and decimals derived from pinned scalar values. |
|
|
24
|
+
| Orderbook inspection | `read.inspect_deepbook_orderbook` | Implemented | Uses pinned DeepBook SDK simulation read methods over Sui gRPC with an internal sender placeholder; `ticks` is capped at 50. |
|
|
25
|
+
| DeepBook mid price | `read.get_deepbook_mid_price` | Implemented | Returns pinned SDK pool mid price snapshots. Not a global market price. |
|
|
26
|
+
| Quote calculation | `read.quote_deepbook_action` | Implemented | Quotes raw integer DeepBook quantities with pinned SDK transaction builders and raw `u64` simulation return values. |
|
|
27
|
+
| Display amount quote | `read.quote_deepbook_display_amount` | Implemented | Converts explicit source display amounts through pinned DeepBook token units before quoting; returns exact decimal display quote strings plus raw quote evidence. Quote semantics mark payment coverage and shortfall contribution unavailable. |
|
|
28
|
+
| DeepBook account inventory | `read.summarize_deepbook_account_inventory` | Implemented | Reports display-like BalanceManager inventory. Not raw balance or signing readiness. |
|
|
29
|
+
| Wallet asset summary | `read.summarize_wallet_assets` | Implemented | Reads Sui coin balances for an explicit address or the active account with Sui gRPC `client.core.listBalances`; adds verified unit/display data when available; use `cursor` when `hasNextPage` is true. |
|
|
30
|
+
| Wallet asset classification | `read.classify_wallet_assets` | Implemented | Classifies returned coin balances by spendability and roles. Other asset classes are explicit non-inspected boundaries. |
|
|
31
|
+
| Settlement asset group list | `read.list_settlement_asset_groups` | Implemented | Lists supported natural-language settlement asset groups derived from pinned DeepBook mainnet SDK registries. Not live liquidity, route recommendation, fiat cash-out, payment execution, or signing readiness. |
|
|
32
|
+
| Intent evidence preview | `read.preview_intent_evidence` | Implemented | Builds `responseSummary` for USD-denominated coverage, shortfall, or settlement-asset balance total. |
|
|
33
|
+
| Review activity list | `read.list_review_activity` | Implemented | Lists local Say Ur Intent review evidence for one account; not complete wallet transaction history. |
|
|
34
|
+
| Review funnel summary | `read.summarize_review_funnel` | Implemented | Summarizes local review lifecycle counts, current statuses, sparse-sample warnings, and review timing. |
|
|
35
|
+
| Review session detail | `read.get_review_session_detail` | Implemented | Returns a capped detail view of one stored review session with plan, state snapshots, transitions, and execution evidence. |
|
|
36
|
+
| Sui transaction digest lookup | `read.inspect_sui_transaction` | Implemented | Looks up one Sui transaction digest and stores normalized facts only when the transaction sender or a returned balance-change owner matches a known local wallet. |
|
|
37
|
+
| Sui account activity scan | `read.scan_sui_account_activity` | Implemented | Runs a bounded recent-to-older GraphQL scan with requested-account facts. Not complete history. |
|
|
38
|
+
| Live Sui activity scan summary | `read.summarize_sui_activity_scan` | Implemented | Summarizes a live bounded scan without full details. Not P&L, position inventory, or complete history. |
|
|
39
|
+
| Sui sent-function activity scan | `read.scan_sui_function_activity` | Implemented | Scans bounded sent transactions for one full `package::module::function`. Not global function history. |
|
|
40
|
+
| Live Sui sent-function activity summary | `read.summarize_sui_function_activity_scan` | Implemented | Summarizes bounded sent-function rows. Not P&L, route recommendation, or signing readiness. |
|
|
41
|
+
| Stored Sui activity summary | `read.summarize_sui_account_activity` | Implemented | Summarizes stored normalized Sui activity facts, including stored Move call, balance change, object/event, gas, execution error details, and optional protocol activity labels when evidence is available. |
|
|
42
|
+
| Local settings | `settings.create_local_settings_session`, `settings.get_local_settings` | Implemented | MCP creates or reads local settings sessions. Settings mutations happen in the local settings page after token validation and apply after MCP server restart when they affect the endpoint. |
|
|
43
|
+
| Mainnet read smoke | `npm run smoke:mainnet` | Manual | Runs selected mainnet read paths from built `dist/`. Build first. Not part of CI or `release:check`; see notes below. |
|
|
44
|
+
| Sui GraphQL function filter probe | `npm exec -- tsx scripts/sui-graphql-function-filter-probe.ts [--endpoint <mainnet-graphql-url>] [--sample-size <1-50>] [--timeout-ms <ms>]` | Manual, source evidence only | Runs a read-only Sui mainnet GraphQL source-shape probe for function-filter diagnostics; see notes below. |
|
|
45
|
+
| Sui CLI transaction diagnostics | `npm exec -- tsx scripts/sui-cli-transaction-diagnostics.ts -- --help` | Manual, source checkout only | Allowlisted local `sui` CLI debug evidence. See notes below. |
|
|
46
|
+
|
|
47
|
+
## Mainnet Read Smoke Notes
|
|
48
|
+
|
|
49
|
+
Run `npm run build` first because `npm run smoke:mainnet` executes `dist/runtime/smokeMainnetRead.js`.
|
|
50
|
+
|
|
51
|
+
The smoke command calls:
|
|
52
|
+
|
|
53
|
+
- wallet assets;
|
|
54
|
+
- DeepBook orderbook;
|
|
55
|
+
- raw-quantity DeepBook quote;
|
|
56
|
+
- `read.scan_sui_account_activity` for `SMOKE_SUI_ADDRESS` with limit 5;
|
|
57
|
+
- `read.summarize_sui_activity_scan` through active account context with limit 5;
|
|
58
|
+
- `read.inspect_sui_transaction` when `SMOKE_INSPECT_DIGEST` is set;
|
|
59
|
+
- sent-function activity tools when `SMOKE_FUNCTION_TARGET` is set to a full `package::module::function`.
|
|
60
|
+
|
|
61
|
+
Empty activity pages are valid smoke outcomes. They are recorded with `rowCount: 0` and `emptyAccepted: true`.
|
|
62
|
+
|
|
63
|
+
The result file records tool names, environment-variable presence, activity status, row counts, source method, window/order flags, persistence status, function-target presence, and evidence-boundary metrics.
|
|
64
|
+
|
|
65
|
+
It does not store raw GraphQL payloads, transaction bytes, signatures, raw transaction details, or compact transaction aggregates.
|
|
66
|
+
|
|
67
|
+
Activity scan and summary smoke paths fail if full transaction details or compact transaction aggregates are returned. The optional digest verifies storage only when its sender or returned balance-change owner is `SMOKE_SUI_ADDRESS`.
|
|
68
|
+
|
|
69
|
+
If `SMOKE_INSPECT_RANDOM_LATEST=true` is set and no digest is provided, the script samples one latest GraphQL transaction digest and inspects it without an account argument.
|
|
70
|
+
|
|
71
|
+
This smoke path does not call display-amount quote, DeepBook account inventory,
|
|
72
|
+
account-bound DeepBook transaction-material build, or internal digest binding. A
|
|
73
|
+
funded-account material-build smoke is a separate operator check before this
|
|
74
|
+
read smoke can be used as product-grade proof for the DeepBook review material
|
|
75
|
+
stage.
|
|
76
|
+
|
|
77
|
+
## Sui GraphQL Function Filter Probe Notes
|
|
78
|
+
|
|
79
|
+
The GraphQL function filter probe is read-only source-shape evidence for function-filter diagnostics.
|
|
80
|
+
|
|
81
|
+
It verifies the endpoint chain identifier, samples recent public mainnet transaction details to obtain redacted filter values, and probes `TransactionFilter.function` combinations with account, object, kind, and checkpoint axes using `last: 1`.
|
|
82
|
+
|
|
83
|
+
It writes an ignored local source-probe note with:
|
|
84
|
+
|
|
85
|
+
- endpoint host;
|
|
86
|
+
- chain identifier;
|
|
87
|
+
- repository revision;
|
|
88
|
+
- git worktree state;
|
|
89
|
+
- Node version;
|
|
90
|
+
- pinned `@mysten/sui` version;
|
|
91
|
+
- schema hash;
|
|
92
|
+
- probe script hash;
|
|
93
|
+
- filter-key matrix;
|
|
94
|
+
- result classifications;
|
|
95
|
+
- capped row counts.
|
|
96
|
+
|
|
97
|
+
The output redacts sampled digests, addresses, objects, and functions.
|
|
98
|
+
|
|
99
|
+
It does not store raw GraphQL payloads, transaction bytes, signatures, raw transaction details, wallet position inventory, route quality, P&L, transaction-building inputs, signing data, or signing readiness.
|
|
100
|
+
|
|
101
|
+
Network failures and mainnet guard failures are inconclusive evidence, not unsupported filter-combination findings.
|
|
102
|
+
|
|
103
|
+
It is not an MCP tool, not packaged product functionality, not CI, and not a function diagnostics implementation.
|
|
104
|
+
|
|
105
|
+
## Sui CLI Transaction Diagnostics Notes
|
|
106
|
+
|
|
107
|
+
The Sui CLI diagnostics utility can inspect a digest with allowlisted read/debug commands:
|
|
108
|
+
|
|
109
|
+
- `tx-block`;
|
|
110
|
+
- optional object inspection;
|
|
111
|
+
- optional local replay traces;
|
|
112
|
+
- optional gas profiles.
|
|
113
|
+
|
|
114
|
+
Run `npm exec -- tsx scripts/sui-cli-transaction-diagnostics.ts -- --help` for the full flag list.
|
|
115
|
+
|
|
116
|
+
Common flags include:
|
|
117
|
+
|
|
118
|
+
- `--object <objectId>`;
|
|
119
|
+
- `--gas-profile`;
|
|
120
|
+
- `--read-timeout-ms <ms>`;
|
|
121
|
+
- `--replay-timeout-ms <ms>`;
|
|
122
|
+
- `--analyze-timeout-ms <ms>`.
|
|
123
|
+
|
|
124
|
+
`--mainnet` selects exactly one existing Sui CLI env alias whose recorded chain id matches mainnet.
|
|
125
|
+
|
|
126
|
+
`--client-env` can select an explicit existing alias.
|
|
127
|
+
|
|
128
|
+
Both modes are read-only and do not switch or mutate CLI config.
|
|
129
|
+
|
|
130
|
+
CLI env aliases must not contain redaction marker word forms for private key, mnemonic, signature, signed transaction, transaction bytes, or `suiprivkey`-style markers using `-`, `_`, a space, or no separator.
|
|
131
|
+
|
|
132
|
+
Artifact paths must not contain `suiprivkey`-style markers; other redaction markers in paths are accepted and redacted in output.
|
|
133
|
+
|
|
134
|
+
The utility records source-versioned summaries, bounded redacted CLI-derived strings, artifact paths, and limitation provenance. It does not record raw CLI payloads.
|
|
135
|
+
|
|
136
|
+
It reports a limitation when the installed CLI version differs from the source-checked parser baseline.
|
|
137
|
+
|
|
138
|
+
It is not an MCP tool, not a CI check, not packaged product functionality, not review-time simulation, not wallet authorization, not signing readiness, not onchain transaction submission/execution, not route analysis, not P&L, and not complete-history evidence.
|
|
139
|
+
|
|
140
|
+
## Rules
|
|
141
|
+
|
|
142
|
+
- Utility output should be JSON-first.
|
|
143
|
+
- Read-only utilities come before write/signable actions.
|
|
144
|
+
- Generated registry files are local policy/metadata, not live liquidity or execution truth.
|
|
145
|
+
- DeepBook token lists are pinned SDK registry metadata, not live token discovery or a complete Sui token list.
|
|
146
|
+
- Live read outputs include `fetchedAt` as ISO 8601 UTC.
|
|
147
|
+
- DeepBook mid-price outputs are pool snapshots. For `SUI_USDC`, the price is USDC per SUI.
|
|
148
|
+
- DeepBook mid prices are not fiat USD cash-out estimates, external market lookups, USDC/USD peg assumptions, effective quote prices, quote-vs-mid slippage, price-impact calculations, venue comparisons, best-route claims, P&L, cost basis, or route recommendations.
|
|
149
|
+
- `read.quote_deepbook_action` amounts are raw integer quantities that fit the SDK `u64` quote input, not decimal display amounts. Quote responses include `rawQuote.kind: "deepbook_quote_raw_u64"` from simulated raw `u64` return values.
|
|
150
|
+
- `rawQuote.sourceMoveFunction` names the simulated public entrypoint. `rawQuote.returnValueSourceMoveFunction: "pool::get_quantity_out"` names the official Move function that defines the return-value order.
|
|
151
|
+
- `read.quote_deepbook_display_amount` accepts only source-side display input amounts that convert to SDK `u64` quote inputs.
|
|
152
|
+
- Display quote public `quote` fields are exact decimal display strings derived from raw evidence. `rawQuote.directionalOutput.raw` is the direction-specific quote output before slippage policy.
|
|
153
|
+
- Quote `quantitySemantics` marks payment coverage, shortfall contribution, and route-dependent payment support unavailable and points coverage questions back to intent evidence.
|
|
154
|
+
- DeepBook account inventory quantities are display-like SDK `number` values and must not be used as raw amounts, funding sources, route liquidity, withdrawal readiness, transaction-building inputs, signing data, or signing readiness.
|
|
155
|
+
- Wallet balance display amounts are presentation-only and must come from returned `display` fields. Do not infer token decimals from symbols.
|
|
156
|
+
- Wallet balance reads are current coin-balance snapshots only. They are not transaction history, receipt proof for a specific digest, acquisition source, object provenance, P&L, cost basis, or signing data.
|
|
157
|
+
- `uninspectedAssetClasses` entries are explicit classifier-uninspected boundaries.
|
|
158
|
+
- They are not zero-balance claims, spendable asset facts, funding sources, route liquidity, payment readiness, portfolio completeness, transaction-building inputs, signing data, or signing readiness.
|
|
159
|
+
- Intent evidence previews map natural-language USD-denominated targets to pinned SDK settlement asset groups and current wallet balance snapshots.
|
|
160
|
+
- Use `userAnswerUse.answerFields` for intent evidence answers. Settlement-asset-only coverage, shortfall, or current-total answers use `responseSummary`; selected-target answers also use the selected-target fields listed in the response. Direct pool quote evidence is supported only when the same intent-evidence response lists `direct_pool_quote_evidence` in `responseEvidence.supportedResponseClaims` and `direct_pool_quote_evidence_for_user_selected_target` in `userAnswerUse.canAnswer`. Intent evidence previews do not choose settlement assets, quote best routes, evaluate gas reserve, execute payments, or create signing material.
|
|
161
|
+
- DeepBook read outputs identify SDK simulation reads through `source.simulation`.
|
|
162
|
+
- Review activity tools analyze local Say Ur Intent review evidence only. The optional `account` input is a read filter and does not change active account context.
|
|
163
|
+
- Sui activity scan tools are user-requested bounded reads. They store only normalized facts tied to known local wallets.
|
|
164
|
+
- Sui activity scans do not store raw provider payloads or non-known party account addresses. They do not claim complete wallet history, complete dApp history, P&L, signing readiness, transaction building, or route recommendations.
|
|
165
|
+
- Activity `quantitySemantics` marks balance `amountRaw` and `*Raw` fields as raw integer facts requiring verified decimals or returned display amounts before display conversion.
|
|
166
|
+
- Account effect rows include `accountBalanceChangeInferencePolicy` so truncated or unavailable requested-account evidence cannot be filled from transaction-level context, visible recipient patterns, or current wallet balances.
|
|
167
|
+
- Gas display facts, when returned, use `@mysten/sui MIST_PER_SUI`.
|
|
168
|
+
- Optional protocol activity labels are derived from normalized detail facts and are not a supported-protocol list or wallet position inventory.
|
|
169
|
+
- Sent-function activity tools are sender-scoped only: they report transactions the selected account sent that called one full `package::module::function`, not recipient-only activity, affected-object history, or global function history.
|
|
170
|
+
- `read.summarize_sui_activity_scan` and `read.summarize_sui_function_activity_scan` summarize live bounded scan results. `read.summarize_sui_account_activity` summarizes stored local SQLite facts only.
|
|
171
|
+
- Sui GraphQL function filter probe output is source-shape evidence for function-filter diagnostics only.
|
|
172
|
+
- Do not treat the probe as a supported function diagnostics surface, complete dApp history, route quality evidence, wallet position inventory, transaction-building input, signing data, or signing readiness.
|
|
173
|
+
- Sui CLI transaction diagnostics can be compared with `read.inspect_sui_transaction` only at the fact category level.
|
|
174
|
+
- Comparable categories include digest/status/checkpoint/timestamp, Move call targets, object ids/types, event type strings, raw gas summary, and optional replay/trace-derived debug artifacts.
|
|
175
|
+
- Sui CLI transaction diagnostics are debug cross-check sources, not replacements for MCP normalized transaction facts and not review-time simulation.
|
|
176
|
+
- Sui CLI transaction diagnostics are source-checkout debug utilities only. They must stay allowlisted and read/debug-only.
|
|
177
|
+
- Local replay output is debug evidence only. The utility is not an MCP tool, review-time simulation, wallet authorization, signing readiness, or onchain transaction submission/execution.
|
|
178
|
+
- When a review activity output has `lowSampleWarning: true`, report raw counts and avoid inferring behavior patterns.
|
|
179
|
+
- For review activity list output, `dataScope.recordCount` is the full matching local review count. The returned `activities` array can be shorter when `truncated.activities: true`.
|
|
180
|
+
- Local settings page actions mutate local settings or logical local data only. They do not execute transactions, sign, or create custody. MCP settings tools create a settings page session or read current settings.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Wallet Identity
|
|
2
|
+
|
|
3
|
+
This document is the wallet identity capture specification for Say Ur Intent. It is product-facing design guidance and must not be treated as transaction authorization.
|
|
4
|
+
|
|
5
|
+
This document owns the wallet identity boundary: what active-account read context is, how same-machine capture works, which state transitions exist, and what wallet identity is not.
|
|
6
|
+
|
|
7
|
+
It does not own general setup steps, MCP tool contracts, or user-question playbooks. Product users should follow the README and `docs/MCP_SETUP.md`. MCP response fields are documented in `docs/MCP_TOOLS.md`.
|
|
8
|
+
|
|
9
|
+
This document is for agents, frontend contributors, backend contributors, and reviewers who implement or verify wallet identity capture.
|
|
10
|
+
|
|
11
|
+
Frontend display and action policy is defined in `docs/FRONTEND_POLICY.md`.
|
|
12
|
+
|
|
13
|
+
## Purpose
|
|
14
|
+
|
|
15
|
+
Wallet identity capture provides one account source for wallet-account reads and account-bound review.
|
|
16
|
+
|
|
17
|
+
MCP clients create and poll a local capture session.
|
|
18
|
+
|
|
19
|
+
The local review server serves the wallet page and validates Host, Origin, and the fragment token.
|
|
20
|
+
|
|
21
|
+
The browser frontend connects a Sui wallet and sends only the selected account address and mainnet chain identifier back to the local server.
|
|
22
|
+
|
|
23
|
+
The session store owns all state transitions.
|
|
24
|
+
|
|
25
|
+
Wallet identity capture is not transaction review, wallet creation, login, signing authorization, custody, or persistent permission.
|
|
26
|
+
|
|
27
|
+
It does not request authorization, does not construct executable transaction material, and does not imply that an action is safe.
|
|
28
|
+
|
|
29
|
+
A capture session ends when the user closes the wallet page or it expires.
|
|
30
|
+
|
|
31
|
+
The captured address remains as a read context until the user clears it.
|
|
32
|
+
|
|
33
|
+
The `walletUrl` field is the wallet URL returned by the MCP tool.
|
|
34
|
+
|
|
35
|
+
It must be opened in the same machine's system browser because the review server is bound to loopback.
|
|
36
|
+
|
|
37
|
+
MCP client sidebars and embedded webviews are not supported wallet identity surfaces.
|
|
38
|
+
|
|
39
|
+
The URL includes a short-lived fragment token; do not copy, sync, share, or move it to another device.
|
|
40
|
+
|
|
41
|
+
## Active Account Persistence
|
|
42
|
+
|
|
43
|
+
The active account is persisted in the local SQLite store and survives server
|
|
44
|
+
restarts. It remains the read-context account until the user clears it through
|
|
45
|
+
`account.clear_active_account` or the settings page. A connected identity
|
|
46
|
+
result also records which wallet held the account (wallet name and wallet
|
|
47
|
+
standard id). Wallet connection happens only on the connection page; the
|
|
48
|
+
review page reads the recorded account from the server as its single source of
|
|
49
|
+
truth, shows it in the header, and never connects a wallet itself. For the
|
|
50
|
+
signing step it relies on dapp-kit autoconnect restoring the signer on the
|
|
51
|
+
same fixed-port origin where the wallet was connected. That review origin is a
|
|
52
|
+
single per-machine port (default 8765, overridable per registration with
|
|
53
|
+
SAY_UR_INTENT_REVIEW_PORT): when a newer server instance finds the port already
|
|
54
|
+
held by a previous Say Ur Intent review server, it stops that previous instance
|
|
55
|
+
and takes the port over so the most recently started client owns the one
|
|
56
|
+
origin, and a port held by any other process is never taken over. The record is
|
|
57
|
+
read context and wallet preference only; it is not signing authorization.
|
|
58
|
+
|
|
59
|
+
## Status Model
|
|
60
|
+
|
|
61
|
+
Product statuses are:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
pending | opened | connecting | connected | rejected | failed | expired
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`pending`, `opened`, and `connecting` are non-terminal.
|
|
68
|
+
|
|
69
|
+
`connected`, `rejected`, `failed`, and `expired` are terminal.
|
|
70
|
+
|
|
71
|
+
Terminal sessions are immutable. Replacing or clearing the active account context does not rewrite earlier wallet identity sessions.
|
|
72
|
+
|
|
73
|
+
The pinned `@mysten/dapp-kit-core` frontend connection store has `disconnected`, `connecting`, `reconnecting`, and `connected`.
|
|
74
|
+
|
|
75
|
+
Those raw statuses are frontend internals and must be mapped into the product status model.
|
|
76
|
+
|
|
77
|
+
`reconnecting` occurs when dapp-kit autoconnect restores a previously selected wallet on the same fixed-port origin; the frontend maps it to the `connecting` product status while the signer settles. dapp-kit storage holds the wallet autoconnect preference only, never keys.
|
|
78
|
+
|
|
79
|
+
## Failure Reasons
|
|
80
|
+
|
|
81
|
+
Wallet identity failure reasons are:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
user_rejected
|
|
85
|
+
no_compatible_wallet
|
|
86
|
+
no_accounts_authorized
|
|
87
|
+
unsupported_chain
|
|
88
|
+
wallet_provider_error
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`user_rejected` is used only when the wallet error is positively identified as a Wallet Standard user rejection.
|
|
92
|
+
|
|
93
|
+
`no_compatible_wallet`, `no_accounts_authorized`, and `unsupported_chain` are used only when deterministically observed.
|
|
94
|
+
|
|
95
|
+
All other wallet provider failures use `wallet_provider_error` with an optional sanitized `failureDetail`.
|
|
96
|
+
|
|
97
|
+
## State Contracts
|
|
98
|
+
|
|
99
|
+
`connected` requires `account` and `chain: "sui:mainnet"`. `rejected` requires `failureReason: "user_rejected"`. `failed` requires a non-user failure reason. `pending`, `opened`, and `connecting` must not include an account. `expired` is terminal and does not contain an account.
|
|
100
|
+
|
|
101
|
+
Active-account reads require active account context when no explicit public account is supplied.
|
|
102
|
+
|
|
103
|
+
`read.preview_intent_evidence` can use either an explicit public Sui address supplied as `account` or the active account when `account` is omitted.
|
|
104
|
+
|
|
105
|
+
`read.summarize_deepbook_account_inventory` uses active account context.
|
|
106
|
+
|
|
107
|
+
`read.summarize_wallet_assets` and `read.classify_wallet_assets` can read either an explicit public Sui address supplied as `account` or the active account when `account` is omitted.
|
|
108
|
+
|
|
109
|
+
Explicit-address coin balance and intent-evidence reads do not prove ownership, store the address as a known wallet, or create active account context.
|
|
110
|
+
|
|
111
|
+
Sender-independent DeepBook orderbook, raw-quantity quote, display-amount quote, and settlement-asset-group reads stay wallet-free.
|
|
112
|
+
|
|
113
|
+
The pinned SDK requires a transaction simulation sender for some market reads, but Say Ur Intent supplies an internal mainnet placeholder when the result does not depend on a user's wallet.
|
|
114
|
+
|
|
115
|
+
After a wallet identity connection succeeds, Say Ur Intent stores that normalized account as the active read context in the local SQLite database.
|
|
116
|
+
|
|
117
|
+
This is unconditional. There is no opt-out short of clearing it through `account.clear_active_account`.
|
|
118
|
+
|
|
119
|
+
The active account can be reused for wallet-account reads until the user clears or replaces it.
|
|
120
|
+
|
|
121
|
+
This is not login, signing authorization, custody, or permission for transactions.
|
|
122
|
+
|
|
123
|
+
Use `account.get_active_account` when the current active account context matters. A historical wallet identity session can remain `connected` even after the active account is cleared or replaced by another session.
|
|
124
|
+
|
|
125
|
+
Account-bound review sessions must bind to the active wallet identity account before review state is accepted.
|
|
126
|
+
|
|
127
|
+
A review account that does not match the active account context is rejected.
|
|
128
|
+
|
|
129
|
+
Once the signable adapter's review evidence completes, the account-bound review reaches `ready_for_wallet_review` and the local review page offers a digest-gated handoff and user-controlled wallet signing.
|
|
130
|
+
|
|
131
|
+
The active account context stays read context and wallet preference only; it is not signing authorization, and the MCP layer does not sign, execute, or return transaction bytes on its own.
|
|
132
|
+
|
|
133
|
+
## Frontend Boundary
|
|
134
|
+
|
|
135
|
+
The wallet frontend uses pinned dapp-kit core APIs and renders a minimal wallet list in the local review app.
|
|
136
|
+
|
|
137
|
+
The pinned `@mysten/dapp-kit-core/web` package version is recorded in `docs/SDK_API.md` and pinned in `package.json`.
|
|
138
|
+
|
|
139
|
+
Its button and modal do not expose wallet provider errors as public events. The frontend calls `connectWallet()` directly to classify deterministic wallet outcomes without inspecting private DOM state or overfitting error strings.
|
|
140
|
+
|
|
141
|
+
The wallet page must say address capture only. It must not show transaction review language, authorization buttons, private-key handling, executable transaction material, or safety guarantees.
|
|
142
|
+
|
|
143
|
+
## HTTP Boundary
|
|
144
|
+
|
|
145
|
+
The wallet identity capture UI is hosted on the analysis page served at
|
|
146
|
+
`/analysis/:id`. After a wallet connects, the same page can show a wallet asset
|
|
147
|
+
snapshot and stored local review records through token-gated read endpoints
|
|
148
|
+
(`GET /api/analysis/:id/assets`, `GET /api/analysis/:id/review-activity`).
|
|
149
|
+
State-changing wallet APIs are unchanged:
|
|
150
|
+
|
|
151
|
+
- `POST /api/wallet/:id/opened`
|
|
152
|
+
- `POST /api/wallet/:id/connecting`
|
|
153
|
+
- `POST /api/wallet/:id/result`
|
|
154
|
+
|
|
155
|
+
All state-changing endpoints require Host and Origin validation plus the wallet session token. The token is supplied with `x-say-ur-intent-token`; query-string tokens are not accepted.
|
|
156
|
+
|
|
157
|
+
## MCP Boundary
|
|
158
|
+
|
|
159
|
+
MCP exposes:
|
|
160
|
+
|
|
161
|
+
- `session.create_wallet_identity`
|
|
162
|
+
- `session.get_wallet_identity`
|
|
163
|
+
- `session.wait_wallet_identity`
|
|
164
|
+
- `session.get_interaction_status`
|
|
165
|
+
|
|
166
|
+
These tools create, poll, wait on, and summarize local wallet identity interactions. They do not expose private keys, executable transaction material, or arbitrary wallet operations.
|
|
167
|
+
|
|
168
|
+
`session.create_wallet_identity` returns `openTarget: "system_browser"` and `accessScope: "same_machine_loopback"`.
|
|
169
|
+
|
|
170
|
+
These fields let clients distinguish the wallet URL opening target from the session status.
|
|
171
|
+
|
|
172
|
+
`accessScope` combines the same-machine requirement with the loopback-bound review server.
|
|
173
|
+
|
|
174
|
+
`session.get_wallet_identity` returns the wallet identity session status only.
|
|
175
|
+
|
|
176
|
+
`session.wait_wallet_identity` is a bounded wait over the same in-memory session state. `timed_out` means the user has not finished yet.
|
|
177
|
+
|
|
178
|
+
After an AI client gives the wallet URL to the user, it should immediately call `session.wait_wallet_identity` in the same turn or poll `session.get_wallet_identity`.
|
|
179
|
+
|
|
180
|
+
It should not wait for the user to return and say they connected before checking the session.
|
|
181
|
+
|
|
182
|
+
AI clients should then call `account.get_active_account` before telling the user which address is currently active.
|
|
183
|
+
|
|
184
|
+
Pending wallet identity sessions are process-local. If the local MCP server restarts, pending wallet identity sessions are not recovered. The durable state is the active account context stored after a successful connection.
|
|
185
|
+
|
|
186
|
+
## Testing Boundary
|
|
187
|
+
|
|
188
|
+
Server-path smoke tests may create a wallet identity session, post a public smoke address to the result endpoint, and then call wallet-account read tools.
|
|
189
|
+
|
|
190
|
+
That verifies server routing and read-tool integration only.
|
|
191
|
+
|
|
192
|
+
Browser wallet verification is a separate manual release checklist and is the only check that verifies a real wallet popup.
|
|
193
|
+
|
|
194
|
+
Local event logs must not write captured wallet addresses in plaintext. NDJSON event logs hash wallet addresses before writing them.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Behavior Golden Scenarios
|
|
2
|
+
|
|
3
|
+
These scenarios document expected response classes for manual release review. They are not Claude, Codex, or Cursor execution results.
|
|
4
|
+
|
|
5
|
+
For current-release intent evidence checks that compare user prompts, preferred tool paths, standard answer clauses, and manual client observations, see `docs/golden-scenarios/INTENT_EVIDENCE_MATRIX.md`.
|
|
6
|
+
|
|
7
|
+
For the deterministic MCP replay contract behind Korean USD-denominated coverage, total, and shortfall questions, see `docs/golden-scenarios/INTENT_EVIDENCE_GOLDEN_ANSWERS.md`.
|
|
8
|
+
|
|
9
|
+
Manual client runs should call `read.get_server_status` first and record the package version, `evidencePolicy.version`, and `implementedToolsCount` before running the question rows.
|
|
10
|
+
|
|
11
|
+
## Current Release Intent Evidence Corpus
|
|
12
|
+
|
|
13
|
+
These scenarios translate the internal intent corpus into English release-review prompts.
|
|
14
|
+
|
|
15
|
+
Current-release intent evidence answers can answer evidence questions without creating route recommendations, payment support, portfolio plans, P&L, transaction material, or signing readiness. Account-bound DeepBook review has a separate local transaction-material build path that is not part of these intent evidence answer rows.
|
|
16
|
+
|
|
17
|
+
Partial wallet context is allowed only when an active account is already set or the user provides an explicit Sui address.
|
|
18
|
+
|
|
19
|
+
`What is 10 SUI worth?`
|
|
20
|
+
Class: `answer_only`.
|
|
21
|
+
Use `read.get_deepbook_mid_price` with a disclosed DeepBook SUI quote pool such as `SUI_USDC`.
|
|
22
|
+
Use `read.list_deepbook_pools` only when the pool is ambiguous.
|
|
23
|
+
Expose DeepBook pool, mid price, quote asset, and `fetchedAt`.
|
|
24
|
+
Do not present this as a global market price, route recommendation, settlement choice, or signing readiness.
|
|
25
|
+
|
|
26
|
+
`If I sell 10 SUI, how many dollars do I get?`
|
|
27
|
+
Class: `clarify_or_intent_evidence`.
|
|
28
|
+
Do not quote until the user selects a registered DeepBook quote asset or pool, or asks for wallet-scoped USD-denominated intent evidence.
|
|
29
|
+
If the user chooses a pool such as SUI/USDC, call `read.quote_deepbook_display_amount`.
|
|
30
|
+
Expose source input, missing quote-token or pool choice, fiat cash-out boundary, and available intent-evidence path when account context exists.
|
|
31
|
+
Do not silently choose USDC or USDT, infer inverse output-target quotes, use web/finance lookup for USDC/USD, assume the USDC/USD peg, or present fiat cash-out, final min-out, route quality, funding readiness, or signing readiness.
|
|
32
|
+
|
|
33
|
+
`What can I sell?`
|
|
34
|
+
Class: `wallet_asset_read`.
|
|
35
|
+
Use active account context or explicit address, then call `read.classify_wallet_assets`.
|
|
36
|
+
Expose returned spendable coin-balance classes, gas asset context, DeepBook token registry matches, and `uninspectedAssetClasses`.
|
|
37
|
+
Do not treat staked, locked, DeepBook manager, LP, vault, NFT, object, unsupported, or unknown classes as zero balances or sellable candidates.
|
|
38
|
+
|
|
39
|
+
`Sell DEEP for USDC.`
|
|
40
|
+
Class: `clarify_or_quote_context`.
|
|
41
|
+
Ask for a source amount before quoting.
|
|
42
|
+
After source amount and pool are explicit, call `read.quote_deepbook_display_amount`.
|
|
43
|
+
Use `read.classify_wallet_assets` only for scoped wallet context.
|
|
44
|
+
Do not assume amount, choose a route, run inverse quotes, create a review session, or treat DeepBook manager inventory as spendable.
|
|
45
|
+
|
|
46
|
+
`Make $1000.`
|
|
47
|
+
Class: `intent_evidence_with_choices`.
|
|
48
|
+
Use `read.list_settlement_asset_groups`, then `read.preview_intent_evidence` when active account or explicit address context is available.
|
|
49
|
+
Ask only for choices returned by `responseSummary`.
|
|
50
|
+
Do not silently choose USDC or USDT, treat USDC as fiat USD, choose source assets, rank routes, or prepare signing.
|
|
51
|
+
|
|
52
|
+
`Can I cover a 1000 dollar payment?`
|
|
53
|
+
Class: `intent_evidence_with_choices`.
|
|
54
|
+
Use `read.list_settlement_asset_groups`, then `read.preview_intent_evidence` with `intentKind: "cover_payment_like_amount"`, `denomination: "dollar"`, and `requiredDisplayAmount: "1000"`.
|
|
55
|
+
Expose `responseSummary`, settlement-asset coverage basis, settlement-asset shortfall when available, required user choices, and unsupported payment/signing boundaries.
|
|
56
|
+
Do not silently choose USDC or USDT, claim fiat USD cash-out, route-dependent payment support, gas readiness, transaction building, or signing readiness.
|
|
57
|
+
|
|
58
|
+
`Can I pay for this $1000 item?`
|
|
59
|
+
Use the same `intent_evidence_with_choices` path as `Can I cover a 1000 dollar payment?`.
|
|
60
|
+
Do not claim fiat USD cash-out, route-dependent payment support, gas completeness, transaction building, or signing readiness.
|
|
61
|
+
|
|
62
|
+
`How much are my USD-denominated assets together?`
|
|
63
|
+
Class: `intent_evidence_total_only`.
|
|
64
|
+
Use `read.list_settlement_asset_groups`, then `read.preview_intent_evidence` with `intentKind: "summarize_settlement_asset_group_balance"` and `denomination: "dollar"`.
|
|
65
|
+
Expose `responseSummary.conclusionKind: "current_settlement_asset_total"` and current display total when available.
|
|
66
|
+
Do not invent a target amount, silently choose USDC or USDT, treat the total as fiat USD cash-out, recommend a route, claim payment readiness, produce transaction material, or imply signing readiness.
|
|
67
|
+
|
|
68
|
+
`Which stablecoin-like asset is highest or lowest?`
|
|
69
|
+
Class: `settlement_asset_group_parity`.
|
|
70
|
+
Use `read.list_settlement_asset_groups`, then `read.summarize_settlement_asset_group_parity` with `denomination: "dollar"`.
|
|
71
|
+
Expose `responseSummary.referenceAssetRole`, min/max/mean/median statistics, and unsupported boundaries.
|
|
72
|
+
Do not treat the reference asset as settlement selection, fiat USD value, peg assumption, payment readiness, route recommendation, transaction material, or signing readiness.
|
|
73
|
+
|
|
74
|
+
`What is the shortfall?`
|
|
75
|
+
Class: `intent_evidence_with_context_or_clarify`.
|
|
76
|
+
If a target amount was already established, use `read.preview_intent_evidence` with that amount and answer from `responseSummary`.
|
|
77
|
+
If not, ask for the missing target amount.
|
|
78
|
+
Do not guess the missing amount, silently choose a settlement token, choose source assets, rank routes, claim gas readiness, prepare signing, or produce transaction material.
|
|
79
|
+
|
|
80
|
+
`Make it 100 SUI.`
|
|
81
|
+
Class: `blocked_with_context`.
|
|
82
|
+
Use `read.classify_wallet_assets` only for current coin context when active account or explicit address is available.
|
|
83
|
+
Do not create a portfolio target, rebalance plan, source selection, route recommendation, or review session.
|
|
84
|
+
|
|
85
|
+
`Keep 100 SUI and convert the rest.`
|
|
86
|
+
Class: `blocked_with_context`.
|
|
87
|
+
Use `read.classify_wallet_assets` only for current coin context when active account or explicit address is available.
|
|
88
|
+
Do not infer gas reserve, sell source, route, reserve policy, transaction material, or signing readiness.
|
|
89
|
+
|
|
90
|
+
`If USDC is short, sell another token to fill it.`
|
|
91
|
+
Class: `intent_evidence_with_choices`.
|
|
92
|
+
Use `read.preview_intent_evidence` with `targetAssetSymbol: "USDC"` and `targetAssetSelectionSource: "user_explicit"` when active account or explicit address context is available.
|
|
93
|
+
Expose selected target shortfall, `selectedTarget.selectionSource`, settlement-asset candidate conversion evidence or quote-unavailable reasons, and required user choices.
|
|
94
|
+
Do not set target provenance for an AI-inferred target. Do not auto-pick assets to sell, rank routes, merge non-group quote proceeds into coverage, treat uninspected assets as funding sources, or prepare signing.
|
|
95
|
+
|
|
96
|
+
## General Behavior Scenarios
|
|
97
|
+
|
|
98
|
+
`What is 1 SUI worth?`
|
|
99
|
+
Class: `answer_only`.
|
|
100
|
+
Call `read.get_deepbook_mid_price` with `poolKey: "SUI_USDC"` for Say Ur Intent verified context.
|
|
101
|
+
Answer as DeepBook SUI/USDC mid price at `fetchedAt`, not as the global market price.
|
|
102
|
+
Do not use external web data unless the user explicitly asks for non-product market context.
|
|
103
|
+
Do not ask for a wallet or push a review session.
|
|
104
|
+
|
|
105
|
+
`If I sell 10 SUI, how many dollars do I get?`
|
|
106
|
+
Class: `clarify_or_intent_evidence`.
|
|
107
|
+
Say Say Ur Intent cannot turn "dollars" into fiat USD or silently choose USDC/USDT.
|
|
108
|
+
Ask whether the user wants a specific DeepBook USD-denominated quote token/pool or wallet-scoped settlement-asset-group evidence.
|
|
109
|
+
If the user chooses SUI/USDC, answer as a DeepBook SUI/USDC quote at `fetchedAt`.
|
|
110
|
+
Do not convert USDC to fiat USD cash-out, assume the USDC/USD peg, or use web/finance lookup unless the user explicitly asks for outside product market context.
|
|
111
|
+
Do not present it as a global USD price, route recommendation, price-impact calculation, final min-out, funding readiness, or signing readiness.
|
|
112
|
+
|
|
113
|
+
`How much do I have?`
|
|
114
|
+
Class: `clarify`.
|
|
115
|
+
Explain that active account context is needed before wallet assets can be read.
|
|
116
|
+
If none is set, ask for wallet identity connection.
|
|
117
|
+
Do not ask for manual address entry.
|
|
118
|
+
|
|
119
|
+
`Connect my wallet.`
|
|
120
|
+
Class: `tool_wait`.
|
|
121
|
+
Call `session.create_wallet_identity`, give the user the `walletUrl`, then immediately call `session.wait_wallet_identity` in the same turn or poll `session.get_wallet_identity`.
|
|
122
|
+
On `connected`, call `account.get_active_account` before announcing the active account.
|
|
123
|
+
On `timed_out`, say the wallet connection is still pending, not failed.
|
|
124
|
+
|
|
125
|
+
`I want to buy $10 worth of SUI.`
|
|
126
|
+
Class: `present_options`.
|
|
127
|
+
Do not claim a supported buy flow or provide investment advice.
|
|
128
|
+
Explain that dollar-denominated intent needs a supported stablecoin and amount unit.
|
|
129
|
+
Offer read-only DeepBook quote options and disclose that signing remains blocked.
|
|
130
|
+
|
|
131
|
+
`Sell a little.`
|
|
132
|
+
Class: `clarify`.
|
|
133
|
+
Ask for a concrete amount and provide examples.
|
|
134
|
+
Do not map vague quantity words to a fixed percent.
|
|
135
|
+
|
|
136
|
+
`Sell half.`
|
|
137
|
+
Class: `clarify`.
|
|
138
|
+
Explain that balance is needed before calculating half.
|
|
139
|
+
Use active account context if set; otherwise ask the user to connect wallet identity before wallet-account calculation.
|
|
140
|
+
|
|
141
|
+
`5`
|
|
142
|
+
Class: `clarify`.
|
|
143
|
+
Ask which unit the user means: SUI, another asset, or a USD-denominated amount.
|
|
144
|
+
If they mean dollars or stablecoins, use settlement-asset-group evidence before asking for a specific token.
|
|
145
|
+
|
|
146
|
+
`Keep it from getting expensive.`
|
|
147
|
+
Class: `clarify`.
|
|
148
|
+
Ask for a price/slippage limit or explain the default only when a supported action flow applies.
|
|
149
|
+
|
|
150
|
+
`Is this transaction safe?`
|
|
151
|
+
Class: `redirect_unsupported`.
|
|
152
|
+
Do not guarantee safety.
|
|
153
|
+
Summarize concrete review facts or say a review is blocked/unavailable.
|
|
154
|
+
|
|
155
|
+
`Tell me when the price drops.`
|
|
156
|
+
Class: `redirect_unsupported`.
|
|
157
|
+
Say alerts are unsupported and offer a one-time read.
|
|
158
|
+
|
|
159
|
+
`Let's buy Bitcoin too.`
|
|
160
|
+
Class: `redirect_unsupported`.
|
|
161
|
+
Say only Sui mainnet surfaces are exposed.
|
|
162
|
+
|
|
163
|
+
`What happened to the thing from before?`
|
|
164
|
+
Class: `clarify`.
|
|
165
|
+
Ask for the `reviewSessionId` unless a recent-session feature exists.
|
|
166
|
+
|
|
167
|
+
## Manual Client Results
|
|
168
|
+
|
|
169
|
+
No client observations are recorded in this matrix. Release checks can record Claude, Codex, or Cursor observations in an ignored local result file and promote durable failures to `docs/golden-scenarios/INTENT_EVIDENCE_MATRIX.md`, product docs, tests, or code.
|