fountain v0.4.1 -> v0.6.1, so a lost turn fails cleanly and says why - #105
Closed
jhgaylor wants to merge 1 commit into
Closed
fountain v0.4.1 -> v0.6.1, so a lost turn fails cleanly and says why#105jhgaylor wants to merge 1 commit into
jhgaylor wants to merge 1 commit into
Conversation
The status page said completing a turn was a race decided by machine speed, and that a faster machine loses more often. Standing the deployment up and running 27 conversations through it says otherwise: every conversation provisions fresh, the reattach branch is never taken by a first dispatch, and the same laptop returns both outcomes at roughly even odds. What actually happened was a crash. fountain wrote the prompt into the exec session with a bare GenServer.call; spritzer's exec is one-shot, so when the close won the race the call landed on a dead process and exited the ConversationServer. The supervisor restarted it, the restarted server found its own sandbox already `ready` and reattached, and list_sessions got spritzer's 426 — an orphaned turn behind an error that named nothing real. The reattach was the tail of the crash, not the cause. 14 crashes, 14 reattaches, each 1-3ms after its own crash, none without one first. Filed upstream as fountain#603 and fixed in v0.6.0; the exit code it dropped on the way out is #608, fixed in v0.6.1. Bumping straight past v0.6.0 because its release task for verify-email verified the account and then crashed on a PubSub broadcast that the Repo-only VM has nothing to receive (#609, also in v0.6.1). So the pin moves to v0.6.1 and the gate stops asserting a pairing it was only ever right about by accident. It now accepts either legitimate shape — completed, or failed as :command_exited — and fails on a third. A reattach in a fresh conversation is the #603 signature and stops the build, which is stricter than what was here before. The docs carry the corrected mechanism and the numbers behind it, and keep the old reading as history: a claim that was wrong twice is worth being able to trace. Verified: `just e2e` green from nothing at v0.6.1, and 44 conversations across the two pins with zero crashes, zero reattaches and an exit code on every turn. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Superseded by #109. This described a race — which arm of a lost-write crash you landed on, and how the turn died as a result. spritzer 0.5.0 closes it: turns now complete every time (34 of 34), so there is no longer a race to document. #109 carries the pin bump, moves Completing a turn to Verified, and keeps the history — including this PR's own reading of it — in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The status page claimed completing a turn was a race decided by machine speed,
and that a faster machine loses more often — 5 of 5 orphaned on a laptop, 2 of
2 completed on a runner (#67).
Standing the deployment up and running conversations through it says otherwise.
What was actually happening
Every conversation provisions fresh. The reattach branch is never taken by a
first dispatch. What varied was a crash:
27 conversations on
v0.4.1: 27 fresh provisions, 14 crashes, 14 reattaches— 1:1, each reattach 1–3ms after its own crash, and none without a crash
first. The reattach and the
426were the tail of the crash, not the cause.The machine-speed reading did not survive either: the same laptop that gave 5
of 5 gave 8 completed to 12 orphaned over 20 back-to-back runs, and
provisioning duration does not separate the outcomes (median 14.4ms completed
against 13.0ms orphaned, fully overlapping). Those earlier samples were a coin
flip landing the same way twice.
The pin
Filed upstream as fountain#603,
fixed in
v0.6.0. Two follow-ups came out of testing that fix:failure dropped the runtime's exit code.
turns.exit_codewasNULLon all17 failed turns of a 30-conversation run. Fixed in
v0.6.1.v0.6.0'sverify_email/1release task verified the account and then crashed on aPubSub broadcast the Repo-only VM has nothing to receive. Caught by
just e2e, which went red on it. Fixed inv0.6.1.So this goes straight to
v0.6.1.just verify-emailA lost race now costs the turn, not the deployment: conversation back to
idle, turnfailedwith:command_exited (runtime exited N), nothing leftrunning.
The gate
just e2easserted a pairing — reattach implies orphaned, no reattachimplies exit 0. That held on every run, but only because crash ⇒ reattach; it
was right by accident.
It is now three-way and stricter:
exit_code: 0→ completedturn/failedwith:command_exited→ the emulator's one-shot exec(spritzer#18)
conversation — that is the #603 signature, and 44 conversations across the
two pins produced zero of them, so seeing one means the pin regressed
A turn failing for some other reason also stops it: that reason would be new,
and worth reading before it gets documented.
Docs
status.md,data-plane.md,ci.mdand the README carry the correctedmechanism and the measurements behind it. The old reading is kept as history
rather than deleted — a claim that was wrong twice is worth being able to
trace, and the status page's credibility rests on showing its work.
No rate is asserted anywhere. The split moves with how fast conversations are
opened — 11 of 16 completed at three-second intervals against 2 of 14 packed
back to back — and pinning a number to it would be the same mistake one layer
down.
Verification
just e2egreen from nothing atv0.6.1, including register → verify →first-admin → conversation gate → every seam
v0.6.0andv0.6.1: zero crashes, zero reattaches,zero new
426scaptured
v0.6.1failed stream to confirm the other branch classifies —fountain#611 deliberately keeps
:command_exitedin front of the new detailfor exactly this reason
just checkandjust sitecleanUpstream comments posted on #67 and spritzer#18 correcting both.
🤖 Generated with Claude Code