v0.15.0 — the library has no unsealed hive left #239
Replies: 1 comment
|
v0.15.1 follows with the one thing the seals took away.
The same obligation now exists in the vocabulary the boundary leaves standing (#237): "required_drains": [
{"accepts": "in_remember", "emits": "reject",
"because": "a refused block leaves the hive on this lane"}
]A caller that sends me The check errs toward silence on purpose: an out-edge with no condition counts as a drain, and a condition that cannot be evaluated against a lane-only probe counts as unknown and therefore as drained. Only when every out-edge evaluates cleanly to Also in the patch: the documented-port scan no longer blames a template whose name merely ends with a path segment (#238). |
Uh oh!
There was an error while loading. Please reload this page.
Two releases in one day, and they are one story: v0.14.0 made a rule enforceable, v0.15.0 made the shipped library obey it. If you wire hives, the migration section is the part to read.
An edge is laid at the hive
The rule is old and it is a requirement, not a convention:
As of v0.15.0 there is no unsealed hive left in the library. Eighteen templates moved: the four whose ports carried the name of a cell inside (
canvy,memory-hive,access,steward) and the fourteen that declared noparams.portsat all —talkyamong them, which is why the canonical instantiation example could never show the right shape until now.A hive that declares
"ports": []has no interior addresses.talky/keeper/stamp,collector/assemble,drain/drainare refused withhive_port_boundary— not a warning, not a dead letter, a rejectedadd_edges.The migration is one edit per address: drop the last segment and name the lane.
{"from": "<surface>", "to": "./talky/session-keeper", "modifier": {"set_hop": {"route": "'in_turn'"}}}becomes
"to": "./talky"with the identical modifier. For most edges this is a one-token change, because theset_hop.routewas already there — the interior cell discriminated on it too. Where it was not, add it: an edge onto a contracted hive with a missing or misspelled lane is refused withhive_contractand the hive's own sentence explaining what the lane is for. The full per-template table of lanes in and out is in the CHANGELOG.And a lane is named for what the caller wants, never for where it lands inside.
writer,recall,render,mutatorare cell names;in_episode,in_query,in_view,in_cycleare lanes. A lane named after an interior cell is the same structural coupling in a new spelling.A running colony is not affected. Instantiation copies the subtree, so an instance built before this release keeps its own bytes and its own interior addresses. What changes is what you get the next time you instantiate.
What had to be fixed before the library could move
A name means one thing (v0.14.0). Sealing hives meant writing deep names —
./unit/n1rather thann1— and that walked into an assumption the mutation validator had carried since the day it was written: that a diff name means what it is spelled. Invisible while every name was a single segment. Twelve defects came out of it, three of which could destroy data or take a colony down: an instantiation could re-mint a live cell's identity, anadd_edgescould commit onto a node the same diff disconnected, and two entries of one ordinary diff could take the colony down mid-apply. There is now exactly one function that decides which namespace a diff name belongs to, and every check asks it.A door may create the lane it carries (v0.15.0). A hive's failure lane works backwards from the others: the out-door recognises something only the inside knows — an
llmcell'shop.finish_reason— and mints the lane on the way out. The contract check probed exits only withhop.route = <lane>and never read the door's modifier, so a door that creates the lane was invisible and the hive could not declare a lane it demonstrably emits. It reads the modifier now, on both halves. Three tests pin the refusals that must survive — a door stating a different lane is still not this lane's exit.A cell declares that it is an ingress (v0.15.0, breaking). "This cell is where messages enter" used to be inferred from having no incoming edge. That held while the check saw only
config.jsonedges; once it sees the running graph, a genuine ingress that also receives replies — the ordinary shape of a proxy — loses the branch. It is a declaration now, and a list of context keys rather than a boolean, so a cell narrows the standard set instead of being handed all of it:Colonies whose keys all come from edge promotions need no change. A first boot refuses and names the node, the key and the field to add; a running colony reboots, reports per node, and starts.
Things that only show up when you run it
The watchdog could not tell a wedged colony from a starved host. A
cargo buildon the same machine killed a healthy colony three times in one day —on_trip=exitis the default, so each trip ended the process. The heartbeat now carries a phase, declared before the loop can block:Workingat the top of an iteration,Parkedright before the select. Everything in between is one work item, so the supervisor can ask "how long on ONE item" instead of only "how long quiet". A declared item gets a larger bar and outliving that is fatal again.exitstays the default, but it fires only on verdicts that implicate the colony; a starved host is logged loudly and the process lives.A one-shot timer whose moment passed in flight was dropped without a word. Now refused with
at_in_past. Three further disappearances came out of the same thread — the guard and the snapshot used two different clocks,insert_scheduletruncatedatto whole seconds and moved schedules up to a second earlier, and a due one-shot could vanish from the I/O set entirely.A surface join is not a render. After a colony restart the page kept showing the old picture until the operator touched something. It renders on join now, and falls back to the cache only if the render produced nothing. The other half is honest and unfixable server-side: until the transport reconnects the browser holds the old frame — so the page now dims and says so.
A newly instantiated cell could land on a hand-placed one. In a hand-arranged colony the automatic layout is only a fallback, and it computed positions for a layout the pinned cells no longer occupied. Foreign hive frames count as occupied now, and the search for a free spot prefers the cell's own hive.
Where the checks moved
Three gates changed home or grew teeth, and each one was a defect first:
docs/— the specification kept an address the boundary refuses, in the section defining the rule it broke. Deliberate counter-examples carry a marker that names the addresses it exempts, so a counter-example that stops being refused fails the gate instead of quietly becoming a correct example labelled as wrong.error_codes. A comment citing a rejection that no longer exists outlived the rule by weeks.4312 tests, 473 suites, both frozen routing corridors byte-identical.
docs/rewiring.mdships for the first time — it is the operator's view of the mutation format, and it now carries the migration order for putting a grown hive behind its boundary: a topology lives in four places, not two, and innermost first.All reactions