Skip to content

feat(memory): AOI three-layer hierarchical memory architecture#2092

Merged
bug-ops merged 4 commits intomainfrom
feat-issue-1839-aoi-three-layer-memory
Mar 21, 2026
Merged

feat(memory): AOI three-layer hierarchical memory architecture#2092
bug-ops merged 4 commits intomainfrom
feat-issue-1839-aoi-three-layer-memory

Conversation

@bug-ops
Copy link
Owner

@bug-ops bug-ops commented Mar 21, 2026

Closes #1839

Summary

  • Introduces MemoryTier enum (Working/Episodic/Semantic) and promotion pipeline based on the AOI paper (arXiv:2512.13956)
  • Migration 042 adds tier, promotion_timestamp, session_count columns to messages table
  • Background sweep clusters episodic embeddings by cosine similarity, merges clusters via LLM, promotes distilled facts to semantic tier
  • session_count incremented on every session restore via load_history() — drives promotion eligibility
  • Additive tier boost (+0.3) applied to semantic facts in recall scoring
  • /memory promote and /memory tiers slash commands
  • Semantic fact count shown in TUI memory panel
  • --init wizard and --migrate-config updated for [memory.tiers]

Test plan

  • cargo +nightly fmt --check — clean
  • cargo clippy --workspace --features full -- -D warnings — clean
  • cargo nextest run --workspace --features full --lib --bins — 6304 passed (+11 new)
  • Security audit: PASS (SQL parameterized, config validated, no unsafe code)
  • CRIT-1 verified: increment_session_counts_for_conversation wired in load_history(), covered by 2 new unit tests
  • --migrate-config injects [memory.tiers] for existing configs

Follow-up issues to file

  • OBS-1: log singleton cluster skips at debug level (tiers.rs:169)
  • OBS-2: unit tests for SqliteStore tier DB methods (promote_to_semantic, find_promotion_candidates, etc.)
  • OBS-3: add similarity_threshold > 1.0 rejection test in TierConfig

Introduces explicit tier promotion between Working, Episodic, and Semantic
memory layers based on the AOI paper (arXiv:2512.13956).

- Add migration 042: `tier`, `promotion_timestamp`, `session_count` columns
  on `messages` table with indexes
- Add `MemoryTier` enum (Working/Episodic/Semantic) to zeph-memory types
- Add `TierPromotionConfig` under `[memory.tiers]` with validation
- New `tiers.rs`: background sweep loop that clusters episodic embeddings by
  cosine similarity, merges clusters via LLM, promotes distilled facts to
  semantic tier, soft-deletes episodic originals
- Wire `increment_session_counts_for_conversation()` into `load_history()` so
  session_count increments on every session restore
- Apply additive tier boost (+0.3) to semantic facts in recall scoring
- Add `/memory promote` and `/memory tiers` slash commands
- Show semantic fact count in TUI memory panel
- Update `--init` wizard with `[memory.tiers]` prompts
- Update `--migrate-config` to inject `[memory.tiers]` for existing configs

Tests: 6304 passed (+11 new)
@github-actions github-actions bot added enhancement New feature or request size/XL Extra large PR (500+ lines) documentation Improvements or additions to documentation memory zeph-memory crate (SQLite) rust Rust code changes core zeph-core crate config Configuration file changes and removed enhancement New feature or request size/XL Extra large PR (500+ lines) labels Mar 21, 2026
@github-actions github-actions bot added enhancement New feature or request size/XL Extra large PR (500+ lines) labels Mar 21, 2026
@bug-ops bug-ops enabled auto-merge (squash) March 21, 2026 23:00
@bug-ops bug-ops linked an issue Mar 21, 2026 that may be closed by this pull request
@bug-ops bug-ops merged commit d8926cc into main Mar 21, 2026
25 checks passed
@bug-ops bug-ops deleted the feat-issue-1839-aoi-three-layer-memory branch March 21, 2026 23:17
bug-ops added a commit that referenced this pull request Mar 21, 2026
Closes #2094.

Adds 29 inline tests in sqlite/messages/tests.rs covering all tier DB
methods introduced in the AOI three-layer memory epic (#1839, #2092):

- fetch_tiers: empty input, default episodic tier, nonexistent IDs,
  tier value after manual_promote
- count_messages_by_tier: empty DB, all-episodic, post-promotion counts,
  soft-deleted rows excluded
- find_promotion_candidates: empty when session_count below threshold,
  returns rows meeting threshold, excludes semantic rows, respects batch_size
- promote_to_semantic: creates semantic message, soft-deletes originals,
  new ID greater than originals, empty-ids error, tier count update
- manual_promote: empty input no-op, sets tier to semantic, does not
  delete original, idempotent (0 rows affected on second call), skips
  nonexistent IDs
- migration 042 schema defaults: tier defaults to 'episodic',
  session_count defaults to 0 for rows inserted without those columns
bug-ops added a commit that referenced this pull request Mar 21, 2026
Closes #2094.

Adds 29 inline tests in sqlite/messages/tests.rs covering all tier DB
methods introduced in the AOI three-layer memory epic (#1839, #2092):

- fetch_tiers: empty input, default episodic tier, nonexistent IDs,
  tier value after manual_promote
- count_messages_by_tier: empty DB, all-episodic, post-promotion counts,
  soft-deleted rows excluded
- find_promotion_candidates: empty when session_count below threshold,
  returns rows meeting threshold, excludes semantic rows, respects batch_size
- promote_to_semantic: creates semantic message, soft-deletes originals,
  new ID greater than originals, empty-ids error, tier count update
- manual_promote: empty input no-op, sets tier to semantic, does not
  delete original, idempotent (0 rows affected on second call), skips
  nonexistent IDs
- migration 042 schema defaults: tier defaults to 'episodic',
  session_count defaults to 0 for rows inserted without those columns
bug-ops added a commit that referenced this pull request Mar 21, 2026
…2097)

Closes #2094.

Adds 29 inline tests in sqlite/messages/tests.rs covering all tier DB
methods introduced in the AOI three-layer memory epic (#1839, #2092):

- fetch_tiers: empty input, default episodic tier, nonexistent IDs,
  tier value after manual_promote
- count_messages_by_tier: empty DB, all-episodic, post-promotion counts,
  soft-deleted rows excluded
- find_promotion_candidates: empty when session_count below threshold,
  returns rows meeting threshold, excludes semantic rows, respects batch_size
- promote_to_semantic: creates semantic message, soft-deletes originals,
  new ID greater than originals, empty-ids error, tier count update
- manual_promote: empty input no-op, sets tier to semantic, does not
  delete original, idempotent (0 rows affected on second call), skips
  nonexistent IDs
- migration 042 schema defaults: tier defaults to 'episodic',
  session_count defaults to 0 for rows inserted without those columns
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Configuration file changes core zeph-core crate documentation Improvements or additions to documentation enhancement New feature or request memory zeph-memory crate (SQLite) rust Rust code changes size/XL Extra large PR (500+ lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(memory/tiers): log singleton cluster skips at debug level research(memory): AOI three-layer hierarchical memory architecture

1 participant