@yeaft/webchat-agent 0.1.665 → 0.1.666

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.
@@ -36,7 +36,7 @@ import { sendToServer, flushMessageBuffer } from './buffer.js';
36
36
  import { handleRestartAgent, handleUpgradeAgent } from './upgrade.js';
37
37
  import { loadMcpServers, updateMcpConfig } from '../mcp.js';
38
38
  import { getLlmConfig, updateLlmConfig, getUnifySettings, updateUnifySettings } from '../unify/config-api.js';
39
- import { handleUnifyChat, handleUnifyGroupChat, handleUnifyModeSwitch, handleUnifyModelSwitch, resetUnifySession, handleUnifyLoadHistory, handleUnifyAbortThread, handleUnifyAbortAll, handleUnifyVpSubscribe, handleUnifyVpCreate, handleUnifyVpUpdate, handleUnifyVpDelete, handleUnifyVpRead, handleUnifyFeatureMessage, handleUnifyUserMemoryWrite, handleUnifyUserMemoryRemove, handleUnifyMemoryScopeList, handleUnifyMemoryQuery, handleUnifyMemoryTrace, handleUnifyFetchSummaryHistory, handleUnifyFeatureCrud, handleUnifyListGroups, handleUnifyCreateGroup, handleUnifyRenameGroup, handleUnifyArchiveGroup, handleUnifyDeleteGroup, handleUnifyAddMember, handleUnifyRemoveMember, handleUnifySetDefaultVp, handleUnifyDreamTrigger } from '../unify/web-bridge.js';
39
+ import { handleUnifyChat, handleUnifyGroupChat, handleUnifyModeSwitch, handleUnifyModelSwitch, resetUnifySession, handleUnifyLoadHistory, handleUnifyAbortThread, handleUnifyAbortAll, handleUnifyVpSubscribe, handleUnifyVpCreate, handleUnifyVpUpdate, handleUnifyVpDelete, handleUnifyVpRead, handleUnifyFeatureMessage, handleUnifyFetchSummaryHistory, handleUnifyFeatureCrud, handleUnifyListGroups, handleUnifyCreateGroup, handleUnifyRenameGroup, handleUnifyArchiveGroup, handleUnifyDeleteGroup, handleUnifyAddMember, handleUnifyRemoveMember, handleUnifySetDefaultVp, handleUnifyDreamTrigger } from '../unify/web-bridge.js';
40
40
 
41
41
  export async function handleMessage(msg) {
42
42
  switch (msg.type) {
@@ -424,29 +424,6 @@ export async function handleMessage(msg) {
424
424
  handleUnifyFeatureMessage(msg);
425
425
  break;
426
426
 
427
- // task-334h (R6 §Δ29): user-memory skeleton. Payload schema + event
428
- // names are wire-frozen here; real ingestion lands in task-334l.
429
- case 'unify_user_memory_write':
430
- handleUnifyUserMemoryWrite(msg);
431
- break;
432
- case 'unify_user_memory_remove':
433
- handleUnifyUserMemoryRemove(msg);
434
- break;
435
- // task-fix: list MemoryStore entries (scope-tree folder view) for the
436
- // Unify "User Memory" page. Replies with `memory_scope_snapshot`.
437
- case 'unify_memory_scope_list':
438
- handleUnifyMemoryScopeList(msg);
439
- break;
440
-
441
- // R6 G2 — VP/Task memory browser (read-only). Replies with
442
- // unify_memory_query_result / unify_memory_trace_result.
443
- case 'unify_memory_query':
444
- handleUnifyMemoryQuery(msg);
445
- break;
446
- case 'unify_memory_trace':
447
- handleUnifyMemoryTrace(msg);
448
- break;
449
-
450
427
  // R6 G1a — feature summary history + feature affiliation CRUD.
451
428
  case 'unify_fetch_summary_history':
452
429
  await handleUnifyFetchSummaryHistory(msg);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.665",
3
+ "version": "0.1.666",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/unify/cli.js CHANGED
@@ -14,7 +14,7 @@
14
14
  * --skip-skills — Skip skill loading
15
15
  *
16
16
  * REPL commands:
17
- * /memory — Show memory status or manage entries
17
+ * /history — Show conversation history
18
18
  * /history [n] — Show last N messages from conversation
19
19
  * /search <keyword> — Search conversation history
20
20
  * /compact — Trigger manual consolidation
@@ -31,7 +31,6 @@ import { loadSession } from './session.js';
31
31
  import { listModels, resolveModel, parseModelRef } from './models.js';
32
32
  import { buildSystemPrompt } from './prompts.js';
33
33
  import { searchMessages } from './conversation/search.js';
34
- import { consolidate } from './memory/consolidate.js';
35
34
 
36
35
  // ─── Argument parsing ──────────────────────────────────────────
37
36
 
@@ -211,7 +210,7 @@ async function runREPL(config, args) {
211
210
  skipSkills: args.skipSkills,
212
211
  });
213
212
 
214
- const { engine, conversationStore, memoryStore, trace, skillManager, mcpManager, toolRegistry } = session;
213
+ const { engine, conversationStore, trace, skillManager, mcpManager, toolRegistry } = session;
215
214
 
216
215
  // Load persisted conversation as initial messages
217
216
  let conversationMessages = conversationStore.loadRecent(50).map(m => ({
@@ -223,10 +222,9 @@ async function runREPL(config, args) {
223
222
 
224
223
  const hotCount = conversationStore.countHot();
225
224
  const coldCount = conversationStore.countCold();
226
- const memStats = memoryStore.stats();
227
225
 
228
226
  console.log(`Yeaft Unify REPL (model: ${session.config.model})`);
229
- console.log(`Conversation: ${hotCount} hot, ${coldCount} cold | Memory: ${memStats.entryCount} entries`);
227
+ console.log(`Conversation: ${hotCount} hot, ${coldCount} cold`);
230
228
  console.log(`Tools: ${session.status.tools} | Skills: ${session.status.skills}`);
231
229
  if (session.status.mcpServers.length > 0) {
232
230
  console.log(`MCP: ${session.status.mcpServers.join(', ')}`);
@@ -260,7 +258,6 @@ async function runREPL(config, args) {
260
258
  console.log('Commands:');
261
259
  console.log(' /debug — Toggle debug mode');
262
260
  console.log(' /trace <stats|recent> — Query debug trace');
263
- console.log(' /memory [add|clear|stats] — Memory management');
264
261
  console.log(' /history [n] — Show last N messages');
265
262
  console.log(' /search <keyword> — Search conversation history');
266
263
  console.log(' /compact — Trigger consolidation');
@@ -293,55 +290,7 @@ async function runREPL(config, args) {
293
290
  }
294
291
 
295
292
  case 'memory': {
296
- const subcmd = cmdArgs[0];
297
- if (subcmd === 'add') {
298
- // /memory add <section> <entry text>
299
- const section = cmdArgs[1];
300
- const entryText = cmdArgs.slice(2).join(' ');
301
- if (!section || !entryText) {
302
- console.log('Usage: /memory add <section> <entry text>');
303
- } else {
304
- memoryStore.addToSection(section, `- ${entryText}`);
305
- console.log(`Added to MEMORY.md [${section}]: ${entryText}`);
306
- }
307
- } else if (subcmd === 'clear') {
308
- memoryStore.clear();
309
- console.log('All memory cleared.');
310
- } else if (subcmd === 'stats') {
311
- const s = memoryStore.stats();
312
- console.log('Memory stats:');
313
- console.log(` Entries: ${s.entryCount}`);
314
- console.log(` Scopes: ${s.scopes.join(', ') || '(none)'}`);
315
- console.log(` Kinds: ${Object.entries(s.kinds).map(([k, v]) => `${k}=${v}`).join(', ') || '(none)'}`);
316
- } else if (subcmd === 'search') {
317
- const keyword = cmdArgs.slice(1).join(' ');
318
- if (!keyword) {
319
- console.log('Usage: /memory search <keyword>');
320
- } else {
321
- const results = memoryStore.search(keyword);
322
- if (results.length === 0) {
323
- console.log(`No memory entries matching "${keyword}".`);
324
- } else {
325
- console.log(`Found ${results.length} entries:`);
326
- for (const e of results) {
327
- console.log(` [${e.kind}] ${e.name} (scope: ${e.scope})`);
328
- console.log(` ${(e.content || '').slice(0, 100)}`);
329
- }
330
- }
331
- }
332
- } else {
333
- // Default: show MEMORY.md content
334
- const profile = memoryStore.readProfile();
335
- const s = memoryStore.stats();
336
- if (profile) {
337
- console.log('--- MEMORY.md ---');
338
- console.log(profile.slice(0, 1000));
339
- if (profile.length > 1000) console.log('... (truncated)');
340
- } else {
341
- console.log('MEMORY.md is empty.');
342
- }
343
- console.log(`\nEntries: ${s.entryCount} | Scopes: ${s.scopes.length}`);
344
- }
293
+ console.log('Memory commands have been retired. Memory is now managed by Dream V2; use the in-app FTS recall.');
345
294
  break;
346
295
  }
347
296
 
@@ -382,33 +331,7 @@ async function runREPL(config, args) {
382
331
  }
383
332
 
384
333
  case 'compact': {
385
- try {
386
- const budget = session.config.messageTokenBudget || 8192;
387
- const hotTokens = conversationStore.hotTokens();
388
- console.log(`Hot tokens: ${hotTokens} / budget: ${budget}`);
389
-
390
- if (hotTokens <= 0) {
391
- console.log('No messages to compact.');
392
- break;
393
- }
394
-
395
- console.log('Running consolidation...');
396
- const result = await consolidate({
397
- conversationStore,
398
- memoryStore,
399
- adapter: session.adapter,
400
- config: session.config,
401
- budget: Math.min(budget, hotTokens), // force trigger
402
- });
403
- console.log(`Consolidation complete:`);
404
- console.log(` Archived: ${result.archivedCount} messages`);
405
- console.log(` Extracted: ${result.extractedEntries.length} memory entries`);
406
- if (result.compactSummary) {
407
- console.log(` Summary: ${result.compactSummary.slice(0, 200)}...`);
408
- }
409
- } catch (e) {
410
- console.error(`Consolidation error: ${e.message}`);
411
- }
334
+ console.log('The /compact REPL command is retired. Compaction is driven automatically by the engine when the hot-window budget is exceeded.');
412
335
  break;
413
336
  }
414
337
 
@@ -421,7 +344,6 @@ async function runREPL(config, args) {
421
344
  console.log(` Hot messages: ${conversationStore.countHot()}`);
422
345
  console.log(` Hot tokens: ${conversationStore.hotTokens()}`);
423
346
  console.log(` Cold messages: ${conversationStore.countCold()}`);
424
- console.log(` Memory entries: ${memoryStore.stats().entryCount}`);
425
347
  console.log(` Tools: ${toolRegistry.size}`);
426
348
  console.log(` Skills: ${skillManager.size}`);
427
349
  break;
@@ -438,7 +360,6 @@ async function runREPL(config, args) {
438
360
  console.log(` Tools: ${s.toolCount}`);
439
361
  console.log(` Hot messages: ${conversationStore.countHot()}`);
440
362
  console.log(` Cold messages: ${conversationStore.countCold()}`);
441
- console.log(` Memory entries: ${memoryStore.stats().entryCount}`);
442
363
  console.log(` Registered tools: ${toolRegistry.size}`);
443
364
  console.log(` Loaded skills: ${skillManager.size}`);
444
365
  break;
package/unify/engine.js CHANGED
@@ -21,13 +21,11 @@ import { randomUUID } from 'crypto';
21
21
  import { buildSystemPrompt, buildWorkerPrompt } from './prompts.js';
22
22
  import { LLMContextError, LLMAbortError } from './llm/adapter.js';
23
23
  import { runMemoryPreflow, buildRelevantScopes } from './groups/pre-flow.js';
24
- import { shouldConsolidate, consolidate, partitionMessages } from './memory/consolidate.js';
25
- import { extractMemories } from './memory/extract.js';
24
+ import { shouldConsolidate, partitionMessages } from './memory/consolidate.js';
26
25
  import { runCompact as runCompactOrchestrator } from './compact/orchestrator.js';
27
26
  import { evaluateCompactTriggers } from './compact/triggers.js';
28
27
  import { archiveTurn } from './archive/turn-archive.js';
29
28
  import { archiveToolResults } from './archive/tool-results.js';
30
- import { buildMemoryInjection } from './memory/layout.js';
31
29
  import { readSummary as readScopeSummary } from './memory/store-v2.js';
32
30
  import { runAdjust } from './memory/adjust.js';
33
31
  import { runStopHooks } from './stop-hooks.js';
@@ -145,12 +143,6 @@ export class Engine {
145
143
  /** @type {import('./conversation/persist.js').ConversationStore|null} */
146
144
  #conversationStore;
147
145
 
148
- /** @type {import('./memory/store.js').MemoryStore|null} */
149
- #memoryStore;
150
-
151
- /** @type {object|null} — R6 memory shard store (task-334f) */
152
- #memoryShardStore;
153
-
154
146
  /** @type {import('./memory/index-db.js').SegmentIndex|null} — GC.1: SQLite FTS5 segment index */
155
147
  #memoryIndex;
156
148
 
@@ -235,7 +227,6 @@ export class Engine {
235
227
  * trace: object,
236
228
  * config: object,
237
229
  * conversationStore?: import('./conversation/persist.js').ConversationStore,
238
- * memoryStore?: import('./memory/store.js').MemoryStore,
239
230
  * memoryIndex?: import('./memory/index-db.js').SegmentIndex,
240
231
  * toolRegistry?: import('./tools/registry.js').ToolRegistry,
241
232
  * skillManager?: import('./skills.js').SkillManager,
@@ -243,15 +234,13 @@ export class Engine {
243
234
  * yeaftDir?: string,
244
235
  * }} params
245
236
  */
246
- constructor({ adapter, trace, config, conversationStore, memoryStore, memoryShardStore, memoryIndex, amsRegistry, toolRegistry, skillManager, mcpManager, yeaftDir }) {
237
+ constructor({ adapter, trace, config, conversationStore, memoryIndex, amsRegistry, toolRegistry, skillManager, mcpManager, yeaftDir }) {
247
238
  this.#adapter = adapter;
248
239
  this.#trace = trace;
249
240
  this.#config = config;
250
241
  this.#tools = new Map();
251
242
  this.#traceId = randomUUID();
252
243
  this.#conversationStore = conversationStore || null;
253
- this.#memoryStore = memoryStore || null;
254
- this.#memoryShardStore = memoryShardStore || null;
255
244
  this.#memoryIndex = memoryIndex || null;
256
245
  this.#amsRegistry = amsRegistry || null;
257
246
  this.#toolRegistry = toolRegistry || null;
@@ -619,8 +608,6 @@ export class Engine {
619
608
  cwd: process.cwd(),
620
609
  mcpManager: this.#mcpManager,
621
610
  skillManager: this.#skillManager,
622
- memoryStore: this.#memoryStore,
623
- memoryShardStore: this.#memoryShardStore,
624
611
  conversationStore: this.#conversationStore,
625
612
  adapter: this.#adapter,
626
613
  config: this.#config,
@@ -644,8 +631,6 @@ export class Engine {
644
631
  adapter: this.#adapter,
645
632
  trace: this.#trace,
646
633
  config: this.#config,
647
- memoryStore: this.#memoryStore,
648
- memoryShardStore: this.#memoryShardStore,
649
634
  parentToolRegistry: this.#toolRegistry,
650
635
  skillManager: this.#skillManager,
651
636
  mcpManager: this.#mcpManager,
@@ -759,64 +744,21 @@ export class Engine {
759
744
  * @returns {Promise<{ archivedCount: number, extractedCount: number }|null>}
760
745
  */
761
746
  async #maybeConsolidate() {
762
- if (!this.#conversationStore || !this.#memoryStore) return null;
747
+ if (!this.#conversationStore) return null;
763
748
  if (this.#config._readOnly) return null;
764
749
 
765
750
  const budget = this.#config.messageTokenBudget || 8192;
766
751
  const compactCfg = (this.#config && this.#config.compact) || {};
767
-
768
- // Phase 8 PR-H: orchestrator is now the default. The legacy
769
- // shouldConsolidate / consolidate path remains reachable as an
770
- // explicit fallback via `config.compact.useLegacy=true` for parity
771
- // testing during migration. evaluateCompactTriggers (DESIGN §4.1)
772
- // and runCompact (DESIGN §4.2) own the live path.
773
- const useLegacy = compactCfg.useLegacy === true || compactCfg.useOrchestrator === false;
774
- if (!useLegacy) {
775
- return this.#runOrchestratorCompact(budget, compactCfg);
776
- }
777
-
778
- // Default path — surface trigger reasons via trace for observability
779
- // even when we still fall through to the legacy consolidate.
780
- try {
781
- const messages = this.#conversationStore.loadAll();
782
- const tokenCount = this.#conversationStore.hotTokens();
783
- const trig = evaluateCompactTriggers({
784
- messages,
785
- tokenCount,
786
- contextLimit: this.#config.maxContextTokens || 200000,
787
- tokenRatio: compactCfg.tokenRatio,
788
- maxMessages: compactCfg.maxMessages,
789
- });
790
- this.#trace.logEvent && this.#trace.logEvent({
791
- traceId: 'compact_triggers_eval',
792
- eventType: 'compact_triggers_eval',
793
- eventData: { trigger: trig.trigger, reasons: trig.reasons },
794
- });
795
- } catch { /* observability only */ }
796
-
797
- if (!shouldConsolidate(this.#conversationStore, budget)) return null;
798
-
799
- try {
800
- const result = await consolidate({
801
- conversationStore: this.#conversationStore,
802
- memoryStore: this.#memoryStore,
803
- adapter: this.#adapter,
804
- config: this.#fastConfig,
805
- budget,
806
- });
807
- return { archivedCount: result.archivedCount, extractedCount: result.extractedEntries.length };
808
- } catch {
809
- // Consolidation failure is non-critical
810
- return null;
811
- }
752
+ return this.#runOrchestratorCompact(budget, compactCfg);
812
753
  }
813
754
 
814
755
  /**
815
- * Phase 8 PR-D: run compact via the new orchestrator (DESIGN §4.2).
816
- * Hooks adapt the orchestrator's injectable contract to the existing
817
- * conversationStore / memoryStore primitives, so behaviour matches
818
- * the legacy `consolidate` path 1:1 while exercising the new
819
- * triggers / turn-group / orchestrator code on the live path.
756
+ * Run compact via the orchestrator (DESIGN §4.2).
757
+ *
758
+ * PR-B rip: the legacy entries-based extract hook is gone — Dream V2
759
+ * owns durable memory extraction now. The orchestrator runs Track 1
760
+ * (compaction + summary) and Track 2 (task summary refresh, when wired);
761
+ * Track 3 (extract) is intentionally omitted.
820
762
  *
821
763
  * @param {number} budget
822
764
  * @param {object} compactCfg
@@ -824,7 +766,6 @@ export class Engine {
824
766
  */
825
767
  async #runOrchestratorCompact(budget, _compactCfg) {
826
768
  const conversationStore = this.#conversationStore;
827
- const memoryStore = this.#memoryStore;
828
769
  const adapter = this.#adapter;
829
770
  const fastConfig = this.#fastConfig;
830
771
 
@@ -842,9 +783,9 @@ export class Engine {
842
783
  });
843
784
  if (!trig.trigger) return null;
844
785
 
845
- // Use partitionMessages (the legacy primitive) to decide what is
846
- // "cooling": orchestrator's own keepHot is a count, but we want to
847
- // honour the token-budget partitioning the rest of the system uses.
786
+ // Use partitionMessages to decide what is "cooling": orchestrator's
787
+ // own keepHot is a count, but we want to honour the token-budget
788
+ // partitioning the rest of the system uses.
848
789
  const { toArchive } = partitionMessages(messages, budget);
849
790
  if (toArchive.length === 0) return null;
850
791
 
@@ -852,10 +793,6 @@ export class Engine {
852
793
 
853
794
  const hooks = {
854
795
  summarise: async () => {
855
- // Reuse the legacy consolidate path's summary technique by
856
- // invoking adapter directly with a fresh prompt. We keep the
857
- // orchestrator's contract honoured: it takes the cooling slice
858
- // and returns a string.
859
796
  try {
860
797
  const result = await adapter.call({
861
798
  model: fastConfig.model,
@@ -871,11 +808,6 @@ export class Engine {
871
808
  archive: async (_groupIdx, groupMsgs) => {
872
809
  for (const m of groupMsgs) if (m.id) archiveIds.push(m.id);
873
810
  const turnId = groupMsgs[0]?.id || `g_${Date.now()}`;
874
- // Phase 8 PR-E: persist the cooling turn to
875
- // <yeaftDir>/memory/archive/<turnId>.md so message_trace can
876
- // replay it later. Scope is "user/" by default — group/task
877
- // scoping is a follow-up that will arrive with multi-VP archive
878
- // routing. Best-effort: archive failure must not abort compact.
879
811
  if (this.#yeaftDir) {
880
812
  try {
881
813
  await archiveTurn({
@@ -888,26 +820,12 @@ export class Engine {
888
820
  }
889
821
  return { turnId };
890
822
  },
891
- extract: async (coolingMessages) => {
892
- try {
893
- const extracted = await extractMemories({
894
- messages: coolingMessages, adapter, config: fastConfig,
895
- });
896
- for (const e of extracted) memoryStore.writeEntry(e);
897
- if (extracted.length > 0) memoryStore.rebuildScopes();
898
- return { written: extracted.length };
899
- } catch {
900
- return { written: 0 };
901
- }
902
- },
903
823
  };
904
824
 
905
825
  try {
906
826
  const out = await runCompactOrchestrator({
907
827
  messages, keepHot: 10, hooks,
908
828
  });
909
- // Apply side effects to the conversation store: move archived
910
- // ids to cold, persist compact summary, update index.
911
829
  if (archiveIds.length > 0) conversationStore.moveToColdBatch(archiveIds);
912
830
  if (out.compactSummary) conversationStore.updateCompactSummary(out.compactSummary);
913
831
  const lastKept = messages[messages.length - 1];
@@ -1012,28 +930,16 @@ export class Engine {
1012
930
  */
1013
931
  async *#runQuery({ prompt, messages, signal, userEffort = null, scenario = 'chat', vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId, vpPlan }) {
1014
932
 
1015
- // ─── Pre-query: Memory Injection (task-287) + Compact Summary ──
1016
- // Two-layer recall:
1017
- // 1. Static memory index injection (buildMemoryInjection always)
1018
- // 2. FTS5 pre-flow recall (#recallMemory → groups/pre-flow.js →
1019
- // memory/preflow.js when memoryIndex is wired)
1020
- // No per-turn fuzzy recall via old recall.js — LLM calls memory_load /
1021
- // memory_query on demand (memory_search still works as a deprecated alias).
933
+ // ─── Pre-query: FTS5 Memory Recall + Compact Summary ──
934
+ // Memory feed comes from two places:
935
+ // (a) FTS5 pre-flow recall (#recallMemory groups/pre-flow.js →
936
+ // memory/preflow.js) per-turn scoped recall
937
+ // (b) AMS snapshot (resident summaries + onDemand FTS hits) appended
938
+ // below
939
+ // The legacy entries-aggregate `buildMemoryInjection` (index.md / by-project /
940
+ // by-topic / timeline) was retired in the H2-AMS rip.
1022
941
  let memoryInjection = '';
1023
942
  let recallEntryCount = 0;
1024
- if (this.#yeaftDir) {
1025
- try {
1026
- const entryCount = this.#memoryStore?.stats?.().entryCount ?? 0;
1027
- memoryInjection = buildMemoryInjection({
1028
- yeaftDir: this.#yeaftDir,
1029
- cwd: process.cwd(),
1030
- entryCount,
1031
- language: this.#config.language || 'en',
1032
- });
1033
- } catch {
1034
- // Injection failure is non-critical — fall back to empty.
1035
- }
1036
- }
1037
943
 
1038
944
  // R6 recall: append shard-based recall results to memory injection
1039
945
  const recallResult = await this.#recallMemory(prompt, {
@@ -1326,7 +1232,7 @@ export class Engine {
1326
1232
  }
1327
1233
 
1328
1234
  // ─── LLMContextError → force compact → retry ──────
1329
- if (err instanceof LLMContextError && this.#conversationStore && this.#memoryStore) {
1235
+ if (err instanceof LLMContextError && this.#conversationStore) {
1330
1236
  const consolidated = await this.#maybeConsolidate();
1331
1237
  if (consolidated && consolidated.archivedCount > 0) {
1332
1238
  yield { type: 'consolidate', archivedCount: consolidated.archivedCount, extractedCount: consolidated.extractedCount };
@@ -1451,7 +1357,6 @@ export class Engine {
1451
1357
  const hookResult = await runStopHooks({
1452
1358
  yeaftDir: this.#yeaftDir,
1453
1359
  conversationStore: this.#conversationStore,
1454
- memoryStore: this.#memoryStore,
1455
1360
  adapter: this.#adapter,
1456
1361
  config: this.#fastConfig,
1457
1362
  primaryModel: this.#config.model,
@@ -1780,19 +1685,6 @@ export class Engine {
1780
1685
  return this.#conversationStore;
1781
1686
  }
1782
1687
 
1783
- /**
1784
- * Get the memory store (for external access, e.g., CLI commands).
1785
- * @returns {import('./memory/store.js').MemoryStore|null}
1786
- */
1787
- get memoryStore() {
1788
- return this.#memoryStore;
1789
- }
1790
-
1791
- /** @returns {object|null} — R6 memory shard store (task-334f) */
1792
- get memoryShardStore() {
1793
- return this.#memoryShardStore;
1794
- }
1795
-
1796
1688
  /** @returns {import('./tools/registry.js').ToolRegistry|null} */
1797
1689
  get toolRegistry() { return this.#toolRegistry; }
1798
1690
 
@@ -1,30 +1,18 @@
1
1
  /**
2
- * summary.js — task-334n: Feature multi-VP collaboration summary protocol.
2
+ * summary.js — Feature multi-VP collaboration summary protocol.
3
3
  *
4
4
  * Owns:
5
5
  * - postSummary() — write a `type=summary` message to the group jsonl
6
- * and run the extractor (B + C)
7
- * - extractFeatureMemory() — turn a summary body into 2-5 feature-memory entries
8
- * via 334f feature-memory shard lib (C)
9
6
  * - buildSummaryReminder() — compute the §Δ31.4 3-AND soft reminder shape
10
- * consumed by 334e's `featureCtx.summaryReminder` (D)
11
- * - buildFeatureCtxMemories() — assemble feature-memory top-5 (pinned + recent +
12
- * tag relevance) for feature_ctx (E)
7
+ * - buildFeatureCtxMemories() feature-memory top-5 (post-rip stub: returns [])
13
8
  *
14
9
  * Hard boundaries:
15
- * - does NOT touch 334o jsonl rotation internals (calls group.appendMessage)
16
- * - does NOT touch 334f shard-store impl (calls openMemoryShardStore API)
17
- * - does NOT touch 334e prompts main frame (returns plain shapes that feed
18
- * the existing renderFeatureCtx contract)
19
- * - does NOT self-loop-write VP-memory (extractor writes feature-memory only;
20
- * VP-level synthesis is deferred to 334g dream)
21
- * - softCap overflow does NOT create new shards (334f already routes into
22
- * dream queue via projectDeriveHint; we just surface `needsRecompression`)
10
+ * - does NOT touch jsonl rotation internals (calls group.appendMessage)
11
+ * - does NOT write feature-memory shards — the H2-AMS rip retired the shard
12
+ * store; feature memory now flows through Dream V2's scope merge instead.
23
13
  */
24
14
 
25
15
  import { join } from 'path';
26
- import { openMemoryShardStore } from '../memory/shard-store.js';
27
- import { AUTHORED_BY } from '../memory/schema.js';
28
16
 
29
17
  // ─── §Δ31.4 soft-reminder thresholds ─────────────────────────────
30
18
  /** Must be initiator AND members>1 AND (age≥20min OR turns≥10). */
@@ -119,36 +107,11 @@ export function postSummary(opts) {
119
107
  },
120
108
  });
121
109
 
122
- // 2) Run the extractor write feature-memory entries (C).
110
+ // 2) Feature-memory extraction is now owned by Dream V2 (per-group diff
111
+ // triage → merge by target scope → atomic segments). The legacy in-line
112
+ // shard-store extractor was retired in the H2-AMS rip; we leave
113
+ // `memoryIds` empty so callers don't depend on inline-extracted IDs.
123
114
  const memoryIds = [];
124
- try {
125
- const store = openMemoryShardStore(memoryDir, 'feature');
126
- const raw = extractor(body) || [];
127
- const bounded = clampExtracted(raw);
128
- for (const [i, item] of bounded.entries()) {
129
- const kind = EXTRACT_KINDS.includes(item.kind) ? item.kind : 'progress';
130
- const shard = KIND_TO_SHARD[kind] || 'progress';
131
- const id = `mem-${stored.id}-${i + 1}`;
132
- store.put({
133
- id,
134
- shard,
135
- kind,
136
- featureId,
137
- body: typeof item.body === 'string' ? item.body.trim() : '',
138
- tags: Array.isArray(item.tags) ? item.tags.slice(0, 5) : [],
139
- authoredBy: AUTHORED_BY.SUMMARY,
140
- sourceRef: { featureId, msgIds: [stored.id] },
141
- createdAt: new Date(now()).toISOString(),
142
- });
143
- memoryIds.push(id);
144
- }
145
- } catch (err) {
146
- // Extractor failures must not fail the summary post; the message is
147
- // already persisted (audit property). We return the empty memoryIds so
148
- // callers can surface a warning if they want.
149
- // eslint-disable-next-line no-console
150
- console.warn('[task-334n] summary-extractor failed:', err?.message || err);
151
- }
152
115
 
153
116
  return {
154
117
  message: stored,
@@ -241,62 +204,16 @@ export function buildSummaryReminder(input) {
241
204
 
242
205
  /**
243
206
  * Assemble feature-memory top-5 for 334e's `featureCtx.memories` field.
244
- * Ordering (§Δ16.5): pinned first recent tag-relevant. Supersedes are
245
- * hidden (entries with supersededBy != null are filtered out).
207
+ * Post-rip stub: the underlying shard store was retired in the H2-AMS rip;
208
+ * Dream V2 owns feature-scope memory now. Returning `[]` keeps the prompt
209
+ * shape valid until a follow-up wires the new scope-summary read path.
246
210
  *
247
- * @param {string} memoryDir groups/<g>/features/<f>/memory/
211
+ * @param {string} memoryDir unused (kept for callsite compatibility)
248
212
  * @param {{ tags?: string[], top?: number }} [opts]
249
213
  * @returns {Array<{body:string, shard:string, authoredBy?:string}>}
250
214
  */
251
- export function buildFeatureCtxMemories(memoryDir, opts = {}) {
252
- const top = Number.isFinite(opts.top) ? Number(opts.top) : 5;
253
- const tagHints = Array.isArray(opts.tags) ? opts.tags : [];
254
- const nowMs = typeof opts.now === 'number' ? opts.now : Date.now();
255
- let results = [];
256
- try {
257
- const store = openMemoryShardStore(memoryDir, 'feature');
258
- const q = store.query({});
259
- const hits = (q.results || [])
260
- .filter((r) => !r.supersededBy)
261
- .map((r) => {
262
- const full = store.get(r.id);
263
- return {
264
- id: r.id,
265
- shard: r.shard || 'general',
266
- body: full?.body || '',
267
- tags: Array.isArray(r.tags) ? r.tags : [],
268
- pinned: !!r.pinned,
269
- createdAt: full?.createdAt || null,
270
- authoredBy: full?.authoredBy || null,
271
- };
272
- })
273
- .filter((r) => r.body && r.body.trim());
274
-
275
- const score = (r) => {
276
- let s = 0;
277
- if (r.pinned) s += 1000;
278
- if (r.createdAt) {
279
- const ageMs = nowMs - new Date(r.createdAt).getTime();
280
- const halfLifeMs = 24 * 60 * 60 * 1000;
281
- s += Math.max(0, 100 * Math.pow(0.5, Math.max(0, ageMs) / halfLifeMs));
282
- }
283
- for (const t of tagHints) if (r.tags.includes(t)) s += 5;
284
- return s;
285
- };
286
- hits.sort((a, b) => {
287
- const ds = score(b) - score(a);
288
- if (ds !== 0) return ds;
289
- return String(b.createdAt || '').localeCompare(String(a.createdAt || ''));
290
- });
291
- results = hits.slice(0, top).map((r) => ({
292
- body: r.body,
293
- shard: r.shard,
294
- ...(r.authoredBy ? { authoredBy: r.authoredBy } : {}),
295
- }));
296
- } catch {
297
- results = [];
298
- }
299
- return results;
215
+ export function buildFeatureCtxMemories(_memoryDir, _opts = {}) {
216
+ return [];
300
217
  }
301
218
 
302
219
  // ─── (F) related-feature ACL fail-closed gate ─────────────────────
package/unify/index.js CHANGED
@@ -22,10 +22,8 @@ export { buildSystemPrompt, SUPPORTED_LANGUAGES } from './prompts.js';
22
22
  export { Engine } from './engine.js';
23
23
  export { ConversationStore, parseMessage, estimateTokens } from './conversation/persist.js';
24
24
  export { searchMessages } from './conversation/search.js';
25
- export { MemoryStore, parseEntry, serializeEntry, MEMORY_KINDS } from './memory/store.js';
26
25
 
27
26
  // Phase 5: Advanced features
28
- export { KINDS, KIND_PRIORITY, KIND_DESCRIPTIONS, IMPORTANCE_LEVELS, validateEntry, parseScopePath, getAncestorScopes, areScopesRelated } from './memory/types.js';
29
27
  export { runStopHooks } from './stop-hooks.js';
30
28
  export { MCPManager, createMCPManager } from './mcp.js';
31
29
  export { SkillManager, createSkillManager, parseSkill, serializeSkill } from './skills.js';