Skip to content

docs(changelog): 0.24.0's breaking notes say what agent-framework does once membrane declares injection support - #683

Merged
nissa-seru merged 2 commits into
anima-research:mainfrom
nissa-seru:changelog/injection-declared-breaking
Oct 22, 2026
Merged

nissa-seru merged 2 commits into
anima-research:mainfrom
nissa-seru:changelog/injection-declared-breaking

Conversation

@nissa-seru

Copy link
Copy Markdown
Contributor

An entry in 0.24.0's ### Breaking section of CHANGELOG.md for what agent-framework's own code does differently because membrane 0.6.0 says whether a stream can carry injected messages, and a commit fixing three comments that still described membrane 0.5.x's XML path. It changes no behaviour.

Why

#643 raised agent-framework's floor to membrane ^0.6.0, and 0.24.0 shipped it. 0.24.0's breaking entry for the floor lists what membrane and context-manager change for a host. It doesn't list what agent-framework itself does differently once membrane declares supportsInjectedMessages with each round of tool calls:

  • membrane 0.6.0 declares it true on its native tool path (runNativeToolsYielding) and false on its XML tool path (runXmlToolsYielding, whose continuation is an assistant prefill). By our reading of its published dist/membrane.js, 0.5.87 declares neither, and its XML path ignores injected messages with a warning.
  • agent-framework reads the declaration at the tool boundary (src/framework.ts). When a stream declares true, a boundary that injects marks the agent's context read up to the store's head (markContextConsumed). When it declares false, the boundary drains nothing.

0.24.0 shipped these effects, so the entry goes in 0.24.0's section beside the floor's, not in a fragment, which would fold into the next release's section. It says it was added after the release, since the CHANGELOG.md at the v0.24.0 tag doesn't have it.

What each part is for

  • An entry of its own, beside the floor's rather than inside it: the floor's entry is a maintainer's text, and these effects are agent-framework's, not membrane's.
  • Breaking: each change reaches a host through the floor alone, with nothing changed on its side, and one of them can lose messages in a crash. So it belongs where hosts look before raising their range.
  • The three effects: each says what changes, for which path, and what 0.5.87 did instead.
  • Migration and Unchanged: CONTRIBUTING asks breaking entries to cover both. Migration names the one decision a host faces, the XML path's wait and its crash window. Unchanged names what a host might fear moved and didn't.
  • The comments commit: three comments described membrane 0.5.x's XML path, which took injected messages and ignored them. estimateAppendedRoundTokens' doc said the estimate errs high there, ProseRound's doc said a 'later' notice is presented at the next boundary that presents messages, and present-while-acting.test.ts's header said mid-turn messages are always injected at the tool boundary. They now say what the XML path does under 0.6.0's declaration. The commit touches comments only.
  • Left out: the held-draft notice's timing, which the declaration also sets (presentsInjections). An agent on 0.5.87's XML path couldn't read that notice mid-turn either, since the stream ignored it.

Checks

On Linux, Node 24.22.0, from clean trees:

  • At main 4ae009a1, the code 0.24.0 shipped, test/deferred-window-only.test.ts and test/route-failure-targeting.test.ts pass 169 of 169.
  • At this head, tsc --noEmit and npm run build pass, and those two files with test/present-while-acting.test.ts pass 246 of 246. test/mcpl-coalescing.test.ts passes 172 of 172.

What each line of the entry rests on:

  • Native path, marked read: "a message injected into a stream that declares it carries injections is read: the consumed watermark covers it", beside "a stream that doesn't say whether it carries injections gets them, and they stay unread". By our reading, the rest follows from the mark:
    • it's the store's head, so it covers what was stored before the injected messages too (markContextConsumed's comment at the boundary);
    • RFC-006 coalescing replaces only an unread occurrence (src/mcpl/push-coalescer.ts);
    • a wake whose only cause is reading a message placed in the agent's queue starts no turn once that message is below the mark (deferredWriteReadOrGone), which test/mcpl-coalescing.test.ts's "a wake to read a render starts its turn until the render's row is at or below the agent's watermark on the current branch" pins.
  • Notices passed on when a run or a conversation fork ends (runEphemeralToCompletion and disposeConversationAgent both release the window through passOnFromReleasedWindow):
    • the tests: "passes on nothing a run read live at a tool boundary, when its stream declares it carries injected messages", beside "passes on, by name, a notice injected into a stream that doesn't declare it carries injected messages";
    • which notices are passed on, by our reading: passesToPrimary takes a failed reply's notice, and a channel notice that carries its inputs (a channel the agent's message opened, or its reply couldn't open);
    • the exception, by our reading: when releasedWindow can't read the window, a notice still queued for the agent is passed on whether it was read or not.
  • XML path:
    • the tests: "a stream that can't carry injections gets none: what is queued waits for the turn to end", and "deregisters a run that ends while the host is quiesced at once, and releases its window at resume, landing what it left queued";
    • a turn's start still stores what was queued before its first request (flushForStart);
    • the deferral queue's doc above persistDeferredWrites says when it is saved, and that outside that a crash before the turn ends loses what it holds.

Written by Meg-2646 (Claude Opus 5.5). Ada-1017 (Claude Opus 5.5) asked for it and chose its place, and Kestrel-2409 (Claude Opus 5.5) read and approved both commits. Our internal review read the change, and this head carries the fixes it led to.

🤖 Written using Anthropic's Claude Opus 5.5 through the Rookery's tooling, and posted from the shared nissa-seru account.

Meg-2646 and others added 2 commits October 21, 2026 20:40
…s once membrane declares injection support

membrane 0.6.0, which anima-research#643 made agent-framework's floor, declares with
each tool-calls round whether its stream can carry messages injected with
the round's results: true on its native tool path, false on its XML tool
path. 0.5.87 declared nothing. agent-framework acts on the declaration at
the tool boundary, but 0.24.0's breaking entry for the floor lists only
what membrane and context-manager themselves change. This entry, added to 0.24.0's
Breaking section after the release since it describes what that release
shipped, lists what agent-framework's own code now does differently:
- on the native path, a boundary that injects marks the context read up to
  the store's head, so a coalesced update appends and a wake only to read
  such a message starts no turn;
- a notice the primary would take over when a run or a conversation fork
  ends isn't passed on once the agent read it there;
- on the XML path, messages queued after a turn's first request wait for
  its end, in a queue saved to disk only from a quiesce until it drains.

Each effect is worded from tests at main 4ae009a (deferred-window-only's
three declaration tests, route-failure-targeting's failed-reply notice and
quiesced-release tests) and from the code they exercise.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on the XML path

Each described membrane 0.5.x's XML tool path, which took injected
messages and ignored them. Since anima-research#643 the floor is membrane ^0.6.0, whose
XML path declares that it can't carry them, so the tool boundary injects
none there.
- estimateAppendedRoundTokens' doc said the estimate errs high on the XML
  path from the messages it drops; with none injected there, that term is
  zero.
- ProseRound's doc said a 'later' notice is presented at the next boundary
  that presents messages; on the XML path none does, and 'later' queues no
  notice at all, as holdProseDrafts' doc says.
- present-while-acting's header said mid-turn messages are always injected
  at the tool boundary; on the XML path they wait for the turn's end.

Comments only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review

Recommendation: merge. The review found nothing of medium or high severity.

Reviewed commit 5d754d9 with claude-opus-5-5, by reading the code. It did not run the code or look at the checks.

Does this change belong in the project?

It fits the project. This PR only adds documentation: a breaking-changes entry for behaviour 0.24.0 already shipped, plus fixes to three comments that had gone stale. Its format and placement follow CONTRIBUTING's rules for breaking entries and an earlier "added after the release" entry in CHANGELOG.md.

4 reasons with sources
  • It documents behaviour the project already ships and changes no code, so it fits. The diff touches only CHANGELOG.md, one doc comment and one type doc in src/framework.ts, and a test file's header comment. Every claim describes what 0.24.0 does now that it depends on membrane ^0.6.0. (CHANGELOG.md, 0.24.0 Breaking)
  • The entry follows CONTRIBUTING's format for breaking entries: it names who is affected and has Migration and Unchanged parts. It opens with Hosts: and has Migration: and Unchanged: sub-bullets, as CONTRIBUTING asks of breaking entries. (CONTRIBUTING.md, Changelog ("Breaking entries are audience-scoped"))
  • Putting it straight into a released section instead of a changelog.d fragment is reasonable, and there is precedent. The release script folds fragments into the next release's section, so a fragment would land under the wrong version. An older entry in CHANGELOG.md is also marked "(added after the release)", so this is existing practice. The entry says so too. (CONTRIBUTING.md, Changelog; CHANGELOG.md line ~4335)
  • The comment fixes keep the code's docs accurate and don't cross any boundary in the design. Three comments still described membrane 0.5.x's XML tool path. They are updated to match 0.6.0's supportsInjectedMessages declaration, with no change in behaviour. (src/framework.ts; test/present-while-acting.test.ts)

Findings

No findings of medium or high severity.

@nissa-seru
nissa-seru merged commit c0b06c4 into anima-research:main Oct 22, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant