Overview
Expand entity_facts.data_type beyond the current "observation" default to include temporal classifications that distinguish ephemeral states from durable traits, and add a first-class "decision" type with do-not-reopen semantics.
Motivation
The memory extractor currently treats all extracted facts equally. A passing "I hate mornings" gets the same durability as "I'm a software engineer." This causes temporary emotional states to persist as permanent identity facts, and settled decisions to be reopened by future sessions that do not have the original reasoning context.
Emerged from architecture discussion with Edmund — the need for mood/state/trait distinction and explicit decision tracking with reasoning.
Related to #141 (extraction categories) but focused on the schema and lifecycle side rather than extraction prompt changes.
Proposed data_type Values
| data_type |
Description |
Lifecycle |
Example |
observation |
General fact (current default) |
Normal confidence decay |
"Lives in Austin" |
preference |
Durable preference |
Slow decay, high recall priority |
"Prefers dark mode" |
mood |
Ephemeral emotional state |
Auto-decays within 24-48h |
"Feeling stressed today" |
state |
Current but temporary condition |
Auto-decays within 1-2 weeks |
"Working on deadline for Friday" |
trait |
Durable identity/personality fact |
Very slow decay, high confidence |
"Is an introvert" |
decision |
Explicit settled decision |
No auto-decay, do_not_reopen flag |
"We use pnpm not npm for openclaw" |
routine |
Recurring pattern/habit |
No auto-decay |
"Takes medication at 9am" |
obligation |
Commitment with deadline |
Decays after deadline passes |
"Present at conference May 15" |
Schema Changes
-- Expand data_type to support new values
-- Current: defaults to 'observation'
ALTER TABLE entity_facts
DROP CONSTRAINT IF EXISTS entity_facts_data_type_check;
-- Add check constraint for valid types
ALTER TABLE entity_facts
ADD CONSTRAINT entity_facts_data_type_check
CHECK (data_type IN (
'observation', 'preference', 'mood', 'state',
'trait', 'decision', 'routine', 'obligation'
));
-- For decisions: add reasoning and do_not_reopen fields
-- Option A: Use entity_facts.data jsonb field for metadata
-- Option B: Dedicated decisions table (if decisions need richer schema)
Memory Extractor Changes
- Extraction prompt must classify temporal nature of facts
- Moods should NEVER auto-promote to traits
- Decisions must capture: what was decided, alternatives considered, reasoning, decided_by, decided_at
Memory Maintenance Changes
- memory-maintenance.py needs type-specific decay rates:
- mood: aggressive decay (24-48h half-life)
- state: moderate decay (1-2 week half-life)
- trait/decision/routine: very slow or no auto-decay
- obligation: decay after deadline date passes
Relationship to Existing Issues
Acceptance Criteria
Overview
Expand entity_facts.data_type beyond the current "observation" default to include temporal classifications that distinguish ephemeral states from durable traits, and add a first-class "decision" type with do-not-reopen semantics.
Motivation
The memory extractor currently treats all extracted facts equally. A passing "I hate mornings" gets the same durability as "I'm a software engineer." This causes temporary emotional states to persist as permanent identity facts, and settled decisions to be reopened by future sessions that do not have the original reasoning context.
Emerged from architecture discussion with Edmund — the need for mood/state/trait distinction and explicit decision tracking with reasoning.
Related to #141 (extraction categories) but focused on the schema and lifecycle side rather than extraction prompt changes.
Proposed data_type Values
observationpreferencemoodstatetraitdecisionroutineobligationSchema Changes
Memory Extractor Changes
Memory Maintenance Changes
Relationship to Existing Issues
Acceptance Criteria