| name | functional-platform |
| description | Deliver immutable, concurrency-aware services and applications across Elixir, Scala, Haskell, Clojure, Erlang, and F# while keeping runtime and data-model choices explicit. |
Functional Platform
Use this pack for functional-platform work: Elixir and Erlang services, Phoenix applications, Scala backends, Haskell libraries, Clojure services, F# applications, and data-first systems where immutable state and effect boundaries shape the design.
Defer first-pass route choice and lane selection to ../../reference/routing-guidance.md.
This is the general functional-language family pack for the repo. Use the overlay in reference/elixir-phoenix-scala-clojure.md to tune decisions for Phoenix, Scala, and Clojure-heavy stacks while keeping the shared expectations for immutability, runtime behavior, message flow, and application structure intact.
Setup posture
- Prefer modernizing, refining, or extending an existing project in place.
- Treat scaffold,
create, init, or new flows as greenfield-only and explicit-request-only. Defer to reference/project-setup-policy.md.
Core focus
- Model domain behavior with immutable data, explicit transformations, and clear effect boundaries.
- Keep process, actor, mailbox, queue, stream, or task-based concurrency visible instead of treating every runtime as ordinary threaded code.
- Separate pure or mostly pure domain logic from I/O, persistence, and framework edges.
- Keep schema, spec, or type-driven validation at the boundary where data enters or leaves the application.
- Structure services and applications around modules, OTP trees, pipelines, and stable domain composition rather than incidental mutation.
Shared functional-platform standards
- Respect the runtime model of each family: OTP processes in Elixir and Erlang, JVM effect or actor runtimes in Scala, pure core plus effect shell in Haskell and F#, and data-first collection flows in Clojure.
- Keep state ownership explicit, whether it lives in an owned process, a stream topology, a persistent data structure, or a controlled effect boundary.
- Make blocking versus non-blocking behavior readable so runtime scheduling and throughput do not become guesswork.
- Use tests that exercise transformations, message flow, and boundary contracts rather than only happy-path controller or handler behavior.
- Keep framework and runtime conventions visible enough that contributors can trace where data is validated, transformed, and dispatched.
Default workflow
- Inspect the runtime, build tool, application structure, and current concurrency model.
- Choose the functional-runtime overlay in
reference/elixir-phoenix-scala-clojure.md.
- Define data shapes, effect boundaries, concurrency ownership, and service structure before broad implementation.
- Implement domain transformations, runtime wiring, and boundary tests together so the operational model stays coherent.
- Run
review skill after substantial functional-platform changes.
Collaboration in this repo
- Use research tools or the built-in Explore behavior before editing so new work matches local namespace, module, and runtime conventions.
- Use research tools, Context7, or equivalent knowledge retrieval when library APIs, runtime semantics, or framework behavior need a source-of-truth check.
- Use
review skill when changes materially affect concurrency behavior, process trees, state ownership, or core data flow.
Overlays
reference/elixir-phoenix-scala-clojure.md for immutable modeling, process or message concurrency, and selected framework or runtime distinctions.
Guardrails
- Do not port mutable object-oriented patterns directly into runtimes that want data-first or effect-aware structure.
- Do not hide process-tree, queueing, or scheduler behavior inside macros, decorators, or framework glue.
- Do not flatten Elixir, Scala, Haskell, Clojure, Erlang, and F# into one lowest-common-denominator style that ignores runtime strengths.