From aa924ddb88b17492954ffd42510dfe4befda5042 Mon Sep 17 00:00:00 2001 From: mintaka Date: Wed, 16 Sep 2026 20:52:23 -0400 Subject: [PATCH 1/2] docs(compass): describe the agent's real session protocol, not ACP (RIG-1329) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The in-container agent is the first-party SDK agent — `CompassAgent` wraps `Agent` and drives a typed `AgentFrame`/`AgentControl` protocol over stdio. ACP is no longer used anywhere, but the term survived in comments. The mapper comments were the costly ones: they cited `acp-event-mapper.ts` line-for-line (`:130`, `:247`, `:255`, `:378`) for behaviour this file now owns outright, pointing every reader at a file that does not exist. Proto doc-comments are fixed at the source and regenerated, never hand-edited; the generated diff is comment-only. Internal `.acp*` CSS selectors are renamed to `.session*`. Fixture identifiers and historical design records keep the term: they record what was named or decided then, and the comms fixtures are asserted by id. Co-authored-by: Matt Wilkinson --- apps/ui/src/App.tsx | 7 ++- apps/ui/src/agent-state.ts | 4 +- apps/ui/src/app.css | 24 ++++----- apps/ui/src/comms-stub.ts | 8 +-- apps/ui/src/live/adapt.ts | 8 +-- go/gen/compass/v1/comms.pb.go | 29 +++++----- .../v1/compassv1connect/comms.connect.go | 14 ++--- .../src/gen/compass/v1/comms_pb.ts | 35 ++++++------ packages/compass-agent/src/mapping.test.ts | 5 +- packages/compass-agent/src/mapping.ts | 54 +++++++------------ .../src/gen/compass/v1/comms_pb.ts | 35 ++++++------ proto/compass/v1/comms.proto | 35 ++++++------ 12 files changed, 114 insertions(+), 144 deletions(-) diff --git a/apps/ui/src/App.tsx b/apps/ui/src/App.tsx index 6a3a4c148..a5f4294a4 100644 --- a/apps/ui/src/App.tsx +++ b/apps/ui/src/App.tsx @@ -29,7 +29,7 @@ import { shortcutForAria } from "./keyboard/keymap"; // The Compass ADE shell — an Orca-inspired layout over the compass.v1 surface // (docs/specs/product/compass.md). A CSS grid: a topbar, a left agent-folder -// tree, a central Bridge (swimlane board) / agent (ACP + terminals) view, a +// tree, a central Bridge (swimlane board) / agent (session + terminals) view, a // right sidebar (fleet conversations + files/VCS/PR), and a bottom usage bar. // The board is primary; the "channel" and "agent" surfaces render as center // matches within the same shell (single Switch), reached via the store. @@ -37,9 +37,8 @@ import { shortcutForAria } from "./keyboard/keymap"; // This is the dev walking-skeleton made fully explorable: every surface reads // the in-memory stub (stub-data.ts) through one store (store.ts), so it renders // and is clickable in `vite dev` with no daemon and no Wails IPC. When the -// daemon grows the real board / agent / ACP / audit streams, the store's -// accessors swap the fixture for the generated @compass/client and the -// components stay as-is. +// daemon grows the real board / agent / session / audit streams, the store's +// accessors swap the fixture for the generated @compass/client and components stay as-is. // App is the router ROOT LAYOUT (record A1): the shell chrome (topbar, // sidebars, UsageBar) stays outside the routed region, and the `
` center diff --git a/apps/ui/src/agent-state.ts b/apps/ui/src/agent-state.ts index 36f788869..341606f1a 100644 --- a/apps/ui/src/agent-state.ts +++ b/apps/ui/src/agent-state.ts @@ -12,8 +12,8 @@ import type { AgentState } from "./stub-data"; * set, the projection falls back to the pure enum mapping. */ export interface AgentStreamRefinement { - /** An ACP permission / `ask` request is open on the stream — the agent has - * asked for input. Refines `WORKING` → `waiting` (Matt's "ask tool" state). */ + /** An agent permission / `ask` request is open on the stream — the agent has + * asked for input. Refines `WORKING` → `waiting`. */ awaitingInput?: boolean; /** The agent completed a turn and no human has opened its view yet. Refines * `READY` → `done` (emerald check, deliberately not idle grey). */ diff --git a/apps/ui/src/app.css b/apps/ui/src/app.css index 6a887d2e2..72ecf8e78 100644 --- a/apps/ui/src/app.css +++ b/apps/ui/src/app.css @@ -1,6 +1,6 @@ /* Compass ADE — dev UI styling. Dark, dense, board-first. An Orca-inspired * shell: a left folder tree of agents, a central Bridge (swimlane board) or - * agent (ACP + terminals) view, and a right sidebar carrying the fleet + * agent (session + terminals) view, and a right sidebar carrying the fleet * conversations (Supervisor · Status) above the issue files/VCS/PR * tabs, plus a bottom usage bar. All read one store. */ @@ -761,7 +761,7 @@ color: var(--cx-error); } -/* ── Agent view: ACP conversation + terminals ──────────────────────────── */ +/* ── Agent view: session conversation + terminals ───────────────────────── */ .agent-view { display: grid; @@ -915,8 +915,8 @@ padding: 1px 4px; } -/* ACP conversation column. */ -.acp { +/* Session conversation column. */ +.session { display: flex; flex-direction: column; min-height: 0; @@ -924,7 +924,7 @@ overflow: hidden; } -.acp-stream { +.session-stream { flex: 1; overflow-y: auto; padding: 14px; @@ -1283,7 +1283,7 @@ } /* The prompt composer (non-functional in the mockup). */ -.acp-composer { +.session-composer { flex: none; border-top: 1px solid var(--cx-border); padding: 10px 12px; @@ -1292,7 +1292,7 @@ align-items: flex-end; } -.acp-composer .field { +.session-composer .field { flex: 1; background: var(--cx-bg-panel); border: 1px solid var(--cx-border); @@ -1302,7 +1302,7 @@ font-size: 12px; } -.acp-composer .send { +.session-composer .send { background: var(--cx-accent); border: none; border-radius: var(--cx-radius-sm); @@ -2362,14 +2362,14 @@ /* Fleet panes host a full-height flex conversation, not a scrolling document — * the counterpart of .r-pane { overflow-y: auto }. The border-right suppression - * mirrors the dock's own .acp override against .acp's base border + * mirrors the dock's own session override against the session base border * (dock-in-sidebar D3/T1). */ .r-pane.fleet { display: flex; overflow: hidden; } -.r-pane.fleet .acp { +.r-pane.fleet .session { flex: 1; min-height: 0; border-right: none; @@ -2716,7 +2716,7 @@ overflow: hidden; } -.av-pane-body .acp { +.av-pane-body .session { flex: 1; min-height: 0; border-right: none; @@ -3246,7 +3246,7 @@ font-size: 11px; } -/* Conversation messages reuse the .msg family from the ACP view (role coloring, +/* Conversation messages reuse the .msg family from the session view (role coloring, * head layout). Channel-specific bits below. */ .msg-text { white-space: pre-wrap; diff --git a/apps/ui/src/comms-stub.ts b/apps/ui/src/comms-stub.ts index 42e8415b5..745ede5f0 100644 --- a/apps/ui/src/comms-stub.ts +++ b/apps/ui/src/comms-stub.ts @@ -35,8 +35,8 @@ export interface ChannelGroup { } /** A channel's kind (comms.proto ChannelKind). A plain channel is the default; - * DMs are direct conversations. An agent's ACP surface is NOT a channel — it is - * the agent workspace (the session observation panel), a separate surface. */ + * DMs are direct conversations. An agent's session observation surface is not a + * channel — it is a separate workspace panel. */ export type ChannelKind = "channel" | "dm" | "group_dm"; /** Per-channel membership state — the still-in-design join/subscribe model @@ -197,8 +197,8 @@ export function isQuestionAnswered(q: AskQuestion): boolean { /** A durable content block inside a channel message. The comms model * narrows the proto's MessageBlock oneof to the two durable conversation kinds: * `text` (settled markdown, may carry @-mentions) and `ask` (an inline async - * question). The rich ACP blocks (thought/tool_call/plan/diff) are NOT part of - * the conversation — they render in the session observation panel. */ + * question). Rich execution blocks (thought/tool_call/plan/diff) are not part of + * the conversation — they render in the session observation panel. */ export type ConvBlock = | { kind: "text"; text: string } | { kind: "ask"; ask: Ask }; diff --git a/apps/ui/src/live/adapt.ts b/apps/ui/src/live/adapt.ts index 05d799856..ca4c82028 100644 --- a/apps/ui/src/live/adapt.ts +++ b/apps/ui/src/live/adapt.ts @@ -263,10 +263,10 @@ export function adaptAsk(w: WireAsk): Ask { /** Map a wire MessageBlock's oneof to a durable domain block, or `undefined` for * any other/unset case. The domain narrows the proto oneof to the two DURABLE - * conversation kinds (comms-stub.ts:143-147): the rich ACP blocks - * (thought/tool_call/plan/diff) are execution trace that renders in the session - * observation panel, not the conversation, so a non-durable case is DROPPED — - * not mapped to a placeholder (which would render as a phantom message body) + * conversation kinds (comms-stub.ts:143-147): rich execution blocks + * (thought/tool_call/plan/diff) are session trace rendered in the observation + * panel, not conversation content, so a non-durable case is DROPPED — not mapped + * to a placeholder (which would render a phantom message body) * and not thrown on (which would blank the whole channel over one block). */ function adaptBlock(w: WireMessage["blocks"][number]): ConvBlock | undefined { switch (w.block.case) { diff --git a/go/gen/compass/v1/comms.pb.go b/go/gen/compass/v1/comms.pb.go index f0a4d2dff..8aedcd0cb 100644 --- a/go/gen/compass/v1/comms.pb.go +++ b/go/gen/compass/v1/comms.pb.go @@ -3,7 +3,7 @@ // agents are first-class accounts in a management hierarchy. Channels nest in // channel groups, so a user's space (e.g. group "matt" → channel // "coordination", the path "matt.coordination") carries group-level -// permissions. An agent's interactive surface — its ACP UI: the conversation +// permissions. An agent's interactive surface: the session conversation // (text and structured asks) plus terminal and file panes — renders in the // agent's channel; the AgentWorkspace is the observation pane over that session // (D5), its access a projection of channel membership. All @@ -942,16 +942,14 @@ func (x *PinnedEntry) GetPinnedByAccountId() string { return "" } -// An agent's interactive surface: the observation pane for one agent account — -// the ACP conversation plus the terminal and file panes the ADE hosts. Demoted -// to the observation pane (D5, fork f): no longer a message container, and its -// access is a projection of the agent's channel membership rather than a -// separate participant ACL. +// An agent's interactive surface: the session observation pane for one agent +// account, including the conversation, terminal, and file panes the ADE hosts. +// Demoted to the observation pane (D5, fork f); access projects channel membership. type AgentWorkspace struct { state protoimpl.MessageState `protogen:"open.v1"` // Server-assigned stable id. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // The agent account whose ACP session this surface renders. + // The agent account whose session this surface renders. AgentAccountId string `protobuf:"bytes,2,opt,name=agent_account_id,json=agentAccountId,proto3" json:"agent_account_id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -1096,8 +1094,8 @@ func (x *Topic) GetArchived() bool { } // A message in a channel — the persisted unit of the comms layer, held in the -// Server store of record (D12). An agent's ACP turn is a channel message whose -// blocks stream in and update as the session runs (see MessageUpdated). +// Server store of record (D12). An agent turn is a channel message whose blocks +// stream in and update as the session runs (see MessageUpdated). type Message struct { state protoimpl.MessageState `protogen:"open.v1"` // Server-assigned stable id. @@ -1111,7 +1109,7 @@ type Message struct { // The posting account (a user or an agent). AuthorAccountId string `protobuf:"bytes,3,opt,name=author_account_id,json=authorAccountId,proto3" json:"author_account_id,omitempty"` AtUnixMs int64 `protobuf:"varint,4,opt,name=at_unix_ms,json=atUnixMs,proto3" json:"at_unix_ms,omitempty"` - // Ordered content; mirrors ACP session/update blocks (D5). + // Ordered content; mirrors session-update blocks from the SDK (D5). Blocks []*MessageBlock `protobuf:"bytes,5,rep,name=blocks,proto3" json:"blocks,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -1183,10 +1181,9 @@ func (x *Message) GetBlocks() []*MessageBlock { } // One content block in a message: the durable conversation the comms layer -// persists. `text` is settled markdown; `ask` is a structured question the ACP -// surface needs (D5). The execution trace (thought / tool calls / plans / -// diffs) is delivered as opaque OMP-native session data on a dedicated stream, -// not as comms blocks. +// persists. `text` is settled markdown; `ask` is a structured question the +// session surface needs (D5). The execution trace (thought / tool calls / plans / +// diffs) is delivered as opaque OMP-native session data on a dedicated stream. type MessageBlock struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Block: @@ -3884,8 +3881,8 @@ func (x *UpdatePinnedBoardResponse) GetChannel() *Channel { type OpenAgentWorkspaceRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - // The agent account to open the workspace (ACP surface) for. A `@handle`; the - // server resolves it to an account id; unknown → NOT_FOUND. + // The agent account to open the workspace (session surface) for. A `@handle`; + // the server resolves it to an account id; unknown → NOT_FOUND. AgentHandle string `protobuf:"bytes,1,opt,name=agent_handle,json=agentHandle,proto3" json:"agent_handle,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache diff --git a/go/gen/compass/v1/compassv1connect/comms.connect.go b/go/gen/compass/v1/compassv1connect/comms.connect.go index 586f47b2e..f3bf5b08b 100644 --- a/go/gen/compass/v1/compassv1connect/comms.connect.go +++ b/go/gen/compass/v1/compassv1connect/comms.connect.go @@ -3,7 +3,7 @@ // agents are first-class accounts in a management hierarchy. Channels nest in // channel groups, so a user's space (e.g. group "matt" → channel // "coordination", the path "matt.coordination") carries group-level -// permissions. An agent's interactive surface — its ACP UI: the conversation +// permissions. An agent's interactive surface: the session conversation // (text and structured asks) plus terminal and file panes — renders in the // agent's channel; the AgentWorkspace is the observation pane over that session // (D5), its access a projection of channel membership. All @@ -152,9 +152,9 @@ type CommsServiceClient interface { // emits AccountChanged; surfaces re-derive the tree from the changed // parent_agent_id with no surface-specific plumbing. ReparentAgent(context.Context, *connect.Request[v1.ReparentAgentRequest]) (*connect.Response[v1.ReparentAgentResponse], error) - // Open (or fetch) the caller's agent workspace for an agent — its ACP surface - // (D5). Idempotent: created on first open, returned after. Authorized: the - // caller must be a member of the agent's channel. + // Open (or fetch) the caller's agent workspace for an agent — its session + // observation surface (D5). Idempotent: created on first open, returned after. + // Authorized: the caller must be a member of the agent's channel. OpenAgentWorkspace(context.Context, *connect.Request[v1.OpenAgentWorkspaceRequest]) (*connect.Response[v1.OpenAgentWorkspaceResponse], error) // Page a channel's message history, newest-first. The channel is one the // caller may see. @@ -507,9 +507,9 @@ type CommsServiceHandler interface { // emits AccountChanged; surfaces re-derive the tree from the changed // parent_agent_id with no surface-specific plumbing. ReparentAgent(context.Context, *connect.Request[v1.ReparentAgentRequest]) (*connect.Response[v1.ReparentAgentResponse], error) - // Open (or fetch) the caller's agent workspace for an agent — its ACP surface - // (D5). Idempotent: created on first open, returned after. Authorized: the - // caller must be a member of the agent's channel. + // Open (or fetch) the caller's agent workspace for an agent — its session + // observation surface (D5). Idempotent: created on first open, returned after. + // Authorized: the caller must be a member of the agent's channel. OpenAgentWorkspace(context.Context, *connect.Request[v1.OpenAgentWorkspaceRequest]) (*connect.Response[v1.OpenAgentWorkspaceResponse], error) // Page a channel's message history, newest-first. The channel is one the // caller may see. diff --git a/packages/compass-agent/src/gen/compass/v1/comms_pb.ts b/packages/compass-agent/src/gen/compass/v1/comms_pb.ts index 94567dca9..9360c6e49 100644 --- a/packages/compass-agent/src/gen/compass/v1/comms_pb.ts +++ b/packages/compass-agent/src/gen/compass/v1/comms_pb.ts @@ -3,7 +3,7 @@ // agents are first-class accounts in a management hierarchy. Channels nest in // channel groups, so a user's space (e.g. group "matt" → channel // "coordination", the path "matt.coordination") carries group-level -// permissions. An agent's interactive surface — its ACP UI: the conversation +// permissions. An agent's interactive surface: the session conversation // (text and structured asks) plus terminal and file panes — renders in the // agent's channel; the AgentWorkspace is the observation pane over that session // (D5), its access a projection of channel membership. All @@ -364,11 +364,9 @@ export const PinnedEntrySchema: GenMessage = /*@__PURE__*/ messageDesc(file_compass_v1_comms, 6); /** - * An agent's interactive surface: the observation pane for one agent account — - * the ACP conversation plus the terminal and file panes the ADE hosts. Demoted - * to the observation pane (D5, fork f): no longer a message container, and its - * access is a projection of the agent's channel membership rather than a - * separate participant ACL. + * An agent's interactive surface: the session observation pane for one agent + * account, including the conversation, terminal, and file panes the ADE hosts. + * Demoted to the observation pane (D5, fork f); access projects channel membership. * * @generated from message compass.v1.AgentWorkspace */ @@ -381,7 +379,7 @@ export type AgentWorkspace = Message$1<"compass.v1.AgentWorkspace"> & { id: string; /** - * The agent account whose ACP session this surface renders. + * The agent account whose session this surface renders. * * @generated from field: string agent_account_id = 2; */ @@ -455,8 +453,8 @@ export const TopicSchema: GenMessage = /*@__PURE__*/ /** * A message in a channel — the persisted unit of the comms layer, held in the - * Server store of record (D12). An agent's ACP turn is a channel message whose - * blocks stream in and update as the session runs (see MessageUpdated). + * Server store of record (D12). An agent turn is a channel message whose blocks + * stream in and update as the session runs (see MessageUpdated). * * @generated from message compass.v1.Message */ @@ -492,7 +490,7 @@ export type Message = Message$1<"compass.v1.Message"> & { atUnixMs: bigint; /** - * Ordered content; mirrors ACP session/update blocks (D5). + * Ordered content; mirrors session-update blocks from the SDK (D5). * * @generated from field: repeated compass.v1.MessageBlock blocks = 5; */ @@ -508,10 +506,9 @@ export const MessageSchema: GenMessage = /*@__PURE__*/ /** * One content block in a message: the durable conversation the comms layer - * persists. `text` is settled markdown; `ask` is a structured question the ACP - * surface needs (D5). The execution trace (thought / tool calls / plans / - * diffs) is delivered as opaque OMP-native session data on a dedicated stream, - * not as comms blocks. + * persists. `text` is settled markdown; `ask` is a structured question the + * session surface needs (D5). The execution trace (thought / tool calls / plans / + * diffs) is delivered as opaque OMP-native session data on a dedicated stream. * * @generated from message compass.v1.MessageBlock */ @@ -1829,8 +1826,8 @@ export const UpdatePinnedBoardResponseSchema: GenMessage & { /** - * The agent account to open the workspace (ACP surface) for. A `@handle`; the - * server resolves it to an account id; unknown → NOT_FOUND. + * The agent account to open the workspace (session surface) for. A `@handle`; + * the server resolves it to an account id; unknown → NOT_FOUND. * * @generated from field: string agent_handle = 1; */ @@ -2616,9 +2613,9 @@ export const CommsService: GenService<{ output: typeof ReparentAgentResponseSchema; }, /** - * Open (or fetch) the caller's agent workspace for an agent — its ACP surface - * (D5). Idempotent: created on first open, returned after. Authorized: the - * caller must be a member of the agent's channel. + * Open (or fetch) the caller's agent workspace for an agent — its session + * observation surface (D5). Idempotent: created on first open, returned after. + * Authorized: the caller must be a member of the agent's channel. * * @generated from rpc compass.v1.CommsService.OpenAgentWorkspace */ diff --git a/packages/compass-agent/src/mapping.test.ts b/packages/compass-agent/src/mapping.test.ts index 74279c79b..dce4e0490 100644 --- a/packages/compass-agent/src/mapping.test.ts +++ b/packages/compass-agent/src/mapping.test.ts @@ -564,9 +564,8 @@ describe("EventMapper — tool call title is intent-or-toolName", () => { }); describe("EventMapper — tool result output extraction", () => { - // The `output` field mirrors the ACP mapper's extractReadableText: a bare - // string trimmed, an Error's message, a `text`/`errorMessage`/`message` - // property, and a hard cap at 4000 chars (adding "…"). + // The `output` field renders a bare string trimmed, an Error's message, a + // `text`/`errorMessage`/`message` property, capped at 4000 chars with "…". function outputOf(result: unknown): string { const ev = soleTyped( mapper().map({ diff --git a/packages/compass-agent/src/mapping.ts b/packages/compass-agent/src/mapping.ts index 440748005..decc3153d 100644 --- a/packages/compass-agent/src/mapping.ts +++ b/packages/compass-agent/src/mapping.ts @@ -57,9 +57,8 @@ export type MapOutput = OutboundFrame | UnmappedEvent; // asserted exactly. export type Clock = () => number; -// Cap on emitted tool-call `output` text, mirroring the ACP mapper's ACP_TEXT_LIMIT -// (acp-event-mapper.ts:130) so a pathological tool result does not put an unbounded -// string on the wire. The session renderer shows a disclosure, not the full blob. +// Cap emitted tool-call output at 4,000 characters so pathological results do +// not put an unbounded string on the wire. The renderer shows a disclosure. const OUTPUT_TEXT_LIMIT = 4_000; // Maps the agent's session-event stream to compass.v1 frames. Stateful on the @@ -135,10 +134,8 @@ export class EventMapper { }), }), ]; - // The `todo` tool's result is the authoritative plan snapshot — emit a - // SessionPlan alongside the tool-call settle (mirrors the ACP mapper's - // mapTodoResultToPlanUpdate, acp-event-mapper.ts:378). A failed todo or - // an unparseable result yields no plan (the extractor returns undefined). + // A successful `todo` result is the authoritative plan snapshot. Emit a + // SessionPlan alongside the settled tool call; invalid results emit none. if (event.toolName === "todo" && !event.isError) { const entries = extractPlanEntries(event.result); if (entries !== undefined) { @@ -153,9 +150,7 @@ export class EventMapper { return out; } case "todo_reminder": - // A periodic plan nudge carrying the current todos — emit the plan - // snapshot (mirrors the ACP mapper's todo_reminder arm, - // acp-event-mapper.ts:247). The todos are already typed on the event. + // A periodic SDK reminder carries current todos; emit the plan snapshot. return [ this.#sessionEvent({ case: "plan", @@ -170,8 +165,7 @@ export class EventMapper { }), ]; case "todo_auto_clear": - // The todo list was cleared → an empty plan (mirrors - // acp-event-mapper.ts:255). + // The SDK cleared the todo list; emit an empty plan. return [ this.#sessionEvent({ case: "plan", @@ -341,9 +335,8 @@ export class EventMapper { } // ── Runtime-narrowed readers (never an inline cast) ────────────────────────── -// The SDK types tool `args`/`result`/`partialResult` as `any`; these read them through the -// `isRecord` guard so every access is on a known-object value. Mirrors the ACP mapper's -// readers but compass-native (its own target types), not an ACP dependency. +// SDK tool payloads are narrowed through `isRecord` before property access. +// The readers emit Compass-native target types. // The one narrowing primitive: is `value` a non-null object we can index by key? // Every reader below narrows through this before any property read, so there is @@ -358,10 +351,8 @@ function readString(value: unknown, key: string): string | undefined { return typeof prop === "string" ? prop : undefined; } -// A best-effort human-readable rendering of a tool result for the `output` field, mirroring -// acp-event-mapper.ts extractReadableText: a bare string, an Error's message, a -// `text`/`errorMessage`/`message` property, else the JSON. Capped at OUTPUT_TEXT_LIMIT; -// undefined when nothing readable is present (the caller defaults to ""). +// Render a tool result for `output`: strings, Error messages, known text fields, +// or JSON. Cap at OUTPUT_TEXT_LIMIT; undefined lets the caller default to "". function extractReadableText(value: unknown): string | undefined { if (typeof value === "string") return normalizeText(value); if (value instanceof Error) return normalizeText(value.message); @@ -394,10 +385,8 @@ function safeJsonStringify(value: unknown): string | undefined { } } -// Extract file diffs from a tool result, mirroring acp-event-mapper.ts -// extractDiffToolCallContent: a `details.perFileResults[]` array or the single `details`, -// each carrying `path` + `oldText`/`newText`. A creation has no `oldText`. Entries flagged -// `isError` or lacking a path / any text are skipped. +// Extract file diffs from a tool result's `details.perFileResults[]` or `details`. +// Skip errors and entries lacking a path or any text. function extractDiffs(result: unknown): SessionFileDiff[] { if (!isRecord(result)) return []; const details = result.details; @@ -427,10 +416,8 @@ function buildDiff(entry: unknown): SessionFileDiff | undefined { }); } -// Extract plan entries from the `todo` tool result, mirroring acp-event-mapper.ts -// extractTodoPhases/extractTodoEntries: a `details.phases[].tasks[]` shape, each task a -// `{ content, status }`. Returns undefined when not a todo snapshot, an empty array when -// present but with no valid tasks. +// Extract plan entries from `details.phases[].tasks[]`. Return undefined when the +// result is not a todo snapshot, or an empty array when it has no valid tasks. function extractPlanEntries(result: unknown): AgentPlanEntry[] | undefined { if (!isRecord(result)) return undefined; const details = result.details; @@ -457,9 +444,8 @@ function extractPlanEntries(result: unknown): AgentPlanEntry[] | undefined { return entries; } -// Map an SDK todo status (string literal) to the compass plan-entry status enum, -// mirroring acp-event-mapper.ts:367 todoStatusMap: "abandoned" folds to COMPLETED -// (the plan enum has no abandoned state), an unknown/absent status → PENDING. +// Map an SDK todo status to the Compass plan-entry enum. Unknown or absent status +// becomes PENDING; the enum has no separate abandoned state. function planStatus(status: unknown): AgentPlanEntryStatus { switch (status) { case "in_progress": @@ -472,9 +458,8 @@ function planStatus(status: unknown): AgentPlanEntryStatus { } } -// A display title for a tool call: the caller-supplied `intent` when present (the agent's own -// label), else the tool name. The ACP mapper builds elaborate titles; the compass session -// renderer shows a plain title, so intent-or-name is the faithful-but-simpler rendering. +// Display the caller's `intent` when present, otherwise the tool name. The +// session renderer uses this plain title rather than elaborating tool arguments. function toolTitle( toolName: string, args: unknown, @@ -482,8 +467,7 @@ function toolTitle( ): string { const trimmed = intent?.trim(); if (trimmed !== undefined && trimmed.length > 0) return trimmed; - // `args` is accepted for parity with the ACP title builder's signature and to - // leave a grounded seam for richer titles; the dumb emitter does not read it. + // `args` remains part of the mapper signature for future richer titles. void args; return toolName; } diff --git a/packages/compass-client/src/gen/compass/v1/comms_pb.ts b/packages/compass-client/src/gen/compass/v1/comms_pb.ts index 94567dca9..9360c6e49 100644 --- a/packages/compass-client/src/gen/compass/v1/comms_pb.ts +++ b/packages/compass-client/src/gen/compass/v1/comms_pb.ts @@ -3,7 +3,7 @@ // agents are first-class accounts in a management hierarchy. Channels nest in // channel groups, so a user's space (e.g. group "matt" → channel // "coordination", the path "matt.coordination") carries group-level -// permissions. An agent's interactive surface — its ACP UI: the conversation +// permissions. An agent's interactive surface: the session conversation // (text and structured asks) plus terminal and file panes — renders in the // agent's channel; the AgentWorkspace is the observation pane over that session // (D5), its access a projection of channel membership. All @@ -364,11 +364,9 @@ export const PinnedEntrySchema: GenMessage = /*@__PURE__*/ messageDesc(file_compass_v1_comms, 6); /** - * An agent's interactive surface: the observation pane for one agent account — - * the ACP conversation plus the terminal and file panes the ADE hosts. Demoted - * to the observation pane (D5, fork f): no longer a message container, and its - * access is a projection of the agent's channel membership rather than a - * separate participant ACL. + * An agent's interactive surface: the session observation pane for one agent + * account, including the conversation, terminal, and file panes the ADE hosts. + * Demoted to the observation pane (D5, fork f); access projects channel membership. * * @generated from message compass.v1.AgentWorkspace */ @@ -381,7 +379,7 @@ export type AgentWorkspace = Message$1<"compass.v1.AgentWorkspace"> & { id: string; /** - * The agent account whose ACP session this surface renders. + * The agent account whose session this surface renders. * * @generated from field: string agent_account_id = 2; */ @@ -455,8 +453,8 @@ export const TopicSchema: GenMessage = /*@__PURE__*/ /** * A message in a channel — the persisted unit of the comms layer, held in the - * Server store of record (D12). An agent's ACP turn is a channel message whose - * blocks stream in and update as the session runs (see MessageUpdated). + * Server store of record (D12). An agent turn is a channel message whose blocks + * stream in and update as the session runs (see MessageUpdated). * * @generated from message compass.v1.Message */ @@ -492,7 +490,7 @@ export type Message = Message$1<"compass.v1.Message"> & { atUnixMs: bigint; /** - * Ordered content; mirrors ACP session/update blocks (D5). + * Ordered content; mirrors session-update blocks from the SDK (D5). * * @generated from field: repeated compass.v1.MessageBlock blocks = 5; */ @@ -508,10 +506,9 @@ export const MessageSchema: GenMessage = /*@__PURE__*/ /** * One content block in a message: the durable conversation the comms layer - * persists. `text` is settled markdown; `ask` is a structured question the ACP - * surface needs (D5). The execution trace (thought / tool calls / plans / - * diffs) is delivered as opaque OMP-native session data on a dedicated stream, - * not as comms blocks. + * persists. `text` is settled markdown; `ask` is a structured question the + * session surface needs (D5). The execution trace (thought / tool calls / plans / + * diffs) is delivered as opaque OMP-native session data on a dedicated stream. * * @generated from message compass.v1.MessageBlock */ @@ -1829,8 +1826,8 @@ export const UpdatePinnedBoardResponseSchema: GenMessage & { /** - * The agent account to open the workspace (ACP surface) for. A `@handle`; the - * server resolves it to an account id; unknown → NOT_FOUND. + * The agent account to open the workspace (session surface) for. A `@handle`; + * the server resolves it to an account id; unknown → NOT_FOUND. * * @generated from field: string agent_handle = 1; */ @@ -2616,9 +2613,9 @@ export const CommsService: GenService<{ output: typeof ReparentAgentResponseSchema; }, /** - * Open (or fetch) the caller's agent workspace for an agent — its ACP surface - * (D5). Idempotent: created on first open, returned after. Authorized: the - * caller must be a member of the agent's channel. + * Open (or fetch) the caller's agent workspace for an agent — its session + * observation surface (D5). Idempotent: created on first open, returned after. + * Authorized: the caller must be a member of the agent's channel. * * @generated from rpc compass.v1.CommsService.OpenAgentWorkspace */ diff --git a/proto/compass/v1/comms.proto b/proto/compass/v1/comms.proto index e9d57c5d8..16d83a754 100644 --- a/proto/compass/v1/comms.proto +++ b/proto/compass/v1/comms.proto @@ -3,7 +3,7 @@ // agents are first-class accounts in a management hierarchy. Channels nest in // channel groups, so a user's space (e.g. group "matt" → channel // "coordination", the path "matt.coordination") carries group-level -// permissions. An agent's interactive surface — its ACP UI: the conversation +// permissions. An agent's interactive surface: the session conversation // (text and structured asks) plus terminal and file panes — renders in the // agent's channel; the AgentWorkspace is the observation pane over that session // (D5), its access a projection of channel membership. All @@ -81,9 +81,9 @@ service CommsService { // parent_agent_id with no surface-specific plumbing. rpc ReparentAgent(ReparentAgentRequest) returns (ReparentAgentResponse); - // Open (or fetch) the caller's agent workspace for an agent — its ACP surface - // (D5). Idempotent: created on first open, returned after. Authorized: the - // caller must be a member of the agent's channel. + // Open (or fetch) the caller's agent workspace for an agent — its session + // observation surface (D5). Idempotent: created on first open, returned after. + // Authorized: the caller must be a member of the agent's channel. rpc OpenAgentWorkspace(OpenAgentWorkspaceRequest) returns (OpenAgentWorkspaceResponse); // Page a channel's message history, newest-first. The channel is one the @@ -296,15 +296,13 @@ enum ChannelKind { // ── Agent workspace (D5) ───────────────────────────────────────────────────── -// An agent's interactive surface: the observation pane for one agent account — -// the ACP conversation plus the terminal and file panes the ADE hosts. Demoted -// to the observation pane (D5, fork f): no longer a message container, and its -// access is a projection of the agent's channel membership rather than a -// separate participant ACL. +// An agent's interactive surface: the session observation pane for one agent +// account, including the conversation, terminal, and file panes the ADE hosts. +// Demoted to the observation pane (D5, fork f); access projects channel membership. message AgentWorkspace { // Server-assigned stable id. string id = 1; - // The agent account whose ACP session this surface renders. + // The agent account whose session this surface renders. string agent_account_id = 2; } @@ -332,8 +330,8 @@ message Topic { // ── Messages + content blocks (D5) ───────────────────────────────────────── // A message in a channel — the persisted unit of the comms layer, held in the -// Server store of record (D12). An agent's ACP turn is a channel message whose -// blocks stream in and update as the session runs (see MessageUpdated). +// Server store of record (D12). An agent turn is a channel message whose blocks +// stream in and update as the session runs (see MessageUpdated). message Message { // Server-assigned stable id. string id = 1; @@ -346,15 +344,14 @@ message Message { // The posting account (a user or an agent). string author_account_id = 3; int64 at_unix_ms = 4; - // Ordered content; mirrors ACP session/update blocks (D5). + // Ordered content; mirrors session-update blocks from the SDK (D5). repeated MessageBlock blocks = 5; } // One content block in a message: the durable conversation the comms layer -// persists. `text` is settled markdown; `ask` is a structured question the ACP -// surface needs (D5). The execution trace (thought / tool calls / plans / -// diffs) is delivered as opaque OMP-native session data on a dedicated stream, -// not as comms blocks. +// persists. `text` is settled markdown; `ask` is a structured question the +// session surface needs (D5). The execution trace (thought / tool calls / plans / +// diffs) is delivered as opaque OMP-native session data on a dedicated stream. message MessageBlock { oneof block { // Settled user-facing / assistant text (markdown). @@ -800,8 +797,8 @@ message UpdatePinnedBoardResponse { } message OpenAgentWorkspaceRequest { - // The agent account to open the workspace (ACP surface) for. A `@handle`; the - // server resolves it to an account id; unknown → NOT_FOUND. + // The agent account to open the workspace (session surface) for. A `@handle`; + // the server resolves it to an account id; unknown → NOT_FOUND. string agent_handle = 1; } From 41b0d47af6186fdcc5d43fda485f515fcbab89cb Mon Sep 17 00:00:00 2001 From: mintaka Date: Wed, 16 Sep 2026 22:37:42 -0400 Subject: [PATCH 2/2] docs(compass): restore contract clauses the terminology sweep dropped MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review found the rewrite deleted normative statements that carried no ACP terminology, so a purge narrowed the documented contract in four checked-in client surfaces. Restored: AgentWorkspace is "no longer a message container" and its access is a projection of channel membership "rather than a separate participant ACL"; the execution trace goes on a dedicated stream "not as comms blocks", which is the prohibition a producer reads. Two comments had become wrong rather than merely shorter. `planStatus` no longer said "abandoned" folds to COMPLETED, which a reader would infer as PENDING from the surrounding text — the opposite of the code. The readers' header lost the reason they exist (the SDK types tool payloads as `any`) and restated what the next comment already said. Also: an em-dash lost its pair in the file header, `adapt.ts` kept a line citation pointing at unrelated code (now a symbol reference), and a CSS comment named a "session view" that does not exist. Co-authored-by: Matt Wilkinson --- apps/ui/src/App.tsx | 3 ++- apps/ui/src/agent-state.ts | 2 +- apps/ui/src/app.css | 4 ++-- apps/ui/src/comms-stub.ts | 4 ++-- apps/ui/src/live/adapt.ts | 10 ++++----- go/gen/compass/v1/comms.pb.go | 21 +++++++++++-------- .../v1/compassv1connect/comms.connect.go | 12 +++++------ .../src/gen/compass/v1/comms_pb.ts | 21 +++++++++++-------- packages/compass-agent/src/mapping.ts | 8 +++---- .../src/gen/compass/v1/comms_pb.ts | 21 +++++++++++-------- proto/compass/v1/comms.proto | 21 +++++++++++-------- 11 files changed, 70 insertions(+), 57 deletions(-) diff --git a/apps/ui/src/App.tsx b/apps/ui/src/App.tsx index a5f4294a4..524fd8ae2 100644 --- a/apps/ui/src/App.tsx +++ b/apps/ui/src/App.tsx @@ -38,7 +38,8 @@ import { shortcutForAria } from "./keyboard/keymap"; // the in-memory stub (stub-data.ts) through one store (store.ts), so it renders // and is clickable in `vite dev` with no daemon and no Wails IPC. When the // daemon grows the real board / agent / session / audit streams, the store's -// accessors swap the fixture for the generated @compass/client and components stay as-is. +// accessors swap the fixture for the generated @compass/client and the +// components stay as-is. // App is the router ROOT LAYOUT (record A1): the shell chrome (topbar, // sidebars, UsageBar) stays outside the routed region, and the `
` center diff --git a/apps/ui/src/agent-state.ts b/apps/ui/src/agent-state.ts index 341606f1a..278294739 100644 --- a/apps/ui/src/agent-state.ts +++ b/apps/ui/src/agent-state.ts @@ -13,7 +13,7 @@ import type { AgentState } from "./stub-data"; */ export interface AgentStreamRefinement { /** An agent permission / `ask` request is open on the stream — the agent has - * asked for input. Refines `WORKING` → `waiting`. */ + * asked for input. Refines `WORKING` → `waiting`. */ awaitingInput?: boolean; /** The agent completed a turn and no human has opened its view yet. Refines * `READY` → `done` (emerald check, deliberately not idle grey). */ diff --git a/apps/ui/src/app.css b/apps/ui/src/app.css index 72ecf8e78..df580a032 100644 --- a/apps/ui/src/app.css +++ b/apps/ui/src/app.css @@ -3246,8 +3246,8 @@ font-size: 11px; } -/* Conversation messages reuse the .msg family from the session view (role coloring, - * head layout). Channel-specific bits below. */ +/* Conversation messages reuse the .msg family from the agent view (role + * coloring, head layout). Channel-specific bits below. */ .msg-text { white-space: pre-wrap; overflow-wrap: anywhere; diff --git a/apps/ui/src/comms-stub.ts b/apps/ui/src/comms-stub.ts index 745ede5f0..0f3899844 100644 --- a/apps/ui/src/comms-stub.ts +++ b/apps/ui/src/comms-stub.ts @@ -197,8 +197,8 @@ export function isQuestionAnswered(q: AskQuestion): boolean { /** A durable content block inside a channel message. The comms model * narrows the proto's MessageBlock oneof to the two durable conversation kinds: * `text` (settled markdown, may carry @-mentions) and `ask` (an inline async - * question). Rich execution blocks (thought/tool_call/plan/diff) are not part of - * the conversation — they render in the session observation panel. */ + * question). Rich execution blocks (thought/tool_call/plan/diff) are not part + * of the conversation — they render in the session observation panel. */ export type ConvBlock = | { kind: "text"; text: string } | { kind: "ask"; ask: Ask }; diff --git a/apps/ui/src/live/adapt.ts b/apps/ui/src/live/adapt.ts index ca4c82028..572b748aa 100644 --- a/apps/ui/src/live/adapt.ts +++ b/apps/ui/src/live/adapt.ts @@ -263,11 +263,11 @@ export function adaptAsk(w: WireAsk): Ask { /** Map a wire MessageBlock's oneof to a durable domain block, or `undefined` for * any other/unset case. The domain narrows the proto oneof to the two DURABLE - * conversation kinds (comms-stub.ts:143-147): rich execution blocks - * (thought/tool_call/plan/diff) are session trace rendered in the observation - * panel, not conversation content, so a non-durable case is DROPPED — not mapped - * to a placeholder (which would render a phantom message body) - * and not thrown on (which would blank the whole channel over one block). */ + * conversation kinds (`ConvBlock` in comms-stub.ts): rich execution blocks + * (thought/tool_call/plan/diff) are session trace rendered in the observation + * panel, not conversation content, so a non-durable case is DROPPED — not + * mapped to a placeholder (which would render a phantom message body) and not + * thrown on (which would blank the whole channel over one block). */ function adaptBlock(w: WireMessage["blocks"][number]): ConvBlock | undefined { switch (w.block.case) { case "text": diff --git a/go/gen/compass/v1/comms.pb.go b/go/gen/compass/v1/comms.pb.go index 8aedcd0cb..8d7be74d8 100644 --- a/go/gen/compass/v1/comms.pb.go +++ b/go/gen/compass/v1/comms.pb.go @@ -3,12 +3,12 @@ // agents are first-class accounts in a management hierarchy. Channels nest in // channel groups, so a user's space (e.g. group "matt" → channel // "coordination", the path "matt.coordination") carries group-level -// permissions. An agent's interactive surface: the session conversation -// (text and structured asks) plus terminal and file panes — renders in the -// agent's channel; the AgentWorkspace is the observation pane over that session -// (D5), its access a projection of channel membership. All -// comms flow through this layer, so audit and search are properties of the -// substrate, not a separate pipeline (D1). +// permissions. An agent's interactive surface — the session conversation (text +// and structured asks) plus terminal and file panes — renders in the agent's +// channel; the AgentWorkspace is the observation pane over that session (D5), +// its access a projection of channel membership. All comms flow through this +// layer, so audit and search are properties of the substrate, not a separate +// pipeline (D1). // // This lives alongside compass.proto in the same owned `compass.v1` package as // an additive surface (new file, new service) that evolves the contract from a @@ -944,7 +944,9 @@ func (x *PinnedEntry) GetPinnedByAccountId() string { // An agent's interactive surface: the session observation pane for one agent // account, including the conversation, terminal, and file panes the ADE hosts. -// Demoted to the observation pane (D5, fork f); access projects channel membership. +// Demoted to the observation pane (D5, fork f): no longer a message container, +// and its access is a projection of the agent's channel membership rather than +// a separate participant ACL. type AgentWorkspace struct { state protoimpl.MessageState `protogen:"open.v1"` // Server-assigned stable id. @@ -1182,8 +1184,9 @@ func (x *Message) GetBlocks() []*MessageBlock { // One content block in a message: the durable conversation the comms layer // persists. `text` is settled markdown; `ask` is a structured question the -// session surface needs (D5). The execution trace (thought / tool calls / plans / -// diffs) is delivered as opaque OMP-native session data on a dedicated stream. +// session surface needs (D5). The execution trace (thought / tool calls / plans +// / diffs) is delivered as opaque OMP-native session data on a dedicated +// stream, not as comms blocks. type MessageBlock struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Block: diff --git a/go/gen/compass/v1/compassv1connect/comms.connect.go b/go/gen/compass/v1/compassv1connect/comms.connect.go index f3bf5b08b..7fe2acd70 100644 --- a/go/gen/compass/v1/compassv1connect/comms.connect.go +++ b/go/gen/compass/v1/compassv1connect/comms.connect.go @@ -3,12 +3,12 @@ // agents are first-class accounts in a management hierarchy. Channels nest in // channel groups, so a user's space (e.g. group "matt" → channel // "coordination", the path "matt.coordination") carries group-level -// permissions. An agent's interactive surface: the session conversation -// (text and structured asks) plus terminal and file panes — renders in the -// agent's channel; the AgentWorkspace is the observation pane over that session -// (D5), its access a projection of channel membership. All -// comms flow through this layer, so audit and search are properties of the -// substrate, not a separate pipeline (D1). +// permissions. An agent's interactive surface — the session conversation (text +// and structured asks) plus terminal and file panes — renders in the agent's +// channel; the AgentWorkspace is the observation pane over that session (D5), +// its access a projection of channel membership. All comms flow through this +// layer, so audit and search are properties of the substrate, not a separate +// pipeline (D1). // // This lives alongside compass.proto in the same owned `compass.v1` package as // an additive surface (new file, new service) that evolves the contract from a diff --git a/packages/compass-agent/src/gen/compass/v1/comms_pb.ts b/packages/compass-agent/src/gen/compass/v1/comms_pb.ts index 9360c6e49..69d7a9240 100644 --- a/packages/compass-agent/src/gen/compass/v1/comms_pb.ts +++ b/packages/compass-agent/src/gen/compass/v1/comms_pb.ts @@ -3,12 +3,12 @@ // agents are first-class accounts in a management hierarchy. Channels nest in // channel groups, so a user's space (e.g. group "matt" → channel // "coordination", the path "matt.coordination") carries group-level -// permissions. An agent's interactive surface: the session conversation -// (text and structured asks) plus terminal and file panes — renders in the -// agent's channel; the AgentWorkspace is the observation pane over that session -// (D5), its access a projection of channel membership. All -// comms flow through this layer, so audit and search are properties of the -// substrate, not a separate pipeline (D1). +// permissions. An agent's interactive surface — the session conversation (text +// and structured asks) plus terminal and file panes — renders in the agent's +// channel; the AgentWorkspace is the observation pane over that session (D5), +// its access a projection of channel membership. All comms flow through this +// layer, so audit and search are properties of the substrate, not a separate +// pipeline (D1). // // This lives alongside compass.proto in the same owned `compass.v1` package as // an additive surface (new file, new service) that evolves the contract from a @@ -366,7 +366,9 @@ export const PinnedEntrySchema: GenMessage = /*@__PURE__*/ /** * An agent's interactive surface: the session observation pane for one agent * account, including the conversation, terminal, and file panes the ADE hosts. - * Demoted to the observation pane (D5, fork f); access projects channel membership. + * Demoted to the observation pane (D5, fork f): no longer a message container, + * and its access is a projection of the agent's channel membership rather than + * a separate participant ACL. * * @generated from message compass.v1.AgentWorkspace */ @@ -507,8 +509,9 @@ export const MessageSchema: GenMessage = /*@__PURE__*/ /** * One content block in a message: the durable conversation the comms layer * persists. `text` is settled markdown; `ask` is a structured question the - * session surface needs (D5). The execution trace (thought / tool calls / plans / - * diffs) is delivered as opaque OMP-native session data on a dedicated stream. + * session surface needs (D5). The execution trace (thought / tool calls / plans + * / diffs) is delivered as opaque OMP-native session data on a dedicated + * stream, not as comms blocks. * * @generated from message compass.v1.MessageBlock */ diff --git a/packages/compass-agent/src/mapping.ts b/packages/compass-agent/src/mapping.ts index decc3153d..291b77dcc 100644 --- a/packages/compass-agent/src/mapping.ts +++ b/packages/compass-agent/src/mapping.ts @@ -335,8 +335,8 @@ export class EventMapper { } // ── Runtime-narrowed readers (never an inline cast) ────────────────────────── -// SDK tool payloads are narrowed through `isRecord` before property access. -// The readers emit Compass-native target types. +// The SDK types tool `args`/`result`/`partialResult` as `any`; these read them +// through the `isRecord` guard so every access is on a known-object value. // The one narrowing primitive: is `value` a non-null object we can index by key? // Every reader below narrows through this before any property read, so there is @@ -444,8 +444,8 @@ function extractPlanEntries(result: unknown): AgentPlanEntry[] | undefined { return entries; } -// Map an SDK todo status to the Compass plan-entry enum. Unknown or absent status -// becomes PENDING; the enum has no separate abandoned state. +// Map an SDK todo status to the Compass plan-entry enum: "abandoned" folds to +// COMPLETED (the enum has no abandoned state); unknown or absent is PENDING. function planStatus(status: unknown): AgentPlanEntryStatus { switch (status) { case "in_progress": diff --git a/packages/compass-client/src/gen/compass/v1/comms_pb.ts b/packages/compass-client/src/gen/compass/v1/comms_pb.ts index 9360c6e49..69d7a9240 100644 --- a/packages/compass-client/src/gen/compass/v1/comms_pb.ts +++ b/packages/compass-client/src/gen/compass/v1/comms_pb.ts @@ -3,12 +3,12 @@ // agents are first-class accounts in a management hierarchy. Channels nest in // channel groups, so a user's space (e.g. group "matt" → channel // "coordination", the path "matt.coordination") carries group-level -// permissions. An agent's interactive surface: the session conversation -// (text and structured asks) plus terminal and file panes — renders in the -// agent's channel; the AgentWorkspace is the observation pane over that session -// (D5), its access a projection of channel membership. All -// comms flow through this layer, so audit and search are properties of the -// substrate, not a separate pipeline (D1). +// permissions. An agent's interactive surface — the session conversation (text +// and structured asks) plus terminal and file panes — renders in the agent's +// channel; the AgentWorkspace is the observation pane over that session (D5), +// its access a projection of channel membership. All comms flow through this +// layer, so audit and search are properties of the substrate, not a separate +// pipeline (D1). // // This lives alongside compass.proto in the same owned `compass.v1` package as // an additive surface (new file, new service) that evolves the contract from a @@ -366,7 +366,9 @@ export const PinnedEntrySchema: GenMessage = /*@__PURE__*/ /** * An agent's interactive surface: the session observation pane for one agent * account, including the conversation, terminal, and file panes the ADE hosts. - * Demoted to the observation pane (D5, fork f); access projects channel membership. + * Demoted to the observation pane (D5, fork f): no longer a message container, + * and its access is a projection of the agent's channel membership rather than + * a separate participant ACL. * * @generated from message compass.v1.AgentWorkspace */ @@ -507,8 +509,9 @@ export const MessageSchema: GenMessage = /*@__PURE__*/ /** * One content block in a message: the durable conversation the comms layer * persists. `text` is settled markdown; `ask` is a structured question the - * session surface needs (D5). The execution trace (thought / tool calls / plans / - * diffs) is delivered as opaque OMP-native session data on a dedicated stream. + * session surface needs (D5). The execution trace (thought / tool calls / plans + * / diffs) is delivered as opaque OMP-native session data on a dedicated + * stream, not as comms blocks. * * @generated from message compass.v1.MessageBlock */ diff --git a/proto/compass/v1/comms.proto b/proto/compass/v1/comms.proto index 16d83a754..8bdb15b55 100644 --- a/proto/compass/v1/comms.proto +++ b/proto/compass/v1/comms.proto @@ -3,12 +3,12 @@ // agents are first-class accounts in a management hierarchy. Channels nest in // channel groups, so a user's space (e.g. group "matt" → channel // "coordination", the path "matt.coordination") carries group-level -// permissions. An agent's interactive surface: the session conversation -// (text and structured asks) plus terminal and file panes — renders in the -// agent's channel; the AgentWorkspace is the observation pane over that session -// (D5), its access a projection of channel membership. All -// comms flow through this layer, so audit and search are properties of the -// substrate, not a separate pipeline (D1). +// permissions. An agent's interactive surface — the session conversation (text +// and structured asks) plus terminal and file panes — renders in the agent's +// channel; the AgentWorkspace is the observation pane over that session (D5), +// its access a projection of channel membership. All comms flow through this +// layer, so audit and search are properties of the substrate, not a separate +// pipeline (D1). // // This lives alongside compass.proto in the same owned `compass.v1` package as // an additive surface (new file, new service) that evolves the contract from a @@ -298,7 +298,9 @@ enum ChannelKind { // An agent's interactive surface: the session observation pane for one agent // account, including the conversation, terminal, and file panes the ADE hosts. -// Demoted to the observation pane (D5, fork f); access projects channel membership. +// Demoted to the observation pane (D5, fork f): no longer a message container, +// and its access is a projection of the agent's channel membership rather than +// a separate participant ACL. message AgentWorkspace { // Server-assigned stable id. string id = 1; @@ -350,8 +352,9 @@ message Message { // One content block in a message: the durable conversation the comms layer // persists. `text` is settled markdown; `ask` is a structured question the -// session surface needs (D5). The execution trace (thought / tool calls / plans / -// diffs) is delivered as opaque OMP-native session data on a dedicated stream. +// session surface needs (D5). The execution trace (thought / tool calls / plans +// / diffs) is delivered as opaque OMP-native session data on a dedicated +// stream, not as comms blocks. message MessageBlock { oneof block { // Settled user-facing / assistant text (markdown).