Under the hood

Effect integration workflows

Understand bounded integration execution, interruption, resource ownership, and fail-closed recovery.

v0.3.0 referenceReviewed

On this page

Hopya uses stable Effect 4.0.0 on Node 24 (upstream review: 2026-10-02). The API declares ^4.0.0; its lockfile pins the release.

Documentation: reference table
OwnerResponsibility
Adonis / LucidAuthentication, permissions, SQL transactions, migrations
EffectIntegration failures, resource lifetimes, bounded concurrency

Native v4 migration

Native v4 migration: reference table
Native APIBehavior
Effect.resultSuccess.success / Failure.failure, replacing either and Right/Left
Effect.callbackNode callbacks with interruption finalizer
catch / catchCauseNative v4 failure/cause handling
timeoutOrElse({duration,orElse})Native deadline handling
SemaphoreBounded admission/concurrency
fnUntracedReusable integration generators; runtime execution at Promise/worker boundaries
Graph actionsCompose HTTP, credential, SMTP Effects directly

Expected failures belong in try, tryPromise, or fail. Exceptions from sync/gen or rejected promise calls are defects; result handles expected failures, not defects. This migration does not reclassify a database outage as invalid credentials.

Cause identity and Promise boundaries
  • v4 Causes use flat reasons; native runPromise/runSync squash to original failures/defects, not v3’s FiberFailure.
  • Hopya’s runSyncThrow/runPromiseThrow inspect Exit, preserve original identity including HttpError, and normalize interruption-only causes to AbortError. The Promise bridge accepts an abort signal and still supports intentionally propagated database/security defects.

Durable automation execution

Durable automation execution: reference table
BoundaryBehavior
QueueDatabase authoritative; event enqueue commits with originating audited mutation
VersionsImmutable; task updates use publisher’s workspace service with causation/re-entry limits
ClaimsFour-run batches, concurrency four
Failure isolationEach run captures its own Exit, including defects; siblings continue
Failed attemptRunning nodes/steps fail, untouched ones skip in one lease-checked transaction; delivered output retained
Completion / legacy acknowledgmentCurrent lease required
Expired graph, linear, webhook leaseFail closed; no automatic replay
Recovery storage unavailableKeep lease for fail-closed expiry, never report success

Failure does not prove a remote write failed. Inspect its outcome before explicitly starting another attempt. No delivery, token exchange, SQL write, or task mutation is blindly retried.

Database lifetime and SQLite worker serialization
  • Lucid Promises cannot be cancelled. Wait for their actual outcome before releasing worker ownership or terminal recovery on interruption.
  • SQLite state operations serialize separately from concurrent network work: synchronous better-sqlite3 busy waits otherwise block another same-event-loop transaction’s commit.
  • PostgreSQL keeps concurrent state operations. Stored-data/state-I/O errors are explicit sanitized failures.

Transport and credential lifetimes

Transport and credential lifetimes: reference table
WorkflowAdmission / deadlineResource and security ownership
DNSFive secondsCancellable resolver, concurrent A/AAAA checks; both families checked before address pin
Pinned HTTPAbsolute/socket deadlines; body/output boundsFresh socket per resolution; no redirects; destroy request/response on interruption; native header/config errors sanitized
Graph dispatchPublisher checks before each node and after DNS/OAuthLease guards task writes/outcomes; credential origin/path/workspace binding, encryption/revocation/redaction remain enforced
OAuthFour permits; 20 seconds including admissionAwait single-flight refresh through encrypted-token persistence before releasing ownership/lock; SQLite persistence serialized
SMTPTwo permits; 15 seconds including admissionAbort controller, transport, actual connection/TLS sockets; cleanup on success/failure/timeout/interruption; native errors sanitized

Nodemailer’s close() alone cannot stop active delivery; cleanup also aborts/destroys sockets during connection and TLS upgrade.

Other reviewed boundaries

Other reviewed boundaries: reference table
BoundaryReview
AgentEffect interruption + browser disconnect + 45-second deadline; admission before awaited context query closes four-request race; bounded response/current permissions retained
Origin middlewareExpected rejection uses failure channel, not Promise defect
OIDCNative outer deadline plus SDK request timeout; outer interruption does not itself abort openid-client’s Promise; shared discovery/config not mutated per caller
Live SQLShared failure bridge, request-owned clients, driver deadlines, finally; no blanket timeout/retry around writes
Pure validation / OpenAPI / bulk admissionNative API migration only
Storage / appearanceCollector database-error accounting and expected missing-logo failure channel

Verification boundaries

Historical upstream records, not checks newly run for this documentation site:

Verification boundaries: reference table
EvidenceRecorded result
Focused Node24 API workTypecheck + 54 tests across automations/transport/core/accounts/SSO/agent-lifecycle/HTTP; real 45-second deadline
Integrated 2026-10-02 checkAPI/web/operator typechecks; 125 API, 73 web unit, eight initializer tests; both builds
StreamReal deadline + complete 42,707,557-byte / 800-item snapshot
PackagingCompose config/whitespace pass; existing Vite large-chunk advisory
DependenciesOnly Effect 4.0.0; zero reported audit vulnerabilities
Unverified external behaviorActual SMTP/TLS deployments, OAuth/OIDC providers, PostgreSQL worker execution, DNS failure modes, process-kill recovery
BrowserNo Playwright/browser workflow verification
Regression coverage and local fixture evidence
  • Coverage: failure/defect identity, cleanup, invalid-header isolation, DNS cancellation, local SMTP interruption/permit reuse/delivery, bounded claims, acknowledgment failure after remote acceptance, sibling completion, expired-lease non-replay.
  • Existing tests retain immutable version/branch/lease/permission/secret/OAuth-state/request/re-entry checks.
  • Disposable implicit-TLS SMTP fixture verified post-handshake cleanup and subsequent delivery. Self-signed trust bypass was fixture-only; key/certificate removed.
  • Initial automation runs exposed SQLite worker locking, repaired before passing rerun. Local fixtures and simulated stale leases are limited evidence, not production-readiness certification.

Official references