Repository navigation
the pin chip and the wire read one fact, a routing change lands on the next message, and a recording launch makes its own calls (#1022) - #1025
Conversation
…ile the wire would demand it, a routing change lands on the next message, and a recording launch makes its own calls Issue #1022 saw `moonshotai/kimi-k3@morph` on the status chip over three turns another machine answered. The chip, the panel's `lane` tail and the fold's mark were drawn from the profile row while the wire asked the transport, and the two disagree the moment the wire retires a pairing. They now read one door — `provider.PinNow`, which answers the machine a request will demand and, beside it, the machine a person's row still names that nothing is asking for — and the model is folded by the transport, under the same normaliser the retirement was written with, rather than against a key built on the surface's own spelling. A routing change landed on the next session rather than the next message, because the chat door read the row and wrote it onto the session config, which every client then held as an answer of its own — and an answer handed down beats the row this process installs. The door now installs the row and hands down nothing, so the conversation's clients read the live one; the settings panel re-installs it and re-reads its own two fields in the same keystroke. An engine host and a task child still carry their parent's row explicitly and still win. `AFORGE_DEBUG=1 aforge` wrote a folder holding run.json and no request bodies, because the host rule read the --debug FLAG while the record has three doors. It reads the switch, so the environment pin keeps the calls in this process exactly as the flag does. And the fold got the two gestures it was missing: `enter` on the machine already in force takes the pin off, and typing while a fold is open filters that model's machines before it filters the models. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
The row is installed on the process-wide knob rather than handed down onto the session's config, so the accessor the v3 door used to touch is no longer called from outside this package. The law that every persisted row names a reader something outside internal/config really calls now names InstallRoutingRow, which is what the launch and the settings panel both call. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
…ting row No door in this binary hands a routing row down any more: the engine host builds its session through the same profile door, and the two in-process auxiliaries carry a parent field that is now empty. The seam is still there and a caller that holds a row this process did not install still wins with it — which is what the comments now say, instead of naming call sites that do not exist. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
The tail on the model row was asking the transport directly, which skips the four states where this surface may name no machine at all — a hosted window, routing off, no model, a model served direct. It now goes through the same door the chip does, as a door rather than a snapshot, because a pin written two rows above it moves the answer in the same keystroke. The one reading that had no caller is gone. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
Real-model drive — Spark,
|
Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
It had been inserted between that comment and the function it documents. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
…t exist Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
|
Found by the Spark gate: `core` matches Cloudflare too, because c-l-o-u-d-f-l-a-r-e carries those four letters in order and the third matching rung is a subsequence. Keeping them in the ledger's order put the cursor on the machine nobody typed for, so the matched machines are sorted by the same summed rungs a model id is scored by — a prefix first, then a substring by where it starts, then the loose letters — with ties keeping the order the fold draws when nothing is typed. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
…machines The model list's own loop and the fold's were the same summed rungs written twice; the list now asks queryScore as the fold does, and the fold's two parallel readings ride a named pair instead of an anonymous one. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv
Spark gate — green at
|
Closes #1022.
Problem
Four things, all from the same drive.
@morphwhile three turns were answered by Sail Research. The status chip, the settings panel'slanetail and the picker fold's mark were drawn from the profile row; the wire asked the transport. The two disagree the moment the wire retires a pairing.routingwroteconfig.json, and thelanerow beside it went on explainingautoin the launch word on the same screen.AFORGE_DEBUG=1 aforgewroterun.jsonand no request bodies. Four launches;aforge chat --debugwrote them all.auto(≈16↑presses past every machine, and one too far lands on another model's row whereenterswitches the model), and its filter box filtered models, not machines.Cause
app.pinnedNowaskedprovider.PinnedFor, butlaneNow,sheet.laneWordandarmLanes'spicker.pinall readconfig.LanePinned/config.LaneAt— the row on disk, which a retirement never touches.applyV3Governanceread the routing row and wrote it ontosession.Config.Routing, whichnewProviderClienthanded every client asprovider.StaticRouting(...). A handed-down answer beats the rowInstallRoutingputs in place, so the conversation's clients were pinned to the word on disk at launch.app.routingandsheet.routingwere launch snapshots too.v3TakeHostRoadwas givendebug: *debug— the flag. With only the environment pin set, the launch took the host road, and the host process (never told to record) made the calls while this process wrote the header.applyLaneChoiceonly ever pinned;picker.rankclearedp.unfoldbefore matching anything.Fix
provider.PinNow(model)answers the machine a request will demand and the machine a person's row still names that nothing is asking for, read together under one lock, with the model folded bylanePinFor— the same normaliser the retirement was written with, which also closes the surface-spelling seam noted on provider, config, tui3:simplerouting — bare to OpenRouter unpinned, exactly the named provider pinned — is the row this build ships #1019.PinnedForis its first half.tui3'slaneInForceis the one reading every naming site makes: chip,laneNow,picker.force(besidepicker.pin, which still tells the fold's three rungs apart), andlaneRowTail. A retired pairing drawsauto (morph cannot serve this model)on the model row and marksautoin the fold; thelanerow itself is left exactly as written, because pinning again puts it straight back.cfg.Routing; it installs the row (config.InstallRoutingRow, the half ofInstallLaneRowsthe panel calls alone) and the session's clients read it live.Config.routingInForce()states the same rule for the gates on this side (the lane beat).app.routingRowChangedre-installs and re-readsapp.routing/sheet.routingon the write.debug: trace.Enabled().enteron the machine in force unpins (keyed on what the wire would demand, soenteron a stood-down machine re-pins, as the manual promises); the hint slot readsenter unpin · ← back · esc. Typing while a fold is open matches that model's machines first, through the sametokenScorethe model list uses, and falls through to the models when nothing matches.Manual
models-and-cost.md(the "next session" claim and the model row's tail),lanes.md(a new section for the two gestures, and what the retirement does and does not touch),commands.md,keys.md,debug-record.mdandstaying-on-that-machine.md(a recording launch keeps its conversation in this terminal, by the pin as by the flag).Evidence
internal/provider/pinchip_test.go— the law: over every state of the row (auto, openrouter, pinned, retired, re-pinned, base that carries no choice), what a surface may name equals whatdrawLaneChoicedemands for a call a person is reading.internal/tui3/pinchip_test.go— the surface reads the transport and not the row;laneRowTailover its states; the unpin toggle and its hint; the fold's filter; a routing cycle reaching the transport,app.routing, thelanerow's explanation and the fold's sentence on one frame.cmd/aforge/recordroad_test.go— the host road is decided by the switch (AST law) and refuses a host while the record is on.cmd/aforge/routinglive_test.go,internal/session/routinglive_test.go— the door hands down no row and installs one; a session with no row of its own follows the live one, a session carrying one keeps it.make test-laws,make pr-ready BASE=origin/dev) and a real-model drive: pasted into a comment below.Not verified
🤖 Generated with Claude Code
https://claude.ai/code/session_0182eyxXP8Xe7ADNKpYDe4wv