Skip to content

Commit d4fa4e9

Browse files
committed
Harden Base Sepolia rehearsal and launch demo
1 parent 4ffda74 commit d4fa4e9

35 files changed

Lines changed: 2457 additions & 172 deletions

.env.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,19 @@ BASE_SEPOLIA_RPC_URL=
77
# Hex deployer key for Foundry script runs. Keep the real value out of Git.
88
BASE_SEPOLIA_DEPLOYER_KEY_HEX=
99

10+
# Optional explorer key for Base Sepolia source verification. Keep real values
11+
# in your shell or ignored .env file only.
12+
BASE_SEPOLIA_BASESCAN_API_KEY=
13+
BASESCAN_API_KEY=
14+
1015
# Comma-separated FlowPulse-capable contract addresses for testnet reads.
1116
BASE_SEPOLIA_FLOWPULSE_ADDRESSES=
1217
BASE_SEPOLIA_FROM_BLOCK=
1318
BASE_SEPOLIA_TO_BLOCK=
1419
BASE_SEPOLIA_FINALIZED_BLOCK=
1520

21+
# Optional local artifact paths for rehearsal outputs.
22+
BASE_SEPOLIA_REHEARSAL_PLAN_OUT=fixtures/deployments/base-sepolia-rehearsal-plan.json
23+
BASE_SEPOLIA_REHEARSAL_ARTIFACT_OUT=fixtures/deployments/base-sepolia-rehearsal.latest.json
24+
1625
FLOWMEMORY_DASHBOARD_DATA_PATH=apps/dashboard/public/data/flowmemory-dashboard-v0.json

apps/dashboard/README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,70 @@ npm run dev
4747

4848
If the API is not running, the workbench marks the control-plane as offline, shows stale fixture fallback where appropriate, and keeps rendering deterministic local data. This app is for private/local validation and canary review only; it does not initiate value-bearing wallet flows.
4949

50+
## Beginner Demo Path
51+
52+
The full launch-demo script lives in:
53+
54+
```text
55+
docs/LAUNCH_DEMO_RUNBOOK.md
56+
```
57+
58+
From the repo root, the normal browser-demo setup is:
59+
60+
```powershell
61+
npm run flowchain:init
62+
npm run flowchain:start
63+
npm run flowchain:demo
64+
npm run flowchain:export
65+
```
66+
67+
Then start the local API and workbench in separate PowerShell windows:
68+
69+
```powershell
70+
npm run control-plane:serve
71+
```
72+
73+
```powershell
74+
npm run workbench:dev
75+
```
76+
77+
Open the Vite URL, usually:
78+
79+
```text
80+
http://127.0.0.1:5173/
81+
```
82+
83+
Click path for a short demo:
84+
85+
1. **Workbench** (`/`) for local API status, setup path, object switcher, provenance, and raw private/local object views.
86+
2. **Overview** (`/overview`) for local fixture metrics, recent FlowPulse observations, verifier attention, hardware risk, and devnet block window.
87+
3. **Flow Memory** (`/flowmemory`) for MemorySignal, MemoryReceipt, RootfieldBundle, AgentMemoryView, and RootflowTransition state.
88+
4. **Base canary** (`/canary`) for the isolated guarded canary review. This is not a production-readiness claim.
89+
5. **Raw JSON** (`/raw`) only when a reviewer asks for the payload behind the UI.
90+
91+
Workbench panel meanings:
92+
93+
| Panel | Meaning |
94+
| --- | --- |
95+
| Node and API status | Local chain/API health, block height, state root, pending transaction count, and API URL. |
96+
| Local setup path | Beginner command sequence for installing, refreshing launch fixtures, starting, smoking, and opening the workbench. |
97+
| Control-plane endpoints and local actions | Local API endpoints and optional browser-safe actions when the API advertises them. |
98+
| Workbench coverage metrics | Counts for data source, node views, chain objects, smoke objects, and challenges. |
99+
| Object switcher | Clickable local object views such as blocks, transactions, agents, models, receipts, reports, memory cells, challenges, finality, bridge-shaped local test objects, provenance, hardware signals, and raw JSON. |
100+
101+
Canary panel meanings:
102+
103+
| Panel | Meaning |
104+
| --- | --- |
105+
| Canary boundary hero | Reminder that the current Base canary is visible on Base but still gated for production. |
106+
| Reader command / review fixture / hard boundary strip | The reader shape, runtime fixture path, and no broad scan/no production/no real-funds boundary. |
107+
| Canary metrics | Counts from the committed canary fixture, including rejected logs and duplicates. |
108+
| Canary FlowPulse stream | Observed canary logs with block, pulse type, transaction hash, and log index. |
109+
| FlowPulse contracts | Canary contracts that emitted FlowPulse logs in the review fixture. |
110+
| Launch gates | Remaining boundaries before any production claim. |
111+
| Canary Rootflow state | Rootflow transitions reconstructed from the canary observations. |
112+
| Canary JSON | Full loaded canary dashboard payload for reviewer inspection. |
113+
50114
## Data Boundary
51115

52116
The canonical dashboard fixture is generated by the launch-core command and lives at:

apps/dashboard/public/data/flowmemory-dashboard-base-canary-v0.json

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"metadata": {
33
"schema": "flowmemory.dashboard.fixture.v0",
4-
"generatedAt": "2026-05-13T20:05:51.625Z",
4+
"generatedAt": "2026-05-13T23:49:07.586Z",
55
"mode": "canary",
66
"description": "Generated Base mainnet canary dashboard data from the guarded FlowPulse reader. It is canary-only and not a production-readiness claim.",
77
"fixturePath": "fixtures/dashboard/flowmemory-dashboard-base-canary-v0.json",
@@ -136,7 +136,7 @@
136136
"currentBlock": 45955540,
137137
"finalizedBlock": 45955540,
138138
"source": "live",
139-
"lastUpdated": "2026-05-13T20:05:51.625Z"
139+
"lastUpdated": "2026-05-13T23:49:07.586Z"
140140
},
141141
"flowPulseObservations": [
142142
{
@@ -161,13 +161,13 @@
161161
"uri": "flowmemory://base-canary/rootfield",
162162
"summary": "rootfield registration from Base canary reader",
163163
"status": "finalized",
164-
"lastUpdated": "2026-05-13T20:05:51.625Z",
164+
"lastUpdated": "2026-05-13T23:49:07.586Z",
165165
"provenance": {
166166
"subsystem": "indexer",
167167
"origin": "live",
168168
"chainContext": "base-mainnet-canary",
169169
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
170-
"capturedAt": "2026-05-13T20:05:51.625Z",
170+
"capturedAt": "2026-05-13T23:49:07.586Z",
171171
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
172172
}
173173
},
@@ -193,13 +193,13 @@
193193
"uri": "flowmemory://uniswap-v4/after-swap",
194194
"summary": "swap memory signal from Base canary reader",
195195
"status": "finalized",
196-
"lastUpdated": "2026-05-13T20:05:51.625Z",
196+
"lastUpdated": "2026-05-13T23:49:07.586Z",
197197
"provenance": {
198198
"subsystem": "indexer",
199199
"origin": "live",
200200
"chainContext": "base-mainnet-canary",
201201
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
202-
"capturedAt": "2026-05-13T20:05:51.625Z",
202+
"capturedAt": "2026-05-13T23:49:07.586Z",
203203
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
204204
}
205205
},
@@ -225,13 +225,13 @@
225225
"uri": "flowmemory://base-canary/root",
226226
"summary": "root commitment from Base canary reader",
227227
"status": "finalized",
228-
"lastUpdated": "2026-05-13T20:05:51.625Z",
228+
"lastUpdated": "2026-05-13T23:49:07.586Z",
229229
"provenance": {
230230
"subsystem": "indexer",
231231
"origin": "live",
232232
"chainContext": "base-mainnet-canary",
233233
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
234-
"capturedAt": "2026-05-13T20:05:51.625Z",
234+
"capturedAt": "2026-05-13T23:49:07.586Z",
235235
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
236236
}
237237
},
@@ -257,13 +257,13 @@
257257
"uri": "flowmemory://uniswap-v4/after-swap",
258258
"summary": "swap memory signal from Base canary reader",
259259
"status": "finalized",
260-
"lastUpdated": "2026-05-13T20:05:51.625Z",
260+
"lastUpdated": "2026-05-13T23:49:07.586Z",
261261
"provenance": {
262262
"subsystem": "indexer",
263263
"origin": "live",
264264
"chainContext": "base-mainnet-canary",
265265
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
266-
"capturedAt": "2026-05-13T20:05:51.625Z",
266+
"capturedAt": "2026-05-13T23:49:07.586Z",
267267
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
268268
}
269269
}
@@ -284,13 +284,13 @@
284284
],
285285
"evidenceUri": "docs/DEPLOYMENTS/2026-05-13-base-canary-v0.md",
286286
"status": "finalized",
287-
"lastUpdated": "2026-05-13T20:05:51.625Z",
287+
"lastUpdated": "2026-05-13T23:49:07.586Z",
288288
"provenance": {
289289
"subsystem": "indexer",
290290
"origin": "live",
291291
"chainContext": "base-mainnet-canary",
292292
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
293-
"capturedAt": "2026-05-13T20:05:51.625Z",
293+
"capturedAt": "2026-05-13T23:49:07.586Z",
294294
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
295295
}
296296
}
@@ -331,13 +331,13 @@
331331
"logIndex": "229"
332332
},
333333
"id": "0xef6e3d4a6375fdaf3573db4550b7a6c4ac535f6ddbf8a2759014c7e6ee5dc17d",
334-
"lastUpdated": "2026-05-13T20:05:51.625Z",
334+
"lastUpdated": "2026-05-13T23:49:07.586Z",
335335
"provenance": {
336336
"subsystem": "indexer",
337337
"origin": "live",
338338
"chainContext": "base-mainnet-canary",
339339
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
340-
"capturedAt": "2026-05-13T20:05:51.625Z",
340+
"capturedAt": "2026-05-13T23:49:07.586Z",
341341
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
342342
}
343343
},
@@ -373,13 +373,13 @@
373373
"logIndex": "274"
374374
},
375375
"id": "0x7da37f62f68f29fdd92dde90fdb5783bce555c868bfb0181187ae955eb2d8c95",
376-
"lastUpdated": "2026-05-13T20:05:51.625Z",
376+
"lastUpdated": "2026-05-13T23:49:07.586Z",
377377
"provenance": {
378378
"subsystem": "indexer",
379379
"origin": "live",
380380
"chainContext": "base-mainnet-canary",
381381
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
382-
"capturedAt": "2026-05-13T20:05:51.625Z",
382+
"capturedAt": "2026-05-13T23:49:07.586Z",
383383
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
384384
}
385385
},
@@ -415,13 +415,13 @@
415415
"logIndex": "364"
416416
},
417417
"id": "0x508409804fe0dae77e8ced57cb45968877fcbad6f525a99b4f911ce58759eab7",
418-
"lastUpdated": "2026-05-13T20:05:51.625Z",
418+
"lastUpdated": "2026-05-13T23:49:07.586Z",
419419
"provenance": {
420420
"subsystem": "indexer",
421421
"origin": "live",
422422
"chainContext": "base-mainnet-canary",
423423
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
424-
"capturedAt": "2026-05-13T20:05:51.625Z",
424+
"capturedAt": "2026-05-13T23:49:07.586Z",
425425
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
426426
}
427427
},
@@ -457,13 +457,13 @@
457457
"logIndex": "1212"
458458
},
459459
"id": "0x91d0da9bc41fad8cb3fa66b72ba804f6685d34f0c167bd3fbf1ac48f91402188",
460-
"lastUpdated": "2026-05-13T20:05:51.625Z",
460+
"lastUpdated": "2026-05-13T23:49:07.586Z",
461461
"provenance": {
462462
"subsystem": "indexer",
463463
"origin": "live",
464464
"chainContext": "base-mainnet-canary",
465465
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
466-
"capturedAt": "2026-05-13T20:05:51.625Z",
466+
"capturedAt": "2026-05-13T23:49:07.586Z",
467467
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
468468
}
469469
}
@@ -534,13 +534,13 @@
534534
]
535535
},
536536
"id": "0x1d530aa927338513f49fbd12145d05b1428347b5cfa0fb241033a9d070123637",
537-
"lastUpdated": "2026-05-13T20:05:51.625Z",
537+
"lastUpdated": "2026-05-13T23:49:07.586Z",
538538
"provenance": {
539539
"subsystem": "indexer",
540540
"origin": "live",
541541
"chainContext": "base-mainnet-canary",
542542
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
543-
"capturedAt": "2026-05-13T20:05:51.625Z",
543+
"capturedAt": "2026-05-13T23:49:07.586Z",
544544
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
545545
}
546546
},
@@ -609,13 +609,13 @@
609609
]
610610
},
611611
"id": "0x4dbf295239f26095033ddbc39dbb3d2780a554ca697d3ea89c588bda449939d1",
612-
"lastUpdated": "2026-05-13T20:05:51.625Z",
612+
"lastUpdated": "2026-05-13T23:49:07.586Z",
613613
"provenance": {
614614
"subsystem": "indexer",
615615
"origin": "live",
616616
"chainContext": "base-mainnet-canary",
617617
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
618-
"capturedAt": "2026-05-13T20:05:51.625Z",
618+
"capturedAt": "2026-05-13T23:49:07.586Z",
619619
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
620620
}
621621
},
@@ -684,13 +684,13 @@
684684
]
685685
},
686686
"id": "0x79640fe5901417b9254f9de76f011cdd54ffe9587aaf564f241f4b0cc2ec82da",
687-
"lastUpdated": "2026-05-13T20:05:51.625Z",
687+
"lastUpdated": "2026-05-13T23:49:07.586Z",
688688
"provenance": {
689689
"subsystem": "indexer",
690690
"origin": "live",
691691
"chainContext": "base-mainnet-canary",
692692
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
693-
"capturedAt": "2026-05-13T20:05:51.625Z",
693+
"capturedAt": "2026-05-13T23:49:07.586Z",
694694
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
695695
}
696696
},
@@ -759,13 +759,13 @@
759759
]
760760
},
761761
"id": "0x623c146bc8899c5edadaed215cc86a1292f1f5c97acb245e86c0462190078ca5",
762-
"lastUpdated": "2026-05-13T20:05:51.625Z",
762+
"lastUpdated": "2026-05-13T23:49:07.586Z",
763763
"provenance": {
764764
"subsystem": "indexer",
765765
"origin": "live",
766766
"chainContext": "base-mainnet-canary",
767767
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
768-
"capturedAt": "2026-05-13T20:05:51.625Z",
768+
"capturedAt": "2026-05-13T23:49:07.586Z",
769769
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
770770
}
771771
}
@@ -804,13 +804,13 @@
804804
"unsupported": 0,
805805
"reorged": 0
806806
},
807-
"lastUpdated": "2026-05-13T20:05:51.625Z",
807+
"lastUpdated": "2026-05-13T23:49:07.586Z",
808808
"provenance": {
809809
"subsystem": "indexer",
810810
"origin": "live",
811811
"chainContext": "base-mainnet-canary",
812812
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
813-
"capturedAt": "2026-05-13T20:05:51.625Z",
813+
"capturedAt": "2026-05-13T23:49:07.586Z",
814814
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
815815
}
816816
}
@@ -842,13 +842,13 @@
842842
"Source verification and operator policy must be completed before any production claim."
843843
],
844844
"localOnly": false,
845-
"lastUpdated": "2026-05-13T20:05:51.625Z",
845+
"lastUpdated": "2026-05-13T23:49:07.586Z",
846846
"provenance": {
847847
"subsystem": "worker",
848848
"origin": "live",
849849
"chainContext": "base-mainnet-canary",
850850
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
851-
"capturedAt": "2026-05-13T20:05:51.625Z",
851+
"capturedAt": "2026-05-13T23:49:07.586Z",
852852
"localPathHint": "fixtures/deployments/base-canary-indexer-state.json"
853853
}
854854
}
@@ -862,7 +862,7 @@
862862
"severity": "info",
863863
"title": "Canary mode",
864864
"summary": "Base mainnet canary logs are visible, but verifier reports, source verification, multisig ownership, and production hook wiring are not complete.",
865-
"openedAt": "2026-05-13T20:05:51.625Z",
865+
"openedAt": "2026-05-13T23:49:07.586Z",
866866
"linkedObjectIds": [
867867
"0x2a7ADd68a1d45C3251E2F92fFe4926124654a97C",
868868
"0x179Df6d52e9DeF5D02704583a2E4E5a9FF427245",
@@ -877,13 +877,13 @@
877877
],
878878
"recommendedAction": "Use this view for launch demonstrations and operator review only.",
879879
"status": "unresolved",
880-
"lastUpdated": "2026-05-13T20:05:51.625Z",
880+
"lastUpdated": "2026-05-13T23:49:07.586Z",
881881
"provenance": {
882882
"subsystem": "alerts",
883883
"origin": "live",
884884
"chainContext": "base-mainnet-canary",
885885
"fixturePath": "fixtures/deployments/base-canary-indexer-state.json",
886-
"capturedAt": "2026-05-13T20:05:51.625Z",
886+
"capturedAt": "2026-05-13T23:49:07.586Z",
887887
"localPathHint": "fixtures/deployments/base-canary-v0.json"
888888
}
889889
}

contracts/DEPLOYMENT_BOUNDARY.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,25 @@ Private keys must not be committed to the repo, copied into docs, or stored in g
121121
## Current Commands
122122

123123
```powershell
124+
npm run deploy:base-sepolia:plan -- --json
124125
npm run deploy:base-sepolia
125126
npm run deploy:base-sepolia:broadcast
126127
npm run read:base-sepolia -- --rpc-url <base-sepolia-rpc-url> --address <flowpulse-contract> --from-block <n> --to-block <n>
128+
npm run read:base-sepolia -- --rpc-url <base-sepolia-rpc-url> --address <flowpulse-contract> --resume-from-checkpoint --to-block <n>
127129
npm run verify:base-canary:sources -- --json
128130
```
129131

132+
`deploy:base-sepolia:plan` requires no private key and writes a non-secret
133+
rehearsal plan to `fixtures/deployments/base-sepolia-rehearsal-plan.json`.
134+
130135
`deploy:base-sepolia` requires `BASE_SEPOLIA_RPC_URL` and
131136
`BASE_SEPOLIA_DEPLOYER_KEY_HEX` from the local shell or an untracked `.env`
132137
loader. The example file is `.env.example`; real key material must stay
133138
outside Git.
134139

140+
The detailed public testnet rehearsal runbook is
141+
`docs/DEPLOYMENTS/BASE_SEPOLIA_REHEARSAL.md`.
142+
135143
`verify:base-canary:sources` reads `fixtures/deployments/base-canary-v0.json`
136144
and prints a dry-run verification plan by default. It also writes the same
137145
non-secret plan to

0 commit comments

Comments
 (0)