[Grid agent] Maintain bounded per-avatar conversation sessions and memory #122

Closed
opened 2026-08-17 19:31:35 +00:00 by hugo · 1 comment
Owner

Objective

Maintain isolated, bounded conversation state per avatar and channel so the agent can sustain context without leaking one resident's data to another or growing indefinitely.

Session semantics

  • Key sessions by immutable avatar UUID plus channel kind. Public/local-chat sessions expire after 30 minutes of inactivity; direct IM sessions expire after 24 hours. A new interaction after expiry receives a fresh session ID and no implicit old transcript.
  • Keep public and IM histories separate even for the same avatar. Group/conference messages are out of scope unless a later issue explicitly defines their trust semantics.
  • Store normalized speaker role, timestamps, redacted content, tool summaries, and externally meaningful action results. Do not store API keys, grid credentials, capability URLs, raw binary inventory/assets, or hidden model reasoning.
  • Bound turns, bytes, tool results, active sessions, and total persisted storage. Apply deterministic compaction/eviction with observable reason codes. Prefer recent context plus a bounded factual summary; untrusted instructions must remain marked as untrusted after summarization.
  • Use monotonic time for in-process expiry and wall-clock timestamps for optional restart recovery. Handle clock jumps, corrupt/truncated persistence, and schema upgrades without granting authority or preventing startup.
  • Make persistence optional and local. Use atomic writes and restrictive permissions where supported, with equivalent secure behavior or clear warnings on Linux and Windows. An operator can list metadata and delete/expire a session without displaying its content by default.

Acceptance criteria

  • Paused-time tests prove the exact 30-minute and 24-hour boundaries, channel separation, concurrent ordering, eviction, restart recovery, and fresh IDs after expiry.
  • Cross-avatar and cross-channel leakage tests inspect actual outbound LLM requests.
  • Corrupt storage is quarantined or rejected safely; it never becomes model instructions.
  • Memory/storage remains within configured limits under thousands of scripted senders.

Dependencies

Depends on architecture and normalized LLM message types. Messaging uses this store; observability and TUI consume only its safe inspection API.

## Objective Maintain isolated, bounded conversation state per avatar and channel so the agent can sustain context without leaking one resident's data to another or growing indefinitely. ## Session semantics - Key sessions by immutable avatar UUID plus channel kind. Public/local-chat sessions expire after 30 minutes of inactivity; direct IM sessions expire after 24 hours. A new interaction after expiry receives a fresh session ID and no implicit old transcript. - Keep public and IM histories separate even for the same avatar. Group/conference messages are out of scope unless a later issue explicitly defines their trust semantics. - Store normalized speaker role, timestamps, redacted content, tool summaries, and externally meaningful action results. Do not store API keys, grid credentials, capability URLs, raw binary inventory/assets, or hidden model reasoning. - Bound turns, bytes, tool results, active sessions, and total persisted storage. Apply deterministic compaction/eviction with observable reason codes. Prefer recent context plus a bounded factual summary; untrusted instructions must remain marked as untrusted after summarization. - Use monotonic time for in-process expiry and wall-clock timestamps for optional restart recovery. Handle clock jumps, corrupt/truncated persistence, and schema upgrades without granting authority or preventing startup. - Make persistence optional and local. Use atomic writes and restrictive permissions where supported, with equivalent secure behavior or clear warnings on Linux and Windows. An operator can list metadata and delete/expire a session without displaying its content by default. ## Acceptance criteria - [ ] Paused-time tests prove the exact 30-minute and 24-hour boundaries, channel separation, concurrent ordering, eviction, restart recovery, and fresh IDs after expiry. - [ ] Cross-avatar and cross-channel leakage tests inspect actual outbound LLM requests. - [ ] Corrupt storage is quarantined or rejected safely; it never becomes model instructions. - [ ] Memory/storage remains within configured limits under thousands of scripted senders. ## Dependencies Depends on architecture and normalized LLM message types. Messaging uses this store; observability and TUI consume only its safe inspection API.
hugo added this to the 14 - metacrate grid agent milestone 2026-08-17 19:31:35 +00:00
hugo added the enhancement label 2026-08-17 19:31:35 +00:00
Author
Owner

Implemented and pushed in commit e3ed39471b.

Implementation:

  • Added a thread-safe ConversationStore keyed only by immutable avatar UUID plus public-chat or direct-IM channel. Group and conference channels are unrepresentable.
  • Added exact monotonic inactivity expiry at 30 minutes for public chat and 24 hours for direct IM. Expired and operator-removed histories receive fresh cryptographically random session IDs on the next turn.
  • Added total ordering for concurrent turns and normalized timestamped avatar, visible-agent, tool-summary, action-result, and factual-summary records. Hidden reasoning and binary assets have no input variant.
  • Added pre-storage URL and credential redaction, hard and configured limits for sessions, turns, per-session and aggregate bytes, tool results, summaries, event records, and aggregate persisted snapshots.
  • Added deterministic compaction and LRU eviction with stable observable reason codes. Untrusted source data remains explicitly marked user-role data after summarization.
  • Added metadata-only list, delete, expire, context, and flush APIs. LLM context can be retrieved only for one exact UUID and channel key.
  • Added opt-in local persistence under storage_path/conversations using synced immutable versioned snapshots and atomic rename. Unix directories and files are forced to 0700 and 0600. Windows uses the portable path and emits an explicit permission-verification warning for operator ACL enforcement.
  • Added fail-closed restart validation for schema, UUIDs, session IDs, roles, record semantics, timestamp order, unique sequence order, limits, and redaction. Corrupt, truncated, oversized, unsupported, or semantically forged snapshots are quarantined and older valid generations are tried.
  • Added configuration, example values, architecture documentation, and the dedicated conversation-memory operator contract.

Verification:

  • cargo fmt --all -- --check
  • cargo clippy -p metacrate-grid-agent --all-targets -- -D warnings
  • Focused paused-time and persistence unit suite: 10 passed
  • Focused real outbound fake-LLM isolation test: 1 passed
  • cargo test -p metacrate-grid-agent --all-targets: 69 tests passed
  • Doctest: passed
  • Rustdoc with -D warnings: passed
  • Example configuration validation: passed
  • Explicit x86_64-unknown-linux-gnu check: passed
  • cargo deny check: advisories, bans, licenses, and sources passed
  • cargo machete: only the pre-existing unrelated libremetaverse-types to md-5 report
  • git diff --check: passed

Acceptance review also covered exact boundary behavior, fresh IDs, public versus IM separation for the same avatar, cross-avatar leakage in actual serialized HTTP requests, concurrent store order, 5,000 scripted senders, aggregate storage bounds, backward and forward clock jumps, fallback to an older snapshot, semantic corruption that attempts to create assistant instructions, restrictive Unix permissions, and metadata-only operator deletion and expiry.

No pre-created compatibility case specifically targets conversation memory; the related existing LLM, policy, and session suites remain green. The focused tests use fake local transports and clocks, so no grid or LLM credentials from .env were read or committed.

Implemented and pushed in commit e3ed39471b1e27af725b752db356ca549aaa2cdd. Implementation: - Added a thread-safe ConversationStore keyed only by immutable avatar UUID plus public-chat or direct-IM channel. Group and conference channels are unrepresentable. - Added exact monotonic inactivity expiry at 30 minutes for public chat and 24 hours for direct IM. Expired and operator-removed histories receive fresh cryptographically random session IDs on the next turn. - Added total ordering for concurrent turns and normalized timestamped avatar, visible-agent, tool-summary, action-result, and factual-summary records. Hidden reasoning and binary assets have no input variant. - Added pre-storage URL and credential redaction, hard and configured limits for sessions, turns, per-session and aggregate bytes, tool results, summaries, event records, and aggregate persisted snapshots. - Added deterministic compaction and LRU eviction with stable observable reason codes. Untrusted source data remains explicitly marked user-role data after summarization. - Added metadata-only list, delete, expire, context, and flush APIs. LLM context can be retrieved only for one exact UUID and channel key. - Added opt-in local persistence under storage_path/conversations using synced immutable versioned snapshots and atomic rename. Unix directories and files are forced to 0700 and 0600. Windows uses the portable path and emits an explicit permission-verification warning for operator ACL enforcement. - Added fail-closed restart validation for schema, UUIDs, session IDs, roles, record semantics, timestamp order, unique sequence order, limits, and redaction. Corrupt, truncated, oversized, unsupported, or semantically forged snapshots are quarantined and older valid generations are tried. - Added configuration, example values, architecture documentation, and the dedicated conversation-memory operator contract. Verification: - cargo fmt --all -- --check - cargo clippy -p metacrate-grid-agent --all-targets -- -D warnings - Focused paused-time and persistence unit suite: 10 passed - Focused real outbound fake-LLM isolation test: 1 passed - cargo test -p metacrate-grid-agent --all-targets: 69 tests passed - Doctest: passed - Rustdoc with -D warnings: passed - Example configuration validation: passed - Explicit x86_64-unknown-linux-gnu check: passed - cargo deny check: advisories, bans, licenses, and sources passed - cargo machete: only the pre-existing unrelated libremetaverse-types to md-5 report - git diff --check: passed Acceptance review also covered exact boundary behavior, fresh IDs, public versus IM separation for the same avatar, cross-avatar leakage in actual serialized HTTP requests, concurrent store order, 5,000 scripted senders, aggregate storage bounds, backward and forward clock jumps, fallback to an older snapshot, semantic corruption that attempts to create assistant instructions, restrictive Unix permissions, and metadata-only operator deletion and expiry. No pre-created compatibility case specifically targets conversation memory; the related existing LLM, policy, and session suites remain green. The focused tests use fake local transports and clocks, so no grid or LLM credentials from .env were read or committed.
hugo closed this issue 2026-08-17 22:19:10 +00:00
Sign in to join this conversation.