Skip to content

3ngram 1.2.7

Choose a tag to compare

@github-actions github-actions released this 06 Aug 08:56
81418e3

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_token grant
    (issue #86). The authorization-code exchange minted a
    refresh token unconditionally, but the token route gates the refresh grant on
    the client's advertised grant_types. A client registered for
    authorization_code alone — which is also the schema default when a CIMD
    document omits grant_types entirely — therefore received a refresh token
    that the very next request rejected as invalid_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_token on 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 remember tool 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_project selector gained includeUnscoped: true. briefing and
    handoff were updated at the time; remember was 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 only scope_project with
    includeUnscoped: true opts 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