Repository navigation
Conversation
…heck sorts agents into An optional set of sub-states under Needs you. agent_state doesn't change: a session in one is still waiting, and an optional agent_sub_state says which. With no set, the board, the API and turn check's requests are as they were. At the end of a turn, a waiting verdict is followed by a second request that picks the sub-state, so the descriptions never reach the verdict's request. A question form gets one request on its text, and its place arrives as agent.substate, never a second agent.waiting. A permission prompt goes to the default by rule. What can't be placed sits in the default, marked not sorted. Each box keeps a stamped copy, and the app spreads the newest. The set can be edited over /v1/substates, berthd substates and MCP, including by an agent on the box, with limits, a before: hook and an event. /v1/turncheck stays closed to local callers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@Stener1 is attempting to deploy a commit to the seanbrydonio's projects Team on Vercel. A member of the Team first needs to authorize it. |
Contributor
Author
|
I can't add the |
… and every card style shows not sorted Waits open before a set was turned on or changed, or before turn check was, used to stay unsorted until their next wait. The box now sorts them then, one request at a time: a form by its words, any other wait by the agent's last message. At its start it sorts the waits it never tried, so a restart asks about each once. A wait recorded before the box kept sub-states is placed by the event that began it. The board now hands the Not sorted tag to the card as a line of its own (children), so a card style that takes children shows it too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…reset Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ough, and an unmarked form by its questions Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Closes #213.
Summary
Needs you mixes asks that want an answer with asks that send you off to do something. This adds an optional set of columns under it, which turn check sorts agents into. Off by default: with no set, the board, the API and turn check's requests are unchanged.
agent_statedoesn't change. A session in a sub-state is stillwaiting, so sends, waits, notifications and plugins behave as they did. An optionalagent_sub_statesays which one, and older clients ignore it.waitingonly for now), at most 6. The first is the default. Stored per box insubstates.jsonwith a revision and a stamp.substatescapability inGET /v1/info. A box keeps only what is newer than it holds, so two laptops can't flip it. An older box shows as outdated and keeps today's behaviour./v1/substates,berthd substatesand MCP, with limits, abefore:substates.changehook and asubstates.changedevent./v1/turncheckstays closed to local callers, and only a paired laptop can spread a stamped set.One decision that differs from #213: I proposed sharing turn check's request. It's two requests instead. An agent can write a description, and with a shared request the only thing between that text and the verdict is a sentence asking the model to ignore it. Now a description can't reach the verdict's request at all, and a provider that can't take the second question costs only the sort. A hostile description didn't move the verdict in the shared request when I tried it on 31 real turns, so this is a matter of guarantee, not of a bug seen. Accuracy was the same either way.
Evidence
Unchanged with no set. Before and after removing the set, the same four columns:
The preset (mock). Two amber columns, with counts. The card on an older box is tagged:
Real boxes, a real Claude Code, the real provider (
verify-berthd, scenariodashboard-sub-states-live):Claude Code's terminal driver was also run by hand: a form reports as a
permissionwait with toolAskUserQuestion, then again about 6 seconds later as a notification, and it stays one wait.Waits already open, and every card style (a second commit, after trying it on real waits). Agents that were already waiting when the set was turned on stayed Not sorted until their next wait, so a board turned on mid-day had every card in the first column. Now the box sorts them when a set is turned on or changed, or turn check is: one request at a time, a form by its questions and any other wait by the agent's last message. A wait too young to tell whether its own form placing is under way is looked at again once its window has passed. At start, the box sorts the waits it never tried, so a restart asks about each once. A wait recorded before the box kept sub-states is placed by the event that began it. The board also hands Not sorted to the card as a line of its own (
children), so a card component that takes children shows it too.Real box (
dashboard-sub-states-open-waits):Tests:
TestWaitsOpenBeforeASetAreSortedWhenItIsTurnedOn,TestTheStartPassAsksAboutAWaitOnce,TestAWaitTooYoungForThePassIsSortedLater,TestAnUnmarkedFormIsSortedByItsQuestions,TestAWaitFromBeforeSubStatesCanBePlaced. The new data flow: for a wait that isn't a form, the agent's last message goes to the provider, as it does at the end of every turn with turn check on; the docs say so.Tests
TestTurnCheckReplayspasses on every existing fixture without re-recording, andTestNoSubStatesLeavesTheClassifierRequestByteIdenticalandTestDescriptionsNeverReachTheVerdictsRequesthold the request to today's bytes.TestSubStateReplays: synthetic turns placed correctly on recorded gateway answers./v1/turncheck, older clients, no file:internal/box/substates_test.go.app/src/lib/substates.test.ts,app/e2e/dashboard-sub-states.spec.ts, and the existing dashboard specs unchanged.go vet,go test -race ./..., the app's checks and build, and the docs build pass, exceptTestTheCatalogIsCapped, which fails the same way on main on my machine because it counts the machine's real commands.cargo checkwasn't run: no Rust changed.Accuracy: on 51 real past asks from two machines, labelled by hand before any classifier call, the prompt was right on 47 (92%). The asks themselves aren't in this PR.
Not tested:
Merge Danger
Door: two-way
Removing every sub-state restores today's behaviour on the spot.
substates.jsonand thesubmark inturns.jsonare additive, and an older berthd ignores both.Blast Radius: small
With no set, the added work is a mutex-guarded read of an empty set on a waiting session, plus one read of a box's info. With a set, each form costs one classifier call, and each end-of-turn wait one more. Turning a set on, changing it, or turning turn check on costs one call per agent already waiting and not yet placed. The turn check ledger and
check()are touched, so a bug there would show on turn check for everyone: that is what the byte-identical and replay tests guard.🤖 Generated with Claude Code