opencode-effect-enforcer 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +12 -10
  2. package/docs/effect-4.0.0-rc.112.md +316 -0
  3. package/guidance/effect-first-development.md +30 -17
  4. package/guidance/progressive-disclosure-guidance.md +13 -0
  5. package/package.json +4 -3
  6. package/patterns/avoid-direct-tag-checks.md +8 -2
  7. package/patterns/avoid-react-hooks.md +18 -37
  8. package/patterns/effect-run-in-body.md +1 -1
  9. package/patterns/require-effect-concurrency.md +11 -0
  10. package/patterns/use-console-service.md +6 -1
  11. package/skills/effect-ai-language-model/SKILL.md +10 -16
  12. package/skills/effect-ai-prompt/SKILL.md +36 -2
  13. package/skills/effect-ai-provider/SKILL.md +13 -0
  14. package/skills/effect-ai-streaming/SKILL.md +81 -108
  15. package/skills/effect-ai-tool/SKILL.md +50 -87
  16. package/skills/effect-atom-rpc/SKILL.md +9 -2
  17. package/skills/effect-atom-state/SKILL.md +5 -0
  18. package/skills/effect-cache/SKILL.md +32 -0
  19. package/skills/effect-cli/SKILL.md +22 -3
  20. package/skills/effect-concurrency-testing/SKILL.md +7 -9
  21. package/skills/effect-domain-modeling/SKILL.md +208 -1169
  22. package/skills/effect-domain-predicates/SKILL.md +5 -6
  23. package/skills/effect-error-handling/SKILL.md +5 -4
  24. package/skills/effect-http-api/SKILL.md +12 -1
  25. package/skills/effect-http-client/SKILL.md +1 -1
  26. package/skills/effect-http-server/SKILL.md +14 -3
  27. package/skills/effect-layer-design/SKILL.md +22 -56
  28. package/skills/effect-mcp-server/SKILL.md +1 -1
  29. package/skills/effect-pattern-matching/SKILL.md +44 -11
  30. package/skills/effect-platform-abstraction/SKILL.md +1 -1
  31. package/skills/effect-platform-layers/SKILL.md +1 -1
  32. package/skills/effect-rpc-api/SKILL.md +8 -1
  33. package/skills/effect-rpc-client/SKILL.md +20 -6
  34. package/skills/effect-rpc-cluster/SKILL.md +44 -14
  35. package/skills/effect-rpc-server/SKILL.md +32 -5
  36. package/skills/effect-scheduling/SKILL.md +1 -1
  37. package/skills/effect-schema-composition/SKILL.md +69 -15
  38. package/skills/effect-schema-v4/SKILL.md +43 -1
  39. package/skills/effect-scope/SKILL.md +30 -0
  40. package/skills/effect-service-implementation/SKILL.md +10 -4
  41. package/skills/effect-socket/SKILL.md +5 -5
  42. package/skills/effect-sql/SKILL.md +22 -0
  43. package/skills/effect-stream/SKILL.md +32 -1
  44. package/skills/effect-testing/SKILL.md +39 -31
  45. package/skills/effect-workflow/SKILL.md +6 -0
  46. package/src/enforcer.ts +1 -1
  47. package/src/index.ts +1 -1
  48. package/src/skills.ts +4 -4
  49. package/patterns/vm-in-wrong-file.md +0 -51
  50. package/skills/effect-react-vm/SKILL.md +0 -675
package/README.md CHANGED
@@ -6,6 +6,10 @@
6
6
  An opinionated OpenCode V2 plugin that gives coding agents current Effect v4
7
7
  guidance and reviews their TypeScript edits for common Effect anti-patterns.
8
8
 
9
+ **Supported Effect version: `4.0.0-rc.112`.** See the
10
+ [full rc.111 → rc.112 release notes and audit](docs/effect-4.0.0-rc.112.md)
11
+ for upstream changes, companion-package notes, and repository migration details.
12
+
9
13
  ## Install
10
14
 
11
15
  Add the npm package to your global or project `opencode.jsonc`:
@@ -21,7 +25,7 @@ That is the complete installation. OpenCode resolves published package entries
21
25
  for you; there is no separate `npm install` step. Use the global config at
22
26
  `~/.config/opencode/opencode.jsonc` to enable it everywhere, or a project config
23
27
  to enable it only for that project. You can also pin a release, for example
24
- `"opencode-effect-enforcer@0.2.3"`.
28
+ `"opencode-effect-enforcer@0.2.5"`.
25
29
 
26
30
  Start a new OpenCode session, then verify the plugin if needed:
27
31
 
@@ -57,12 +61,12 @@ Look for `opencode.effect-enforcer` with `state.status` set to `active`.
57
61
 
58
62
  ## What You Get
59
63
 
60
- - **54 focused skills** registered in OpenCode's native skill catalog, covering
64
+ - **53 focused skills** registered in OpenCode's native skill catalog, covering
61
65
  Effect's core, platform, AI, RPC, SQL, frontend, and testing APIs.
62
66
  - **4 guidance documents** injected into model context so Effect-first
63
67
  boundaries, domain modeling, dependency design, and skill routing stay
64
68
  visible while the agent works.
65
- - **46 tested patterns** run after successful `write`, `edit`, `patch`, and
69
+ - **45 tested patterns** run after successful `write`, `edit`, `patch`, and
66
70
  `apply_patch` calls, reporting only violations in newly added text.
67
71
  - **Advisory remediation** appended to the completed tool result so the model
68
72
  reviews and fixes valid findings without a detector blocking the underlying
@@ -81,7 +85,7 @@ available.
81
85
  - [Effect, and the Near-Inexpressible Majesty of Layers](guidance/post__effect-and-the-near-inexpressible-majesty-of-layers.md): Explains services, Layers, typed dependencies, and testable implementations.
82
86
  - [Parse, don't validate](guidance/post__parse-dont-validate.md): Shows how refined types preserve validation knowledge and make illegal states unrepresentable.
83
87
 
84
- ### Skills (54)
88
+ ### Skills (53)
85
89
 
86
90
  #### Modeling And Core APIs
87
91
 
@@ -147,7 +151,6 @@ available.
147
151
  - [`effect-atom-state`](skills/effect-atom-state/SKILL.md): Manage reactive React state with Effect Atom.
148
152
  - [`effect-atom-rpc`](skills/effect-atom-rpc/SKILL.md): Build cached, invalidating, SSR-aware RPC atoms for React clients.
149
153
  - [`effect-react-composition`](skills/effect-react-composition/SKILL.md): Compose React components around explicit Effect Atom state and behavior.
150
- - [`effect-react-vm`](skills/effect-react-vm/SKILL.md): Implement testable View Models that bridge Effect services and React views.
151
154
 
152
155
  #### Configuration, Operations, And Testing
153
156
 
@@ -158,7 +161,7 @@ available.
158
161
  - [`effect-concurrency-testing`](skills/effect-concurrency-testing/SKILL.md): Test fibers, PubSub, Deferred, Latch, SubscriptionRef, and concurrent streams.
159
162
  - [`effect-incremental-migration`](skills/effect-incremental-migration/SKILL.md): Migrate Promise-based modules incrementally while preserving required compatibility.
160
163
 
161
- ### Patterns (46)
164
+ ### Patterns (45)
162
165
 
163
166
  #### Types, Modeling, And Collections
164
167
 
@@ -217,8 +220,7 @@ available.
217
220
 
218
221
  #### React And Testing Conventions
219
222
 
220
- - [`avoid-react-hooks`](patterns/avoid-react-hooks.md): Directs React state and effects into Effect Atom View Models.
221
- - [`vm-in-wrong-file`](patterns/vm-in-wrong-file.md): Enforces dedicated `.vm.ts` files for View Model definitions.
223
+ - [`avoid-react-hooks`](patterns/avoid-react-hooks.md): Reviews React state and effects for Effect Atom alternatives.
222
224
  - [`avoid-expect-in-if`](patterns/avoid-expect-in-if.md): Prevents conditional assertions that allow tests to pass without checking behavior.
223
225
 
224
226
  ## Per-Agent Opt-Out
@@ -283,8 +285,8 @@ The release tag must exactly match the package version, such as `v0.2.0` for
283
285
  `"version": "0.2.0"`.
284
286
 
285
287
  There is no generated `dist` tree. OpenCode imports the TypeScript entrypoint,
286
- and npm publishes the authoritative `src/`, `skills/`, `guidance/`, and
287
- `patterns/` directories directly.
288
+ and npm publishes the authoritative `src/`, `skills/`, `guidance/`, `patterns/`,
289
+ and `docs/` directories directly.
288
290
 
289
291
  ## Credits
290
292
 
@@ -0,0 +1,316 @@
1
+ # Effect 4.0.0-rc.111 → 4.0.0-rc.112
2
+
3
+ ## Version and provenance
4
+
5
+ - Previous direct dependency: `effect@4.0.0-rc.111`.
6
+ - Target: `effect@4.0.0-rc.112`, the npm `rc` dist-tag checked on 2026-09-06.
7
+ - Rechecked on 2026-09-07: `rc` remains rc.112; `latest` is the separate v3 line (`3.22.1`).
8
+ - Exact source: [`effect@4.0.0-rc.112`](https://github.com/Effect-TS/effect/tree/effect%404.0.0-rc.112), release commit `2600f62f`.
9
+ - [Complete source comparison](https://github.com/Effect-TS/effect/compare/effect%404.0.0-rc.111...effect%404.0.0-rc.112).
10
+ - [Upstream Effect changelog](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/effect/CHANGELOG.md).
11
+
12
+ The interval is **exclusive of rc.111 and inclusive of rc.112**: one release.
13
+ The notes below retain every upstream Effect release entry and every additional
14
+ companion-package change. Dependency-only companion releases are recorded in the
15
+ package table. Earlier beta/RC corrections found during this repository's audit
16
+ are separate from the upstream release notes.
17
+
18
+ ## Full upstream Effect release notes
19
+
20
+ ### Minor Changes
21
+
22
+ - [#7390](https://github.com/Effect-TS/effect/pull/7390) [`a5f78d3`](https://github.com/Effect-TS/effect/commit/a5f78d3fcbaa792d49e80d103ab438e0b50812fd) Thanks @tim-smart! - Make RPC serialization schema-aware.
23
+
24
+ Add `codecFor` to RPC serialization and client/server protocols so RPC and cluster
25
+ network payloads use the transport's schema codec. Framing, cluster storage, and
26
+ existing built-in wire formats remain unchanged.
27
+
28
+ ### Patch Changes
29
+
30
+ - [#7411](https://github.com/Effect-TS/effect/pull/7411) [`20cb4f2`](https://github.com/Effect-TS/effect/commit/20cb4f260e45d37fa417c292c57be015314efe16) Thanks @altendky! - Add `RcMap.getOption` and `LayerMap.contextEffectOption` for atomically retaining
31
+ entries only when they are already cached.
32
+
33
+ - [#7437](https://github.com/Effect-TS/effect/pull/7437) [`44675cb`](https://github.com/Effect-TS/effect/commit/44675cbce3dabfb85c68a3703b5de525768336fb) Thanks @wmaurer! - Add an optional `description` to `AiError.AuthenticationError`, rendered after the kind-based suggestion, and pass the provider's own error text through it on HTTP 401 and 403, so authentication failures report what actually went wrong instead of only a category.
34
+
35
+ - [#7393](https://github.com/Effect-TS/effect/pull/7393) [`b6bf5e1`](https://github.com/Effect-TS/effect/commit/b6bf5e14492643076454131148f97cde24ad5306) Thanks @wmaurer! - Fix `Prompt.autoComplete` swallowing `j` and `k` while typing a filter query.
36
+
37
+ - [#7401](https://github.com/Effect-TS/effect/pull/7401) [`0b9f780`](https://github.com/Effect-TS/effect/commit/0b9f780ff28b71042241791a9e8bcb5b631be2bd) Thanks @gjermundgaraba! - Retry transient EventLog remote write failures so pending local entries are synchronized after recovery.
38
+
39
+ - [#7384](https://github.com/Effect-TS/effect/pull/7384) [`150e92c`](https://github.com/Effect-TS/effect/commit/150e92c4169c245e701da02575eef0b69c3ecd64) Thanks @tim-smart! - Improve synchronous Schema decode and encode performance by preserving completed parser exits and using a direct loop for common struct parsers.
40
+
41
+ - [#7386](https://github.com/Effect-TS/effect/pull/7386) [`6740db2`](https://github.com/Effect-TS/effect/commit/6740db247ed20cb85da43c9f48ade8fecfd8c1ae) Thanks @tim-smart! - Add `Schema.TaggedUnion.matchOrElse` for partial case matching with a typed fallback.
42
+
43
+ - [#7389](https://github.com/Effect-TS/effect/pull/7389) [`d57bba1`](https://github.com/Effect-TS/effect/commit/d57bba1486fa60971b6e0bf7459a329cfd5acdc4) Thanks @tim-smart! - Improve `SchemaError` construction performance by skipping stack frame capture.
44
+
45
+ - [#7402](https://github.com/Effect-TS/effect/pull/7402) [`be75d5e`](https://github.com/Effect-TS/effect/commit/be75d5ea6e516c25e3affec25806d31c2b203bc4) Thanks @tim-smart! - Improve Pool acquisition and release performance. Pool now tracks usage
46
+ incrementally, stores available items in an intrusive FIFO, and skips work for
47
+ fixed and empty pools. This changes the public `Pool.State` and `Pool.PoolItem`
48
+ interfaces.
49
+
50
+ - [#7402](https://github.com/Effect-TS/effect/pull/7402) [`be75d5e`](https://github.com/Effect-TS/effect/commit/be75d5ea6e516c25e3affec25806d31c2b203bc4) Thanks @tim-smart! - Add `Pool.use`, which borrows an item while an effect runs and returns it on any
51
+ exit. Unlike `Effect.scoped(Pool.get(pool))`, it does not require a `Scope`.
52
+
53
+ - [#7402](https://github.com/Effect-TS/effect/pull/7402) [`be75d5e`](https://github.com/Effect-TS/effect/commit/be75d5ea6e516c25e3affec25806d31c2b203bc4) Thanks @tim-smart! - Reduce scoped resource acquisition allocations by storing the first Scope
54
+ finalizer inline and allocating a Map only when a second is added. This changes
55
+ the public `Scope.State.Open` interface.
56
+
57
+ - [#7424](https://github.com/Effect-TS/effect/pull/7424) [`02a5146`](https://github.com/Effect-TS/effect/commit/02a5146d6933c7f6052553550bce5658225e4100) Thanks @tim-smart! - Skip remote event journal write callbacks when there are no uncommitted entries and return an `Option` indicating
58
+ whether the callback ran.
59
+
60
+ - [#7312](https://github.com/Effect-TS/effect/pull/7312) [`15272a6`](https://github.com/Effect-TS/effect/commit/15272a66adf02501e7747761e2a3c41bff67bb46) Thanks @godu! - Fix shell completion for choice values containing quotes, spaces, word-break characters, Unicode, and shell metacharacters.
61
+
62
+ Bash now quotes candidates for readline, keeps choice values intact when reconstructing words, and supports Bash 3.2 without associative arrays. Fish and Zsh escape choices across both parsing rounds, and Fish hides value-taking flags after use without suppressing their value completions.
63
+
64
+ - [#7395](https://github.com/Effect-TS/effect/pull/7395) [`436f10d`](https://github.com/Effect-TS/effect/commit/436f10d1efccec308426532ff3f88df9a96434f3) Thanks @wmaurer! - Fix `Prompt.file` swallowing `j` and `k` while typing a filter query.
65
+
66
+ - [#7406](https://github.com/Effect-TS/effect/pull/7406) [`058fb15`](https://github.com/Effect-TS/effect/commit/058fb15647fa01ad771277bd368783fcf5f262e8) Thanks @gcanti! - Preserve finite string and unique symbol key unions in the return types of `Array.groupBy` and `Iterable.groupBy`.
67
+
68
+ Previously, grouping widened finite keys to `string` or `symbol`, which lost known-key autocomplete and allowed access to keys that the selector could never produce. The new `Record.ReadonlyRecord.GroupByResult` keeps finite keys and marks their properties optional because any group may be absent at runtime, while open `string` and `symbol` selectors retain their existing record index signatures.
69
+
70
+ - [#7415](https://github.com/Effect-TS/effect/pull/7415) [`4d89bb8`](https://github.com/Effect-TS/effect/commit/4d89bb8ffb4cf567a1d11072246b6161ce638712) Thanks @gcanti! - Reject unsupported JSON Schema references instead of resolving them by their final path segment, closes [#7409](https://github.com/Effect-TS/effect/issues/7409).
71
+
72
+ - [#7420](https://github.com/Effect-TS/effect/pull/7420) [`480fb15`](https://github.com/Effect-TS/effect/commit/480fb156590785cf98f67bdec4fc282a608e2d87) Thanks @gcanti! - Make JSON Schema dialect conversions preserve custom keywords, translate conditionals, contains, dependencies, identifiers, and tuples where representable, relocate local references after structural changes, and throw instead of silently changing unsupported constraints.
73
+
74
+ - [#7417](https://github.com/Effect-TS/effect/pull/7417) [`f77ec19`](https://github.com/Effect-TS/effect/commit/f77ec19cff1cbbeeae928e3bd0ece00a7d22bab8) Thanks @Makisuo! - Defer built-in OpenAPI response generation until the documentation route is first requested, retrying after generation defects.
75
+
76
+ - [#7388](https://github.com/Effect-TS/effect/pull/7388) [`925b82a`](https://github.com/Effect-TS/effect/commit/925b82a81f59a4d459b488621030f24ba99d6a27) Thanks @ebramanti! - Fix MCP initialize rejected over the protocol version header
77
+
78
+ `McpServer.layerHttp` validated the `MCP-Protocol-Version` header on every POST, including
79
+ the `initialize` request. That header reports the version negotiated by an earlier
80
+ `initialize`, so on a fresh connection a client can only send its own default. Whenever
81
+ that default was not among the server's registered protocols the `initialize` returned
82
+ `400` and never reached version negotiation, even when the body offered a version the
83
+ server supports.
84
+
85
+ The header check now applies only to requests after initialization, where the
86
+ specification requires it. An `initialize` negotiates from the version offered in its
87
+ body, through the protocol registry, and reports the selected version in the response.
88
+
89
+ - [#7403](https://github.com/Effect-TS/effect/pull/7403) [`7455246`](https://github.com/Effect-TS/effect/commit/7455246f352385f5cbbdd8299555265ee289490e) Thanks @hsyntax! - Add support for explicit cache breakpoints on the OpenAI responses API for GPT-5.6-or-later.
90
+
91
+ - [#7442](https://github.com/Effect-TS/effect/pull/7442) [`118124d`](https://github.com/Effect-TS/effect/commit/118124d913d0a02ac5c1f7799a39bd90031769d9) Thanks @tim-smart! - Redact password prompt values from CLI wizard command output.
92
+
93
+ - [#7366](https://github.com/Effect-TS/effect/pull/7366) [`0dd7825`](https://github.com/Effect-TS/effect/commit/0dd7825e4da4d3a00fa9bd410a1d55f3d4874d07) Thanks @tim-smart! - Add `SchemaBinary`, a compact schema-derived codec with streaming, optional fingerprints and dictionaries, and RPC support.
94
+
95
+ - [#7404](https://github.com/Effect-TS/effect/pull/7404) [`b722eca`](https://github.com/Effect-TS/effect/commit/b722eca6d283a88970ad0efba0b4e921915eca78) Thanks @gcanti! - Add a public `StandardSchema` module containing the vendored Standard Schema V1 specification and remove the direct dependency on `@standard-schema/spec`.
96
+
97
+ - [#7436](https://github.com/Effect-TS/effect/pull/7436) [`811d579`](https://github.com/Effect-TS/effect/commit/811d579c432856a9e3fc05b517fd8e924cbf991a) Thanks @gcanti! - Fix JSON Schema imports:
98
+
99
+ - Type-specific keywords no longer imply a type. For example, `minLength` validates strings without rejecting
100
+ non-string values.
101
+ - Constraints next to `const`, `enum`, and `$ref` are now applied instead of being ignored.
102
+ - Disjoint and linear union intersections are imported without a Cartesian expansion. Other overlapping union
103
+ intersections fail with an explicit error.
104
+ - References to definitions without unions no longer make otherwise linear intersections fail.
105
+ - Imported `oneOf` schemas remain `oneOf` when exported again.
106
+ - `minItems` is preserved when `prefixItems` does not fully enforce it.
107
+
108
+ - [#7382](https://github.com/Effect-TS/effect/pull/7382) [`043b587`](https://github.com/Effect-TS/effect/commit/043b587e6e93f6624bf974bcd7ed976eaa17f0e1) Thanks @tim-smart! - Replace per-prompt prefix options with a context-based theme for CLI prompt symbols and colors.
109
+
110
+ - [#7373](https://github.com/Effect-TS/effect/pull/7373) [`8583727`](https://github.com/Effect-TS/effect/commit/85837274fa929a921985464585513a68c261e365) Thanks @ChubbyDuck! - Drop unreachable concurrency guard in iteratorEagerImpl
111
+
112
+ - [#7429](https://github.com/Effect-TS/effect/pull/7429) [`d9d2cfc`](https://github.com/Effect-TS/effect/commit/d9d2cfcb732754001b7323cf8afaccc48539bb74) Thanks @gcanti! - Reject unsupported JSON Schema validation keywords and object or array `const` / `enum` values during import instead of
113
+ silently weakening validation.
114
+
115
+ - [#7428](https://github.com/Effect-TS/effect/pull/7428) [`5c4b7a0`](https://github.com/Effect-TS/effect/commit/5c4b7a0b17931cd1538c6595a54b21ffe9c1e906) Thanks @ebramanti! - Return workflow execution IDs from generated RPC and HTTP discard endpoints.
116
+
117
+ ## Additional companion-package release notes
118
+
119
+ The four AI provider packages repeat #7437 above; `@effect/ai-openai` also
120
+ repeats #7403. The remaining non-dependency entries are reproduced here:
121
+
122
+ - **`@effect/atom-react`** — [#7435](https://github.com/Effect-TS/effect/pull/7435) [`4148e21`](https://github.com/Effect-TS/effect/commit/4148e21eb5f86ef37e07086ec9f3cc7e55d24e90) Thanks @mattrobrob! - Relax react peer dependency range
123
+ - **`@effect/platform-bun`** — [#7408](https://github.com/Effect-TS/effect/pull/7408) [`e1fb57f`](https://github.com/Effect-TS/effect/commit/e1fb57ffbf3cef2dd3016bacd26a4166a52618b7) Thanks @phibr0! - Compress outgoing Bun WebSocket messages when per-message deflate is configured and negotiated. Messages
124
+ smaller than 1 KiB are left uncompressed, matching the default threshold used by Node's `ws` server.
125
+ The threshold is configurable via the new `websocket.compressionThreshold` server option.
126
+ - **`@effect/platform-node`** — [#7440](https://github.com/Effect-TS/effect/pull/7440) [`7d8535a`](https://github.com/Effect-TS/effect/commit/7d8535af823a0186f771a78a02fa07dbee706df9) Thanks @tim-smart! - Return `Option.none()` when reading an incoming message's remote address after Node clears its socket.
127
+ - **`@effect/sql-d1`, `@effect/sql-mysql2`, `@effect/sql-pglite`, `@effect/doctest`** — [#7421](https://github.com/Effect-TS/effect/pull/7421) [`1f686d9`](https://github.com/Effect-TS/effect/commit/1f686d99a79e36ef144bd9ad6f4141a5a43d2599) Thanks @tim-smart! - Update production dependencies to their latest releases.
128
+ - **`@effect/sql-pg`** — [#7391](https://github.com/Effect-TS/effect/pull/7391) [`1144032`](https://github.com/Effect-TS/effect/commit/1144032cedda7b5eacc1ebf980d06957c7a59ddf) Thanks @tim-smart! - Add low-level PostgreSQL protocol, binary type, and authentication codecs to `@effect/sql-pg`.
129
+
130
+ `PgProtocol` encodes protocol 3.0 messages and incrementally parses backend frames. Its stateful parser throws terminal errors. `PgTypes` handles binary scalar and one-dimensional array OIDs; its public codecs return typed `Result` failures, while parser field readers use an internal throwing fast path. `PgAuth` implements MD5 and SCRAM-SHA-256 with typed `Result` failures.
131
+
132
+ Encoded frames and decoded byte fields are stable views over internal buffers. Copy data that must outlive its message. `PgClient` remains unchanged and still uses `pg` at runtime.
133
+
134
+ ### Complete companion release inventory
135
+
136
+ All packages below move from `4.0.0-rc.111` to `4.0.0-rc.112` and update their
137
+ Effect dependency to rc.112. Paths link to the exact-tag changelogs, including
138
+ their full repeated dependency commit lists. “Dependency only” means no separate
139
+ feature/fix release note; it does not assert that every source file is identical.
140
+
141
+ | Package | Additional notes | Other Effect-family dependency updates |
142
+ | --- | --- | --- |
143
+ | [@effect/ai-anthropic](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/ai/anthropic/CHANGELOG.md) | #7437 | — |
144
+ | [@effect/ai-openai](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/ai/openai/CHANGELOG.md) | #7437, #7403 | — |
145
+ | [@effect/ai-openai-compat](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/ai/openai-compat/CHANGELOG.md) | #7437 | — |
146
+ | [@effect/ai-openrouter](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/ai/openrouter/CHANGELOG.md) | #7437 | — |
147
+ | [@effect/atom-react](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/atom/react/CHANGELOG.md) | #7435 | — |
148
+ | [@effect/atom-solid](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/atom/solid/CHANGELOG.md) | Dependency only | — |
149
+ | [@effect/atom-vue](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/atom/vue/CHANGELOG.md) | Dependency only | — |
150
+ | [@effect/opentelemetry](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/opentelemetry/CHANGELOG.md) | Dependency only | — |
151
+ | [@effect/platform-browser](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/platform/browser/CHANGELOG.md) | Dependency only | — |
152
+ | [@effect/platform-bun](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/platform/bun/CHANGELOG.md) | #7408 | platform-node-shared |
153
+ | [@effect/platform-deno](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/platform/deno/CHANGELOG.md) | Dependency only | platform-node-shared |
154
+ | [@effect/platform-node](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/platform/node/CHANGELOG.md) | #7440 | platform-node-shared |
155
+ | [@effect/platform-node-shared](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/platform/node-shared/CHANGELOG.md) | Dependency only | — |
156
+ | [@effect/sql-clickhouse](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/clickhouse/CHANGELOG.md) | Dependency only | platform-node |
157
+ | [@effect/sql-d1](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/d1/CHANGELOG.md) | #7421 | — |
158
+ | [@effect/sql-libsql](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/libsql/CHANGELOG.md) | Dependency only | — |
159
+ | [@effect/sql-mssql](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/mssql/CHANGELOG.md) | Dependency only | — |
160
+ | [@effect/sql-mysql2](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/mysql2/CHANGELOG.md) | #7421 | — |
161
+ | [@effect/sql-pg](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/pg/CHANGELOG.md) | #7391 | — |
162
+ | [@effect/sql-pglite](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/pglite/CHANGELOG.md) | #7421 | — |
163
+ | [@effect/sql-sqlite-bun](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/sqlite-bun/CHANGELOG.md) | Dependency only | — |
164
+ | [@effect/sql-sqlite-do](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/sqlite-do/CHANGELOG.md) | Dependency only | — |
165
+ | [@effect/sql-sqlite-node](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/sqlite-node/CHANGELOG.md) | Dependency only | — |
166
+ | [@effect/sql-sqlite-react-native](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/sqlite-react-native/CHANGELOG.md) | Dependency only | — |
167
+ | [@effect/sql-sqlite-wasm](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/sql/sqlite-wasm/CHANGELOG.md) | Dependency only | — |
168
+ | [@effect/docgen](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/tools/docgen/CHANGELOG.md) | Dependency only | platform-node |
169
+ | [@effect/doctest](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/tools/doctest/CHANGELOG.md) | #7421 | — |
170
+ | [@effect/openapi-generator](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/tools/openapi-generator/CHANGELOG.md) | Dependency only | platform-node |
171
+ | [@effect/vitest](https://github.com/Effect-TS/effect/blob/effect%404.0.0-rc.112/packages/vitest/CHANGELOG.md) | Dependency only | — |
172
+
173
+ ## Migration map for this repository
174
+
175
+ The release was audited from the exact tag, including public signatures and
176
+ implementation semantics. Moving `main` was already ahead of the release and was
177
+ not used to infer rc.112 availability. The local runtime typechecks with rc.112
178
+ without source changes; the dependency/lockfile update is the runtime migration.
179
+
180
+ | Surface | Required action / guidance | Owning skills |
181
+ | --- | --- | --- |
182
+ | Schema-aware RPC | Forward required `codecFor` on custom client/server protocols; preserve schema services. Existing built-in formats retain their encoding; cluster storage stays JSON. | `effect-rpc-api`, `effect-rpc-client`, `effect-rpc-server`, `effect-rpc-cluster`, `effect-atom-rpc` |
183
+ | Binary schemas | Public `SchemaBinary.toCodec`, streaming channels, incremental parsing, fingerprints, dictionary lifetime, frame limits, and buffer ownership; avoid exported `@internal` fast paths. | `effect-schema-composition`, `effect-schema-v4`, `effect-stream` |
184
+ | Schema semantics | `matchOrElse` overloads and fallback narrowing, strict JSON Schema imports/conversions, vendored Standard Schema types, stack-free SchemaError. | `effect-schema-v4`, `effect-pattern-matching`, `effect-domain-modeling` |
185
+ | Resource ownership | Atomic cached-only retention with `RcMap.getOption` / `LayerMap.contextEffectOption`, `Pool.use`, and changed public Pool/Scope state interfaces. | `effect-cache`, `effect-layer-design`, `effect-scope`, `effect-service-implementation` |
186
+ | CLI | Replace `prefix` with `theme`, context/local precedence, filter navigation, password wizard redaction, and shell completion escaping. | `effect-cli` |
187
+ | AI | Authentication descriptions preserve provider text; OpenAI Responses GPT-5.6+ explicit cache configuration and prompt breakpoints. | `effect-ai-provider`, `effect-ai-prompt` |
188
+ | Event replication | Empty remote batches skip callbacks and return `None`; non-empty callbacks return `Some`; transient remote writes retry and synchronize pending entries. | `effect-rpc-cluster` |
189
+ | Workflow proxies | Generated RPC/HTTP discard endpoints return string execution IDs; distinguish these endpoints from client-side response-discard options. | `effect-workflow`, `effect-rpc-cluster`, `effect-atom-rpc` |
190
+ | HTTP / MCP | Lazy OpenAPI generation retries after defects; MCP initialize negotiates from body before header validation; Bun WebSocket compression threshold and missing Node remote addresses. | `effect-http-api`, `effect-mcp-server`, `effect-http-server` |
191
+ | Collections | Finite `groupBy` keys remain finite and optional; consumers handle absent groups. | `effect-domain-modeling` |
192
+ | PostgreSQL | Public `PgProtocol`, `PgTypes`, `PgAuth`; synchronous parser vs typed Result failures and buffer ownership. `PgClient` still uses `pg`. | `effect-sql` |
193
+ | Companion peers | React peer range is `>=19.0.0 <20.0.0`; the rc.112 Vitest adapter requires `>=4.1.0 <5.0.0`. | `effect-atom-state`, `effect-testing` |
194
+
195
+ ## Earlier documentation drift corrected during the audit
196
+
197
+ These are **not new rc.112 breaking changes**:
198
+
199
+ - Correct `Schema.Schema<T>` versus `Schema.Codec<T, E, RD, RE>` signatures.
200
+ Constructor defaults, including tags, are not automatically decoding defaults;
201
+ `.makeEffect` belongs to the schema instance and fails with `SchemaIssue.Issue`.
202
+ - Replace the repetitive domain-modeling templates with a coherent, compiler-
203
+ checked class-based lifecycle: branded identity, legal transitions, class-
204
+ preserving construction, schema equivalence, orders, optional fields, and
205
+ recursive encoded types. Remove the invalid “change only `_tag`” transition.
206
+ - Correct `Stream.mapArrayEffect`, `Effect.andThen`, `Effect.catch`,
207
+ `Effect.catchCause`, `Effect.mapError` + `orDie`, `Effect.die`, and `runFold`'s
208
+ initial-value thunk. AI streaming examples now scope accumulators per run and
209
+ release semaphore permits even if history setup fails.
210
+ - Yield a Toolkit and provide its handler Layer; use `Tool.HandlerServices` and
211
+ error schemas rather than instance-only JSON checks. The complete tool example
212
+ uses a typed service implementation instead of unchecked database casts.
213
+ - Replace the incomplete Deferred/fiber deduplication example with `Effect.cached`;
214
+ explain that caches and restartable worker coordinators have different contracts.
215
+ - Distinguish complete `Layer.succeed` fakes from partial, defect-stubbing
216
+ `Layer.mock`; preserve deliberate caller-scoped service requirements.
217
+ - Correct RPC abort inspection (`onExit`, interrupt-reason annotations) and HTTP
218
+ streaming semantics: bounded framed response queues backpressure producers even
219
+ without RPC acks. Discarded responses do not erase transport failures.
220
+ - Correct v4 test utilities (`Result`, `TxRef` / `Effect.tx`, `Logger.layer`,
221
+ `Fiber.await`), lexical scope in the event-publisher test, and interruption
222
+ assertions. Keep this repository's existing Vitest runner for compiler/inventory
223
+ tests; installing `@effect/vitest` would require a separate peer-version migration.
224
+ - Apply Effect.fn result transformations in its constructor call and use a
225
+ Duration-input `Metric.timer` with `Effect.trackDuration`; correct the
226
+ `timeoutOrElse` option to `orElse`.
227
+ - Repair flattened upstream platform paths and remove tool-specific/stale
228
+ line-number references from core guidance.
229
+
230
+ ## Coverage and intentionally retained material
231
+
232
+ The changed-surface and qualified-symbol scan covered **all 53 remaining bundled
233
+ skills, 45 patterns, four guidance documents, and runtime source**. Findings were checked
234
+ against exact-tag exports/signatures before edits; aliases, re-exports, custom
235
+ application services, and explicitly obsolete examples are not missing APIs.
236
+
237
+ **35 skills changed.** In addition to the migration-map owners, corrective edits
238
+ cover `effect-ai-language-model`, `effect-ai-streaming`, `effect-ai-tool`,
239
+ `effect-concurrency-testing`, `effect-domain-predicates`, `effect-error-handling`,
240
+ `effect-http-client`, `effect-platform-abstraction`, `effect-platform-layers`,
241
+ `effect-scheduling`, and `effect-socket`.
242
+
243
+ The other **18 skills** had no migration requirement identified by this release
244
+ surface/symbol audit: `effect-ai-chat`, `effect-batching`,
245
+ `effect-command-executor`, `effect-config`, `effect-context-witness`,
246
+ `effect-fiber`, `effect-filesystem`, `effect-graph`, `effect-incremental-migration`,
247
+ `effect-managed-runtime`, `effect-observability`, `effect-optics`,
248
+ `effect-parallelization`, `effect-path`, `effect-pubsub-event-bus`,
249
+ `effect-react-composition`, `effect-typeclass-design`, and
250
+ `effect-wide-events`. Their relevant new cross-cutting semantics live in the
251
+ owning skills above rather than duplicated release notes in every file.
252
+
253
+ **Five retained patterns changed:**
254
+
255
+ - `require-effect-concurrency`: detect the removed literal `concurrency: 'inherit'`
256
+ in addition to missing explicit concurrency. Regression cases cover data-first,
257
+ curried, quoted-key, and unrelated-string cases.
258
+ - `avoid-direct-tag-checks`: correct the false claim that TypeScript cannot narrow
259
+ tags; recommend schema match/guards and explain `matchOrElse`.
260
+ - `effect-run-in-body`: use the platform `BunRuntime.runMain` boundary.
261
+ - `use-console-service`: correct TestConsole capture APIs and distinguish console
262
+ capture from structured log capture.
263
+ - `avoid-react-hooks`: direct shared state/effect guidance to Effect Atom in
264
+ ordinary state modules, with React-specific hook use reviewed contextually.
265
+
266
+ The other 40 detector definitions require no rc.112 API migration. All 45 retain
267
+ their one-to-one detector tests and README catalog entries.
268
+
269
+ **Two guidance documents changed:** core Effect-first conventions and
270
+ version-aware progressive disclosure/routing. Both bundled essays retain their
271
+ original text.
272
+
273
+ At the user's request, the `effect-react-vm` skill, `vm-in-wrong-file` pattern,
274
+ and its detector test were removed. Atom RPC cross-links now point directly to
275
+ `effect-atom-state`. The catalog contains **53 skills, 45 patterns, and four
276
+ guidance documents**.
277
+
278
+ ## Verification
279
+
280
+ `test/documentation-types.test.ts` compiles the **14 self-contained TypeScript
281
+ blocks** marked `<!-- typecheck -->` directly from their Markdown source. It
282
+ uses the installed pinned Effect release with strict types, exact optional
283
+ properties, and unchecked-index checking. Virtual modules keep normal package
284
+ resolution; no generated source/distribution files are committed. A malformed
285
+ marker/fence fails the test instead of silently dropping coverage.
286
+
287
+ The checked blocks cover binary codec/channel round trips, pool borrowing,
288
+ cached-only retention, task construction/transitions/recursion, tagged matching,
289
+ cache layer composition, RPC abort inspection, tool handler wiring, streaming
290
+ history ownership, and workflow logging/metrics. Partial snippets, intentionally
291
+ bad examples, conceptual pseudocode, and examples needing optional companion
292
+ packages are reviewed guidance, not part of this compiler gate. The gate does
293
+ not claim to execute every documentation example or replace upstream integration
294
+ tests.
295
+
296
+ Repository completion commands:
297
+
298
+ ```sh
299
+ bun run check
300
+ bun run lint
301
+ bun run test
302
+ ```
303
+
304
+ Verified on 2026-09-07 after the VM-related removals:
305
+
306
+ - `bun run check` passed formatting, lint, and TypeScript checks.
307
+ - `bun run lint` passed with zero warnings and errors.
308
+ - `bun run test` passed **912 tests across 53 test files**, including all 14
309
+ marked documentation examples and the 53-skill / 45-pattern / four-guidance
310
+ inventory checks.
311
+ - `git diff --check` passed.
312
+
313
+ The full test suite includes the bidirectional pattern inventory, README/skill
314
+ inventory, runtime adapter tests, detector regressions, and documentation compiler
315
+ gate. Published files remain authoritative; `docs/` is included in the package
316
+ so this release record ships alongside the skills and guidance.
@@ -2,6 +2,12 @@
2
2
 
3
3
  This document defines the working model behind Effect-first code using the Effect v4 ecosystem.
4
4
 
5
+ Bundled baseline: **Effect 4.0.0-rc.112**. Check the consuming project's installed
6
+ version and inspect the matching upstream release tag before using newer APIs.
7
+ The release changelog and migration audit are in `docs/effect-4.0.0-rc.112.md`.
8
+ Source paths below are relative to the Effect source reference; locate symbols
9
+ by name rather than relying on line numbers or a particular tool name.
10
+
5
11
  ## Definition
6
12
 
7
13
  Effect-first development means domain code is written in Effect-native constructs first, and native JavaScript/TypeScript patterns only at explicit boundaries.
@@ -289,7 +295,8 @@ export type Tenant = typeof Tenant.Type;
289
295
  - If schema properties are a union of literal strings (for example `kind`, `state`, `category`), compose class variants into a `Schema.Union` and finalize with `Schema.toTaggedUnion("<field>")`.
290
296
  - Prefer `Schema.Class` for tagged union member schemas.
291
297
  - Use `Schema.TaggedUnion` only for canonical `_tag` object-union construction.
292
- - Reference: [Effect schema docs](packages/effect/SCHEMA.md:1891) (via effect_ref_read) and [toTaggedUnion notes](packages/effect/SCHEMA.md:1934) (via effect_ref_read).
298
+ - Reference: `packages/effect/SCHEMA.md`, sections `TaggedUnion` and `toTaggedUnion`.
299
+ - In rc.112, both union forms offer `matchOrElse` for partial matching with a typed fallback. Prefer `match` when every variant must be handled separately. `toTaggedUnion` narrows fallback input to unmatched variants; direct `Schema.TaggedUnion` types it as the full union.
293
300
 
294
301
  Example:
295
302
 
@@ -342,7 +349,8 @@ export const InternalJobEvent = Schema.TaggedUnion({
342
349
 
343
350
  - Prefer `Effect.fn("Name")(...)` for reusable/public effectful functions.
344
351
  - Use `Effect.fnUntraced(...)` for internal hot paths where tracing overhead is unnecessary.
345
- - Reference: [Effect.fn docs](packages/effect/src/Effect.ts:12850) (via effect_ref_read) and [Effect.fnUntraced docs](packages/effect/src/Effect.ts:12821) (via effect_ref_read).
352
+ - Reference: `Effect.fn` / `Effect.fnUntraced` in `packages/effect/src/Effect.ts`.
353
+ - Pass result-transforming combinators after the function body in the `Effect.fn` constructor call. The returned function itself has no `.pipe` method; its returned Effect does.
346
354
 
347
355
  Example:
348
356
 
@@ -374,11 +382,12 @@ const parseInternal = Effect.fnUntraced(function* (input: string) {
374
382
 
375
383
  Example:
376
384
 
385
+ <!-- typecheck -->
377
386
  ```ts
378
387
  import { Effect } from 'effect';
379
388
  import * as Metric from 'effect/Metric';
380
389
 
381
- const durationMs = Metric.histogram('workflow_duration_ms', {
390
+ const durationMs = Metric.timer('workflow_duration_ms', {
382
391
  boundaries: Metric.boundariesFromIterable([10, 50, 100, 250, 500, 1000])
383
392
  });
384
393
  const failures = Metric.counter('workflow_failures_total');
@@ -387,7 +396,7 @@ const workflow = Effect.fn('Workflow.run')(function* (requestId: string) {
387
396
  yield* Effect.annotateCurrentSpan('requestId', requestId);
388
397
  yield* Effect.logInfo('workflow started');
389
398
  return 'ok';
390
- }).pipe(
399
+ },
391
400
  Effect.withLogSpan('workflow.run'),
392
401
  Effect.annotateLogs({ service: 'my-app' }),
393
402
  Effect.trackDuration(durationMs),
@@ -418,7 +427,7 @@ const program = Effect.sleep(pollInterval).pipe(Effect.timeout(timeout));
418
427
  - `Schema.OptionFromNullishOr`
419
428
  - `Schema.OptionFromOptionalKey`
420
429
  - `Schema.OptionFromOptional`
421
- - Reference: [Schema Option helpers](packages/effect/src/Schema.ts:5422) (via effect_ref_read) and [Schema optional field docs](packages/effect/SCHEMA.md:636) (via effect_ref_read).
430
+ - Reference: `Schema.OptionFrom*` in `packages/effect/src/Schema.ts` and optional fields in `packages/effect/SCHEMA.md`.
422
431
 
423
432
  Example:
424
433
 
@@ -439,7 +448,7 @@ export class AccountInput extends Schema.Class<AccountInput>('AccountInput')({
439
448
  - Data-first: `fn(self, arg)`
440
449
  - Data-last: `pipe(self, fn(arg))`
441
450
  - Build these helpers with `dual` from `effect/Function`.
442
- - Reference: [dual API](packages/effect/src/Function.ts:106) (via effect_ref_read).
451
+ - Reference: `dual` in `packages/effect/src/Function.ts`.
443
452
 
444
453
  Example:
445
454
 
@@ -492,7 +501,7 @@ You are not done if these fail:
492
501
  - Application entrypoints and tests may execute effects with `Effect.run*`.
493
502
  - Library and domain exports should return `Effect` values.
494
503
  - Keep runtime execution in one place so wiring, logging, and lifecycle behavior stay auditable.
495
- - Reference: [runPromise](packages/effect/src/Effect.ts:8423) (via effect_ref_read), [runSync](packages/effect/src/Effect.ts:8606) (via effect_ref_read), and [runFork](packages/effect/src/Effect.ts:8264) (via effect_ref_read).
504
+ - Reference: `runPromise`, `runSync`, and `runFork` in `packages/effect/src/Effect.ts`.
496
505
 
497
506
  Example:
498
507
 
@@ -530,7 +539,8 @@ const readSdkValue = (client: ExternalSdk) =>
530
539
  - Use `Effect.acquireUseRelease` for acquisition/use/release flows.
531
540
  - Prefer `Effect.scoped` for helper composition that allocates resources.
532
541
  - Do not manually open resources without an explicit finalization strategy.
533
- - Reference: [acquireUseRelease](packages/effect/src/Effect.ts:6254) (via effect_ref_read) and [scoped](packages/effect/src/Effect.ts:6079) (via effect_ref_read).
542
+ - Reference: `acquireUseRelease` and `scoped` in `packages/effect/src/Effect.ts`.
543
+ - For pool checkouts in rc.112 use `Pool.use(pool, callback)` to return the item on every exit without adding a caller `Scope` requirement. Do not return an item from `Effect.scoped(Pool.get(pool))` and then use it after release.
534
544
 
535
545
  Example:
536
546
 
@@ -549,7 +559,7 @@ const withConnection = <A, E, R>(
549
559
  - Keep retry policy close to the failing effect.
550
560
  - Retry only proven-idempotent operations at the narrowest boundary that can classify the failure.
551
561
  - Let exhausted failures remain visible unless the boundary has a truthful fallback.
552
- - Reference: [retry](packages/effect/src/Effect.ts:3978) (via effect_ref_read).
562
+ - Reference: `retry` in `packages/effect/src/Effect.ts` and the Schedule cookbook.
553
563
 
554
564
  Example:
555
565
 
@@ -564,17 +574,18 @@ const resilientFetch = fetchRemote.pipe(Effect.retry(Schedule.recurs(3)));
564
574
  - Use `Effect.timeoutOption` when timeout should become `Option.None`.
565
575
  - Use `Effect.timeoutOrElse` when timeout should produce a typed fallback effect.
566
576
  - Avoid manually racing ad-hoc timers for business logic timeouts.
567
- - Reference: [timeoutOption](packages/effect/src/Effect.ts:4421) (via effect_ref_read) and [timeoutOrElse](packages/effect/src/Effect.ts:4467) (via effect_ref_read).
577
+ - Reference: `timeoutOption` and `timeoutOrElse` in `packages/effect/src/Effect.ts`.
568
578
 
569
579
  Example:
570
580
 
571
581
  ```ts
572
582
  import { Duration, Effect } from 'effect';
573
583
 
584
+ declare const slowLookup: Effect.Effect<string>;
574
585
  const lookupCachedOnTimeout = slowLookup.pipe(
575
586
  Effect.timeoutOrElse({
576
587
  duration: Duration.seconds(2),
577
- onTimeout: () => Effect.succeed('cached-value')
588
+ orElse: () => Effect.succeed('cached-value')
578
589
  })
579
590
  );
580
591
  ```
@@ -584,7 +595,7 @@ const lookupCachedOnTimeout = slowLookup.pipe(
584
595
  - Prefer `Effect.forkChild` so lifecycle is supervised by parent scope.
585
596
  - Use `Effect.forkDetach` only for explicit daemon semantics.
586
597
  - Make fork intent explicit in code review and comments for detached work.
587
- - Reference: [forkChild](packages/effect/src/Effect.ts:7978) (via effect_ref_read) and [forkDetach](packages/effect/src/Effect.ts:8121) (via effect_ref_read).
598
+ - Reference: `forkChild` and `forkDetach` in `packages/effect/src/Effect.ts`.
588
599
 
589
600
  Example:
590
601
 
@@ -621,7 +632,7 @@ const hydrateUsers = (ids: ReadonlyArray<string>) =>
621
632
  - Use `Config` and `ConfigProvider` for configuration loading and parsing.
622
633
  - Keep direct `process.env` access out of domain code.
623
634
  - Layer/provide config sources explicitly for tests and non-default environments.
624
- - Reference: [Config](packages/effect/src/Config.ts) (via effect_ref_read) and [ConfigProvider](packages/effect/src/ConfigProvider.ts:358) (via effect_ref_read).
635
+ - Reference: `packages/effect/CONFIG.md`, `packages/effect/src/Config.ts`, and `ConfigProvider.ts`.
625
636
 
626
637
  Example:
627
638
 
@@ -638,7 +649,7 @@ const loadPort = Effect.fn('Config.loadPort')(function* () {
638
649
  - Use `Config.redacted` for secret config values.
639
650
  - Use `Redacted.make` for sensitive values coming from non-config sources.
640
651
  - Never log secret values after unwrapping.
641
- - Reference: [Config.redacted](packages/effect/src/Config.ts:1161) (via effect_ref_read) and [Redacted](packages/effect/src/Redacted.ts) (via effect_ref_read).
652
+ - Reference: `Config.redacted` in `packages/effect/src/Config.ts` and `packages/effect/src/Redacted.ts`.
642
653
 
643
654
  Example:
644
655
 
@@ -681,7 +692,7 @@ const findUserOptional = (id: string) =>
681
692
  - Unrecoverable infrastructure failures where surfacing the error provides no actionable recovery path (e.g., the data directory is unwritable).
682
693
  - Discarding irrelevant upstream error types: when a consuming service cannot meaningfully recover from a dependency's error type and the error is not part of the consumer's own contract, `Effect.orDie` is legitimate. For example, a config loader that depends on an auth service may use `yield* authSvc.all().pipe(Effect.orDie)` because auth failures during config loading are unrecoverable.
683
694
  - Do not model normal user-facing errors as defects.
684
- - Reference: [die](packages/effect/src/Effect.ts:1745) (via effect_ref_read) and [orDie](packages/effect/src/Effect.ts:3557) (via effect_ref_read).
695
+ - Reference: `die` and `orDie` in `packages/effect/src/Effect.ts`.
685
696
 
686
697
  Example:
687
698
 
@@ -710,7 +721,7 @@ const validateInput = Effect.fn('Input.validate')(function* (value: string) {
710
721
  - Document why isolation is necessary for behavior-sensitive paths.
711
722
  - Compose `defaultLayer` values directly by default.
712
723
  - Use `Layer.suspend(() => ...)` only when import evaluation order or a real circular dependency requires deferred composition.
713
- - Reference: [Effect.provide local option](packages/effect/src/Effect.ts:5592) (via effect_ref_read) and [Layer.fresh](packages/effect/src/Layer.ts:1621) (via effect_ref_read).
724
+ - Reference: `Effect.provide` and `Layer.fresh` in `packages/effect/src/{Effect,Layer}.ts`.
714
725
 
715
726
  Example:
716
727
 
@@ -751,7 +762,8 @@ export class CreateOrderInput extends Schema.Class<CreateOrderInput>(
751
762
  - Put defaults in schema definitions, not in handler/service fallback object literals.
752
763
  - Use `Schema.withConstructorDefault` for constructor-time defaults.
753
764
  - Use `Schema.withDecodingDefault` / `Schema.withDecodingDefaultKey` for decode-time defaults.
754
- - Constructor defaults may fail with `SchemaIssue.Issue`. Likewise, `Schema.makeEffect` returns validation failures directly as `SchemaIssue.Issue`, not wrapped in `Schema.SchemaError`.
765
+ - Constructor defaults may fail with `SchemaIssue.Issue`. Likewise, `MySchema.makeEffect(fields)` returns validation failures directly as `SchemaIssue.Issue`, not wrapped in `Schema.SchemaError`.
766
+ - Constructor defaults (including `Schema.tag`) do not automatically apply during boundary decoding. Unknown input uses `Schema.decodeUnknownEffect`; `decodeSync` is not a constructor replacement.
755
767
 
756
768
  Example:
757
769
 
@@ -982,6 +994,7 @@ const UnknownToString = Schema.Unknown.pipe(
982
994
  - For invalidatable caches, use `Effect.cachedInvalidateWithTTL(effect, Duration.infinity)` which returns a `[cachedEffect, invalidate]` tuple. Call `yield* invalidate` to force re-computation on next access.
983
995
  - For time-based caches, use `Effect.cachedWithTTL(effect, duration)`.
984
996
  - Prefer `Effect.cachedInvalidateWithTTL` with `Duration.infinity` over mutable `let` rebinding of cached effects.
997
+ - For keyed scoped resources, rc.112 adds `RcMap.getOption` and `LayerMap.contextEffectOption`. They atomically retain already-cached entries and propagate acquisition failures; `None` means missing/closed, not failed. A `has` check followed by `get` is not equivalent.
985
998
 
986
999
  Example:
987
1000
 
@@ -1,18 +1,31 @@
1
1
  # Agent Rules
2
2
 
3
+ The bundled guidance targets **Effect 4.0.0-rc.112**. Read the consuming project's
4
+ version before applying an API: stable v3, older prereleases, and unreleased main
5
+ can have different contracts. Keep directly used Effect-family packages on
6
+ compatible release versions.
7
+
3
8
  Load all relevant skills before writing or planning any code. Effect is a massive ecosystem — without loading skills you will write outdated v3 code or miss high-leverage libraries. Load AT LEAST 4 `effect-*` skills before any Effect work.
4
9
 
5
10
  When skills leave any ambiguity, or when you encounter unfamiliar APIs during implementation, read the OpenCode `effect` reference at `~/.local/share/opencode/repos/github.com/Effect-TS/effect@main/`. Treat this reference as the source of truth over `node_modules`, stale external docs, or memory.
6
11
 
12
+ Check the reference revision too. For this baseline, inspect the
13
+ `effect@4.0.0-rc.112` tag (for example with `git show
14
+ effect@4.0.0-rc.112:packages/effect/src/Schema.ts`) when main has moved ahead.
15
+ Source symbols and signatures at that tag take precedence over stale prose or
16
+ line-number links. Public exports marked `@internal` in source are not application APIs.
17
+
7
18
  ## Skill routing
8
19
 
9
20
  Load every branch that the task crosses:
10
21
 
11
22
  - Schemas, brands, variants, optionality, or decoding: `effect-schema-v4`, `effect-schema-composition`, and `effect-domain-modeling`.
23
+ - Binary schema codecs and framed binary streams: `effect-schema-composition` and `effect-stream`; RPC serialization also needs `effect-rpc-client` / `effect-rpc-server`.
12
24
  - Services, layers, runtime wiring, or scoped lifetimes: `effect-service-implementation`, `effect-layer-design`, `effect-scope`, and `effect-fiber`.
13
25
  - Configuration or secrets: `effect-config`.
14
26
  - Retry, repeat, polling, backoff, pacing, or recurrence: `effect-scheduling` plus the relevant error, HTTP, or testing skill.
15
27
  - Memoization, keyed caches, or request batching: `effect-cache` and `effect-batching`.
28
+ - Retained keyed resources or pooled checkout: `effect-cache`, `effect-layer-design`, and `effect-scope`.
16
29
  - Streams, queues, pubsubs, pagination, or backpressure: `effect-stream` and the relevant concurrency skill.
17
30
  - Outgoing HTTP: `effect-http-client` plus the relevant platform-layer skill.
18
31
  - Effect tests, virtual time, or concurrent synchronization: `effect-testing` and `effect-concurrency-testing`.