|
| 1 | +--- |
| 2 | +kind: fixed |
| 3 | +title: A reading beside the work is waited on, not guessed at, and a held memory line is not lost |
| 4 | +pr: 952 |
| 5 | +surface: [chat, engine] |
| 6 | +invalidates: |
| 7 | + - "A HELD MEMORY LINE IS NO LONGER SAID INTO THE DARK. `Agent.refreshMemory` took the lines the post-turn pass had no stream for off the queue and said them onto the hub the reading had been HANDED when it started (`memoryNotice(hub, line)`). A recall rides beside the turn and is never joined, so on a busy machine it runs after that turn has ended — measured on this package's own suite beside another one, where every losing run logged `ctxErr=context canceled hubClosed=true` — and the line was taken, said to a closed stream, and never said again. Every memory line now goes through `Agent.sayMemory`, which asks the hub to say it and HOLDS IT WHEN THE HUB COULD NOT: `eventHub.send` reports whether the event landed, so a line that met a closed stream, or no stream at all, is queued for the next turn by the same door. The correctness of that no longer rests on any ordering between this door and the roads that end turns — the hub answers from under its own lock, which is the only place the answer is not already stale." |
| 8 | + - "`memoryNotice` IS GONE, AND SO ARE THE CAPTURED HUBS. `Agent.routedMemory` and `Agent.runMemoryCommand` take `say func(string)` where they took `hub *eventHub`, and nil says nothing — which is a task node's reading borrowing its parent's store, exactly as silent as it was. `Agent.refreshMemory(ctx, cue)`, `Agent.importMemoryFile()` and `Agent.startRecallLocked(ctx, cue)` no longer take a hub at all; nothing in the memory pass holds one." |
| 9 | + - "`eventHub.send` REPORTS WHETHER THE EVENT LANDED (`send(Event) (landed bool)`, agent.go). It answered nothing before, so a caller holding something a person is owed had to trust an ordering to know whether to keep it; only the hub's own lock can answer, since a hub reads open until the moment it closes under it. Every other caller is drawing a line that belongs to the turn it is in and correctly ignores the answer. `TestALineSaidOntoAClosedStreamIsHeldInstead` pins the property with the pointer deliberately left on a closed hub." |
| 10 | + - "A READING'S LANDING IS A FACT A TEST CAN WAIT ON. `readBeside` (sidecar.go) tells a `besideWatch` carried on the work's context when each reading under it STARTS and when it has LANDED, the second after the settle closes, so whoever the watch lets go of finds the answer there to take. `besideWatch.quiet(ctx)` waits until none is in flight OR until the work those readings belong to is over — bounded by that fact and not by a clock, because `sidecar.end` cancels a reading's window without joining it. It is `desk.settled`'s bargain for the other half of that file: THE RUNNING PRODUCT CARRIES NO WATCH AND NEVER WAITS ON ONE, and `TestTheRunningProductNeverWaitsOnAReadingsLanding` reads the tree with `go/ast` — so it is on the laws gate — and fails the build on either of the two ways the product would reach for one." |
| 11 | + - "THREE FIXTURES NO LONGER GUESS AT THE SCHEDULER. A scripted conversation answers in no time and never blocks, so a reading the turn has just started can sit unscheduled behind it for as many rounds as the machine is busy: in every failing run the mark's drawing was still pending at all eight remaining boundaries, the script ended in words, and `markAside.takeAtTheEnd` journalled a drawing nobody could spend. A fixture that opts in with `watchReadings(t, agent)` answers the conversation only once every reading beside its turn has landed (`answerWhenQuiet`, applied by `scriptedCompleter`, `routeCompleter` and `reflexScript` to the request that carries the belt), which is the order a real turn usually has: a real model spends seconds on a step, the readings beside it are small, and a drawing that splits cuts the step it lands in. `racingAgent`, `stewardCheckpointAgent` and the three route tests that held their first answer take it." |
| 12 | + - "`routeCompleter.holdUntilRaced`, `awaitRace` AND `stopHolding` ARE DELETED. Holding the conversation until the pre-turn calls had been ENTERED — in a loop that slept a millisecond at a time — said nothing about the verdict having been parsed and settled, which is what the boundary after the first word kept failing to find. Nothing sets a hold count now; the watch is the whole of it." |
| 13 | + - "A SCRIPTED ARM ORDERS ITSELF BY A SIGNAL, INCLUDING ITS FIRST TOKEN. `lanestub.Profile.FirstTokenUntil` holds a lane's first word until a channel closes, after it has waited out its TTFT as scripted — `StallUntil`'s stated rule for the one wait `StallUntil` cannot hold, since that one only takes hold after `StallAfter` deltas. It holds the whole reply on the unstreamed path, where the first token and the last arrive together. `TestARescueTheCallCouldNotPayForSaysSoOnTheRow` needed it: lane A was scripted at sixty milliseconds against a ceiling of fifty, and a starved timer spent that ten-millisecond margin, so the first token arrived before the controller acted and the row said nothing had been done at all (`action = \"\"`, once in three hundred runs of #924's own head under twelve busy cores). It now holds A's first word on `theControllersWord`, which closes on any rung of the waiting ladder — the report of either half, a rescue, a model switch — so a regression that acts differently fails on its assertion rather than hanging." |
| 14 | + - "`docs/rules/ci.md` SAYS WHAT TO DO WITH A TEST THAT FAILS ONLY BESIDE ANOTHER SUITE — reproduce it under load, wait on the fact through the door that owns it, and never `t.Skip`, a retry or a wider bound. It is on that page because the known-red ledger's rules are, and because nothing may be added to that ledger." |
| 15 | +--- |
| 16 | + |
| 17 | +Five tests were green alone and red beside another suite, a different one each |
| 18 | +run, none of them on the ledger. One was the product's: a memory line a person |
| 19 | +is owed could be taken off its queue by a reading that had outlived its turn and |
| 20 | +said to a stream that had already closed. The other four were tests that |
| 21 | +measured the scheduler and called it the road — a count of the calls a fixture |
| 22 | +had answered, a script long enough on a quiet machine, ten milliseconds of wall |
| 23 | +clock between a ceiling and a first token. What replaces all three guesses is a |
| 24 | +wait on the fact itself. |
| 25 | + |
| 26 | +Still true and not fixed here: a drawing that splits can miss the boundary its |
| 27 | +own cut opened, because `act` runs before the settle by #871's ruling and a loop |
| 28 | +that reaches `take` in that window finds the reading pending — it pays another |
| 29 | +generation for the drawing, or drops it when that generation is the turn's last. |
| 30 | +The same gap is there when the drawing lands between a boundary and the next |
| 31 | +request, where `Agent.cutGeneration` finds nothing in flight to cut. |
0 commit comments