Skip to content

Auto-distill on untrusted-channel runtimes: cred-isolate the extraction host + protect unreviewed writes #658

Description

@Poytr1

Follow-up to #653 / PR #655 (owner-accepted P2).

Context

#655 made auto-distillation work on every harness by mirroring the memory-dream trust model: the read-only/plan permission mode stays a hard gate, and the trusted system-prompt channel became observed (ride _meta.systemPrompt when present, else prepend the policy inline). This lets Codex/OpenCode distill instead of silently no-op'ing.

Residual risk (accepted as P2 by the owner for now)

Auto-distillation differs from a dream in two ways that make the untrusted-channel path riskier than the dream path:

  1. No staging/review — the distiller parses the model's JSON and appends it to shared agent-scoped live memory directly (unlike a dream, which stages + reviews, or requires an explicit autoAdopt opt-in).
  2. Runs on the warm hostrunMemoryExtraction reuses the agent's warm ACP host (full agent tool credentials + materialized config files), whereas a dream runs on a dedicated excludeAgentToolCredentials host.

On a runtime without an ACP system-prompt channel, the inline policy and the attacker-controlled finished turn share user-message priority, so a prompt injection could:

  • control the distilled JSON → write poisoned "facts" into shared memory unreviewed; and
  • ask the runtime to read a credential and re-encode it into a "memory" — the read-only mode blocks writes/side-effects but not reads, and the literal-value secret masker is defense-in-depth and won't catch arbitrary re-encoding.

(The trusted-channel/Claude path is unchanged and keeps the prior protection.)

Proposed fix

Give the untrusted-channel distillation path the dream's credential isolation: run extraction on a dedicated excludeAgentToolCredentials host (reuse buildDreamHost / buildAcpHost), cached per agent (long-lived) since distillation runs every turn — so cost stays ~one extra process per auto-distill agent rather than a spawn per turn. This closes the credential-read/re-encode path; the remaining unreviewed-write (memory-poisoning) residual matches the class the trusted-channel path already tolerates. Optionally, consider a lightweight review/quarantine for untrusted-channel distilled writes.

The provider-credential-vs-model-tools gap is the same accepted P2 as the dream path (F3, #36).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions