Skip to content

docs(effect): record rc.112 finalizer, abortSignal, and language-service caveats - #531

Merged
ScriptedAlchemy merged 2 commits into
mainfrom
docs/effect-conventions-caveats
Sep 4, 2026
Merged

docs(effect): record rc.112 finalizer, abortSignal, and language-service caveats#531
ScriptedAlchemy merged 2 commits into
mainfrom
docs/effect-conventions-caveats

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Docs-only follow-up to the Effect conformance PRs (#512, #513, #516, #519, #520, #522). Records, in docs/effect-conventions.md, the places where the vendored guidance (repos/effect/LLMS.md, agent-patterns/*; the latter is repo-owned and is corrected where it was wrong) contradicts the pinned effect@4.0.0-rc.112 source or the repo's practice.

Changes

  1. Stage 3 "finalizers are infallible by type" corrected. True for Effect.acquireRelease (release: (a, exit) => Effect<unknown, never, R>) and Effect.addFinalizer (Effect<void, never, R>); not for Effect.acquireUseRelease's release or Effect.onExit/ensuring handlers, which rc.112 types Effect<void, E3, R3> and merges via combineFinalizerCauseCause.combine(useCause, handlerCause). Cause.squash returns the first Fail reason, so that merge is first-failure-wins at the boundary. The explicit Effect.exit sequence (refactor(dev): finish the coordinator's Effect orchestration; fan out epoch-store reads with Effect.forEach #513 DevCoordinatorCloseError, refactor(events): report IPC claim and endpoint teardown failures instead of ignoring them #516 IPC claim release / socket removal) is named as the sanctioned way to get last-failure-wins. Source: effect/dist/internal/effect.js combineFinalizerCause, causeCombine, causeSquash; Effect.d.ts signatures.
  2. Scope rules: Effect.abortSignal caveat. rc.112 is acquireRelease(sync(() => new AbortController()), c => sync(() => c.abort())) mapped to .signal — aborts only on scope close, no reason, no controller handle. A contract that must abort with a reason owns the controller as the scoped resource (refactor(dev): type MCP session lifecycle failures and scope the tool-call abort controller #512 #admitRequest + AbortSignal.any).
  3. Language-service caveat. agent-patterns/effect-scope.md § AbortSignal cites an abortControllerInEffect rule that does not exist in @effect/language-service@0.87.2; the real *InEffect* rules are listed (from the installed package's rule table).
  4. New "Open decisions (maintainer)" section, not decided: isRecord (two local guards, ~400 call sites) vs LLMS.md § Predicate (rc.112 has Predicate.isObject/isObjectOrArray, no isRecord); Data.Error (yieldable, untagged, rc.112 Cause.YieldableError) as an option for internal class errors that currently need Effect.fail(...), with the existing +12 kB hook-size measurement and the public-contract constraint noted.

Notes

Review status

Author posts no PR comments; thread dispositions are recorded here.

  • Codex review of 9ffa847 (2 threads, both addressed in e0b2f5b):
    • "Update the editable scope pattern itself" — correct: agent-patterns/effect-scope.md is a tracked root-level file, not under repos/. Its § AbortSignal now states the rc.112 contract (scope-close abort, no reason, controller never exposed), names the owned-controller shape for reason-carrying aborts, and drops the nonexistent abortControllerInEffect rule. The conventions caveat says the pattern was corrected and keeps the real *InEffect* rule list for the re-pin check.
    • "Inventory all existing isRecord implementations" — correct. The decision record now separates the shared guards (core/strict-json.ts isRecord/isJsonRecord/isPlainRecord, workbench/src/client-helpers.ts) from the fifteen private isRecord copies (enumerated by module), the seven local aliases, and the five copies emitted as strings into generated hook/proxy/sandbox source (which stay: that JS imports nothing).
  • Last reviewed head: 9ffa847 (Codex, 2 threads, both fixed). Unreviewed head: e0b2f5b (docs-only follow-up commit addressing those threads). No fresh review arrived in ~10 minutes and the author posts no PR comments, so the PR merges on green CI per the reviewer-quota fallback; re-request once credits return.

@ScriptedAlchemy ScriptedAlchemy added the skip-changeset PR changes a publishable package but ships no observable change; changeset not required label Sep 4, 2026
@changeset-bot

changeset-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: e0b2f5b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T06:00:14.212076Z 9ffa847 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9ffa847fd7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/effect-conventions.md Outdated
Comment on lines +101 to +103
- Caveat on `agent-patterns/effect-scope.md` § AbortSignal (vendored under
`repos/`, so not editable here): the language-service rule it names,
`abortControllerInEffect`, does not exist in `@effect/language-service@0.87.2`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the editable scope pattern itself

agent-patterns/effect-scope.md is a tracked root-level file, not vendored under repos/, and it still tells developers that abortControllerInEffect enforces this rule. Since contributors are directed to read that pattern before writing Effect code, adding a caveat here while incorrectly declaring the source uneditable leaves the primary guidance knowingly inaccurate; correct the pattern itself.

AGENTS.md reference: AGENTS.md:L128-L133

Useful? React with 👍 / 👎.

Comment thread docs/effect-conventions.md Outdated
Comment on lines +558 to +562
- **`isRecord` vs `Predicate`.** `LLMS.md` § Predicate says never to write
helpers like `isRecord` and to use the `Predicate` module. The repo has two
hand-written guards — `core/strict-json.ts` `isRecord` (non-null,
non-array object) and `workbench/src/client-helpers.ts` `isRecord` — with
roughly 400 call sites across the three packages, against about a dozen

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Inventory all existing isRecord implementations

The tree has substantially more than these two hand-written guards: repo-wide search also finds independent implementations in build/pack-inventory.ts, install/{doctor,install}.ts, several host-contract validators, and multiple MCP modules. As written, this decision record understates what either option touches and a migration based on it would leave the same divergence in place; distinguish the sanctioned shared helpers from the remaining local copies or enumerate those copies.

AGENTS.md reference: AGENTS.md:L17-L24

Useful? React with 👍 / 👎.

@pkg-pr-new

pkg-pr-new Bot commented Sep 4, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@531
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@531
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@531

commit: e0b2f5b

@ScriptedAlchemy
ScriptedAlchemy merged commit c11746e into main Sep 4, 2026
13 checks passed
@ScriptedAlchemy
ScriptedAlchemy deleted the docs/effect-conventions-caveats branch September 4, 2026 06:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changeset PR changes a publishable package but ships no observable change; changeset not required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant