Effect keeps the surfaces on one contract
An Effect Schema defines accepted values and provides types and runtime checks.
Our shared contract describes one actionâs input, output, failures, and metadata.
Effect Schema owns inputs, outputs, and failures in our shared contract. implement.ts binds the handler and its approval requirement.¶
A projection builds an interface from a capability, a named action with a contract and handler. The HTTP projection creates an Effect HttpApi. Other projections create CLI commands and an AI toolkit from the same contracts.¶
apps/cli/src/surfaces.ts and apps/site/src/app.ts supply implementations with Layers.¶
Follow one interface at a time
- MCP is another surface28: discover and call the toolkit over the protocol.¶
- OpenAPI describes the refusal too14: derive the HTTP document and declare the bodyless decode failure.¶
- One schema, three surfaces25: project the contract instead of maintaining three schemas.¶
- Schemas define the boundary25: decode unknown values and keep domain refusals typed.¶
- One program can replace several tool calls21: combine content capabilities without widening their authority.¶
Layer supplies the job
packages/core/src/join-intake.ts builds a Layer.effect(JoinInterest, ...). It captures the ticket, scoring, events, contact store, delivery, and token services. It then returns the submission method.¶
Source: packages/core/src/join-intake.ts at b4d6b8f499e57bc76914ad70df3a0c99751ae28c, lines 55â69.¶
export const joinIntakeLayer = Layer.effect(
JoinInterest,
Effect.gen(function* makeJoinIntake() {
const tickets = yield* IntakeTicket;
const scorer = yield* AbuseScore;
const events = yield* IntakeEvents;
const contacts = yield* JoinContactStore;
const intake = yield* SubscriberIntake;
const tokens = yield* InterestTokens;
const crypto = yield* Crypto.Crypto;
const submit = Effect.fn("JoinInterest.submit")(function* submit(
input: JoinInput
): Effect.fn.Return<JoinOutput> {
const statusRef = yield* newStatusRef;Effectâs Layer.provide supplies a Layerâs dependencies. HttpApiBuilder.layer registers HTTP routes and can expose OpenAPI14. Neither requires a second domain handler.¶
One capability, every surface18 states the house rule9. Hexagonal architecture27 names the adapter boundary. The fence45 enforces it.¶
The peers page records other Effect and Alchemy projects, whose designs can differ.¶
Start with Effect basics29, then construct a service26 and compose its Layers18.¶
See also: Structure an Effect codebase by domain17.¶
Sources
- packages/capability/src/contract.ts. GitHub. packages/capability/src/contract.ts Accessed 2026-10-02.
- packages/capability/src/implement.ts. GitHub. packages/capability/src/implement.ts Accessed 2026-10-02.
- packages/capability/src/to-http-api.ts. GitHub. packages/capability/src/to-http-api.ts Accessed 2026-10-02.
- apps/cli/src/surfaces.ts. GitHub. apps/cli/src/surfaces.ts Accessed 2026-10-02.
- apps/site/src/app.ts. GitHub. apps/site/src/app.ts Accessed 2026-10-02.
- packages/core/src/join-intake.ts. GitHub. packages/core/src/join-intake.ts Accessed 2026-10-02.
- Effect 4 Layer. GitHub. Effect 4 Layer Accessed 2026-10-02.
- Effect 4 HttpApiBuilder. GitHub. Effect 4 HttpApiBuilder Accessed 2026-10-02.
Last changed 2026-10-18 in e5c3077. Source on GitHub. Change log.
Linked from
- Agent guide. An Effect stack so pure (aspirational) Kit Langton will blush.
Effect keeps the surfaces on one contract â Schema owns values, projections build interfaces, and Layers supply implementations.
- Change log. What changed in the files served here, newest first.
Effect keeps the surfaces on one contract â edited: docs: refresh XState excerpts and peer evidence
- Full agent guide. An Effect stack so pure (aspirational) Kit Langton will blush.
- MCP is another surface. MCP lists and calls schema-typed tools; rat-stack projects the same handlers instead of adding MCP-only behavior.
See how we do it with Effect for the whole path.¶
- One program can replace several tool calls. Code mode combines typed content calls inside one bounded execute request.
See how we do it with Effect for the whole path.¶
- One schema, three surfaces. A capability contract feeds CLI, HTTP, and MCP; OpenAPI is generated output, not their input.
See how we do it with Effect for the whole path.¶
- OpenAPI describes the refusal too. The generated HTTP contract declares inputs, outputs, and the bodyless 400 returned when decoding fails.
See how we do it with Effect for the whole path.¶
- Rat Stack lore | rat-stack. Short, source-grounded notes on the ideas and decisions behind rat-stack.
Effect keeps the surfaces on one contract â Schema owns values, projections build interfaces, and Layers supply implementations.
- Source change history (log.md). The generated change log as Markdown.
Effect keeps the surfaces on one contract â edited: docs: refresh XState excerpts and peer evidence