Skip to content

Add safe context and memory for Discord agent workflows #265

@michaelmwu

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
    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