DOC72_PROPOSAL_CONTINUITY_SYNTHESIS_ARCHITECTURE_R2.md
Current Specs/DOC72/DOC72_PROPOSAL_CONTINUITY_SYNTHESIS_ARCHITECTURE_R2.md
# DOC72 Proposal — Continuity Synthesis Architecture (CSA) R2
**Date:** 2026-04-29
**Status:** Draft normative proposal for DOC72 R5.74 integration. Supersedes CSA R1 (2026-04-13).
**Target:** DOC72 (primary), with cross-doc obligations into DOC24, DOC11, DOC15, DOC73, DOC8, DOC2 (retirement), EC Core.
**Purpose:** A unified architecture for short-term work-state continuity, three-tier fresh-surface context injection, activity-type-aware significance gating, and DOC2 retirement. Reconciles RRB v6's intent with the modern spec suite (DOC72 R5.73, DOC24 R3, DOC15 R7.1, DOC73 V1.5.1) and OpenClaw's documented runtime hooks.
**Schema alignment:** All references verified against DOC72 R5.73, DOC24 R3, DOC15 R7.1, DOC73 V1.5.1 FINAL operative schemas.
---
## R1 → R2 Change Summary (read this first if you reviewed R1)
R2 is a substantial revision driven by four findings since R1 was drafted:
1. **DOC73 V1.5.1 already specifies session and cross-session narrative summarization** (§6.3 + §6.4 Mechanisms 1, 3, 4). CSA must INTEGRATE with these mechanisms, not run parallel to them. R1's continuity agent had its own LLM session-summary path that duplicates DOC73 §6.3. R2 collapses to one session-end LLM pass.
2. **OpenClaw exposes a documented ContextEngine plugin slot with named lifecycle hooks** (`bootstrap`, `ingest`, `assemble`, `compact`, `afterTurn`, `prepareSubagentSpawn`, `onSubagentEnded`) plus a pre-compaction memory-flush turn. R1 had vague hook prose. R2 targets these explicitly.
3. **OpenClaw Dreaming has expanded** (v2026.4.9 grounded REM backfill, dreaming.model knob, redacted transcript ingestion). R1 §5.6 said "coexist." R2 says **disable** — ELNOR's pipeline is canonical for ELNOR users; running both creates a competing memory truth-store.
4. **RRB v6 is retired.** Its three OCM jobs are reframed: Job 1 (brief construction) becomes the CSA continuity card per §6.1 below, Job 2 (cross-surface semantic query) becomes new §7, Job 3 (per-surface compressed summaries) is dropped. The OCM agent name is preserved per DOC15 R7.1's reference, but recast as a deterministic-by-default state renderer with sparse LLM augmentation.
R2 also adds three new sections: §7 (Cross-Surface Semantic Query), §8 (Direct Session Transcript Access), §9 (External Surface Observation Pathways — gap acknowledgment). And it restructures the fresh-surface injection model into an explicit three-tier system (§6) with anti-duplication rules.
A full R1→R2 diff is in Appendix D.
---
## 0. Governing Principles
1. **One brain, not two.** All durable knowledge lives in the DOC72 entity graph. Continuity data is staged in a lightweight log and promoted into the graph by a governed pipeline. The constellation is a derived read-model — a view over graph + log — not a second truth store.
2. **Continuity is ephemeral by default, durable by promotion.** Session summaries, open questions, and key decisions start in the continuity log with timestamps and decay policies. Only items that prove durable (referenced again, linked to deadlines, user-confirmed) graduate into the canonical graph.
3. **Deterministic first, LLM-enriched optionally.** The core continuity capture (entity references, procedure completions, timestamps, work-phase) is deterministic and always available. LLM-generated narrative synthesis is additive, configurable, and independently disableable.
4. **One session-end LLM pass, not many.** DOC73 §6.3 already specifies a session-summarization LLM call at session close. CSA does NOT run a second parallel pass. CSA's narrative `session_summary` is identical to DOC73's `session_summary` field; CSA's structured extras (open_questions, key_decisions, work_phase) are extracted in the same pass.
5. **Domain-agnostic.** All schemas, triggers, and decay policies use generic terminology. Legal, development, music, and personal work streams use the same architecture. Domain signal profiles enhance entity recognition but are never required.
6. **No prompt bloat.** Continuity data enters the LLM through DOC24's existing delivery pipeline as tagged cards within the existing token budget waterfall (DOC24 R3 §19.1A). No new injection channel. The three-tier injection model (§6) defines explicit per-tier budgets that fit within the surface profile caps.
7. **Compaction-safe.** Continuity capture runs BEFORE OpenClaw compaction so that work-state context survives summarization. R2 targets the documented OpenClaw `compact` hook and the existing pre-compaction memory-flush turn.
8. **OpenClaw Dreaming is disabled.** ELNOR's nightly extraction pipeline is the canonical knowledge-consolidation path (DOC72 nightly_consolidation_pass, DOC73 PBE consolidation, DOC8 utility tracking, BDSM ledger consolidation). Dreaming runs a parallel pipeline that competes with ELNOR's governance and is not used in ELNOR deployments. See §10.
---
## 1. Problem Statement
### 1.1 The continuity gap (unchanged from R1)
ELNOR captures durable knowledge (entities, relationships, procedures, confidence) and delivers it via DOC24's packet assembly. But it does not capture WHERE THE USER LEFT OFF — the narrative work-state that connects one session to the next.
When the user opens a conversation after a week away, entity resolution can pull `Henderson` (graph entity, confidence 0.95). But it cannot tell the agent: "You were drafting the damages section. Subsections 1-3 are done. Event study section pending — waiting on expert data from Christensen. You decided to focus on price impact approach."
That narrative context is currently lost to compaction, model switching, and session boundaries.
### 1.2 The cross-conversation gap (unchanged from R1)
ELNOR sessions are independent. Work done in one conversation does not automatically inform another. If the user updates DOC72 in conversation A, creates a new DOC24 addendum in conversation B, and discusses an OpenClaw update in conversation C, then returns to conversation A a week later — conversation A has no awareness that B and C happened.
### 1.3 The compaction problem (unchanged from R1)
OpenClaw compacts long conversations by summarizing early turns. After compaction, nuanced work-state details are lost. If continuity is captured BEFORE compaction, the work-state survives in the continuity log even when the conversation transcript does not.
### 1.4 The model-switching problem (unchanged from R1)
When the user switches from Gemini to Claude mid-conversation (or between conversations), the new model receives the transcript text cold. Continuity data — stored outside the transcript in the graph-linked continuity log — is model-independent and survives switching.
### 1.5 The fresh-surface orientation gap (NEW in R2)
When a fresh agent surface opens (new chat window, new model, new IDE session), the agent has zero context about the user's recent work. The user compensates by typing a preamble: "I'm working on Smith v. Acme, drafting the opposition to motion to dismiss, struggling with §III scienter formulation, recent rulings…"
The user wants this loaded automatically. R2 specifies a three-tier injection (§6) that delivers:
- **Tier 1 (per-work-context, work-state):** Where you are right now in this specific thread.
- **Tier 2 (cross-context, recent activity):** What you've been doing lately across all your work.
- **Tier 3 (stable facts):** Who you are and your standing preferences.
Tiers 1 and 3 are CSA-/DOC73-native. Tier 2 depends on DOC73 §6.4 Mechanism 4 (weekly/monthly rollup), which is named but undefined; CSA R2 declares a cross-doc obligation to DOC73 R-next to specify Mechanism 4 (see Appendix A.4).
### 1.6 What other systems do (updated in R2)
- **Claude.ai memory:** Generated rolling summaries, extracted post-conversation, stored separately, injected globally into every new chat. Flat-text, no work-context isolation, no graph linkage.
- **OpenAI / ChatGPT memory:** Persistent fact storage ("user has a daughter named X"). Closer to ELNOR's `memory_directive` nodes than to work-state continuity. Global, no session-bridging narrative.
- **OpenClaw Dreaming (v2026.4.9+):** Background memory consolidation via REM phases. Ingests redacted session transcripts. Writes Dream Diary at `DREAMS.md` and consolidates daily memory signals into `MEMORY.md`. **ELNOR does not use Dreaming** — see §10.
- **OpenClaw Active Memory plugin:** Blocking pre-reply sub-agent that surfaces recalled facts. Disabled in ELNOR per DOC24 R2.5 §19.3A; CSA's three-tier injection is strictly superior for ELNOR's use case.
ELNOR's CSA architecture is distinguished by: per-work-context isolation (no cross-contamination between unrelated topics), event-driven capture (not always-on background LLM), graph-linked structured entries (not flat text), governed promotion to durable memory (not direct memory writes), and integration with DOC24's existing token budget waterfall (no new injection channels).
### 1.7 OpenClaw Dreaming coexistence — re-examined
R1 §1.5 / §5.6 proposed that ELNOR could coexist with Dreaming by treating `MEMORY.md` and `DREAMS.md` as source surfaces for DOC72 intake. R2 reverses this. Reasoning:
- Dreaming runs on raw session transcripts (its native input). ELNOR's nightly extraction pipeline also runs on transcripts. **Both consuming the same input is duplicate work.**
- Dreaming produces flat-text MEMORY.md. ELNOR produces structured DOC72 entity nodes with provenance, significance gating, sealed-signal partitioning, and BDSM utility tracking. Re-extracting Dreaming's flat-text output into ELNOR's pipeline LOSES the very structure ELNOR's pipeline produces directly.
- Configuration overhead, conflicting state risk, and unclear canonical truth justification are all real costs of running both.
**Recommendation:** ELNOR deployments disable Dreaming (`openclaw.dreaming.mode = "off"`). This is documented in §10 and Appendix A.5 (EC Core obligation).
---
## 2. Architecture Overview
### 2.1 Components
```
┌─────────────────────────────────────────────────────────────────┐
│ Sessions (chat / room / panel / forum / external) │
└─────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
afterTurn hook compact hook bootstrap hook
(continuity capture (pre-compaction (fresh-surface
triggers + dirty memory-flush injection)
flag check) piggyback)
│ │ │
▼ ▼ │
Continuity Agent ────────────────────► │
│ │
▼ │
Continuity Log (per work_context_id) │
ELNOR_MEMORY/continuity/{work_context_id}.jsonl │
│ │
▼ │
Constellation Builder ◄──── DOC72 graph (entities) │
│ │
▼ │
ELNOR_MEMORY/mirror/work_context/{wc_id}.json │
│ │
▼ │
DOC24 Packet Assembly ◄─────────────────────────────┘
│
│ Tier 1: continuity card (resume tag, 60-120 tok)
│ Tier 2: rollup card (recent_activity tag, 100-200 tok)
│ Tier 3: PBE living memory card (existing infra, 50-100 tok)
▼
LLM Prompt
│
▼
Nightly Promotion Engine ───► DOC72 graph (durable nodes)
├─► Continuity log cleanup (decay)
└─► DOC73 §6.4 Mechanism 4 rollup
(recent_activity.md)
```
**Continuity Agent (§5):** A configurable background process (deterministic or LLM-enriched). Triggers via OpenClaw's documented `afterTurn` and `compact` hooks. Writes to the continuity log. Does NOT write to the graph directly. Does NOT run a separate session-summary LLM pass — defers to DOC73 §6.3.
**Continuity Log (§3):** Per-work-context append-only JSONL files under `ELNOR_MEMORY/continuity/`. Staging area for ephemeral work-state data. Entries carry timestamps and decay naturally.
**Constellation Builder (§4):** Extends DOC72 R5.73 §42A (absorbed-GIE V2.2) constellation schema with continuity fields. Reads from both the graph (permanent entities, goals, obligations) AND the continuity log (session history, open questions, key decisions). Produces a merged view.
**Three-Tier Injection (§6):** The constellation feeds the Tier 1 continuity card. DOC73 §6.4 Mechanism 4 rollup feeds the Tier 2 recent-activity card. DOC73 PBE living memory feeds the Tier 3 stable-facts card. All three injected at fresh-surface boot via DOC24's existing packet pipeline.
**Promotion Engine (§3.3):** Nightly job. Reviews continuity log entries, promotes qualifying entries into the canonical graph (unresolved questions linked to deadlines → obligation nodes; key decisions referenced 3+ times → memory_directive nodes; etc.). Coordinates with DOC73 §6.4 Mechanism 4 to produce the cross-context rollup file.
### 2.2 Truth boundaries
| Store | Type | Owner | Canonical? | Rebuildable? |
|---|---|---|---|---|
| `entity_graph.sqlite` | SQLite | EC / DOC72 | Yes | No — this IS truth |
| `ELNOR_MEMORY/continuity/{wc_id}.jsonl` | JSONL | EC | Yes (staging truth) | No — contains LLM-generated content |
| `ELNOR_MEMORY/mirror/work_context/{wc_id}.json` | JSON | EC | No — derived view | Yes — from graph + continuity log |
| `ELNOR_MEMORY/rollup/recent_activity.md` | Markdown | EC | Yes (staging truth) | No — contains LLM-generated narrative |
| DOC73 session manifests (per DOC73 §6.3-6.4) | Per DOC73 | EC / DOC73 | Yes | No |
The continuity log is canonical for its own content (session work-state, open questions, key decisions) but is NOT part of the entity graph. It's a governed staging area. The constellation is a derived view that merges graph + continuity log. The rollup file is generated nightly from session manifests + continuity log entries; not the entity graph itself.
### 2.3 Three-tier injection summary (full spec in §6)
| Tier | Source | Tag | Budget | Cadence | Scope |
|---|---|---|---|---|---|
| 1 | Continuity log + DOC72 entities | `resume` | 60-120 tok | Real-time (event-triggered) | This work context |
| 2 | DOC73 §6.4 Mechanism 4 rollup | `recent_activity` | 100-200 tok | Nightly | All work contexts (excluding current Tier-1 context) |
| 3 | DOC73 PBE living memory | `living_memory` | 50-100 tok | Slow-changing (consolidation cadence) | User-stable facts and preferences |
Total fresh-surface continuity budget: 210-420 tokens. Fits within DOC24 R3 chat surface profile (250-350 tokens for context layers, expandable to ~400 with Lane 1 borrowing).
---
## 3. Continuity Log
### 3.1 Storage
One JSONL file per work context:
```
ELNOR_MEMORY/continuity/{work_context_id}.jsonl
```
For conversations not linked to a named work context, a synthetic work context ID is derived from the primary entities discussed: `wc_auto_{sha256(sorted_entity_ids)[:12]}`. If no entities are resolved, entries go to `wc_unlinked.jsonl` (limited to 20 entries, oldest-first eviction).
### 3.2 Entry schema (R2 — updated)
```ts
type ContinuityEntry = {
entry_id: string;
entry_type: "session_summary_ref" | "open_question" | "key_decision"
| "cross_conversation_update" | "work_phase_change";
// Source
source_session_id: string; // OpenClaw session ID
source_agent_id?: string; // Which agent produced this
captured_at: string; // ISO datetime
capture_mode: "deterministic" | "llm_enriched";
// Content (varies by entry_type)
content: SessionSummaryRefContent | OpenQuestionContent | KeyDecisionContent
| CrossConversationUpdateContent | WorkPhaseChangeContent;
// Lifecycle
delivered: boolean; // For cross_conversation_update
promoted_to_graph: boolean;
promoted_node_id?: string;
decay_at: string; // ISO datetime — when this entry expires
// Linking
linked_entity_ids: string[];
work_context_id: string;
linked_doc73_session_summary_id?: string; // R2: reference to DOC73 §6.3 summary
schema_version: 2;
};
// R2 CHANGE: was SessionSummaryContent. Now references DOC73 §6.3 instead
// of carrying its own narrative summary text. The narrative lives
// in DOC73 session manifests, not in the continuity log.
type SessionSummaryRefContent = {
doc73_session_summary_id: string; // R2: pointer to DOC73 §6.3 summary
entities_referenced: string[]; // From DOC24 entity resolution
procedures_executed: string[]; // From execution receipts
tools_used: string[]; // From action receipts
turn_count: number;
duration_minutes?: number;
};
type OpenQuestionContent = {
question: string; // "Need to check with Christensen about data timeline"
context: string; // Brief context
resolved: boolean;
resolved_at?: string;
resolution_summary?: string;
};
type KeyDecisionContent = {
decision: string; // "Focusing on price impact approach for loss causation"
rationale?: string; // "Corrective disclosure alone was insufficient per Judge Chen"
superseded_by?: string; // entry_id of a later decision that replaces this
};
type CrossConversationUpdateContent = {
summary: string; // "Henderson updated in another conversation"
source_session_id: string;
affected_entity_ids: string[];
};
type WorkPhaseChangeContent = {
previous_phase?: string;
new_phase: string; // "drafting" | "research" | "review" | "waiting_for_external" | "revision" | "completed"
reason?: string;
};
```
### 3.3 Decay policy
Every continuity entry has a `decay_at` timestamp computed at write time:
| Entry type | Default TTL | Notes |
|---|---|---|
| `session_summary_ref` | 30 days | Pointer becomes stale; underlying DOC73 summary may persist longer per DOC73 retention policy |
| `open_question` | 60 days | Longer because unresolved questions remain relevant |
| `key_decision` | 60 days | Decisions shape ongoing work direction |
| `cross_conversation_update` | 7 days after delivery | One-time notification; consumed and cleared |
| `work_phase_change` | 30 days | Only the latest phase matters |
TTL values are Category C (user-configurable) parameters in `ELNOR_MEMORY/config/continuity_config.json`.
**Pre-decay promotion check** (nightly, by Promotion Engine):
- Open question still unresolved after 14 days AND linked to entity with deadline → promote to `obligation` node.
- Key decision referenced in 3+ sessions → promote to `memory_directive` node.
- `session_summary_ref`: pointer decays normally; the underlying DOC73 summary follows DOC73's retention rules independently.
If promotion occurs, `promoted_to_graph: true` and `promoted_node_id` are set. The entry then decays on schedule.
### 3.4 Dynamic window sizing
The constellation builder limits how many `session_summary_ref` entries are included in the view. Window is proportional to activity density:
```ts
function computeEffectiveWindow(
config: ContinuityConfig,
sessionsInLast30Days: number,
): number {
return Math.min(
config.max_session_history_window, // Category C, default 15, range 3-25
sessionsInLast30Days + 2,
);
}
```
A work context touched 12 times in 30 days gets 14 entries. One touched twice gets 4. Prevents starvation of active contexts and stale baggage on dormant ones.
---
## 4. Constellation Schema Extension
### 4.1 New fields on WorkContextConstellationSchema
Extending DOC72 R5.73 §42A `WorkContextConstellationSchema` with continuity fields:
```ts
export const ContinuityEnrichmentSchema = z.object({
// R2: now stores REFERENCES to DOC73 session summaries, not raw text
session_history: z.array(z.object({
doc73_session_summary_id: z.string().max(120),
captured_at: z.string().datetime(),
source_session_id: z.string().max(120),
turn_count: z.number().int().optional(),
capture_mode: z.enum(["deterministic", "llm_enriched"]),
})).default([]), // Bounded by dynamic window (§3.4)
cross_conversation_updates: z.array(z.object({
summary: z.string().max(300),
source_session_id: z.string().max(120),
captured_at: z.string().datetime(),
delivered: z.boolean().default(false),
})).default([]),
open_questions: z.array(z.object({
question: z.string().max(300),
context: z.string().max(200).optional(),
captured_at: z.string().datetime(),
source_session_id: z.string().max(120),
resolved: z.boolean().default(false),
})).default([]), // Max 10
active_work_phase: z.enum([
"research", "drafting", "review", "revision",
"waiting_for_external", "completed", "paused", "unknown",
]).default("unknown"),
key_decisions: z.array(z.object({
decision: z.string().max(300),
rationale: z.string().max(300).optional(),
captured_at: z.string().datetime(),
source_session_id: z.string().max(120),
superseded_by: z.string().max(120).optional(),
})).default([]), // Max 5
});
```
### 4.2 Revised constellation build rules
Build inputs:
1. Graph entities, goals, obligations linked to the work context (DOC72 R5.73 baseline)
2. Recent mention observations from backlink pipeline (DOC72 R5.73 §42A)
3. Confirmed co-occurrence motifs (DOC72 R5.73 §42A)
4. Recent experience/provenance deltas
5. **Continuity log entries** for this work context (`ELNOR_MEMORY/continuity/{wc_id}.jsonl`)
6. **DOC73 session summaries** referenced by `session_history[].doc73_session_summary_id` (R2)
Build procedure for continuity fields (unchanged from R1 except for §6 above):
1. Read all non-expired entries from the continuity log for this work context.
2. Filter `session_summary_ref` entries by dynamic window (§3.4); for each, fetch the linked DOC73 session_summary text via `doc73_session_summary_id`.
3. Filter `open_questions`: remove resolved, cap at 10.
4. Filter `key_decisions`: remove superseded, cap at 5.
5. Filter `cross_conversation_updates`: include only undelivered.
6. Set `active_work_phase` from most recent `work_phase_change` entry.
7. Merge with DOC72 R5.73 §42A baseline content.
**On delivery:** When constellation is delivered (via DOC24 continuity card), mark all `cross_conversation_updates` as `delivered: true`. On next rebuild, delivered updates older than 7 days are removed.
### 4.3 Rebuild triggers
The constellation is rebuilt when:
- Work context's entities/goals/obligations change in the graph
- New continuity log entry written for this work context
- A continuity log entry is promoted to the graph
- A continuity log entry decays (nightly)
- A linked DOC73 session_summary is updated
- Manual refresh requested via Knowledge Manager
Rebuilds are asynchronous. If a stale constellation is requested before rebuild completes, the stale version is served with `stale: true` (per DOC72 R5.73 §42A async rendering rule).
---
## 5. Continuity Agent
### 5.1 Operating modes
```ts
export const ContinuityConfigSchema = z.object({
mode: z.enum(["full", "deterministic", "off"]).default("full"),
// R2: synthesis_model is consumed by DOC73 §6.3 — same knob
synthesis_model: z.string().max(120).optional(),
// Trigger tuning
min_dirty_turns: z.number().int().positive().default(3),
idle_trigger_minutes: z.number().int().positive().default(15),
debounce_minutes: z.number().int().positive().default(30),
// Window and decay
max_session_history_window: z.number().int().min(3).max(25).default(15),
session_summary_ttl_days: z.number().int().positive().default(30),
open_question_ttl_days: z.number().int().positive().default(60),
key_decision_ttl_days: z.number().int().positive().default(60),
cross_update_ttl_days_after_delivery: z.number().int().positive().default(7),
// R2: deterministic-mode heuristic capture for open_questions / key_decisions
// (without LLM). Catches some signal but degraded vs full mode.
deterministic_heuristic_capture: z.boolean().default(true),
schema_version: z.literal(2),
});
```
| Mode | Deterministic | LLM | Notes |
|---|---|---|---|
| `full` | Yes | Yes (via DOC73 §6.3) | Default. Rich narrative session summaries, nuanced open_questions and key_decisions extraction. |
| `deterministic` | Yes | No | Free, offline. Captures `session_summary_ref` (with templated summary), `work_phase_change`, `cross_conversation_update`. Optionally captures `open_questions` and `key_decisions` via heuristic detection (§5.3). Honestly degraded vs `full`. |
| `off` | No | No | Nothing captured. CSA's tier-1 card empty for this user; tier-2 and tier-3 unaffected. |
**Storage:** `ELNOR_MEMORY/config/continuity_config.json`
**Q Settings surface:** A "Continuity" section with mode toggle, synthesis model selector, and explanatory text:
> "This feature captures work-state context across sessions. 'Deterministic' mode is free and works offline but does not extract open questions or key decisions narratively (uses heuristic detection only). 'Full' mode adds LLM-generated narrative through DOC73's session summarization pass — recommended."
### 5.2 Trigger model — OpenClaw hooks (R2 — updated)
R2 specifies the continuity agent as a **ContextEngine plugin** (per OpenClaw's documented plugin slot). The plugin registers handlers on three lifecycle hooks:
```ts
// Pseudocode
registerContextEnginePlugin({
name: "elnor-continuity",
hooks: {
afterTurn: async (turn, session) => {
markDirty(session);
const trigger = checkTriggerConditions(session);
if (trigger) await captureContinuity(session, trigger);
},
compact: async (session, ctx) => {
// Pre-compaction memory-flush piggyback (CRITICAL trigger)
await captureContinuity(session, "pre_compaction");
},
bootstrap: async (session, ctx) => {
// Fresh-surface injection — see §6
await injectThreeTierContext(session, ctx);
},
},
});
```
**Dirty flag:** A session is "dirty" when it has had meaningful activity since the last continuity capture. "Meaningful" means:
- At least `min_dirty_turns` user messages (default 3), OR
- At least one tool execution, OR
- At least one entity resolution that produced a candidate.
Glancing at a chat and switching away does NOT set the flag.
**Trigger conditions** (any of these fires capture for dirty sessions):
```ts
type ContinuityTrigger =
| "idle_timeout" // Dirty session idle for idle_trigger_minutes (default 15)
| "debounced_defocus" // Dirty session lost focus AND debounce_minutes (default 30) elapsed since last capture
| "pre_compaction" // OpenClaw `compact` hook fired — CRITICAL trigger
| "nightly_sweep" // Nightly job captures all dirty sessions
| "manual_request"; // User or system explicitly requests capture
```
**Pre-compaction is mandatory** when continuity mode is not `off`. The `compact` hook is the documented OpenClaw lifecycle event; CSA piggybacks on the existing pre-compaction memory-flush turn so capture happens before the conversation is summarized away.
**Rapid session switching scenario** (unchanged from R1):
User touches Henderson at 9:00, switches to Johnson at 9:03, back to Henderson at 9:08, to DOC24 at 9:11, back to Johnson at 9:16.
| Time | Action | Henderson | Johnson | DOC24 | Agent fires? |
|---|---|---|---|---|---|
| 9:00 | Henderson (5 turns) | Dirty | — | — | No |
| 9:03 | → Johnson | Dirty (defocused) | — | — | No (debounce 0 min) |
| 9:08 | → Henderson | Dirty (refocused) | — | — | No |
| 9:11 | → DOC24 | Dirty (defocused 11 min) | — | — | No |
| 9:16 | → Johnson (3 turns) | Dirty | Dirty | — | No |
| 9:30 | Still Johnson | Dirty (debounce 30 met) | Dirty | — | **Yes — Henderson** |
| 9:46 | Idle 15 min on Johnson | — | Dirty (idle met) | — | **Yes — Johnson** |
Two captures in 46 minutes, not five.
### 5.3 Deterministic capture (R2 — updated)
In all modes, deterministic capture writes structured signals without an LLM call:
```ts
function captureDeterministic(session: SessionState): Partial<ContinuityEntry>[] {
const entries: Partial<ContinuityEntry>[] = [];
const entityIds = session.resolvedEntityIds;
const procedureIds = session.executedProcedureIds;
const toolIds = session.usedToolIds;
const turnCount = session.userTurnCount;
// Session summary REFERENCE — no narrative text in continuity log itself
// Narrative summary lives in DOC73 §6.3 manifest; this entry references it.
entries.push({
entry_type: "session_summary_ref",
capture_mode: "deterministic",
content: {
doc73_session_summary_id: session.doc73SessionSummaryId, // empty in pure-deterministic mode
entities_referenced: entityIds,
procedures_executed: procedureIds,
tools_used: toolIds,
turn_count: turnCount,
},
linked_entity_ids: entityIds,
});
const lastRoutingDecision = session.lastRoutingDecision;
if (lastRoutingDecision?.activity_type) {
const currentPhase = mapActivityTypeToPhase(lastRoutingDecision.activity_type);
entries.push({
entry_type: "work_phase_change",
capture_mode: "deterministic",
content: { new_phase: currentPhase },
linked_entity_ids: entityIds,
});
}
// R2 NEW: heuristic capture of open_questions and key_decisions
// when deterministic_heuristic_capture is enabled
if (config.deterministic_heuristic_capture) {
const heuristicQuestions = extractHeuristicQuestions(session.recentTurns);
const heuristicDecisions = extractHeuristicDecisions(session.recentTurns);
for (const q of heuristicQuestions) {
entries.push({
entry_type: "open_question",
capture_mode: "deterministic",
content: { question: q.text, context: q.context, resolved: false },
linked_entity_ids: entityIds,
});
}
for (const d of heuristicDecisions) {
entries.push({
entry_type: "key_decision",
capture_mode: "deterministic",
content: { decision: d.text, rationale: undefined },
linked_entity_ids: entityIds,
});
}
}
return entries;
}
function extractHeuristicQuestions(turns: Turn[]): { text: string; context: string }[] {
// Heuristic patterns — NOT LLM-grade quality, but free
// - User messages ending with "?" that contain "I'll come back to" / "let me deal with that later" / "TODO" / "remember to"
// - "I need to" / "we need to" + verb followed by entity reference
// - "still need to figure out" / "open question"
// Returns 0-N candidate open questions; degrades gracefully on noise.
// Implementation deferred to build phase.
return [];
}
function extractHeuristicDecisions(turns: Turn[]): { text: string }[] {
// Heuristic patterns
// - "we decided" / "let's go with" / "going with" + claim
// - "I'll commit to" / "we're committing to" + claim
// - Strong-language claims: "definitely", "for sure"
// Returns 0-N candidate key decisions; degrades gracefully on noise.
return [];
}
function mapActivityTypeToPhase(activityType: string): string {
const mapping: Record<string, string> = {
research: "research",
drafting: "drafting",
communication: "drafting",
strategic: "review",
operational: "drafting",
recall: "unknown",
};
return mapping[activityType] ?? "unknown";
}
```
**Honest characterization:** deterministic mode catches some open-question and key-decision signal via heuristic but is genuinely degraded vs. `full` mode. Heuristics generate false positives (rhetorical questions, hedged "we should consider" not actually decisions). The continuity card rendering (§6) marks heuristic-captured entries with reduced confidence in the constellation view.
### 5.4 LLM-enriched capture (R2 — UPDATED — DEFERS TO DOC73 §6.3)
R2 fundamental change: **CSA does not run a separate session-summary LLM pass.**
Instead, CSA hooks into the DOC73 §6.3 session-summarization pipeline. DOC73's existing pass produces:
- `session_summary` (200-500 tokens narrative) — owned by DOC73, written to session manifest.
CSA augments this single pass to additionally extract:
- `open_questions` (structured array)
- `key_decisions` (structured array)
- `work_phase` (single enum value)
The synthesis prompt is jointly governed by DOC73 §6.3 and CSA. Recommended unified prompt (subject to DOC73 §6.3 normative authority):
```
You are reviewing a conversation to capture both a session summary and
work-state continuity for cross-session reference.
Given the recent conversation turns below:
PART A — SESSION SUMMARY (DOC73 §6.3):
A 1-2 sentence narrative of what was accomplished and what remains. Focus
on work state, not topic summary. Good: "Drafted subsections 1-3 of the
damages section. Event study section pending — waiting on expert data."
Bad: "Discussed the Henderson case." (200-500 tokens)
PART B — STRUCTURED EXTRAS (CSA):
1. OPEN QUESTIONS: Things the user said they'd come back to, asked but
didn't fully resolve, or explicitly deferred. Only genuine open items,
not rhetorical questions.
2. KEY DECISIONS: Strategic or directional decisions made during this
session that shape future work. Only decisions that would matter if
the user resumed this work next week.
3. WORK PHASE: The dominant phase of work in this session — research,
drafting, review, revision, waiting_for_external, completed, paused.
Respond in JSON:
{
"session_summary": "...",
"open_questions": [{"question": "...", "context": "..."}, ...],
"key_decisions": [{"decision": "...", "rationale": "..."}, ...],
"work_phase": "..."
}
If nothing meaningful was accomplished (casual chat, quick lookup), respond:
{"session_summary": null, "open_questions": [], "key_decisions": [],
"work_phase": "unknown"}
```
**Input:** Last 10 user turns + assistant responses (or fewer if shorter). Tool call results excluded. Bounded to ~2,000 tokens.
**Model:** Uses `continuity_config.synthesis_model` (same knob as DOC73's). Both DOC73 and CSA share the same configurable model — typically Kimi or a local Ollama model. Async, off the hot path.
**Cost estimate:** ~2,000 input + ~300 output tokens per capture. At Kimi pricing (~$0.50/M input), ~$0.001-0.002 per capture. At 10-15 captures/day, ~$0.01-0.03/day.
**Authority note:** DOC73 §6.3 owns canonical authority over the session_summary content and storage (manifest field). CSA owns the structured extras (continuity log entries). The unified prompt and shared LLM call are coordination, not authority transfer.
### 5.5 Cross-conversation detection
The continuity agent detects cross-conversation updates by monitoring graph change events. When an entity is modified in any session, EC emits `graph.entity.upserted`. The continuity agent checks: does this entity appear in any OTHER work context's constellation? If so, write a `cross_conversation_update` entry to that work context's continuity log.
```ts
async function onEntityChanged(event: EntityUpsertedEvent): Promise<void> {
const sourceSessionId = event.source_session_id;
const entityId = event.entity_id;
const affectedContexts = await findWorkContextsReferencingEntity(entityId);
for (const ctx of affectedContexts) {
if (ctx.work_context_id === event.work_context_id) continue;
await appendContinuityEntry({
entry_type: "cross_conversation_update",
source_session_id: sourceSessionId,
content: {
summary: `${event.canonical_name} was updated in another conversation.`,
source_session_id: sourceSessionId,
affected_entity_ids: [entityId],
},
work_context_id: ctx.work_context_id,
linked_entity_ids: [entityId],
delivered: false,
decay_at: computeDecayAt("cross_conversation_update"),
});
}
}
```
In `deterministic` mode: cross-conversation detection still works (driven by graph events, not LLM synthesis). Summary text is templated.
In `full` mode: summary text can be enriched via the DOC73 §6.3 pass: "DOC72 was updated to R5.73 — changes to constellation schema and backlink pipeline that may affect DOC24 integration."
### 5.6 OpenClaw Active Memory plugin coexistence
R1 §5.6 noted DOC24 R2.5 §19.3A's coexistence rules for the OpenClaw Active Memory plugin (duplicate-injection prevention, Lane 3 budget reduction). R2 retains this. CSA's three-tier injection (§6) is strictly superior for ELNOR's use case; if Active Memory is detected, CSA's Lane 1 priority can preempt while Lane 3 is reduced as DOC24 R2.5 specifies.
**OpenClaw Dreaming coexistence is treated separately in §10 — disabled, not coexisting.**
---
## 6. Three-Tier Fresh-Surface Injection (R2 — NEW SECTION)
The R1 design had a single continuity card. R2 specifies an explicit three-tier model with anti-duplication rules.
### 6.1 Tier 1 — Continuity card (`resume` tag)
**Purpose:** Per-work-context work-state. "Where you are right now in this thread."
**Source:** Constellation continuity fields (§4) — session_history, open_questions, key_decisions, active_work_phase, cross_conversation_updates.
**Tag:** Add `resume` to DOC24 R3 canonical primary injection tag vocabulary (§26.5.1):
| Tag | Meaning | LLM behavior |
|---|---|---|
| `resume` | Work-state continuity from prior sessions in this work context | Pick up where the user left off; reference prior progress; acknowledge what's changed |
**Render template** (DOC24 R3 §26.4 addition):
```ts
type ContinuityCardContent = {
work_context_name: string;
active_work_phase: string;
session_history: Array<{ summary: string; captured_at: string }>; // Last 2-3
open_questions: string[]; // Max 3
key_decisions: Array<{ decision: string }>; // Max 2
cross_conversation_updates: string[]; // Undelivered only
};
```
**Example rendered card** (60-120 tokens):
```xml
<card type="continuity" tag="resume">
Henderson damages section — drafting phase.
Last session (Mon): Completed subsections 1-3 (price impact). Event study pending — waiting on Christensen data.
Open: Need to address Dura more directly in intro.
Decision: Focusing on price impact approach over corrective disclosure alone.
Since last session: DOC72 updated in another conversation (entity graph changes).
</card>
```
**Injection rules:**
1. Entity resolution matches a work context with non-empty continuity data, AND
2. The user's current session is NOT the session that produced the latest session_history entry (no "what you just did" injection in the same conversation), AND
3. At least 30 minutes have elapsed since the latest session_history entry (no injection for brief breaks).
**Budget:** Lane 1 (request context). Subject to normal trimming, but elevated priority — only non-droppable cards and explicit entity cards outrank.
**Card cap:** 120 tokens hard limit. Renderer truncates session_history first, then key_decisions, then open_questions, then cross_conversation_updates if budget exceeded.
### 6.2 Tier 2 — Recent activity card (`recent_activity` tag)
**Purpose:** Cross-context narrative summary. "What you've been doing lately across all your work."
**Source:** DOC73 §6.4 Mechanism 4 weekly/monthly rollup file (`ELNOR_MEMORY/rollup/recent_activity.md`). Currently named in DOC73 V1.5.1 §6.4 but undefined — see Appendix A.4 for the cross-doc obligation to DOC73 R-next.
**Tag:** Add `recent_activity` to DOC24 R3 canonical primary injection tag vocabulary (§26.5.1):
| Tag | Meaning | LLM behavior |
|---|---|---|
| `recent_activity` | Cross-context narrative summary of recent work | Use as context for what the user has been engaged with broadly; do not assume direct relevance to current message |
**Render template:** Inject the rollup file's content as-is, truncated to budget. The rollup file is a single markdown narrative (e.g., "Past 2 weeks: heavy on Henderson appeal scienter argument with three drafts of opposition. ELNOR red-team work focused on DOC73 V1.5.1 living memory section. Intermittent synth exploration weekends.")
**Example rendered card** (100-200 tokens):
```xml
<card type="recent_activity" tag="recent_activity">
Past 2 weeks (excluding current matter):
- ELNOR red-team work on DOC73 V1.5.1 PBE living memory section; resolved authority salience boundary
- DOC24 R3 token budget waterfall finalized
- Intermittent synth exploration weekends (Eurorack patches: Mutable Marbles + Plaits combos)
- Smith v. Acme appeal: motion practice, deposition prep
</card>
```
**Injection rules:**
1. Always inject at fresh-surface boot (default).
2. **Anti-duplication with Tier 1:** if Tier 1 fires, Tier 2 explicitly excludes the current Tier 1 work context from its narrative. The rollup is rendered at injection time with a `current_work_context_id` filter parameter; the renderer drops sentences referencing that context. (Implementation: rollup file is actually generated as per-context segments; the renderer concatenates all segments except the active one.)
3. Tier 2 may be skipped if the rollup file is empty or stale (>7 days old without refresh).
**Budget:** Lane 1, max 200 tokens. Droppable under pressure (lower priority than `resume`).
### 6.3 Tier 3 — Living memory card (`living_memory` tag)
**Purpose:** Stable user facts, preferences, and standing instructions.
**Source:** DOC73 V1.5.1 PBE living memory consolidation. Already-existing infrastructure.
**Tag:** `living_memory` already in DOC24 R3 vocabulary per DOC73 V1.5.1 PBE integration. R2 makes its role in fresh-surface injection explicit.
**Example rendered card** (50-100 tokens):
```xml
<card type="living_memory" tag="living_memory">
Will Brody, securities litigator. Principal architect of ELNOR.
Prefers direct assessment, no hedging. Cite section numbers when reviewing.
Use TS schemas and paste-ready code over descriptions.
</card>
```
**Injection rules:**
1. Always inject at fresh-surface boot.
2. **Anti-duplication with Tier 2:** Tier 3 carries STABLE facts (slow-changing user identity, preferences). Tier 2 carries RECENT activity (fast-changing). They MUST NOT overlap — DOC73 V1.5.1 §6.5 living-memory consolidation rules already enforce this for Tier 3 (stability gate before promotion to PBE).
3. Tier 3 is **non-droppable** — it's the only tier that always lands.
**Budget:** Lane 1, max 100 tokens. Non-droppable.
### 6.4 Total budget and trimming order
| Tier | Tag | Max | Droppable | Priority |
|---|---|---|---|---|
| 1 | `resume` | 120 tok | Droppable (low) | High (only non-droppable + entity cards beat) |
| 2 | `recent_activity` | 200 tok | Droppable (high) | Medium |
| 3 | `living_memory` | 100 tok | Non-droppable | Always |
**Total ceiling:** 420 tokens.
**Trimming order under pressure** (DOC24 R3 §19.1A waterfall applies):
1. Drop Tier 2 first (cross-context narrative is least essential).
2. Trim Tier 1 (drop session_history first, then key_decisions, etc. per §6.1).
3. NEVER drop Tier 3.
If the surface profile budget cannot accommodate Tier 3 + Tier 1, surface profile is mis-configured — log warning and inject Tier 3 only.
### 6.5 Activity-type inheritance (R2 retention from R1)
The constellation's `active_work_phase` feeds DOC24 R3's `activity_type` inference (§13.3 `RoutingDecision.activity_type`). If the constellation says `active_work_phase: "research"` and the user hasn't clearly indicated otherwise in the current message, the routing decision inherits the research classification. This means the correct card-type mix (DOC24 R3 §26.8) is selected even when the user's first message in a resumed conversation is brief ("let's continue").
### 6.6 Integration with existing packet assembly
No new injection channel. All three tier cards are `CompactEntityCard` variants entering through DOC24 R3 §27 lane assembly:
- Tier 1: `node_kind: "work_context_constellation"`, `tag: "resume"`
- Tier 2: `node_kind: "rollup_recent_activity"`, `tag: "recent_activity"`
- Tier 3: `node_kind: "pbe_living_memory"`, `tag: "living_memory"`
---
## 7. Cross-Surface Semantic Query (R2 — NEW SECTION)
R1 had no semantic query capability. R2 reintroduces it as a separate, optional capability — preserving RRB v6's OCM Job 2 (cross-surface query mode) without the cost of always-on LLM agents.
### 7.1 Purpose
Answer queries like *"what's been discussed about Tellabs across all my surfaces?"* — semantic search over continuity log entries and (optionally) DOC73 session summaries, returning attributed answers.
### 7.2 Capability registration
A new DOC24 R3 capability:
```ts
const CONTINUITY_CROSS_SURFACE_QUERY: ActionRegistryEntry = {
action_id: "continuity.cross_surface_query",
domain: "continuity",
display_name: "Cross-Surface Continuity Query",
user_goal: "Search prior work-state across all my conversations",
description: "Returns attributed continuity entries matching the query, optionally filtered by entity, topic, or time window. Read-only, attributed, low-trust.",
stability_class: "stable_action",
agent_invocable: true,
invocation_bindings: [{
transport: "internal",
binding_name: "continuity_query",
readiness: "ready",
client_exposure: { elnor_native: true, mcp_external: false, q_ui: true },
}],
confirmation_policy: "none",
safety_class: "read",
aliases: ["continuity query", "cross-chat search"],
common_phrases: ["what have I said about", "in other chats", "across my conversations"],
codegen_source: "companion_registration",
schema_version: 1,
};
```
### 7.3 Query schema
```ts
type ContinuityQueryRequest = {
requesting_agent_id: string;
requesting_run_id: string;
requesting_surface_kind: string;
requesting_surface_id: string;
query: string; // Free-text query
topic_filter?: string[]; // Optional entity IDs to scope
agent_filter?: string[]; // Optional source agent IDs
time_window_hours?: number; // Optional window (default 720 = 30 days)
max_results?: number; // Default 5, cap 20
cross_context_permission?: "current_only" | "lineage" | "all"; // Default "lineage"
};
type ContinuityQueryResult = {
entries: Array<{
entry_id: string;
work_context_id: string;
entry_type: string;
captured_at: string;
source_session_id: string;
content_excerpt: string; // Bounded snippet
relevance_score: number; // 0-1
linked_entity_ids: string[];
}>;
synthesis?: string; // Optional LLM-generated attributed summary
trust_banner: "low_trust"; // Always low-trust per R1/RRB v6 contract
fallback_mode?: "lexical_only"; // Set if embedding/LLM unavailable
};
```
### 7.4 Index strategy (configurable)
Three options, configurable via `continuity_config.json`:
```ts
type ContinuityQueryIndexStrategy =
| "lexical_only" // ripgrep over JSONL files. Free, no infra.
| "embedding_augmented" // Qwen3-Embedding-0.6B over MLX. Embed each entry on write.
| "hybrid"; // Lexical for entity-name matches, embedding for semantic
// similarity, RRF rank fusion.
```
Default: `hybrid`. Falls back to `lexical_only` if MLX/Qwen3 unavailable.
**Embedding details (when used):**
- Model: Qwen3-Embedding-0.6B via MLX (already locked infra per ELNOR architectural invariant).
- Embedded fields: `summary` (when present), `question`, `decision`, `rationale`, `content_excerpt`.
- Storage: `ELNOR_MEMORY/continuity/embeddings/{wc_id}.faiss` (or sqlite-vec if preferred).
- Cost: negligible — sub-millisecond per entry, no API cost.
### 7.5 Synthesis layer (optional)
When `synthesis: true` is set on the request, top-K retrieved entries are passed to a small LLM for attributed-answer synthesis:
```
You are answering a question about the user's prior work-state across
multiple sessions. Below are attributed continuity entries. Produce a
concise attributed answer (max 200 tokens). DO NOT hallucinate. If the
entries don't directly answer, say so.
Question: {query}
Entries:
[{captured_at}] [session: {source_session_id}] [type: {entry_type}]
{content_excerpt}
...
Respond in JSON:
{
"answer": "...",
"attributions": [{"entry_id": "...", "snippet": "..."}, ...]
}
```
**Cost:** Only fires when invoked. ~1,000 input + ~250 output tokens per query. ~$0.001/query at Kimi pricing.
### 7.6 Trust boundary and rate limits
- **Read-only.** Cannot mutate any state.
- **Low-trust banner.** Results displayed with banner: "Cross-surface continuity result — verify before acting. Cannot be sole basis for durable actions per CSA §7.6."
- **Rate limits:** `OCM_QUERY_RATE_PER_MINUTE = 6` per session, `OCM_QUERY_RATE_PER_DAY = 200` per user. Configurable.
- **Lexical fallback required** when synthesis or embedding unavailable. Never silent degradation — fallback explicitly marked in result.
- **Cross-context permission:** Default `lineage` — query can read entries from work contexts in the same domain lineage as the requesting surface (e.g., legal-domain queries see legal-domain continuity, not synth-domain). `current_only` restricts to current work context. `all` requires explicit user grant per session (not default).
### 7.7 Relationship to RRB v6 OCM query mode
RRB v6 §4.4 specified OCM query mode as the cross-surface query capability. R2 §7 carries that intent forward with these clarifications:
- The mechanism is now invoked as a DOC24 capability (`continuity.cross_surface_query`), not an OCM-internal pathway.
- The OCM agent name (per DOC15 R7.1) maps to the deterministic-by-default continuity agent (§5) plus this query capability (§7) plus the rendering of Tier 1 cards (§6.1). OCM is the umbrella name; CSA defines the substance.
- Power-user feature, optional. Can be disabled via `continuity_config.cross_surface_query_enabled = false`.
---
## 8. Direct Session Transcript Access (R2 — NEW SECTION)
OpenClaw stores session transcripts as plain JSONL files at `~/.openclaw/agents/<agentId>/sessions/<SessionId>.jsonl`. R2 adds three first-class capabilities for direct named transcript access — separate from the embedding-based cross-surface query (§7).
### 8.1 Why this is separate from §7
§7 (cross-surface semantic query) answers "what have I said about X across my chats?" — content search across many sessions. Power-user, costs depend on index choice.
§8 (direct transcript access) answers "show me the transcript of session Y" or "summarize what I worked on yesterday in chat Z" — direct named access. Cheap, simple, always available.
### 8.2 Three capabilities
```ts
const SESSION_LIST: ActionRegistryEntry = {
action_id: "session.list",
domain: "session",
display_name: "List Sessions",
user_goal: "List my prior conversation sessions",
description: "List sessions in the user's workspace, optionally filtered by work_context_id, time window, agent_id.",
stability_class: "stable_action",
agent_invocable: true,
invocation_bindings: [{
transport: "internal",
binding_name: "session_list",
readiness: "ready",
client_exposure: { elnor_native: true, mcp_external: false, q_ui: true },
}],
confirmation_policy: "none",
safety_class: "read",
aliases: ["list chats", "list sessions", "what conversations"],
common_phrases: ["my recent chats", "sessions from yesterday", "conversations about"],
codegen_source: "companion_registration",
schema_version: 1,
};
const SESSION_READ_TRANSCRIPT: ActionRegistryEntry = {
action_id: "session.read_transcript",
domain: "session",
display_name: "Read Session Transcript",
user_goal: "Read the full transcript of a prior session",
description: "Returns the JSONL transcript for a named session. Optional last_n_turns parameter.",
stability_class: "stable_action",
agent_invocable: true,
invocation_bindings: [{
transport: "internal",
binding_name: "session_read",
readiness: "ready",
client_exposure: { elnor_native: true, mcp_external: false, q_ui: true },
}],
confirmation_policy: "none",
safety_class: "read",
aliases: ["read chat", "transcript", "show conversation"],
common_phrases: ["pull up that chat", "show me the transcript", "what did we discuss"],
codegen_source: "companion_registration",
schema_version: 1,
};
const SESSION_SUMMARIZE: ActionRegistryEntry = {
action_id: "session.summarize",
domain: "session",
display_name: "Summarize Session",
user_goal: "Get a summary of a prior session",
description: "Returns a summary of a named session. If a DOC73 session_summary exists, returns it. Otherwise generates one on-demand via the configured synthesis model.",
stability_class: "stable_action",
agent_invocable: true,
invocation_bindings: [{
transport: "internal",
binding_name: "session_summarize",
readiness: "ready",
client_exposure: { elnor_native: true, mcp_external: false, q_ui: true },
}],
confirmation_policy: "none",
safety_class: "read",
aliases: ["summarize chat", "summary of session"],
common_phrases: ["summarize that conversation", "what was that chat about"],
codegen_source: "companion_registration",
schema_version: 1,
};
```
### 8.3 Schema
```ts
type SessionListRequest = {
work_context_id?: string;
time_window_hours?: number;
agent_id?: string;
limit?: number; // Default 20, cap 100
};
type SessionListResult = {
sessions: Array<{
session_id: string;
started_at: string;
last_activity_at: string;
agent_id: string;
work_context_id?: string;
turn_count: number;
has_doc73_summary: boolean;
primary_entity_ids: string[]; // Top entities by mention count
}>;
};
type SessionReadTranscriptRequest = {
session_id: string;
last_n_turns?: number; // If unset, full transcript (subject to budget)
};
type SessionReadTranscriptResult = {
session_id: string;
turns: Array<{
turn_id: string;
role: "user" | "assistant" | "tool";
content: string; // Bounded per-turn excerpt for budget
tool_calls?: any[];
timestamp: string;
}>;
truncated: boolean;
};
type SessionSummarizeRequest = {
session_id: string;
force_regenerate?: boolean; // Default false — uses existing DOC73 summary if available
};
type SessionSummarizeResult = {
session_id: string;
summary: string;
generated_at: string;
source: "doc73_existing" | "on_demand_generated";
doc73_session_summary_id?: string; // If from existing DOC73 summary
};
```
### 8.4 Trust boundary
- **Workspace-scoped.** Cannot read sessions from other users' workspaces or other agents' instances.
- **Attribution required.** Every result carries `session_id`, `started_at`, `agent_id`. Renderer surfaces attribution.
- **Read-only.** No tool can mutate transcripts or session metadata.
- **Privacy filter.** Sensitive content (e.g., DOC73 sealed signals) is redacted in transcript reads — same redaction as Dreaming would apply per OpenClaw v2026.4.9 grounded REM contract.
- **Token budget per call:** SessionReadTranscriptResult capped at 4,000 tokens (configurable). Truncated reads return `truncated: true` with continuation hint.
### 8.5 Use cases
- "Summarize what I worked on yesterday in the chat about Henderson" → `session.list(work_context_id=wc_henderson, time_window=24)` → `session.summarize(session_id=...)`.
- "Pull up the conversation where I decided X" → `continuity.cross_surface_query(query="decided X")` (§7) returns entry with session_id → `session.read_transcript(session_id=...)`.
- "Review what was discussed in the room I was just in" → `session.read_transcript(session_id=current_room_session_id, last_n_turns=20)`.
### 8.6 Distinction from §7
| Capability | When | How | Cost |
|---|---|---|---|
| §7 cross-surface semantic query | "I don't know which session has the answer" | Embedding/lexical search over continuity log | LLM call only on synthesis |
| §8 direct session access | "I know which session I want" | Filesystem read + optional summary | Zero or single LLM call |
§7 is a power-user content-search capability. §8 is the basic plumbing for cross-chat awareness — should be present in every ELNOR deployment.
---
## 9. External Surface Observation Pathways (R2 — NEW SECTION, GAP ACKNOWLEDGMENT)
CSA's cross-conversation detection (§5.5) fires on `graph.entity.upserted` events. This works for ELNOR-native chat surfaces. It does NOT work for external surfaces (browser, document editors, email, file edits) unless those surfaces emit observation events into ELNOR's graph.
### 9.1 The gap
Will's example: "If I have an open chat working on a motion and then I open up a document in the browser and comment on it... they should be aware of each other."
For CSA's cross-conversation push to fire, the document edit must produce an `entity.upserted` event. If ELNOR has no observation pathway from the external surface, the event never fires, and the motion chat never receives a `cross_conversation_update`.
### 9.2 What's required
External surface observation pathways. Specific implementations are out of scope for CSA itself but are named here as cross-doc dependencies.
| Pathway | Captures | Implementation home |
|---|---|---|
| Browser activity capture | URL visits, comment edits, doc views | DOC20 / Q browser intake (existing — see DOC20 Q_BROWSER_INTAKE_ARCHITECTURE) |
| File watcher | File saves, document edits in tracked folders | EC Core / OpenClaw file watcher plugin |
| Manual user push | User-initiated "I just did X" event | Q UI button, simple event injection |
| App-specific MCP plugins | Per-app event sources (Word, Email, Slack, etc.) | DOC22 plugins / OpenClaw MCP integrations |
### 9.3 CSA's requirement
CSA does not specify these pathways. CSA REQUIRES that they exist for cross-conversation push to function across external surfaces. Without external pathways, CSA's cross-conversation detection is limited to ELNOR-native chat surfaces.
Cross-doc obligation to DOC20 / DOC22 / EC Core: provide event-emission contracts for each external surface category. Not blocking on CSA promotion to operative — CSA can ship and function on chat surfaces alone — but listed as known follow-up work.
---
## 10. OpenClaw Dreaming — Disabled (R2 — REPLACES R1 §5.6)
### 10.1 Background
OpenClaw v2026.4.9 added grounded REM backfill to the Dreaming subsystem. Dreaming now ingests redacted session transcripts into the dreaming corpus, alongside daily memory signals and recall traces. It writes a narrative Dream Diary at `DREAMS.md` via a configurable model (`dreaming.model` knob) and consolidates daily memory signals into `MEMORY.md`.
### 10.2 ELNOR's position
Dreaming is **disabled** in ELNOR deployments. ELNOR's nightly extraction pipeline is the canonical knowledge-consolidation path:
- **DOC72 nightly_consolidation_pass** — entity merging, graph hygiene, backlink compaction.
- **DOC73 PBE consolidation** — living memory consolidation per V1.5.1 §6.5.
- **DOC73 §6.3 session-summarization** — per-session narrative summaries (CSA defers to this; see §5.4).
- **DOC73 §6.4 Mechanism 3 cross-session consolidation** — topic-scoped state-of-play summaries.
- **DOC73 §6.4 Mechanism 4 weekly/monthly rollup** — cross-context narrative rollup (CSA Tier 2 source; see Appendix A.4).
- **DOC8 nightly processing** — utility tracking, threshold tuning.
- **BDSM nightly extraction** — utility ledger consolidation.
### 10.3 Why disabled, not coexisting
Both Dreaming and ELNOR's pipeline consume raw session transcripts. Running both means:
1. Same transcripts read twice (waste of LLM cost and disk I/O).
2. Two separate memory artifacts requiring reconciliation (ELNOR DOC72 graph vs OpenClaw MEMORY.md).
3. Configuration overhead deciding which is canonical.
4. Risk of conflicting state.
5. ELNOR's structured output (entity nodes with provenance, significance gating, sealed-signal partitioning) is strictly more capable than Dreaming's flat-text MEMORY.md for ELNOR's use case.
R1 §5.6 proposed coexistence (treat MEMORY.md as a source surface for ELNOR intake). R2 reverses this — coexistence costs more than it provides. Disabling Dreaming is cleaner.
### 10.4 Configuration
EC Core obligation: ensure OpenClaw configuration includes `dreaming.mode = "off"` (or the OpenClaw-equivalent disable flag) at provisioning time. See Appendix A.5.
If the user explicitly re-enables Dreaming for a specific reason (e.g., wants Dream Diary for unrelated reasons), CSA still functions — Dreaming output goes to MEMORY.md/DREAMS.md and is NOT consumed by ELNOR's intake pipeline. The two operate in parallel without integration. This is supported but not recommended.
### 10.5 OpenClaw Active Memory plugin (separate)
Active Memory plugin coexistence rules from DOC24 R2.5 §19.3A still apply (preempt with CSA Lane 1, reduce Lane 3 budget if Active Memory detected). Active Memory is treated separately from Dreaming.
---
## 11. Activity-Type-Aware Significance Gating
(R2 retains R1 §7 substantively unchanged, refreshed for current spec section refs.)
### 11.1 Problem
DOC72 R5.73's significance gate (§42A absorbed-GIE invariants + DOC72 baseline §20A) uses a fixed threshold to decide whether incoming knowledge is worth extracting. Works for steady-state but fails during active research where graph coverage is sparse.
### 11.2 Design
The significance gate receives `activity_type` from DOC24 R3 routing (§13.3). When activity is "research" AND user is in an active work context, threshold is lowered:
```ts
function computeSignificanceThreshold(
baseThreshold: number, // Default 0.5, DOC8-tunable
activityType: string | undefined,
hasActiveWorkContext: boolean,
): number {
if (activityType === "research" && hasActiveWorkContext) {
return baseThreshold * 0.6; // 0.5 → 0.3
}
return baseThreshold;
}
```
### 11.3 Signal flow (refreshed for current spec refs)
1. User sends a message.
2. DOC24 R3 §13.0 pre-agent routing classifies `activity_type: "research"` (verb-family patterns: "find", "research", "look up", "analyze").
3. `RoutingDecision` (incl `activity_type`) passes to DOC72 R5.73 intake pipeline as observation context.
4. DOC72 §20A significance gate reads `activity_type`, adjusts threshold.
5. Knowledge below default threshold passes the lowered gate.
6. Knowledge enters graph with `source` provenance.
7. DOC8 nightly processing evaluates whether research-mode captures were useful (cited later, referenced again, never touched).
8. DOC8 adjusts the threshold multiplier (0.6) up/down based on capture utility.
### 11.4 Domain-agnostic operation
Mechanism is domain-agnostic. "Research" means same thing for lawyer, developer, musician. Threshold adjustment applies to all knowledge types. Domain signal profiles can enhance entity recognition (case citations, API references, etc.) but are enhancements, not requirements.
### 11.5 Web search result handling
When agent calls `web_search` during research, results flow through the same significance gate:
- Research context active → lowered threshold lets more results into graph as candidate entities.
- No research context → normal threshold; most results consumed ephemerally.
- All graph entries from web search carry `source: "web_search"` provenance.
No separate "verified facts cache" — web search results either pass the gate and enter the graph (with provenance and TTL), or they don't and are consumed ephemerally.
### 11.6 Normative rules
1. Significance threshold adjustment is computed per-observation, not per-session.
2. `activity_type` is determined by DOC24 R3 verb-family classification. DOC72 does NOT independently classify.
3. DOC8 tracks research-mode capture utility as feedback signal. Multiplier (default 0.6) is DOC8-tunable Category B parameter.
4. Domain signal profiles may add entity recognition patterns; not required.
---
## 12. Temporal Awareness and DOC2 Retirement
(R2 retains R1 §8 with section-ref refresh against DOC24 R3, DOC15 R7.1, DOC11 R14+R15.)
### 12.1 Background
DOC2 (Freshness Manager Addendum v1.11.4) addressed three problems: models not knowing the current date, stale answers, no mechanism for web-verified fact storage. These are now solved by the broader architecture.
### 12.2 Temporal awareness prompt
Single instruction block in the system prompt:
```
Today is {current_date}. Your training data has a cutoff and may not
reflect recent events or the latest available information. When uncertain
whether your knowledge is current, use the web_search tool to verify
before answering. Search rather than guess.
```
~40 tokens. Injected once per system prompt build (prompt cache). Rebuilt after compaction. `{current_date}` substituted by EC at assembly time.
**CIL position (DOC15 R7.1):** Dedicated position above KOI, below personality. Present every turn (system prompt). Non-suppressible — present even during DOC24 R3 kill-switch (per §33). Universal — no model-conditional logic.
### 12.3 Model temporal profile
DOC11 R14+R15's model registry adds:
```ts
type ModelTemporalProfile = {
model_id: string;
knowledge_cutoff_date: string | null;
date_awareness: "provider_injected" | "requires_injection" | "unknown";
last_profile_verified: string;
schema_version: 1;
};
```
**Maintenance:** Updated manually for in-use models. Configuration concern.
### 12.4 Recency router migration
DOC2 §6.1 deterministic recency router migrates to DOC24 R3 §13.2A as additional verb-family patterns:
```ts
const RECENCY_PATTERNS: VerbFamilyPattern[] = [
{
family: "recency_must_search",
patterns: [
"today", "yesterday", "tomorrow", "latest", "current", "right now",
"this week", "this month", "as of", "recently", "breaking", "update",
"what happened", "news",
],
implicit_action_id: "search.web",
},
{
family: "recency_should_search",
patterns: ["find", "link", "source", "URL", "where can I"],
implicit_action_id: "search.web",
},
];
```
When classified `recency_must_search`, `web_search` is mounted in active pack (if not already) and temporal instruction encourages use.
### 12.5 Web search tool registration
```ts
const WEB_SEARCH_ACTION: ActionRegistryEntry = {
action_id: "search.web",
domain: "search",
display_name: "Web Search",
user_goal: "Search the web for current information",
description: "Search the web using configured provider (Brave, Gemini, Perplexity, Grok, Kimi)",
stability_class: "stable_action",
agent_invocable: true,
invocation_bindings: [{
transport: "native_openclaw_tool",
binding_name: "web_search",
readiness: "ready",
client_exposure: { elnor_native: true, mcp_external: false, q_ui: false },
}],
confirmation_policy: "none",
safety_class: "read",
aliases: ["search", "web search", "look up online"],
common_phrases: ["search the web", "look this up", "find online", "google this"],
codegen_source: "companion_registration",
schema_version: 1,
};
```
### 12.6 DOC2 retirement mapping
| DOC2 component | New home | Status |
|---|---|---|
| Temporal context injection (§3) | DOC15 R7.1 CIL position + §12.2 prompt | Migrated |
| Model Capability Registry (§3) | DOC11 R14+R15 model temporal profile (§12.3) | Migrated (simplified) |
| Deterministic Recency Router (§6) | DOC24 R3 §13.2A recency patterns (§12.4) | Migrated |
| Web Search Executor (§7) | OpenClaw native `web_search` + DOC24 R3 registry (§12.5) | Migrated |
| Verified Facts Cache (§5) | Retired — significance-gated graph intake (§11.5) replaces | Retired |
| TTL by category (§6.3) | DOC72 R5.73 domain signal profiles — temporal decay config | Migrated |
| Staleness UI (§9) | DOC21/22 — freshness indicator on responses | Deferred to UI pass |
| Source tiers (§5.2) | Retained conceptually in `source` provenance | Subsumed |
**DOC2 status:** Retired. All normative content absorbed into DOC72 R5.74 (this proposal §§11-12), DOC24 R3 (§13.2A recency patterns, §14 web search registration), DOC11 R14+R15 (model temporal profile), DOC15 R7.1 (CIL temporal position). DOC2 marked "SUPERSEDED — see CSA R2 §12" in master spec registry.
---
## 13. Normative Rules
1. The continuity log is a staging area, not a second brain. All durable knowledge promoted to the graph; ephemeral data decays.
2. Constellation views are derived read-models. Deleting a constellation file and rebuilding from graph + continuity log produces the same result.
3. The continuity agent writes to the log only. NEVER writes to the entity graph directly. Promotion is a separate governed pipeline (nightly job via EC).
4. Deterministic capture is always available and free. LLM synthesis is additive and independently disableable.
5. **CSA does not run a separate session-summary LLM pass.** DOC73 §6.3 owns canonical session-summary authority. CSA augments DOC73's single pass to extract structured extras (open_questions, key_decisions, work_phase) in the same call. R2 invariant.
6. The pre-compaction trigger (`compact` hook) is mandatory when continuity mode is not `off`. Compaction MUST NOT destroy work-state context that hasn't been captured.
7. Cross-conversation detection uses graph change events. Works in both `deterministic` and `full` modes.
8. Activity-type-aware significance gating is a DOC72 R5.73 §20A mechanism. DOC24 provides the activity_type signal; DOC72 adjusts the gate.
9. The temporal awareness prompt is universal. No model-conditional logic. ~40 tokens in system prompt.
10. Web search results enter the graph only through the significance gate. No separate verified facts cache.
11. DOC2 is retired. All normative content migrated to DOC72, DOC24, DOC11, DOC15.
12. **OpenClaw Dreaming is disabled in ELNOR deployments.** ELNOR pipeline is canonical for knowledge consolidation.
13. **Three-tier injection model** (Tier 1 `resume`, Tier 2 `recent_activity`, Tier 3 `living_memory`) is the canonical fresh-surface continuity injection. No additional injection channels.
14. Tier 1 and Tier 2 anti-duplication: Tier 2 explicitly excludes the current Tier 1 work context from its narrative.
15. Tier 3 (`living_memory`) is non-droppable. Tier 1 and Tier 2 are droppable under budget pressure.
16. Cross-surface semantic query (§7) is read-only, attributed, low-trust, rate-limited. Cannot be sole basis for durable actions.
17. Direct session transcript access (§8) is workspace-scoped, attributed, with privacy filtering for sealed signals.
18. External surface observation pathways (§9) are required for cross-conversation push to function across non-chat surfaces. Implementation home: DOC20 / DOC22 / EC Core. Not blocking CSA promotion.
---
## Appendix A — Cross-Doc Obligations
### A.1 DOC24 R3
| Obligation | Priority | Detail |
|---|---|---|
| Add `resume`, `recent_activity` to canonical primary injection tag vocabulary (§26.5.1) | High | Two new tags for Tier 1 and Tier 2 cards |
| Add three-tier card rendering templates (§26.4) | High | `renderContinuityCard`, `renderRecentActivityCard` (60-200 tok); `renderLivingMemoryCard` already exists per DOC73 V1.5.1 PBE |
| Register `search.web` as stable semantic action (§14.5) | High | OpenClaw native `web_search` registration |
| Add recency patterns to verb-family classification (§13.2A) | High | `recency_must_search` and `recency_should_search` |
| Three-tier injection rules in packet assembly (§27) | High | Tier 1 entity-resolution match + 30-min elapsed; Tier 2 always at fresh boot with current-context filter; Tier 3 always non-droppable |
| Constellation `active_work_phase` feeds routing `activity_type` | Medium | Inherited when first message is ambiguous |
| Token budget waterfall (§19.1A) per-tier caps | High | Tier 1: 120 tok max; Tier 2: 200 tok max; Tier 3: 100 tok max non-droppable |
| Register `continuity.cross_surface_query` capability (§7) | Medium | Power-user feature, can be disabled in config |
| Register `session.list`, `session.read_transcript`, `session.summarize` capabilities (§8) | High | Basic plumbing for cross-chat awareness |
### A.2 DOC11 R14+R15
| Obligation | Priority | Detail |
|---|---|---|
| Add `ModelTemporalProfile` to model registry | Medium | knowledge_cutoff_date, date_awareness, last_profile_verified |
| Register continuity agent as ContextEngine plugin (`afterTurn`, `compact`, `bootstrap` hooks) | High | OpenClaw documented plugin slot |
| Document OpenClaw `web_search` tool availability | Medium | Provider auto-detection order |
| Document `dreaming.mode = "off"` provisioning default | High | EC Core obligation linkage |
### A.3 DOC15 R7.1
| Obligation | Priority | Detail |
|---|---|---|
| Add temporal awareness prompt to CIL hierarchy | High | Above KOI, below personality. ~40 tokens. Universal. Non-suppressible during kill-switch. |
| OCM agent contract: maps to CSA continuity agent (§5) + cross-surface query capability (§7) + Tier 1 card rendering (§6.1) | High | OCM is the umbrella name; CSA defines the substance. Deterministic-by-default, sparse LLM augmentation via shared DOC73 §6.3 pass. |
### A.4 DOC73 R-next (CRITICAL — required for Tier 2)
| Obligation | Priority | Detail |
|---|---|---|
| Specify §6.4 Mechanism 4 weekly/monthly rollup | **CRITICAL** | Currently named in V1.5.1 but undefined. Tier 2 (`recent_activity` card, §6.2) depends on this. See accompanying DOC73 proposal handoff document. |
| Confirm §6.3 session_summary content authority extends to allowing CSA structured-extras extraction in the same LLM pass | High | Per CSA §5.4 unified-prompt model |
| Provide stable `doc73_session_summary_id` field in session manifests for CSA continuity log references | High | Per §3.2 schema |
### A.5 DOC8
| Obligation | Priority | Detail |
|---|---|---|
| Track research-mode capture utility | High | Feedback signal: % of research captures referenced in later work |
| Tune significance threshold multiplier | High | Category B parameter, default 0.6, canary trial |
| Evaluate continuity promotion candidates | Medium | Flag open questions and key decisions for graph promotion |
### A.6 EC Core (Addendum A V3.3+)
| Obligation | Priority | Detail |
|---|---|---|
| Create continuity log directory and files | High | `ELNOR_MEMORY/continuity/` |
| Register continuity agent as ContextEngine plugin via DOC11 R14+R15 hooks | High | OpenClaw plugin registration |
| Register nightly promotion job | High | Review continuity log, promote qualifying entries, clean expired |
| Register cross-conversation event handler | High | Listen for `graph.entity.upserted`, write cross-conversation updates |
| **Provision OpenClaw with `dreaming.mode = "off"`** | High | Per §10.4 |
| Wire continuity config to Q Settings | Medium | Mode toggle, model selector |
| Provision `ELNOR_MEMORY/rollup/recent_activity.md` infrastructure | High | Tier 2 source file (per DOC73 R-next §6.4 Mechanism 4 schema) |
| Implement `session.list`, `session.read_transcript`, `session.summarize` handlers | High | Per §8 |
| Implement `continuity.cross_surface_query` handler with chosen index strategy | Medium | Per §7 |
### A.7 DOC2
| Obligation | Priority | Detail |
|---|---|---|
| Retire DOC2 | High | Mark SUPERSEDED in master spec registry. All content migrated per §12.6 |
### A.8 DOC20 / DOC22 (deferred — §9 gap)
| Obligation | Priority | Detail |
|---|---|---|
| Provide event-emission contracts for external surfaces | Deferred | Browser intake (DOC20), app-specific MCP plugins (DOC22) emit `entity.upserted` events into ELNOR graph for CSA cross-conversation push to function |
| Register continuity config in Q Settings page | Medium | Mode toggle, synthesis model selector |
| Register freshness indicator on responses | Deferred | Staleness UI from DOC2 §9 — UI integration pass |
### A.9 DOC21 (Q UI)
| Obligation | Priority | Detail |
|---|---|---|
| Q UI rendering of three-tier injection at fresh-surface boot | Medium | User-visible "Brief loaded" indicator; click-to-inspect for current Tier 1 content |
| Manual "I just did X" event injection button | Deferred (§9 gap) | For external surface observation when no automatic pathway exists |
---
## Appendix B — Storage Paths
| Artifact | Path | Format |
|---|---|---|
| Continuity log (per work context) | `ELNOR_MEMORY/continuity/{work_context_id}.jsonl` | Append-only JSONL, schema_version: 2 |
| Continuity log (unlinked) | `ELNOR_MEMORY/continuity/wc_unlinked.jsonl` | Append-only JSONL, max 20 entries |
| Continuity config | `ELNOR_MEMORY/config/continuity_config.json` | Atomic JSON, schema_version: 2 |
| Constellation views | `ELNOR_MEMORY/mirror/work_context/{work_context_id}.json` | Per-context atomic JSON |
| Cross-surface query embeddings | `ELNOR_MEMORY/continuity/embeddings/{wc_id}.faiss` | FAISS index (or sqlite-vec) |
| Recent-activity rollup (Tier 2) | `ELNOR_MEMORY/rollup/recent_activity.md` | Markdown, refreshed nightly per DOC73 R-next §6.4 Mech 4 |
| OpenClaw session transcripts (read-only via §8) | `~/.openclaw/agents/<agentId>/sessions/<SessionId>.jsonl` | OpenClaw native, append-only JSONL |
| DOC73 session manifests | Per DOC73 V1.5.1 §6.3 (path TBD per cross-doc obligation) | Per DOC73 |
---
## Appendix C — Build Dependency Order
| Step | What | Dependencies |
|---|---|---|
| 1 | Continuity log schema + storage (§3) | EC Core file management (existing) |
| 2 | Continuity config schema + settings (§5.1) | Step 1 |
| 3a | Deterministic capture (§5.3) | Steps 1-2, DOC24 R3 routing decision (existing) |
| 3b | Temporal awareness prompt (§12.2) | DOC15 R7.1 CIL (existing) |
| 3c | Recency router patterns (§12.4) | DOC24 R3 §13.2A (existing) |
| 3d | Web search tool registration (§12.5) | DOC24 R3 §14 (existing), OpenClaw web_search (existing) |
| 4 | Constellation schema extension (§4) | DOC72 R5.73 §42A (existing) |
| 5 | OpenClaw ContextEngine plugin registration (§5.2) | DOC11 R14+R15 hook integration |
| 6 | LLM-enriched capture (§5.4) | Steps 1-2, DOC73 §6.3 unified prompt agreement |
| 7 | Cross-conversation detection (§5.5) | Steps 1-2, graph events (existing) |
| 8 | Trigger model + pre-compaction hook (§5.2) | Steps 1-3a, OpenClaw `compact` hook (existing v2026.4.9+) |
| 9 | Three-tier injection cards (§6) | Steps 4, 6; DOC73 R-next §6.4 Mech 4 (Tier 2 source) |
| 10 | Activity-type significance gating (§11) | DOC24 R3 routing decision, DOC72 §20A gate |
| 11 | Nightly promotion engine (§3.3) | Steps 1, 4, DOC72 graph write pipeline |
| 12 | Direct session transcript access (§8) | OpenClaw transcript path (existing); DOC24 R3 capability registration |
| 13 | Cross-surface semantic query (§7) | Steps 1, 4, 11; Qwen3 MLX embedding infra (existing if hybrid/embedding strategy chosen) |
| 14 | DOC2 retirement (§12.6) | Steps 3b-3d verified working |
| 15 | OpenClaw Dreaming disabled provisioning (§10.4) | EC Core OpenClaw config management |
Steps 3a-3d can be built in parallel. Steps 6, 7, 8, 10 can be built in parallel after Steps 1-2. Step 9 depends on Step 6 + DOC73 R-next §6.4 Mech 4.
---
## Appendix D — Changes from R1
For reviewers familiar with R1, here is the explicit diff:
### Removed from R1
- §1.5 OpenClaw Dreaming "coexistence" framing — replaced with §10 "disabled" framing.
- R1 §5.4 standalone session-summary LLM call — replaced with §5.4 deferral to DOC73 §6.3 unified pass.
- R1 §5.6 "Dreaming coexistence" — replaced with §10 fuller treatment.
- R1's single-card injection model — replaced with §6 three-tier model.
### Added in R2
- §6 Three-Tier Fresh-Surface Injection (NEW) — explicit Tier 1 / Tier 2 / Tier 3 model with anti-duplication rules and budget caps.
- §7 Cross-Surface Semantic Query (NEW) — preserves RRB v6 OCM Job 2 as a registered DOC24 capability.
- §8 Direct Session Transcript Access (NEW) — `session.list`, `session.read_transcript`, `session.summarize` capabilities.
- §9 External Surface Observation Pathways (NEW) — gap acknowledgment.
- §10 OpenClaw Dreaming — Disabled (REWRITTEN from R1 §5.6).
- R2 R1→R2 change summary at top.
- R2 Appendix D (this section).
### Updated in R2
- §0 Governing Principles — added principles 4 (one session-end LLM pass), 7 (compaction-safe with explicit OpenClaw hooks), 8 (Dreaming disabled).
- §1.5 Fresh-surface orientation gap — new explanation tying RRB v6 intent to three-tier model.
- §1.6 What other systems do — Dreaming reference updated to v2026.4.9 expanded behavior.
- §2 Architecture Overview — diagram updated to show three-tier injection and OpenClaw hook integration.
- §3.2 Entry schema — `session_summary_ref` replaces `session_summary` (references DOC73 instead of carrying narrative).
- §4.1 Continuity enrichment schema — `session_history` carries DOC73 references, not raw text.
- §5.1 Operating modes — added `deterministic_heuristic_capture` config flag.
- §5.2 Trigger model — explicit OpenClaw ContextEngine plugin registration with named hooks.
- §5.3 Deterministic capture — added heuristic open-question and key-decision detection.
- §5.4 LLM-enriched capture — fundamental rewrite to defer to DOC73 §6.3 unified pass.
- §11 (was §7) Activity-type significance gating — section refs refreshed to DOC72 R5.73 §20A, DOC24 R3 §13.0/§13.3.
- §12 (was §8) Temporal awareness and DOC2 retirement — section refs refreshed to DOC15 R7.1, DOC11 R14+R15, DOC24 R3.
- §13 Normative rules — six new rules (5, 12-18) reflecting R2 additions.
- Appendix A Cross-Doc Obligations — substantially expanded; new A.4 (DOC73 R-next CRITICAL), A.8 (DOC20/22 deferred), A.9 (DOC21 Q UI).
- Appendix B Storage Paths — added rollup file, embeddings, OpenClaw transcript paths.
- Appendix C Build Dependency Order — refactored with new sections 5, 9, 12, 13, 15.
### Dropped (no replacement)
- Per-surface compressed summaries (RRB v6 SurfaceSummaryArtifact). Niche use case, not worth the complexity. Noted in §6 commentary as deferred-until-real-use-case.
---
*End of DOC72 Proposal — Continuity Synthesis Architecture R2*