1# Railway GraphQL migration verification
2
3The providers use `@distilled.cloud/railway`. Every operation is a
4`Query.fn` whose builder reads only the fields it needs; shared projection
5functions describe resource attributes, and reconcile plans add only fields
6needed for decisions. Nested connection helpers in `src/Railway/GraphQL.ts`
7take a projection function and paginate all results with `Query.items`.
8Service listing walks actual environment service instances instead of
9probing every service/environment combination.
10
11The SDK's [client guide](../../../../submodules/distilled/packages/railway/README.md)
12describes `Query.fn` plans, pagination, per-root typed errors, and retry
13behavior. Its [patch evidence](../../../../submodules/distilled/packages/railway/patches/graphql/README.md)
14records observed wire errors and the contracts generated from them.
15
16## Run isolated live tests
17
18Use a dedicated project and stage when another worktree might be testing
19Railway. The final component of the project name must follow Alchemy's
20physical-name suffix rules; `graphqltest` is a valid suffix.
21
22```sh
23timeout -k 5 240 doppler run --project alchemy-v2 --config dev -- \
24 env ALCHEMY_TEST_STAGE=test_graphql_f9c5 \
25 RAILWAY_TEST_PROJECT_NAME=alchsuite-graphqltest \
26 pnpm test test/Railway/Postgres.test.ts \
27 --profile testing --retry 0 --concurrency 1
28```
29
30Tests own separate environments within the project. Use bounded batches;
31the command's deadline is a failure, not a reason to repeat it blindly.
32Credentials come from the configured profile/environment and never belong
33in test output or fixtures. The dedicated project can be removed after all
34of its tests finish; do not remove another worktree's shared suite project.
35
36## Live flywheel findings
37
38Verified during the September 12, 2026 migration:
39
40The run records 52 distinct passing live Railway checks. After standardizing
41deletion confirmation, the final affected batches pass 17 lifecycle checks
42(two documented gates) and all three database CRUD checks again.
43
44- Project, environment, variable, group, service, domain, TCP proxy, usage,
45 login session, audit log, cloud agent, and sandbox test paths use selective
46 operations. Entitlement probes retain exact tagged failures.
47- Bucket CRUD and S3 object round trips pass. Credential creation can lag
48 bucket creation; its exact observed failure is patched and readiness is
49 bounded.
50- Private-network CRUD/rename and template deployment/list/delete regressions
51 are enabled and pass. Network identifiers accept the actual BigInt wire
52 representation. Inaccessible template metadata stays optional.
53- Mongo, MySQL, Postgres, and Redis CRUD, query/ping, update, listing, and
54 deletion pass. Mongo and MySQL deployed Service integrations pass.
55 Postgres's deployed Service and Function SQL integrations pass. The MySQL
56 fixture uses an exact dependency record to avoid ambiguous lockfile versions.
57- Function canvas lifecycle and async HTTP lifecycle pass. Owned services
58 are deleted globally; deleting only an environment instance and waiting
59 for the whole service to disappear was an incorrect convergence check.
60- Redis and bucket bindings pass deployed runtime round trips.
61- CDN create/update/disable passes direct selective read-back assertions.
62 It waits for a public domain to be ready and sends Railway's lowercase
63 HTML-caching values. A pathless generic failure is classified without
64 inventing a field-specific cause or an entitlement restriction.
65- Thirteen website/CDN cases pass: Astro, CDN, Next.js, Nuxt,
66 Octane, React Router, SolidStart, StaticSite, SvelteKit, TanStack Start,
67 Vite, Vocs, and Waku. This covers deployment, HTTP serving, and deletion;
68 the dedicated CDN case also checks update and disablement.
69
70The Postgres runtime check also exposed a shared SQL-driver compatibility
71issue: Railway URLs use `sslmode=no-verify`, which Effect's parser rejects.
72`SQL/PostgresTls.ts` normalizes the URL and explicit TLS options together,
73preserving caller overrides and redacted credentials. SNI is now handled by
74the upstream driver. A parser-level local
75regression covers this without opening a network connection.
76
77## Local verification
78
79```sh
80bun test submodules/distilled/packages/core/src/graphql.test.ts \
81 submodules/distilled/packages/core/src/codegen/graphql-client.test.ts \
82 submodules/distilled/packages/railway/test/graphql.test.ts
83pnpm exec tsc -b
84timeout -k 5 240 pnpm test test/SQL/PostgresTls.test.ts --profile testing
85timeout -k 5 60 pnpm test test/Railway/GraphQL.local.test.ts --retry 0 --sequential
86pnpm docs:gen
87pnpm docs:check-jsdoc
88```
89
90The GraphQL suites cover selected result/error types, aliases, fragments,
91partial responses, multiple simultaneous errors, null propagation, variables,
92pagination, scalar validation, generated symbol collisions, and deterministic
93regeneration. The migration run passes 64 GraphQL tests and 12 TLS tests;
94four virtual-clock deletion tests prove that exhausted polling fails explicitly
95and preserves typed query errors. The full workspace type-check and JSDoc
96check pass.
97
98These results were recorded on Effect rc.113 before rebasing onto the rc.115
99upgrade in main. The rebase preserves upstream removal of the SNI shim and
100adapts the no-verify normalization tests. The rc.115 results below supersede
101that earlier validation record.
102
103## Single-invocation verification on Effect rc.115
104
105Both Foldkit tests are explicitly skipped for the fixture's incompatible Effect
106API. The complete Railway directory was then selected in one invocation:
107
108```sh
109timeout -k 5 240 doppler run --project alchemy-v2 --config dev -- \
110 env ALCHEMY_TEST_STAGE=test_graphql_whole \
111 RAILWAY_TEST_PROJECT_NAME=alchsuite-graphqlwhole \
112 pnpm test test/Railway --profile testing --retry 0 --concurrency 8 --sequential
113```
114
115The runner collected 55 files / 85 tests. At the 240-second deadline it had
116recorded **64 passed, 5 failed, 9 skipped, and 7 unfinished**; the command
117exited 124. This was not a complete run or a passing suite.
118
119- Group creation and the canvas Function lifecycle failed on
120 `GraphQLTransportError` with HTTP 503 and a non-GraphQL response.
121- The bindings fixture's `beforeAll` failed on the same HTTP 503, preventing
122 its three tests from running; the runner counted them as failures.
123- Template deployment/list/delete passed in the shared single-process run.
124- SolidStart, StaticSite, SvelteKit, TanStackStart, Vite, Vocs, and Waku cloud
125 tests were still running at the deadline; they have no final outcome.
126- Nine skips comprise both Foldkit tests and the seven pre-existing gates
127 described below. No additional tests were disabled.
128
129The preceding complete rc.115 run in separate batches recorded 74 passed,
1304 failed, and 7 skipped. Those failures were both Foldkit tests, template
131service discovery, and StaticSite domain creation. Its separate SDK and TLS
132checks passed 64 and 9 tests respectively. The workspace type-check reported
133three AWS SigningError contract mismatches in DbAuthToken and S3 presigning.
134
135## Explicit coverage limits
136
137- Three existing Effect-native Function/RPC cases exceed the canvas command's
138 96 KiB limit and remain skipped. The smaller Function and runtime binding
139 cases above are exercised.
140- Backup entitlement, connected GitHub repositories, and external ACME DNS
141 require their documented test environment variables.
142- Foldkit's local and cloud tests explicitly use `test.provider.skip`:
143 installed `foldkit@0.148.2` requires `SchemaTransformation.transformOrFail`,
144 which is unavailable in the workspace's Effect rc.115. Re-enable both
145 when the fixture is compatible with the workspace Effect version.
146- The existing Vocs local test remains skipped for its fixture cwd issue.
147
148These limits must not be reported as passing live coverage.