Skip to content

fix(memory): tighten persistence rules and add conversational events#522

Open
vsumner wants to merge 2 commits intomainfrom
codex/memory-observation-p1
Open

fix(memory): tighten persistence rules and add conversational events#522
vsumner wants to merge 2 commits intomainfrom
codex/memory-observation-p1

Conversation

@vsumner
Copy link
Copy Markdown
Collaborator

@vsumner vsumner commented Apr 1, 2026

Why

This is the first packet of the memory-evolution work. The immediate goal is to tighten what the persistence branch is allowed to save and to start recording the most important conversational corrections explicitly.

Before this change, the persistence prompt still allowed too much derivable or noisy state into durable memory, and the working-memory event surface did not have first-class types for user corrections or revised decisions. That made the next observation-memory work harder because the system was still losing important conversational pivots while retaining lower-value chatter.

Scope

This PR is intentionally narrow.

It includes prompt-discipline changes plus the first conversational working-memory event semantics. It does not yet expand the broader event vocabulary or improve working-memory rendering end to end.

What Changed

  • tightened automatic memory persistence guidance to exclude derivable repo state, git churn, and ephemeral task chatter
  • taught persistence runs to normalize relative dates into absolute timestamps and to treat stale recalled memory as something to verify, not blindly trust
  • added user_correction and decision_revised as working-memory event types and allowed memory_persistence_complete to persist them
  • replaced the conversational-event regression with deterministic eventual polling instead of a fixed sleep
  • included a minimal clippy cleanup in src/llm/model.rs because repo gates were red on this branch otherwise

Testing

  • just preflight
  • just gate-pr
  • cargo test -p spacebot persists_conversational_events -- --test-threads=1 --nocapture
  • cargo test -p spacebot test_event_type_roundtrip -- --test-threads=1 --nocapture

Notes

  • The src/llm/model.rs change is not part of the memory packet itself. It is the smallest repo-level lint fix needed to get just gate-pr green.
  • Follow-up work should expand the conversational event vocabulary and improve working-memory rendering so recent activity reads less like ops telemetry.

Note

Memory persistence now enforces stricter guard rails on what gets saved durably. The core changes include introducing user_correction and decision_revised event types to capture conversational inflection points, normalizing relative dates to absolute timestamps for cache stability, and filtering out derivable/transient data (repo state, git history, ephemeral task output). These constraints ensure memory captures semantically valuable pivots rather than noise. The MemoryPersistenceConfig docs now clarify that active persistence thresholds are configured via WorkingMemoryConfig rather than the legacy branch cadence. Updated tests verify both new event types round-trip correctly through the persistence pipeline.
Written by Tembo for commit af64604

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 1, 2026

Walkthrough

This PR extends the memory persistence system by introducing two new event types (UserCorrection and DecisionRevised) to the working memory event taxonomy. Changes include updating prompt guidance, adding enum variants, wiring them through serialization, and modifying the persistence tool to validate outcomes before persisting events. Documentation is updated to reflect that working-memory triggers are now configured via WorkingMemoryConfig.

Changes

Cohort / File(s) Summary
Prompt and Tool Documentation
prompts/en/memory_persistence.md.j2, prompts/en/tools/memory_save_description.md.j2
Expanded event type taxonomy guidance to include new user_correction and decision_revised types; added operational rules for ephemeral information exclusion and handling stale memory conflicts.
Configuration Documentation
src/config/types.rs
Updated doc comments for MemoryPersistenceConfig to clarify that active persistence triggers are now configured via WorkingMemoryConfig thresholds; marked message_interval as legacy branch cadence.
Event Type Implementation
src/memory/working.rs
Extended WorkingMemoryEventType enum with UserCorrection and DecisionRevised variants; added string mappings in serialization/deserialization; updated test to verify new variants.
Memory Persistence Tool
src/tools/memory_persistence_complete.rs
Extended WorkingMemoryEventInput schema to accept new event types; refactored event-to-enum conversion to use parse() method; reordered control flow to validate outcome before persisting events; added integration test for new event type persistence.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: tightening memory persistence rules and adding conversational event types (user_correction and decision_revised).
Description check ✅ Passed The description clearly explains the why, scope, what changed, and testing approach, directly relating to the changeset across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/memory-observation-p1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vsumner vsumner marked this pull request as ready for review April 1, 2026 01:58
@vsumner vsumner requested a review from jamiepine April 1, 2026 01:58
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/tools/memory_persistence_complete.rs (1)

203-205: Consider logging when an unrecognized event type falls back to System.

When WorkingMemoryEventType::parse() returns None, the code silently falls back to System. This could mask LLM prompt drift or schema mismatches. A debug/trace log would aid troubleshooting without impacting normal operation.

🔍 Optional: Add trace-level logging for unrecognized event types
-                let event_type =
-                    crate::memory::WorkingMemoryEventType::parse(&event_input.event_type)
-                        .unwrap_or(crate::memory::WorkingMemoryEventType::System);
+                let event_type = match crate::memory::WorkingMemoryEventType::parse(&event_input.event_type) {
+                    Some(et) => et,
+                    None => {
+                        tracing::trace!(
+                            raw_event_type = %event_input.event_type,
+                            "unrecognized event_type, falling back to System"
+                        );
+                        crate::memory::WorkingMemoryEventType::System
+                    }
+                };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/tools/memory_persistence_complete.rs` around lines 203 - 205, The code
silently falls back to WorkingMemoryEventType::System when
WorkingMemoryEventType::parse(&event_input.event_type) returns None; add a
trace- or debug-level log in that branch to record the original
event_input.event_type and that the System fallback was used. Modify the logic
around the parse call that sets event_type (referencing
WorkingMemoryEventType::parse, event_input.event_type, and
WorkingMemoryEventType::System) to detect the None case and emit a trace/debug
message (e.g., using tracing::trace! or log::debug!) before assigning System so
unrecognized event types are visible during troubleshooting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/tools/memory_persistence_complete.rs`:
- Around line 203-205: The code silently falls back to
WorkingMemoryEventType::System when
WorkingMemoryEventType::parse(&event_input.event_type) returns None; add a
trace- or debug-level log in that branch to record the original
event_input.event_type and that the System fallback was used. Modify the logic
around the parse call that sets event_type (referencing
WorkingMemoryEventType::parse, event_input.event_type, and
WorkingMemoryEventType::System) to detect the None case and emit a trace/debug
message (e.g., using tracing::trace! or log::debug!) before assigning System so
unrecognized event types are visible during troubleshooting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6792852a-4058-476f-b3b6-d0df5f911645

📥 Commits

Reviewing files that changed from the base of the PR and between 66846e5 and af64604.

📒 Files selected for processing (6)
  • prompts/en/memory_persistence.md.j2
  • prompts/en/tools/memory_save_description.md.j2
  • src/config/types.rs
  • src/llm/model.rs
  • src/memory/working.rs
  • src/tools/memory_persistence_complete.rs

@vsumner vsumner force-pushed the codex/memory-observation-p1 branch from f47982a to 9850d4d Compare April 7, 2026 23:35
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
prompts/en/memory_persistence.md.j2 (1)

38-41: Clarify where normalized timestamps should be written.

Since events currently have no explicit timestamp field, specify that the absolute timestamp should be embedded in summary when time matters.

Proposed wording tweak
-   - Normalize relative time references to absolute dates/times with timezone
+   - Normalize relative time references to absolute dates/times with timezone
      (for example `2026-03-31T14:20:00-04:00`) so downstream memory checks are
      stable across sessions.
+   - If a timestamp is relevant, include it directly in `summary` (there is no separate event_time field).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@prompts/en/memory_persistence.md.j2` around lines 38 - 41, The prompt should
explicitly state that when normalizing relative times to absolute timestamps,
the generated absolute timestamp must be embedded into the event's summary field
(i.e., write the ISO-8601 timestamp into the existing summary string) because
events lack an explicit timestamp property; update the text in the
memory_persistence.md.j2 prompt to instruct authors to append or include the
normalized timestamp in `summary` (e.g., "…include normalized time as ISO-8601
in the `summary` field") and give a brief example format to use.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@prompts/en/memory_persistence.md.j2`:
- Around line 38-41: The prompt should explicitly state that when normalizing
relative times to absolute timestamps, the generated absolute timestamp must be
embedded into the event's summary field (i.e., write the ISO-8601 timestamp into
the existing summary string) because events lack an explicit timestamp property;
update the text in the memory_persistence.md.j2 prompt to instruct authors to
append or include the normalized timestamp in `summary` (e.g., "…include
normalized time as ISO-8601 in the `summary` field") and give a brief example
format to use.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 19c2aa77-5e14-423d-9c14-ea844e5294fc

📥 Commits

Reviewing files that changed from the base of the PR and between af64604 and 9850d4d.

📒 Files selected for processing (5)
  • prompts/en/memory_persistence.md.j2
  • prompts/en/tools/memory_save_description.md.j2
  • src/config/types.rs
  • src/memory/working.rs
  • src/tools/memory_persistence_complete.rs
✅ Files skipped from review due to trivial changes (1)
  • src/config/types.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • prompts/en/tools/memory_save_description.md.j2
  • src/memory/working.rs
  • src/tools/memory_persistence_complete.rs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant