Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 96 additions & 1 deletion packages/opencode/specs/effect/http-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
Loading