Repository navigation
room: every FDE has a standing conversation with the project's agent - #314
Merged
Merged
Conversation
sail project apply leaves the box's FDE a home room, <project>--<handle>,
titled with the project's name, assigned to the FDE and engaged with the
project's member through the doors POST /v1/rooms and POST
/v1/rooms/{id}/members take, so every admission check runs as it does there.
A second apply changes nothing; a room the FDE disengaged stays disengaged; a
refused engage keeps the room and the next apply engages it.
agent.member (agent, model, mode) is a new optional key of the definition,
defaulting to agent.type, the agent's default model and full access; a member
the project does not install, an unknown mode or an unsafe model is refused
when the definition is read. GET /v1/projects/{p} names the member and
project apply --json reports home_room.
Also: the run log stream reads a gone tail to the end of its pipe, so the
lines written between an empty ready() and the exit are no longer dropped.
Spec: sail-project-dm.
POST /v1/rooms takes an optional member, admitted exactly as addRoomMember
admits one (owner, trusted roster, mode, model, Running, installed) and seated
in the same write that creates the room. HomeRoom.ensure creates the home room
that way, so a refused member leaves no room and no revision for sync to carry,
the next apply creates it seated, and an empty roster is only ever its owner's
choice: the updated_at == created_at inference is gone.
HomeRoom.idOf keeps <project>--<handle> when that is a room id, and otherwise
folds the handle to the room id alphabet, cuts it to fit and suffixes 8 hex of
its sha256, so every valid handle gets a home room within the spec/room id
namespace. GET /v1/projects/{p} names the reader's home_room id so Mast never
derives it. A room someone else owns under the id refuses the apply naming the
owner.
The agent.type default member is validated when the definition is read, like a
declared one; a definition naming no agent has no member.
Spec: sail-project-dm.
Spec: sail-project-dm.
A folded id ending in the handle's CRC-32 shared a namespace with verbatim ids, so Ada.L and ada-l-2a8d4330 both named acme--ada-l-2a8d4330 and the second FDE's apply was refused. The folded id is now home-- and the SHA-256 of project and handle: 64 hex characters, longer than any handle, so no verbatim id can spell it. Spec: sail-project-dm.
…ith no FDE has none
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.
Spec:
sail-project-dm. Paired with standardapplied/mast#134 (branchagent/sail-project-dm), which places the home room in Mast's sidebar.What changes
agent.memberin the definition (agent,model,mode). It is optional, and each field has a default:agent.type, the agent's default model, andfull. The member is validated when the definition is read, whether it is declared or comes from theagent.typedefault. A member the project does not install, an unknown mode, or a model that is not one shell-safe token is refused there, soproject applyrefuses before provisioning and names the field. A definition that names no agent has no member.Agent.installs()replaces three copies of the "install, else type" rule (apply, provisioner, reviewer roster).HomeRoom.ensureis the last step ofProjectApplyCommand.converge. It runs as the box's FDE (CliOperator) and goes through the API's own door,POST /v1/rooms, which now takes an optionalmember.addRoomMemberadmits one: owner, trusted roster, a valid mode and model, the container Running, and the harness installed. The room is then written with the member already seated, in one revision.HomeRoom.idOf(project, handle). It is<project>--<handle>when that is a valid room id.sail project apply --jsongainshome_room: {id, created, engaged}(or{skipped}).GET /v1/projects/{p}gainsmemberand the reader'shome_roomid, so Mast never derives the id itself.AgentLogStreamer.pumpdropped lines that a tail wrote between an emptyready()and its exit.pumpRelaysWhatTheTailWroteBetweenAnEmptyReadyAndItsExitreproduces it deterministically.Tests
HomeRoomTestruns against the realSailOperationswith a scripted container shell. It covers:Ada.L) getting a room, and the longest project and handle staying valid and distinct;HomeRoomIT(real incus) runs the sequence: missing harness and no room, then install and the room created seated, then a no-op apply, then disengage, then an apply that leaves it disengaged.SailYamlTestcovers the implicit member refused when not installed, no agent meaning no member, and a member block with nothing to fall back on.ApiRouterTestcoversPOST /v1/roomswith amember.SailOperationsTestcoversmemberandhome_roomon the project response.Departures from the spec
HomeRoom.idOf), so the room id is not literally<project>--<handle>for those handles.