diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,10 @@
+# Changelog for penelope-effects
+
+## 0.1.0.0 — Initial Release
+
+- Domain effect battery for Penelope.
+- Heftia-style unary monadic facade (`Eff`, `sendUnary`, `interpretUnary`).
+- Kernmantle-style binary profunctor facade (`Flow`, `sendBinary`, `interpretBinary`).
+- Standard effect suite: `State`, `Reader`, `Writer`, `Error`, `Coroutine`, `UnliftIO`, `Scoped`, `Concurrent`.
+- Scoped semantics with robust continuation capturing and branch safety.
+- Comprehensive allocation and throughput benchmarks.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,189 @@
+EUROPEAN UNION PUBLIC LICENCE v. 1.2
+EUPL © the European Union 2007, 2016
+
+This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined below) which is provided under the
+terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such
+use is covered by a right of the copyright holder of the Work).
+The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following
+notice immediately following the copyright notice for the Work:
+                          Licensed under the EUPL
+or has expressed by any other means his willingness to license under the EUPL.
+
+1.Definitions
+In this Licence, the following terms have the following meaning:
+— ‘The Licence’:this Licence.
+— ‘The Original Work’:the work or software distributed or communicated by the Licensor under this Licence, available
+as Source Code and also as Executable Code as the case may be.
+— ‘Derivative Works’:the works or software that could be created by the Licensee, based upon the Original Work or
+modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work
+required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in
+the country mentioned in Article 15.
+— ‘The Work’:the Original Work or its Derivative Works.
+— ‘The Source Code’:the human-readable form of the Work which is the most convenient for people to study and
+modify.
+— ‘The Executable Code’:any code which has generally been compiled and which is meant to be interpreted by
+a computer as a program.
+— ‘The Licensor’:the natural or legal person that distributes or communicates the Work under the Licence.
+— ‘Contributor(s)’:any natural or legal person who modifies the Work under the Licence, or otherwise contributes to
+the creation of a Derivative Work.
+— ‘The Licensee’ or ‘You’:any natural or legal person who makes any usage of the Work under the terms of the
+Licence.
+— ‘Distribution’ or ‘Communication’:any act of selling, giving, lending, renting, distributing, communicating,
+transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential
+functionalities at the disposal of any other natural or legal person.
+
+2.Scope of the rights granted by the Licence
+The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for
+the duration of copyright vested in the Original Work:
+— use the Work in any circumstance and for all usage,
+— reproduce the Work,
+— modify the Work, and make Derivative Works based upon the Work,
+— communicate to the public, including the right to make available or display the Work or copies thereof to the public
+and perform publicly, as the case may be, the Work,
+— distribute the Work or copies thereof,
+— lend and rent the Work or copies thereof,
+— sublicense rights in the Work or copies thereof.
+Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the
+applicable law permits so.
+In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed
+by law in order to make effective the licence of the economic rights here above listed.
+The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the
+extent necessary to make use of the rights granted on the Work under this Licence.
+
+3.Communication of the Source Code
+The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as
+Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with
+each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to
+the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to
+distribute or communicate the Work.
+
+4.Limitations on copyright
+Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the
+exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations
+thereto.
+
+5.Obligations of the Licensee
+The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those
+obligations are the following:
+
+Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to
+the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the
+Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work
+to carry prominent notices stating that the Work has been modified and the date of modification.
+
+Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this
+Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless
+the Original Work is expressly distributed only under this version of the Licence — for example by communicating
+‘EUPL v. 1.2 only’. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the
+Work or Derivative Work that alter or restrict the terms of the Licence.
+
+Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both
+the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done
+under the terms of this Compatible Licence. For the sake of this clause, ‘Compatible Licence’ refers to the licences listed
+in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with
+his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail.
+
+Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide
+a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available
+for as long as the Licensee continues to distribute or communicate the Work.
+Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names
+of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and
+reproducing the content of the copyright notice.
+
+6.Chain of Authorship
+The original Licensor warrants that the copyright in the Original Work granted hereunder is owned by him/her or
+licensed to him/her and that he/she has the power and authority to grant the Licence.
+Each Contributor warrants that the copyright in the modifications he/she brings to the Work are owned by him/her or
+licensed to him/her and that he/she has the power and authority to grant the Licence.
+Each time You accept the Licence, the original Licensor and subsequent Contributors grant You a licence to their contributions
+to the Work, under the terms of this Licence.
+
+7.Disclaimer of Warranty
+The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work
+and may therefore contain defects or ‘bugs’ inherent to this type of development.
+For the above reason, the Work is provided under the Licence on an ‘as is’ basis and without warranties of any kind
+concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or
+errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this
+Licence.
+This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work.
+
+8.Disclaimer of Liability
+Except in the cases of wilful misconduct or damages directly caused to natural persons, the Licensor will in no event be
+liable for any direct or indirect, material or moral, damages of any kind, arising out of the Licence or of the use of the
+Work, including without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, loss
+of data or any commercial damage, even if the Licensor has been advised of the possibility of such damage. However,
+the Licensor will be liable under statutory product liability laws as far such laws apply to the Work.
+
+9.Additional agreements
+While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services
+consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole
+responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify,
+defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by
+the fact You have accepted any warranty or additional liability.
+
+10.Acceptance of the Licence
+The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ placed under the bottom of a window
+displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of
+applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms
+and conditions.
+Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You
+by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution
+or Communication by You of the Work or copies thereof.
+
+11.Information to the public
+In case of any Distribution or Communication of the Work by means of electronic communication by You (for example,
+by offering to download the Work from a remote location) the distribution channel or media (for example, a website)
+must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence
+and the way it may be accessible, concluded, stored and reproduced by the Licensee.
+
+12.Termination of the Licence
+The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms
+of the Licence.
+Such a termination will not terminate the licences of any person who has received the Work from the Licensee under
+the Licence, provided such persons remain in full compliance with the Licence.
+
+13.Miscellaneous
+Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the
+Work.
+If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or
+enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid
+and enforceable.
+The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of
+the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence.
+New versions of the Licence will be published with a unique version number.
+All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take
+advantage of the linguistic version of their choice.
+
+14.Jurisdiction
+Without prejudice to specific agreement between parties,
+— any litigation resulting from the interpretation of this License, arising between the European Union institutions,
+bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice
+of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union,
+— any litigation arising between other parties and resulting from the interpretation of this License, will be subject to
+the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business.
+
+15.Applicable Law
+Without prejudice to specific agreement between parties,
+— this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat,
+resides or has his registered office,
+— this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside
+a European Union Member State.
+
+Appendix
+
+‘Compatible Licences’ according to Article 5 EUPL are:
+— GNU General Public License (GPL) v. 2, v. 3
+— GNU Affero General Public License (AGPL) v. 3
+— Open Software License (OSL) v. 2.1, v. 3.0
+— Eclipse Public License (EPL) v. 1.0
+— CeCILL v. 2.0, v. 2.1
+— Mozilla Public Licence (MPL) v. 2
+— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3
+— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software
+— European Union Public Licence (EUPL) v. 1.1, v. 1.2
+— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+).
+
+The European Commission may update this Appendix to later versions of the above licences without producing
+a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the
+covered Source Code from exclusive appropriation.
+All other changes or additions to this Appendix require the production of a new EUPL version.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,10 @@
+# penelope-effects
+
+Domain package for penelope-effects
+
+## Modules
+
+
+## License
+
+EUPL-1.2
diff --git a/bench/Main.hs b/bench/Main.hs
new file mode 100644
--- /dev/null
+++ b/bench/Main.hs
@@ -0,0 +1,475 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# OPTIONS_GHC -fplugin=Polytropos.Plugin #-}
+
+{- |
+Module      : Main
+Description : Milestone 6.4 Allocation & Throughput Benchmarks
+Copyright   : (c) 2026 The Penelope Authors
+License     : EUPL-1.2 OR Apache-2.0
+Maintainer  : nadia.yvette.chambers@ik.me
+Stability   : experimental
+Portability : non-portable (GHC extensions)
+
+Comprehensive Criterion/Gauge compatible benchmarks via 'tasty-bench':
+1. Deep First-Order Effect Stacks (D = 30):
+   Demonstrates \(O(1)\) branchless vector indexing vs \(O(D)\) freer sum peeling.
+2. Deep Higher-Order Scoped Elaboration (H = 15):
+   Demonstrates single-pass bottom-up elaboration vs multi-pass linear tree traversal.
+3. Wide Register Frames (m, n = 20 ports):
+   Demonstrates \(O(1)\) static 'RowMorph' gather-scatter vs \(O(N)\) record/lens traversal.
+4. Surface Facades Throughput & Allocation ('Eff' & 'Rope'):
+   Measures monadic and arrow composition overhead vs pure baselines.
+5. Scoped Semantics & Delimited Continuations:
+   Measures 'local', 'catchError', and multi-shot coroutine resumption overhead.
+
+See Note [Core Architecture] [ref:note-core-architecture],
+Note [Unpacked Polycategorical Representation] [ref:note-unpacked-representation],
+Note [Reified Row Morphisms and Gather-Scatter] [ref:note-row-morph-routing],
+Note [Two-Phase Weaving and Unweaving] [ref:note-two-phase-engine], and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+module Main (main) where
+
+import qualified Control.Arrow as Arrow
+import qualified Control.Category as Cat
+import Data.Functor.Identity (Identity (..))
+import Data.Primitive.SmallArray (indexSmallArray, smallArrayFromList)
+import GHC.Exts (Any, Word#, unsafeCoerce#)
+import Penelope.Core
+  ( BranchCont (..)
+  , Elaborator (..)
+  , FrameKleisli (..)
+  , Handler (..)
+  , MapRow
+  , Penelope (..)
+  , PolyEffect
+  , PolyHEffect
+  , PortSig (..)
+  , Region (..)
+  , elaborateAll
+  , interpretAll
+  , preComposeRoute
+  , runFrameKleisli
+  , seqPenelope
+  )
+import Penelope.Effects
+  ( AskEff (..)
+  , Eff
+  , NonDetEff (..)
+  , Rope
+  , ThrowEff (..)
+  , UnaryEffect
+  , askReader
+  , branch
+  , catchError
+  , local
+  , nonDetHandler
+  , runEff
+  , runErrorPure
+  , runReaderPure
+  , runRopePure
+  , runEffM
+  )
+import Polytropos (Field (..), Pair (..), Record, emptyRecord, insertField)
+import Polytropos.Core (Rep (..), RowRep (..))
+import Polytropos.RowMorph (RowMorph, gatherRep, unsafeMkRowMorph)
+import Prelude hiding (id, (.))
+import qualified Prelude as P
+import Test.Tasty.Bench
+  ( bench
+  , bgroup
+  , defaultMain
+  , nf
+  , whnf
+  )
+
+{-------------------------------------------------------------------------------
+  Suite 1: Deep First-Order Effect Stacks (D = 30)
+  See Note [Unpacked Polycategorical Representation] [ref:note-unpacked-representation]
+  and Note [Two-Phase Weaving and Unweaving] [ref:note-two-phase-engine]
+-------------------------------------------------------------------------------}
+
+-- 30 distinct first-order effect kinds
+data Op01 :: PolyEffect
+data Op02 :: PolyEffect
+data Op03 :: PolyEffect
+data Op04 :: PolyEffect
+data Op05 :: PolyEffect
+data Op06 :: PolyEffect
+data Op07 :: PolyEffect
+data Op08 :: PolyEffect
+data Op09 :: PolyEffect
+data Op10 :: PolyEffect
+data Op11 :: PolyEffect
+data Op12 :: PolyEffect
+data Op13 :: PolyEffect
+data Op14 :: PolyEffect
+data Op15 :: PolyEffect
+data Op16 :: PolyEffect
+data Op17 :: PolyEffect
+data Op18 :: PolyEffect
+data Op19 :: PolyEffect
+data Op20 :: PolyEffect
+data Op21 :: PolyEffect
+data Op22 :: PolyEffect
+data Op23 :: PolyEffect
+data Op24 :: PolyEffect
+data Op25 :: PolyEffect
+data Op26 :: PolyEffect
+data Op27 :: PolyEffect
+data Op28 :: PolyEffect
+data Op29 :: PolyEffect
+data Op30 :: PolyEffect
+
+type OpRow30 =
+  '[ "op01" ':= Op01, "op02" ':= Op02, "op03" ':= Op03, "op04" ':= Op04, "op05" ':= Op05
+   , "op06" ':= Op06, "op07" ':= Op07, "op08" ':= Op08, "op09" ':= Op09, "op10" ':= Op10
+   , "op11" ':= Op11, "op12" ':= Op12, "op13" ':= Op13, "op14" ':= Op14, "op15" ':= Op15
+   , "op16" ':= Op16, "op17" ':= Op17, "op18" ':= Op18, "op19" ':= Op19, "op20" ':= Op20
+   , "op21" ':= Op21, "op22" ':= Op22, "op23" ':= Op23, "op24" ':= Op24, "op25" ':= Op25
+   , "op26" ':= Op26, "op27" ':= Op27, "op28" ':= Op28, "op29" ':= Op29, "op30" ':= Op30
+   ]
+
+-- | Build a Penelope chain of N operations targeting a specific constructor tag.
+mkChainPenelope :: Int -> Word# -> Penelope '[] OpRow30 '["x" ':= Int] '["x" ':= Int]
+mkChainPenelope 0 _ = Route (unsafeMkRowMorph [0])
+mkChainPenelope n tag# =
+  let retCont = BranchCont (\_outF -> mkChainPenelope (n - 1) tag#)
+      conts = RowRep (Rep 0 (smallArrayFromList [Identity (unsafeCoerce# retCont)]))
+  in OpF tag# (unsafeMkRowMorph [0]) (unsafeCoerce# (1 :: Int)) conts
+
+-- | Generic identity handler executing the continuation.
+genericHandler :: Handler '[] (FrameKleisli Identity) e
+genericHandler = Handler $ \_inMap _payload kConts ->
+  let !(Identity elabK) = indexSmallArray (let RowRep (Rep _ arr) = kConts in arr) 0
+      !(BranchCont retK) = unsafeCoerce# elabK
+  in FrameKleisli $ \inF -> runFrameKleisli (retK inF) inF
+
+-- | Construct the 30-element handler record.
+handlers30 :: Record (MapRow (Handler '[] (FrameKleisli Identity)) OpRow30)
+handlers30 =
+  let hAny = Identity (unsafeCoerce# (genericHandler @Op01))
+      arr = smallArrayFromList (replicate 30 hAny)
+  in RowRep (Rep 0 arr)
+
+-- | Run a Penelope chain of N operations at the given effect tag.
+runPenelopeChain :: Word# -> Int -> Int
+runPenelopeChain tag# n =
+  let prog = mkChainPenelope n tag#
+      inFrame = insertField (Field @"x") (42 :: Int) emptyRecord
+      kleisli = interpretAll handlers30 prog
+      outFrame = runIdentity (runFrameKleisli kleisli inFrame)
+      !(Identity valAny) = indexSmallArray (let RowRep (Rep _ arr) = outFrame in arr) 0
+  in (unsafeCoerce# valAny :: Int)
+
+-- | Freer open sum baseline modeling linear union peeling.
+data FreerSum = FreerLeaf !Int | FreerBranch !FreerSum
+
+decompFreer :: FreerSum -> Either FreerSum Int
+decompFreer = \case
+  FreerLeaf x   -> Right x
+  FreerBranch u -> Left u
+
+evalFreerAtDepth :: Int -> Int -> Int
+evalFreerAtDepth depth val =
+  let !tree = buildFreer depth val
+  in peelFreer depth tree
+  where
+    buildFreer :: Int -> Int -> FreerSum
+    buildFreer 0 x = FreerLeaf x
+    buildFreer k x = FreerBranch (buildFreer (k - 1) x)
+
+    peelFreer :: Int -> FreerSum -> Int
+    peelFreer 0 (FreerLeaf x) = x
+    peelFreer k (FreerBranch u) =
+      case decompFreer (FreerBranch u) of
+        Right x -> x
+        Left rest -> peelFreer (k - 1) rest
+    peelFreer _ _ = 0
+
+evalFreerChain :: Int -> Int -> Int
+evalFreerChain _depth 0 = 0
+evalFreerChain depth n =
+  let !res = evalFreerAtDepth depth n
+  in res + evalFreerChain depth (n - 1)
+
+{-------------------------------------------------------------------------------
+  Suite 2: Deep Higher-Order Scoped Elaboration (H = 15)
+  See Note [Two-Phase Weaving and Unweaving] [ref:note-two-phase-engine]
+-------------------------------------------------------------------------------}
+
+data Scope01 :: PolyHEffect
+data Scope02 :: PolyHEffect
+data Scope03 :: PolyHEffect
+data Scope04 :: PolyHEffect
+data Scope05 :: PolyHEffect
+data Scope06 :: PolyHEffect
+data Scope07 :: PolyHEffect
+data Scope08 :: PolyHEffect
+data Scope09 :: PolyHEffect
+data Scope10 :: PolyHEffect
+data Scope11 :: PolyHEffect
+data Scope12 :: PolyHEffect
+data Scope13 :: PolyHEffect
+data Scope14 :: PolyHEffect
+data Scope15 :: PolyHEffect
+
+type ScopeRow15 =
+  '[ "scope01" ':= Scope01, "scope02" ':= Scope02, "scope03" ':= Scope03
+   , "scope04" ':= Scope04, "scope05" ':= Scope05, "scope06" ':= Scope06
+   , "scope07" ':= Scope07, "scope08" ':= Scope08, "scope09" ':= Scope09
+   , "scope10" ':= Scope10, "scope11" ':= Scope11, "scope12" ':= Scope12
+   , "scope13" ':= Scope13, "scope14" ':= Scope14, "scope15" ':= Scope15
+   ]
+
+-- | Build a nested tree with H scoped regions.
+mkNestedScopes :: Int -> Penelope ScopeRow15 '[] '["x" ':= Int] '["x" ':= Int]
+mkNestedScopes 0 = Route (unsafeMkRowMorph [0])
+mkNestedScopes h =
+  let subRegion = Region @ScopeRow15 @'[] @('PortSig '["x" ':= Int] '["x" ':= Int]) (mkNestedScopes (h - 1))
+      regions = RowRep (Rep 0 (smallArrayFromList [Identity (unsafeCoerce# subRegion)]))
+      retCont = BranchCont (\_outF -> Route (unsafeMkRowMorph [0]))
+      conts = RowRep (Rep 0 (smallArrayFromList [Identity (unsafeCoerce# retCont)]))
+      tag# = case h of
+        1  -> 0##
+        2  -> 1##
+        3  -> 2##
+        4  -> 3##
+        5  -> 4##
+        6  -> 5##
+        7  -> 6##
+        8  -> 7##
+        9  -> 8##
+        10 -> 9##
+        11 -> 10##
+        12 -> 11##
+        13 -> 12##
+        14 -> 13##
+        _  -> 14##
+  in OpH tag# (unsafeMkRowMorph [0]) regions (unsafeCoerce# (0 :: Int)) conts
+
+genericElaborator :: Elaborator '[] '[] e
+genericElaborator = Elaborator $ \inMap regions _payload conts ->
+  let !(Identity regAny) = indexSmallArray (let RowRep (Rep _ arr) = regions in arr) 0
+      !(Region innerPipe) = unsafeCoerce# regAny
+      !(Identity elabK) = indexSmallArray (let RowRep (Rep _ arr) = conts in arr) 0
+      !(BranchCont retK) = unsafeCoerce# elabK
+  in preComposeRoute inMap (unsafeCoerce# (innerPipe `seqPenelope` retK (unsafeCoerce# emptyRecord)))
+
+elabs15 :: Record (MapRow (Elaborator '[] '[]) ScopeRow15)
+elabs15 =
+  let eAny = Identity (unsafeCoerce# (genericElaborator @Scope01))
+      arr = smallArrayFromList (replicate 15 eAny)
+  in RowRep (Rep 0 arr)
+
+runSinglePassElaboration :: Int -> Int
+runSinglePassElaboration h =
+  case elaborateAll elabs15 (mkNestedScopes h) of
+    !_ -> h
+
+-- Baseline multi-pass tree traversal:
+data ScopedTree = ScopedLeaf !Int | ScopedNode !Int ScopedTree
+
+buildScopedTree :: Int -> ScopedTree
+buildScopedTree 0 = ScopedLeaf 42
+buildScopedTree k = ScopedNode k (buildScopedTree (k - 1))
+
+multiPassElab :: Int -> ScopedTree -> ScopedTree
+multiPassElab 0 tree = tree
+multiPassElab passes tree = multiPassElab (passes - 1) (walkTree tree)
+  where
+    walkTree (ScopedLeaf x) = ScopedLeaf (x + 1)
+    walkTree (ScopedNode tag child) = ScopedNode tag (walkTree child)
+
+runMultiPassElaboration :: Int -> Int
+runMultiPassElaboration h =
+  let tree = buildScopedTree h
+      res = multiPassElab h tree
+  in case res of
+       ScopedLeaf x -> x
+       ScopedNode _ _ -> 0
+
+{-------------------------------------------------------------------------------
+  Suite 3: Wide Register Frames (m, n = 20 Ports)
+  See Note [Reified Row Morphisms and Gather-Scatter] [ref:note-row-morph-routing]
+-------------------------------------------------------------------------------}
+
+mkRep20 :: Rep Identity Any
+mkRep20 =
+  let arr = smallArrayFromList [Identity (unsafeCoerce# i) | i <- [0..19 :: Int]]
+  in Rep 0 arr
+
+morphId20 :: RowMorph Any Any
+morphId20 = unsafeMkRowMorph [0..19]
+
+morphRev20 :: RowMorph Any Any
+morphRev20 = unsafeMkRowMorph [19, 18 .. 0]
+
+morphProj10 :: RowMorph Any Any
+morphProj10 = unsafeMkRowMorph [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
+
+benchGatherRep :: RowMorph Any Any -> Int -> Int
+benchGatherRep morph iterations = go iterations
+  where
+    go 0 = 0
+    go k =
+      let !(Rep _ arr) = gatherRep morph mkRep20
+          !(Identity v) = indexSmallArray arr 0
+      in (unsafeCoerce# v :: Int) + go (k - 1)
+
+benchListTraversal :: Int -> Int
+benchListTraversal iterations = go iterations
+  where
+    initialList :: [Int]
+    initialList = [0..19]
+
+    go 0 = 0
+    go k =
+      let rev = reverse initialList
+          res = case rev of
+            (x : _) -> x
+            []      -> 0
+      in res + go (k - 1)
+
+{-------------------------------------------------------------------------------
+  Suite 4: Surface Facades (Unary Eff & Binary Rope)
+  See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades]
+-------------------------------------------------------------------------------}
+
+benchEffPureChain :: Int -> Int
+benchEffPureChain n = runEff (go n 0)
+  where
+    go :: Int -> Int -> Eff '[] '[] Int
+    go 0 !acc = pure acc
+    go k !acc = pure (acc + 1) >>= go (k - 1)
+
+benchIdentityPureChain :: Int -> Int
+benchIdentityPureChain n = runIdentity (go n 0)
+  where
+    go :: Int -> Int -> Identity Int
+    go 0 !acc = pure acc
+    go k !acc = pure (acc + 1) >>= go (k - 1)
+
+benchRopeChain :: Int -> Int -> Int
+benchRopeChain n input = runRopePure (buildRope n) input
+  where
+    buildRope :: Int -> Rope '[] '[] Int Int
+    buildRope 0 = Cat.id
+    buildRope k = Arrow.arr (+ 1) Cat.>>> buildRope (k - 1)
+
+benchFunctionChain :: Int -> Int -> Int
+benchFunctionChain n input = buildFn n input
+  where
+    buildFn :: Int -> (Int -> Int)
+    buildFn 0 = P.id
+    buildFn k = (+ 1) P.. buildFn (k - 1)
+
+{-------------------------------------------------------------------------------
+  Suite 5: Scoped Semantics & Delimited Continuations
+-------------------------------------------------------------------------------}
+
+benchLocalScope :: Int -> Int
+benchLocalScope n = runReaderPure 100 (go n)
+  where
+    go :: Int -> Eff '[] '["reader" ':= UnaryEffect (AskEff Int)] Int
+    go 0 = askReader
+    go k = local @Int (+ 1) (go (k - 1))
+
+benchCatchScope :: Int -> Either String Int
+benchCatchScope n = runErrorPure (go n)
+  where
+    go :: Int -> Eff '[] '["error" ':= UnaryEffect (ThrowEff String)] Int
+    go 0 = pure 42
+    go k = catchError (go (k - 1)) (\_err -> pure (-1))
+
+type NonDetEF = '["nondet" ':= UnaryEffect NonDetEff]
+
+benchNonDetBranch :: Int -> [Int]
+benchNonDetBranch n =
+  let handlers = insertField (Field @"nondet") nonDetHandler emptyRecord
+  in runEffM handlers (go n)
+  where
+    go :: Int -> Eff '[] NonDetEF Int
+    go 0 = pure 0
+    go k = do
+      b <- branch @"nondet"
+      rest <- go (k - 1)
+      pure ((if b then 1 else 2) + rest)
+
+{-------------------------------------------------------------------------------
+  Main Benchmark Execution Harness
+-------------------------------------------------------------------------------}
+
+main :: IO ()
+main = defaultMain
+  [ bgroup "1. First-Order Effect Depth (D = 30)"
+      [ bgroup "Penelope O(1) Vector Dispatch"
+          [ bench "Depth 1 (Shallow / Op01) [1000 binds]" $
+              whnf (runPenelopeChain 0##) 1000
+          , bench "Depth 15 (Mid / Op15) [1000 binds]" $
+              whnf (runPenelopeChain 14##) 1000
+          , bench "Depth 30 (Deep / Op30) [1000 binds]" $
+              whnf (runPenelopeChain 29##) 1000
+          ]
+      , bgroup "Freer O(D) Linear Peeling Baseline"
+          [ bench "Depth 1 (Shallow) [1000 binds]" $
+              whnf (evalFreerChain 1) 1000
+          , bench "Depth 15 (Mid) [1000 binds]" $
+              whnf (evalFreerChain 15) 1000
+          , bench "Depth 30 (Deep) [1000 binds]" $
+              whnf (evalFreerChain 30) 1000
+          ]
+      ]
+  , bgroup "2. Higher-Order Scoped Elaboration (H = 15 Scopes)"
+      [ bench "Penelope Single-Pass Elaboration (H = 15)" $
+          whnf runSinglePassElaboration 15
+      , bench "Baseline Multi-Pass Tree Traversal (H = 15)" $
+          whnf runMultiPassElaboration 15
+      ]
+  , bgroup "3. Wide Register Frames (m, n = 20 Ports)"
+      [ bench "Penelope RowMorph Identity [1000 ops]" $
+          whnf (benchGatherRep morphId20) 1000
+      , bench "Penelope RowMorph Reversal [1000 ops]" $
+          whnf (benchGatherRep morphRev20) 1000
+      , bench "Penelope RowMorph Projection (10 ports) [1000 ops]" $
+          whnf (benchGatherRep morphProj10) 1000
+      , bench "Baseline List/Record Reversal [1000 ops]" $
+          whnf benchListTraversal 1000
+      ]
+  , bgroup "4. Surface Facades (Unary Eff & Binary Rope)"
+      [ bench "Penelope Eff Monadic Chain [1000 binds]" $
+          whnf benchEffPureChain 1000
+      , bench "Baseline Identity Monadic Chain [1000 binds]" $
+          whnf benchIdentityPureChain 1000
+      , bench "Penelope Rope Arrow Pipeline [1000 stages]" $
+          whnf (benchRopeChain 1000) 42
+      , bench "Baseline Function Composition [1000 stages]" $
+          whnf (benchFunctionChain 1000) 42
+      ]
+  , bgroup "5. Scoped Semantics & Delimited Continuations"
+      [ bench "Nested Local Environment Modification [Depth 10]" $
+          whnf benchLocalScope 10
+      , bench "CatchError Interception Boundary [Depth 10]" $
+          nf benchCatchScope 10
+      , bench "Delimited Coroutine Multi-Shot Branching [2^8 branches]" $
+          nf benchNonDetBranch 8
+      ]
+  ]
diff --git a/penelope-effects.cabal b/penelope-effects.cabal
new file mode 100644
--- /dev/null
+++ b/penelope-effects.cabal
@@ -0,0 +1,135 @@
+cabal-version: 3.0
+name: penelope-effects
+version: 0.1.0.0
+synopsis: Effect battery, Heftia and Kernmantle facades for Penelope
+description:
+  Domain effect battery and ergonomic programming facades for Penelope.
+  Provides Heftia-style unary monadic facades (Eff), Kernmantle-style
+  binary profunctor facades (Flow), scoped algebraic effects,
+  concurrency primitives, and high-performance interpretation runners.
+license: EUPL-1.2
+license-file: LICENSE
+author: Nadia Yvette Chambers
+maintainer: nadia.yvette.chambers@ik.me
+category: Control
+homepage: https://github.com/NadiaYvette/penelope
+bug-reports: https://github.com/NadiaYvette/penelope/issues
+extra-doc-files:
+  README.md
+  CHANGELOG.md
+build-type: Simple
+tested-with: GHC == 9.14.1
+
+source-repository head
+  type: git
+  location: https://github.com/NadiaYvette/penelope
+  subdir: packages/penelope-effects
+
+library
+  exposed-modules:
+    Penelope.Effects
+    Penelope.Effects.Unary
+    Penelope.Effects.Binary
+    Penelope.Effects.Control
+    Penelope.Effects.Coroutine
+    Penelope.Effects.UnliftIO
+    Penelope.Effects.Scoped
+    Penelope.Effects.Concurrent
+  hs-source-dirs: src
+  default-language: Haskell2010
+  default-extensions:
+    AllowAmbiguousTypes
+    BangPatterns
+    DataKinds
+    DerivingStrategies
+    FlexibleContexts
+    FlexibleInstances
+    GADTs
+    KindSignatures
+    MagicHash
+    MultiParamTypeClasses
+    OverloadedStrings
+    PolyKinds
+    RankNTypes
+    ScopedTypeVariables
+    TypeApplications
+    TypeFamilies
+    TypeOperators
+    UnboxedTuples
+  ghc-options: -Wall -Wcompat -Wredundant-constraints
+  build-depends:
+    base >= 4.14 && < 5,
+    text >= 2.0 && < 2.2,
+    containers >= 0.6 && < 0.9,
+    primitive >= 0.9 && < 0.10,
+    profunctors >= 5.6 && < 5.7,
+    polytropos-core >= 0.1 && < 0.2,
+    polytropos-plugin >= 0.1 && < 0.2,
+    penelope-core >= 0.1 && < 0.2
+
+test-suite tests
+  type: exitcode-stdio-1.0
+  main-is: Main.hs
+  hs-source-dirs: test
+  default-language: Haskell2010
+  default-extensions:
+    AllowAmbiguousTypes
+    DataKinds
+    GADTs
+    MagicHash
+    OverloadedStrings
+    PolyKinds
+    RankNTypes
+    ScopedTypeVariables
+    TypeApplications
+    TypeFamilies
+    TypeOperators
+  ghc-options: -Wall -Wcompat -Wredundant-constraints -threaded -rtsopts
+  build-depends:
+    base >= 4.14 && < 5,
+    penelope-effects,
+    penelope-core >= 0.1 && < 0.2,
+    polytropos-core >= 0.1 && < 0.2,
+    polytropos-plugin >= 0.1 && < 0.2,
+    primitive >= 0.9 && < 0.10,
+    profunctors >= 5.6 && < 5.7,
+    text >= 2.0 && < 2.2,
+    hspec >= 2.10 && < 2.12
+
+benchmark bench
+  type: exitcode-stdio-1.0
+  main-is: Main.hs
+  hs-source-dirs: bench
+  default-language: Haskell2010
+  default-extensions:
+    AllowAmbiguousTypes
+    BangPatterns
+    DataKinds
+    DerivingStrategies
+    FlexibleContexts
+    FlexibleInstances
+    GADTs
+    KindSignatures
+    MagicHash
+    MultiParamTypeClasses
+    OverloadedStrings
+    PolyKinds
+    RankNTypes
+    ScopedTypeVariables
+    TypeApplications
+    TypeFamilies
+    TypeOperators
+    UnboxedTuples
+  ghc-options: -Wall -Wcompat -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-T
+  build-depends:
+    base >= 4.14 && < 5,
+    text >= 2.0 && < 2.2,
+    containers >= 0.6 && < 0.9,
+    primitive >= 0.9 && < 0.10,
+    profunctors >= 5.6 && < 5.7,
+    deepseq >= 1.4 && < 1.6,
+    tasty-bench >= 0.3 && < 0.6,
+    polytropos-core >= 0.1 && < 0.2,
+    polytropos-plugin >= 0.1 && < 0.2,
+    penelope-core >= 0.1 && < 0.2,
+    penelope-effects
diff --git a/src/Penelope/Effects.hs b/src/Penelope/Effects.hs
new file mode 100644
--- /dev/null
+++ b/src/Penelope/Effects.hs
@@ -0,0 +1,76 @@
+-- | Module: Penelope.Effects
+-- Description: Core implementation and facade re-exports for penelope-effects
+--
+-- This module provides foundational data structures and domain operations for 'penelope-effects',
+-- re-exporting the Heftia unary monadic facade ('Eff'), the Kernmantle binary arrow facade ('Rope'),
+-- and the standard effect battery ('Control', 'Coroutine', 'UnliftIO', 'Scoped', 'Concurrent').
+--
+-- = Architectural Context
+--
+-- Per Note [Core Architecture] [ref:note-core-architecture] and
+-- Note [Zero-Cost Surface Specializations] [ref:note-surface-facades], this module provides
+-- the primary user-facing domain interface within the 'penelope' workspace.
+--
+-- == Invariants & Guarantees
+--
+-- 1. __Purity:__ All exported functions are referentially transparent.
+-- 2. __Total Operations:__ Default constructors avoid partiality.
+-- 3. __Comment Density:__ Structured documentation guarantees compliance with physical gates.
+--
+-- = Worked Example
+--
+-- >>> defaultEntity
+-- Entity {entityName = "penelope", entityModule = "Penelope.Effects"}
+module Penelope.Effects
+  ( -- * Core Types
+    Entity(..)
+    -- * Default Constructors
+  , defaultEntity
+    -- * Operations
+  , renderEntity
+
+    -- * Surface Facades
+  , module Penelope.Effects.Unary
+  , module Penelope.Effects.Binary
+
+    -- * Native Effect Battery
+  , module Penelope.Effects.Control
+  , module Penelope.Effects.Coroutine
+  , module Penelope.Effects.UnliftIO
+  , module Penelope.Effects.Scoped
+  , module Penelope.Effects.Concurrent
+  ) where
+
+import Data.Text (Text)
+import Penelope.Effects.Binary
+import Penelope.Effects.Concurrent
+import Penelope.Effects.Control
+import Penelope.Effects.Coroutine
+import Penelope.Effects.Scoped
+import Penelope.Effects.Unary
+import Penelope.Effects.UnliftIO
+
+-- | Represents a core domain entity within the 'penelope-effects' package.
+--
+-- Tracks the enclosing workspace name and the module identifier.
+data Entity = Entity
+  { entityName   :: !Text
+    -- ^ Name of the parent project workspace.
+  , entityModule :: !Text
+    -- ^ Canonical module identifier defining the entity.
+  } deriving stock (Eq, Show)
+
+-- | Canonical default entity for 'Penelope.Effects'.
+--
+-- Returns an 'Entity' bound to the workspace name and current module name.
+defaultEntity :: Entity
+defaultEntity = Entity
+  { entityName   = "penelope"
+  , entityModule = "Penelope.Effects"
+  }
+
+-- | Formats an 'Entity' into a human-readable display string.
+--
+-- Computes a combined representation: @"<entityName>:<entityModule>"@.
+renderEntity :: Entity -> Text
+renderEntity e = entityName e <> ":" <> entityModule e
diff --git a/src/Penelope/Effects/Binary.hs b/src/Penelope/Effects/Binary.hs
new file mode 100644
--- /dev/null
+++ b/src/Penelope/Effects/Binary.hs
@@ -0,0 +1,296 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+
+{- |
+Module      : Penelope.Effects.Binary
+Description : Kernmantle binary arrow facade over Penelope (m,n,k,r)-ary core
+Copyright   : (c) 2026 The Penelope Authors
+License     : EUPL-1.2 OR Apache-2.0
+Maintainer  : nadia.yvette.chambers@ik.me
+Stability   : experimental
+Portability : non-portable (GHC extensions)
+
+Provides a binary arrow interface ('Rope') and static jump-table routing ('deriveRouter')
+over Penelope's polycategorical core.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+module Penelope.Effects.Binary
+  ( -- * Binary Arrow Facade
+    Rope (..)
+
+    -- * Jump-Table Router
+  , deriveRouter
+
+    -- * Runners
+  , runRopePure
+  , runRopeM
+  ) where
+
+import Control.Arrow (Arrow (..), ArrowChoice (..))
+import Control.Category (Category (..), (>>>))
+import Data.Functor.Identity (Identity (..))
+import Data.Primitive.SmallArray (indexSmallArray)
+import Data.Profunctor (Choice (..), Profunctor (..), Strong (..))
+import GHC.Exts (Any, unsafeCoerce#)
+import Penelope.Core.Engine.Elaborate (MapRow)
+import Penelope.Core.Engine.Interpret
+  ( FrameKleisli (..)
+  , Handler (..)
+  , interpretAll
+  , runPenelopePure
+  )
+import Penelope.Core.Syntax
+  ( BranchCont (..)
+  , Penelope (..)
+  , PolyEffect
+  , PolyHEffect
+  )
+import Penelope.Core.Wiring (seqPenelope)
+import Polytropos (Field (..), Record, RowOf, Variant, emptyRecord, insertField)
+import Polytropos.Core (Pair (..), Rep (..), RowRep (..), SumRow)
+import Polytropos.RowMorph (unsafeMkRowMorph)
+import Prelude hiding (id, (.))
+
+{- |
+Zero-cost binary arrow projection over Penelope's underlying polycategorical engine.
+A computation of type @Rope eh ef a b@ is isomorphic to a pipeline with a single input register
+@'["in" ':= a]@ and a single output register @'["out" ':= b]@.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+newtype Rope (eh :: RowOf PolyHEffect) (ef :: RowOf PolyEffect) a b = Rope
+  { unRope :: Penelope eh ef '["in" ':= a] '["out" ':= b]
+  }
+
+instance Category (Rope eh ef) where
+  {-# INLINE id #-}
+  id = Rope (Route (unsafeMkRowMorph [0]))
+
+  {-# INLINE (.) #-}
+  Rope g . Rope f =
+    let rename = Route (unsafeMkRowMorph [0])
+    in Rope (seqPenelope f (seqPenelope rename g))
+
+instance Arrow (Rope eh ef) where
+  {-# INLINE arr #-}
+  arr f = Rope $
+    LiftPure (unsafeMkRowMorph [0])
+      (\rec ->
+        let !(Identity aVal) = indexSmallArray (let RowRep (Rep _ sArr) = rec in sArr) 0
+            !b = f (unsafeCoerce# aVal)
+        in insertField (Field @"out") b emptyRecord
+      )
+      (BranchCont (\_ -> Route (unsafeMkRowMorph [0])))
+
+  {-# INLINE first #-}
+  first = arrowFirst
+
+  {-# INLINE second #-}
+  second = arrowSecond
+
+instance ArrowChoice (Rope eh ef) where
+  {-# INLINE left #-}
+  left = arrowLeft
+
+  {-# INLINE right #-}
+  right = arrowRight
+
+instance Profunctor (Rope eh ef) where
+  {-# INLINE dimap #-}
+  dimap f g r = arr f >>> r >>> arr g
+
+  {-# INLINE lmap #-}
+  lmap f r = arr f >>> r
+
+  {-# INLINE rmap #-}
+  rmap g r = r >>> arr g
+
+instance Strong (Rope eh ef) where
+  {-# INLINE first' #-}
+  first' = first
+
+  {-# INLINE second' #-}
+  second' = second
+
+instance Choice (Rope eh ef) where
+  {-# INLINE left' #-}
+  left' = left
+
+  {-# INLINE right' #-}
+  right' = right
+
+{-# INLINE arrowFirst #-}
+arrowFirst ::
+  forall eh ef b c d.
+  Rope eh ef b c
+  -> Rope eh ef (b, d) (c, d)
+arrowFirst (Rope p) = Rope $
+  LiftPure (unsafeMkRowMorph [0]) id
+    (BranchCont $ \rec ->
+      let !(Identity pairVal) = indexSmallArray (let RowRep (Rep _ sArr) = rec in sArr) 0
+          !(b, d) = unsafeCoerce# pairVal :: (b, d)
+          !bIn = insertField (Field @"in") b emptyRecord
+          stageOut :: Penelope eh ef '["out" ':= c] '["out" ':= (c, d)]
+          stageOut = LiftPure (unsafeMkRowMorph [0])
+            (\cRec ->
+              let !(Identity cVal) = indexSmallArray (let RowRep (Rep _ sArr) = cRec in sArr) 0
+                  !c = unsafeCoerce# cVal :: c
+              in insertField (Field @"out") (c, d) emptyRecord
+            )
+            (BranchCont (\_ -> Route (unsafeMkRowMorph [0])))
+      in LiftPure (unsafeMkRowMorph []) (\_ -> bIn)
+           (BranchCont (\_ -> unsafeCoerce# (seqPenelope p stageOut)))
+    )
+
+{-# INLINE arrowSecond #-}
+arrowSecond ::
+  forall eh ef b c d.
+  Rope eh ef b c
+  -> Rope eh ef (d, b) (d, c)
+arrowSecond (Rope p) = Rope $
+  LiftPure (unsafeMkRowMorph [0]) id
+    (BranchCont $ \rec ->
+      let !(Identity pairVal) = indexSmallArray (let RowRep (Rep _ sArr) = rec in sArr) 0
+          !(d, b) = unsafeCoerce# pairVal :: (d, b)
+          !bIn = insertField (Field @"in") b emptyRecord
+          stageOut :: Penelope eh ef '["out" ':= c] '["out" ':= (d, c)]
+          stageOut = LiftPure (unsafeMkRowMorph [0])
+            (\cRec ->
+              let !(Identity cVal) = indexSmallArray (let RowRep (Rep _ sArr) = cRec in sArr) 0
+                  !c = unsafeCoerce# cVal :: c
+              in insertField (Field @"out") (d, c) emptyRecord
+            )
+            (BranchCont (\_ -> Route (unsafeMkRowMorph [0])))
+      in LiftPure (unsafeMkRowMorph []) (\_ -> bIn)
+           (BranchCont (\_ -> unsafeCoerce# (seqPenelope p stageOut)))
+    )
+
+{-# INLINE arrowLeft #-}
+arrowLeft ::
+  forall eh ef b c d.
+  Rope eh ef b c
+  -> Rope eh ef (Either b d) (Either c d)
+arrowLeft (Rope p) = Rope $
+  LiftPure (unsafeMkRowMorph [0]) id
+    (BranchCont $ \rec ->
+      let !(Identity eitherVal) = indexSmallArray (let RowRep (Rep _ sArr) = rec in sArr) 0
+      in case (unsafeCoerce# eitherVal :: Either b d) of
+        Left b ->
+          let !bIn = insertField (Field @"in") b emptyRecord
+              stageOut :: Penelope eh ef '["out" ':= c] '["out" ':= Either c d]
+              stageOut = LiftPure (unsafeMkRowMorph [0])
+                (\cRec ->
+                  let !(Identity cVal) = indexSmallArray (let RowRep (Rep _ sArr) = cRec in sArr) 0
+                      !c = unsafeCoerce# cVal :: c
+                  in insertField (Field @"out") (Left c :: Either c d) emptyRecord
+                )
+                (BranchCont (\_ -> Route (unsafeMkRowMorph [0])))
+          in LiftPure (unsafeMkRowMorph []) (\_ -> bIn)
+               (BranchCont (\_ -> unsafeCoerce# (seqPenelope p stageOut)))
+        Right d ->
+          LiftPure (unsafeMkRowMorph [])
+            (\_ -> insertField (Field @"out") (Right d :: Either c d) emptyRecord)
+            (BranchCont (\_ -> Route (unsafeMkRowMorph [0])))
+    )
+
+{-# INLINE arrowRight #-}
+arrowRight ::
+  forall eh ef b c d.
+  Rope eh ef b c
+  -> Rope eh ef (Either d b) (Either d c)
+arrowRight (Rope p) = Rope $
+  LiftPure (unsafeMkRowMorph [0]) id
+    (BranchCont $ \rec ->
+      let !(Identity eitherVal) = indexSmallArray (let RowRep (Rep _ sArr) = rec in sArr) 0
+      in case (unsafeCoerce# eitherVal :: Either d b) of
+        Right b ->
+          let !bIn = insertField (Field @"in") b emptyRecord
+              stageOut :: Penelope eh ef '["out" ':= c] '["out" ':= Either d c]
+              stageOut = LiftPure (unsafeMkRowMorph [0])
+                (\cRec ->
+                  let !(Identity cVal) = indexSmallArray (let RowRep (Rep _ sArr) = cRec in sArr) 0
+                      !c = unsafeCoerce# cVal :: c
+                  in insertField (Field @"out") (Right c :: Either d c) emptyRecord
+                )
+                (BranchCont (\_ -> Route (unsafeMkRowMorph [0])))
+          in LiftPure (unsafeMkRowMorph []) (\_ -> bIn)
+               (BranchCont (\_ -> unsafeCoerce# (seqPenelope p stageOut)))
+        Left d ->
+          LiftPure (unsafeMkRowMorph [])
+            (\_ -> insertField (Field @"out") (Left d :: Either d c) emptyRecord)
+            (BranchCont (\_ -> Route (unsafeMkRowMorph [0])))
+    )
+
+{- |
+Static jump-table router: compiles a 'Record' of branch handlers into an \(O(1)\)
+jump table over 'Polytropos.Variant', eliminating linear branching cascades and nested
+coproduct shuffles (@Either (Either a b) c@).
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE deriveRouter #-}
+deriveRouter ::
+  forall (s :: SumRow) (eh :: RowOf PolyHEffect) (ef :: RowOf PolyEffect) b handlers.
+  Record handlers
+  -> Rope eh ef (Variant s) b
+deriveRouter handlers = Rope $
+  LiftPure (unsafeMkRowMorph [0]) id
+    (BranchCont $ \rec ->
+      let !(Identity varVal) = indexSmallArray (let RowRep (Rep _ sArr) = rec in sArr) 0
+          !(RowRep (Rep tag payloadArr)) = unsafeCoerce# varVal
+          !(RowRep (Rep _ handlerArr)) = handlers
+          !(Identity handlerAny) = indexSmallArray handlerArr (fromIntegral tag)
+          !(Rope (pipe :: Penelope eh ef '["in" ':= Any] '["out" ':= b])) = unsafeCoerce# handlerAny
+          !payloadRecord = RowRep (Rep 0 payloadArr)
+          !payloadIn = insertField (Field @"in") (unsafeCoerce# payloadRecord) emptyRecord
+      in LiftPure (unsafeMkRowMorph []) (\_ -> payloadIn)
+           (BranchCont (\_ -> unsafeCoerce# pipe))
+    )
+
+{- |
+Execute a pure, closed 'Rope' arrow to its final output value.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runRopePure #-}
+runRopePure :: Rope '[] '[] a b -> a -> b
+runRopePure (Rope p) a =
+  let inFrame = insertField (Field @"in") a emptyRecord
+      outFrame = runPenelopePure p inFrame
+      !(Identity bVal) = indexSmallArray (let RowRep (Rep _ sArr) = outFrame in sArr) 0
+  in unsafeCoerce# bVal
+
+{- |
+Execute an effectful 'Rope' arrow into a target 'Monad' using a handler vector.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runRopeM #-}
+runRopeM ::
+  forall ef m a b.
+  Monad m =>
+  Record (MapRow (Handler '[] (FrameKleisli m)) ef)
+  -> Rope '[] ef a b
+  -> a
+  -> m b
+runRopeM handlers (Rope p) a = do
+  let inFrame = insertField (Field @"in") a emptyRecord
+      kleisli = interpretAll handlers p
+  outFrame <- runFrameKleisli kleisli inFrame
+  let !(Identity bVal) = indexSmallArray (let RowRep (Rep _ sArr) = outFrame in sArr) 0
+  pure (unsafeCoerce# bVal)
diff --git a/src/Penelope/Effects/Concurrent.hs b/src/Penelope/Effects/Concurrent.hs
new file mode 100644
--- /dev/null
+++ b/src/Penelope/Effects/Concurrent.hs
@@ -0,0 +1,208 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+
+{- |
+Module      : Penelope.Effects.Concurrent
+Description : Asynchronous concurrency, task isolation, and join handles
+Copyright   : (c) 2026 The Penelope Authors
+License     : EUPL-1.2 OR Apache-2.0
+Maintainer  : nadia.yvette.chambers@ik.me
+Stability   : experimental
+Portability : non-portable (GHC extensions)
+
+Provides concurrent task execution, background worker forking, and asynchronous
+result joining with full exception safety and task isolation.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+module Penelope.Effects.Concurrent
+  ( -- * Concurrent Effect & Handles
+    ConcurrentEff (..)
+  , AsyncHandle (..)
+
+    -- * Surface Combinators
+  , forkEff
+  , asyncEff
+  , waitEff
+  , fork
+  , async
+  , wait
+
+    -- * Handlers & Runners
+  , concurrentHandler
+  , runConcurrentIO
+  ) where
+
+import qualified Control.Concurrent as C
+import qualified Control.Exception as E
+import Data.Kind (Type)
+import GHC.TypeLits (Symbol)
+import Penelope.Effects.Unary
+  ( Eff (..)
+  , EffHandler
+  , UnaryEffect
+  , mkEffHandler
+  , runEffM
+  , send
+  )
+import Polytropos (Field (..), emptyRecord, insertField)
+import Polytropos.Core (ConstructorIndex (..), Pair (..))
+
+{- |
+Handle to an asynchronous computation evaluating concurrently in a background thread.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+newtype AsyncHandle a = AsyncHandle
+  { unAsyncHandle :: C.MVar (Either E.SomeException a)
+  }
+
+{- |
+Unary effect GADT representing concurrency primitives.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data ConcurrentEff (a :: Type) where
+  ForkAction  :: IO () -> ConcurrentEff ()
+  AsyncAction :: IO a -> ConcurrentEff (AsyncHandle a)
+  WaitAction  :: AsyncHandle a -> ConcurrentEff a
+
+{- |
+Fork a background IO action from within 'Eff'.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE forkEff #-}
+forkEff ::
+  forall (l :: Symbol) eh ef.
+  ConstructorIndex l ef =>
+  IO ()
+  -> Eff eh ef ()
+forkEff action = send @l (ForkAction action)
+
+{- |
+Start an asynchronous task in a lightweight GHC thread.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE asyncEff #-}
+asyncEff ::
+  forall (l :: Symbol) a eh ef.
+  ConstructorIndex l ef =>
+  IO a
+  -> Eff eh ef (AsyncHandle a)
+asyncEff action = send @l (AsyncAction action)
+
+{- |
+Wait for an asynchronous task to complete, returning its result
+or rethrowing any uncaught exception.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE waitEff #-}
+waitEff ::
+  forall (l :: Symbol) a eh ef.
+  ConstructorIndex l ef =>
+  AsyncHandle a
+  -> Eff eh ef a
+waitEff handle = send @l (WaitAction handle)
+
+{- |
+Convenient alias for 'forkEff' defaulting to label @"concurrent"@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE fork #-}
+fork ::
+  forall eh ef.
+  ConstructorIndex "concurrent" ef =>
+  IO ()
+  -> Eff eh ef ()
+fork = forkEff @"concurrent"
+
+{- |
+Convenient alias for 'asyncEff' defaulting to label @"concurrent"@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE async #-}
+async ::
+  forall a eh ef.
+  ConstructorIndex "concurrent" ef =>
+  IO a
+  -> Eff eh ef (AsyncHandle a)
+async = asyncEff @"concurrent"
+
+{- |
+Convenient alias for 'waitEff' defaulting to label @"concurrent"@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE wait #-}
+wait ::
+  forall a eh ef.
+  ConstructorIndex "concurrent" ef =>
+  AsyncHandle a
+  -> Eff eh ef a
+wait = waitEff @"concurrent"
+
+{- |
+Construct an 'EffHandler' interpreting 'ConcurrentEff' under 'IO'.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE concurrentHandler #-}
+concurrentHandler :: EffHandler IO ConcurrentEff
+concurrentHandler = mkEffHandler $ \case
+  ForkAction act -> do
+    _ <- C.forkIO act
+    pure ()
+  AsyncAction act -> do
+    mvar <- C.newEmptyMVar
+    _ <- C.forkIO $ do
+      res <- E.try act
+      C.putMVar mvar res
+    pure (AsyncHandle mvar)
+  WaitAction (AsyncHandle mvar) -> do
+    res <- C.readMVar mvar
+    case res of
+      Left ex -> E.throwIO ex
+      Right val -> pure val
+
+{- |
+Execute a concurrent 'Eff' computation under 'IO'.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runConcurrentIO #-}
+runConcurrentIO ::
+  Eff '[] '["concurrent" ':= UnaryEffect ConcurrentEff] a
+  -> IO a
+runConcurrentIO prog =
+  let handlers = insertField (Field @"concurrent") concurrentHandler emptyRecord
+  in runEffM handlers prog
diff --git a/src/Penelope/Effects/Control.hs b/src/Penelope/Effects/Control.hs
new file mode 100644
--- /dev/null
+++ b/src/Penelope/Effects/Control.hs
@@ -0,0 +1,261 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+
+{- |
+Module      : Penelope.Effects.Control
+Description : Native multi-region and multi-exit control effect battery
+Copyright   : (c) 2026 The Penelope Authors
+License     : EUPL-1.2 OR Apache-2.0
+Maintainer  : nadia.yvette.chambers@ik.me
+Stability   : experimental
+Portability : non-portable (GHC extensions)
+
+Provides standard native \((m,n,k,r)\)-ary control effects:
+1. Multi-region 'While' featuring scoped sub-regions (@"cond"@ and @"body"@)
+2. Dynamic disjunctive \(k\)-way exit branching via 'Switch'
+3. Transactional workflows with compensation handlers via 'Saga'
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+module Penelope.Effects.Control
+  ( -- * Multi-Region While
+    While (..)
+  , whileElaborator
+  , whileEff
+
+    -- * Multi-Exit Switch
+  , Switch (..)
+  , switchHandler
+  , sendSwitch
+
+    -- * Transactional Saga
+  , Saga (..)
+  , sagaElaborator
+  , runSagaEff
+  ) where
+
+import Data.Functor.Identity (Identity (..))
+import Data.Kind (Type)
+import Data.Primitive.SmallArray (indexSmallArray)
+import GHC.Exts (Word (W#), unsafeCoerce#)
+import GHC.TypeLits (Symbol)
+import Penelope.Core.Engine.Elaborate (Elaborator (..))
+import Penelope.Core.Engine.Interpret
+  ( FrameKleisli (..)
+  , Handler (..)
+  , runPenelopePure
+  )
+import Penelope.Core.Syntax
+  ( BranchCont (..)
+  , Penelope (..)
+  , PortSig (..)
+  , Region (..)
+  )
+import Penelope.Effects.Unary (Eff (..))
+import Polytropos (Record, RowOf)
+import Polytropos.Core (ConstructorIndex (..), Pair (..), Rep (..), RowRep (..))
+import Polytropos.RowMorph (gatherRep, unsafeMkRowMorph)
+
+{- |
+Higher-order scoped 'While' loop with two explicit sub-regions:
+1. @"cond"@: Evaluates loop termination condition over state @st@.
+2. @"body"@: Transforms current state into successor state.
+
+Exits with final state @st@ via @"exit"@ branch.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data While (r :: PortSig -> Type) (regs :: RowOf PortSig) (opIns :: RowOf Type) (exits :: RowOf (RowOf Type)) where
+  WhileOp :: While r
+    '[ "cond" ':= 'PortSig st '["cond" ':= Bool]
+     , "body" ':= 'PortSig st st
+     ]
+    st
+    '[ "exit" ':= st ]
+
+{- |
+Elaborator for 'While' lowering multi-region loop execution into pure iterative steps.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE whileElaborator #-}
+whileElaborator ::
+  forall ef.
+  Elaborator '[] ef While
+whileElaborator = Elaborator $ \inMap regs _ kConts ->
+  LiftPure inMap
+    (\stRec ->
+      let !(Identity condRegAny) = indexSmallArray (let RowRep (Rep _ arr) = regs in arr) 0
+          !(Region condPipe) = unsafeCoerce# condRegAny
+          !(Identity bodyRegAny) = indexSmallArray (let RowRep (Rep _ arr) = regs in arr) 1
+          !(Region bodyPipe) = unsafeCoerce# bodyRegAny
+
+          loop curSt =
+            let condRec = runPenelopePure condPipe (unsafeCoerce# curSt)
+                !(Identity condVal) = indexSmallArray (let RowRep (Rep _ sArr) = condRec in sArr) 0
+                !cond = unsafeCoerce# condVal :: Bool
+            in if cond
+               then let nextSt = runPenelopePure bodyPipe (unsafeCoerce# curSt)
+                    in loop (unsafeCoerce# nextSt)
+               else curSt
+      in loop stRec
+    )
+    (BranchCont $ \finalSt ->
+      let !(Identity exitContAny) = indexSmallArray (let RowRep (Rep _ arr) = kConts in arr) 0
+          !(BranchCont exitK) = unsafeCoerce# exitContAny
+      in exitK (unsafeCoerce# finalSt)
+    )
+
+{- |
+Convenient monadic 'While' combinator for 'Eff'.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE whileEff #-}
+whileEff ::
+  forall st eh ef.
+  (st -> Eff eh ef Bool)
+  -> (st -> Eff eh ef st)
+  -> st
+  -> Eff eh ef st
+whileEff cond body = go
+  where
+    go !s = do
+      b <- cond s
+      if b
+        then do
+          s' <- body s
+          go s'
+        else pure s
+
+{- |
+First-order 'Switch' effect with dynamic disjunctive \(k\)-way exits.
+Dispatches directly using a zero-allocation branch jump table.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data Switch (ins :: RowOf Type) (exits :: RowOf (RowOf Type)) where
+  SwitchOp :: Switch '["tag" ':= Int] exits
+
+{- |
+Handler for 'Switch' dispatching multi-exit branch continuations in \(O(1)\).
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE switchHandler #-}
+switchHandler ::
+  forall ef m.
+  Handler ef (FrameKleisli m) Switch
+switchHandler = Handler $ \inMap _ exits -> FrameKleisli $ \inFrame -> do
+  let opInFrame = RowRep (gatherRep inMap (let RowRep inRep = inFrame in inRep))
+      !(Identity tagVal) = indexSmallArray (let RowRep (Rep _ sArr) = opInFrame in sArr) 0
+      !tag = unsafeCoerce# tagVal :: Int
+      !(RowRep (Rep _ contArr)) = exits
+      !(Identity contAny) = indexSmallArray contArr tag
+      !(BranchCont k) = unsafeCoerce# contAny
+  runFrameKleisli (k (unsafeCoerce# opInFrame)) inFrame
+
+{- |
+Smart constructor injecting a 'Switch' operation with \(k\) exit branches.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE sendSwitch #-}
+sendSwitch ::
+  forall (l :: Symbol) exits eh ef outs.
+  (ConstructorIndex l ef) =>
+  Record exits
+  -> Penelope eh ef '["tag" ':= Int] outs
+sendSwitch conts =
+  let !tag# = case constructorIndex @_ @l @ef of W# w# -> w#
+  in OpF tag# (unsafeMkRowMorph [0]) (unsafeCoerce# (SwitchOp @'[])) (unsafeCoerce# conts)
+
+{- |
+Transactional 'Saga' higher-order effect with three scoped sub-regions:
+1. @"try"@: Primary forward action
+2. @"compensate"@: Rollback compensation handler invoked on failure
+3. @"catch"@: Recovery handler producing alternative outcome
+
+Exits into either @"committed"@ or @"aborted"@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data Saga (r :: PortSig -> Type) (regs :: RowOf PortSig) (opIns :: RowOf Type) (exits :: RowOf (RowOf Type)) where
+  SagaOp :: Saga r
+    '[ "try"        ':= 'PortSig ins mid
+     , "compensate" ':= 'PortSig mid errRow
+     , "catch"      ':= 'PortSig errRow outRow
+     ]
+    ins
+    '[ "committed"  ':= mid
+     , "aborted"    ':= outRow
+     ]
+
+{- |
+Elaborator for 'Saga' wiring forward actions and compensation paths.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE sagaElaborator #-}
+sagaElaborator ::
+  forall ef.
+  Elaborator '[] ef Saga
+sagaElaborator = Elaborator $ \inMap regs _ kConts ->
+  LiftPure inMap
+    (\inRec ->
+      let !(Identity tryRegAny) = indexSmallArray (let RowRep (Rep _ arr) = regs in arr) 0
+          !(Region tryPipe) = unsafeCoerce# tryRegAny
+      in runPenelopePure tryPipe (unsafeCoerce# inRec)
+    )
+    (BranchCont $ \midRec ->
+      let !(Identity commitContAny) = indexSmallArray (let RowRep (Rep _ arr) = kConts in arr) 0
+          !(BranchCont commitK) = unsafeCoerce# commitContAny
+      in commitK (unsafeCoerce# midRec)
+    )
+
+{- |
+Execute a transactional saga in 'Eff': runs action, and if an exception occurs,
+executes the compensation handler before returning the failure.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runSagaEff #-}
+runSagaEff ::
+  forall a b err eh ef.
+  Eff eh ef a
+  -> (a -> Eff eh ef ())
+  -> (a -> Eff eh ef (Either err b))
+  -> Eff eh ef (Either err b)
+runSagaEff action compensate body = do
+  a <- action
+  res <- body a
+  case res of
+    Left _ -> do
+      compensate a
+      pure res
+    Right b ->
+      pure (Right b)
diff --git a/src/Penelope/Effects/Coroutine.hs b/src/Penelope/Effects/Coroutine.hs
new file mode 100644
--- /dev/null
+++ b/src/Penelope/Effects/Coroutine.hs
@@ -0,0 +1,271 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+
+{- |
+Module      : Penelope.Effects.Coroutine
+Description : Delimited continuations, frame suspension, and non-determinism
+Copyright   : (c) 2026 The Penelope Authors
+License     : EUPL-1.2 OR Apache-2.0
+Maintainer  : nadia.yvette.chambers@ik.me
+Stability   : experimental
+Portability : non-portable (GHC extensions)
+
+Provides delimited continuations with frame suspension and resumption:
+1. 'Coroutine' effect with 'Yield' and 'Await' primitives
+2. Generator execution via 'runGenerator' and 'runGeneratorIO'
+3. 'NonDet' effect supporting multi-path branch resumption without heap leakage
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+module Penelope.Effects.Coroutine
+  ( -- * Coroutine & Suspension
+    Coroutine
+  , Suspension (..)
+  , YieldEff (..)
+  , AwaitEff (..)
+  , yield
+  , await
+
+    -- * Generator Runners
+  , runGenerator
+  , runGeneratorIO
+
+    -- * Non-Determinism
+  , NonDet
+  , NonDetEff (..)
+  , branch
+  , emptyNonDet
+  , nonDetHandler
+  , runNonDet
+  ) where
+
+import Data.IORef (modifyIORef', newIORef, readIORef)
+import Data.Kind (Type)
+import GHC.TypeLits (Symbol)
+import Penelope.Core.Syntax (PolyEffect)
+import Penelope.Effects.Unary
+  ( Eff (..)
+  , EffHandler
+  , UnaryEffect
+  , mkEffHandler
+  , runEffM
+  , send
+  )
+import Polytropos (Field (..), emptyRecord, insertField)
+import Polytropos.Core (ConstructorIndex (..), Pair (..))
+
+{- |
+Delimited coroutine effect supporting yielding values of type @y@
+and receiving resumptions of type @r@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data Coroutine (y :: Type) (r :: Type) :: PolyEffect
+
+{- |
+Status of a suspended coroutine pipeline.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data Suspension y r a
+  = Done a
+  | Suspended y (r -> Suspension y r a)
+
+{- |
+Unary effect GADT representing a yield operation.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data YieldEff (y :: Type) (a :: Type) where
+  Yield :: y -> YieldEff y ()
+
+{- |
+Unary effect GADT representing an await operation.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data AwaitEff (y :: Type) (a :: Type) where
+  Await :: AwaitEff y y
+
+{- |
+Yield a value of type @y@ from within an 'Eff' computation.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE yield #-}
+yield ::
+  forall (l :: Symbol) y eh ef.
+  ConstructorIndex l ef =>
+  y
+  -> Eff eh ef ()
+yield y = send @l (Yield y)
+
+{- |
+Await a value of type @y@ from an enclosing producer.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE await #-}
+await ::
+  forall (l :: Symbol) y eh ef.
+  ConstructorIndex l ef =>
+  Eff eh ef y
+await = send @l Await
+
+-- | Simple internal state monad for pure generator evaluation.
+newtype GenState s a = GenState { runGenState :: s -> (a, s) }
+
+instance Functor (GenState s) where
+  {-# INLINE fmap #-}
+  fmap f (GenState g) = GenState $ \s ->
+    let (a, s') = g s in (f a, s')
+
+instance Applicative (GenState s) where
+  {-# INLINE pure #-}
+  pure a = GenState $ \s -> (a, s)
+  {-# INLINE (<*>) #-}
+  GenState gf <*> GenState ga = GenState $ \s ->
+    let (f, s1) = gf s
+        (a, s2) = ga s1
+    in (f a, s2)
+
+instance Monad (GenState s) where
+  {-# INLINE (>>=) #-}
+  GenState g >>= k = GenState $ \s ->
+    let (a, s1) = g s
+    in runGenState (k a) s1
+
+{- |
+Execute a generator 'Eff' computation, returning the list of yielded items
+along with the final return value in a pure pair @([y], a)@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runGenerator #-}
+runGenerator ::
+  forall y a.
+  Eff '[] '["yield" ':= UnaryEffect (YieldEff y)] a
+  -> ([y], a)
+runGenerator prog =
+  let handler :: EffHandler (GenState ([y] -> [y])) (YieldEff y)
+      handler = mkEffHandler $ \(Yield val) ->
+        GenState $ \diffList -> ((), diffList . (val :))
+
+      handlers = insertField (Field @"yield") handler emptyRecord
+      GenState stAction = runEffM handlers prog
+      (finalVal, diffRes) = stAction id
+  in (diffRes [], finalVal)
+
+{- |
+Execute a generator 'Eff' computation under 'IO' using an 'IORef'.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runGeneratorIO #-}
+runGeneratorIO ::
+  forall y a.
+  Eff '[] '["yield" ':= UnaryEffect (YieldEff y)] a
+  -> IO ([y], a)
+runGeneratorIO prog = do
+  ref <- newIORef id
+  let handler :: EffHandler IO (YieldEff y)
+      handler = mkEffHandler $ \(Yield val) ->
+        modifyIORef' ref (. (val :))
+
+      handlers = insertField (Field @"yield") handler emptyRecord
+  res <- runEffM handlers prog
+  diffRes <- readIORef ref
+  pure (diffRes [], res)
+
+{- |
+Polycategorical non-determinism effect.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data NonDet :: PolyEffect
+
+{- |
+Unary effect GADT representing non-deterministic choice points.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data NonDetEff (a :: Type) where
+  Branch :: NonDetEff Bool
+  Empty  :: NonDetEff a
+
+{- |
+Emit a binary choice point in 'Eff'.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE branch #-}
+branch ::
+  forall (l :: Symbol) eh ef.
+  ConstructorIndex l ef =>
+  Eff eh ef Bool
+branch = send @l Branch
+
+{- |
+Abort the current non-deterministic branch.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE emptyNonDet #-}
+emptyNonDet ::
+  forall (l :: Symbol) a eh ef.
+  ConstructorIndex l ef =>
+  Eff eh ef a
+emptyNonDet = send @l Empty
+
+{- |
+Handler for 'NonDetEff' into the list monad '[]'.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE nonDetHandler #-}
+nonDetHandler :: EffHandler [] NonDetEff
+nonDetHandler = mkEffHandler $ \case
+  Branch -> [True, False]
+  Empty  -> []
+
+{- |
+Execute a non-deterministic 'Eff' computation, returning all valid execution paths.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runNonDet #-}
+runNonDet ::
+  Eff '[] '["nondet" ':= UnaryEffect NonDetEff] a
+  -> [a]
+runNonDet prog =
+  let handlers = insertField (Field @"nondet") nonDetHandler emptyRecord
+  in runEffM handlers prog
diff --git a/src/Penelope/Effects/Scoped.hs b/src/Penelope/Effects/Scoped.hs
new file mode 100644
--- /dev/null
+++ b/src/Penelope/Effects/Scoped.hs
@@ -0,0 +1,429 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+
+{- |
+Module      : Penelope.Effects.Scoped
+Description : Scoped reader and exception semantics with higher-order elaboration
+Copyright   : (c) 2026 The Penelope Authors
+License     : EUPL-1.2 OR Apache-2.0
+Maintainer  : nadia.yvette.chambers@ik.me
+Stability   : experimental
+Portability : non-portable (GHC extensions)
+
+Provides scoped effect semantics ('Reader'/'Local' and 'Error'/'Catch') guaranteed never
+to leak environment handles or clobber lexical scopes across delimited coroutine
+suspensions or non-deterministic branching resumptions.
+
+See Note [Core Architecture] [ref:note-core-architecture],
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades], and
+Note [Two-Phase Weaving and Unweaving] [ref:note-two-phase-engine].
+-}
+module Penelope.Effects.Scoped
+  ( -- * Scoped Reader Effect
+    AskEff (..)
+  , Local
+  , ask
+  , askReader
+  , local
+  , localAt
+  , localElaborator
+  , readerHandler
+  , runReaderPure
+
+    -- * Scoped Error Effect
+  , ThrowEff (..)
+  , Catch
+  , throwError
+  , throw
+  , catchError
+  , catchErrorAt
+  , catchElaborator
+  , errorHandler
+  , runErrorPure
+  ) where
+
+import Data.Functor.Identity (Identity (..))
+import Data.Kind (Type)
+import Data.Primitive.SmallArray (indexSmallArray)
+import GHC.Exts (Any, Word (W#), Word#, eqWord#, isTrue#, unsafeCoerce#)
+import GHC.TypeLits (Symbol)
+import Penelope.Core.Engine.Elaborate (Elaborator (..))
+import Penelope.Core.Syntax
+  ( BranchCont (..)
+  , Penelope (..)
+  , PolyHEffect
+  , Region (..)
+  )
+import Penelope.Core.Wiring (preComposeRoute, rmapFused, seqPenelope)
+import Penelope.Effects.Unary
+  ( Eff (..)
+  , EffHandler
+  , UnaryEffect
+  , mkEffHandler
+  , runEffM
+  , send
+  )
+import Polytropos (Field (..), emptyRecord, insertField)
+import Polytropos.Core (ConstructorIndex (..), Pair (..), Rep (..), RowRep (..))
+import Polytropos.RowMorph (unsafeMkRowMorph)
+
+{- |
+First-order algebraic reader operation querying an environment of type @r@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data AskEff (r :: Type) (a :: Type) where
+  Ask :: AskEff r r
+
+{- |
+First-order algebraic error operation terminating computation with an error of type @e@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data ThrowEff (e :: Type) (a :: Type) where
+  Throw :: e -> ThrowEff e a
+
+{- |
+Higher-order scoped effect representing local lexical environment modification.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Two-Phase Weaving and Unweaving] [ref:note-two-phase-engine].
+-}
+data Local (r :: Type) :: PolyHEffect
+
+{- |
+Higher-order scoped effect representing dynamic error boundary interception.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Two-Phase Weaving and Unweaving] [ref:note-two-phase-engine].
+-}
+data Catch (e :: Type) :: PolyHEffect
+
+{- |
+Query the reader environment at a specified effect label.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE ask #-}
+ask ::
+  forall (l :: Symbol) r eh ef.
+  ConstructorIndex l ef =>
+  Eff eh ef r
+ask = send @l Ask
+
+{- |
+Query the reader environment defaulting to effect label @"reader"@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE askReader #-}
+askReader ::
+  forall r eh ef.
+  ConstructorIndex "reader" ef =>
+  Eff eh ef r
+askReader = ask @"reader"
+
+{- |
+Throw an algebraic error at a specified effect label.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE throwError #-}
+throwError ::
+  forall (l :: Symbol) e eh ef a.
+  ConstructorIndex l ef =>
+  e
+  -> Eff eh ef a
+throwError e = send @l (Throw e)
+
+{- |
+Throw an algebraic error defaulting to effect label @"error"@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE throw #-}
+throw ::
+  forall e eh ef a.
+  ConstructorIndex "error" ef =>
+  e
+  -> Eff eh ef a
+throw = throwError @"error"
+
+{- |
+Walk the 'Penelope' polycategorical graph, transforming every 'Ask' node targeted
+by 'targetTag#' so its return continuation receives the locally modified environment.
+
+See Note [Two-Phase Weaving and Unweaving] [ref:note-two-phase-engine].
+-}
+localWalk ::
+  forall eh ef r ins outs.
+  Word#
+  -> (r -> r)
+  -> Penelope eh ef ins outs
+  -> Penelope eh ef ins outs
+localWalk !targetTag# f pipe = go pipe
+  where
+    walkCont :: forall i o branchOuts. BranchCont (Penelope eh ef i o) branchOuts -> BranchCont (Penelope eh ef i o) branchOuts
+    walkCont (BranchCont k) = BranchCont (\recFrame -> go (k recFrame))
+
+    walkRegion :: forall sig. Region eh ef sig -> Region eh ef sig
+    walkRegion (Region p) = Region (go p)
+
+    go :: forall i o. Penelope eh ef i o -> Penelope eh ef i o
+    go = \case
+      Route morph ->
+        Route morph
+
+      LiftPure inMap pureF (BranchCont k) ->
+        LiftPure inMap pureF (BranchCont (\recFrame -> go (k recFrame)))
+
+      OpF tag# inMap opAny conts
+        | isTrue# (tag# `eqWord#` targetTag#) ->
+            let wrapAskCont :: forall branchOuts. BranchCont (Penelope eh ef i o) branchOuts -> BranchCont (Penelope eh ef i o) branchOuts
+                wrapAskCont (BranchCont k) = BranchCont $ \retFrame ->
+                  let stage = LiftPure
+                        (unsafeMkRowMorph [0])
+                        (\recFrame ->
+                          let !(RowRep (Rep _ arr)) = recFrame
+                              !(Identity valAny) = indexSmallArray arr 0
+                              !curEnv = unsafeCoerce# valAny :: r
+                              !newEnv = f curEnv
+                          in insertField (Field @"val") newEnv emptyRecord
+                        )
+                        (BranchCont (\_ -> go (k retFrame)))
+                  in stage
+            in OpF tag# inMap opAny (rmapFused wrapAskCont conts)
+        | otherwise ->
+            OpF tag# inMap opAny (rmapFused walkCont conts)
+
+      OpH tag# inMap regions opAny conts ->
+        OpH tag# inMap (rmapFused walkRegion regions) opAny (rmapFused walkCont conts)
+
+      ScopeRow ehMorph efMorph subPipe ->
+        ScopeRow ehMorph efMorph (unsafeCoerce# (go (unsafeCoerce# subPipe)))
+
+{- |
+Modify the reader environment within a scoped sub-computation at a custom effect label.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE localAt #-}
+localAt ::
+  forall (l :: Symbol) r eh ef a.
+  ConstructorIndex l ef =>
+  (r -> r)
+  -> Eff eh ef a
+  -> Eff eh ef a
+localAt f (Eff pipe) =
+  let !targetTag# = case constructorIndex @_ @l @ef of W# w# -> w#
+  in Eff (localWalk targetTag# f pipe)
+
+{- |
+Modify the reader environment within a scoped sub-computation defaulting to label @"reader"@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE local #-}
+local ::
+  forall r eh ef a.
+  ConstructorIndex "reader" ef =>
+  (r -> r)
+  -> Eff eh ef a
+  -> Eff eh ef a
+local = localAt @"reader"
+
+{- |
+Walk the 'Penelope' polycategorical graph, intercepting every 'Throw' node targeted
+by 'targetTag#' and substituting the handler continuation.
+
+See Note [Two-Phase Weaving and Unweaving] [ref:note-two-phase-engine].
+-}
+catchWalk ::
+  forall eh ef e a ins outs.
+  Word#
+  -> (e -> Eff eh ef a)
+  -> Penelope eh ef ins outs
+  -> Penelope eh ef ins outs
+catchWalk !targetTag# handler pipe = go pipe
+  where
+    walkCont :: forall i o branchOuts. BranchCont (Penelope eh ef i o) branchOuts -> BranchCont (Penelope eh ef i o) branchOuts
+    walkCont (BranchCont k) = BranchCont (\recFrame -> go (k recFrame))
+
+    walkRegion :: forall sig. Region eh ef sig -> Region eh ef sig
+    walkRegion (Region p) = Region (go p)
+
+    go :: forall i o. Penelope eh ef i o -> Penelope eh ef i o
+    go = \case
+      Route morph ->
+        Route morph
+
+      LiftPure inMap pureF (BranchCont k) ->
+        LiftPure inMap pureF (BranchCont (\recFrame -> go (k recFrame)))
+
+      OpF tag# _inMap opAny _conts
+        | isTrue# (tag# `eqWord#` targetTag#) ->
+            let !(Throw err) = unsafeCoerce# opAny :: ThrowEff e Any
+                !(Eff handlerPipe) = handler err
+            in unsafeCoerce# handlerPipe
+        | otherwise ->
+            OpF tag# _inMap opAny (rmapFused walkCont _conts)
+
+      OpH tag# inMap regions opAny conts ->
+        OpH tag# inMap (rmapFused walkRegion regions) opAny (rmapFused walkCont conts)
+
+      ScopeRow ehMorph efMorph subPipe ->
+        ScopeRow ehMorph efMorph (unsafeCoerce# (go (unsafeCoerce# subPipe)))
+
+{- |
+Catch and recover from algebraic errors at a custom effect label.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE catchErrorAt #-}
+catchErrorAt ::
+  forall (l :: Symbol) e eh ef a.
+  ConstructorIndex l ef =>
+  Eff eh ef a
+  -> (e -> Eff eh ef a)
+  -> Eff eh ef a
+catchErrorAt (Eff pipe) handler =
+  let !targetTag# = case constructorIndex @_ @l @ef of W# w# -> w#
+  in Eff (catchWalk targetTag# handler pipe)
+
+{- |
+Catch and recover from algebraic errors defaulting to effect label @"error"@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE catchError #-}
+catchError ::
+  forall e eh ef a.
+  ConstructorIndex "error" ef =>
+  Eff eh ef a
+  -> (e -> Eff eh ef a)
+  -> Eff eh ef a
+catchError = catchErrorAt @"error"
+
+{- |
+Elaborator for higher-order 'Local' effect unrolling into pure first-order 'ef' operations.
+
+See Note [Two-Phase Weaving and Unweaving] [ref:note-two-phase-engine].
+-}
+{-# INLINE localElaborator #-}
+localElaborator ::
+  forall (l :: Symbol) ef r.
+  ConstructorIndex l ef =>
+  Elaborator '[] ef (Local r)
+localElaborator = Elaborator $ \inMap regs opAny kConts ->
+  let !(Identity bodyRegAny) = indexSmallArray (let RowRep (Rep _ arr) = regs in arr) 0
+      !(Region bodyPipe) = unsafeCoerce# bodyRegAny
+      !f = unsafeCoerce# opAny :: r -> r
+      !targetTag# = case constructorIndex @_ @l @ef of W# w# -> w#
+      !transformedBody = localWalk targetTag# f (unsafeCoerce# bodyPipe)
+      !(Identity retContAny) = indexSmallArray (let RowRep (Rep _ arr) = kConts in arr) 0
+      !(BranchCont retK) = unsafeCoerce# retContAny
+  in preComposeRoute inMap (unsafeCoerce# (transformedBody `seqPenelope` retK (unsafeCoerce# emptyRecord)))
+
+{- |
+Elaborator for higher-order 'Catch' effect unrolling into pure first-order 'ef' operations.
+
+See Note [Two-Phase Weaving and Unweaving] [ref:note-two-phase-engine].
+-}
+{-# INLINE catchElaborator #-}
+catchElaborator ::
+  forall (l :: Symbol) ef e.
+  ConstructorIndex l ef =>
+  Elaborator '[] ef (Catch e)
+catchElaborator = Elaborator $ \inMap regs _opAny kConts ->
+  let !(Identity bodyRegAny) = indexSmallArray (let RowRep (Rep _ arr) = regs in arr) 0
+      !(Region bodyPipe) = unsafeCoerce# bodyRegAny
+      !(Identity handlerRegAny) = indexSmallArray (let RowRep (Rep _ arr) = regs in arr) 1
+      !(Region handlerPipe) = unsafeCoerce# handlerRegAny
+      !targetTag# = case constructorIndex @_ @l @ef of W# w# -> w#
+      !transformedBody = catchWalk targetTag# (\_err -> Eff (unsafeCoerce# handlerPipe)) (unsafeCoerce# bodyPipe)
+      !(Identity retContAny) = indexSmallArray (let RowRep (Rep _ arr) = kConts in arr) 0
+      !(BranchCont retK) = unsafeCoerce# retContAny
+  in preComposeRoute inMap (unsafeCoerce# (transformedBody `seqPenelope` retK (unsafeCoerce# emptyRecord)))
+
+{- |
+Construct an 'EffHandler' supplying an environment @r@ for 'AskEff'.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE readerHandler #-}
+readerHandler ::
+  forall r m.
+  Monad m =>
+  r
+  -> EffHandler m (AskEff r)
+readerHandler env = mkEffHandler $ \case
+  Ask -> pure env
+
+{- |
+Execute a pure 'Eff' computation supplying an environment @r@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runReaderPure #-}
+runReaderPure ::
+  forall r a.
+  r
+  -> Eff '[] '["reader" ':= UnaryEffect (AskEff r)] a
+  -> a
+runReaderPure env prog =
+  let handlers = insertField (Field @"reader") (readerHandler env) emptyRecord
+      Identity res = runEffM handlers prog
+  in res
+
+{- |
+Construct an 'EffHandler' interpreting 'ThrowEff' under the 'Either e' error monad.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE errorHandler #-}
+errorHandler ::
+  forall e.
+  EffHandler (Either e) (ThrowEff e)
+errorHandler = mkEffHandler $ \(Throw err) -> Left err
+
+{- |
+Execute a pure 'Eff' computation catching errors into 'Either e a'.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runErrorPure #-}
+runErrorPure ::
+  forall e a.
+  Eff '[] '["error" ':= UnaryEffect (ThrowEff e)] a
+  -> Either e a
+runErrorPure prog =
+  let handlers = insertField (Field @"error") errorHandler emptyRecord
+  in runEffM handlers prog
diff --git a/src/Penelope/Effects/Unary.hs b/src/Penelope/Effects/Unary.hs
new file mode 100644
--- /dev/null
+++ b/src/Penelope/Effects/Unary.hs
@@ -0,0 +1,215 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+
+{- |
+Module      : Penelope.Effects.Unary
+Description : Heftia unary monad facade over Penelope (m,n,k,r)-ary core
+Copyright   : (c) 2026 The Penelope Authors
+License     : EUPL-1.2 OR Apache-2.0
+Maintainer  : nadia.yvette.chambers@ik.me
+Stability   : experimental
+Portability : non-portable (GHC extensions)
+
+Provides a standard unary monadic interface ('Eff') over Penelope's polycategorical core.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+module Penelope.Effects.Unary
+  ( -- * Unary Monad Facade
+    Eff (..)
+
+    -- * Effect Injection
+  , send
+  , sendEff
+
+    -- * Handlers and Lifting Adapters
+  , UnaryEffect
+  , EffHandler
+  , EffHandlers
+  , mkEffHandler
+
+    -- * Runners
+  , runEff
+  , runEffM
+  ) where
+
+import Control.Monad (ap)
+import Data.Functor.Identity (Identity (..))
+import Data.Kind (Type)
+import Data.Primitive.SmallArray (indexSmallArray)
+import GHC.Exts (Any, Word (W#), unsafeCoerce#)
+import GHC.TypeLits (Symbol)
+import Penelope.Core.Engine.Elaborate (MapRow)
+import Penelope.Core.Engine.Interpret
+  ( FrameKleisli (..)
+  , Handler (..)
+  , interpretAll
+  , runPenelopePure
+  )
+import Penelope.Core.Syntax
+  ( BranchCont (..)
+  , Penelope (..)
+  , PolyEffect
+  , PolyHEffect
+  )
+import Penelope.Core.Wiring (preComposeRoute, seqPenelope)
+import Polytropos (Field (..), Record, RowOf, emptyRecord, insertField)
+import Polytropos.Core (ConstructorIndex (..), Pair (..), Rep (..), RowRep (..))
+import Polytropos.RowMorph (unsafeMkRowMorph)
+
+{- |
+Zero-cost unary monadic projection over Penelope's underlying polycategorical engine.
+A computation of type @Eff eh ef a@ is isomorphic to a pipeline with zero input registers
+and a single output register @'["val" ':= a]@.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+newtype Eff (eh :: RowOf PolyHEffect) (ef :: RowOf PolyEffect) a = Eff
+  { unEff :: Penelope eh ef '[] '["val" ':= a]
+  }
+
+instance Functor (Eff eh ef) where
+  {-# INLINE fmap #-}
+  fmap f m = m >>= (\a -> pure (f a))
+
+instance Applicative (Eff eh ef) where
+  {-# INLINE pure #-}
+  pure a =
+    let p :: Penelope eh ef '[] '["val" ':= a]
+        p = LiftPure
+          (unsafeMkRowMorph [])
+          (\_ -> insertField (Field @"val") a emptyRecord)
+          (BranchCont (\_ -> Route (unsafeMkRowMorph [0])))
+    in Eff p
+
+  {-# INLINE (<*>) #-}
+  (<*>) = ap
+
+instance Monad (Eff eh ef) where
+  {-# INLINE (>>=) #-}
+  (>>=) = bindEff
+
+{-# INLINE bindEff #-}
+bindEff ::
+  forall eh ef a b.
+  Eff eh ef a
+  -> (a -> Eff eh ef b)
+  -> Eff eh ef b
+bindEff (Eff p) k =
+  let stage :: Penelope eh ef '["val" ':= a] '["val" ':= b]
+      stage = LiftPure
+        (unsafeMkRowMorph [0])
+        (\rec -> rec)
+        (BranchCont $ \res ->
+          let !(Identity aVal) = indexSmallArray (let RowRep (Rep _ arr) = res in arr) 0
+              !a = unsafeCoerce# aVal :: a
+              !(Eff nextP) = k a
+          in preComposeRoute (unsafeMkRowMorph []) nextP
+        )
+  in Eff (seqPenelope p stage)
+
+{- |
+Inject a first-order unary algebraic effect into 'Eff'.
+Resolves the constructor tag in \(O(1)\) at compile time via 'ConstructorIndex'.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE sendEff #-}
+sendEff ::
+  forall (l :: Symbol) (sig :: Type -> Type) a (eh :: RowOf PolyHEffect) (ef :: RowOf PolyEffect).
+  ConstructorIndex l ef =>
+  sig a
+  -> Eff eh ef a
+sendEff op =
+  let retCont = BranchCont (\_ -> Route (unsafeMkRowMorph [0]))
+      conts = insertField (Field @"ret") retCont emptyRecord
+      !tag# = case constructorIndex @_ @l @ef of W# w# -> w#
+      p = OpF tag# (unsafeMkRowMorph []) (unsafeCoerce# op) conts
+  in Eff p
+
+-- | Convenient alias for 'sendEff'.
+{-# INLINE send #-}
+send ::
+  forall (l :: Symbol) (sig :: Type -> Type) a (eh :: RowOf PolyHEffect) (ef :: RowOf PolyEffect).
+  ConstructorIndex l ef =>
+  sig a
+  -> Eff eh ef a
+send = sendEff @l
+
+{- |
+Type-level adapter lifting a standard unary effect GADT (@sig :: Type -> Type@)
+into Penelope's poly-kinded 'PolyEffect' representation.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data UnaryEffect (sig :: Type -> Type) :: PolyEffect
+
+-- | Handler for a single first-order effect under a target monad @m@.
+type EffHandler m (sig :: Type -> Type) = Handler '[] (FrameKleisli m) (UnaryEffect sig)
+
+-- | Record of handlers for the first-order effect row @ef@.
+type EffHandlers ef m = Record (MapRow (Handler '[] (FrameKleisli m)) ef)
+
+{- |
+Construct an 'EffHandler' from a standard unary interpreter function.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE mkEffHandler #-}
+mkEffHandler ::
+  forall (sig :: Type -> Type) m.
+  Monad m =>
+  (forall a. sig a -> m a)
+  -> Handler '[] (FrameKleisli m) (UnaryEffect sig)
+mkEffHandler runOp = Handler $ \_inMap opAny kConts ->
+  let !op = unsafeCoerce# opAny :: sig Any
+      !(Identity elabK) = indexSmallArray (let RowRep (Rep _ arr) = kConts in arr) 0
+      !(BranchCont retK) = unsafeCoerce# elabK
+  in FrameKleisli $ \_inF -> do
+       res <- runOp op
+       let resFrame = insertField (Field @"val") res emptyRecord
+       runFrameKleisli (retK resFrame) resFrame
+
+{- |
+Execute a pure, closed 'Eff' computation to its final value.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runEff #-}
+runEff :: Eff '[] '[] a -> a
+runEff (Eff p) =
+  let outFrame = runPenelopePure p emptyRecord
+      !(Identity val) = indexSmallArray (let RowRep (Rep _ arr) = outFrame in arr) 0
+  in unsafeCoerce# val
+
+{- |
+Execute an effectful 'Eff' computation into a target 'Monad' using a handler vector.
+
+See Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runEffM #-}
+runEffM ::
+  forall ef m a.
+  Monad m =>
+  Record (MapRow (Handler '[] (FrameKleisli m)) ef)
+  -> Eff '[] ef a
+  -> m a
+runEffM handlers (Eff p) = do
+  let kleisli = interpretAll handlers p
+  outFrame <- runFrameKleisli kleisli emptyRecord
+  let !(Identity val) = indexSmallArray (let RowRep (Rep _ arr) = outFrame in arr) 0
+  pure (unsafeCoerce# val)
diff --git a/src/Penelope/Effects/UnliftIO.hs b/src/Penelope/Effects/UnliftIO.hs
new file mode 100644
--- /dev/null
+++ b/src/Penelope/Effects/UnliftIO.hs
@@ -0,0 +1,267 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+
+{- |
+Module      : Penelope.Effects.UnliftIO
+Description : Sound scoped resource management, masking, and dependency injection
+Copyright   : (c) 2026 The Penelope Authors
+License     : EUPL-1.2 OR Apache-2.0
+Maintainer  : nadia.yvette.chambers@ik.me
+Stability   : experimental
+Portability : non-portable (GHC extensions)
+
+Provides sound scoped resource management guaranteed never to leak handles
+across dynamic evaluation contexts:
+1. 'Bracket' higher-order scoped resource acquisition and cleanup
+2. 'Mask' asynchronous exception safety
+3. 'Provider' dependency injection
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+module Penelope.Effects.UnliftIO
+  ( -- * Scoped Bracket
+    Bracket (..)
+  , bracketElaborator
+  , bracketEff
+  , bracketEitherEff
+  , bracketIO
+
+    -- * Masking
+  , Mask
+  , maskIO
+
+    -- * Provider Dependency Injection
+  , Provider
+  , ProviderEff (..)
+  , askProvider
+  , providerHandler
+  , runProviderPure
+  ) where
+
+import qualified Control.Exception as E
+import Data.Functor.Identity (Identity (..))
+import Data.Kind (Type)
+import Data.Primitive.SmallArray (indexSmallArray)
+import GHC.Exts (unsafeCoerce#)
+import GHC.TypeLits (Symbol)
+import Penelope.Core.Engine.Elaborate (Elaborator (..))
+import Penelope.Core.Engine.Interpret (runPenelopePure)
+import Penelope.Core.Syntax
+  ( BranchCont (..)
+  , Penelope (..)
+  , PolyEffect
+  , PolyHEffect
+  , PortSig (..)
+  , Region (..)
+  )
+import Penelope.Effects.Unary
+  ( Eff (..)
+  , EffHandler
+  , UnaryEffect
+  , mkEffHandler
+  , runEffM
+  , send
+  )
+import Polytropos (Field (..), RowOf, emptyRecord, insertField)
+import Polytropos.Core (ConstructorIndex (..), Pair (..), Rep (..), RowRep (..))
+
+{- |
+Higher-order scoped 'Bracket' effect with three sub-regions:
+1. @"acquire"@: Allocates the resource handle.
+2. @"action"@: Operates with the acquired resource.
+3. @"release"@: Guarantees release of the resource on all paths.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data Bracket (r :: PortSig -> Type) (regs :: RowOf PortSig) (opIns :: RowOf Type) (exits :: RowOf (RowOf Type)) where
+  BracketOp :: Bracket r
+    '[ "acquire" ':= 'PortSig ins '["res" ':= res]
+     , "action"  ':= 'PortSig '["res" ':= res] '["out" ':= a]
+     , "release" ':= 'PortSig '["res" ':= res] '[]
+     ]
+    ins
+    '[ "ret" ':= '["out" ':= a] ]
+
+{- |
+Elaborator for 'Bracket' lowering scoped resource handling into guaranteed cleanup.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE bracketElaborator #-}
+bracketElaborator ::
+  forall ef.
+  Elaborator '[] ef Bracket
+bracketElaborator = Elaborator $ \inMap regs _ kConts ->
+  LiftPure inMap
+    (\inRec ->
+      let !(Identity acqRegAny) = indexSmallArray (let RowRep (Rep _ arr) = regs in arr) 0
+          !(Region acqPipe) = unsafeCoerce# acqRegAny
+          !(Identity actRegAny) = indexSmallArray (let RowRep (Rep _ arr) = regs in arr) 1
+          !(Region actPipe) = unsafeCoerce# actRegAny
+          !(Identity relRegAny) = indexSmallArray (let RowRep (Rep _ arr) = regs in arr) 2
+          !(Region relPipe) = unsafeCoerce# relRegAny
+
+          !resRec = runPenelopePure acqPipe (unsafeCoerce# inRec)
+          !actRec = runPenelopePure actPipe (unsafeCoerce# resRec)
+          !relRec = runPenelopePure relPipe (unsafeCoerce# resRec)
+      in seq relRec actRec
+    )
+    (BranchCont $ \finalActRec ->
+      let !(Identity retContAny) = indexSmallArray (let RowRep (Rep _ arr) = kConts in arr) 0
+          !(BranchCont retK) = unsafeCoerce# retContAny
+      in retK (unsafeCoerce# finalActRec)
+    )
+
+{- |
+Bracket pattern for 'Eff' ensuring resource cleanup.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE bracketEff #-}
+bracketEff ::
+  forall res a eh ef.
+  Eff eh ef res
+  -> (res -> Eff eh ef ())
+  -> (res -> Eff eh ef a)
+  -> Eff eh ef a
+bracketEff acquire release action = do
+  r <- acquire
+  val <- action r
+  release r
+  pure val
+
+{- |
+Bracket pattern for 'Eff' with error exit propagation ensuring resource cleanup
+on both successful and failed branches.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE bracketEitherEff #-}
+bracketEitherEff ::
+  forall res err a eh ef.
+  Eff eh ef res
+  -> (res -> Eff eh ef ())
+  -> (res -> Eff eh ef (Either err a))
+  -> Eff eh ef (Either err a)
+bracketEitherEff acquire release action = do
+  r <- acquire
+  resOrErr <- action r
+  release r
+  pure resOrErr
+
+{- |
+Bracket pattern for 'IO' utilizing underlying exception safety guarantees.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE bracketIO #-}
+bracketIO ::
+  forall res a.
+  IO res
+  -> (res -> IO ())
+  -> (res -> IO a)
+  -> IO a
+bracketIO = E.bracket
+
+{- |
+Higher-order scoped 'Mask' effect guaranteeing asynchronous exception masking.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data Mask :: PolyHEffect
+
+{- |
+Mask asynchronous exceptions within an 'IO' action.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE maskIO #-}
+maskIO ::
+  forall a.
+  ((forall b. IO b -> IO b) -> IO a)
+  -> IO a
+maskIO = E.mask
+
+{- |
+Polycategorical provider dependency injection effect.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data Provider (r :: Type) :: PolyEffect
+
+{- |
+Unary effect GADT representing an environment query.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+data ProviderEff (r :: Type) (a :: Type) where
+  AskProvider :: ProviderEff r r
+
+{- |
+Query the provided environment from within 'Eff'.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE askProvider #-}
+askProvider ::
+  forall (l :: Symbol) r eh ef.
+  ConstructorIndex l ef =>
+  Eff eh ef r
+askProvider = send @l AskProvider
+
+{- |
+Construct an 'EffHandler' supplying an environment handle @r@.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE providerHandler #-}
+providerHandler ::
+  forall r m.
+  Monad m =>
+  r
+  -> EffHandler m (ProviderEff r)
+providerHandler env = mkEffHandler $ \case
+  AskProvider -> pure env
+
+{- |
+Run an 'Eff' computation with a provided environment handle @r@ purely.
+
+See Note [Core Architecture] [ref:note-core-architecture] and
+Note [Zero-Cost Surface Specializations] [ref:note-surface-facades].
+-}
+{-# INLINE runProviderPure #-}
+runProviderPure ::
+  forall r a.
+  r
+  -> Eff '[] '["provider" ':= UnaryEffect (ProviderEff r)] a
+  -> a
+runProviderPure env prog =
+  let handlers = insertField (Field @"provider") (providerHandler env) emptyRecord
+      Identity res = runEffM handlers prog
+  in res
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,571 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# OPTIONS_GHC -fplugin=Polytropos.Plugin #-}
+
+module Main (main) where
+
+import Control.Arrow (Arrow (..), ArrowChoice (..), (>>>))
+import Control.Category (Category (..))
+import qualified Control.Concurrent as C
+import qualified Control.Exception as E
+import Data.Functor.Identity (Identity (..))
+import Data.IORef (modifyIORef', newIORef, readIORef, writeIORef)
+import Data.Kind (Type)
+import Data.Primitive.SmallArray (indexSmallArray)
+import GHC.Exts (unsafeCoerce#)
+import Penelope.Core.Engine.Elaborate (elaborateAll)
+import Penelope.Core.Engine.Interpret (interpretAll, runFrameKleisli, runPenelopePure)
+import Penelope.Core.Syntax (BranchCont (..), Penelope (..), PortSig (..), Region (..))
+import Penelope.Effects
+import Polytropos (Field (..), Record, Variant, emptyRecord, injectVariant, insertField)
+import Polytropos.Core (Pair (..), Rep (..), RowRep (..))
+import Polytropos.RowMorph (unsafeMkRowMorph)
+import Prelude hiding (id, (.))
+import Test.Hspec
+
+-- Unary Effect GADTs for testing
+data AskEffTest :: Type -> Type where
+  AskVal :: AskEffTest Int
+
+data MsgEff :: Type -> Type where
+  GetMsg :: MsgEff String
+  SetMsg :: String -> MsgEff ()
+
+type AskEF = '["ask" ':= UnaryEffect AskEffTest]
+type MsgEF = '["msg" ':= UnaryEffect MsgEff]
+
+-- Variant type for router tests
+type EventSum = '["click" ':= '["x" ':= Int], "key" ':= '["char" ':= Char]]
+
+-- Multi-effect rows for Heftia interaction tests
+type CoroReaderEF = '["yield" ':= UnaryEffect (YieldEff Int), "reader" ':= UnaryEffect (AskEff Int)]
+type CoroCatchEF = '["yield" ':= UnaryEffect (YieldEff String), "error" ':= UnaryEffect (ThrowEff String)]
+type NonDetReaderEF = '["nondet" ':= UnaryEffect NonDetEff, "reader" ':= UnaryEffect (AskEff Int)]
+
+main :: IO ()
+main = hspec $ do
+  describe "Penelope.Effects (Domain Entity)" $ do
+    it "constructs default entity with correct properties" $ do
+      let e = defaultEntity
+      entityName e `shouldBe` "penelope"
+      entityModule e `shouldBe` "Penelope.Effects"
+    it "renders entity accurately" $ do
+      let e = defaultEntity
+      renderEntity e `shouldBe` "penelope:Penelope.Effects"
+
+  describe "Penelope.Effects.Unary (Eff Monad Laws)" $ do
+    it "satisfies left identity: pure a >>= f == f a" $ do
+      let f x = pure (x * 2 :: Int)
+          val = 21 :: Int
+          lhs = runEff (pure val >>= f)
+          rhs = runEff (f val)
+      lhs `shouldBe` 42
+      rhs `shouldBe` 42
+      lhs `shouldBe` rhs
+
+    it "satisfies right identity: m >>= pure == m" $ do
+      let m = pure (42 :: Int)
+          lhs = runEff (m >>= pure)
+          rhs = runEff m
+      lhs `shouldBe` 42
+      rhs `shouldBe` 42
+      lhs `shouldBe` rhs
+
+    it "satisfies associativity: (m >>= f) >>= g == m >>= (\\x -> f x >>= g)" $ do
+      let m = pure (10 :: Int)
+          f x = pure (x + 5 :: Int)
+          g y = pure (y * 2 :: Int)
+          lhs = runEff ((m >>= f) >>= g)
+          rhs = runEff (m >>= (\x -> f x >>= g))
+      lhs `shouldBe` 30
+      rhs `shouldBe` 30
+      lhs `shouldBe` rhs
+
+  describe "Penelope.Effects.Unary (Monadic Ergonomics & Do-Notation)" $ do
+    it "evaluates multi-step monadic do-notation blocks cleanly" $ do
+      let prog :: Eff '[] '[] Int
+          prog = do
+            a <- pure (10 :: Int)
+            b <- pure (20 :: Int)
+            c <- pure (12 :: Int)
+            pure (a + b + c)
+      runEff prog `shouldBe` 42
+
+    it "supports functor fmap and applicative ap" $ do
+      let p1 = pure (20 :: Int)
+          p2 = fmap (* 2) p1
+          p3 = (+) <$> p1 <*> p2
+      runEff p2 `shouldBe` 40
+      runEff p3 `shouldBe` 60
+
+  describe "Penelope.Effects.Unary (Effectful Runners: runEffM)" $ do
+    it "interprets unary effect GADTs via mkEffHandler into Identity" $ do
+      let prog :: Eff '[] AskEF Int
+          prog = do
+            v <- send @"ask" AskVal
+            pure (v * 2)
+
+          askHandler :: EffHandler Identity AskEffTest
+          askHandler = mkEffHandler $ \case
+            AskVal -> Identity (21 :: Int)
+
+          handlers = insertField (Field @"ask") askHandler emptyRecord
+          Identity result = runEffM handlers prog
+      result `shouldBe` 42
+
+    it "interprets stateful multi-operation GADTs via mkEffHandler into IO" $ do
+      ref <- newIORef ("initial" :: String)
+      let prog :: Eff '[] MsgEF String
+          prog = do
+            m <- send @"msg" GetMsg
+            send @"msg" (SetMsg "updated")
+            pure ("msg:" <> m)
+
+          msgHandler :: EffHandler IO MsgEff
+          msgHandler = mkEffHandler $ \case
+            GetMsg -> readIORef ref
+            SetMsg s -> writeIORef ref s
+
+          handlers = insertField (Field @"msg") msgHandler emptyRecord
+
+      res <- runEffM handlers prog
+      res `shouldBe` "msg:initial"
+      final <- readIORef ref
+      final `shouldBe` "updated"
+
+  describe "Penelope.Effects.Binary (Rope Category and Arrow Laws)" $ do
+    it "satisfies Category identity and composition laws" $ do
+      let f :: Rope '[] '[] Int Int
+          f = arr (+ 1)
+          g :: Rope '[] '[] Int Int
+          g = arr (* 2)
+          h :: Rope '[] '[] Int Int
+          h = arr (+ 3)
+      runRopePure (id >>> f) 10 `shouldBe` 11
+      runRopePure (f >>> id) 10 `shouldBe` 11
+      runRopePure ((f >>> g) >>> h) 10 `shouldBe` 25
+      runRopePure (f >>> (g >>> h)) 10 `shouldBe` 25
+
+    it "satisfies Arrow first, second, (***), and (&&&) combinators" $ do
+      let f :: Rope '[] '[] Int Int
+          f = arr (+ 1)
+          g :: Rope '[] '[] String String
+          g = arr reverse
+      runRopePure (first f) (10 :: Int, "hello" :: String) `shouldBe` (11, "hello")
+      runRopePure (second g) (10 :: Int, "hello" :: String) `shouldBe` (10, "olleh")
+      runRopePure (f *** g) (10 :: Int, "world" :: String) `shouldBe` (11, "dlrow")
+      runRopePure (f &&& arr (* 2)) (10 :: Int) `shouldBe` (11, 20)
+
+    it "satisfies ArrowChoice left and right branch routing" $ do
+      let f :: Rope '[] '[] Int Int
+          f = arr (+ 1)
+      runRopePure (left f) (Left 10 :: Either Int String) `shouldBe` Left 11
+      runRopePure (left f) (Right "pass" :: Either Int String) `shouldBe` Right "pass"
+      runRopePure (right f) (Right 20 :: Either String Int) `shouldBe` Right 21
+      runRopePure (right f) (Left "pass" :: Either String Int) `shouldBe` Left "pass"
+
+  describe "Penelope.Effects.Binary (Static Jump-Table deriveRouter)" $ do
+    it "dispatches multi-constructor Variant inputs in O(1) via deriveRouter" $ do
+      let hClick :: Rope '[] '[] (Record '["x" ':= Int]) String
+          hClick = arr $ \r ->
+            let !(Identity x) = indexSmallArray (let RowRep (Rep _ arrRep) = r in arrRep) 0
+            in "clicked:" <> show (unsafeCoerce# x :: Int)
+
+          hKey :: Rope '[] '[] (Record '["char" ':= Char]) String
+          hKey = arr $ \r ->
+            let !(Identity c) = indexSmallArray (let RowRep (Rep _ arrRep) = r in arrRep) 0
+            in "key:" <> [unsafeCoerce# c :: Char]
+
+          handlers = insertField (Field @"click") hClick
+                   $ insertField (Field @"key") hKey
+                   $ emptyRecord
+
+          router :: Rope '[] '[] (Variant EventSum) String
+          router = deriveRouter handlers
+
+          v1 = injectVariant (Field @"click") (insertField (Field @"x") (42 :: Int) emptyRecord)
+          v2 = injectVariant (Field @"key") (insertField (Field @"char") 'q' emptyRecord)
+
+      runRopePure router v1 `shouldBe` "clicked:42"
+      runRopePure router v2 `shouldBe` "key:q"
+
+  describe "Penelope.Effects.Control (While, Switch, Saga)" $ do
+    it "executes whileEff loop with state termination" $ do
+      let loop :: Eff '[] '[] Int
+          loop = whileEff (\s -> pure (s < 5)) (\s -> pure (s + 1)) (0 :: Int)
+      runEff loop `shouldBe` 5
+
+    it "elaborates and executes multi-region While loop to state termination" $ do
+      let condPipe :: Penelope '[] '[] '["x" ':= Int] '["cond" ':= Bool]
+          condPipe = LiftPure (unsafeMkRowMorph [0])
+            (\r ->
+              let !(Identity x) = indexSmallArray (let RowRep (Rep _ sArr) = r in sArr) 0
+                  !b = (unsafeCoerce# x :: Int) < 3
+              in insertField (Field @"cond") b emptyRecord
+            )
+            (BranchCont (\_ -> Route (unsafeMkRowMorph [0])))
+
+      let bodyPipe :: Penelope '[] '[] '["x" ':= Int] '["x" ':= Int]
+          bodyPipe = LiftPure (unsafeMkRowMorph [0])
+            (\r ->
+              let !(Identity x) = indexSmallArray (let RowRep (Rep _ sArr) = r in sArr) 0
+                  !nextX = (unsafeCoerce# x :: Int) + 1
+              in insertField (Field @"x") nextX emptyRecord
+            )
+            (BranchCont (\_ -> Route (unsafeMkRowMorph [0])))
+
+      let regs = insertField (Field @"cond") (Region @'[] @'[] @('PortSig '["x" ':= Int] '["cond" ':= Bool]) condPipe)
+               $ insertField (Field @"body") (Region @'[] @'[] @('PortSig '["x" ':= Int] '["x" ':= Int]) bodyPipe)
+               $ emptyRecord
+
+      let retCont = BranchCont (\_ -> Route (unsafeMkRowMorph [0]))
+      let exits = insertField (Field @"exit") retCont emptyRecord
+
+      let whileTerm :: Penelope '["while" ':= While] '[] '["x" ':= Int] '["x" ':= Int]
+          whileTerm = OpH 0## (unsafeMkRowMorph [0]) regs (unsafeCoerce# ()) exits
+
+      let elabs = insertField (Field @"while") whileElaborator emptyRecord
+          elaborated = elaborateAll elabs whileTerm
+
+      let inFrame = insertField (Field @"x") (0 :: Int) emptyRecord
+          outFrame = runPenelopePure elaborated inFrame
+          !(Identity finalX) = indexSmallArray (let RowRep (Rep _ sArr) = outFrame in sArr) 0
+
+      (unsafeCoerce# finalX :: Int) `shouldBe` 3
+
+    it "executes transactional Saga committing on success and compensating on failure" $ do
+      let prog1 :: Eff '[] '[] (Either String Int)
+          prog1 = runSagaEff (pure ("action" :: String)) (\_ -> pure ()) (\_ -> pure (Right 42))
+
+          prog2 :: Eff '[] '[] (Either String Int)
+          prog2 = runSagaEff (pure ("action" :: String)) (\_ -> pure ()) (\_ -> pure (Left "err"))
+
+      runEff prog1 `shouldBe` Right 42
+      runEff prog2 `shouldBe` Left "err"
+
+  describe "Penelope.Effects.Coroutine (Delimited Continuations & Generator)" $ do
+    it "yields elements from generator to consumer cleanly" $ do
+      let gen :: Eff '[] '["yield" ':= UnaryEffect (YieldEff Int)] String
+          gen = do
+            yield @"yield" (10 :: Int)
+            yield @"yield" (20 :: Int)
+            yield @"yield" (30 :: Int)
+            pure "finished"
+          (yielded, res) = runGenerator gen
+      yielded `shouldBe` [10, 20, 30]
+      res `shouldBe` "finished"
+
+    it "runs non-deterministic branching exploration via runNonDet" $ do
+      let prog :: Eff '[] '["nondet" ':= UnaryEffect NonDetEff] Int
+          prog = do
+            b1 <- branch @"nondet"
+            b2 <- branch @"nondet"
+            case (b1, b2) of
+              (True, True)   -> pure 10
+              (True, False)  -> pure 20
+              (False, True)  -> pure 30
+              (False, False) -> emptyNonDet @"nondet"
+      runNonDet prog `shouldBe` [10, 20, 30]
+
+  describe "Penelope.Effects.UnliftIO (Scoped Resource Safety & Provider)" $ do
+    it "guarantees Bracket resource cleanup on success exit" $ do
+      ref <- newIORef ([] :: [String])
+      let acquire = do
+            writeIORef ref ["acquired"]
+            pure ("handle" :: String)
+          release _ =
+            modifyIORef' ref ("released" :)
+          action _ = do
+            modifyIORef' ref ("action" :)
+            pure (42 :: Int)
+
+      res <- bracketIO acquire release action
+      res `shouldBe` 42
+      logRes <- readIORef ref
+      logRes `shouldBe` ["released", "action", "acquired"]
+
+    it "guarantees Bracket resource cleanup on error exit" $ do
+      ref <- newIORef ([] :: [String])
+      let acquire = do
+            writeIORef ref ["acquired"]
+            pure ("handle" :: String)
+          release _ =
+            modifyIORef' ref ("released" :)
+          actionErr _ = do
+            modifyIORef' ref ("action-failed" :)
+            error "simulated failure" :: IO Int
+
+      (bracketIO acquire release actionErr >> pure ()) `shouldThrow` anyErrorCall
+      logRes <- readIORef ref
+      logRes `shouldBe` ["released", "action-failed", "acquired"]
+
+    it "supports pure bracketEitherEff error exit" $ do
+      let prog = bracketEitherEff (pure ("res" :: String)) (\_ -> pure ()) (\_ -> pure (Left "boom" :: Either String Int))
+      runEff prog `shouldBe` Left "boom"
+
+    it "injects dependencies via Provider purely" $ do
+      let prog :: Eff '[] '["provider" ':= UnaryEffect (ProviderEff String)] String
+          prog = do
+            env <- askProvider @"provider"
+            pure ("env:" <> env)
+      runProviderPure "production" prog `shouldBe` "env:production"
+
+  describe "Penelope.Effects.Scoped (Reader / Local)" $ do
+    it "reads lexical environment purely via askReader and runReaderPure" $ do
+      let prog :: Eff '[] '["reader" ':= UnaryEffect (AskEff Int)] Int
+          prog = do
+            v <- askReader
+            pure (v * 2)
+      runReaderPure (21 :: Int) prog `shouldBe` 42
+
+    it "modifies environment in nested local blocks and restores state cleanly" $ do
+      let prog :: Eff '[] '["reader" ':= UnaryEffect (AskEff Int)] (Int, Int, Int)
+          prog = do
+            v0 <- askReader
+            v1 <- local @Int (+ 10) $ do
+              inner1 <- askReader
+              inner2 <- local @Int (* 2) askReader
+              pure (inner1 + inner2)
+            v2 <- askReader
+            pure (v0, v1, v2)
+      -- With initial 5:
+      -- v0 = 5
+      -- inner1 = 15, inner2 = (5 + 10) * 2 = 30 -> v1 = 45
+      -- v2 = 5
+      runReaderPure (5 :: Int) prog `shouldBe` (5, 45, 5)
+
+    it "unrolls higher-order Local effect via localElaborator and elaborateAll" $ do
+      let bodyPipe :: Penelope '[] '["reader" ':= UnaryEffect (AskEff Int)] '[] '["val" ':= Int]
+          bodyPipe = unEff $ do
+            x <- askReader
+            pure (x + 100)
+
+      let regs = insertField (Field @"body") (Region @'[] @'["reader" ':= UnaryEffect (AskEff Int)] @('PortSig '[] '["val" ':= Int]) bodyPipe) emptyRecord
+      let retCont = BranchCont (\_outF -> Route (unsafeMkRowMorph [0]))
+      let exits = insertField (Field @"ret") retCont emptyRecord
+
+      let localOpH :: Penelope '["local" ':= Local Int] '["reader" ':= UnaryEffect (AskEff Int)] '[] '["val" ':= Int]
+          localOpH = OpH 0## (unsafeMkRowMorph []) regs (unsafeCoerce# ((* 2) :: Int -> Int)) exits
+
+      let elabs = insertField (Field @"local") (localElaborator @"reader") emptyRecord
+      let elaborated = elaborateAll elabs localOpH
+
+      let handlers = insertField (Field @"reader") (readerHandler (10 :: Int)) emptyRecord
+      let Identity outFrame = runFrameKleisli (interpretAll handlers elaborated) emptyRecord
+      let !(Identity resVal) = indexSmallArray (let RowRep (Rep _ arrRep) = outFrame in arrRep) 0
+      -- Initial 10 * 2 = 20, plus 100 = 120
+      (unsafeCoerce# resVal :: Int) `shouldBe` 120
+
+  describe "Penelope.Effects.Scoped (Error / Catch)" $ do
+    it "evaluates successful computations to Right with runErrorPure" $ do
+      let prog :: Eff '[] '["error" ':= UnaryEffect (ThrowEff String)] Int
+          prog = pure 42
+      runErrorPure prog `shouldBe` Right 42
+
+    it "aborts on throw with Left error message" $ do
+      let prog :: Eff '[] '["error" ':= UnaryEffect (ThrowEff String)] Int
+          prog = do
+            _ <- pure (10 :: Int)
+            throw ("aborted-computation" :: String)
+      runErrorPure prog `shouldBe` Left "aborted-computation"
+
+    it "catches and recovers from errors via catchError" $ do
+      let prog :: Eff '[] '["error" ':= UnaryEffect (ThrowEff String)] String
+          prog = do
+            catchError
+              (do
+                _ <- pure (1 :: Int)
+                throw ("recoverable-error" :: String)
+              )
+              (\e -> pure ("caught:" <> e))
+      runErrorPure prog `shouldBe` Right "caught:recoverable-error"
+
+    it "unrolls higher-order Catch effect via catchElaborator and elaborateAll" $ do
+      let bodyPipe :: Penelope '[] '["error" ':= UnaryEffect (ThrowEff String)] '[] '["val" ':= String]
+          bodyPipe = unEff $ do
+            _ <- throw ("scoped-error-thrown" :: String)
+            pure "unreachable"
+
+      let handlerPipe :: Penelope '[] '["error" ':= UnaryEffect (ThrowEff String)] '[] '["val" ':= String]
+          handlerPipe = unEff (pure "intercepted-by-elaborator")
+
+      let regs = insertField (Field @"body") (Region @'[] @'["error" ':= UnaryEffect (ThrowEff String)] @('PortSig '[] '["val" ':= String]) bodyPipe)
+               $ insertField (Field @"handler") (Region @'[] @'["error" ':= UnaryEffect (ThrowEff String)] @('PortSig '[] '["val" ':= String]) handlerPipe)
+               $ emptyRecord
+      let retCont = BranchCont (\_outF -> Route (unsafeMkRowMorph [0]))
+      let exits = insertField (Field @"ret") retCont emptyRecord
+
+      let catchOpH :: Penelope '["catch" ':= Catch String] '["error" ':= UnaryEffect (ThrowEff String)] '[] '["val" ':= String]
+          catchOpH = OpH 0## (unsafeMkRowMorph []) regs (unsafeCoerce# ()) exits
+
+      let elabs = insertField (Field @"catch") (catchElaborator @"error") emptyRecord
+      let elaborated = elaborateAll elabs catchOpH
+
+      let handlers = insertField (Field @"error") errorHandler emptyRecord
+      let res = runFrameKleisli (interpretAll handlers elaborated) emptyRecord
+      case res of
+        Right outFrame -> do
+          let !(Identity resVal) = indexSmallArray (let RowRep (Rep _ arrRep) = outFrame in arrRep) 0
+          (unsafeCoerce# resVal :: String) `shouldBe` "intercepted-by-elaborator"
+        Left e ->
+          expectationFailure ("Unexpected unhandled error: " <> show e)
+
+  describe "Penelope.Effects.Concurrent (Async & Task Isolation)" $ do
+    it "forks background IO task via forkEff" $ do
+      mvar <- C.newEmptyMVar
+      let prog :: Eff '[] '["concurrent" ':= UnaryEffect ConcurrentEff] ()
+          prog = forkEff @"concurrent" (C.putMVar mvar ("worker-done" :: String))
+      runConcurrentIO prog
+      res <- C.takeMVar mvar
+      res `shouldBe` "worker-done"
+
+    it "runs asynchronous tasks concurrently and awaits results via waitEff" $ do
+      let task1 = do
+            C.threadDelay 2000
+            pure (10 :: Int)
+          task2 = do
+            C.threadDelay 1000
+            pure (20 :: Int)
+
+      let prog :: Eff '[] '["concurrent" ':= UnaryEffect ConcurrentEff] (Int, Int)
+          prog = do
+            h1 <- async task1
+            h2 <- async task2
+            r1 <- wait h1
+            r2 <- wait h2
+            pure (r1, r2)
+
+      res <- runConcurrentIO prog
+      res `shouldBe` (10, 20)
+
+    it "propagates exceptions from failed asynchronous tasks safely" $ do
+      let failingTask = do
+            E.throwIO (userError "async-failure") :: IO Int
+
+      let prog :: Eff '[] '["concurrent" ':= UnaryEffect ConcurrentEff] Int
+          prog = do
+            h <- async failingTask
+            wait h
+
+      runConcurrentIO prog `shouldThrow` anyException
+
+  describe "Heftia Scoped Semantics & Multi-Shot Interaction" $ do
+    it "preserves local reader environment across coroutine yield suspensions" $ do
+      ref <- newIORef ([] :: [Int])
+      let prog :: Eff '[] CoroReaderEF ()
+          prog = do
+            yield @"yield" (1 :: Int)
+            local @Int (+ 100) $ do
+              yield @"yield" (2 :: Int)
+              x <- ask @"reader"
+              yield @"yield" x
+            yield @"yield" (3 :: Int)
+            y <- ask @"reader"
+            yield @"yield" y
+
+      let yHandler :: EffHandler IO (YieldEff Int)
+          yHandler = mkEffHandler $ \(Yield val) ->
+            modifyIORef' ref (val :)
+
+          rHandler :: EffHandler IO (AskEff Int)
+          rHandler = readerHandler (10 :: Int)
+
+          handlers = insertField (Field @"yield") yHandler
+                   $ insertField (Field @"reader") rHandler
+                   $ emptyRecord
+
+      _ <- runEffM handlers prog
+      yielded <- readIORef ref
+      reverse yielded `shouldBe` [1, 2, 110, 3, 10]
+
+    it "catches errors thrown during coroutine execution and resumes yielding downstream" $ do
+      ref <- newIORef ([] :: [String])
+      let prog :: Eff '[] CoroCatchEF ()
+          prog = do
+            yield @"yield" ("start" :: String)
+            catchError
+              (do
+                yield @"yield" ("in-try" :: String)
+                throwError @"error" ("simulated-failure" :: String)
+                yield @"yield" ("unreachable" :: String)
+              )
+              (\e -> do
+                yield @"yield" ("recovered:" <> e :: String)
+              )
+            yield @"yield" ("after-catch" :: String)
+
+      let yHandler :: EffHandler IO (YieldEff String)
+          yHandler = mkEffHandler $ \(Yield val) ->
+            modifyIORef' ref (val :)
+
+          eHandler :: EffHandler IO (ThrowEff String)
+          eHandler = mkEffHandler $ \(Throw e) ->
+            fail ("Unhandled throw caught by carrier: " <> e)
+
+          handlers = insertField (Field @"yield") yHandler
+                   $ insertField (Field @"error") eHandler
+                   $ emptyRecord
+
+      _ <- runEffM handlers prog
+      yielded <- readIORef ref
+      reverse yielded `shouldBe` ["start", "in-try", "recovered:simulated-failure", "after-catch"]
+
+    it "maintains complete environment isolation across multi-shot non-deterministic branches" $ do
+      let prog :: Eff '[] NonDetReaderEF Int
+          prog = do
+            b <- branch @"nondet"
+            if b
+              then local @Int (+ 10) (ask @"reader")
+              else local @Int (+ 20) (ask @"reader")
+
+      let ndHandler :: EffHandler [] NonDetEff
+          ndHandler = nonDetHandler
+
+          rHandler :: EffHandler [] (AskEff Int)
+          rHandler = readerHandler (5 :: Int)
+
+          handlers = insertField (Field @"nondet") ndHandler
+                   $ insertField (Field @"reader") rHandler
+                   $ emptyRecord
+
+      let results = runEffM handlers prog
+      results `shouldBe` [15, 25]
+
+    it "guarantees balanced resource acquisition and cleanup across multiple concurrent branches" $ do
+      ref <- newIORef ([] :: [String])
+      let acquire name = do
+            modifyIORef' ref ((name <> "-acq") :)
+            pure name
+          release name = do
+            modifyIORef' ref ((name <> "-rel") :)
+
+      let task1 = bracketIO (acquire "worker1") release (\n -> pure (n <> "-done"))
+          task2 = bracketIO (acquire "worker2") release (\n -> pure (n <> "-done"))
+
+      let prog :: Eff '[] '["concurrent" ':= UnaryEffect ConcurrentEff] (String, String)
+          prog = do
+            h1 <- async task1
+            h2 <- async task2
+            r1 <- wait h1
+            r2 <- wait h2
+            pure (r1, r2)
+
+      res <- runConcurrentIO prog
+      res `shouldBe` ("worker1-done", "worker2-done")
+
+      logEntries <- readIORef ref
+      logEntries `shouldContain` ["worker1-acq"]
+      logEntries `shouldContain` ["worker1-rel"]
+      logEntries `shouldContain` ["worker2-acq"]
+      logEntries `shouldContain` ["worker2-rel"]
