Skip to content

Keep a Planner's runs and questions through a refused reply, and capture decisions across edits - #777

Merged
lavaman131 merged 7 commits into
mainfrom
fix/planner-decision-lifecycle
Nov 4, 2026
Merged

lavaman131 merged 7 commits into
mainfrom
fix/planner-decision-lifecycle

Conversation

@lavaman131

Copy link
Copy Markdown
Collaborator

Fix the Planner's decision lifecycle

A Planner turn could report "stopped after 30 min" while its workflow runs and questions were alive, an open_decisions retry could be counted as captured when nothing held the question, and a stale batch could land beside the wrong paragraph. This PR fixes those as one standalone change. Link-drop, suspension and reconnect handling is not here; it follows in a separate PR.

Root causes

  • The 30-minute "stop" was not a timeout. It was the run's age at the moment a refused Chat reply released its Planner session. The release destroyed a session that still owned live or paused workflow runs, or a question it was waiting on, so the run was reported as stopped after however long it had been alive.
  • Repeated keys counted 0. The turn's capture count included only cards it had just created. A repair turn that retried open_decisions with the stable keys of cards an earlier turn had already created therefore counted 0 captured decisions, the Chat reply was refused ("could not move its questions into inline decisions"), and the refusal released the Planner session, again reporting the run as stopped. A retry with the stable keys the repair prompt asks for could never succeed.
  • Strict revision equality. open_decisions refused the whole batch whenever the revision had moved on since the Planner's read, whatever had changed: a person typing, a workflow run writing, or the Planner's own earlier card. A document with live writers could keep refusing it.
  • Digest-only rebasing. Once the batch was allowed to survive a revision change, it found each paragraph by digest in the document as it now stands. An identical paragraph inserted ahead, a paragraph rewritten beside an identical copy, or one that was already duplicated when the Planner read it, all anchored the card to the wrong block. A retry in that state was then reported as "a different decision, use a new key", which was not what had happened.
  • The remembered read was overwritten. The outline kept for a revision was replaced by the result of an edit made from that revision, so what the Planner had read was lost.

Fixes

  • A refused or unverifiable reply no longer releases a session that owns live or paused runs or has open host requests (questions it asked). The session is let go when those end. Explicit Stop, sign-out, revocation, the owner binding ending and the document closing still release it, a question is still never posted in Chat, and there is no wall-clock limit on a long busy reply.
  • A repair that repeats the stable keys of cards that already exist now counts the cards it returns, new or not, so it no longer fails for want of a new card, and its summary says they are already in the document instead of claiming they were added. That count must not be fooled in the other direction, so a repeated key replays only the decision it made: the same question, response kind, choices (apart from options people added since) and passages. Otherwise the whole batch is refused naming the key and nothing is created. Only a card that still holds its question counts as captured; a discarded card is never recreated.
  • A stale batch keeps its place instead of being refused, but is matched against the revision the Planner read. The digest must have named exactly one block then, the block that was read must still be the block carrying it, and it must carry it alone now. Otherwise the batch is refused with a message that the document changed and the Planner should read it again, and nothing is created. A revision the server no longer retains is refused the same way. An identical replay of an existing card stays idempotent: judged against the same read where the server still holds it, and otherwise (after a restart or once the read is evicted) only for a card that still stands beside the one paragraph it was opened on, not by an anchor recovered onto an identical copy. A card with several passages is refused in that case until the Planner reads again, since a later passage cannot be told from an identical copy. The refusal names what actually happened: the read is gone, the paragraph appeared more than once when read, the block read was rewritten, removed or moved, or an identical paragraph now stands beside it. The remembered read is no longer overwritten by an edit's result, records which live block each entry was, and the revision an edit_plan returns is remembered once published so a batch written from it survives another writer's edit. A replay of an existing key is checked against the same read where the server still holds it.

Tests

  • Red before green for each change: the new capture, invoke and session tests fail on the old code and pass on this head. For the stale-capture work, new capture-decisions tests fail without the source change for a paragraph rewritten beside an identical copy, a paragraph already repeated when read, a revision no longer retained, a replay whose read was evicted beside an identical copy, a replay after a rewrite, a replay naming a different intact paragraph, an address whose index disagrees with its digest, and an open_decisions batch written from the revision edit_plan returned after another writer's edit.
  • On this head: bun test 6813 pass, 0 fail (22 skipped for the missing PostgreSQL URL); bun run types; bun run ci; and 43 Chromium tests across the harness decisions deck, planner decisions, run card, planner attachment, open-ended decisions, decision prose and inline decision deck.
  • bun run test:postgres was not run; storage is unchanged.

Not in this PR

Link-drop, suspension, resumable-session and reconnect behavior is out of scope and follows in a separate PR. This change does not alter how a dropped link is handled.

Assistant-model: Claude Sonnet 5.5
Assistant-workflow: goal (run 29d6269b-6026-4c1f-8a50-399c757f21c0)
Assistant-duration: unmeasured converged, estimated unmeasured
Assistant-verification: bun test unit passed: 6813 pass, 0 fail on the final head
Assistant-verification: bun run types passed: whole workspace and e2e on the final head
Assistant-verification: bun run ci passed: dprint, oxlint, tokens and design checks on the final head
Assistant-verification: bun run e2e passed: 43 tests across seven decision and Planner files on the final head
Assistant-verification: bun run test:postgres unavailable: not run, storage is unchanged
Co-authored-by: Alex Lavaee lavaman131@github.com

Known limitation

One narrow case is left for #776: a replay whose read was evicted can be accepted beside an identical copy of a rewritten paragraph.

Assistant-workflow: goal (runs 5c2dd386-1e50-4873-be57-3bc47480ae71 and 29d6269b-6026-4c1f-8a50-399c757f21c0)
Assistant-duration: 5h15m converged, estimated 45-90m
Assistant-verification: bun run types passed: after rebase onto main 6dbb78e
Assistant-verification: bun test passed: apps/server chat, questions, agent, harness, experiments, tasks, 1936 pass, 0 fail after rebase
Co-authored-by: Alex Lavaee lavaman131@github.com

…eply

A Chat reply the Planner could not move into inline decisions failed its
turn, and a failed turn let go the retained Planner session. A workflow run
that session still owned was then shown as "stopped after N min" and its
open questions were withdrawn, although nothing had stopped it. N is only
how long the run had lasted when the reply failed; no budget or timer was
involved.

- A turn that fails only because its Chat reply could not be verified or
  moved into inline decisions (PlannerReplyError) keeps a session that still
  owns live or paused runs. The failure is still announced and the withheld
  text is still never published. Any other failure, an interruption, Stop,
  the owner binding ending or the document closing lets the session go as
  before, and a run reported stopped stays stopped.
- A repair that repeats open_decisions keys an earlier turn already created
  counts as having created them: the turn now records every decision
  open_decisions returns, new or not. Retrying with stable keys, as the
  repair prompt asks, no longer fails the turn again for want of a new card.
  The summary says such cards are already in the document rather than
  claiming they were added.
- A Default machine Planner that is replying now counts as in use, like one
  waiting on a question or a run, so a reply that outlasts PLANNER_IDLE_MS
  with nobody viewing the document is not cut off, and idle time counts from
  its end. A Planner with no reply, question or run, and nobody viewing the
  document, is still released after 30 minutes.

Assistant-model: Claude Sonnet 5.5
Assistant-workflow: inline
Assistant-duration: 43m converged, estimated 45-90m
Assistant-verification: red before fix passed: on the old code the new Chat lifecycle tests failed (a refused reply destroyed the session and posted "plan-review was stopped after 31 min."; a repeated capture threw "could not move its questions") and the long-reply planner-dispatch test failed (the Planner was stopped mid-reply after a simulated 31 minutes); the new reply-policy unit tests only failed to load without PlannerReplyError
Assistant-verification: bun test unit passed: GIT_CONFIG_GLOBAL=/dev/null bun test apps/server/src/chat apps/server/src/harness/remote apps/server/src/experiments on this commit's tree alone (836 pass, 0 fail)
Assistant-verification: full suite, types, ci and e2e unavailable: run once on the final head of this two-commit change, recorded on the next commit, not on this commit alone
User-preference: no wall-clock timeout for active work or pending human decisions
Co-authored-by: Alex Lavaee <lavaman131@github.com>
open_decisions refused a whole batch whenever the document's revision had
moved on since the Planner's read, whatever had changed: a person typing, a
workflow run writing, or the Planner's own earlier card. The Planner got
"The document changed; read it again before opening a decision" and had to
read and write the batch again, which a document with live writers can keep
refusing.

Every related block already carries the digest the Planner read, so a stale
batch now keeps its place instead. A block that still carries its digest is
used wherever it now stands. A block that changed, or whose digest is
ambiguous, still refuses the whole batch with the same error and creates
nothing. Each card is still created once under its stable key, so a retry
never duplicates one, and the Planner's access is still confirmed before the
batch is read. open_decision and ask keep their strict revision check.

Assistant-model: Claude Sonnet 5.5
Assistant-workflow: inline
Assistant-duration: 50m converged, estimated 45-90m
Assistant-verification: red before fix passed: on the old code the new capture-decisions tests (an unrelated edit, a moved paragraph, a mixed replay) and the open_decisions tool test failed with "The document changed; read it again before opening a decision"; the existing mixed-replay test that pinned the strict revision now expects the rebase, and a changed paragraph is still refused with nothing created
Assistant-verification: bun test unit passed: GIT_CONFIG_GLOBAL=/dev/null bun test on the final head (6788 pass, 0 fail); a second full run had one failure in the timing-dependent WriterLease test, outside this change, which passes 5 of 5 times alone
Assistant-verification: bun run types passed: whole workspace, on the final head
Assistant-verification: bun run ci passed: dprint, oxlint, tokens and design checks, on the final head (72 existing lint warnings, none in changed files)
Assistant-verification: bun run e2e passed: 55 tests across harness, planner-decisions, run-card, planner-attachment, machine-choice and open-ended-decisions on the final tree; an earlier run of the same files had two machine-choice sidebar menu failures that passed on rerun and on the unmodified base, and no web code changed
Assistant-verification: bun run test:postgres unavailable: not run, storage is unchanged
User-preference: no wall-clock timeout for active work or pending human decisions
Co-authored-by: Alex Lavaee <lavaman131@github.com>
…ng a captured decision

Independent review found four ways the previous two commits let a turn count
a decision as captured when nothing live held the Planner's questions, or let
a batch land beside the wrong passage.

- A repeated open_decisions key returned the original card whatever the new
  input said, so a different question, response kind, choices or passage was
  dropped silently and the turn reported "already in the document". A key now
  repeats only the decision it made: the stored question, response kind and
  choices (apart from options or criteria people added since) and its passages
  must match, otherwise the whole batch is refused, naming the key, and
  nothing is created, replaced or replayed. Identical replays stay idempotent,
  including after a restart or an option a person added.
- A stale batch rebased by digest used the addressed block whenever its
  digest still matched, so an identical paragraph inserted ahead of the
  original anchored the card to the copy. A stale batch now needs exactly one
  block carrying the digest; a repeated digest refuses the whole batch with the
  same "read it again" error and creates nothing. Other callers of
  resolveBlock keep their behaviour.
- The reply policy counted any record the turn returned, including a card a
  person discarded or that was cancelled, so a replayed discarded key made a
  turn with two withheld questions succeed. Only a card that still holds its
  question (open, reopened or answered) counts, for repeated and new cards
  alike; a discarded card is never recreated and the turn still fails visibly.
- A refused or unverifiable reply still destroyed a Planner session that
  waited only on a question it asked, such as an ask_user_question with no
  reported workflow run, aborting its host signal and cancelling the decision.
  Every atomic or remote Planner session now counts its open host requests; a
  session with one is kept, with or without a refused reply, and let go when
  the request ends. An explicit Stop, the owner binding ending and the
  document closing still let it go.

Assistant-model: Claude Sonnet 5.5
Assistant-workflow: inline
Assistant-duration: 19m converged, estimated 45-90m
Assistant-verification: red before fix passed: with the source of this commit stashed (the PendingInputs class kept so the tests load), 15 of the new or extended tests failed on the old code: six capture-decisions (a repeated key with another question, description, response kind, choices or passage, and a mixed batch, all resolved to the original card), one capture-decisions (an identical paragraph inserted ahead anchored to the copy), three invoke (changed, discarded and discarded-new reported success), three invoke (a Planner with only an open question was destroyed after a refused reply, after a normal turn, and the Stop and close cases found nothing retained) and two session tests (no pending-request count)
Assistant-verification: bun test unit passed: GIT_CONFIG_GLOBAL=/dev/null bun test apps/server/src/chat apps/server/src/harness apps/server/src/questions apps/server/src/agent apps/server/src/plan on this tree (1936 pass, 0 fail)
Assistant-verification: bun run types passed: whole workspace, on this tree
Assistant-verification: bun run ci passed: dprint, oxlint (72 existing warnings, none new), tokens and design checks, on this tree
Assistant-verification: full suite and bun run e2e unavailable: run once on the final head of this round, recorded on the next commit, not on this commit alone
User-preference: no wall-clock timeout for active work or pending human decisions
Co-authored-by: Alex Lavaee <lavaman131@github.com>
A stale open_decisions batch found each paragraph by digest in the document as it
stands, so it still anchored a card to an identical copy when the paragraph the
Planner read had been rewritten, or when the paragraph was already repeated at the
time of the read. A retry of a key whose paragraph had been rewritten was refused
with "already holds a different decision, use a new key", which misdescribes it.

A stale batch is now matched against the revision the Planner read. The digest must
have named exactly one block then, the block that was read must still be the block
that carries it, and it must carry it alone. Otherwise the whole batch is refused
with the document-changed message, naming the key, and nothing is created. A
revision the server no longer retains is refused the same way. An identical replay
of a key whose card exists stays idempotent, judged by the card's own anchor.

The outline remembered for a revision was overwritten by the result of an edit made
from that revision, so what the Planner read was lost; the edit result no longer
replaces it. Each remembered outline now also records the live block behind every
entry, which is how a rewritten paragraph is told from its twin.

Assistant-model: Claude Sonnet 5.5
Assistant-workflow: goal (run 29d6269b-6026-4c1f-8a50-399c757f21c0)
Assistant-duration: unmeasured converged, estimated unmeasured
Assistant-verification: red before fix passed: with the source stashed, 4 of the new capture-decisions tests failed on the old code (rewritten paragraph beside a copy, paragraph already repeated when read, revision not retained, repeated key after a rewrite reporting a different decision) and all 30 pass with it
Assistant-verification: bun test unit passed: GIT_CONFIG_GLOBAL=/dev/null bun test on this head (6807 pass, 0 fail, 22 skipped for TEST_DATABASE_URL)
Assistant-verification: bun run types passed: whole workspace and e2e, on this head
Assistant-verification: bun run ci passed: dprint, oxlint (72 existing warnings, none new), tokens and design checks, on this head
Assistant-verification: bun run e2e passed: 43 tests across harness-decisions-deck, planner-decisions, run-card, planner-attachment, open-ended-decisions, decision-prose and inline-decision-deck on this head
Assistant-verification: bun run test:postgres unavailable: not run, storage is unchanged
Co-authored-by: Alex Lavaee <lavaman131@github.com>
…lay beside a twin

Review of the previous commit found three gaps in the stale decision batch.

An edit_plan result hands the Planner a new revision to work from, but that
revision's outline was never remembered, so any later edit by another writer made
open_decisions at that revision refuse with "no longer retained", undoing the
survival of an edit elsewhere. The outline of the revision an edit returns is now
remembered, with its block anchors, once the edit is published.

A replay of an existing key was judged by the card's anchor alone, and a card whose
paragraph was rewritten beside an identical copy could be recovered by digest onto
the copy and reported as captured. Where the server still holds the Planner's read,
the block that read named must now be the card's own block; where it does not (after
a restart), an identical replay is still judged by the card's anchor as before.

A stale replay of a known key that points at a different, intact paragraph now gets
the "already holds a different decision" refusal again, since the document-changed
message is wrong for it.

Assistant-model: Claude Sonnet 5.5
Assistant-workflow: goal (run 29d6269b-6026-4c1f-8a50-399c757f21c0)
Assistant-duration: unmeasured converged, estimated unmeasured
Assistant-verification: red before fix passed: with the source of this commit reverted, three new tests failed on the previous head (open_decisions at an edit_plan-returned revision after another writer's edit, a replay after a rewrite beside an identical copy, a stale replay naming a different intact paragraph) and pass with it
Assistant-verification: bun test unit passed: GIT_CONFIG_GLOBAL=/dev/null bun test on this head (6810 pass, 0 fail, 22 skipped for TEST_DATABASE_URL)
Assistant-verification: bun run types passed: whole workspace and e2e, on this head
Assistant-verification: bun run ci passed: dprint, oxlint (72 existing warnings, none new), tokens and design checks, on this head
Assistant-verification: bun run e2e passed: 43 tests across harness-decisions-deck, planner-decisions, run-card, planner-attachment, open-ended-decisions, decision-prose and inline-decision-deck on this head
Assistant-verification: bun run test:postgres unavailable: not run, storage is unchanged
Co-authored-by: Alex Lavaee <lavaman131@github.com>
… was refused

Review of the previous commit found that a replay of an existing key whose read the
server no longer holds (after a restart, or once more than eight revisions have been
outlined) was still judged by the card's anchor alone. That anchor can have been
recovered by digest onto an identical copy of a rewritten paragraph, so the replay
was reported as captured. Without the read, a replay now needs the card to stand
beside the paragraph the input names, which the recovered anchor does not show; an
identical replay of a card still beside its paragraph stays idempotent.

The refusal text also listed causes that had not happened. It now names the one that
did: the server no longer has that read, the address does not match the block read at
that position, the paragraph appeared more than once when it was read, the block read
was rewritten, removed or moved since, or an identical paragraph now stands beside it.
A stale address whose index disagrees with its digest is refused, as it is at the
current revision.

Assistant-model: Claude Sonnet 5.5
Assistant-workflow: goal (run 29d6269b-6026-4c1f-8a50-399c757f21c0)
Assistant-duration: unmeasured converged, estimated unmeasured
Assistant-verification: red before fix passed: with the source of this commit reverted, five new or extended capture-decisions tests failed (the three refusal causes, an evicted-read replay beside a twin, an index that disagrees with its digest) and all 34 pass with it
Assistant-verification: bun test unit passed: GIT_CONFIG_GLOBAL=/dev/null bun test on this head (6812 pass, 0 fail, 22 skipped for TEST_DATABASE_URL)
Assistant-verification: bun run types passed: whole workspace and e2e, on this head
Assistant-verification: bun run ci passed: dprint, oxlint (72 existing warnings, none new), tokens and design checks, on this head
Assistant-verification: bun run e2e passed: 43 tests across harness-decisions-deck, planner-decisions, run-card, planner-attachment, open-ended-decisions, decision-prose and inline-decision-deck on this head
Assistant-verification: bun run test:postgres unavailable: not run, storage is unchanged
Co-authored-by: Alex Lavaee <lavaman131@github.com>
… a twin

Review of the previous commit found that, without the Planner's read, a replay of a
multi-passage card was checked against where the card stands for its first passage
only. A later passage was judged by its anchor, which can have been recovered by
digest onto an identical copy of a rewritten paragraph, so the replay was reported as
captured while the same input with the read retained was refused.

Without the read, a replay is now accepted only for a card standing beside the one
passage it was opened on. A card with several passages is refused, with the cause
that the server no longer has that read, until the Planner reads the document again;
a retry at a fresh revision is judged normally and stays idempotent. The decisions
guide states this.

Assistant-model: Claude Sonnet 5.5
Assistant-workflow: goal (run 29d6269b-6026-4c1f-8a50-399c757f21c0)
Assistant-duration: unmeasured converged, estimated unmeasured
Assistant-verification: red before fix passed: with the one-line change reverted, the new capture-decisions test (a card on two passages, the second rewritten beside an identical copy, the read evicted by nine later outlines, then a replay) failed and all 35 pass with it
Assistant-verification: bun test unit passed: GIT_CONFIG_GLOBAL=/dev/null bun test on this head (6813 pass, 0 fail, 22 skipped for TEST_DATABASE_URL)
Assistant-verification: bun run types passed: whole workspace and e2e, on this head
Assistant-verification: bun run ci passed: dprint, oxlint (72 existing warnings, none new), tokens and design checks, on this head
Assistant-verification: bun run e2e passed: 43 tests across harness-decisions-deck, planner-decisions, run-card, planner-attachment, open-ended-decisions, decision-prose and inline-decision-deck on this head
Assistant-verification: bun run test:postgres unavailable: not run, storage is unchanged
Co-authored-by: Alex Lavaee <lavaman131@github.com>
@lavaman131
lavaman131 force-pushed the fix/planner-decision-lifecycle branch from 9ccd43c to 1fb197c Compare November 4, 2026 08:38
@lavaman131
lavaman131 merged commit 73ae113 into main Nov 4, 2026
46 of 48 checks passed
@lavaman131
lavaman131 deleted the fix/planner-decision-lifecycle branch November 4, 2026 08:43
lavaman131 added a commit that referenced this pull request Nov 4, 2026
…ction until it returns

A Planner machine that lost its connection (asleep, network down) ended its own work: the
server finished the turn, withdrew every question the client had asked, showed its live runs
as stopped and forgot the session, so a network failure read as the Planner stopping
("was stopped after N min") and cancelled Decisions nobody had answered. The reattach
protocol could not undo it, because the client's own close had already settled its questions
and a stopped run card is terminal. The user's decision is that a dropped connection ends
nothing by itself, however long the machine stays away; only an explicit Stop, a sign-out,
unpairing or revoking the machine, a Planner reset, or archiving or deleting the document
does.

A client may now ask for the new `resumable-sessions` feature, and the package client does by
default (`resumable: false` opts out). For such a link that drops unexpectedly (the socket
closes with no detach or refusal, or the server closes it as unresponsive) the server keeps
each session that has a live or paused run, or a question waiting on a member, with no
deadline. The document's Planner is announced as `disconnected` and its live run cards carry
`disconnected` with their last status; Chat says once that the Planner disconnected and once
that it came back; `@chopin` and `invoke_planner` say it is disconnected; Decisions stay open
and answerable and answers are held. The same account's next link sends `resume` first (the
sessions and questions it still holds) and gets `resumed` back: answered questions are
delivered once, withdrawn ones are withdrawn, and runs carry on. `PLANNER_ATTACH_GRACE_MS` now
leases only a detached link's ownership, or a drop with nothing to keep; a quiet machine's
connector connection, the Default machine idle period and the owner's GitHub credential being
renewed no longer end a disconnected Planner either, and the document is not offered to another
of its owner's machines meanwhile.

Explicit acts are never lost on the way. A Stop pressed while the machine is away, or sent and
unanswered when the link dropped, is held and delivered first after `resumed`, and Chat says
only what is true: stopped when the client confirmed it, asked when the connection is known to
be down, not confirmed when it did not answer, and kept once the drop is noticed. A Resume now
undoes only the Stops it covers, and a Resume pressed while away is refused, not held. A
question the client withdraws while the link is down settles at once and is withdrawn in
Chopin on resume. The client acknowledges every `input-result` with `input-received`, so an
answer written into a socket the server had not yet noticed was dead, including to the only
question of a Planner with no run, is kept with its session until acknowledged and sent again
after `resumed`. A same-account client that notices its own drop first and reconnects at once
takes the old link's work over with its first `resume`, which shows that link is dead. A
refusal carries `retry` only when Chopin could not decide, and the package client keeps its
questions pending only for that.

A server restart still forgets every session in memory: a client's `resume` finds nothing and
it settles its questions as cancelled, the Decisions stay open and answerable exactly as after
a crash, the stored run cards come back stopped and stay so until a session is started again,
and a graceful shutdown posts no Chat line about it. The documentation says so rather than
promising more.

The shipped connector does not speak the agent protocol itself; it starts a Planner backend
command. It now keeps a current Planner credential in a private file,
`CHOPIN_PLANNER_TOKEN_FILE`, for as long as a backend runs, so a backend that keeps its
sessions through a drop can attach again hours later with a fresh one, and the agent
connection guide states the revised backend contract. No Planner backend ships in this
repository, and no test composes the connector, a backend and a drop longer than the
credential's 15 minutes end to end; what is tested is each side: the connector's renewed
file, the server accepting a fresh machine credential and resuming, and the package client's
resume, acknowledgement and retries.

The stale-twin capture finding of the previous review round was already settled by the
decision-capture work in main (#777); a test pins its second variant.

Assistant-model: Claude Sonnet 5.5
Assistant-workflow: goal (run 2ec31f8e-bdf5-4bf5-a416-011edba43bee)
Assistant-verification: red before fix passed: with each fix reverted its new tests failed, in three rounds of fixes (no-deadline hold, acknowledgement kept, Stop wording and late answers, shutdown cancelling and posting, hand-over, retry classification, withdrawal after resume, malformed frame, credential file renewal, skewed clock, hung stop, file mode)
Assistant-verification: mutation check passed: re-adding a grace timer for a suspended link failed the four no-deadline link-resume tests, and dropping the acknowledgement or the hand-over failed theirs
Assistant-verification: bun test unit passed: GIT_CONFIG_GLOBAL=/dev/null bun test on this commit's tree
Assistant-verification: bun run types passed: whole workspace and e2e, on this commit's tree
Assistant-verification: bun run ci passed: dprint, oxlint (72 existing warnings, none new), tokens and design checks, on this commit's tree
Assistant-verification: bun run test:postgres unavailable: not run, storage is unchanged
User-preference: A dropped connection never ends runs or open questions; only an explicit Stop, sign-out or unpairing does
Co-authored-by: Alex Lavaee <lavaman131@github.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.

1 participant