Add Effect-native rewrite audit playbook

This commit is contained in:
elpresidank 2026-06-01 22:00:28 -05:00
parent b58e51bf75
commit 7f81c56c80
2 changed files with 492 additions and 0 deletions

View file

@ -0,0 +1,305 @@
# TrustGraph Effect-Native Rewrite Opportunity Audit
This is the first ranked audit produced from the playbook in
`ts/EFFECT_NATIVE_REWRITE_PLAYBOOK.md`. It is an opportunity map, not a code
rewrite. The branch was `ts-port-effect-v4`; the only unrelated local file seen
during the audit was `.idea/effect.intellij.xml`.
## Inputs
Verified source roots:
- TrustGraph TS port: `/home/elpresidank/YeeBois/dev/trustgraph/ts`
- Effect v4 subtree: `/home/elpresidank/YeeBois/projects/beep-effect2/.repos/effect-v4`
- Reactivity fallback: `ts/node_modules/effect/src/unstable/reactivity`
- Atom React fallback: `ts/packages/workbench/node_modules/@effect/atom-react`
Signal counts from `ts/packages`:
| Signal | Count |
| --- | ---: |
| `Effect.runPromise` | 71 |
| `Map<` | 54 |
| `JSON.stringify` | 50 |
| `WebSocket` | 45 |
| `process.env` | 44 |
| `new Map` | 42 |
| `toPromiseRequestor` | 19 |
| `makeAsyncProcessor` | 19 |
| `new Promise` | 18 |
| `JSON.parse` | 16 |
| `receive(` | 16 |
| `setTimeout` | 13 |
| `while (` | 10 |
| `localStorage` | 8 |
## Ranked Findings
### P0: Collapse Base Messaging Promise Facades
- Impact: 5
- Risk: 4
- Confidence: 4
- TrustGraph evidence:
- `ts/packages/base/src/messaging/runtime.ts` already defines Effect
producer, consumer, request/response factories, queues, fibers, and scopes.
- `ts/packages/base/src/messaging/consumer.ts` still has a manual
`while (running)` receive loop, `sleep`, and Promise delay helpers.
- `ts/packages/base/src/messaging/subscriber.ts` still manages resolver maps
and timeout promises.
- `ts/packages/base/src/processor/flow.ts` exposes compatibility scope
helpers and converts Effect handles back into Promise-style handles.
- Effect evidence:
- `effect/Queue`, `effect/PubSub`, `effect/Stream`, `effect/Scope`,
`effect/Layer`, `effect/Schedule`, `effect/Ref`.
- Sources: `packages/effect/src/Queue.ts`, `PubSub.ts`, `Stream.ts`,
`Scope.ts`, `Layer.ts`, `Schedule.ts`, `Ref.ts`.
- Rewrite shape:
- Make the Effect runtime factories the canonical internal surface.
- Keep Promise adapters only at external compatibility boundaries.
- Replace polling sleep loops with scheduled scoped consumers where possible.
- Replace resolver maps with `Queue`, `Deferred`, or `PubSub`-backed routing.
- Tests:
- `cd ts && bun run --cwd packages/base test`
- Existing runtime tests around request/response, flow specs, and consumers
should be expanded before removing compatibility behavior.
- Blockers:
- Public package exports may still expect Promise-shaped producer, consumer,
and request/response handles. Inventory callers before changing exports.
### P0: Convert Stateful Flow Services To Scoped Effect Services
- Impact: 5
- Risk: 4
- Confidence: 4
- TrustGraph evidence:
- `ts/packages/flow/src/config/service.ts` uses `makeAsyncProcessor`,
mutable nested `Map` state, `while (this.running)`, `receive(2000)`,
`sleep`, JSON persistence, and direct `process.env`.
- `ts/packages/flow/src/librarian/service.ts`, `cores/service.ts`, and
`flow-manager/service.ts` repeat the same service-object pattern.
- Effect evidence:
- `Context`, `Layer.scoped`, `Ref`, `SynchronizedRef`, `Schedule`,
`Effect.addFinalizer`, `Config`, `Schema`, `effect/FileSystem`,
`effect/unstable/persistence/KeyValueStore`.
- Sources: `packages/effect/src/Context.ts`, `Layer.ts`, `Ref.ts`,
`SynchronizedRef.ts`, `Schedule.ts`, `Config.ts`, `Schema.ts`,
`ts/node_modules/effect/src/FileSystem.ts`,
`ts/node_modules/effect/src/unstable/persistence/KeyValueStore.ts`.
- Rewrite shape:
- Model each service as a `Context` service plus a scoped layer.
- Store service state in `Ref` or `SynchronizedRef`, not mutable object fields.
- Express persistence with `effect/FileSystem` or
`KeyValueStore.layerFileSystem` when the installed beta exposes the needed
provider.
- Decode persisted payloads and config with schemas at boundaries.
- Tests:
- Service-specific tests plus `cd ts && bun run --cwd packages/flow test`.
- Add persistence round-trip tests before replacing file IO.
- Blockers:
- These services are behavior-heavy. Do one service per PR after the shared
runtime surface is stable.
### P0: Make Gateway Dispatcher Effect-Native
- Impact: 5
- Risk: 3
- Confidence: 4
- TrustGraph evidence:
- `ts/packages/flow/src/gateway/server.ts` already builds RPC/WebSocket
pieces with Effect.
- `ts/packages/flow/src/gateway/rpc-server.ts` uses `Queue` and RPC layers.
- `ts/packages/flow/src/gateway/dispatch/manager.ts` still keeps
`Map<string, Promise<RequestResponse<unknown, unknown>>>`, manual
streaming completion checks, and per-publish producer construction.
- Effect evidence:
- `effect/unstable/rpc` `RpcClient`, `RpcServer`, `RpcSerialization`.
- `effect/unstable/socket` `Socket`.
- `effect/Queue`, `Stream`, `Scope`, `Layer`.
- Sources: `ts/node_modules/effect/src/unstable/rpc/RpcClient.ts`,
`RpcServer.ts`, `RpcSerialization.ts`, and
`ts/node_modules/effect/src/unstable/socket/Socket.ts`.
- Rewrite shape:
- Convert dispatcher manager methods to Effect-returning functions internally.
- Cache requestors as scoped resources instead of Promise values.
- Represent streaming dispatch as `Stream` or `Queue` instead of callback
completion detection where the wire protocol allows it.
- Keep Fastify route handlers as Promise boundaries.
- Tests:
- Gateway dispatch tests with fake pubsub.
- `cd ts && SKIP_LLM=1 bun run test:pipeline` after implementation.
- Blockers:
- The gateway is an integration boundary. Preserve current HTTP and WebSocket
wire behavior during the first rewrite.
### P1: Remove RAG And Agent `toPromiseRequestor` Bridges
- Impact: 4
- Risk: 3
- Confidence: 5
- TrustGraph evidence:
- `ts/packages/flow/src/retrieval/document-rag-service.ts`
- `ts/packages/flow/src/retrieval/graph-rag-service.ts`
- `ts/packages/flow/src/agent/react/service.ts`
- All define `toPromiseRequestor` and then immediately adapt Effect
requestors back to Promise-style clients.
- Effect evidence:
- Existing TrustGraph `EffectRequestResponse` in
`ts/packages/base/src/messaging/runtime.ts`.
- `effect/Stream`, `Effect.fn`, `Effect.runPromiseWith` for boundary-only
execution.
- Rewrite shape:
- Update RAG engines and agent helpers to accept Effect requestors or
functions returning `Effect`.
- Keep Promise wrappers only for old public APIs or tests that explicitly
verify compatibility.
- Convert streaming agent flows to `Stream` where possible.
- Tests:
- Existing RAG and agent service tests.
- Add tests that assert requestor errors stay typed through the Effect path.
- Blockers:
- Engine call signatures need a small design pass so RAG and agent rewrite in
the same direction.
### P1: Finish Client RPC Boundary Modernization
- Impact: 4
- Risk: 3
- Confidence: 4
- TrustGraph evidence:
- `ts/packages/client/src/socket/effect-rpc-client.ts` already uses
`Socket.makeWebSocket`, `RpcClient.layerProtocolSocket`, and
`RpcSerialization.layerNdjson`.
- The same file still owns `scopePromise`, `clientPromise`, repeated
`Effect.runPromise`, listener sets, a WebSocket constructor shim, and a
Promise facade.
- `ts/packages/client/src/socket/trustgraph-socket.ts` is mostly a
compatibility API over the Effect RPC client.
- Effect evidence:
- `effect/unstable/socket/Socket`: `makeWebSocket`, `fromWebSocket`,
`toChannel`, `layerWebSocket`.
- `effect/unstable/rpc/RpcClient`: `layerProtocolSocket`.
- `effect/unstable/rpc/RpcSerialization`: `layerNdjson`, `layerNdJsonRpc`.
- Rewrite shape:
- Treat `EffectRpcClient` as an internal managed runtime or scoped layer.
- Expose Promise-returning methods only through a thin compatibility adapter.
- Move browser vs Node WebSocket constructor selection into platform layers.
- Tests:
- `cd ts && bun run --cwd packages/client test`
- Keep timeout/retry tests around `withDispatchRequestPolicy`.
- Blockers:
- Workbench and CLI still consume Promise-shaped client APIs.
### P1: Make SDK, Storage, And Provider Layers Managed Resources
- Impact: 4
- Risk: 3
- Confidence: 3
- TrustGraph evidence:
- `ts/packages/flow/src/storage/triples/falkordb.ts`
- `ts/packages/flow/src/storage/embeddings/qdrant-graph.ts`
- `ts/packages/flow/src/storage/embeddings/qdrant-doc.ts`
- `ts/packages/flow/src/model/text-completion/*.ts`
- These files create direct SDK clients and read `process.env` in live
constructors.
- Effect evidence:
- `Effect.acquireRelease`, `Layer.scoped`, `Config`, `ConfigProvider`,
`effect/FileSystem`, `effect/unstable/persistence/KeyValueStore`,
`Metric`, `Logger`.
- AI provider modules from installed provider packages, with subtree source
proof under `packages/ai/*/src`, including `OpenAiLanguageModel.ts`,
`AnthropicLanguageModel.ts`, and `OpenRouterLanguageModel.ts`.
- Rewrite shape:
- Move env reading into `Config` loaders and provider-specific layers.
- Scope SDK clients that need explicit close/disconnect.
- Replace `console` or ad hoc logging with `Effect.log*` and metrics where
useful.
- Tests:
- Provider config tests with `ConfigProvider.fromMap`.
- Storage tests with fake clients before changing real resource lifetimes.
- Blockers:
- Some third-party SDK clients may not have meaningful finalizers. Mark those
no-op after proof instead of forcing fake lifecycle code.
### P2: Canonicalize MCP Around The Effect Server
- Impact: 3
- Risk: 2
- Confidence: 5
- TrustGraph evidence:
- `ts/packages/mcp/src/server.ts` is the old SDK/Zod server.
- `ts/packages/mcp/src/server-effect.ts` has Effect AI tools, schemas,
`McpServer`, HTTP API integration, and provider layers.
- Effect evidence:
- `effect/unstable/ai` `Tool`, `Toolkit`, `McpServer`, `McpSchema`,
`LanguageModel`.
- Sources: `ts/node_modules/effect/src/unstable/ai/Tool.ts`,
`Toolkit.ts`, `McpServer.ts`, `McpSchema.ts`, `LanguageModel.ts`.
- Rewrite shape:
- Do not rewrite the Effect server from scratch.
- Make the Effect server canonical after parity checks.
- Keep the old server only as compatibility or delete it once entrypoints and
tests prove the Effect path is complete.
- Tests:
- MCP package build/test.
- Tool parity diff against `server.ts` before removal.
- Blockers:
- Needs a policy decision about old SDK server lifetime.
### P2: Tighten Workbench Platform And Reactivity Usage
- Impact: 3
- Risk: 2
- Confidence: 4
- TrustGraph evidence:
- `ts/packages/workbench/src/atoms/workbench.ts` already uses Atom,
AsyncResult, Reactivity, browser layers, and metrics.
- Remaining direct browser state includes `localStorage` reads/writes and DOM
theme inspection.
- Effect evidence:
- `BrowserKeyValueStore.layerLocalStorage`,
`BrowserKeyValueStore.layerSessionStorage`, `BrowserHttpClient`,
`Clipboard`.
- `AtomRpc`, `AtomHttpApi`, `AtomRegistry`, `AsyncResult`, `Reactivity`.
- Rewrite shape:
- Leave the workbench out of the first rewrite wave.
- Later, move persistent UI state through `BrowserKeyValueStore` and keep
remote state in Atom RPC/HTTP API families if the client API becomes fully
typed Effect RPC.
- Tests:
- `cd ts && bun run workbench:qa`.
- Blockers:
- Workbench is already the most modern surface. Backend/runtime wins should
happen first.
## Recommended PR Order
1. Base messaging/runtime convergence design and tests.
2. Gateway dispatcher internal Effect conversion.
3. RAG and agent requestor bridge removal.
4. One stateful Flow service conversion, starting with config or cores.
5. Client compatibility facade tightening.
6. Storage/provider managed resource cleanup.
7. MCP canonicalization and Workbench polish.
## No-Op Rules
Do not flag these as rewrite blockers without additional proof:
- Promise-returning CLI actions and Fastify route handlers at external
boundaries.
- `S.Class`, `S.TaggedErrorClass`, `Context.Service`, `Rpc.make`, and
`HttpApi.make` when they are required or idiomatic for the Effect API.
- Plain `Map` usage for local pure transformations, such as graph utility
construction, unless the state is long-lived, mutable service state.
- JSON stringification that is part of the TrustGraph wire contract, unless a
schema codec can preserve the exact encoded form.
## Acceptance
This audit is complete when:
- `ts/EFFECT_NATIVE_REWRITE_PLAYBOOK.md` exists.
- This ranked audit exists and cites concrete TrustGraph and Effect surfaces.
- `git diff --check` passes for both files.
- No code rewrite is mixed into this audit.

View file

@ -0,0 +1,187 @@
# TrustGraph Effect-Native Rewrite Playbook
This playbook is the context packet for read-only sub-agents that audit the
TrustGraph TypeScript port for code that hand-rolls behavior already provided by
Effect v4. It is not an implementation plan for a single rewrite. Its job is to
make future scouts fast, grounded, and allergic to invented APIs.
## Source Baseline
Verify these paths at the start of every audit run:
- TrustGraph TS port: `/home/elpresidank/YeeBois/dev/trustgraph/ts`
- Effect v4 subtree: `/home/elpresidank/YeeBois/projects/beep-effect2/.repos/effect-v4`
- Installed Effect fallback: `ts/node_modules/effect`
- Installed Atom React fallback: `ts/packages/workbench/node_modules/@effect/atom-react`
The prompt typo path `~/YeeBois/projecects/...` is not valid on this machine.
Use `~/YeeBois/projects/...`.
When a package is not present in the subtree, verify it from TrustGraph's
installed package sources before proposing a replacement. This matters for
`effect/unstable/reactivity`, `effect/unstable/ai`, `effect/unstable/rpc`,
`effect/unstable/socket`, `effect/unstable/http`, `effect/unstable/httpapi`,
and `@effect/atom-react`.
Important import rule: the Effect v4 subtree contains separate packages such as
`@effect/ai`, `@effect/rpc`, and `@effect/platform`, but TrustGraph currently
resolves many beta APIs through `effect/unstable/*` import paths. Prefer the
installed TrustGraph import path when it exists; use the subtree package path as
source proof, not as an automatic import recommendation.
## Primitive Map
Use this map as the starting baseline. A finding is only valid when it cites the
TrustGraph path, the import path, and the Effect source path that proves the
primitive exists.
| Handrolled pattern | Preferred Effect primitive | Import path | Verified source |
| --- | --- | --- | --- |
| Promise loops, top-level async orchestration | `Effect`, `Effect.fn`, `Effect.scoped`, `Effect.runPromiseWith` at boundaries | `effect` | `packages/effect/src/Effect.ts` |
| Resource construction and teardown | `Layer`, `Scope`, `Effect.acquireRelease`, `Effect.addFinalizer` | `effect` | `packages/effect/src/Layer.ts`, `packages/effect/src/Scope.ts` |
| Mutable service state | `Ref`, `SynchronizedRef`, `SubscriptionRef` | `effect` | `packages/effect/src/Ref.ts`, `packages/effect/src/SynchronizedRef.ts` |
| Polling, delays, retry/backoff | `Schedule`, `Effect.sleep`, `Effect.retry` | `effect` | `packages/effect/src/Schedule.ts`, `packages/effect/src/Effect.ts` |
| Callback queues and streaming fanout | `Queue`, `PubSub`, `Stream`, `Channel` | `effect` | `packages/effect/src/Queue.ts`, `packages/effect/src/PubSub.ts`, `packages/effect/src/Stream.ts`, `packages/effect/src/Channel.ts` |
| Env/config decoding | `Config`, `ConfigProvider`, platform config providers | `effect`, `effect/ConfigProvider`, provider packages | `packages/effect/src/Config.ts`, `packages/effect/src/ConfigProvider.ts`, `packages/platform/src/PlatformConfigProvider.ts` |
| JSON/wire schemas | `Schema`, `ParseResult`, `RpcSchema` | `effect/Schema`, `effect/unstable/rpc/RpcSchema` | `packages/effect/src/Schema.ts`, `ts/node_modules/effect/src/unstable/rpc/RpcSchema.ts` |
| WebSocket lifecycle and framing | `Socket`, `RpcClient`, `RpcServer`, `RpcSerialization` | `effect/unstable/socket`, `effect/unstable/rpc` | `ts/node_modules/effect/src/unstable/socket/*.ts`, `ts/node_modules/effect/src/unstable/rpc/*.ts` |
| HTTP servers/clients and typed APIs | `HttpApi`, `HttpApiClient`, `HttpApiBuilder`, `HttpClient`, `HttpServer` | `effect/unstable/http`, `effect/unstable/httpapi`, platform providers | `ts/node_modules/effect/src/unstable/http/*.ts`, `ts/node_modules/effect/src/unstable/httpapi/*.ts` |
| File, storage, and process IO | `FileSystem`, `KeyValueStore`, `ChildProcess`, `ChildProcessSpawner` | `effect/FileSystem`, `effect/unstable/persistence/KeyValueStore`, `effect/unstable/process/*`, provider packages | `ts/node_modules/effect/src/FileSystem.ts`, `ts/node_modules/effect/src/unstable/persistence/KeyValueStore.ts`, `ts/node_modules/effect/src/unstable/process/*.ts` |
| Browser local storage and clipboard | `BrowserKeyValueStore`, `Clipboard`, `BrowserHttpClient`, `BrowserSocket` | `@effect/platform-browser/*` | `ts/node_modules/.bun/@effect+platform-browser@4.0.0-beta.75+a5c1409dbf4ddafe/node_modules/@effect/platform-browser/src/*.ts` |
| AI tools, MCP, and model calls | `Tool`, `Toolkit`, `McpServer`, `McpSchema`, `LanguageModel`, provider layers | `effect/unstable/ai`, provider packages such as `@effect/ai-openai` | `ts/node_modules/effect/src/unstable/ai/*.ts`, `packages/ai/ai/src/*.ts` |
| Workbench async state | `Atom`, `AtomRpc`, `AtomHttpApi`, `AsyncResult`, `AtomRegistry`, `Reactivity` | `effect/unstable/reactivity`, `@effect/atom-react` | `ts/node_modules/effect/src/unstable/reactivity/*.ts`, `ts/packages/workbench/node_modules/@effect/atom-react/src/*.ts` |
| Metrics and logs | `Metric`, `Logger`, `Effect.log*` | `effect`, `@effect/opentelemetry` | `packages/effect/src/Metric.ts`, `packages/effect/src/Logger.ts` |
Known concrete exports useful to scouts:
- `Socket.makeWebSocket`, `Socket.fromWebSocket`, `Socket.toChannel`,
`Socket.toChannelString`, `Socket.layerWebSocket`.
- `RpcClient.layerProtocolSocket`, `RpcServer.layerProtocolWebsocket`,
`RpcServer.layerProtocolSocketServer`, `RpcSerialization.layerNdjson`,
`RpcSerialization.layerNdJsonRpc`.
- `BunFileSystem`, `BunSocket`, `BunHttpClient`, `BunHttpServer`,
`BunRuntime`, `BunChildProcessSpawner` from `@effect/platform-bun`.
- `BrowserKeyValueStore.layerLocalStorage`,
`BrowserKeyValueStore.layerSessionStorage`,
`BrowserHttpClient.layerXMLHttpRequest`.
- `Atom.make`, `Atom.runtime`, `Atom.fn`, `Atom.family`,
`Atom.subscriptionRef`, `AtomRegistry.layer`, `Reactivity.layer`,
`Reactivity.query`, `Reactivity.stream`, `Reactivity.mutation`.
- `Tool.make`, `Toolkit.make`, `McpServer.registerToolkit`,
`LanguageModel.generateText`, `LanguageModel.streamText`.
## Scout Workflow
1. Confirm repo state with `git status -sb`. Preserve unrelated files,
especially `.idea/effect.intellij.xml`.
2. Refresh the source baseline above. If a path moved, record the corrected path
in the report before making any recommendations.
3. Run quick signal scans:
```sh
rg -n "new Promise|setTimeout|while \\(|receive\\(|Effect\\.runPromise|toPromiseRequestor|makeAsyncProcessor|process\\.env|JSON\\.parse|JSON\\.stringify|localStorage|new Map|WebSocket" ts/packages --glob '*.ts' --glob '*.tsx'
```
4. Split scouts by lane. If the thread cannot spawn every scout in parallel,
run them in batches using the same report schema.
5. Every finding must include both:
- Evidence of the handrolled TrustGraph pattern.
- Evidence of the exact Effect primitive that could replace it.
6. Do not rewrite code in this audit. The output is a ranked opportunity map and
a recommended PR order.
## Agent Lanes
Use these lane prompts as the durable starting point.
### Base Messaging And Processor Runtime
Inspect `ts/packages/base/src/messaging`, `ts/packages/base/src/processor`, and
`ts/packages/base/src/spec`. Find Promise compatibility facades, polling
receivers, manual request/response caches, top-level `Effect.runPromise`, and
mutable maps. Compare against `Queue`, `PubSub`, `Stream`, `Scope`, `Layer`,
`Schedule`, `Ref`, and `SynchronizedRef`.
### Flow Stateful Services
Inspect `ts/packages/flow/src/config`, `librarian`, `cores`, `flow-manager`,
`prompt`, and service entrypoints. Find `makeAsyncProcessor` object services,
`while (this.running)`, `sleep`, `receive(2000)`, local persistence, and
process-env config. Compare against scoped layers, state refs, schedules,
`FileSystem`, `KeyValueStore`, `Config`, and schema codecs. In TrustGraph's
installed beta, prefer `effect/FileSystem` and
`effect/unstable/persistence/KeyValueStore` plus runtime-specific provider
packages.
### Gateway And RPC Boundaries
Inspect `ts/packages/flow/src/gateway` and `ts/packages/client/src/socket`.
Find manual requestor caches, streaming completion detectors, WebSocket
constructor shims, Promise-returning compatibility APIs, and repeated
`Effect.runPromise`. Compare against `Socket`, `RpcClient`, `RpcServer`,
`RpcSerialization`, `Stream`, `Queue`, and `Scope`.
### RAG, Agent, Provider, And Storage Layers
Inspect `ts/packages/flow/src/retrieval`, `agent`, `storage`, `query`, `model`,
and `embeddings`. Find `toPromiseRequestor`, direct SDK resource management,
ambient config, JSON parsing, and manual telemetry. Compare against
`EffectRequestResponse`, `Stream`, provider `Layer`s, `Config`, `Schema`,
`Metric`, `Logger`, and `effect/unstable/ai`.
### MCP And Workbench
Inspect `ts/packages/mcp` and `ts/packages/workbench`. Treat these as
lower-priority unless a handrolled pattern clearly remains. Prefer making the
Effect MCP server canonical over rewriting it from scratch. In workbench,
compare local storage and remote state wiring against `BrowserKeyValueStore`,
`AtomRpc`, `AtomHttpApi`, `AsyncResult`, and `Reactivity`.
## Report Schema
Each scout must return findings in this shape:
```md
## Finding: <short title>
- Priority: P0 | P1 | P2 | No-op
- Impact: 1-5
- Risk: 1-5
- Confidence: 1-5
- TrustGraph evidence: <path:line> and pattern name
- Effect evidence: <import path> and source path
- Current behavior: <what must be preserved>
- Rewrite shape: <Effect-native replacement direction>
- Tests: <specific existing or required tests>
- Blockers: <unknowns, API constraints, compatibility requirements>
```
Scoring:
- P0: large handrolled lifecycle/concurrency/transport surface with a verified
Effect primitive and clear behavior-preserving route.
- P1: real replacement opportunity, but either risk or compatibility needs a
focused design pass.
- P2: cleanup or local modernization; useful but not strategic.
- No-op: current code is already Effect-native, public-boundary Promise code is
intentional, or the Effect primitive does not actually fit.
## Acceptance Checks
For an audit-only pass:
```sh
git status -sb
git diff --check -- ts/EFFECT_NATIVE_REWRITE_PLAYBOOK.md ts/EFFECT_NATIVE_REWRITE_AUDIT.md
```
For any later implementation PR, rerun the relevant package tests and at least:
```sh
cd ts && bun run check:tsgo
cd ts && bun run build
cd ts && bun run test
```
If gateway, live services, or workbench behavior changes, also run the existing
smoke lanes from `ts/CLASS_EFFECT_GOAL.md`.