// ---------------------------------------------------------------------------// Fixed-executor ExecutionStackMiddleware — the single-scope, boot-built// execution variant of `./execution-stack-middleware.ts`.//// The per-request `ExecutionStackMiddleware` resolves a `Principal` and then// builds a FRESH per-(user, org) executor each request via `makeExecutionStack`// -> `makeScopedExecutor`, binding `{ tenant: organizationId, subject:// accountId }`. That is the cloud / self-host model: a per-request executor// derived from identity.//// Local is structurally different: ONE executor is built once at boot over a// SINGLE tenant derived from the working directory, with// `oauthEndpointUrlPolicy: { allowHttp: true }`, and shared across every request// (and the in-process MCP). There is no per-request (user, org) binding. Forcing// local through the scoped middleware would (a) swap its cwd tenant for a// synthetic identity-derived one — orphaning existing `~/.executor` data — and// (b) silently drop `allowHttp`.//// So a host whose execution is a single boot executor supplies a// `FixedExecutionProvider` (the pre-built executor + engine) and this middleware// resolves identity to `AuthContext` exactly like the scoped variant, then// provides the FIXED executor + engine + plugin extension Services to the// handler — no per-request rebuild. The identity seam still runs (so a host can// gate or attribute requests), but the executor is constant. This is local's// genuine model expressed as a first-class `make()` execution mode, not a// special case bolted onto the scoped path.// --------------------------------------------------------------------------- import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";import { Context, Effect } from "effect";import type * as Cause from "effect/Cause"; import type { AnyPlugin, Executor, PluginExtensions } from "@executor-js/sdk";import type { ExecutionEngine } from "@executor-js/execution"; import { ExecutionEngineService, ExecutorService } from "../services";import { providePluginExtensions, type PluginExtensionServices } from "../plugin-routes";import { authContextFromPrincipal, AuthContext, isPlatformPrincipal, ReadOnlyCredential, type Principal, type ResolvedPrincipal,} from "./identity";import type { FailureRenderingStrategy } from "./execution-stack-middleware"; /** * The pre-built, boot-scoped execution a fixed-executor host serves on. Local * builds this ONCE (single cwd scope + `allowHttp`) and shares it across every * request and the in-process MCP. `extensions` is the plugin extension map * (`executor[pluginId]`) the handlers' `*ExtensionService` Tags read. */export interface FixedExecution<TPlugins extends readonly AnyPlugin[] = readonly AnyPlugin[]> { readonly executor: Executor<TPlugins>; readonly engine: ExecutionEngine<Cause.YieldableError>; readonly extensions: PluginExtensions<TPlugins>;} export class FixedExecutionProvider extends Context.Service< FixedExecutionProvider, FixedExecution>()("@executor-js/api/FixedExecutionProvider") {} export interface MakeFixedExecutionMiddlewareOptions< TPlugins extends readonly AnyPlugin[], E, RLong, RStrategy,> { /** The host's plugin tuple — drives the typed extension Services and binding. */ readonly plugins: TPlugins; /** * Resolve the inbound web `Request` to a neutral `Principal`. The credential * shape stays inside this function; local's single-user provider always * resolves the one local Principal. (The seam's type admits a platform * credential, but a fixed-executor host has no platform view — one resolving * here is refused below.) */ readonly authenticate: (request: Request) => Effect.Effect<ResolvedPrincipal, E, RLong>; /** Render `authenticate` failures (text for local, matching self-host). */ readonly strategy: FailureRenderingStrategy<E | ReadOnlyCredential, RStrategy>;} /** * Build the fixed-executor `ExecutionStackMiddleware`. Per request: resolve the * `Principal` (and render any failure), build the `AuthContext`, then provide * the boot-built `FixedExecutionProvider`'s executor + engine + plugin extension * Services to the wrapped handler. `RCapture` is the boot-scoped context * captured once at layer-build time (the identity provider + the fixed execution * seam); the per-request body depends only on `HttpRouter`-provided context. * * Returned as the `HttpRouter.middleware` value (NOT `.layer`) so it composes * the same way the scoped variant does. */export const makeFixedExecutionMiddleware = < const TPlugins extends readonly AnyPlugin[], E, RLong = never, RStrategy = never, RCapture = RLong | RStrategy | FixedExecutionProvider,>( options: MakeFixedExecutionMiddlewareOptions<TPlugins, E, RLong, RStrategy>,) => { const provideExecutorExtensions = providePluginExtensions(options.plugins); return HttpRouter.middleware<{ provides: | AuthContext | ExecutorService | ExecutionEngineService | PluginExtensionServices<TPlugins>; }>()( Effect.gen(function* () { const captured = yield* Effect.context<RCapture>(); const { executor, engine, extensions } = yield* FixedExecutionProvider.asEffect(); return (httpEffect) => Effect.gen(function* () { const request = yield* HttpServerRequest.HttpServerRequest; const webRequest = yield* HttpServerRequest.toWeb(request); const resolved = yield* options.strategy.renderFailure( options.authenticate(webRequest).pipe( // The fixed executor binds ONE subject at boot; there is no // platform view to serve an org credential, so it is refused // rather than silently acting as the boot subject. Effect.filterOrFail( (principal): principal is Principal => !isPlatformPrincipal(principal), () => new ReadOnlyCredential({ code: "read_only_credential", message: "Organization API keys are not accepted on this host", }), ), ), ); // The strategy recovered the failure into a Response — return it. if (!isPrincipal(resolved)) return resolved; const auth = AuthContext.of(authContextFromPrincipal(resolved)); return yield* httpEffect.pipe( Effect.provideService(AuthContext, auth), Effect.provideService(ExecutorService, executor), Effect.provideService(ExecutionEngineService, engine), provideExecutorExtensions(extensions as PluginExtensions<TPlugins>), ); }).pipe(Effect.provideContext(captured as Context.Context<RCapture>)); }), );}; // `renderFailure` yields either the resolved `Principal` (proceed) or an// already-built `HttpServerResponse` (the strategy recovered the failure).const isPrincipal = ( value: Principal | HttpServerResponse.HttpServerResponse,): value is Principal => !HttpServerResponse.isHttpServerResponse(value);
// ---------------------------------------------------------------------------
// Fixed-executor ExecutionStackMiddleware — the single-scope, boot-built
// execution variant of `./execution-stack-middleware.ts`.
//
// The per-request `ExecutionStackMiddleware` resolves a `Principal` and then
// builds a FRESH per-(user, org) executor each request via `makeExecutionStack`
// -> `makeScopedExecutor`, binding `{ tenant: organizationId, subject:
// accountId }`. That is the cloud / self-host model: a per-request executor
// derived from identity.
//
// Local is structurally different: ONE executor is built once at boot over a
// SINGLE tenant derived from the working directory, with
// `oauthEndpointUrlPolicy: { allowHttp: true }`, and shared across every request
// (and the in-process MCP). There is no per-request (user, org) binding. Forcing
// local through the scoped middleware would (a) swap its cwd tenant for a
// synthetic identity-derived one — orphaning existing `~/.executor` data — and
// (b) silently drop `allowHttp`.
//
// So a host whose execution is a single boot executor supplies a
// `FixedExecutionProvider` (the pre-built executor + engine) and this middleware
// resolves identity to `AuthContext` exactly like the scoped variant, then
// provides the FIXED executor + engine + plugin extension Services to the
// handler — no per-request rebuild. The identity seam still runs (so a host can
// gate or attribute requests), but the executor is constant. This is local's
// genuine model expressed as a first-class `make()` execution mode, not a
// special case bolted onto the scoped path.
// ---------------------------------------------------------------------------
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
import { Context, Effect } from "effect";
import type * as Cause from "effect/Cause";
import type { AnyPlugin, Executor, PluginExtensions } from "@executor-js/sdk";
import type { ExecutionEngine } from "@executor-js/execution";
import { ExecutionEngineService, ExecutorService } from "../services";
import { providePluginExtensions, type PluginExtensionServices } from "../plugin-routes";
import {
authContextFromPrincipal,
AuthContext,
isPlatformPrincipal,
ReadOnlyCredential,
type Principal,
type ResolvedPrincipal,
} from "./identity";
import type { FailureRenderingStrategy } from "./execution-stack-middleware";
/**
* The pre-built, boot-scoped execution a fixed-executor host serves on. Local
* builds this ONCE (single cwd scope + `allowHttp`) and shares it across every
* request and the in-process MCP. `extensions` is the plugin extension map
* (`executor[pluginId]`) the handlers' `*ExtensionService` Tags read.
*/
export interface FixedExecution<TPlugins extends readonly AnyPlugin[] = readonly AnyPlugin[]> {
readonly executor: Executor<TPlugins>;
readonly engine: ExecutionEngine<Cause.YieldableError>;
readonly extensions: PluginExtensions<TPlugins>;
}
export class FixedExecutionProvider extends Context.Service<
FixedExecutionProvider,
FixedExecution
>()("@executor-js/api/FixedExecutionProvider") {}
export interface MakeFixedExecutionMiddlewareOptions<
TPlugins extends readonly AnyPlugin[],
E,
RLong,
RStrategy,
> {
/** The host's plugin tuple — drives the typed extension Services and binding. */
readonly plugins: TPlugins;
/**
* Resolve the inbound web `Request` to a neutral `Principal`. The credential
* shape stays inside this function; local's single-user provider always
* resolves the one local Principal. (The seam's type admits a platform
* credential, but a fixed-executor host has no platform view — one resolving
* here is refused below.)
*/
readonly authenticate: (request: Request) => Effect.Effect<ResolvedPrincipal, E, RLong>;
/** Render `authenticate` failures (text for local, matching self-host). */
readonly strategy: FailureRenderingStrategy<E | ReadOnlyCredential, RStrategy>;
}
/**
* Build the fixed-executor `ExecutionStackMiddleware`. Per request: resolve the
* `Principal` (and render any failure), build the `AuthContext`, then provide
* the boot-built `FixedExecutionProvider`'s executor + engine + plugin extension
* Services to the wrapped handler. `RCapture` is the boot-scoped context
* captured once at layer-build time (the identity provider + the fixed execution
* seam); the per-request body depends only on `HttpRouter`-provided context.
*
* Returned as the `HttpRouter.middleware` value (NOT `.layer`) so it composes
* the same way the scoped variant does.
*/
export const makeFixedExecutionMiddleware = <
const TPlugins extends readonly AnyPlugin[],
E,
RLong = never,
RStrategy = never,
RCapture = RLong | RStrategy | FixedExecutionProvider,
>(
options: MakeFixedExecutionMiddlewareOptions<TPlugins, E, RLong, RStrategy>,
) => {
const provideExecutorExtensions = providePluginExtensions(options.plugins);
return HttpRouter.middleware<{
provides:
| AuthContext
| ExecutorService
| ExecutionEngineService
| PluginExtensionServices<TPlugins>;
}>()(
Effect.gen(function* () {
const captured = yield* Effect.context<RCapture>();
const { executor, engine, extensions } = yield* FixedExecutionProvider.asEffect();
return (httpEffect) =>
Effect.gen(function* () {
const request = yield* HttpServerRequest.HttpServerRequest;
const webRequest = yield* HttpServerRequest.toWeb(request);
const resolved = yield* options.strategy.renderFailure(
options.authenticate(webRequest).pipe(
// The fixed executor binds ONE subject at boot; there is no
// platform view to serve an org credential, so it is refused
// rather than silently acting as the boot subject.
Effect.filterOrFail(
(principal): principal is Principal => !isPlatformPrincipal(principal),
() =>
new ReadOnlyCredential({
code: "read_only_credential",
message: "Organization API keys are not accepted on this host",
}),
),
),
);
// The strategy recovered the failure into a Response — return it.
if (!isPrincipal(resolved)) return resolved;
const auth = AuthContext.of(authContextFromPrincipal(resolved));
return yield* httpEffect.pipe(
Effect.provideService(AuthContext, auth),
Effect.provideService(ExecutorService, executor),
Effect.provideService(ExecutionEngineService, engine),
provideExecutorExtensions(extensions as PluginExtensions<TPlugins>),
);
}).pipe(Effect.provideContext(captured as Context.Context<RCapture>));
}),
);
};
// `renderFailure` yields either the resolved `Principal` (proceed) or an
// already-built `HttpServerResponse` (the strategy recovered the failure).
const isPrincipal = (
value: Principal | HttpServerResponse.HttpServerResponse,
): value is Principal => !HttpServerResponse.isHttpServerResponse(value);