cogmem 3.6.5 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.7.0
4
+
5
+ - Upgraded Memory Atlas into a multi-dimensional navigation graph: canonical episodes and raw events exist once, while time, topic, issue, entity, session/thread, memory-kind, and action-kind facets connect to them with typed edges.
6
+ - Added deterministic episode title and one-line summary generation for Atlas cards, preserving the original long summary in metadata and marking low-confidence titles for review.
7
+ - Added facet query planning for day/month/year, topic, issue, and entity cues, including strict facet intersection, canonicalId dedupe, matched facet/path explanations, and explicit relaxation traces.
8
+ - Added agent-facing Atlas `cards[]` on graph search/explore with `displayTitle`, `oneLineSummary`, `canonicalId`, `matchedFacets`, `matchedPaths`, `relatedButNotSelected`, and source drill-down locators.
9
+ - Extended Atlas cards to timeline results and CLI recall JSON, shared relaxation behavior across graph search/explore/timeline, and made broad “记忆黑盒” recall select the initial Memory Context/sourceContext discussion while listing later graph/runtime and Atlas readability issues as related side context.
10
+ - Renamed the live Atlas projection to `memory_atlas.v2` with 3.7 schema metadata while still consuming legacy `memory_atlas.v1` dirty triggers, so upgraded 3.6.5 databases rebuild the multi-facet projection instead of trusting stale clean state.
11
+ - Integrated facet graph cards into `historical_discussion` recall so OpenClaw/Hermes agents can explain selected memories while still grounding answers in Raw Ledger source locators.
12
+ - Updated OpenClaw plugin 0.7.0 and its generated bridge to preserve strict facet matches through Context Cortex planning and to include selected cards, matched facets/paths, related-but-not-selected side context, and relaxation traces in both volatile recall and Atlas context blocks.
13
+ - Updated README, Memory Atlas docs, OpenClaw/Hermes skills, AGENTS runbooks, and operations references with npm-first install/update flow and the 3.7.0 multi-facet Atlas command playbook.
14
+
3
15
  ## 3.6.5
4
16
 
5
17
  - Added `cogmem memory plan` as a read-only agent operations summary with queue state, blocking/non-blocking next actions, Dream backlog hints, and vector fallback state.
package/MEMORY_ATLAS.md CHANGED
@@ -1,4 +1,4 @@
1
- # Memory Atlas v1
1
+ # Memory Atlas v2
2
2
 
3
3
  Memory Atlas lets an agent inspect what Cogmem remembers before it chooses a precise recall or Raw Ledger drilldown. It is a rebuildable navigation projection, not a new source of truth.
4
4
 
@@ -6,19 +6,30 @@ Memory Atlas lets an agent inspect what Cogmem remembers before it chooses a pre
6
6
 
7
7
  Atlas projects existing project-scoped records into these node kinds:
8
8
 
9
- - `project`, `topic`, `entity`, `cluster`, `episode`, `belief`, `action`, and `time`.
10
- - Raw `event` nodes appear only for explicit evidence navigation.
9
+ - Canonical content nodes: `episode`, `raw_event`, `cluster`, `belief`, `action`, `decision`, and `correction`.
10
+ - Facet nodes: `time`, `topic`, `issue`, `entity`, `session`, `thread`, `memoryKind`, and `actionKind`.
11
11
  - Action frames are extracted deterministically from raw user evidence and link actor, target, action kind, time, topic, project, and evidence.
12
12
 
13
- Existing memory edges remain canonical. Atlas adds derived navigation edges such as `TARGETS`, `OCCURRED_IN`, and evidence drilldowns without changing the underlying belief or binding graph.
13
+ Existing memory edges remain canonical. Atlas adds derived navigation edges such as `OCCURRED_ON`, `OCCURRED_IN`, `ABOUT_TOPIC`, `PART_OF_ISSUE`, `INVOLVES_ENTITY`, `IN_SESSION`, `IN_THREAD`, and `HAS_EVIDENCE` without changing the underlying belief or binding graph. The 3.7.0 offline curator automatically proposes only bounded `SAME_ISSUE`, `FOLLOWS_UP`, and weak `RELATED_TO` episode relations; stronger relations such as `REFINES`, `CORRECTS`, `CONTRADICTS`, and `SUPERSEDES` remain reserved for explicit evidence-bearing governance/binding flows.
14
+
15
+ This is not a copied tree. One episode exists once as `episode:<id>`. A day, topic, issue, entity, session, memory kind, or action kind is only a facet entrance:
16
+
17
+ ```text
18
+ time:2026-06-06 ───────┐
19
+ topic:.../memory-blackbox ─┼──> episode:<id>
20
+ issue:memory-context-blackbox ─┘
21
+ episode:<id> ──HAS_EVIDENCE──> raw_event:<eventId>
22
+ ```
23
+
24
+ Search and explore output dedupe by `canonicalId`. When a canonical episode is reached through several facet paths, the result appears once with all `matchedFacets` and `matchedPaths`.
14
25
 
15
26
  ## Agent workflow
16
27
 
17
28
  1. Use `graph_overview` when the user asks what is remembered.
18
- 2. Use `graph_explore` for broad history, project-state, or relationship questions.
19
- 3. Use `graph_search` when a topic/entity/cluster is already known.
29
+ 2. Use `graph_explore` for broad history, project-state, relationship, or multi-facet questions.
30
+ 3. Use `graph_search` when a topic/entity/cluster is already known and no expansion is needed.
20
31
  4. Use `graph_node`, `graph_neighbors`, `graph_path`, or `graph_timeline` to narrow the graph. Timeline applies the available facets to any timestamped Atlas nodes; action frames are an optional richer result, not a requirement.
21
- 5. Use returned `eventId` values and `cogmem memory show` before quoting exact source text.
32
+ 5. Use returned `sourceLocator.command` or event IDs with `cogmem memory show` before quoting exact source text.
22
33
  6. Use normal `cogmem_recall` for a direct factual memory question.
23
34
 
24
35
  Atlas summaries are `hint_only_not_evidence` in effect. Project scope, raw evidence ownership, and governance still decide what may be claimed as durable memory.
@@ -27,16 +38,41 @@ Atlas summaries are `hint_only_not_evidence` in effect. Project scope, raw evide
27
38
 
28
39
  Activation controls default visibility, not existence. Maintenance decays Atlas activation deterministically; an explicit `cogmem_graph_touch` raises nodes that the agent actually used. Read-only overview/search/explore calls do not change ranking. A query can still surface a cold node when its available facets match.
29
40
 
30
- Facets include project, time, topic, person/object, event, decision, correction, goal, preference, plan, action, and ordinary keywords. The engine combines the facets actually present in the message, similar to filtering multiple columns in a table. It does not require the fixed combination entity + time + action.
41
+ Facets include project, day/month/year, topic, issue, entity/person/project, session/thread, memory kind, action kind, and ordinary keywords. The engine combines the facets actually present in the message, similar to filtering multiple columns in a table. It does not require the fixed combination entity + time + action.
31
42
 
32
43
  For example, all of these can revive cold memory:
33
44
 
45
+ - `6月6号聊过什么`
46
+ - `6月6号关于记忆黑盒聊过什么`
47
+ - `记忆黑盒后来有没有继续讨论`
48
+ - `memory graph 卡死的问题修了吗`
34
49
  - `2025 Hermes 的决策`
35
50
  - `在留更新里被纠正过的计划`
36
51
  - `去年 OpenClaw 失败的配置事件`
37
52
  - `餐车 POS 项目中关于库存的偏好`
38
53
 
39
- Exact constraints may bypass the visibility floor. They never bypass `projectId`, evidence validation, or traversal limits.
54
+ Exact constraints may bypass the visibility floor. They never bypass `projectId`, evidence validation, or traversal limits. If strict intersection is empty, Atlas may relax day to parent month or issue to parent topic, but JSON must include `relaxationTrace`; it must not silently substitute a nearby memory.
55
+
56
+ `graph-search` and `graph-explore` include agent-facing `cards` when canonical episodes match:
57
+
58
+ ```json
59
+ {
60
+ "canonicalId": "episode:episode-xxx",
61
+ "displayTitle": "CogMem Memory Context 黑盒与原文下钻",
62
+ "oneLineSummary": "用户指出注入的 CogMem Memory Context 像黑盒,需要能从摘要下钻到原始对话。",
63
+ "matchedFacets": [
64
+ { "type": "time", "value": "2026-06-06" },
65
+ { "type": "topic", "value": "PROJECT/Cogmem/memory-blackbox" }
66
+ ],
67
+ "matchedPaths": [],
68
+ "relatedButNotSelected": [],
69
+ "sourceLocator": {
70
+ "command": "cogmem memory show --event evt-... --before 2 --after 2 --json"
71
+ }
72
+ }
73
+ ```
74
+
75
+ Agents should prefer `cards` over raw node labels for historical discussion because cards preserve the canonical episode, match reason, and drilldown command.
40
76
 
41
77
  ## Bounds
42
78
 
@@ -58,6 +94,7 @@ BrainEval release fixtures fail closed on Atlas project isolation, node/hop boun
58
94
  cogmem memory graph --project <id> --json
59
95
  cogmem memory graph-search --project <id> --query <query> --json
60
96
  cogmem memory graph-explore --project <id> --query <query> --json
97
+ cogmem memory graph-explore --project openclaw --query "6月6号关于记忆黑盒聊过什么" --json
61
98
  cogmem memory graph-node --project <id> --id <node-id> --json
62
99
  cogmem memory graph-neighbors --project <id> --id <node-id> --hops 1 --json
63
100
  cogmem memory graph-path --project <id> --from <node-id> --to <node-id> --json
@@ -98,4 +135,4 @@ Upgrade an existing 3.5.2 database with:
98
135
  cogmem migrate --yes --backup --json
99
136
  ```
100
137
 
101
- Migration 0025 creates and backfills the disposable projection. Migration 0026 adds exact memory-kind metadata, projection health, and candidate-review audit state. Migration 0027 corrects 3.6.0-upgraded databases by marking Atlas projections dirty until the real action/time rebuild runs. A 3.5.2 schema-24 database, an existing 3.6.0 schema-26 database, or a pre-release schema-25 test database reaches the 3.6.1 schema-27 state with the same command. `cogmem memory tick` refreshes only dirty projects, records rebuild errors, prunes old access telemetry, and decays navigation activation without starting a daemon.
138
+ Migration 0025 creates and backfills the disposable projection. Migration 0026 adds exact memory-kind metadata, projection health, and candidate-review audit state. Migration 0027 corrects 3.6.0-upgraded databases by marking Atlas projections dirty until the real action/time rebuild runs. Cogmem 3.7.0 keeps the projection-first schema and adds facet nodes, canonical cards, issue hints, and episode relation edges during Atlas rebuild/maintenance. `cogmem memory tick` refreshes only dirty projects, records rebuild errors, prunes old access telemetry, and decays navigation activation without starting a daemon.
package/README.md CHANGED
@@ -11,7 +11,7 @@ It is not a knowledge-base app, a note-taking app, a vector RAG wrapper, an Obsi
11
11
 
12
12
  ## Status
13
13
 
14
- Current version: `3.6.5`
14
+ Current version: `3.7.0`
15
15
 
16
16
  Distribution: npm registry. GitHub remains the source mirror and hosts this installer, but package install and upgrade resolve `cogmem` from npm by default.
17
17
 
@@ -89,7 +89,7 @@ Memory Binding
89
89
  CPU-canonicalized raw-event bindings to stable entity/topic paths, claim-key clusters, and activation-aware graph edges for source-anchored organization before fact promotion.
90
90
 
91
91
  Memory Atlas
92
- A bounded, project-scoped content map over topics, entities, clusters, episodes, beliefs, actions, time, and their source-anchored relations. Agents use it to inventory, filter, navigate, and then drill down to Raw Ledger evidence.
92
+ A bounded, project-scoped, multi-dimensional memory navigation graph. Canonical episodes and raw evidence exist once; time, topic, issue, entity, session, memory-kind, and action-kind facets connect to them with typed edges. Agents use it to intersect facets, dedupe by canonicalId, explain why a memory matched, and then drill down to Raw Ledger evidence.
93
93
 
94
94
  User-Shaped Topic Ontology
95
95
  A stable memory-class skeleton plus project-scoped topic names, aliases, parent paths, relations, and reversible audit operations learned from explicit user language.
@@ -229,7 +229,7 @@ cogmem migrate --dry-run --json
229
229
 
230
230
  For a manual migration, run `cogmem migrate --yes --backup`. The migration runner adopts the existing `_meta.schema_version`, applies only later idempotent migrations, preserves Raw Ledger rows, and creates a timestamped, transaction-consistent standalone database backup before changing an on-disk database. The backup includes committed SQLite WAL pages instead of copying only the main database file.
231
231
 
232
- Upgrade a 3.5.2 database, a 3.6.0 database, or a pre-release schema-25 test database into the 3.6.5 schema set with one command:
232
+ Upgrade a 3.5.2 database, a 3.6.x database, or a pre-release schema-25 test database into the current 3.7.0 schema and projection set with one command:
233
233
 
234
234
  ```bash
235
235
  cogmem migrate --yes --backup --json
@@ -276,9 +276,9 @@ For a host timer, call `dream tick`; the timer only wakes the sealed-episode sch
276
276
  cogmem dream tick --project my-agent --mode auto --max-episodes 10 --json
277
277
  ```
278
278
 
279
- Raw events are always written first. `KernelAgentMemoryBackend` and OpenClaw plugin 0.6.3 assemble live turns automatically. The foreground hook uses deterministic rules and previous assistant/user context; background import and repair paths may use the advisory hybrid classifier. Advisory output is allow-listed and cannot directly mutate durable memory. Unknown turns now fail closed as ambiguous. Continuation requires explicit continuation language or project/topic/entity/semantic overlap; Cogmem does not route domains with an expanding hard-coded keyword dictionary.
279
+ Raw events are always written first. `KernelAgentMemoryBackend` and OpenClaw plugin 0.7.0 assemble live turns automatically. The foreground hook uses deterministic rules and previous assistant/user context; background import and repair paths may use the advisory hybrid classifier. Advisory output is allow-listed and cannot directly mutate durable memory. Unknown turns now fail closed as ambiguous. Continuation requires explicit continuation language or project/topic/entity/semantic overlap; Cogmem does not route domains with an expanding hard-coded keyword dictionary.
280
280
 
281
- Hookless MCP agents can call `cogmem_episode_append` or bounded `cogmem_episode_import`. Existing OpenClaw/Hermes import commands use stable content identities and the same episode schema. Low-confidence imported groups soft-seal for review unless an operator explicitly forces sealing. Cogmem 3.6.4 and later skip import batch sealing for empty episode boundaries and skip legacy empty Dream jobs so one bad imported episode cannot block the queue. Episode semantic summaries and closure receipts are control hints, never durable evidence; every Dream candidate must cite a non-empty subset of the episode's raw event IDs and still pass CPU governance.
281
+ Hookless MCP agents can call `cogmem_episode_append` or bounded `cogmem_episode_import`. Existing OpenClaw/Hermes import commands use stable content identities and the same episode schema. Low-confidence imported groups soft-seal for review unless an operator explicitly forces sealing. Cogmem skips import batch sealing for empty episode boundaries and skips legacy empty Dream jobs so one bad imported episode cannot block the queue. Episode semantic summaries and closure receipts are control hints, never durable evidence; every Dream candidate must cite a non-empty subset of the episode's raw event IDs and still pass CPU governance.
282
282
 
283
283
  User-shaped topic state is project-scoped. Explicit user operations become active and auditable; model-proposed topics, aliases, and relations remain candidates. Use MCP `cogmem_topic_list` to inspect nodes, `cogmem_topic_operate` to create, rename, alias, move, merge, split, or relate topics, and `cogmem_topic_rollback` to reverse an audited operation. Alias collisions fail closed as `needs_review`; applications can also call `TopicGovernance.rollback()` through the public API.
284
284
 
@@ -304,21 +304,24 @@ cogmem memory review --project my-agent --id <candidate-id> --action approve --a
304
304
 
305
305
  `cogmem memory map` remains the system anatomy map. Memory Atlas is the content map. It does not replace recall or create a second fact store; it projects existing topics, entities, clusters, episodes, beliefs, action frames, time buckets, bindings, and evidence into a bounded navigation surface.
306
306
 
307
+ In 3.7.0, Atlas is a multi-dimensional navigation graph rather than a folder tree. A remembered episode has one canonical node such as `episode:<id>`. Time, topic, issue, entity, session/thread, memory-kind, and action-kind nodes are facet entrances connected to that canonical episode with typed edges. Results dedupe by `canonicalId` and explain `matchedFacets` plus `matchedPaths`.
308
+
307
309
  ```bash
308
310
  cogmem memory graph --project my-agent --json
309
311
  cogmem memory graph-search --project my-agent --query "Hermes" --json
310
312
  cogmem memory graph-explore --project my-agent --query "去年我让你对 Hermes 做过什么" --json
313
+ cogmem memory graph-explore --project openclaw --query "6月6号关于记忆黑盒聊过什么" --json
311
314
  cogmem memory graph-node --project my-agent --id "entity:<id>" --json
312
315
  cogmem memory graph-neighbors --project my-agent --id "entity:<id>" --hops 2 --json
313
316
  cogmem memory graph-path --project my-agent --from "entity:<id>" --to "action:<id>" --json
314
317
  cogmem memory graph-timeline --project my-agent --query "2025 Hermes 的决策和修复" --json
315
318
  ```
316
319
 
317
- Atlas filtering is not limited to entity + time + action. The query compiler combines whichever facets are actually present, such as project, time range, topic, person/object, event, decision, correction, goal, preference, plan, action, and ordinary keywords. Exact multi-facet matches may surface cold nodes even when their activation has decayed. Project scope and raw evidence validation are never bypassed.
320
+ Atlas filtering is not limited to entity + time + action. The facet planner combines whichever facets are actually present, such as project, day/month/year, topic, issue, entity/person/project, session/thread, memory kind, action kind, and ordinary keywords. Strict multi-facet matches may surface cold nodes even when their activation has decayed. If strict intersection is empty, JSON includes `relaxationTrace` instead of silently pretending an exact match existed. Project scope and raw evidence validation are never bypassed.
318
321
 
319
322
  Defaults are 8 nodes, one hop, and two evidence IDs per node. Hard limits are 30 nodes, two hops, ten evidence IDs, six path hops, and 2,000 visited nodes. Raw excerpts are omitted unless `--include-evidence` or `includeEvidence: true` is explicit. `evidenceTotal` reports all known evidence while `evidenceReturned` reports the bounded payload. Every returned evidence item carries an `eventId` and a `cogmem memory show` drilldown command.
320
323
 
321
- In 3.6.5, Atlas search and explore evidence also carries `sourceLocator.command` and `sourceLocator.contextCommand`. Agents should run that locator before quoting exact wording, before claiming a historical topic is absent, or when a graph summary looks relevant but underspecified.
324
+ Atlas search and explore return agent-facing `cards` for canonical episodes. Each card includes `canonicalId`, `displayTitle`, `oneLineSummary`, `matchedFacets`, `matchedPaths`, `relatedButNotSelected`, and `sourceLocator.command` / `sourceLocator.contextCommand` when evidence is available. Agents should run that locator before quoting exact wording, before claiming a historical topic is absent, or when a graph summary looks relevant but underspecified.
322
325
 
323
326
  Atlas reads do not brighten everything they display. MCP graph queries are read-only/idempotent; call `cogmem_graph_touch` only after the agent actually uses selected nodes. Maintenance decays activation, refreshes dirty projections only, and prunes old access telemetry.
324
327
 
@@ -357,7 +360,7 @@ Operational cost classes:
357
360
 
358
361
  Never overlap maintenance writers against one database. Wait for each command to exit, use returned `durationMs`, backlog, and failure details to set the next interval, and keep routine status/candidate inspection on the read-only path. A `vectors` count of zero is not by itself a failure: `memory status --json` includes `vectorState.recallAvailableWithoutVectors` and the active fallback status.
359
362
 
360
- `memory bind` backfills Memory Binding for raw user events written outside the agent turn path, including imported OpenClaw/Hermes history and adapter-written raw events. In 3.6.5 it scans by Raw Ledger cursor rather than only the latest page. Use `--since <globalSeq>` to resume from a known ledger sequence.
363
+ `memory bind` backfills Memory Binding for raw user events written outside the agent turn path, including imported OpenClaw/Hermes history and adapter-written raw events. It scans by Raw Ledger cursor rather than only the latest page. Use `--since <globalSeq>` to resume from a known ledger sequence.
361
364
 
362
365
  `memory map` includes Memory Binding and Graph Recall counters. Bindings attach valuable user raw events to stable topic/entity paths before any fact promotion, fuse same-claim evidence into claim-key clusters, and create graph anchors for source drill-down. Correction events create explicit correction edges and review flags instead of poisoning the active cluster. Treat bindings, clusters, and graph edges as organization hints, not as verified long-term facts.
363
366
 
@@ -378,7 +381,7 @@ cogmem strategy plan --project hermes --query "我当时的原话是什么?" -
378
381
  cogmem strategy outcomes --project hermes --json
379
382
  ```
380
383
 
381
- OpenClaw plugin 0.6.3 skips Cogmem entirely for greetings, uses only session state/turn bridge for short continuations, and applies Strategy Cortex before full recall. Navigation turns use one bridge/kernel lifecycle for Atlas exploration, evidence-bearing node/timeline drill-down, and recall. The bounded volatile `<COGMEM_MEMORY_ATLAS>` block includes evidence event IDs and drill-down commands; OpenClaw does not need MCP for this path.
384
+ OpenClaw plugin 0.7.0 skips Cogmem entirely for greetings, uses only session state/turn bridge for short continuations, and applies Strategy Cortex before full recall. Navigation turns use one bridge/kernel lifecycle for Atlas exploration, evidence-bearing node/timeline drill-down, and recall. The bounded volatile `<COGMEM_MEMORY_ATLAS>` block includes selected memory cards, matched facets, matched paths, related-but-not-selected cards, evidence event IDs, and drill-down commands; OpenClaw does not need MCP for this path.
382
385
 
383
386
  `cogmem connect openclaw --auto --force --json` and `cogmem connect hermes --auto --force --json` now return structured `nextSteps`. Only `nextSteps` with `actor: "agent"` and `safeForAutomation: true` are mirrored into `nextCommands`. Interactive setup, gateway restart, and Hermes reload remain visible as operator/host steps but are intentionally absent from `nextCommands`.
384
387
 
@@ -790,7 +793,7 @@ npm pack --dry-run --json
790
793
  npm publish --dry-run --access public
791
794
  ```
792
795
 
793
- Create a GitHub Release from the matching version tag, for example `v3.6.5`. The `.github/workflows/publish.yml` workflow publishes to npm only when the release is published, not when a tag is pushed. The npm Trusted Publisher entry must match repository `liuqin164/cogmem`, workflow file `publish.yml`, and environment `npm publish`.
796
+ Create a GitHub Release from the matching version tag, for example `v3.7.0`. The `.github/workflows/publish.yml` workflow publishes to npm only when the release is published, not when a tag is pushed. The npm Trusted Publisher entry must match repository `liuqin164/cogmem`, workflow file `publish.yml`, and environment `npm publish`.
794
797
 
795
798
  Publish manually only for emergency fallback:
796
799
 
@@ -1,11 +1,11 @@
1
- # cogmem 3.6.5 Release Checklist
1
+ # cogmem 3.7.0 Release Checklist
2
2
 
3
3
  This release is distributed through the npm registry. GitHub remains the source and review mirror.
4
4
 
5
5
  ## Required Metadata
6
6
 
7
7
  - `package.json` name is `cogmem`.
8
- - `package.json` version is `3.6.5`.
8
+ - `package.json` version is `3.7.0`.
9
9
  - `package.json` has `publishConfig.access = public`.
10
10
  - Public export `.` points to `dist/public.js` and `dist/public.d.ts`.
11
11
  - Internal subpath `./internal` exists only as an explicit advanced subpath.
@@ -61,7 +61,8 @@ MCP `tools/list` includes strategy, episode append/import/status/seal/repair, to
61
61
  - README and skills explain Raw Ledger-first episode assembly, soft/hard sealing, explicit conditional Dream ticks, raw-event evidence grounding, repair/retry, and hookless Hermes MCP/import usage.
62
62
  - README and skills give the full post-import maintenance sequence: status, episode status, Dream status, bounded Dream tick, candidate listing, govern candidate, needs-confirmation listing, explicit review, and recall verification.
63
63
  - README and skills explain that 3.6.4+ skips empty imported episode boundaries and legacy empty Dream jobs instead of letting them abort `dream tick`.
64
- - README and skills explain the 3.6.5 agent operations protocol: `memory plan` for next actions, default grouped `memory candidates --json`, `memory list --since/--until/--order`, historical-discussion recall intent, Atlas evidence `sourceLocator`, and cursor-based `memory bind`.
64
+ - README and skills explain the 3.7.0 agent operations protocol: `memory plan` for next actions, default grouped `memory candidates --json`, `memory list --since/--until/--order`, historical-discussion recall intent, Atlas canonical cards, `matchedFacets`, `relatedButNotSelected`, `relaxationTrace`, Atlas evidence `sourceLocator`, and cursor-based `memory bind`.
65
+ - README, `MEMORY_ATLAS.md`, and installed skills explain the multi-dimensional Atlas model: a canonical episode/raw event exists once, facet nodes connect through typed edges, query results intersect facets, and display/injection dedupes by `canonicalId`.
65
66
  - `connect openclaw|hermes --json` documents structured `nextSteps`; `nextCommands` must contain only agent-safe, non-interactive commands and must not include `cogmem init`, `cogmem-init`, gateway restart, or Hermes reload.
66
67
  - README and skills document `cogmem mcp` as the preferred MCP server command for new configs while preserving `cogmem-mcp` as a compatibility bin.
67
68
  - README and skills explain CPU foreground versus hybrid background classification, contextual short replies, registry-aware topic boundaries, safe reopen, semantic-summary non-evidence status, per-job Dream modes/failures, stable import identity, and schema migration 24.
@@ -93,7 +94,7 @@ npm publish --dry-run --access public
93
94
 
94
95
  The pack dry-run must include built public API files, CLI files, examples, docs, and `install.sh`. It must not include local databases or machine-specific files.
95
96
 
96
- After verification, create a GitHub Release from the matching version tag, for example `v3.6.5`. The release workflow publishes through npm Trusted Publishing when the release is published. It must not publish on tag push alone.
97
+ After verification, create a GitHub Release from the matching version tag, for example `v3.7.0`. The release workflow publishes through npm Trusted Publishing when the release is published. It must not publish on tag push alone.
97
98
 
98
99
  Emergency manual fallback:
99
100
 
@@ -1,4 +1,5 @@
1
1
  import type { MemoryKernel, MemoryKernelNavigationResult } from '../factory.js';
2
+ import type { MemoryAtlasCard, MemoryAtlasRelatedCard, MemoryAtlasRelaxationStep } from '../atlas/MemoryAtlasTypes.js';
2
3
  import { type MemoryEventCharRange, type MemoryEventSourceRange, type SourceContextWindowMetadata } from '../recall/SourceContextMetadata.js';
3
4
  import type { BeliefRecord, MemoryEvent } from '../types/index.js';
4
5
  import type { StrategyRetrievalPolicy } from '../strategy/StrategyCapsule.js';
@@ -152,6 +153,10 @@ export interface AgentRecallItem {
152
153
  text: string;
153
154
  projectId?: string;
154
155
  topicPath?: string;
156
+ canonicalId?: string;
157
+ displayTitle?: string;
158
+ matchedFacets?: MemoryAtlasCard['matchedFacets'];
159
+ matchedPaths?: MemoryAtlasCard['matchedPaths'];
155
160
  tags: string[];
156
161
  source?: string;
157
162
  sourceType?: 'compiled_memory' | 'imported_summary' | 'raw_ledger' | 'raw_ledger_session';
@@ -170,12 +175,15 @@ export interface AgentRecallResult {
170
175
  runtime?: NonNullable<MemoryKernelNavigationResult['navigation']>['runtime'];
171
176
  fallbackUsed: boolean;
172
177
  queryPlan?: AgentRecallQueryPlan;
178
+ atlasCards?: MemoryAtlasCard[];
179
+ relatedButNotSelected?: MemoryAtlasRelatedCard[];
180
+ relaxationTrace?: MemoryAtlasRelaxationStep[];
173
181
  /** Present on all kernel-produced results. Optional for source compatibility with external result mocks. */
174
182
  decisionTrace?: AgentRecallDecisionTrace;
175
183
  }
176
184
  export interface AgentRecallDecisionTrace {
177
185
  version: 'agent_recall_decision.v1';
178
- selectedLane: 'graph' | 'compiled' | 'brain_fallback' | 'raw_ledger' | 'mixed' | 'none';
186
+ selectedLane: 'facet_graph_raw_ledger' | 'graph' | 'compiled' | 'brain_fallback' | 'raw_ledger' | 'mixed' | 'none';
179
187
  reason: 'previous_session' | 'forensic_quote' | 'historical_discussion' | 'graph_selected' | 'raw_cue_match_preferred' | 'compiled_cue_match' | 'brain_fallback_selected' | 'raw_ledger_only' | 'no_recall_evidence';
180
188
  candidateCounts: {
181
189
  graph: number;
@@ -247,6 +255,8 @@ export declare class KernelAgentMemoryBackend {
247
255
  private recallPreviousSession;
248
256
  private recallForensicQuote;
249
257
  private recallHistoricalDiscussion;
258
+ private facetGraphItemsForQuery;
259
+ private toAgentRecallItemFromAtlasCard;
250
260
  private recallForensicAnchor;
251
261
  private searchRawEventsByQueryPlan;
252
262
  private rawLedgerFallbackItemsForQuery;
@@ -257,6 +267,8 @@ export declare class KernelAgentMemoryBackend {
257
267
  private recallCueTerms;
258
268
  private itemSearchableText;
259
269
  private mergeRecallItems;
270
+ private mergeHistoricalRecallItems;
271
+ private compiledItemsForHistoricalQuery;
260
272
  private dedupeRawEventsByTurnPreferUser;
261
273
  private expandRawSearchTexts;
262
274
  private findPreviousSessionId;
@@ -498,41 +498,82 @@ export class KernelAgentMemoryBackend {
498
498
  const allowsGraph = laneAllowed(query.retrievalPolicy, 'graph');
499
499
  const allowsCompiled = laneAllowed(query.retrievalPolicy, 'compiled');
500
500
  const allowsRawSource = laneAllowed(query.retrievalPolicy, 'raw_source');
501
+ const facetResult = allowsGraph ? this.facetGraphItemsForQuery(query, limit) : { items: [], cards: [], relatedButNotSelected: [], relaxationTrace: [] };
502
+ const facetItems = allowsRawSource ? facetResult.items : [];
501
503
  const graphItems = allowsGraph ? this.memoryBindingGraphItemsForQuery(query, queryPlan, limit) : [];
502
504
  const rawItems = allowsRawSource ? this.rawLedgerFallbackItemsForQuery(queryPlan, query, Math.max(limit * 2, 10)) : [];
503
- const retrievalLimit = Math.max(limit * 4, 24);
504
505
  const compiledItems = allowsCompiled
505
- ? this.filterAgentEvidence(this.kernel.navigateMemory(queryPlan.primarySearchText, {
506
- projectId: query.projectId,
507
- limit: retrievalLimit,
508
- startTime: query.startTime,
509
- endTime: query.endTime,
510
- }).rawEvidence, query.agentId, query.collection, query.excludeSessionId)
511
- .slice(0, limit)
512
- .map((neuron) => this.toAgentRecallItem(neuron))
506
+ ? this.compiledItemsForHistoricalQuery(queryPlan, query, limit)
513
507
  : [];
514
- const items = this.mergeRecallItems(rawItems, this.mergeRecallItems(graphItems, compiledItems, limit), limit);
515
- const selectedLane = rawItems.length > 0
516
- ? 'raw_ledger'
517
- : graphItems.length > 0
518
- ? 'graph'
519
- : compiledItems.length > 0
520
- ? 'compiled'
521
- : 'none';
508
+ const items = this.mergeHistoricalRecallItems(facetItems, rawItems, graphItems, compiledItems, limit);
509
+ const selectedLane = facetItems.length > 0
510
+ ? 'facet_graph_raw_ledger'
511
+ : rawItems.length > 0
512
+ ? 'raw_ledger'
513
+ : graphItems.length > 0
514
+ ? 'graph'
515
+ : compiledItems.length > 0
516
+ ? 'compiled'
517
+ : 'none';
522
518
  return {
523
- recallMode: rawItems.length > 0 ? 'raw_ledger_fallback' : 'brain_recall_fallback',
519
+ recallMode: facetItems.length > 0 || rawItems.length > 0 ? 'raw_ledger_fallback' : 'brain_recall_fallback',
524
520
  items,
525
521
  fallbackUsed: true,
526
522
  queryPlan,
523
+ atlasCards: facetResult.cards,
524
+ relatedButNotSelected: facetResult.relatedButNotSelected,
525
+ relaxationTrace: facetResult.relaxationTrace,
527
526
  decisionTrace: recallDecisionTrace(selectedLane, 'historical_discussion', {
528
- graph: graphItems.length,
527
+ graph: graphItems.length + facetItems.length,
529
528
  navigation: compiledItems.length,
530
529
  scopedNavigation: compiledItems.length,
531
530
  brainFallback: 0,
532
- rawLedger: rawItems.length,
531
+ rawLedger: rawItems.length + facetItems.length,
533
532
  }, items.length),
534
533
  };
535
534
  }
535
+ facetGraphItemsForQuery(query, limit) {
536
+ try {
537
+ const atlas = this.kernel.graphExplore(query.query, {
538
+ projectId: query.projectId,
539
+ limit,
540
+ includeEvidence: true,
541
+ evidenceLimit: 2,
542
+ refresh: true,
543
+ staleOk: true,
544
+ });
545
+ const cards = (atlas.cards ?? []).slice(0, limit);
546
+ const items = cards.map((card) => this.toAgentRecallItemFromAtlasCard(card, query)).filter((item) => Boolean(item));
547
+ const relatedButNotSelected = cards.flatMap((card) => card.relatedButNotSelected ?? []).slice(0, 8);
548
+ return { items, cards, relatedButNotSelected, relaxationTrace: atlas.relaxationTrace ?? [] };
549
+ }
550
+ catch {
551
+ return { items: [], cards: [], relatedButNotSelected: [], relaxationTrace: [] };
552
+ }
553
+ }
554
+ toAgentRecallItemFromAtlasCard(card, query) {
555
+ const eventId = card.sourceLocator?.eventId ?? card.evidenceEventIds[0];
556
+ const sourceContext = eventId ? this.toAgentSourceContext(eventId) : undefined;
557
+ const anchorEvent = sourceContext?.event;
558
+ return {
559
+ id: `facet:${card.canonicalId}`,
560
+ text: [card.displayTitle, card.oneLineSummary].filter(Boolean).join(': '),
561
+ projectId: query.projectId,
562
+ topicPath: card.parentTopics[0],
563
+ canonicalId: card.canonicalId,
564
+ displayTitle: card.displayTitle,
565
+ matchedFacets: card.matchedFacets,
566
+ matchedPaths: card.matchedPaths,
567
+ tags: ['facet_graph', card.eventKind, card.issueType].filter((tag) => Boolean(tag)),
568
+ source: 'memory_atlas',
569
+ sourceType: 'raw_ledger',
570
+ sourceAnchor: anchorEvent ? this.toAgentSourceAnchorFromContextEvent(anchorEvent) : eventId ? { eventId } : undefined,
571
+ sourceContext,
572
+ confidence: Math.min(1, 0.7 + card.matchedFacets.length * 0.08),
573
+ whyMatched: card.whyMatched,
574
+ canAnswerExactQuote: Boolean(sourceContext),
575
+ };
576
+ }
536
577
  recallForensicAnchor(query, limit) {
537
578
  if (!query.anchorEventId)
538
579
  return [];
@@ -698,15 +739,55 @@ export class KernelAgentMemoryBackend {
698
739
  const out = [];
699
740
  const seen = new Set();
700
741
  for (const item of [...primary, ...secondary]) {
701
- if (seen.has(item.id))
742
+ const keys = [item.canonicalId, item.sourceAnchor?.eventId, item.id].filter((value) => Boolean(value));
743
+ if (keys.some((key) => seen.has(key)))
702
744
  continue;
703
- seen.add(item.id);
745
+ for (const key of keys)
746
+ seen.add(key);
704
747
  out.push(item);
705
748
  if (out.length >= limit)
706
749
  break;
707
750
  }
708
751
  return out;
709
752
  }
753
+ mergeHistoricalRecallItems(facetItems, rawItems, graphItems, compiledItems, limit) {
754
+ const merged = this.mergeRecallItems(facetItems, this.mergeRecallItems(rawItems, this.mergeRecallItems(graphItems, compiledItems, limit), limit), limit);
755
+ if (merged.some((item) => item.sourceType === 'imported_summary'))
756
+ return merged;
757
+ const importedSupport = compiledItems.find((item) => item.sourceType === 'imported_summary');
758
+ if (!importedSupport)
759
+ return merged;
760
+ const withoutDuplicate = merged.filter((item) => item.id !== importedSupport.id && item.sourceAnchor?.eventId !== importedSupport.sourceAnchor?.eventId);
761
+ if (withoutDuplicate.length < limit)
762
+ return [...withoutDuplicate, importedSupport];
763
+ return [...withoutDuplicate.slice(0, Math.max(0, limit - 1)), importedSupport];
764
+ }
765
+ compiledItemsForHistoricalQuery(queryPlan, query, limit) {
766
+ const retrievalLimit = Math.max(limit * 4, 24);
767
+ const out = [];
768
+ const seen = new Set();
769
+ for (const searchText of uniqueNonEmpty([queryPlan.primarySearchText, ...queryPlan.searchTexts, queryPlan.originalQuery])) {
770
+ const rawEvidence = this.kernel.navigateMemory(searchText, {
771
+ projectId: query.projectId,
772
+ limit: retrievalLimit,
773
+ startTime: query.startTime,
774
+ endTime: query.endTime,
775
+ }).rawEvidence;
776
+ const items = this.filterAgentEvidence(rawEvidence, query.agentId, query.collection, query.excludeSessionId)
777
+ .map((neuron) => this.toAgentRecallItem(neuron));
778
+ for (const item of items) {
779
+ const key = item.id || item.sourceAnchor?.eventId;
780
+ if (key && seen.has(key))
781
+ continue;
782
+ if (key)
783
+ seen.add(key);
784
+ out.push(item);
785
+ if (out.length >= limit)
786
+ return out;
787
+ }
788
+ }
789
+ return out;
790
+ }
710
791
  dedupeRawEventsByTurnPreferUser(events) {
711
792
  const byTurn = new Map();
712
793
  for (const event of events) {
@@ -0,0 +1,31 @@
1
+ import type { MemoryEvent } from '../types/index.js';
2
+ export interface EpisodeTitleInput {
3
+ episodeId: string;
4
+ summary?: string | null;
5
+ topicPath?: string | null;
6
+ episodeType?: string | null;
7
+ startedAt?: number | null;
8
+ events: MemoryEvent[];
9
+ }
10
+ export interface EpisodeTitleResult {
11
+ displayTitle: string;
12
+ oneLineSummary: string;
13
+ topicHints: string[];
14
+ issueHints: string[];
15
+ eventKind: string;
16
+ userIntent?: string;
17
+ localDate?: string;
18
+ confidence: number;
19
+ reviewNeeded: boolean;
20
+ sourceEventIds: string[];
21
+ generatorTrace: {
22
+ usedUserText: boolean;
23
+ usedAssistantText: boolean;
24
+ fallback: boolean;
25
+ matchedRules: string[];
26
+ };
27
+ }
28
+ export declare class EpisodeTitleGenerator {
29
+ generate(input: EpisodeTitleInput): EpisodeTitleResult;
30
+ }
31
+ //# sourceMappingURL=EpisodeTitleGenerator.d.ts.map