diff --git a/packages/opencode/specs/effect/http-api.md b/packages/opencode/specs/effect/http-api.md index d872ab42f337..cce3f4081f53 100644 --- a/packages/opencode/specs/effect/http-api.md +++ b/packages/opencode/specs/effect/http-api.md @@ -261,6 +261,50 @@ Each route-group spike should follow the same shape. - assert that the service behavior is unchanged - assert that the generated OpenAPI contains the migrated paths and schemas +## Boundary composition + +The first slices should keep the existing outer server composition and only replace the route contract and handler layer. + +### Auth + +- keep `AuthMiddleware` at the outer Hono app level +- do not duplicate auth checks inside each `HttpApi` group for the first parallel slices +- treat auth as an already-satisfied transport concern before the request reaches the `HttpApi` handler + +Practical rule: + +- if a route is currently protected by the shared server middleware stack, the experimental `HttpApi` route should stay mounted behind that same stack + +### Instance and workspace lookup + +- keep `WorkspaceRouterMiddleware` as the source of truth for resolving `directory`, `workspace`, and session-derived workspace context +- let that middleware provide `Instance.current` and `WorkspaceContext` before the request reaches the `HttpApi` handler +- keep the `HttpApi` handlers unaware of path-to-instance lookup details when the existing Hono middleware already handles them + +Practical rule: + +- `HttpApi` handlers should yield services from context and assume the correct instance has already been provided +- only move instance lookup into the `HttpApi` layer if we later decide to migrate the outer middleware boundary itself + +### Error mapping + +- keep domain and service errors typed in the service layer +- declare typed transport errors on the endpoint only when the route can actually return them intentionally +- prefer explicit endpoint-level error schemas over relying on the outer Hono `ErrorMiddleware` for expected route behavior + +Practical rule: + +- request decoding failures should remain transport-level `400`s +- storage or lookup failures that are part of the route contract should be declared as typed endpoint errors +- unexpected defects can still fall through to the outer error middleware while the slice is experimental + +For the current parallel slices, this means: + +- auth still composes outside `HttpApi` +- instance selection still composes outside `HttpApi` +- success payloads should be schema-defined from canonical Effect schemas +- known route errors should be modeled at the endpoint boundary incrementally instead of all at once + ## Exit criteria for the spike The first slice is successful if: @@ -283,13 +327,64 @@ The first parallel `question` spike gave us a concrete pattern to reuse. - the experimental slice should stay mounted in parallel and keep calling the existing service layer unchanged. - compare generated OpenAPI semantically at the route and schema level; in the current setup the exported OpenAPI paths do not include the outer Hono mount prefix. +## Route inventory + +Status legend: + +- `done` - parallel `HttpApi` slice exists +- `next` - good near-term candidate +- `later` - possible, but not first wave +- `defer` - not a good early `HttpApi` target + +Current instance route inventory: + +- `question` - `done` + endpoints in slice: `GET /question`, `POST /question/:requestID/reply` +- `permission` - `done` + endpoints in slice: `GET /permission`, `POST /permission/:requestID/reply` +- `provider` - `next` + best next endpoint: `GET /provider/auth` + later endpoint: `GET /provider` + defer first-wave OAuth mutations +- `config` - `next` + best next endpoint: `GET /config/providers` + later endpoint: `GET /config` + defer `PATCH /config` for now +- `project` - `later` + best small reads: `GET /project`, `GET /project/current` + defer git-init mutation first +- `workspace` - `later` + best small reads: `GET /experimental/workspace/adaptor`, `GET /experimental/workspace`, `GET /experimental/workspace/status` + defer create/remove mutations first +- `file` - `later` + good JSON-only candidate set, but larger than the current first-wave slices +- `mcp` - `later` + has JSON-only endpoints, but interactive OAuth/auth flows make it a worse early fit +- `session` - `defer` + large, stateful, mixes CRUD with prompt/shell/command/share/revert flows and a streaming route +- `event` - `defer` + SSE only +- `global` - `defer` + mixed bag with SSE and process-level side effects +- `pty` - `defer` + websocket-heavy route surface +- `tui` - `defer` + queue-style UI bridge, weak early `HttpApi` fit + +Recommended near-term sequence after the first spike: + +1. `provider` auth read endpoint +2. `config` providers read endpoint +3. `project` read endpoints +4. `workspace` read endpoints + ## Checklist - [x] add one small spike that defines an `HttpApi` group for a simple JSON route set - [x] use Effect Schema request / response types for that slice - [x] keep the underlying service calls identical to the current handlers - [x] compare generated OpenAPI against the current Hono/OpenAPI setup -- [ ] document how auth, instance lookup, and error mapping would compose in the new stack +- [x] document how auth, instance lookup, and error mapping would compose in the new stack - [ ] decide after the spike whether `HttpApi` should stay parallel, replace only some groups, or become the long-term default ## Rule of thumb