Skip to content

Surface AI-actor disclosure in the TUI prompt and audit trail #25

@cuihtlauac

Description

@cuihtlauac

Problem

The TUI prompt (src/tui.rs:87-113) shows From: <session> @ <host> and treats every requester identically. When the request originates from sudo-proxy-mcp — i.e. an AI agent is the one asking — that fact is only legible if the human notices the literal string sudo-proxy-mcp in the From: line and remembers what it means.

Industry practice around generative-AI transparency is moving toward an explicit signal at decision points: when a human is asked to approve an action that an AI proposed, the UI should say so plainly. sudo-proxy is exactly such a decision point. The current default session name leaks the information by accident; a malicious or mis-configured client can also set session to anything it wants (src/protocol.rs:16-17), so the AI/human distinction cannot be inferred from session alone.

Proposal

Add a structured, server-trusted signal that says "the requester self-identifies as an AI agent" and display it in the TUI.

  1. Protocol. Add an agent field to Request in src/protocol.rs:

    /// Self-declared identity of the requester. The daemon does not
    /// authenticate this; it is shown to the human approver as-is.
    /// Conventional values: \"human\", \"ai\".
    #[serde(default)]
    pub agent: String,

    #[serde(default)] keeps it forward-compatible with old clients (src/protocol.rs:385 discusses the convention).

  2. MCP server. src/mcp.rs:184 already sets session: \"sudo-proxy-mcp\" on the wire. Set agent: \"ai\" there too. Optionally accept an override from the MCP client so a downstream model can pass through a more specific identity (\"ai:claude-opus-4-7\", etc.) — but the daemon should never trust the string beyond display.

  3. CLI client. sudo-request is human-driven; default agent: \"human\" there. Leave unknown as the wire default for unannotated peers.

  4. TUI. In src/tui.rs:87-93, when req.agent starts with ai, prepend a distinct banner above the Privilege Request line — e.g. bold yellow [AI-AGENT REQUEST] — and include the declared identity on its own line. Do not colour the rest of the prompt; the goal is to draw the eye once, not desensitise.

  5. Audit trail. When Append-only audit log of approved requests and outcomes #6 (append-only audit log) lands, persist the agent field alongside the rest of the request. Operators reviewing history should be able to grep "approved by me, requested by an AI."

Things to consider

  • The agent value is self-declared. The TUI must not phrase it as if the daemon verified it — "requester self-identifies as:" rather than "requester is:". Treat it like reason: human-readable metadata, not a trust signal.
  • Do not collapse this into session. session is a free-form tag (project name, ticket ID); overloading it loses both signals.
  • Resist a boolean. agent: \"ai\" / agent: \"human\" / agent: \"automation\" (cron, CI) is more honest than is_ai: true/false; a human running a wrapper script is not an AI but is also not interactively typing.
  • Backwards compatibility: omitted agent deserialises to empty string; render that as nothing rather than as an explicit "unknown" label, otherwise every legacy sudo-request call sprouts a noisy banner.
  • Interaction with Annotate TUI prompt with factual risk signals (not a conflated score) #7 (factual risk signals): the agent banner sits outside the signals block. It is about who is asking, not about what they are asking for.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions