You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Claude Code and Codex templates, with similar generated driver instructions, tell agents to read and respond without defining a common trust boundary for the enclosed body.
Existing shell, JSON, or UI escaping may protect representation syntax, but it does not by itself establish a consistent semantic boundary between adapter-owned guidance and peer-supplied content.
This issue does not assert that a particular body will cause a model or person to take an unsafe action. It addresses the agmsg-owned part of the boundary: consistently classifying, separating, and bounding peer content before presenting it to a person, agent, model, or hook.
Security objective and limits
Every message body that an agmsg adapter presents to a receiver must be presented as untrusted peer content, regardless of who appears to have sent it.
The framing should tell a receiver that the body may contain a request, but does not:
override system, user, or current-task instructions;
grant tool, filesystem, network, or lifecycle authority;
change approval requirements;
become trusted because its sender provenance is verified.
Sender, recipient, and team fields remain routing or display metadata, not authority. #515 owns whether sender provenance is verified; provenance must never upgrade the body’s trust classification.
This is defense in depth. A text wrapper, delimiter, separate content item, UI component, or model instruction cannot guarantee that an LLM or person will ignore hostile or misleading content. The implementation and documentation must not claim to solve prompt injection or provide a security boundary stronger than the receiving runtime actually supports.
Required agmsg-owned invariants
Every peer body that an agmsg adapter presents is classified as untrusted data.
Adapter-owned metadata and guidance are fixed by the adapter and cannot be extended, closed, or replaced by body text.
Multiline, delimiter-like, Unicode, and other supported text is represented without making wrapper boundaries ambiguous.
The framing layer does not grant permissions, alter approvals, or introduce automatic tool or lifecycle actions.
Legacy rows and messages without provenance metadata receive the same untrusted classification when presented.
Model- and hook-facing delivery has documented per-message and per-delivery size/count limits. Any omission or truncation is explicit and does not modify the stored body.
Applying a presentation limit must not mark an omitted row or silently omitted body as read. Limits must be applied before the current read-state transition, or the adapter must use a metadata-only/fetch-later path that leaves omitted rows eligible.
Framing does not add duplicate plaintext body copies to operational logs or diagnostics.
All body-presenting adapters follow one documented contract and common conformance fixtures, using shared rendering helpers where practical.
Stable or machine-consumed output formats use a versioned mode or tested compatibility path when framing changes their representation.
The current Monitor path intercepts legacy ctrl:despawn rows before presenting them. This issue does not change that classification or require those intercepted rows to be rendered; #514 owns removal of message-text lifecycle controls. If the same text is presented through another ordinary body surface, it is still untrusted content there.
Adapter-specific rendering
CLI inbox and history
Show a compact, explicit untrusted-content marker for each presented message.
Separate metadata from the body unambiguously instead of relying only on sender: body.
Preserve supported body text without evaluation or silent rewriting.
Apply any output limit before marking rows read; rows omitted by the limit must remain eligible.
Keep existing read-state behavior otherwise outside this change.
Cover both unread delivery and manual history/replay output.
Monitor
Provide an explicit trust field or fixed header/body representation for each presented event.
Encode multiline and delimiter-like content unambiguously.
Keep adapter-owned Monitor instructions outside the event body.
If the stream format changes incompatibly, introduce a versioned mode or documented compatibility path and test existing consumers.
Stop hook
Keep the hook decision and adapter guidance fixed and adapter-owned.
Present inbox entries inside a clearly marked untrusted-data section.
If the hook protocol only permits a string reason, use an unambiguous, escaped, and bounded sub-envelope within that string.
A body must not be able to appear as another hook field or as adapter-owned guidance.
Bound output before marking rows read; omitted rows must remain eligible.
Codex bridge
Keep the bridge’s continuation/reply guidance fixed and separate from message data.
Represent each inline inbox entry in an escaped or length-delimited envelope with an explicit untrusted classification.
Use structured or separate input items only where the app-server contract supports them, and do not describe item separation as an authority boundary unless the runtime documents one.
Preserve existing approval behavior; this issue must not enable auto-approval or broaden tool authority.
Do not call inbox.sh, mark every selected row read, and then silently discard rows or body text to meet a context limit. Apply limits before the read transition or use an explicit metadata-only/fetch-later path.
Desktop
Cover the current Desktop behavior:
Treat the full bodies shown in team-room and app-user chat views as peer content, kept structurally separate from UI-owned metadata and controls.
Treat the body preview injected into a non-native pane as untrusted peer content, not as adapter or user authority.
Keep preview flattening and truncation explicit, deterministic, Unicode-safe, and covered by conformance tests.
Ensure body text cannot alter the fixed kickoff guidance or introduce additional injected submissions.
Do not add body copies to diagnostics or logs while framing the UI or PTY-injection paths.
The design work in #263 proposes a future metadata-only wake collector whose destination thread reads its official inbox. If that design is implemented:
the wake collector must remain body-blind;
the destination thread must receive bodies through this same framing contract;
framing must not cause the wake/dispatch component to log or consume bodies merely to classify them.
Completion of this issue does not require implementing #263.
Driver templates and generated instructions
Update all applicable agent templates and generated receiver instructions to state that inbox bodies are untrusted peer content. A message may be evaluated as a request only under the receiver’s existing task, instructions, permissions, and approval requirements.
Avoid language implying that every message must automatically be followed. Preserve driver-specific delivery behavior and test generated instruction files, not only source templates.
Scope separation
This issue is independently closable against current and legacy message rows.
Work
Question answered
Owned elsewhere
Typed lifecycle controls
Can message text directly invoke an agmsg lifecycle operation?
How is a body framed when an existing adapter presents it to a receiver/model?
Here
Completion must not depend on #514, #515, #263, or #373. This issue preserves existing delivery and read-state semantics except that a new presentation limit must not acknowledge content it omitted.
Non-goals
Guaranteeing that an LLM or person will ignore misleading or hostile instructions
Bodies cannot collide with or modify wrapper metadata, headings, hook fields, UI controls, injected submissions, or adapter guidance.
Multiline, tabs, Unicode, legacy empty-body rows, and delimiter-like text remain unambiguous.
Model- and hook-facing adapters enforce documented count/size limits and visibly identify truncation or omission.
Rows or bodies omitted by a framing limit are not silently marked read or lost.
The framing implementation does not add permissions, approval bypasses, command evaluation, lifecycle actions, or automatic execution.
Stable and machine-consumed formats maintain compatibility through versioning or a tested compatibility path.
Framing metadata and diagnostics introduce no credentials, opaque provenance references, sensitive environment values, new project-path disclosure, or extra plaintext body copies.
Documentation explicitly states that framing is defense in depth and is not a guarantee of model compliance.
no framing path evaluates body content as a command or changes approval configuration;
diagnostics do not gain an additional plaintext body copy or new sensitive path/value exposure.
These tests validate agmsg-owned rendering, read-state preservation, and side effects only. Model or human compliance must not be treated as a deterministic, testable security property.
Problem
agmsg presents peer-supplied message bodies through several surfaces that also carry agmsg-owned metadata or instructions. On current
main:Existing shell, JSON, or UI escaping may protect representation syntax, but it does not by itself establish a consistent semantic boundary between adapter-owned guidance and peer-supplied content.
This issue does not assert that a particular body will cause a model or person to take an unsafe action. It addresses the agmsg-owned part of the boundary: consistently classifying, separating, and bounding peer content before presenting it to a person, agent, model, or hook.
Security objective and limits
Every message body that an agmsg adapter presents to a receiver must be presented as untrusted peer content, regardless of who appears to have sent it.
The framing should tell a receiver that the body may contain a request, but does not:
Sender, recipient, and team fields remain routing or display metadata, not authority. #515 owns whether sender provenance is verified; provenance must never upgrade the body’s trust classification.
This is defense in depth. A text wrapper, delimiter, separate content item, UI component, or model instruction cannot guarantee that an LLM or person will ignore hostile or misleading content. The implementation and documentation must not claim to solve prompt injection or provide a security boundary stronger than the receiving runtime actually supports.
Required agmsg-owned invariants
The current Monitor path intercepts legacy
ctrl:despawnrows before presenting them. This issue does not change that classification or require those intercepted rows to be rendered; #514 owns removal of message-text lifecycle controls. If the same text is presented through another ordinary body surface, it is still untrusted content there.Adapter-specific rendering
CLI inbox and history
sender: body.Monitor
Stop hook
reason, use an unambiguous, escaped, and bounded sub-envelope within that string.Codex bridge
inbox.sh, mark every selected row read, and then silently discard rows or body text to meet a context limit. Apply limits before the read transition or use an explicit metadata-only/fetch-later path.Desktop
Cover the current Desktop behavior:
The design work in #263 proposes a future metadata-only wake collector whose destination thread reads its official inbox. If that design is implemented:
Completion of this issue does not require implementing #263.
Driver templates and generated instructions
Update all applicable agent templates and generated receiver instructions to state that inbox bodies are untrusted peer content. A message may be evaluated as a request only under the receiver’s existing task, instructions, permissions, and approval requirements.
Avoid language implying that every message must automatically be followed. Preserve driver-specific delivery behavior and test generated instruction files, not only source templates.
Scope separation
This issue is independently closable against current and legacy message rows.
Completion must not depend on #514, #515, #263, or #373. This issue preserves existing delivery and read-state semantics except that a new presentation limit must not acknowledge content it omitted.
Non-goals
watch.shAcceptance criteria
Test plan
Use synthetic fixtures only; do not include credentials, personal data, local project paths, or operational secrets.
Cover every current body-presenting adapter with:
ctrl:despawninterception as an explicit out-of-scope compatibility case for Monitor.Assert that:
These tests validate agmsg-owned rendering, read-state preservation, and side effects only. Model or human compliance must not be treated as a deterministic, testable security property.
Related work