3ngram 1.2.7
3ngram v1.2.7
Patch release: an OAuth correctness fix that stops handing clients a credential
the authorization server would never honour, and a correction to the remember
tool description that had been telling agents the opposite of what the read
surface actually does.
Changes
-
Refresh tokens are no longer issued to clients that never advertised the
refresh_tokengrant (issue #86). The authorization-code exchange minted a
refresh token unconditionally, but the token route gates the refresh grant on
the client's advertisedgrant_types. A client registered for
authorization_codealone — which is also the schema default when a CIMD
document omitsgrant_typesentirely — therefore received a refresh token
that the very next request rejected asinvalid_client. Nothing in the token
response signalled that, so the client had no way to know the credential was
inert until it tried to use it and lost its session.Issuance now matches what the authorization server will actually honour: the
refresh token is omitted from the response and its hash is not persisted,
since a hash for a token no client was ever handed can never be presented or
rotated.refresh_tokenon the token response is now optional, which is what
RFC 6749 §5.1 always specified.Rotation additionally fails closed if a client's advertised grants are
narrowed between issuance and rotation, rather than revoking the predecessor
and minting no successor.This predates the CIMD grant-type narrowing in #85 —
grant_types: ['authorization_code']has always been accepted. -
The
remembertool description no longer contradicts the read surface
(issue #71). It asserted flatly that "a memory written with a NULL project
never matches a project filter", which stopped being true once the
scope_projectselector gainedincludeUnscoped: true.briefingand
handoffwere updated at the time;rememberwas missed, so the write
surface was describing the opposite of what the read surface does.The description now distinguishes the two cases precisely: the bare
project
selector is still never widened, and onlyscope_projectwith
includeUnscoped: trueopts NULL-project memories back in. It also drops a
dangling(issue #244)citation, which referenced an internal tracker item
that means nothing to a reader of the public tool surface.Tool descriptions are standing context on every MCP connection, so the
regenerated surfaces (docs/reference/tools.mdx,
eval/fixtures/transport-surfaces.json) and the recorded transport-cost
floors move with it: +13 surface tokens, +104 per-task uncached, +26 per-task
cache-effective. -
Threads design doc published at
docs/concepts/threads.mdx. Design
documentation only — no runtime change and no package version moves with it.
Upgrading
No configuration or migration changes.
One behavioural note for OAuth integrators: a client whose registration
advertises only authorization_code will now receive a token response with no
refresh_token field. That credential was already non-functional — presenting
it returned invalid_client — so nothing that previously worked stops working.
Clients that parse the token response should treat refresh_token as optional,
per RFC 6749 §5.1. To keep receiving refresh tokens, advertise the
refresh_token grant in the client's grant_types.
Library versions
@3ngram/core 0.8.5, @3ngram/db 0.7.4, @3ngram/schema 0.6.3,
@3ngram/config 0.2.5, @3ngram/llm 0.2.4.
Immutable container reference
ghcr.io/b3dmar/3ngram@sha256:bf4ce8d4a5ae4605b91e8c9c383f1690522be70488e8f9682bf8ee4bc88036ea