@zktx.io/sui-mcp 0.5.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.
Files changed (218) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES/@mysten-bcs-2.0.5-Apache-2.0.txt +205 -0
  3. package/LICENSES/@mysten-sui-2.17.0-Apache-2.0.txt +201 -0
  4. package/LICENSES/@mysten-utils-0.3.3-Apache-2.0.txt +205 -0
  5. package/LICENSES/fancy-canvas-2.1.0-MIT.txt +7 -0
  6. package/LICENSES/lightweight-charts-5.2.0-NOTICE.txt +2 -0
  7. package/README.md +288 -0
  8. package/dist/adapters/adapterLifecycleValidators.js +5 -0
  9. package/dist/adapters/adapterPromptSurfaces.js +60 -0
  10. package/dist/adapters/deepbook/deepbookHumanReviewProducer.js +178 -0
  11. package/dist/adapters/deepbook/deepbookQuotePolicy.js +112 -0
  12. package/dist/adapters/deepbook/deepbookReviewEvidence.js +507 -0
  13. package/dist/adapters/deepbook/deepbookReviewLifecycle.js +85 -0
  14. package/dist/adapters/deepbook/deepbookSwapIntent.js +79 -0
  15. package/dist/adapters/deepbook/deepbookTransactionMaterialProducer.js +254 -0
  16. package/dist/adapters/intentPlanFactories.js +51 -0
  17. package/dist/adapters/reviewAdapters.js +47 -0
  18. package/dist/core/action/adapterLifecycleValidation.js +12 -0
  19. package/dist/core/action/contractNameRegistry.js +151 -0
  20. package/dist/core/action/forbiddenFields.js +43 -0
  21. package/dist/core/action/humanReadableReviewEvidence.js +193 -0
  22. package/dist/core/action/humanReadableReviewProjectionVerifier.js +29 -0
  23. package/dist/core/action/ptbVisualizationProducer.js +71 -0
  24. package/dist/core/action/receiptPtbGraph.js +29 -0
  25. package/dist/core/action/reviewCheckResults.js +6 -0
  26. package/dist/core/action/reviewStateValidation.js +11 -0
  27. package/dist/core/action/reviewTimeSimulationEvidence.js +470 -0
  28. package/dist/core/action/schemas.js +491 -0
  29. package/dist/core/action/signableAdapterContract.js +998 -0
  30. package/dist/core/action/suiChainReceiptEvidence.js +106 -0
  31. package/dist/core/action/suiChainReceiptMapping.js +107 -0
  32. package/dist/core/action/suiChainReceiptReader.js +211 -0
  33. package/dist/core/action/suiChainReceiptVerifier.js +178 -0
  34. package/dist/core/action/swapHumanReadableReviewProjection.js +130 -0
  35. package/dist/core/action/swapQuotePolicyEvidence.js +271 -0
  36. package/dist/core/action/transactionFunding.js +244 -0
  37. package/dist/core/action/transactionObjectOwnershipEvidence.js +256 -0
  38. package/dist/core/action/transactionObjectOwnershipProducer.js +323 -0
  39. package/dist/core/action/types.js +33 -0
  40. package/dist/core/action/walletReviewContractAssembler.js +286 -0
  41. package/dist/core/activity/accountAssetTimeline.js +157 -0
  42. package/dist/core/activity/accountAssetTimelineUsdcReferences.js +120 -0
  43. package/dist/core/activity/activityStore.js +16 -0
  44. package/dist/core/activity/externalActivityCoverage.js +76 -0
  45. package/dist/core/activity/externalActivityTransactionStream.js +82 -0
  46. package/dist/core/activity/localDataService.js +296 -0
  47. package/dist/core/activity/localDataTypes.js +11 -0
  48. package/dist/core/activity/localDataValidation.js +439 -0
  49. package/dist/core/activity/schemaVersion.js +2 -0
  50. package/dist/core/activity/sqliteActivityStore.js +1068 -0
  51. package/dist/core/activity/sqliteActivityStoreRows.js +389 -0
  52. package/dist/core/activity/sqliteActivityStoreSchema.js +367 -0
  53. package/dist/core/activity/sqliteActivityStoreTypes.js +5 -0
  54. package/dist/core/activity/suiFunctionTarget.js +43 -0
  55. package/dist/core/activity/transactionActivityAccountEffects.js +186 -0
  56. package/dist/core/activity/transactionActivityAnalysis.js +295 -0
  57. package/dist/core/activity/transactionActivityClassifier.js +306 -0
  58. package/dist/core/activity/transactionActivityDetails.js +229 -0
  59. package/dist/core/activity/transactionActivityProtocolRules.js +218 -0
  60. package/dist/core/activity/transactionActivityScanPolicy.js +170 -0
  61. package/dist/core/activity/transactionActivityService.js +379 -0
  62. package/dist/core/activity/transactionActivityTypes.js +18 -0
  63. package/dist/core/eventlog/sink.js +35 -0
  64. package/dist/core/evidence/settlementFamilies.js +85 -0
  65. package/dist/core/evidence/userAnswerUse.js +1 -0
  66. package/dist/core/numeric/rawU64.js +63 -0
  67. package/dist/core/preferences/preferencesStore.js +26 -0
  68. package/dist/core/preferences/sqlitePreferencesRepository.js +136 -0
  69. package/dist/core/proposal/externalProposalReview.js +347 -0
  70. package/dist/core/proposal/schemas.js +208 -0
  71. package/dist/core/proposal/types.js +35 -0
  72. package/dist/core/read/amounts.js +14 -0
  73. package/dist/core/read/coinMetadata.js +60 -0
  74. package/dist/core/read/deepbookOfficialIndexerSource.js +373 -0
  75. package/dist/core/read/deepbookRawQuoteClient.js +86 -0
  76. package/dist/core/read/deepbookReadHelpers.js +321 -0
  77. package/dist/core/read/deepbookRegistry.js +157 -0
  78. package/dist/core/read/deepbookSourceOwners.js +159 -0
  79. package/dist/core/read/deepbookUsdcChartService.js +342 -0
  80. package/dist/core/read/intentEvidenceResponseFormatting.js +228 -0
  81. package/dist/core/read/readCardInputs.js +19 -0
  82. package/dist/core/read/readCardResult.js +40 -0
  83. package/dist/core/read/readResponseGuidance.js +402 -0
  84. package/dist/core/read/readService.js +1639 -0
  85. package/dist/core/read/readServiceTypes.js +88 -0
  86. package/dist/core/read/settlementParityFormatting.js +82 -0
  87. package/dist/core/read/walletReadHelpers.js +99 -0
  88. package/dist/core/review/reviewChecks.js +45 -0
  89. package/dist/core/review/reviewComputation.js +38 -0
  90. package/dist/core/review/reviewComputationResult.js +87 -0
  91. package/dist/core/session/cardSession.js +31 -0
  92. package/dist/core/session/cardSessionStore.js +204 -0
  93. package/dist/core/session/keyedRecordStore.js +18 -0
  94. package/dist/core/session/liveReviewSessionContract.js +3 -0
  95. package/dist/core/session/localSession.js +31 -0
  96. package/dist/core/session/privateReviewArtifacts.js +75 -0
  97. package/dist/core/session/reviewValidity.js +49 -0
  98. package/dist/core/session/sessionErrors.js +9 -0
  99. package/dist/core/session/sessionRecordStore.js +40 -0
  100. package/dist/core/session/sessionStore.js +655 -0
  101. package/dist/core/session/settingsSession.js +1 -0
  102. package/dist/core/session/settingsSessions.js +45 -0
  103. package/dist/core/session/sqliteCardStore.js +88 -0
  104. package/dist/core/session/sqliteSessionStore.js +213 -0
  105. package/dist/core/session/sqliteTransactionMaterialStore.js +64 -0
  106. package/dist/core/session/sqliteWalletWorkflowStore.js +821 -0
  107. package/dist/core/session/status.js +60 -0
  108. package/dist/core/session/transactionMaterialStore.js +221 -0
  109. package/dist/core/session/transactionRequest.js +72 -0
  110. package/dist/core/session/wait.js +79 -0
  111. package/dist/core/session/walletConnection.js +92 -0
  112. package/dist/core/session/walletRuntime.js +38 -0
  113. package/dist/core/session/walletWorkflow.js +608 -0
  114. package/dist/core/session/workflowState.js +80 -0
  115. package/dist/core/session/workflowView.js +150 -0
  116. package/dist/core/suiAddress.js +18 -0
  117. package/dist/core/suiEndpoint.js +72 -0
  118. package/dist/mcp/activeAccountResponse.js +24 -0
  119. package/dist/mcp/prompts.js +146 -0
  120. package/dist/mcp/registerTool.js +19 -0
  121. package/dist/mcp/resources.js +72 -0
  122. package/dist/mcp/responseGuidance.js +326 -0
  123. package/dist/mcp/result.js +17 -0
  124. package/dist/mcp/schemas.js +11 -0
  125. package/dist/mcp/server.js +32 -0
  126. package/dist/mcp/serverInfo.js +131 -0
  127. package/dist/mcp/toolErrors.js +118 -0
  128. package/dist/mcp/toolNames.js +58 -0
  129. package/dist/mcp/tools/account/index.js +44 -0
  130. package/dist/mcp/tools/action/prepareSuiActionReview.js +126 -0
  131. package/dist/mcp/tools/read/commonSchemas.js +43 -0
  132. package/dist/mcp/tools/read/deepbookReadTools.js +686 -0
  133. package/dist/mcp/tools/read/index.js +14 -0
  134. package/dist/mcp/tools/read/readToolHelpers.js +97 -0
  135. package/dist/mcp/tools/read/reviewActivityTools.js +179 -0
  136. package/dist/mcp/tools/read/serverStatusTools.js +100 -0
  137. package/dist/mcp/tools/read/transactionActivityOutput.js +371 -0
  138. package/dist/mcp/tools/read/transactionActivityTools.js +858 -0
  139. package/dist/mcp/tools/read/walletReadTools.js +734 -0
  140. package/dist/mcp/tools/session/executionResultTools.js +44 -0
  141. package/dist/mcp/tools/session/index.js +8 -0
  142. package/dist/mcp/tools/session/shared.js +36 -0
  143. package/dist/mcp/tools/session/statusTools.js +69 -0
  144. package/dist/mcp/tools/session/walletConnectionTools.js +69 -0
  145. package/dist/mcp/tools/settings/index.js +66 -0
  146. package/dist/mcp-app/account.html +3133 -0
  147. package/dist/mcp-app/account.notices.txt +973 -0
  148. package/dist/mcp-app/chart.html +3354 -0
  149. package/dist/mcp-app/chart.notices.txt +1194 -0
  150. package/dist/mcp-app/connect.html +3179 -0
  151. package/dist/mcp-app/connect.notices.txt +1012 -0
  152. package/dist/mcp-app/receipt.html +8430 -0
  153. package/dist/mcp-app/receipt.notices.txt +3549 -0
  154. package/dist/mcp-app/review.html +8430 -0
  155. package/dist/mcp-app/review.notices.txt +3549 -0
  156. package/dist/mcp-ui/contracts.js +31 -0
  157. package/dist/mcp-ui/readCards.js +28 -0
  158. package/dist/mcp-ui/tools.js +134 -0
  159. package/dist/review-app/brand-dark.svg +1 -0
  160. package/dist/review-app/brand-light.svg +1 -0
  161. package/dist/review-app/favicon.svg +1 -0
  162. package/dist/review-app/settings.css +1 -0
  163. package/dist/review-app/settings.js +1 -0
  164. package/dist/review-app/ui.css +809 -0
  165. package/dist/review-server/assets.js +48 -0
  166. package/dist/review-server/html.js +45 -0
  167. package/dist/review-server/http.js +47 -0
  168. package/dist/review-server/middleware/hostOrigin.js +48 -0
  169. package/dist/review-server/middleware/reviewToken.js +7 -0
  170. package/dist/review-server/reviewServerPolicy.js +1 -0
  171. package/dist/review-server/server.js +72 -0
  172. package/dist/review-server/settingsApi.js +158 -0
  173. package/dist/runtime/application.js +203 -0
  174. package/dist/runtime/config.js +97 -0
  175. package/dist/runtime/localSettingsService.js +198 -0
  176. package/dist/runtime/logger.js +66 -0
  177. package/dist/runtime/reviewDependencies.js +58 -0
  178. package/dist/runtime/reviewServerAcquire.js +93 -0
  179. package/dist/runtime/runtimeTermination.js +60 -0
  180. package/dist/runtime/shared/authenticatedFetch.js +127 -0
  181. package/dist/runtime/shared/control.js +93 -0
  182. package/dist/runtime/shared/dataAccess.js +66 -0
  183. package/dist/runtime/shared/mcpHttp.js +84 -0
  184. package/dist/runtime/shared/ownerLease.js +50 -0
  185. package/dist/runtime/shared/server.js +98 -0
  186. package/dist/runtime/shared/stdio.js +113 -0
  187. package/dist/runtime/smokeMainnetRead.js +391 -0
  188. package/dist/runtime/smokeMainnetReadAssertions.js +306 -0
  189. package/dist/runtime/smokeReview.js +40 -0
  190. package/dist/runtime/start.js +90 -0
  191. package/dist/runtime/suiEndpoint.js +97 -0
  192. package/dist/runtime/suiTransactionGraphqlMapping.js +200 -0
  193. package/dist/runtime/suiTransactionGraphqlQueries.js +231 -0
  194. package/dist/runtime/suiTransactionGraphqlSource.js +148 -0
  195. package/dist/runtime/walletConnectConfig.js +3 -0
  196. package/dist/runtime/walletConnectStorage.js +99 -0
  197. package/dist/runtime/walletConnectTransport.js +128 -0
  198. package/dist/runtime/walletSdkChild.js +3 -0
  199. package/dist/runtime/walletSdkChildRuntime.js +160 -0
  200. package/dist/runtime/walletSdkIpc.js +26 -0
  201. package/dist/runtime/walletSdkProcess.js +358 -0
  202. package/docs/AGENT_BEHAVIOR.md +524 -0
  203. package/docs/AGENT_DEVELOPMENT_POLICY.md +815 -0
  204. package/docs/FRONTEND_POLICY.md +534 -0
  205. package/docs/LOCAL_DB_ARCHITECTURE.md +381 -0
  206. package/docs/MCP_SETUP.md +742 -0
  207. package/docs/MCP_TOOLS.md +1318 -0
  208. package/docs/SDK_API.md +206 -0
  209. package/docs/SIGNABLE_ADAPTER_CONTRACT.md +396 -0
  210. package/docs/TRANSACTION_ACTIVITY_LOG.md +194 -0
  211. package/docs/UTILITY_INDEX.md +275 -0
  212. package/docs/WALLET_CONNECTION.md +238 -0
  213. package/docs/golden-scenarios/BEHAVIOR_MATRIX.md +166 -0
  214. package/docs/golden-scenarios/INTENT_EVIDENCE_GOLDEN_ANSWERS.md +161 -0
  215. package/docs/golden-scenarios/INTENT_EVIDENCE_MATRIX.md +259 -0
  216. package/package.json +79 -0
  217. package/protocols/deepbook-margin.md +15 -0
  218. package/protocols/deepbook-v3.md +24 -0
@@ -0,0 +1,381 @@
1
+ # Local DB Architecture
2
+
3
+ Sui MCP uses a local SQLite database for durable product state that must survive MCP server restarts. The database stores account read context, Sui MCP review activity evidence, live review and session state shared across local AI clients, and user-requested bounded Sui activity facts. It is not a custody store, background indexer, complete wallet-history store, or raw transaction archive. Private per-request authority records enforce one admitted transaction; they do not grant standing wallet approval or hold the user's signing key.
4
+
5
+ This document is for maintainers and contributors who change local state, import/export behavior, activity queries, or review evidence storage. Product users normally need only the README and `docs/MCP_SETUP.md`.
6
+
7
+ ## Runtime Boundary
8
+
9
+ The process that binds the configured loopback port initializes these local components. Other stdio processes authenticate that server and forward their calls; they do not open SQLite:
10
+
11
+ - a local SQLite store;
12
+ - a mainnet guard for the configured Sui gRPC endpoint;
13
+ - the local review HTTP server on `127.0.0.1`;
14
+ - authenticated internal MCP sessions, reached by each client through a stdio forwarder.
15
+
16
+ The GraphQL endpoint is also mainnet-guarded when it is saved through settings, imported from a local-data backup, or first used by Sui activity tools.
17
+
18
+ Stdout is reserved for MCP JSON-RPC messages. Logs go to stderr.
19
+
20
+ ## Local Data
21
+
22
+ The runtime creates a local SQLite file for account read context and Sui MCP review activity evidence. Users do not install a database server separately.
23
+
24
+ Override the app data directory only when needed:
25
+
26
+ ```bash
27
+ export SUI_MCP_DATA_DIR="/path/to/local/app-data"
28
+ ```
29
+
30
+ The stored active account is for reading wallet state only. It does not let the toolkit sign transactions on your behalf.
31
+
32
+ User-requested bounded transaction scans can store normalized facts only when a transaction is related to a known local wallet. This product does not run a background or complete wallet history indexer.
33
+
34
+ The default Sui mainnet gRPC and GraphQL endpoints are stored in the local SQLite settings table on first run.
35
+
36
+ To inspect settings or change local data, ask your AI client to create a Sui MCP local settings session and open the returned settings URL in the same machine's system browser.
37
+
38
+ Endpoint changes apply after the MCP server restarts.
39
+
40
+ ## Engine
41
+
42
+ The runtime uses the `better-sqlite3` npm package for normal SQLite file semantics and incremental writes. Users do not install a separate database server.
43
+
44
+ The package targets Node.js `>=22`. Node 22 or 24 LTS is recommended.
45
+
46
+ `better-sqlite3` is an npm dependency, not a separate product database installation. The pinned version is `12.9.0`. Standard macOS arm64/x64, Linux arm64/x64, and Windows x64 platforms normally use prebuilt binaries; less common platforms such as Windows arm64 can require a native build toolchain. The release check verifies that the driver can be imported, can create an in-memory database, and also works after installing the packed tarball.
47
+
48
+ ## File Location
49
+
50
+ The default data directory name is `sui-mcp` on each supported operating
51
+ system. Sui MCP uses the `SUI_MCP_DATA_DIR` override and the
52
+ `sui-mcp.local-data` backup format identifier. Material source enum values
53
+ `sui_mcp_built` and `sui_mcp_verified` identify backend-built or
54
+ backend-verified material. Only the current `sui-mcp.local-data` backup format is accepted. This installation
55
+ uses its own data directory and does not discover or convert another package's
56
+ data. A new installation starts with empty state.
57
+
58
+
59
+ On first start, the runtime creates a SQLite file named `sui-mcp.sqlite` under the operating system's app data directory for Sui MCP.
60
+
61
+ The optional override is:
62
+
63
+ ```bash
64
+ export SUI_MCP_DATA_DIR="/path/to/local/app-data"
65
+ ```
66
+
67
+ Product docs, MCP responses, and tool outputs must not reveal a user's absolute database path. Use placeholders in documentation.
68
+
69
+ ## Open Policy
70
+
71
+ Every database connection applies:
72
+
73
+ ```sql
74
+ PRAGMA journal_mode=WAL;
75
+ PRAGMA synchronous=NORMAL;
76
+ PRAGMA foreign_keys=ON;
77
+ ```
78
+
79
+ Writes use SQLite's normal file-backed engine. An empty file is initialized to the current schema. An existing file is checked read-only before opening for writes: its format identifier and schema metadata must match the current definitions. The runtime does not migrate, repair or silently reset another format.
80
+
81
+ Use an empty `SUI_MCP_DATA_DIR` for a new installation. Existing files remain untouched. Product reset is a separate confirmed Settings action.
82
+
83
+ WAL mode can create companion files next to the main database, such as `sui-mcp.sqlite-wal` and `sui-mcp.sqlite-shm`. Backups and manual moves should keep those files together with the main database while the MCP server is stopped. Avoid placing `SUI_MCP_DATA_DIR` in cloud-synchronized folders such as iCloud Drive, Dropbox, or similar sync roots because WAL companion files can be copied out of order.
84
+
85
+ ## Tables
86
+
87
+ - `accounts`: normalized Sui account addresses and first/last use timestamps.
88
+ - `active_account_context`: a single-row read context. It can point to one active account or be cleared.
89
+ - `review_sessions`: review session header, current status, full action plan JSON, and materialized requested intent JSON when present.
90
+ - `review_state_snapshots`: append-only account-bound `ReviewState` snapshots with status and reason columns for queryability.
91
+ - `review_status_transitions`: append-only review lifecycle timing for funnel and review-timing analysis.
92
+ - `review_requests`: admitted attempts, immutable review evidence and independent request status.
93
+ - `review_executions`: verified chain success/failure, keyed by `attempt_id` and bound to review session, account, plan and digest. Wallet rejection and uncertainty never create a chain failure row.
94
+ - `external_activity_scans`: user-requested digest lookups, bounded account scans, or sent-function scans, including request window, endpoint host, chain identifier, continuation metadata, coverage signals, and internal scan-kind provenance.
95
+ - `external_activity_transactions`: normalized Sui transaction facts linked to a known local account and the first/last scan that observed them. The optional detail JSON stores typed facts such as capped Move call targets, raw balance changes, object changes, event summaries, gas raw cost fields, execution errors, and truncation flags when GraphQL returns them. Each stored detail JSON value is capped at 64 KiB.
96
+ - `local_settings`: allowlisted local settings. The current key set is `suiGrpcUrl` and `suiGraphqlUrl`, stored as JSON-encoded text and applied after restart.
97
+ - `coin_metadata_cache`: account-independent positive cache for Sui coin metadata used only to format wallet balance display amounts. Rows are keyed by normalized coin type and verified mainnet chain identifier, expire after 24 hours, and are excluded from local data export/import. Read or write failures for this cache block affected wallet unit reads with `metadata_cache_unavailable`; they are not reported as unavailable token decimals.
98
+
99
+ The following live session tables hold runtime session state in the shared database so any one review server can serve a session another client created (see [Shared local server](#shared-local-server)):
100
+
101
+ - `live_review_sessions`: the live review session record — status, bound
102
+ account, preparation/connection revision, current attempt reference,
103
+ plan/review-state JSON, timestamps, revision and write-contract marker —
104
+ keyed by session id.
105
+ - `live_private_review_artifacts`: per-session private review evidence (the transaction-material handle, its digest commitment, and derived evidence), cascade-deleted with its review session.
106
+ - `live_transaction_materials`: locally built unsigned transaction bytes stored as a BLOB behind a redacted handle, with a TTL; retained for the admitted request. Terminal request cleanup removes only material still owned by that revision, preserving newer preparation. Owner replacement deletes old private material while retaining immutable review and chain-result evidence.
107
+ - `live_wallet_connections`: verified connection facts, private topic and callback state.
108
+ - `live_settings_sessions`: short-lived Settings page authority.
109
+
110
+ These live tables are distinct from the append-only review evidence tables above: the evidence tables remain the durable activity/audit record, while the live tables hold the in-flight session state that the review server serves.
111
+
112
+ Database columns use snake_case. MCP and HTTP JSON fields use camelCase, so the database `review_session_id` column stores the same review-session identity exposed as `reviewSessionId` in API responses.
113
+
114
+ Table relationships:
115
+
116
+ - `active_account_context.account_id` and `review_sessions.account_id` point to `accounts.id` when an account is present.
117
+ - `review_state_snapshots`, `review_status_transitions`, and `review_executions` point to `review_sessions.id` through `review_session_id` and can also point to `accounts.id` through `account_id`.
118
+ - `external_activity_scans.account_id` points to `accounts.id`. It records which known local account the user-requested lookup or scan was scoped to.
119
+ - `external_activity_transactions.account_id` points to `accounts.id`, and `first_scan_id` / `last_scan_id` point to `external_activity_scans.scan_id`. `known_sender_account_id` points to `accounts.id` only when the sender is also a known local account. Non-known party account addresses are not stored; normalized detail JSON keeps account-owner and event-sender fields only when they match the known local account.
120
+ - `coin_metadata_cache` is account-independent and is keyed by coin type plus chain identifier.
121
+ - `local_settings` is independent local configuration and does not point to account or review rows.
122
+
123
+ The database does not create background transaction indexing tables. Complete external transaction history, raw GraphQL payloads, transaction bytes, signatures, BCS payloads, non-known party account addresses, and arbitrary transaction payloads are not product surfaces of this database. Server-read chain receipt evidence is normalized execution-result JSON for a reviewed signed transaction digest; it is not raw BCS, transaction bytes, wallet signatures, or a complete transaction-history index.
124
+
125
+ `external_activity_scans.kind` records the lookup category as `account_scan`,
126
+ `digest_lookup`, or `function_scan`. Stored scan rows keep their recorded kind;
127
+ the database does not infer missing function targets from `account_scan` rows.
128
+
129
+ The `live_review_sessions` table stores a monotonically increasing `revision`
130
+ and `write_contract_version: "shared_sqlite_review_session_v1"`. Insert and
131
+ update triggers reject revision-unaware writers: inserts must use
132
+ `revision = 0` and the current write-contract marker, and updates must increase
133
+ the revision by exactly one and keep the current write-contract marker.
134
+
135
+ Logical local data reset is the local settings page action that clears stored product state through the runtime without requiring manual database-file deletion. Replace-only import is the settings page import path that replaces local product state from a validated backup. When no unsettled financial request prevents replacement, both logical local data reset and replace-only import clear `coin_metadata_cache`, card records, live review/wallet/settings sessions, private review artifacts and transaction material in the same SQLite transaction. A rollback preserves the existing data and permissions. No separate HTTP cleanup call owns permission invalidation. Clearing active account context does not clear it because coin metadata is account-independent.
136
+
137
+ Non-terminal review session expiry is recorded lazily when the session is read or mutated after its TTL. There is no background expiry worker.
138
+
139
+ ## Shared local server
140
+
141
+ Exactly one parent runtime owner per data directory binds the configured loopback port and creates the shared product services and SQLite stores. Other clients authenticate the listener before sending control credentials and forward MCP messages to it. The authentication covers database identity, internal API version 7, configuration (including WalletConnect project configuration) and server instance. Proof and subsequent dispatch use the same TCP connection. Host/Origin validation is separate from authentication; neither protects against a malicious process running as the same OS user.
142
+
143
+ The private `runtime-control.key` file is separate from UI permissions and wallet credentials and is excluded from product backups. Stdio closure and process signals close the owned server. No client signals a peer backend. The parent may terminate only its own SDK child. A peer can acquire the port after it becomes free. Failed calls are not replayed automatically. MCP framing, cancellation and EOF handling start before backend acquisition; wallet SDK readiness does not block parent service startup.
144
+
145
+ All state-writing MCP callers use this owner, including reads that save activity, metadata or chain results. An asynchronous operation carries the current data generation. Access after replacement or shutdown is refused, preventing a late response from writing into replacement data. Live review transitions retain revision/CAS and SQLite transactions. No network wait is held inside a database transaction.
146
+
147
+ ### Read cards
148
+
149
+ `live_read_cards` owns the card kind (account, receipt, chart, connect or review), permission hash, backend owner, revision, original/accepted input, state/reason and saved result or scoped workflow operation reference. Business request status is not copied into a separate card state machine. Admission and result writes use conditional updates. Expiry is applied by the backend to unsubmitted input; a View timer only requests state. Frame recreation and chat navigation perform no close transition. The backend rejects late writes after local data replacement or owner changes, and recovery closes unfinished cards without repeating their source query.
150
+
151
+ The same record contains a model-safe result and, for receipts, separately validated UI-only input values and PTB display data. They are projections of one source read. They are not activity evidence or serialized signing material. Public saved resources exclude the private partition, and product backups exclude card records and permission hashes entirely.
152
+
153
+ Input TTL is not a result-retention deadline. Completed results survive restart and remain until explicit local data reset/import; there is no automatic age-based deletion or per-card size cap. Existing query limits still apply. DB size can therefore grow with usage. Reset/import affects other local data too and must retain its explicit confirmation and failure-atomicity contract.
154
+
155
+ ### Wallet and request ownership
156
+
157
+ The same product DB stores `review_requests` per attempt, with a unique review
158
+ session/revision admission, immutable reviewed state/account/digest, request
159
+ status and signature/submission timestamps. `review_sessions.current_attempt_id`
160
+ selects the current attempt explicitly. `review_executions` is keyed by attempt,
161
+ contains only verified chain success/failure, and cannot stand in for wallet
162
+ rejection or an unknown outcome. Public history and live request transitions
163
+ commit together with card admission or closure. Old attempts remain readable.
164
+
165
+ `live_request_authority` holds owner, wallet connection revision, submission
166
+ permission, pending callback flags and backend deadlines. `live_wallet_connections`
167
+ holds verified public connection facts and a private SDK topic reference.
168
+ `live_execution_details` holds optional receipt display details separately from
169
+ public history. `live_review_sessions` binds preparation to a connection revision;
170
+ a connection change invalidates unadmitted review data. None of these private
171
+ live tables is exported or restored by public backup.
172
+
173
+ `live_transaction_materials` contains private unsigned bytes bound to the review.
174
+ Admission freezes the transaction for that request; delayed signatures cannot
175
+ substitute a later quote or material. The backend rechecks digest and signer
176
+ before submission. Card/model results and public activity never include bytes
177
+ or signatures. The OS-user-only data directory is 0700 and DB files are 0600.
178
+
179
+ A separate `runtime-owner.sqlite` holds a process-lifetime SQLite exclusive lock,
180
+ so two ports cannot create two product database owners for one data directory.
181
+ The SDK child separately holds `walletconnect/runtime-owner.sqlite`; another SDK
182
+ writer cannot start until the prior process exits and releases that lock. Private
183
+ SDK sessions/keys use `walletconnect/sessions.sqlite` with a current-only format.
184
+ Pinned SDK request/history/message queues and unknown namespaces are volatile.
185
+ Neither file is part of public data backup. SDK state is not business authority;
186
+ restore reconciles only existing known connection records and never replays a
187
+ financial request or restores cleared read context.
188
+
189
+ SDK execution has a separate `walletRunId`. Every wallet command, observation
190
+ and response binds that run, an operation and the parent's data generation.
191
+ Typed private IPC carries transaction bytes and signatures only between backend
192
+ processes. The child opens only SDK storage and performs wallet transport calls;
193
+ product database access, verification and submission stay in the parent. This
194
+ process split isolates failures; it is not an OS security sandbox.
195
+ Ordinary reads use the last confirmed SDK snapshot; wallet-dependent commands
196
+ perform a current session check. After digest, signer and mainnet verification,
197
+ the parent performs a final session check before the synchronous submission CAS
198
+ and dispatch. A later remote event is not presumed already known.
199
+
200
+ Historical service-recovery results in `live_read_cards` remain readable;
201
+ Connect accepts no new service-restart input. Parent recovery closes unfinished
202
+ cards as `server_restarted`. SDK callback flags remain pending until actual
203
+ child exit, while parent verification, submission and lookup flags remain until
204
+ their own work ends. SDK readiness does not clear those independent guards.
205
+
206
+ Initial SDK restoration considers the entire known connection set, including
207
+ prior-owner records, before publishing current eligibility. Only confirmed
208
+ known connected records transfer to the new owner. Multiple valid records are
209
+ management targets, not usable wallet choices: `connectionConflict` is derived
210
+ from those rows with no additional table. Targeted disconnection remains
211
+ available while new pairing, account use, review preparation and signing are
212
+ blocked. The final submission transaction applies the same single-connection
213
+ rule. Failed/stopped records and unknown SDK sessions do not restore authority.
214
+
215
+ `active_account_context.wallet_id` preserves the connection through which the
216
+ default address was selected. Current eligibility requires that exact ID and
217
+ an approved address in the sole unexpired connection, with no pending connection
218
+ operation. Missing source IDs remain valid historical/import data but require
219
+ explicit selection before current default use. Eligibility is derived at the
220
+ database evaluation time and published to cards as `usableConnectionId` and
221
+ `assetReadAccount`; Views do not recount recorded connections. This adds no
222
+ table or expiry writer. Stored status, disconnection outcomes and historical
223
+ account records retain their separate meanings.
224
+
225
+ An admission that changes connection eligibility or targets also publishes the
226
+ owner's ready Connect/Review card revisions in that same transaction, after
227
+ consuming its own input. A competing admission after the confirmation read
228
+ therefore invalidates the earlier revision even before the SDK returns a QR or
229
+ approval. Publication failure rolls back admission; no SDK operation starts.
230
+
231
+ Service-loss authority revocation is retained against its SDK run and data
232
+ generation until it commits. Current wallet-state reads retry that database
233
+ write; they do not start another SDK process. Repeated reads after a successful
234
+ repair do not repeat the transition. Unrelated stored transaction results and
235
+ already dispatched chain observation remain independent of that write.
236
+ The supervisor's explicit replacement primitive requires fencing and actual
237
+ child exit before a new run, but it has no current card or model entry point.
238
+
239
+ If a completed callback's flag write fails, the owner retains its exact operation
240
+ identity as completion evidence. A current state read can retry that database
241
+ write without another network request. Connection cleanup also checks the
242
+ admitted card/run, so a late pairing cleanup cannot clear a later disconnect's
243
+ flag. Data replacement discards old completion evidence; it cannot be applied to
244
+ replacement records. A genuinely unfinished callback is never treated as ended
245
+ merely because a service restart or deadline was observed.
246
+
247
+ Review reads bind their target before asynchronous inspection and check it again
248
+ inside SQLite evaluation. Management cards bind their explicit attempt, consumed
249
+ Review cards bind their admitted operation, and ID-only tools bind the session's
250
+ current attempt. Live review input still requires current wallet eligibility.
251
+ Saved request reads do not advance unrelated request deadlines or connection
252
+ expiry, or require other operations' callback repairs. Their own completed
253
+ callback repair may remain pending without hiding recorded results. A new chain
254
+ lookup requires its own prior lookup callback to be settled; account-busy and
255
+ data-replacement guards retain all pending flags until their actual work ends.
256
+ The target session/card's own required expiry writes still propagate errors.
257
+ This is not availability during an unreadable database or a bypass of authority
258
+ revocation failures.
259
+
260
+ Successful reset/import invalidates pending SDK startup or recovery in the old
261
+ data generation and ends that child without automatically starting another.
262
+ Rejected or rolled-back replacement does not change the run or generation.
263
+ Existing financial pending guards apply before replacement. SDK sessions whose
264
+ product records were removed, failed or stopped cannot restore authority.
265
+
266
+ Stored snapshot readers do not reconcile expiry, call the wallet or observe the
267
+ chain. Current-state operations bind asynchronous evidence verification to the
268
+ review revision, material identity and exact verified bytes. A short synchronous
269
+ transaction samples its decision time, reconciles expiry and collects related
270
+ card, account, connection and request facts together. Projections consume that
271
+ evaluated state without a clock or I/O. Changed evidence requiring another
272
+ verification ends the read with a conflict; it is not retried in an internal
273
+ loop. Wallet availability is runtime information, not a persisted request state;
274
+ public backup and funnel counts exclude it.
275
+
276
+ Both `submitting` and `awaiting_chain_result` retain the initial observation
277
+ window in the session, account-busy and data-replacement guards, even when all
278
+ callback flags are clear. A failed post-submission write cannot strand the
279
+ known digest. Callback completion and chain completion remain separate facts.
280
+ Current Review evaluation also reads whether an unconsumed, unexpired original
281
+ input exists. Historical review status alone does not make an interaction pending.
282
+
283
+ Preparation IDs in the workflow execution set describe only currently running
284
+ computations; they hold no results or authority. If a current owner's stored
285
+ preparation has no running computation, current reads use the existing failure
286
+ writer to settle it. Pending disconnect cards with a settled SDK callback are
287
+ reconciled from the available SDK session or closed as unconfirmed failures.
288
+ These reads never repeat preparation, connection, signing or submission. Raw
289
+ history/export readers do not perform this reconciliation.
290
+
291
+ `ReviewSession.preparationId` identifies an admitted preparation awaiting a
292
+ stored outcome; the field alone does not prove that computation is still
293
+ running. `ReviewSession.preparationError`, stored in `live_review_sessions.preparation_error`,
294
+ is a saved review message: it can record a failed preparation or invalidation
295
+ caused by a wallet connection change. Its presence does not prove that a
296
+ computation ran. The View labels it Earlier review message and keeps it distinct
297
+ from current account-selection guidance and a command delivery failure. These
298
+ fields describe different facts; none grants action or retry authority.
299
+
300
+ Signature admission independently checks the current material handle, expiry,
301
+ bytes, digest and review binding inside its transaction. Displayed actions are
302
+ not admission authority. An admitted attempt keeps its fixed review facts and
303
+ request deadlines; subsequent quote expiry does not cancel that request.
304
+ Revision-specific evidence validity does not remove session/account pending-work
305
+ or data-replacement protections. Mandatory activity rows commit with the state;
306
+ optional event-log failures do not roll back that commit or repeat an operation.
307
+
308
+ Review preparation also checks the immutable bound account against current read
309
+ context and the selected account before writing preparation state. The same pure
310
+ account rule supplies evaluated choices. A selection mismatch is a current
311
+ restriction, not a stored preparation error or an activity transition.
312
+
313
+ Request interruption consumes both its internal origin and the request phase.
314
+ Before submission, user stopping, wallet change and requested disconnection
315
+ record distinct safe reasons with the terminal transition. After submission,
316
+ only explicit user stopping sets `observation_stopped`; wallet changes and
317
+ disconnect requests preserve that flag, the lookup deadline and pending work.
318
+ They cannot silently release account-busy protection or restart an observation
319
+ the user stopped. Existing deadline, owner-recovery and data-replacement rules
320
+ remain separate. Stored reasons flow unchanged to cards, model results, activity
321
+ and public backup; earlier recorded reasons are not rewritten speculatively.
322
+
323
+ Wallet dependency failure keeps guarded DB reads, local deadline reconciliation
324
+ and independent receipt observation available. Only a healthy wallet dependency
325
+ can admit new wallet work or continue a signature toward submission. After
326
+ dispatch, result recording and pending-flag settlement require the current DB
327
+ generation, owner and exact operation, not a working wallet SDK. Pending flags
328
+ remain set until the corresponding asynchronous work actually settles. A DB
329
+ failure is reported as a storage failure, never as an empty successful snapshot.
330
+
331
+ Reset/import checks SDK/signature/submission/initial-observation settlement
332
+ inside the same DB transaction as replacement, including after asynchronous
333
+ endpoint verification. Rejection preserves data and authority. Completed local
334
+ unknown-outcome records may be removed after the explicit warning; removing
335
+ records cannot cancel a transaction. A generation change rejects late writes.
336
+
337
+ The wallet store advances expired signature and initial-observation deadlines
338
+ through the same request transition writer used by the workflow. Current
339
+ session/card reads, current local-data counts and preview counts, and the actual
340
+ reset/import transaction use this operation even when no View is open. Expiry
341
+ does not clear pending SDK/submission/lookup callbacks. Stored activity queries
342
+ and public backup export only read recorded facts; they do not advance live
343
+ requests or interpret imported history as authority. Replacement warnings do not
344
+ claim an earlier counts snapshot is the number being deleted now.
345
+
346
+ Disconnect progress is the existing running Connect card's accepted disconnect
347
+ action and connection reference. Connection updates preserve that operation
348
+ until its result is recorded; no additional persisted connection status is used.
349
+
350
+ ### Current format and backups
351
+
352
+ The current `user_version` is 9. It identifies one supported schema; there is no migration registry or older-format decoder. All clients sharing a data directory must use the same compatible runtime.
353
+
354
+ A current backup carries `format`, `schemaVersion`, `network`, `exportedAt` and its product data. Import rejects a missing or different schema identifier, incomplete required fields, invalid references or invalid raw quantities. Missing settings or activity arrays are not filled from defaults. Supported `function_scan` provenance remains part of the current format. Validation failure leaves current data intact.
355
+
356
+ New installations do not inherit older local review records, activity scans, known/active accounts or stored endpoints. Users configure the required context again; environment overrides retain their existing precedence. Empty local history does not imply an absence of on-chain transactions. Existing DB and backup files are not deleted by startup.
357
+
358
+ ## Boundaries
359
+
360
+ The active account is a read context only. It is not signing authorization, login, authentication for transactions, custody, permission for transactions, or proof of ownership. It stores at most one address per database file; setting a new active account replaces the previous one without revoking anything onchain.
361
+
362
+ NDJSON event logs remain optional audit/debug logs. They are not the product activity source of truth. User-facing activity summaries read from SQLite. Event log write failures do not fail product session transitions or SQLite evidence writes.
363
+
364
+ Raw session tokens are not stored in SQLite. Live session records store token hashes for validation; this private state is separate from activity evidence and product backups. The activity-store evidence input types do not accept session token material, and review evidence JSON is checked with the same forbidden-field-name policy used for MCP output. Transaction bytes, signatures, serialized signing material, token-hash/session-token-like fields, seeds, mnemonics, and private-key-like field names are rejected before write. External proposal ingestion also rejects recognized Sui private-key strings, valid English BIP39 mnemonic phrases, obvious sensitive markers, and suspicious raw secret-like payloads before storing the sanitized requested intent. Generic asset metadata such as token symbols remains allowed.
365
+
366
+ The local settings table is not a secret store. It stores only allowlisted local preferences such as the Sui mainnet gRPC and GraphQL endpoints. It must not store database paths, tokens, credentials, private keys, mnemonics, seeds, or arbitrary API keys. Environment overrides such as `SUI_GRPC_URL` and `SUI_GRAPHQL_URL` can temporarily supersede stored endpoints without mutating the database.
367
+
368
+ Review intent capture follows one adapter convention: if an adapter wants the original requested intent materialized for activity queries, it must place that object at `ActionPlan.adapterData.requestedIntent`. The full `plan_json` remains the canonical action plan, and `intent_json` is only the query-friendly copy of that adapter-supplied intent.
369
+
370
+ ### Private funding evidence
371
+
372
+ Ownership and simulation private artifacts use their v2 evidence formats to
373
+ bind transaction funding to the stored material. They cover real coin objects,
374
+ address withdrawals, gas reservations, and their observed balance/epoch facts.
375
+ They are deeply copied and revalidated before admission, and are excluded from
376
+ public backup. They introduce no table, column, or DB format migration.
377
+
378
+ Old private evidence is not upgraded into funding proof. Existing owner recovery
379
+ removes private material; a new review recomputes it. Historical public reviews,
380
+ admitted request facts, chain results and backup remain readable. Reading history
381
+ does not re-query funding or confer new signing authority.