Effect + Alchemy peer patterns for rat-stack
These peer patterns guide the web client, Alchemy resources, database, Better Auth16, Worker tests, and boundary enforcement. The peer roster lists the candidates and links each studied repo here. See the layer-startups decision for the choices they inform.
Pin reality
The original study base, 1c2a738, pinned Effect 4.0.0-rc.117, Alchemy 2.0.0-beta.79, and XState 6.0.0-alpha.59. Those are historical versions. packages/core/test/docs-pins.test.ts guards the version text in AGENTS.md and README.md. The Effect reference note records the versions on its 2026-09-18 study date.
At that study date, only alchemy-run/alchemy at 9802260db8f8b5a083c4b85eb7ea31ae1ff8f176 matched both Effect and Alchemy lines: its package is beta.79 and its workspace requires Effect rc.117. Maple is one Effect RC behind at rc.116 / Alchemy beta.79; T3Code is rc.115 / beta.79. OpenSEO is Effect beta.93 / Alchemy beta.61, SolStatus beta.107 / beta.72, Smithers rc.115 / beta.76, Pivot beta.103 / beta.65, and Elianiva beta.101 / beta.64. The roster includes repos on shared stack lines with different exact pins. Use older source to study shapes; check APIs before copying code.
The Oct 2 refresh found stable Effect 4 in Alchemy, effect-cf, and vitesakuga. Alchemy also moved to beta.80.
The Oct 9 refresh checks all 29 existing peers and adds 21 verified public projects. The roster records their commits, manifests, and tiers. Alchemy moves to beta.81. Several peers use stable Effect 4.0.1 or 4.0.2. rat-stack keeps Effect 4.0.0 to satisfy Foldkit21’s exact peers. Patterns below keep their original source snapshots and study dates.
XState refresh
Checked 2026-10-18 after rat-stack moves to XState 6.0.0-alpha.69 and @xstate/effect 1.0.0-alpha.8.
All 50 existing peers remain. Five verified public projects join at B. Existing tiers stay unchanged.
The roster records exact versions and pinned source10 paths.
Heb-stack: retain the lifecycle reference; reject API copying
Source: check machine.
Its catalog pins Effect 4.0.0, XState 6.0.0-alpha.63, and bridge 0.1.0-alpha.6. CHECK re-enters checking. RETRY returns from failed to checking.
The declared actor uses fromEffect.
Keep this lifecycle reference. Do not copy its actor declaration into our newer bridge API.
No implementation changes follow from this study.
Clankerbox: retain declared actors; reject the old callback form
Source: host lifecycle.
Its catalog pins Effect 4.0.5, XState 6.0.0-alpha.66, and bridge 0.1.0-alpha.7.
The lifecycle declares observe, make, start, join, stop, and remove actors in setupEffect.
These actors use fromEffect, including callback forms.
Keep the declared-actor reference. Reject direct API copying; rat-stack now uses createEffectLogic.
No new pattern is adopted.
Lute: retain the pure interaction seam
Source: player statechart.
Its player manifest pins Effect 4.0.2, XState 6.0.0-alpha.65, and bridge 0.1.0-alpha.7.
The interaction chart imports setup and types from XState and emits director commands.
Keep this pure statechart reference. It does not show how to migrate an Effect actor declaration.
No new pattern is adopted.
The local-studio and pi-cf additions have verified manifests or lockfiles, without a runtime study. The search is bounded; it does not establish that these are all public bridge consumers.
Alpha.70 gardener
Checked 2026-10-20 after XState 6.0.0-alpha.70 and bridge 1.0.0-alpha.9.
All 55 existing peers remain. Two verified public applications join at B. No existing tier changes.
The roster records default-branch commits and exact versions.
SolStatus moves to Effect 4.0.5 and Alchemy 2.0.0-beta.83. Its C tier reflects the earlier pattern study, not version alignment.
The current pkishorez catalog removes XState and its bridge. Its Effect and Alchemy integration keeps it at B.
DayBee: retain the asset Worker reference
Source: web Stack and manifest.
The manifest pins Effect 4.0.5 and Alchemy 2.0.0-beta.83.
The Stack yields a Cloudflare Worker with a static asset directory. Production alone gets the custom domain.
Keep this deployment reference at B. It adds no lifecycle pattern to adopt.
Betterwispr: retain the two-Worker reference
Source: frontend Stack and manifest.
The manifest pins Effect 4.0.0 and Alchemy 2.0.0-beta.80.
The Stack yields a server Worker and a Vite website. The website receives the server URL through an Alchemy Output.
Keep this deployment reference at B. Our private RPC binding23 remains the supported browser path; no implementation changes follow.
Sourcegraph discovery returns 255 repositories across all searched dependency families. The focused XState queries return no indexed matches, including known consumers. They do not establish that public consumers are absent. GitHub code search requires authentication. The DeepWiki pointer step is unavailable during this pass. The studies above use source files directly. Search coverage remains bounded.
The excerpt audit compares all 66 local references with their selected lines at HEAD. None differ, so no excerpt needs a new pin. The reviewed changes expose no new prohibited code pattern.
Patterns
Browser RPC behind a private Worker binding — adopt
Source: Alchemy example README, RPC schema, browser client, proxy route, Stack.
One RpcGroup declares the wire contract; the backend serves it and AtomRpc.Service turns it into module-scope34 query and mutation atoms for React. The browser calls a same-origin TanStack /rpc route, which forwards to a private BACKEND service binding23; the backend has no public Workers URL.
Adopt this for the web bin. Keep capability schemas in packages/core, the toRpc projection in packages/capability, and UI atoms in the web app.
One schema-derived contract carries payloads and typed failures39 across the wire. The binding23 keeps the backend private.
All browser operations go through toRpc and the same /rpc transport. Keep hand-written domain routes out.
PlanetScale resources and migrations — adapt
Source: T3Code relay database at f5ef0ddb90a8c36584e181b1913e7b8a5df30ffc (Effect rc.115, Alchemy beta.79).
T3Code makes Drizzle.Schema the migration source, then provisions a PlanetScale database or stage branch, a runtime role, and a Hyperdrive connection from that role’s origin. Production retains the shared database; non-production stages use branches. This is the closest inspected resource graph to rat-stack’s planned PlanetScale Postgres Layer.
Adapt this for the database cartridge38. The vendor Layer should own its schema, migration path, role, and Hyperdrive binding23.
Use Alchemy Outputs and typed bindings for connection strings. Keep provider-specific Drizzle details behind the database service tag.
Choose D1 or PlanetScale once with Layer.provide. Keep T3Code’s stage-mode branch out of domain code.
Effect-native Drizzle and local Postgres tests — adapt
Source: Maple’s packages/db/src/client.ts, pglite.ts, and migrate.ts at e7bc2d97bea87c99c8b9b33f377956e923d04373 (Effect rc.116, Alchemy beta.79).
Maple builds Drizzle over @effect/sql-pg, opens the client inside an Effect Scope, and uses PGlite plus the same bundled migrations for local and test paths. Its exported MapleDb remains Postgres-specific. Use the driver implementation and test technique behind a provider-neutral database contract.
Adapt this for the database cartridge38. Keep the public repository-shaped database service small and let each vendor Layer implement it. Scope clients to one invocation. Use a real embedded database for migrations and query tests. Keep Drizzle’s driver type behind the cross-provider API. Share migration fixtures and the service contract. D1 and Postgres keep their own schemas and implementations.
Better Auth’s database seam — adopt
Source: Alchemy’s Database.ts, CloudflareD1.ts, CloudflareHyperdrive.ts, BetterAuth.ts, and example Worker.
@alchemy.run/better-auth@2.0.0-beta.79 makes Database a service supplied by provider-specific Layers, and BetterAuth consumes that service. D1 uses a runtime Worker binding and a separate deploy-time migration connection; Hyperdrive accepts the origin URL for migrations because its runtime connection is minted per invocation, and the integration scopes auth/database work to that execution.
Adopt the official Better Auth integration. It is a separately published Alchemy package with provider subpaths, so rat-stack can use it without forking an adapter.
Its API and migration failures are typed. Database clients are scoped, and the caller supplies one database Layer.
Use one BetterAuth service with the database cartridge’s selected Layer. Keep runtime D1/Postgres switching out of auth code.
Runtime database-provider switching — reject
Source: OpenSEO’s auth.ts, provider.ts, pg/client.ts, and alchemy.run.ts at 0ffff93101043aad7600a3b6a499a0cd2887ef49 (Effect beta.93, Alchemy beta.61).
OpenSEO constructs Better Auth directly and selects either a D1 Drizzle adapter or a Postgres adapter by reading DATABASE_PROVIDER at runtime. Its Postgres client is created inside an AsyncLocalStorage request scope and reaches the database through Hyperdrive, but the auth and schema code still branch on provider.
Reject the selector and retain the request-scope invariant. The branch ties auth to both database implementations; either database Layer should plug into one contract.
An environment string chooses the driver at runtime, outside the Schema/Layer boundary.
Keep the per-request Hyperdrive lifetime. Move provider choice to one Layer.provide at composition.
Fast Worker and Durable Object tests — adopt
Source: Maple’s worker-bridge.test.ts, ChatSessionObject.test.ts, and fake-do-state.ts, same Maple commit as above.
The bridge test invokes Alchemy’s Cloudflare.Workers.makeRequestHandler and checks the request scope, Worker environment, and response. Durable Object tests give the class a narrow fake state backed by real node:sqlite, including SQL storage, alarms, and waitUntil; they exercise object behavior without pretending to be a full workerd runtime.
Adopt this for fast tests alongside real-runtime tests. Keep fixtures beside the Worker or database cartridge that owns them. Real SQL catches query and storage drift. The narrow fake fails when tests ask for an unsupported state operation. Use the Alchemy bridge for deterministic Worker tests. Keep a separate integration test for real service bindings and deployed behavior.
D1 fixture backed by SQLite — adapt
Source: Smithers’ worker/test/d1.ts and action-cache.test.ts at 38846c64dd322d61e67efafadac1fbd9d34df64f (Effect rc.115, Alchemy beta.76).
The test adapter runs shipped SQL migrations against node:sqlite, implements only the D1 calls the code uses, and throws on every unsupported method. That makes it a useful D1 unit-test boundary, but it does not prove Cloudflare’s D1 binding or runtime behavior.
Adapt this for D1 cartridge tests. Expose a test Layer or helper from the D1 package. Keep it local to D1 rather than creating a repo-wide mock database. Unsupported calls fail loudly. Use this for local SQL behavior and the Alchemy integration gate for binding behavior.
Deployed Alchemy integration tests — adopt as a separate gate
Source: Alchemy’s test/integ.test.ts at 9802260db8f8b5a083c4b85eb7ea31ae1ff8f176.
The example’s alchemy/Test/Bun harness deploys the Stack before tests, retries readiness, sends CRUD calls through the /rpc proxy into the database, verifies a tagged failure crosses the wire, and destroys the Stack afterward. This is the closest inspected example of the real-resource integration path called for in VISION.md, but its Bun runner is not a fit for rat-stack’s pnpm test stack.
Adapt this as a separate credentialed integration gate. Keep fast unit tests uncredentialed.
The integration suite belongs to the Stack and can be removed with it. It proves the full binding, wire, and database path.
Port the deploy/test/destroy lifecycle into a pnpm-compatible harness. Keep alchemy/Test/Bun out.
Boundary tests and agent guidance — adapt
Source: Maple’s vendor-isolation.test.ts and CLAUDE.md, same Maple commit.
The test scans explicitly named generic roots and files to keep chat-vendor names inside connector directories, and checks that guarded roots are non-empty and guarded files still exist. The guidance makes app, product-package, and vendor-neutral-library ownership explicit; it also says services capture implementation dependencies and keep request context invocation-scoped.
Adapt the proof. Maple’s lexical vendor-name scanner is product-specific; rat-stack needs checks for its own package ownership and adapter isolation. Encode the capability-only surface25 rule in a test or type-aware lint rule. Check that guarded paths exist and contain files. Extend the current capability fence45 rather than adding a second generic source-scanning framework.
Scoped actor inspection and generated model commands — adapt
Source: beep-effect at a7644af785843bb42546109272970f2f7a82b1d7: catalog, driver manifest, inspector service, test bridge.
Checked Oct 2. Its catalog selects XState alpha.63 and bridge alpha.5. Effect comes from a pkg.pr.new build at b5a2d4c1d62c9620a68d72b7f20248c69ef7663b. That source manifest declares 4.0.0; the installed build’s semver was not verified. It shares a stack line; an exact release match remains unverified.
The inspector has a disabled production Layer. Its enabled Layer owns the inspector, and attach acquires an actor subscription whose finalizer unsubscribes. The test bridge derives event arbitraries from schemas and projects a snapshot’s value and context for model comparisons. Its actor SUT opens a scope and closes it on disposal.
Adapt the lifetime checks. Keep watchActor and ActorWatch in devtools7 as our single inspection path. A second Stately service would bypass that fence. The helper runs tests through ManagedRuntime, which our test fence forbids. Use it.effect.prop and generated command sequences instead of copying its runtime bridge. No production code was adopted.
Verify Foldkit’s exact Effect peers: adopt
Source: Hazel at 2504baa1ab85d7966152a615a08dc0d4af4c1f69: catalogs, Foldkit client, lockfile.
The upstream manifests at 49dc36ef672d1caee23f153f88c09d98c8241670 confirm the boundary: Foldkit and Vite plugin.
Checked Oct 9. Does the shared catalog satisfy Foldkit’s exact Effect peers?
- The catalog selects Effect 4.0.1 and Alchemy beta.80.
- The client selects Foldkit 0.167.0 and uses that Effect catalog.
- The lockfile records Foldkit’s exact Effect 4.0.0 peer.
- The Vite plugin also requires Effect 4.0.0 and depends on platform-node 4.0.0.
Adopt the manifest and lockfile check. Keep Effect 4.0.0 until Foldkit publishes compatible peers and platform dependencies. Do not copy the newer Effect catalog. This study changes no runtime adapter or UI code.
Template lifetime boundaries: adopt
Source: architecture and manifest at 04851db8649501bfaf8d2712429074ba0290a10f.
The source assigns each resource to an application, request, tenant, session, or execution. It acquires request capabilities at the request boundary.
rat-stack already adapts this guidance in cache completed values8, UI tests, and opt-in tracing. PROVENANCE.md records the source and license confirmation.
Keep those lifetime boundaries. The template uses Effect 4.0.0 and Alchemy beta.81, with Foldkit 0.165.0. Its package-manager defaults do not replace pnpm here. This refresh records the existing adoption. It copies no new implementation.
Other screened projects
jonbeckman/solstatus at 83b3e2f4400aa7a2f2f4b738334e0cf91dbf15f5 has Alchemy Cloudflare.Website.Vite, D1, and direct Better Auth, but pins Effect beta.107 / Alchemy beta.72; its runtime is too old to copy. elianiva/elianiva.com at 5799fcb6b5ddc48e1df0223f23a9a15da8d097ae also has a Website.Vite Stack, but uses Effect beta.101 / Alchemy beta.64 and adds no stronger pattern than the current Alchemy example. 13kparkin/Pivot at 1887824d1f96ea6b601fffbc283b836967d32a5c shows PlanetScale/Hyperdrive but uses Effect beta.103 / Alchemy beta.65; T3Code’s newer PlanetScale graph supersedes it for this decision.
Symbol-screened without a relevant client/resource pattern: Dhravya/radish, zonko-ai/harbor-sdk, dmmulroy/overseer, instructa/planr, and statelyai/agent. cameronapak/dotflowy has Better Auth but no Alchemy integration and uses Effect rc.115 / XState alpha.12, so it is not a useful match for this lane. The earlier Effect reference note already covers the XState bridge; this note does not repeat it.
Weekly peers Oct 27
The refresh checks default-branch commits on October 27. No implementation is adopted. DeepWiki is unavailable in this session. The three questions below use commit-pinned source directly.
Session publication: keep the existing boundary
Question: How does omp-agent-mesh distinguish local work from publication failure?
Its session machine declares announce, publishStatus, and depart actors.
The idle and working states each contain publication states. Publication failure enters unsynced and retains the typed failure.
Its manifest pins Effect 4.0.6, XState alpha.70, and bridge alpha.9.
Keep this as a current bridge reference. Do not copy a second publication model into rat-stack without a matching domain need.
Local preparation: keep the existing actor seam
Question: How does durable-pi separate local cancellation from durable execution?
Its preparation reference invokes a declared Effect actor. The machine owns cancellation and deadline transitions. The architecture decision separates local scope cleanup from remote cancellation confirmation. Its manifest pins Effect 4.0.5, XState alpha.68, and bridge alpha.8.
Keep the local lifetime example as a study reference. Do not infer durable execution guarantees from the local actor. No durable adapter is copied.
Worker reconciliation: reject direct reuse on the older bridge
Question: Where does ceirean handle uncertain worker outcomes?
Its worker lifecycle separates readiness, execution authorization, and reconciliation states. Mutation failures can route to reconciliation. Its manifest pins Effect 4.0.5, XState alpha.64, and bridge alpha.6.
Keep the state separation as a reference. Direct reuse requires a bridge migration and behavior checks. No worker implementation is copied.
Existing peer corrections
Clankerbox now declares createEffectLogic actors on bridge alpha.9. Its current lifecycle no longer supports the roster’s older fromEffect warning.
The refresh preserves its tier B and updates that reason from current source.
GitHub redirects danieljvdm/effect-agent to yielded-dev/agent and the Foldkit template to just-be-dev/cafe-stack.
The roster uses those canonical names and keeps both first-seen dates and tiers.
Recommendations from the September study
These recommendations record the original study. The current web bin uses Foldkit; current pins come from manifests.
- TanStack web bin: generate the browser client from capability Schemas as one
RpcGroup, create module-scopeAtomRpcatoms, and forward same-origin/rpcto a privateRpcWorkerbinding. - Better Auth: use
@alchemy.run/better-auth@2.0.0-beta.79; provide the database cartridge’s Layer and keep auth API/migration failures typed. - Database cartridge: expose one repository-shaped service tag; let D1 and PlanetScale/Hyperdrive Layers own schemas, migrations, and bindings; choose with one
Layer.provide. - Worker tests: add
makeRequestHandlerand SQLite-backed DO/D1 fixtures for fast tests, plus one credentialed Alchemy deploy/test/destroy gate using a pnpm-compatible harness. - Capability fence: test or lint that every surface, including
toRpc, originates from the capability registry27; make the test prove its guarded paths exist and contain files.
Last changed 2026-10-27 in 49994c9. Source on GitHub. Change log.
Linked from
- find-peers. Refresh public peers, exact stack versions, and tiers after stack bumps. On gardener passes, refresh peers checked more than 14 days ago without blocking other work.
Record adoptions and rejections, with the reason, in .brain/resources/same-version-repos.svx, and link that entry from the peer’s Studied column.¶