Skip to content

Preserve provenance for extension custom messages at the LLM boundary #228

Open

Description

@shuv1337

Problem

Extension-injected custom messages preserve customType and distinct TUI rendering in session state, but convertToLlm() unconditionally converts every role: "custom" message to role: "user" and drops its provenance metadata.

This is especially risky for asynchronous extensions: subagent output and background-process stdout may contain untrusted repository/web/process text, yet the parent model receives it at the same role tier as literal human instructions.

The issue is not that the TUI confuses the messages; it does not. The trust/provenance loss happens at the model boundary.

Desired design

Introduce a durable internal observation/provenance contract for extension-generated context. Provider adapters may still need to serialize observations into available provider roles, but the transformation should preserve source/type metadata and apply a standard non-spoofable framing/policy rather than silently treating observations as human-authored input.

Acceptance criteria

  • Extension-generated observations are distinguishable from literal user messages through the full session-to-provider pipeline.
  • Provenance includes at least extension/custom type and an explicit trust classification.
  • Provider conversion has a documented strategy for APIs without a native observation/tool role.
  • Async child/process output is framed as untrusted data and cannot override higher-priority instructions by role implication.
  • Existing custom messages remain session-compatible or migrate safely.
  • Tests cover TUI/session preservation, provider conversion, queued steer/follow-up delivery, compaction, and adversarial delimiter/instruction content.
  • Extension docs explain when to use custom context messages versus durable TUI-only appendEntry() data.

Source anchors

  • packages/coding-agent/src/core/messages.ts: CustomMessage, convertToLlm()
  • packages/coding-agent/docs/extensions.md: sendMessage(), appendEntry()
  • Reviewed at 7ead90e361dac2c0e29cd65acca8e2a0a2590183

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions