Skip to content

agent.attached

An agent was put in a room: added, moved in, or brought back. Its harness is handed the room’s last lines with it.

Direction: Chips → the log
Sent by: Chips only; refused from a client
Requires a run: no
Schema: agent.attached.json

Every event also carries the envelope.

Field Required Type Description
v yes 1 Protocol major version.
type yes "agent.attached"
id yes string The event’s own id. Stable across a retry of the same event.
ts yes string When it happened, by Chips’ clock. Stamped on the way in; a value the sender writes is replaced.
workspace_id yes string A workspace identifier: ws_ followed by a ULID.
space_id no string The space, when the event belongs to one.
run_id no string The run, when the event belongs to one.
seq no number Assigned by the server on append, monotonic per workspace. Absent on the way in.
idempotency_key no string Required on every client-originated write. Sending the same key twice is a no-op.
actor yes object The participant an event is attributed to.
actor.kind yes "person" | "harness" | "agent" | "system" Whether a person, a harness, one of a harness’s agents or Chips itself acted.
actor.id yes string The participant id, or system for Chips.
actor.harness_id no string For an agent: the harness it speaks through, whose budget and runs are the agent’s (ADR 0087). Filled in by Chips.
agent_id yes string The agent, in the room this event’s space_id names.
by no string Who put it there: a person, its harness, or Chips (system).
moved_from no string The room it left for this one, when moved.
fork_of no string The agent.fork this copy answers, when it is a fork’s copy (ADR 0087, Fork).
made_for no string The agent.asked this new agent answers, when a person asked for it (ADR 0108).
catch_up no object The room’s last lines before the agent joined, within the budget its harness gave in hello (ADR 0088, point 5). Added as it is sent to the harness; the log does not keep it.
catch_up.lines yes object[] Oldest first, the newest that fit the budget.
catch_up.lines[].seq yes number Where in the log it happened.
catch_up.lines[].at yes string When.
catch_up.lines[].kind yes "said" | "joined" | "left" | "renamed" | "archived" | "unarchived" said: a message, addressed to this harness or not. joined and left: somebody came into the room or went. renamed: somebody took a new name, or the room a new title. archived and unarchived: the room was put away or brought back.
catch_up.lines[].from yes object Who: the one who said it, came, went or took the new name; for the room’s own lines, who retitled, archived or unarchived it.
catch_up.lines[].from.id yes string Their participant id, or system.
catch_up.lines[].from.kind yes "person" | "harness" | "agent" | "system"
catch_up.lines[].from.name yes string What they go by now.
catch_up.lines[].from.role no "owner" | "member" | "guest" Their standing in this room, when they are in it (SEC-15).
catch_up.lines[].from.workspace_role no "owner" | "admin" | "member" | "guest" A person’s standing in the workspace (SEC-15): the plain form says it after the name, so a guest’s line reads as a guest’s. Absent for an agent or a harness.
catch_up.lines[].message_id no string On said: the message.
catch_up.lines[].text no string On said: the words as they read now, so an edited message reads edited; a deleted one is not a line. Cut with an ellipsis when the one line is longer than the whole budget.
catch_up.lines[].transcript no string On said: what a voice note said, as the server heard it (ADR 0054).
catch_up.lines[].files no string[] On said: the names of the files it carried.
catch_up.lines[].addressed_to no string[] On said: the agents it was for (ADR 0081, ADR 0087), so a harness can leave out a line one of its agents already took a turn on. Absent on a message from before Chips said so.
catch_up.lines[].held no true On said: the guard held it (ADR 0081), so it was for nobody.
catch_up.lines[].name no string On renamed, for a participant: the name they took.
catch_up.lines[].previous no string On renamed, for a participant: the name they went by until then.
catch_up.lines[].title no string On renamed, for the room: its new title.
catch_up.since_seq yes number Where they start: after this seq. With a message, where the turn that said the harness’s own last message in the room began (ADR 0105), else its joining; from the pull route, 0.
catch_up.truncated yes boolean Whether older lines after since_seq were left out to fit the budget.
catch_up.before yes number A cursor: GET /v1/spaces/:id/context?before= this reads what came before these lines.
catch_up.files no object[] The room’s files at their current version, newest first, the 20 newest (ADR 0099): with a message, as of it, its own files included; from the pull route, as of now. Each with a URL for this harness. Absent from a Chips before files, and when the room has none.
catch_up.files[].name yes string The file’s name, which its versions share.
catch_up.files[].version yes number Which version this is: 1 for the first, counting each change of its bytes.
catch_up.files[].attachment_id yes string The attachment that is this version: what a post names in replaces when it changes it.
catch_up.files[].sha256 yes string Lowercase hex digest of this version’s bytes.
catch_up.files[].byte_size yes number Size in bytes.
catch_up.files[].mime_type yes string Sniffed from the bytes on upload.
catch_up.files[].by yes object Who posted this version, as a line’s from says it.
catch_up.files[].by.id yes string Their participant id.
catch_up.files[].by.kind yes "person" | "harness" | "agent" | "system"
catch_up.files[].by.name yes string What they go by now.
catch_up.files[].at yes string When this version was posted.
catch_up.files[].message_id no string The message that posted this version.
catch_up.files[].width no number Pixels, for a photo or a video.
catch_up.files[].height no number Pixels, for a photo or a video.
catch_up.files[].duration_ms no number Milliseconds, for a sound or a video.
catch_up.files[].replaces no string In one name’s versions (?name=): the version this one was made from, as its post said (message.post.replaces). Absent where the post said nothing, or named no version of this file.
catch_up.files[].url no string For a harness: a signed URL for this version, bound to its token, as a message’s attachments are. Absent for a person, who fetches it by id.
catch_up.files[].url_expires_at no string When url stops working.
catch_up.spend no object What the room’s job has spent, as of the message (for one Chips held, as of its hand-over, when a new job began), against what the room allows a job (ADR 0117). With a message only; the room note says it in words. Absent from a Chips before it.
catch_up.spend.ceiling_usd yes number What the room allows a job, in US dollars: its own ceiling, or the default (3) when nobody has set one.
catch_up.spend.spent_usd yes number What the room’s runs reported costing since the job began, in US dollars, every harness’s together.
catch_up.spend.since_seq yes number Where the job began: the seq of the last thing a person did in the room, or of the last brief handed into it, whichever is later; 0 when neither has happened.
catch_up.spend.uncounted_runs yes number How many of the job’s runs reported no cost, and so count nothing.
{
"v": 1,
"type": "agent.attached",
"id": "evt_01K4ZQPX0000000000000000G3",
"ts": "2026-09-30T09:06:00.004Z",
"workspace_id": "ws_01K4ZQPX000000000000000001",
"actor": {
"kind": "person",
"id": "usr_01K4ZQPX000000000000000003"
},
"agent_id": "agt_01K4ZQPX0000000000000000A1",
"space_id": "spc_01K4ZQPX000000000000000002",
"by": "usr_01K4ZQPX000000000000000003",
"moved_from": "spc_01K4ZQPX0000000000000000S7"
}