Skip to content

fix(framework)!: a stop ends its AgentFramework instance, and start() and addModule() are refused from then on (#315) - #881

Merged
nissa-seru merged 4 commits into
anima-research:mainfrom
nissa-seru:gideon2613/stop-ends-its-instance
Oct 29, 2026
Merged

nissa-seru merged 4 commits into
anima-research:mainfrom
nissa-seru:gideon2613/stop-ends-its-instance

Conversation

@nissa-seru

@nissa-seru nissa-seru commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

After this change, start() throws and addModule() rejects once a stop() is admitted, for good, whether that stop completes or fails, so a stop ends its AgentFramework instance.

Before, a start() after a settled stop() could begin a second lifecycle on the same instance, and that lifecycle didn't work (#315). @rergards supported ending the instance instead, as an explicit breaking change (comment on #315), and this is that change, with a breaking changelog entry. A host that wants to go on after a stop creates a new AgentFramework on the store. After a failed stop, it first calls stop() again, until a call resolves, unless that stop left its owned store closed, so that stop() can't be tried again. The refusal's text says which applies. The second commit, a02f169c69, removes EventGate.resumeSleep(), whose documented purpose was that restart, as a second breaking change. On Linux with Node 24.22.1, the 15 test files this change touches pass at its head, c3cb848994. At a02f169c69, before main at 0.30.0 was merged in, 9 of their tests failed on the source of e85c57db9a, the base then.

Problem

At e85c57db9a, start() and addModule() are refused while a stop() runs (#532). They're also refused after a stop that closed a store the framework owns, or that closed its context managers and then failed to close that store. In every other case, once a stop() has settled, start() begins a new lifecycle on the same instance. 0.22.0's changelog says so ("A start() after a finished stop() starts a new lifecycle"), and 0.24.0's leaves what it should do as #315's open question.

Our runs at that commit show that this lifecycle doesn't work. After a completed stop() on a store the framework doesn't own, and a start():

  • The event queue stays closed. pushEvent() of an external message or a module's event throws Queue is closed.
  • The maintenance tick, an operator operation, is refused. It throws maintain refused: the framework is stopping.
  • The push coalescer, the liveness watchdog and the MCPL servers stay stopped.
  • Events the queue held when the stop closed it are processed in the new lifecycle, by a new module of the same name.

Turns woken outside the queue did reach the model, in our runs or the base's tests: a sleep's wake, a heartbeat's, a budget restart left pending and a nudge. The nudge's turn then failed at its model's call of a module's tool, with Queue is closed. After a failed stop(), start() is allowed too, and its lifecycle has the same closed queue.

!Closes #315.

Changes

Line numbers are in src/framework.ts at a02f169c69 unless another file is named.

  • The refusal. start() (:4763) and addModule() (:6913) each first call refuseOnceStopped (:4877), which reads the instance's stop state (stopState, :3287). A stop() sets that state when it's admitted, and nothing sets it back to 'none'. A stop() whose budget argument is refused rejects with a RangeError (:4853) and isn't admitted, so it changes nothing. The refusal's text depends on that stop:

    • while it runs: start() refused: the framework is stopping, as before;
    • after it completed: start() refused: this framework has stopped, and a stopped framework doesn't start again. Create a new AgentFramework on its store to go on, with its storePath if it opened the store itself.;
    • after it failed: that a failed stop() may have left its cleanup or final persistence unfinished, and to call stop() again, since only once a stop() of this instance resolves should a new AgentFramework use its store, with its storePath if this one opened the store itself, or another instance use anything this one shares;
    • after it failed and left its owned store closed: that stop() can't be tried again, with that stop's failure as the error's cause.

    addModule()'s texts are the same, with its own name. They replace Cannot start a new lifecycle: owned store is closed and Cannot start a new lifecycle: stop() closed its context managers, and then failed to close its owned store.

  • addModule() refuses before it checks the module's name against MCPL servers' tool prefixes (:6914), so a stopped framework's addModule() says it has stopped even for a name a server's prefix holds.

  • stop() keeps its cleanup and its retry. Its doc (:4801) now says it ends the instance.

  • Removed, since each existed only for a later lifecycle on the same instance:

    • the clearing of a completed stop in resetCompletedStop(), which refuseOnceStopped replaces, so a completed stop() keeps its settled promise;
    • the ownedStoreManagersClosed flag and closeOpenManagers()'s return value, which only fed one of the two refusals refuseOnceStopped replaces. That case is now refused as after any failed stop();
    • start()'s reopening of provider admission;
    • the lifecycle generation, which the event loop and a turn's checks compared, and with it the texts of turns dropped because "the framework was stopped and started again". One behaviour changes with it. A turn that runUntilIdle() began before the first start(), and that's still being assembled when that start() comes, now goes on, where before it was dropped;
    • start()'s call to EventGate.resumeSleep().
  • The withheld-spill gate was closed for the lifecycle generation a stop ended. It's now a flag (guardSpillsClosed, :7779) that stop() clears as it begins (:5028) and sets at its drain (:5296), so a stop() tried again after a failed one reopens it until its own drain.

  • Kept: start()'s loop that puts its MCPL servers' addresses in force (:4773), since it makes this framework's entries the ones in force where another framework has configured the same server id since.

  • start()'s doc (:4742) says what a new instance on the store keeps: what the store holds, and, with the heartbeat on and the same heartbeat state file, the heartbeat's schedule, so a tick or a reminder that fell due meanwhile fires once, shortly after it starts. It says what's lost with the old instance, as on a process restart: an agent's sleep and its wake, a self-wake, the inference requests still queued, a re-armed turn's wait and count, and the redo stack. It names A wake_in_seconds self-wake and a sleep don't survive a restart #627, which is about keeping a sleep and a self-wake across a restart, and quiesce() and resume() for pausing one framework in place.

  • Docs and comments. docs/tool-result-guard.md's paragraph on stop now says that a stopped framework doesn't start again. The comments that described a restart of the same instance no longer do.

  • The changelog entry, changelog.d/315-stop-ends-its-instance.breaking.md, names who needs to act and how to migrate, what a new instance keeps and loses, and what's unchanged.

EventGate.resumeSleep() removed, in a02f169c69

resumeSleep()'s doc gave its purpose as arming a disposed gate's timers again "for a lifecycle that starts after a stop()". At e85c57db9a the framework's start() called it, and with this change nothing in src does. It's a public method of an exported class, so removing it is a breaking change of its own, with its own changelog line. The reset of the gate's disposed mark, which only it made, goes with it, so nothing arms a disposed gate's sleep or self-wake timer again. Its tests go too. We found no call of it on the main branches of connectome-host (0db863c), connectome-smoke (14b7c55) and antra-tess/chapterx, fetched on Oct 28.

Since a02f169c69

Who needs to act

  • A host that calls start() or addModule() after stop() creates a new AgentFramework on the store instead, with the same borrowed store or the same storePath. After a failed stop(), it calls stop() again first, until a call resolves. Where the failed stop left its owned store closed, stop() can't be tried again, and the refusal carries that stop's failure as its cause.
  • Code that calls EventGate.resumeSleep() creates a new AgentFramework, whose gate is its own.

With other open pull requests

By git merge-tree on Oct 29, this head contains main at 0.30.0 (630e2a3a07). Of the open pull requests that merge clean onto 630e2a3a07, one conflicts with this head: #844, which has its own section below. Of those that already conflict with 630e2a3a07, this head adds conflicting regions to four:

With #844

@tel-0s, by git merge-tree on Oct 29, #844 (219a23706e), a draft, conflicts with this head in four files:

Tests

  • test/stop-ends-its-instance.test.ts, new, with eight tests:

    • after a completed stop(), start() and addModule() are refused, and stop() stays settled without tearing down again;
    • a stop() of a framework never started ends it too, with an owned store and with a borrowed one;
    • after a failed stop(), both are refused through each retry, until one resolves, and then for good;
    • after a stop() whose wait on the event loop timed out, start() is refused, and the retry waits for that loop before it resolves;
    • after a failed stop() that closed its owned store, the refusal carries that stop's failure, which stop() rejects with again;
    • a stop() whose budget is refused leaves the lifecycle as it was, so a running framework still adds modules, and one never started starts;
    • a new AgentFramework on a stopped one's borrowed store takes an event and runs a tool call;
    • a turn that runUntilIdle() began before the first start(), held in a module's gatherContext() until after that start(), reaches the model.

    The first four also check addModule() with a module whose name a server's tool prefix holds.

  • test/start-during-stop.test.ts: a call made in stop()'s first synchronous steps is refused for addModule() as well as start().

  • test/tool-result-guard.test.ts: a stop() tried again lets withheld spills write until its own drain. test/tool-result-blocks.test.ts: start() puts its servers' addresses in force over another framework's for the same id.

  • The restart's working cases, as tests at the base pinned them:

    • A sleep across a stop. In test/event-gate-sleep.test.ts, "a framework stopped while its agent sleeps wakes nothing until it's started again, then wakes the agent" now checks only that it wakes nothing once stopped, and "a sleep that ended while stopped wakes the agent in one turn with a request already pending at start" is removed.
    • A budget restart. In test/stop-with-work-in-flight.test.ts, "a budget restart taken up after a stop() and a start() marks its agent inferring again" is removed.
  • test/shutdown-errors.test.ts's "borrowed-store lifecycle changes invalidate a successful stop memo" (ea7e0435) is removed. After a completed stop(), it added a module, stopped the framework, started it and stopped it again. The new file's first test checks that a completed stop() stays settled.

  • The other tests that started a stopped instance again now check their property within one stop, or on a new AgentFramework on the stopped one's store. Those that tested what a restart itself did, by running one or by advancing the lifecycle generation as one did, are removed, in test/start-during-stop.test.ts, test/stop-without-stream.test.ts, test/present-while-acting.test.ts, test/tool-result-guard.test.ts and test/turn-continuation.test.ts.

  • a02f169c69 removes resumeSleep()'s three tests in test/event-gate-sleep.test.ts, and the halves of two others that armed a timer after it.

On Linux with Node 24.22.1, npm 11.19.1 and TypeScript 7.0.2, each tree installed with npm install, which resolved chronicle 0.4.0, context-manager 0.23.1, mcpl-core 0.4.0, membrane 0.8.0, @modelcontextprotocol/client and @modelcontextprotocol/server 2.4.0, discord.js 14.27.0, ws 8.22.0 and chokidar 4.0.3:

  • At a02f169c69, in a copy of a clean checkout, the build exits 0, and the 15 test files this change touches pass 840 of 840.
  • Red first: with e85c57db9a's src and a02f169c69's test files, the build exits 0, and 9 of the 840 tests fail. They're the new file's five tests of the refusal and its test of the turn runUntilIdle() began, and one test each in test/reinit-after-branch-move.test.ts, test/compression-after-release.test.ts and test/shutdown-errors.test.ts whose expectations this change updates.

On Linux with Node 24.22.1, npm 11.19.1 and TypeScript 7.0.2, after main at 0.30.0 was merged in, npm install resolved chronicle 0.5.0, context-manager 0.24.0, mcpl-core 0.4.0, membrane 0.8.0, @modelcontextprotocol/client and @modelcontextprotocol/server 2.4.0, discord.js 14.27.0, ws 8.22.0 and chokidar 4.0.3. With those:

  • At c3cb848994, in a copy of a clean checkout, the build exits 0, and the 15 test files this change touches pass 846 of 846. main added 6 of those tests.
  • At e20be12455, in a copy of a clean checkout, the build exits 0, and those 15 files pass 846 of 846. So do 16 more test files, 475 of 475: those that main added or changed since e85c57db9a and in which a call of .stop() comes before a call of .start(), found by a text match.
  • Red first for c3cb848994: with e20be12455's src and c3cb848994's test/stop-ends-its-instance.test.ts, the build exits 0, and 2 of that file's 8 tests fail, the two that expect the failed stop's refusal.

What a new instance keeps, in runs of probes outside this pull request, each in a copy of a clean checkout, at a02f169c69 and again at c3cb848994, with the same outcomes:

  • The heartbeat's schedule. A framework with the heartbeat on was started and stopped, and the next tick in its saved state was moved into the past. A new framework on the same store and heartbeat state file, configured with another heartbeat message, ticked about 10 s after it started, and the state still held the first framework's message.
  • Not a sleep. An agent was put to sleep for 1 s, its framework was stopped, and 1.5 s passed. A new framework on the same store held no sleep for it before it started, and in the 3 s after its start it made no model call and traced no sleep:expired. With a nudge for the agent before the new framework's start, it made one model call, the nudge's.

Not verified

  • The whole suite at the head. We ran the 15 test files this change touches, and at e20be12455 the 16 more above.
  • What a new instance loses, beyond a sleep. For the rest of start()'s list we ran nothing, and have only what lines of the code at a02f169c69 say: src/gate/event-gate.ts:2135 declares selfWakeDue as a field of the event gate, src/framework.ts:3316 and src/framework.ts:3713 declare pendingRequests and redoStacks as fields of the framework, and src/types/framework.ts:259 says a re-armed turn's wait and count "are kept in memory".
  • Node 22 and macOS. Every run was on Linux with Node 24.22.1.

What this leaves

  • stop() resolves while an addModule()'s start() is pending, and module:added follows it #882: an addModule() made before a stop() can still be running its module's start() when that stop() runs. stop() doesn't wait for that start(). It stops the module, removes it from the registry and resolves, and once the start() finishes, the framework emits module:added for it and addModule() resolves. Our internal review of this pull request found it, and this pull request doesn't change it.

  • Changelog fragment added: changelog.d/315-stop-ends-its-instance.breaking.md.

Gideon-2613 made the change and ran its probes. Cordelia-2434 proposed ending the instance, and Ada-1017 made the design calls. Ezra-2423 weighed what each part is worth, and read the fixes that followed until the last test was added. Stanley-2495 read that test, and Humphrey-2407 the comment fix after it. Stanley-2495 also read the merge of main at 0.30.0, and Ezra-2423 the clause on storePath. Oscar-1808 set its scope. Laurel-2386 wrote this description.

Gideon-2613 added 2 commits October 28, 2026 18:39
…use once a stop() is admitted (anima-research#315)

A start() after a settled stop() began a lifecycle that didn't work: the
event queue stayed closed, so pushEvent() threw and a tool call's result
couldn't be delivered; operator operations and MCPL connects were refused
as "the framework is stopping"; the push coalescer, the watchdog and the
MCPL servers stayed stopped; and events the queue held at the stop ran in
it. The same held after a failed stop(), on the same closed queue.

Now a stop ends its instance. From the moment a valid stop() is admitted,
start() throws and addModule() rejects, for good. While that stop runs the
text stays "<verb> refused: the framework is stopping". Once it has
settled, one family of texts says what to do: after a completed stop,
create a new AgentFramework on its store (its storePath, if it opened the
store itself); after a failed one, call stop()
again, since only a stop() that resolves has finished its cleanup and
final persistence; after a failed one that left its owned store closed,
so that stop() can't be tried again, the error carries that failure as
its cause. They replace "owned store is closed" and "closed its context
managers, and then failed to close its owned store". addModule() refuses
before its prefix checks, so a stopped framework's addModule() always
says it has stopped. stop() keeps its cleanup and retry semantics; a stop() whose
budget is refused is not admitted and changes nothing.

What existed only for a later lifecycle on the same instance goes, each
confirmed by reading:
- resetCompletedStop()'s clearing of a completed stop: a completed stop()
  keeps its settled promise, so stop() stays idempotent for good.
- ownedStoreManagersClosed, and closeOpenManagers()'s boolean: read only
  by the refusal it fed. That case is now a failed stop() that can be
  retried: its store is open and its attempt cleared.
- providerAdmissionClosed = false in start(): the field starts false and
  only stop() sets it, so it is false at every start() that now runs.
- The lifecycle generation: with start() refused after a stop, it changed
  only in stop(), after running is cleared and in the same synchronous
  run that closes provider admission, with only the retry-wait wakers
  between, whose frames resume in later microtasks. So the event loop's
  check added nothing to running, and each turn check's generation half
  held only when its admission half did. The one difference: a turn that
  began before the first start(), through runUntilIdle(), was dropped by
  that start() as "stopped and started again", and now goes on. The
  "stopped and started again" drop texts go with it.
- The withheld-spill gate, closed for the generation a stop ended, is now
  a flag set at a stop's drain and cleared where each stop() began a new
  generation, so a retried stop() reopens it from its start until its own
  drain, as it did.
- start() no longer calls the event gate's resumeSleep(): at a first
  start it only re-armed a timer already armed, since only dispose(),
  which only stop() calls, stops a sleep's timer, and setSleep() arms it
  when it is set. A sleep already due whose timer hasn't yet run is now
  woken by that timer, a moment later, rather than by start().

Kept: the server-address loop in start() (it makes this framework's
entries the ones in force where another framework configured the same id
since, which a test now pins), heartbeat.start(), openLogical.clear() at stop (a stream a failed
stop left running settles against it), the fork unbind at stop (a host
reading the router sees it), and the event gate's disposed mark. Text
that described a restart of the same instance now says what is true.

Tests: stop-ends-its-instance covers the refusals after a completed, a
failed, a timed-out, a retried and an unretriable stop (addModule()'s
with a name a server's prefix holds too), an invalid budget, a new
instance on the stopped one's store running a tool call, and a turn
runUntilIdle() began before the first start() reaching the model when
start() comes. A retried stop's spills and start()'s address precedence
each get a test, and the in-flight refusal from stop()'s first steps
covers addModule(). The starts after a stop elsewhere in the suite each
keep their property within one stop where they have one, move to a new
instance where it holds there, or go where it arose only on reuse.
…e restart a stop no longer allows (anima-research#315)

resumeSleep()'s documented purpose was to arm a disposed gate's timers
again for a lifecycle that starts after a stop(): the framework's
start() called it. A stop now ends its instance, start() no longer calls
it, and at a first start it only re-armed a deadline already armed, or
woke a sleep already due a moment before its timer would. No host we
know of calls it. It's a public method of an exported class, so this is
a breaking removal of its own, in a commit that can be dropped to keep
the method.

With it go the reset of the gate's disposed mark, which only it made, so a
disposed gate arms no sleep or self-wake timer for good, and its tests:
the two that drove a wake through it, the one for a sleep already over
when it ran, and the halves of two others that armed a timer after it.
wakeFromSleep() is now called only by the timer that fired.
Gideon-2613 added 2 commits October 28, 2026 22:01
Catches anima-research#315's change up with 0.30.0. The one conflict is in start(),
where main added `this.earlyTraces = null;` (traces from before start()
are replayed to late listeners and dropped at start()) inside the lines
this change removes (the provider-admission reopening, the lifecycle
generation bump and their comments). The resolution keeps main's line
and drops the rest, as the change does on its own.
Once a retried stop() resolves, a store the framework opened itself is as
closed as after a completed stop. The failed stop's refusal said only that
a new AgentFramework may then use its store, so a host following it
straight to a new instance could hand that instance the closed store
object. It now says, as the completed stop's refusal does, to use the
storePath when this framework opened the store itself.
@nissa-seru
nissa-seru merged commit a56df80 into anima-research:main Oct 29, 2026
12 checks passed
nissa-seru pushed a commit to nissa-seru/agent-framework that referenced this pull request Oct 29, 2026
main 0f11975 brings anima-research#864, anima-research#876, anima-research#881 and the other merges since
62a126c. One file conflicted, test/workspace-three-way.test.ts:
- its observe.js import takes both sides: this branch's RACY_WINDOW_MS
  and anima-research#864's ROOT_ON_ANOTHER_DEVICE, ROOT_REPLACED,
  filesystemKeepsBirthTime and fsTypeKeepsBirthTime;
- anima-research#864's new test, "a filesystem keeps a birth time fixed only where it
  is listed, and only on Linux", goes in before "no restored timestamp
  hides a change", without the comment above that test, which this
  branch removed.
nissa-seru pushed a commit to rufalupa666-netizen/agent-framework that referenced this pull request Oct 29, 2026
main took ten pull requests after 0.30.0 (anima-research#866, anima-research#864, anima-research#873, anima-research#874, anima-research#877,
anima-research#872, anima-research#881, anima-research#875, anima-research#378, anima-research#876). Two places conflicted, and both keep both
sides:
- src/gate/event-gate.ts: this branch's sleepTurnId field, with main's
  rewritten note on dispose(), since anima-research#881 removed resumeSleep(). This
  branch never called resumeSleep().
- test/turn-trigger-provenance.test.ts: this branch's imports. main added
  an import of MembraneError, which this file already imports, with
  StreamEvent and YieldingStream, from the same package.
@nissa-seru
nissa-seru deleted the gideon2613/stop-ends-its-instance branch October 29, 2026 17:00
tel-0s added a commit that referenced this pull request Oct 29, 2026
…instance, inference bounds, the subconscious's own window and binding

main at 4a45766 is 11 merges past this branch's last (630e2a3, the 0.30.0
release), with no release among them, so package.json stays 0.30.0 and this
branch's floors stand (chronicle ^0.6.0, context-manager ^0.25.0, membrane
^0.8.0), which test/dependency-ranges pins. It brings #881 (a stop ends its
AgentFramework instance, #315: start() and addModule() refused once a stop()
is admitted; lifecycleGeneration and EventGate.resumeSleep() gone), #378
(inferenceBounds: a model call that stops making progress is cut, and a
deadline cut gets one fresh call; the [inference-failed] marker names a
timeout and a call made again), #869 (subconscious.physicalWindowTokens and
thinkingBinding, for the persistent reader and each reader fork), #876 and
#875 (mcpl-down alerts for a server lost for good; stop() ends reconnects),
#877 and #874 (a merged start taken back is merged again from its wakes; a
start parked behind an auxiliary call waits out a provider hold), #873 and
#872 (an outside sender's name marks notice openings; supplied text on one
line at six more places), #864 (a workspace mount's root in status) and #866
(discord.js loaded at the first client).

Six paths conflicted (8 regions):

- src/framework.ts (3):
  - stop()'s comment on ending each live fork: main's text. Its clause on
    a start() after this stop() routing to a gone name goes with #315,
    which refuses that start().
  - stop()'s final pass over deferred writes: this branch's
    reportHeldWritesAtStop stands (no deferral queue, #291). Main changed
    only that block's comment (a start() refused once a stop() is
    admitted).
  - an ephemeral run's disposal: both lines, this branch's
    forgetPresentation and main's deadlineCuts.delete.
- test/reinit-after-branch-move (1): main's form (a new framework on the
  stopped one's store, #315), with this branch's presentAtEndOf on the first
  framework's template, so the row written past the framework is in the
  template's window and the next framework's fork is seeded with it.
- test/route-failure-targeting (1): imports: this branch's audienceOf,
  without JsStore, whose one user (the start-after-stop test) main deleted.
- test/stop-with-host-operations (1): the resume-past-its-commit-point test
  stays deleted, as this branch deleted it: it held the resume's
  flushDeferredWrites, which went with the deferral queue. Main's change to
  it was its connection mock's stopReconnecting.
- test/stop-with-work-in-flight (1): imports: ContentBlock alone. Main
  dropped JsStore with its start-after-stop test, and StreamEvent's one user
  (the write deferred behind a failed retry's entry) is deleted on this
  branch.
- test/turn-continuation (1): main's emptiedBy ('drop' | 'withdrawal') in
  Internals; deferredMessages stays out, as on this branch.

Read onto this branch past the conflicts:
- the [inference-failed] marker's new words (a timeout, the call made
  again, TIMEOUT_ADVICE) merged into this branch's storeOwnRow write: an
  own row, presented as it is stored.
- deadlineCuts.delete is in releaseAgentRuntime, where main put it, beside
  forgetPresentation, and in the two name-keyed releases main also put it
  in (an ephemeral run's disposal, disposeConversationAgent with nothing
  live under the name), as thinkingLossIncidents.forget is.
- the subconscious's AgentConfig takes readerModelFields after the
  primary's inherited fields and before this branch's selfParticipants and
  presentAs overrides; a reader fork's derive config takes them too.

storeSees: no new site. Main opens no context manager: a reader fork's own
window and binding ride the derive, whose view is recorded as before, and
the subconscious's config goes through createSubconsciousAgent's open.
agentSees: no new view decision. Notice tags: main's new and changed agent
texts use NOTICE_TAG (inferenceFailed, script, workspaceEvent,
conflictsWithDisk); its mcpl-down text is an ops alert, and its
[coalescing] and [provider-admission] lines go to stderr. Teardown:
deadlineCuts in releaseAgentRuntime (above).

Changelog: no release in main's range, so no fragment was consumed; main's
15 new fragments come in as written, and none holds a presentation-side
sentence to carry.

Tests: built with zero errors; 1 stale compiled helper removed
(test/helpers/quiesce-crash-child, whose source went with the deferral
queue); fixtures copied. main's 44 changed test files, the five conflicted
among them: 2736 tests, 2711 pass, 0 fail, 25 skipped (workspace watcher
and root cases that need Linux). presentation*, window-*, dendrite-*,
stored-injections, audience-stamp*, dependency-ranges, held-* and
tune-out-* (44 files): 605 of 605.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

start() after a completed stop() reuses an instance whose queue, coalescer and watchdog stay stopped

1 participant