Skip to content

Add safe context and memory for Discord agent workflows #265

Description

@michaelmwu

Parent: #257

Goal

Add a safe context and memory layer for Discord agent workflows so the agent can use relevant thread context, recent user messages, session state, and durable user/project/org facts without treating retrieved content as instructions or bypassing policy.

Why this should be a follow-up

The first agent gateway work should establish the command entrypoint, backend policy gate, confirmations, and audit path. Context and memory need separate design because they introduce privacy, retention, consent, prompt-injection, and authorization questions. We should not mix that risk into the initial gateway/confirmation PR.

Core distinction

Raw chat history is not memory.

The system should separate:

  • thread_context: recent messages from the current Discord thread/channel; short-lived, bounded, and source-labeled.
  • session_context: the current agent operation, plan, confirmations, and tool results; tied to an operation_id.
  • durable_memory: explicit user/project/org facts stored with provenance, visibility, verification status, and delete controls.
  • authoritative_profile_data: CRM fields, linked Discord identity, roles, project ownership, and other trusted service data; preferred over inferred memory.

Proposed architecture

Discord /agent request
  -> bot resolves message/thread/channel/user context ids
  -> backend context service loads allowed context snippets
  -> memory store returns durable facts with provenance
  -> orchestrator quotes retrieved context as untrusted data
  -> policy gate re-authorizes every proposed tool call
  -> audit records context sources used

Context and memory permissions

Add distinct scopes for retrieval and mutation:

  • context:read_current_thread
  • context:read_channel_recent
  • context:read_user_recent_self
  • context:read_user_recent_any
  • memory:read_self
  • memory:read_project
  • memory:write_self
  • memory:write_project
  • memory:admin

Every context or memory retrieval should check:

  • Can this actor see the original source?
  • Can this actor use that source for this purpose?
  • Can this response destination receive that information?
  • Is the source private, restricted, or cross-project?
  • Is the fact still valid?

The response-destination check is important: a user may be allowed to read their own private memory, but the bot should not echo it into a public channel.

Data model direction

Add a memory_facts table or equivalent store:

memory_facts
  id
  scope_type          user | project | org
  scope_id
  key
  value_json
  visibility          private | project | org
  source_type
  source_ref
  source_excerpt_hash
  created_by
  verification_status inferred | user_confirmed | admin_confirmed | authoritative
  confidence
  expires_at
  deleted_at
  created_at
  updated_at

Track context sources per agent operation:

agent_context_sources
  id
  operation_id
  source_type         discord_thread | discord_message | crm | memory_fact | docs
  source_ref
  scope_type
  scope_id
  loaded_by
  loaded_at
  token_count
  policy_decision_id

Avoid storing raw Discord message bodies indefinitely unless there is a clear product/legal reason. Prefer source refs, hashes, bounded summaries, or extracted facts.

Prompt-injection guardrails

All retrieved messages, docs, CRM notes, and previous agent outputs are untrusted data.

Required behavior:

  • source-label every context snippet
  • wrap retrieved snippets in explicit "untrusted context" prompt sections
  • never let retrieved content grant scopes, change permissions, or expose new privileged tools
  • never pass raw service credentials to the model
  • prefer structured facts and authoritative profile data over raw snippets
  • re-authorize every tool call after context retrieval
  • audit every context source used

Initial MVP

  1. Add agent request fields for Discord message_id, channel_id, thread_id, optional parent message id, and operation_id.
  2. Add a backend context loader interface with deterministic source adapters.
  3. Implement bounded current-thread loading with max-message and max-token limits.
  4. Add source-labeled context blocks to the agent prompt.
  5. Add audit records for context sources loaded.
  6. Add memory_facts storage for durable facts.
  7. Add read-only memory lookup tools:
    • memory_read.get_user_facts
    • memory_read.get_project_facts
    • memory_read.search_context
  8. Add write tools behind confirmation/admin policy:
    • memory_write.remember_fact
    • memory_write.forget_fact
  9. Add inspect/delete endpoints or commands so users/admins can review and remove stored facts.
  10. Add tests for private-channel leaks, prompt injection, retention bounds, deleted memory, and audit metadata.

Deliberately out of scope for MVP

  • Global search over all prior Discord messages.
  • Loading previous messages from arbitrary users.
  • Automatic persistence of inferred facts without confirmation.
  • Using memory to modify permissions, roles, or available tools.
  • Production deploy or secret access workflows.

Proposed subissues

Acceptance criteria

  • Agent requests can include recent Discord thread context when authorized.
  • The agent can use durable remembered facts with source/provenance attached.
  • Private or restricted context is not loaded unless policy permits it.
  • Retrieved content is always presented to the model as untrusted data.
  • Tool calls remain independently authorized after context retrieval.
  • Users/admins can inspect and remove stored facts.
  • Tests cover context loading, memory lookup, write confirmation, prompt-injection handling, private-channel leaks, retention, and audit logging.

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