Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,15 @@ built-in tool.
Graphify's NetworkX node-link JSON directly for native query/path/explain
tools. The default update path is AST-only and local; semantic extraction
is explicit because it may use an LLM backend.
- **Memory Dreams (`src/memory_entry.rs`)** — Claude-style Dreams are
represented as an agent-owned synthesis seam above the local memory
pipeline, not as a `MemoryEntryLifecycle` state. `DreamScheduler`
exposes explicit policy decisions for when an agent should start a dream,
which prior sessions are eligible inputs, and whether a completed output
store may be adopted through the same `decide_use` gate as generated
durable memories. The current layer intentionally does not call a live
Dreams API. Dream output is generated memory state; the original sessions
and input memory store remain source evidence.
- **Persistence (`src/store.rs`, `src/atif_codec.rs`, `src/atif.rs`)** —
the message log encodes to ATIF v1.7 JSONL under
`RA_HOME/sessions/<cwd-hash>/`. `atif_codec` must round-trip;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-06-02
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
## Context

Ra's memory system currently has two layers: `memory_entry.rs` is a pure policy
model for per-entry lifecycle decisions, and `memory.rs` owns local generated
memory artifacts. WS-159 concluded that Claude-style Dreams should be a
follow-on synthesis pass above that pipeline. The agent, not the platform,
decides when to dream, owns the job state, decides whether to adopt the output,
and chooses which memory store to attach to future sessions.

## Goals / Non-Goals

**Goals:**

- Add a pure local policy/state seam for agent-owned Dreams.
- Keep Dreams out of `MemoryEntryLifecycle`; that enum remains per-entry.
- Reuse `MemoryPolicy` and `decide_use` for output adoption.
- Add focused tests for scheduling decisions, input filtering, job adoption, and
config parsing/defaults.

**Non-Goals:**

- No live Anthropic Dreams API client call in this change.
- No persistence format for remote dream job records beyond the local state type.
- No automatic scheduler that starts jobs without an agent decision.

## Decisions

1. Add Dreams to `memory_entry.rs` as pure policy/state types.

Rationale: the existing module is already the pure lifecycle contract future
integrations compose. A Dreams layer needs the same properties: no I/O, no
client calls, and tests that exercise deterministic policy decisions.

Alternative considered: a new runtime module that spawns background jobs. That
would force API and persistence concerns into this first layer and obscure the
agent-owned decision boundary.

2. Model scheduling as `ShouldDreamDecision` plus `DreamSkipReason`.

Rationale: WS-160 requires explicit skip reasons for disabled memories, region
unavailability, low rate-limit headroom, and insufficient sessions. A boolean
API would hide actionable policy state from the agent.

3. Model dream inputs as selected `MemoryCandidate` values.

Rationale: PR #35 already uses `MemoryCandidate` for session-level
eligibility. Reusing it keeps active-session and minimum-duration semantics
consistent with generation decisions while allowing Dreams to ignore idle
delay because they consume prior sessions.

4. Gate adoption through `decide_use`.

Rationale: dream output is generated memory state. It should not bypass the
same global, region, thread-use, external-context, and durability checks used
for ordinary generated memory entries.

## Risks / Trade-offs

- The first layer does not call the Claude Dreams API -> Mitigation: expose job
state and input/output store seams explicitly so a later integration can plug
in a client boundary without changing policy tests.
- Reusing `MemoryCandidate` means the selected inputs do not yet carry remote
session ids -> Mitigation: this layer validates policy/filtering only; the
runtime that owns remote session ids can retain the ids alongside candidates.

## Migration Plan

Additive only. Existing configs continue to parse because the new
`min_sessions_between_dreams` field has a default. Regenerate the config schema
and update the example config.

## Open Questions

- Which Anthropic model/client boundary should own the live `POST /v1/dreams`
call remains for a later integration change.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Why

Ra now has a Codex-style local memory pipeline, but it lacks a policy surface for
an agent to explicitly decide when to consolidate many sessions into a cleaner
memory store. Claude-style Dreams should sit above the per-entry lifecycle as an
agent-owned background synthesis job, not as another `MemoryEntryLifecycle`
state.

## What Changes

- Add a pure Dreams policy/state layer for agent-owned scheduling decisions.
- Represent dream jobs with explicit pending, running, completed, failed, and
canceled states, including input and optional output memory store ids.
- Add input selection that filters active and too-short sessions and caps inputs
at the Claude Dreams API limit of 100 sessions.
- Gate adoption of a completed dream output through the existing memory use
policy instead of bypassing `decide_use`.
- Add memory config support for `min_sessions_between_dreams`, defaulting to 10.
- Document that dream output is generated memory state while source sessions and
the input store remain source evidence.

## Capabilities

### New Capabilities

- `agent-owned-dreams-memory`: Agent-owned Dreams scheduling, job state, input
selection, and output adoption policy for Ra memory synthesis.

### Modified Capabilities

- `codex-style-memory-system`: Add the memory configuration threshold that
controls the minimum number of sessions between Dreams.

## Impact

- Affected code: `src/memory_entry.rs`, `src/memory.rs`, `src/config.rs`,
`src/lib.rs`, config schema/example, and memory tests.
- No live Anthropic Dreams API integration is included in this layer; the new
API is the local policy/state seam that a later client integration can call.
- No new external dependencies.
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
## ADDED Requirements

### Requirement: Agent-Owned Dream Scheduling

Ra SHALL expose a pure agent-side Dreams scheduling decision that returns an
explicit decision object instead of silently skipping work.

#### Scenario: Dream allowed

- **WHEN** memories are enabled, the region is available, rate-limit headroom is
not below policy, and enough sessions have occurred since the last dream
- **THEN** the scheduling decision allows the agent to start a dream

#### Scenario: Dream skipped with reason

- **WHEN** memories are disabled, the region is unavailable, rate-limit headroom
is too low, or too few sessions have occurred since the last dream
- **THEN** the scheduling decision skips the dream and reports the matching
skip reason

### Requirement: Dream Input Selection

Ra SHALL allow the agent to select dream input sessions from session candidates
while excluding ineligible sessions and enforcing the Claude Dreams API input
limit.

#### Scenario: Eligible dream inputs

- **WHEN** candidate sessions are inactive and meet the configured minimum
session duration
- **THEN** Ra selects them as dream inputs

#### Scenario: Ineligible and excess dream inputs

- **WHEN** candidate sessions are active, shorter than the configured minimum
session duration, or exceed the 100-session input cap
- **THEN** Ra excludes active and too-short sessions and returns at most 100
inputs

### Requirement: Dream Job State

Ra SHALL represent agent-owned dream jobs as state that tracks pending, running,
completed, failed, and canceled statuses, the input memory store id, and an
optional output memory store id.

#### Scenario: Dream job tracks output store

- **WHEN** a dream job is completed with an output memory store id
- **THEN** Ra preserves both the original input store id and the completed output
store id in the job state

### Requirement: Dream Output Adoption Gate

Ra SHALL require completed dream outputs to pass through the existing memory use
policy before they can become active for a future session.

#### Scenario: Completed output is considered for use

- **WHEN** a dream job is completed and has an output memory store id
- **THEN** Ra evaluates adoption with the same memory use gate used for generated
durable memory entries

#### Scenario: Non-completed output is suppressed

- **WHEN** a dream job is pending, running, failed, or canceled
- **THEN** Ra suppresses adoption instead of treating the output as active

### Requirement: Dream Evidence Boundary

Ra SHALL document that dream output is generated memory state while original
sessions and the input memory store remain source evidence.

#### Scenario: Developer guidance distinguishes generated state and evidence

- **WHEN** developers read Ra memory documentation for Dreams
- **THEN** the guidance identifies dream output as generated state and identifies
original sessions plus the input memory store as source evidence
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## ADDED Requirements

### Requirement: Dream Scheduling Configuration

Ra SHALL expose a memory configuration threshold for the minimum number of
eligible sessions between agent-owned Dreams.

#### Scenario: Default dream scheduling threshold

- **WHEN** Ra loads a minimal config
- **THEN** the memory policy uses a conservative default of 10 sessions between
Dreams

#### Scenario: Configured dream scheduling threshold

- **WHEN** Ra loads `[memory] min_sessions_between_dreams`
- **THEN** Ra maps that value into the runtime memory policy
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## 1. Dreams Policy Layer

- [x] 1.1 Add agent-owned Dreams scheduling decisions, skip reasons, scheduler, input selection, job state, and output adoption gate.
- [x] 1.2 Keep Dreams outside `MemoryEntryLifecycle` and reuse existing `decide_use` policy for output adoption.

## 2. Memory Config

- [x] 2.1 Add `min_sessions_between_dreams` to memory policy/config with default value 10 and runtime mapping.
- [x] 2.2 Regenerate the Ra config schema and update the example config.

## 3. Tests And Docs

- [x] 3.1 Add unit tests for dream skip branches, input filtering/cap behavior, completed/non-completed adoption, and config default/parsing.
- [x] 3.2 Add developer documentation explaining the Dreams generated-state/source-evidence boundary and no-live-API scope.
- [x] 3.3 Run relevant tests and OpenSpec validation, then archive the accepted change.
81 changes: 81 additions & 0 deletions openspec/specs/agent-owned-dreams-memory/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# agent-owned-dreams-memory Specification

## Purpose
TBD - created by archiving change add-agent-owned-dreams-memory. Update Purpose after archive.
## Requirements
### Requirement: Agent-Owned Dream Scheduling

Ra SHALL expose a pure agent-side Dreams scheduling decision that returns an
explicit decision object instead of silently skipping work.

#### Scenario: Dream allowed

- **WHEN** memories are enabled, the region is available, rate-limit headroom is
not below policy, and enough sessions have occurred since the last dream
- **THEN** the scheduling decision allows the agent to start a dream

#### Scenario: Dream skipped with reason

- **WHEN** memories are disabled, the region is unavailable, rate-limit headroom
is too low, or too few sessions have occurred since the last dream
- **THEN** the scheduling decision skips the dream and reports the matching
skip reason

### Requirement: Dream Input Selection

Ra SHALL allow the agent to select dream input sessions from session candidates
while excluding ineligible sessions and enforcing the Claude Dreams API input
limit.

#### Scenario: Eligible dream inputs

- **WHEN** candidate sessions are inactive and meet the configured minimum
session duration
- **THEN** Ra selects them as dream inputs

#### Scenario: Ineligible and excess dream inputs

- **WHEN** candidate sessions are active, shorter than the configured minimum
session duration, or exceed the 100-session input cap
- **THEN** Ra excludes active and too-short sessions and returns at most 100
inputs

### Requirement: Dream Job State

Ra SHALL represent agent-owned dream jobs as state that tracks pending, running,
completed, failed, and canceled statuses, the input memory store id, and an
optional output memory store id.

#### Scenario: Dream job tracks output store

- **WHEN** a dream job is completed with an output memory store id
- **THEN** Ra preserves both the original input store id and the completed output
store id in the job state

### Requirement: Dream Output Adoption Gate

Ra SHALL require completed dream outputs to pass through the existing memory use
policy before they can become active for a future session.

#### Scenario: Completed output is considered for use

- **WHEN** a dream job is completed and has an output memory store id
- **THEN** Ra evaluates adoption with the same memory use gate used for generated
durable memory entries

#### Scenario: Non-completed output is suppressed

- **WHEN** a dream job is pending, running, failed, or canceled
- **THEN** Ra suppresses adoption instead of treating the output as active

### Requirement: Dream Evidence Boundary

Ra SHALL document that dream output is generated memory state while original
sessions and the input memory store remain source evidence.

#### Scenario: Developer guidance distinguishes generated state and evidence

- **WHEN** developers read Ra memory documentation for Dreams
- **THEN** the guidance identifies dream output as generated state and identifies
original sessions plus the input memory store as source evidence

16 changes: 16 additions & 0 deletions openspec/specs/codex-style-memory-system/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,19 @@ existing memoryEntry lifecycle policy before writing artifacts.
- **THEN** Ra redacts those fields before writing and records that redaction was
applied

### Requirement: Dream Scheduling Configuration

Ra SHALL expose a memory configuration threshold for the minimum number of
eligible sessions between agent-owned Dreams.

#### Scenario: Default dream scheduling threshold

- **WHEN** Ra loads a minimal config
- **THEN** the memory policy uses a conservative default of 10 sessions between
Dreams

#### Scenario: Configured dream scheduling threshold

- **WHEN** Ra loads `[memory] min_sessions_between_dreams`
- **THEN** Ra maps that value into the runtime memory policy

7 changes: 7 additions & 0 deletions spec/ra-config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,13 @@
"format": "uint64",
"minimum": 0.0
},
"min_sessions_between_dreams": {
"description": "Minimum completed eligible sessions between agent-owned Dreams.",
"default": 10,
"type": "integer",
"format": "uint",
"minimum": 0.0
},
"region_available": {
"description": "Region availability gate. Exposed for parity with Codex-style policy; default true for local Ra.",
"default": true,
Expand Down
1 change: 1 addition & 0 deletions spec/ra.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ mode = "default" # default | plan | ask
# min_idle_before_generation_secs = 600
# min_session_duration_secs = 60
# min_rate_limit_remaining_percent = 0
# min_sessions_between_dreams = 10
# dir = "~/.local/share/ra/memories" # optional override
# max_prompt_memories = 20

Expand Down
Loading
Loading