Repository navigation
feat: adopt core 0.38's streamlined API - #130
Merged
Merged
Conversation
Core 0.38 reshaped its public surface around one Actor type and one name
per concept; the server follows so its wire matches the spec it
implements.
- Scope requests with Stack.asActor(), open with Stack.open(), and pass
ownerEntityId to the adapter.
- DELETE /records/:id takes ?purge=true; the change feed's resume token
is `cursor` (ready frame and record frames); the journal bound is
?afterSeq=; POST /attachments/gc reports deletedFileIds.
- POST /tokens takes { principalId?, subjectId? }, the same Actor names
the response and GET /tokens already report, instead of
{ entityId, onBehalfOf }.
- resumeBufferKey keys on every ChangeFilter field (baseId and both
createdBy halves, as sets). It still read the removed entityId and
knew nothing of baseId or createdBy, so two connections with different
filters could have shared one buffer and received each other's frames.
- Dispatch the renamed and new 0.32 conformance fixtures (purge, exact
typeId and baseId feed filters, attachment and referencesFileId
queries).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01XrHN9A5Uzz9FQN6gEeiuX8
A stale client's old names were silently dropped, widening its request: POST /tokens with `entityId` minted an owner token, `?hard=true` did a soft delete, and old filter names returned unfiltered results. Each now answers 400 naming the replacement. Also key an empty `createdBy` change filter the same as none. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018rAh3A4jeexocb6UcZRAwa
Replaces the list of renamed names with a general rule: every route the server parses itself refuses a query param or body key it doesn't define (400), boolean params take only true/false, and body values of the wrong type are refused rather than dropped. Routes whose input core's wire parsers read are left to those parsers. Keeps the empty-createdBy resume buffer normalization. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018rAh3A4jeexocb6UcZRAwa
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018rAh3A4jeexocb6UcZRAwa
This was referenced Sep 25, 2026
A missing required key stays 400; a key present with the wrong shape is 422, per docs/api.md. Also flattens the expiresAt parse in POST /tokens. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Xa2sc4PJtmLYiBT1QpTRyv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Updates the server to core 0.38, wire-types 0.37, adapter-local 0.37, and commons and conformance-fixtures 0.32. Core 0.38 reshaped its public API around a single
Actortype and gave each concept one name.Stack.asActor(), which replacesforSession()andonBehalfOf. The other renames areStack.open(),ownerEntityIdon the adapter,StackBadRequestError,.capabilities, the object forms ofdefineType()andputAttachment(), andTokenSessionimported from@haverstack/core/wire.DELETE /records/:id?purge=true, which replaces?hard=true.cursorin thereadyframe and on record frames.?afterSeq=.GET /recordsfilters arecreatedBySubject/createdByPrincipal/attachmentLabel/attachmentFileId/referencesFileId.createdBy/updatedByobjects.POST /attachments/gcreturnsdeletedFileIds.kindinstead ofscope.POST /tokenstakes{ principalId?, subjectId? }instead of{ entityId, onBehalfOf }. These are the sameActorfield names the response andGET /tokensalready use.principalIddefaults to the owner, andsubjectIddefaults to the principal.resumeBufferKey: it still read the removedChangeFilter.entityIdand didn't know aboutbaseIdorcreatedBy. As a result, two connections with different filters could have shared one resume buffer and received each other's frames. It now keys on every filter field and treats multi-value fields as sets. Tests are added.typeIdandbaseIdchange-feed filters, and the attachment andreferencesFileIdqueries. The query tests use real uploads so the filters are tested against records that should match and records that shouldn't.Docs
docs/api.mdis updated throughout: record filters, the tokens body, purge,cursor/afterSeq, the change-feed filters and ops (reshare,purge), the gc response, andkindon grantees and targets. The wire contract itself changed in haverstack/core (released as core 0.38 / wire-types 0.37 / conformance-fixtures 0.32).Verification
pnpm run format:check && pnpm run lint && pnpm typecheck && pnpm test && pnpm buildall pass: 29 test files, 582 tests.Notes for reviewers
feat:, notfeat!:, following the precedent of earlier breaking core upgrades (0.10.0). Merging releases 0.11.0. With!, the release workflow would produce 1.0.0.POST /tokensbreaks existing clients of that endpoint. This was chosen so the request body uses the same field names as the response and core'sActortype.🤖 Generated with Claude Code
https://claude.ai/code/session_01XrHN9A5Uzz9FQN6gEeiuX8
Generated by Claude Code