Skip to content

Commit b20dc75

Browse files
committed
Add external tester connect pack gate
1 parent b8d1428 commit b20dc75

31 files changed

Lines changed: 666 additions & 292 deletions

apps/dashboard/public/data/flowchain-live-readiness-report.json

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"schema": "flowchain.live_readiness_dashboard_report.v0",
3-
"generatedAt": "2026-05-17T20:55:41.2198531Z",
3+
"generatedAt": "2026-05-17T21:22:58.9529031Z",
44
"status": "blocked",
55
"deploymentReady": false,
66
"packetShareable": false,
77
"blockedOnlyOnKnownExternalOwnerInputs": true,
88
"summary": "Public launch is still blocked by owner-provided RPC edge, backup, Base 8453 bridge, or tester packet inputs.",
99
"privateRpcUrl": "http://127.0.0.1:8787",
1010
"metrics": {
11-
"latestHeight": "59881",
12-
"finalizedHeight": "59881",
11+
"latestHeight": "60281",
12+
"finalizedHeight": "60281",
1313
"monitorHeightAdvanced": true,
1414
"bridgeRelayerStatus": "blocked",
1515
"bridgeQueuedTransactions": "0",
@@ -21,6 +21,7 @@
2121
"publicRpcDeploymentAutomationStatus": "passed",
2222
"publicRpcDeploymentAutomationAction": "Validate",
2323
"externalTesterPacketStatus": "blocked",
24+
"externalTesterConnectPackStatus": "blocked",
2425
"ownerInputReady": false,
2526
"noSecretStatus": "passed",
2627
"opsSnapshotStatus": "blocked",
@@ -293,8 +294,17 @@
293294
"status": "blocked",
294295
"readinessStatus": "blocked",
295296
"packetStatus": "blocked",
297+
"connectPackStatus": "blocked",
296298
"gatewayStatus": "passed",
297299
"shareable": false,
300+
"connectPackShareable": false,
301+
"connectPackReady": true,
302+
"connectPackNetwork": {
303+
"name": "FlowChain friends-and-family pilot",
304+
"chainId": "flowmemory-local-devnet-v0",
305+
"rpcEndpointPlaceholder": "<OWNER_PUBLIC_ENDPOINT>/rpc",
306+
"explorerSummaryUrlPlaceholder": "<OWNER_PUBLIC_ENDPOINT>/explorer/summary"
307+
},
298308
"externalSharingReady": false,
299309
"localTesterRehearsalReady": true,
300310
"publicTesterGatewayReady": true,
@@ -317,6 +327,21 @@
317327
"/tester/wallets/send",
318328
"/rpc balance_get"
319329
],
330+
"connectPackReadOnlyRoutes": [
331+
"/health",
332+
"/rpc/discover",
333+
"/rpc/readiness",
334+
"/chain/status",
335+
"/explorer/summary",
336+
"/wallets/balances",
337+
"/wallets/transfers",
338+
"/tester/status"
339+
],
340+
"connectPackTesterWriteRoutes": [
341+
"/tester/wallets/create",
342+
"/tester/faucet",
343+
"/tester/wallets/send"
344+
],
320345
"gatewayRoutes": [
321346
"/tester/status",
322347
"/tester/wallets/create",
@@ -455,7 +480,7 @@
455480
"label": "Private L1 origin",
456481
"status": "passed",
457482
"summary": "The public deployment origin service is running privately in live profile before any owner TLS edge is considered shareable.",
458-
"evidence": "serviceStatus=passed, privateBind=True, latestHeight=59881, finalizedHeight=59881",
483+
"evidence": "serviceStatus=passed, privateBind=True, latestHeight=60281, finalizedHeight=60281",
459484
"commands": [
460485
"npm run flowchain:service:status"
461486
],
@@ -592,8 +617,8 @@
592617
"id": "external-tester-sharing",
593618
"label": "External tester packet",
594619
"status": "blocked",
595-
"summary": "External tester packet must remain not-shareable until owner public RPC, backup, and bridge gates pass, and it must rely on fresh tester-wallet evidence plus authenticated tester faucet/send gateway smoke.",
596-
"evidence": "externalTester=blocked, localTesterRehearsalReady=True, testerNetworkFresh=True, publicTesterGatewayReady=True, faucetRoute=True, packetSmoke=True, testerFaucet=True, capRejected=True, externalSharingReady=False, packet=blocked, packetShareable=False",
620+
"summary": "External tester packet and machine-readable connection pack must remain not-shareable until owner public RPC, backup, and bridge gates pass, and they must rely on fresh tester-wallet evidence plus authenticated tester faucet/send gateway smoke.",
621+
"evidence": "externalTester=blocked, localTesterRehearsalReady=True, testerNetworkFresh=True, publicTesterGatewayReady=True, faucetRoute=True, packetSmoke=True, testerFaucet=True, capRejected=True, connectPackReady=True, externalSharingReady=False, packet=blocked, packetShareable=False",
597622
"commands": [
598623
"npm run flowchain:tester:readiness",
599624
"npm run flowchain:external-tester:packet"
@@ -674,19 +699,19 @@
674699
"fileName": "public-deployment-contract-report.json",
675700
"schema": "flowchain.public_deployment_contract_report.v0",
676701
"status": "blocked",
677-
"generatedAt": "2026-05-17T20:55:41.2198531Z"
702+
"generatedAt": "2026-05-17T21:22:58.9529031Z"
678703
},
679704
{
680705
"fileName": "flowchain-live-infra-check-report.json",
681706
"schema": "flowchain.live_infra_check_report.v0",
682707
"status": "blocked",
683-
"generatedAt": "2026-05-17T19:03:14.8669292Z"
708+
"generatedAt": "2026-05-17T21:22:39.5560846Z"
684709
},
685710
{
686711
"fileName": "service-status-report.json",
687712
"schema": "flowchain.service_status_report.v0",
688713
"status": "passed",
689-
"generatedAt": "2026-05-17T20:49:54.2260543Z"
714+
"generatedAt": "2026-05-17T21:21:58.9222250Z"
690715
},
691716
{
692717
"fileName": "service-monitor-report.json",
@@ -710,13 +735,13 @@
710735
"fileName": "public-rpc-readiness-report.json",
711736
"schema": "flowchain.public_rpc_readiness_report.v0",
712737
"status": "blocked",
713-
"generatedAt": "2026-05-17T19:02:05.5015285Z"
738+
"generatedAt": "2026-05-17T21:21:24.3599349Z"
714739
},
715740
{
716741
"fileName": "backup-readiness-report.json",
717742
"schema": "flowchain.backup_readiness_report.v1",
718743
"status": "blocked",
719-
"generatedAt": "2026-05-17T19:03:08.3142430Z"
744+
"generatedAt": "2026-05-17T21:22:32.2350583Z"
720745
},
721746
{
722747
"fileName": "backup-owner-path-dry-run-report.json",
@@ -728,7 +753,7 @@
728753
"fileName": "bridge-relayer-once-report.json",
729754
"schema": "flowchain.bridge_relayer_once_report.v0",
730755
"status": "blocked",
731-
"generatedAt": "2026-05-17T19:03:13.1875436Z"
756+
"generatedAt": "2026-05-17T21:22:37.6163884Z"
732757
},
733758
{
734759
"fileName": "bridge-relayer-guardrail-validation-report.json",
@@ -746,19 +771,25 @@
746771
"fileName": "external-tester-packet-report.json",
747772
"schema": "flowchain.external_tester_packet_report.v0",
748773
"status": "blocked",
749-
"generatedAt": "2026-05-17T19:03:17.4700900Z"
774+
"generatedAt": "2026-05-17T21:22:42.4548904Z"
775+
},
776+
{
777+
"fileName": "external-tester-connect-pack.json",
778+
"schema": "flowchain.external_tester_connect_pack.v0",
779+
"status": "blocked",
780+
"generatedAt": "2026-05-17T21:22:42.4548904Z"
750781
},
751782
{
752783
"fileName": "external-tester-readiness-report.json",
753784
"schema": "flowchain.external_tester_readiness_report.v0",
754785
"status": "blocked",
755-
"generatedAt": "2026-05-17T19:03:15.6449467Z"
786+
"generatedAt": "2026-05-17T21:22:40.3787817Z"
756787
},
757788
{
758789
"fileName": "public-tester-gateway-e2e-report.json",
759790
"schema": "flowchain.public_tester_gateway_e2e_report.v0",
760791
"status": "passed",
761-
"generatedAt": "2026-05-17T18:49:41.2441905Z"
792+
"generatedAt": "2026-05-17T21:06:45.7544746Z"
762793
},
763794
{
764795
"fileName": "ops-snapshot-report.json",
@@ -794,13 +825,13 @@
794825
"fileName": "owner-inputs-report.json",
795826
"schema": "flowchain.owner_inputs_report.v0",
796827
"status": "blocked",
797-
"generatedAt": "2026-05-17T19:03:16.8786801Z"
828+
"generatedAt": "2026-05-17T21:22:41.6153505Z"
798829
},
799830
{
800831
"fileName": "no-secret-scan-report.json",
801832
"schema": "flowchain.no_secret_scan_report.v0",
802833
"status": "passed",
803-
"generatedAt": "2026-05-17T19:31:27.0642221Z"
834+
"generatedAt": "2026-05-17T21:22:39.2390748Z"
804835
}
805836
],
806837
"envValuesPrinted": false,

apps/dashboard/scripts/sync-fixtures.mjs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const liveReadinessReportCopies = [
4848
"bridge-relayer-guardrail-validation-report.json",
4949
"bridge-relayer-loop-validation-report.json",
5050
"external-tester-packet-report.json",
51+
"external-tester-connect-pack.json",
5152
"external-tester-readiness-report.json",
5253
"public-tester-gateway-e2e-report.json",
5354
"ops-snapshot-report.json",
@@ -190,6 +191,7 @@ function writeLiveReadinessSummary() {
190191
const publicRpcDeploymentBundle = reports["public-rpc-deployment-bundle-report.json"];
191192
const publicRpcDeploymentAutomation = reports["public-rpc-deployment-automation-report.json"];
192193
const externalTesterPacket = reports["external-tester-packet-report.json"];
194+
const externalTesterConnectPack = reports["external-tester-connect-pack.json"];
193195
const externalTesterReadiness = reports["external-tester-readiness-report.json"];
194196
const publicTesterGateway = reports["public-tester-gateway-e2e-report.json"];
195197
const opsSnapshot = reports["ops-snapshot-report.json"];
@@ -216,6 +218,7 @@ function writeLiveReadinessSummary() {
216218
name,
217219
group: ownerInputGroup(name),
218220
}));
221+
const connectPackCheckValues = Object.values(externalTesterPacket?.connectPackChecks ?? {});
219222
const latestHeight = asText(serviceStatus?.chain?.latestHeight, "not recorded");
220223
const finalizedHeight = asText(serviceStatus?.chain?.finalizedHeight, "not recorded");
221224
const privateRpcUrl = serviceStatus?.bind
@@ -253,6 +256,7 @@ function writeLiveReadinessSummary() {
253256
publicRpcDeploymentAutomationStatus: asText(publicRpcDeploymentAutomation?.status, "not recorded"),
254257
publicRpcDeploymentAutomationAction: asText(publicRpcDeploymentAutomation?.action, "not recorded"),
255258
externalTesterPacketStatus: asText(externalTesterPacket?.status, "not recorded"),
259+
externalTesterConnectPackStatus: asText(externalTesterConnectPack?.status, "not recorded"),
256260
ownerInputReady: ownerInputs?.ownerInputReady === true,
257261
noSecretStatus: asText(noSecretScan?.status, "not recorded"),
258262
opsSnapshotStatus: asText(opsSnapshot?.status, "not recorded"),
@@ -311,8 +315,17 @@ function writeLiveReadinessSummary() {
311315
status: asText(externalTesterPacket?.status ?? externalTesterReadiness?.status, "not recorded"),
312316
readinessStatus: asText(externalTesterReadiness?.status, "not recorded"),
313317
packetStatus: asText(externalTesterPacket?.status, "not recorded"),
318+
connectPackStatus: asText(externalTesterConnectPack?.status, "not recorded"),
314319
gatewayStatus: asText(publicTesterGateway?.status, "not recorded"),
315320
shareable: externalTesterPacket?.packetShareable === true,
321+
connectPackShareable: externalTesterPacket?.connectPackShareable === true || externalTesterConnectPack?.shareable === true,
322+
connectPackReady: connectPackCheckValues.length > 0 && connectPackCheckValues.every((value) => value === true),
323+
connectPackNetwork: {
324+
name: sanitizeText(externalTesterConnectPack?.network?.name),
325+
chainId: sanitizeText(externalTesterConnectPack?.network?.chainId),
326+
rpcEndpointPlaceholder: sanitizeText(externalTesterConnectPack?.network?.rpcEndpointPlaceholder),
327+
explorerSummaryUrlPlaceholder: sanitizeText(externalTesterConnectPack?.network?.explorerSummaryUrlPlaceholder),
328+
},
316329
externalSharingReady: externalTesterReadiness?.externalSharingReady === true || externalTesterPacket?.externalSharingReady === true,
317330
localTesterRehearsalReady: externalTesterReadiness?.localTesterRehearsalReady === true,
318331
publicTesterGatewayReady: externalTesterReadiness?.checks?.publicTesterGatewayReady === true,
@@ -321,6 +334,8 @@ function writeLiveReadinessSummary() {
321334
faucetRouteValidated: externalTesterReadiness?.checks?.publicTesterGatewayFaucetRouteValidated === true,
322335
packetExecutableSmokeValidated: externalTesterPacket?.packetExecutableSmokeValidated === true || externalTesterReadiness?.checks?.packetExecutableSmokeValidated === true,
323336
packetSmokeRoutes: asArray(externalTesterPacket?.packetSmokeRoutes).map((route) => sanitizeText(route)),
337+
connectPackReadOnlyRoutes: asArray(externalTesterConnectPack?.endpoints?.readOnlyRoutes).map((route) => sanitizeText(route)),
338+
connectPackTesterWriteRoutes: asArray(externalTesterConnectPack?.endpoints?.testerWriteRoutes).map((route) => sanitizeText(route)),
324339
gatewayRoutes: asArray(publicTesterGateway?.routes).map((route) => sanitizeText(route)),
325340
ownerInputGroups: Object.fromEntries(
326341
recordEntries(

docs/agent-runs/live-product-infra-rpc/ARCHITECTURE_AUDIT.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# FlowChain Architecture Audit
22

3-
Generated: 2026-05-17T20:55:47.3747253Z
3+
Generated: 2026-05-17T21:22:59.1109076Z
44
Status: blocked
55
Blocked only on known external owner inputs: True
66

@@ -22,7 +22,7 @@ Blocked only on known external owner inputs: True
2222

2323
| Layer | Requirement | Status | Evidence |
2424
| --- | --- | --- | --- |
25-
| L1 runtime | The block-producing node and service lifecycle are separated from RPC, run in live profile, and expose fresh state evidence. | passed | serviceStatus=passed, liveProfile=True, maxBlocks=0, nodeRunning=True, controlPlaneRunning=True, latestHeight=59881, finalizedHeight=59881 |
25+
| L1 runtime | The block-producing node and service lifecycle are separated from RPC, run in live profile, and expose fresh state evidence. | passed | serviceStatus=passed, liveProfile=True, maxBlocks=0, nodeRunning=True, controlPlaneRunning=True, latestHeight=60281, finalizedHeight=60281 |
2626
| Operations | Operations has explicit status, monitor, ops snapshot, scheduled alert refresh, alert rules, escalation dry run, incident drills, and emergency controls that classify incidents separately from owner-input blockers. | passed | monitorStatus=passed, samples=2, heightAdvanced=True, supervisorValidation=passed, supervisorRestartAttempts=1, opsSnapshot=blocked, criticalCount=0, alertRules=passed, alertInstall=passed, alertInstallFailedChecks=0, escalationDryRun=passed, escalationFailedChecks=0, criticalRules=9, blockedRules=6, unmappedAlerts=0, incidentDrill=passed, incidentCases=10, incidentFailed=0 |
2727
| Operations | Owner-host service lifecycle includes a no-secret Windows Scheduled Task install, status, and uninstall path for reboot-persistent live supervisor autorecovery. | passed | installValidation=passed, failedChecks=0, planDidNotMutate=True, liveProfileDefault=True, relayerDefaultOff=True, relayerOptIn=True, schedulerCmdlets=True |
2828
| RPC/API | The control-plane API has explicit health/discovery/readiness/CORS/rate-limit validation and abuse rejection before it can be exposed publicly. | passed | validationStatus=passed, corsAllowed=True, corsRejected=True, endpointChecks=True, rateLimitProbe=True, rateLimitRejected=True, rateLimitRetryAfter=True, responseHygiene=True, abuseStatus=passed, abusePassed=True, abuseMissingChecks=0 |
@@ -41,9 +41,9 @@ Blocked only on known external owner inputs: True
4141
| Governance/safety | Owner signup checklist maps public RPC edge, tester write token/cap, always-on host, backup storage, Base 8453 RPC, bridge details, and local env-file setup to exact owner actions without requesting secrets. | passed | signupStatus=passed, itemCount=9, externalSignupCount=3, missingCoverage=0, repoOwned=True, localEnvFileSupported=True |
4242
| Security | Architecture reports and live-readiness commands preserve the no-secret and no-live-broadcast safety boundary. | passed | noSecretStatus=passed, liveProductNoLiveBroadcast=True, liveProductEnvValuesPrinted=False, baseTxBroadcasts=False, devPackNoSecrets=True |
4343
| Developer ecosystem | Developer SDK/devkit and docs connect to the real FlowChain RPC, generate a live RPC reference, read wallet data, submit a runtime-backed local wallet send, and fail closed for public readiness. | passed | devPackStatus=passed, methodCount=79, heights=43368->43369, report=E:\FlowMemory\flowmemory-live-infra-rpc\docs\agent-runs\live-product-dev-pack\dev-pack-e2e-report.json |
44-
| External tester launch | Friends-and-family tester sharing requires fresh tester-wallet evidence and executable packet-route smoke, and remains blocked until public RPC, backup, and Base bridge gates pass. | blocked | externalTester=blocked, testerNetworkFresh=True, packet=blocked, packetShareable=False, packetSmoke=True, smokeRoutes=13, externalSharingReady=False |
44+
| External tester launch | Friends-and-family tester sharing requires fresh tester-wallet evidence, executable packet-route smoke, and a machine-readable connection pack, and remains blocked until public RPC, backup, and Base bridge gates pass. | blocked | externalTester=blocked, testerNetworkFresh=True, packet=blocked, packetShareable=False, packetSmoke=True, smokeRoutes=13, connectPackReady=True, externalSharingReady=False |
4545
| External tester launch | Public tester write gateway has a local production-shaped E2E proof for bearer auth, public-only wallet creation, capped wallet sends, balance settlement, and over-cap rejection. | passed | gatewayStatus=passed, configured=True, transferAccepted=True, capRejected=True, report=E:\FlowMemory\flowmemory-live-infra-rpc\docs\agent-runs\live-product-infra-rpc\public-tester-gateway-e2e-report.json |
46-
| Verification | Product-level verification composes runtime, RPC, wallets, public tester gateway, bridge, backup, public deployment contract, executable external tester packet smoke, developer dev-pack, and completion evidence into one auditable path. | passed | liveInfra=blocked, liveProduct=blocked, externalTester=blocked, testerNetworkFresh=True, externalTesterPacket=blocked, packetSmoke=True, publicTesterGateway=passed, devPack=passed |
46+
| Verification | Product-level verification composes runtime, RPC, wallets, public tester gateway, bridge, backup, public deployment contract, executable external tester packet smoke, developer dev-pack, and completion evidence into one auditable path. | passed | liveInfra=blocked, liveProduct=blocked, externalTester=blocked, testerNetworkFresh=True, externalTesterPacket=blocked, packetSmoke=True, connectPackReady=True, publicTesterGateway=passed, devPack=passed |
4747

4848
## Data Flows
4949

0 commit comments

Comments
 (0)