message.post
A harness says something in a space, with any attachments.
Direction: Harness → Chips
Sent by: a person or a harness
Requires a run: no
Schema: message.post.json
Fields
Section titled “Fields”Every event also carries the envelope.
| Field | Required | Type | Description |
|---|---|---|---|
v |
yes | 1 |
Protocol major version. |
type |
yes | "message.post" |
|
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. |
text |
yes | string |
Markdown, with mentions. |
attachments |
no | object[] | Photos, video, voice notes, files, as the upload described them. |
attachments[].attachment_id |
yes | string |
A attachment identifier: att_ followed by a ULID. |
attachments[].filename |
yes | string |
The name to show. Never trusted for its type. |
attachments[].mime_type |
yes | string |
Sniffed from the bytes on upload, not taken from the client. |
attachments[].byte_size |
yes | number |
Size in bytes. |
attachments[].sha256 |
yes | string |
Lowercase hex digest. The store is content-addressed. |
attachments[].width |
no | number |
Pixels, for images and video. |
attachments[].height |
no | number |
Pixels, for images and video. |
attachments[].duration_ms |
no | number |
Milliseconds, for audio and video. |
attachments[].transcript |
no | string |
What was said, for a voice note the server transcribed when it arrived (ADR 0054). Machine-heard: the person’s words as best the server could make them out. |
attachments[].replaces |
no | string |
The version of the room’s file of this name that this one was made from (ADR 0099), from the post’s replaces. Filled in by Chips; a value the sender writes is replaced. |
upload_ids |
no | string[] |
Uploads to attach, by the id POST /v1/uploads gave. Chips fills in attachments from what it stored. |
replaces |
no | { } |
Which version of the room’s file each file here was made from (ADR 0099): an upload’s or attachment’s id, to the attachment_id of the version it changes, as context.files listed it. Each key is one of this post’s upload_ids or attachments. A post made from a version that is no longer current is refused, stale_file, saying which file and who changed it; nothing of it is taken. A version of another name, or of another room, is no version of this file: Chips leaves it out. Chips copies each onto its attachment as replaces, and does not keep the map. |
change |
no | string |
The commit the turn’s push left the room’s project at (ADR 0222): the room shows the change with this message. Chips keeps it only when the commit is on the room’s main and is this agent’s own; otherwise the message is kept without it. |
reply_to |
no | string |
The message being answered, when it is a reply: one said in the same room, or the post is refused (ADR 0219). A person’s reply to an agent’s message is for that agent, unless an @ or to says otherwise; a harness’s reply to an agent’s message is for that agent too (ADR 0081), so a harness sets it only when it means to address them. |
session_ref |
no | string |
The visit this message is for, when the sender means one of several (ADR 0040). Chips checks it names a session of this space and carries it to the harness; a harness that works by visits delivers there rather than choosing, and one that does not ignores it. |
mentions |
no | string[] |
The participants the text’s @handles name, as ids. Filled in by Chips against the space’s members; a value the sender writes is replaced. |
to |
no | "all" | string[] |
Who the sender chose, without typing an @: agent ids and people’s, or all for every agent in the space (ADR 0081, ADR 0087, ADR 0204). A harness’s id names its one agent in the space. Chips keeps only the members. People picked are who a person’s message is for besides its agents (addressed_people); no agent takes a turn for them. An @ in the text decides before it. |
heartbeat |
no | true |
The agent wrote this on its own, on its heartbeat, with nobody asking (ADR 0143): the apps mark it so. Only a harness, or one of its agents, sends it; a check with nothing to say posts nothing. |
addressed_to |
no | string[] |
The agents this message is for, and so the agents that take a turn on it (ADR 0081, ADR 0087). Filled in by Chips from the @s, to, the reply and the space; a value the sender writes is replaced. A message logged without it was for every harness in the space. |
addressed_people |
no | string[] |
Filled in by Chips on a person’s message (ADR 0204): the people it is for, those its @s name, or else those the sender picked in to. They are pushed as an @ pushes them; no agent takes a turn for them. Absent for none; a value the sender writes is replaced. |
addressed_to_all |
no | true |
Filled in by Chips when the message is for every harness in the space, whoever is there: @all, a to of all, or a person’s default of everyone (ADR 0081). That person’s next message that names nobody goes to every harness there is then, one added since included. |
held |
no | true |
Filled in by Chips when harnesses have addressed each other four times since a person last spoke there: the message is posted and shown, and addressed to nobody (ADR 0081). |
held_since |
no | string |
Written by Chips for words the agent said while in no room (ADR 0087, rule 6): when it said them. Posted here as it was attached. |
from_held |
no | string |
Written by Chips: the message.held these words were kept as. |
Example
Section titled “Example”{ "v": 1, "type": "message.post", "id": "evt_01K4ZQPX000000000000000067", "ts": "2026-09-02T14:22:03.004Z", "workspace_id": "ws_01K4ZQPX000000000000000001", "space_id": "spc_01K4ZQPX000000000000000002", "actor": { "kind": "harness", "id": "hrn_01K4ZQPX000000000000000004" }, "run_id": "run_01K4ZQPX000000000000000005", "text": "The PO is for **120 units**, delivery 19 September. Drafting the confirmation to Dana now."}