@0xmaxma/claude-gateway 1.6.8 → 1.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.
Files changed (223) hide show
  1. package/README.md +149 -20
  2. package/config.template.json +59 -1
  3. package/dist/agent/dreaming/accept.d.ts +43 -0
  4. package/dist/agent/dreaming/accept.d.ts.map +1 -0
  5. package/dist/agent/dreaming/accept.js +230 -0
  6. package/dist/agent/dreaming/accept.js.map +1 -0
  7. package/dist/agent/dreaming/applier.d.ts +77 -0
  8. package/dist/agent/dreaming/applier.d.ts.map +1 -0
  9. package/dist/agent/dreaming/applier.js +406 -0
  10. package/dist/agent/dreaming/applier.js.map +1 -0
  11. package/dist/agent/dreaming/audit.d.ts +27 -0
  12. package/dist/agent/dreaming/audit.d.ts.map +1 -0
  13. package/dist/agent/dreaming/audit.js +100 -0
  14. package/dist/agent/dreaming/audit.js.map +1 -0
  15. package/dist/agent/dreaming/compactor.d.ts +66 -0
  16. package/dist/agent/dreaming/compactor.d.ts.map +1 -0
  17. package/dist/agent/dreaming/compactor.js +306 -0
  18. package/dist/agent/dreaming/compactor.js.map +1 -0
  19. package/dist/agent/dreaming/config.d.ts +19 -0
  20. package/dist/agent/dreaming/config.d.ts.map +1 -0
  21. package/dist/agent/dreaming/config.js +107 -0
  22. package/dist/agent/dreaming/config.js.map +1 -0
  23. package/dist/agent/dreaming/episodic.d.ts +42 -0
  24. package/dist/agent/dreaming/episodic.d.ts.map +1 -0
  25. package/dist/agent/dreaming/episodic.js +116 -0
  26. package/dist/agent/dreaming/episodic.js.map +1 -0
  27. package/dist/agent/dreaming/gather.d.ts +31 -0
  28. package/dist/agent/dreaming/gather.d.ts.map +1 -0
  29. package/dist/agent/dreaming/gather.js +55 -0
  30. package/dist/agent/dreaming/gather.js.map +1 -0
  31. package/dist/agent/dreaming/index.d.ts +87 -0
  32. package/dist/agent/dreaming/index.d.ts.map +1 -0
  33. package/dist/agent/dreaming/index.js +377 -0
  34. package/dist/agent/dreaming/index.js.map +1 -0
  35. package/dist/agent/dreaming/migrate-cli.d.ts +17 -0
  36. package/dist/agent/dreaming/migrate-cli.d.ts.map +1 -0
  37. package/dist/agent/dreaming/migrate-cli.js +42 -0
  38. package/dist/agent/dreaming/migrate-cli.js.map +1 -0
  39. package/dist/agent/dreaming/migrate.d.ts +72 -0
  40. package/dist/agent/dreaming/migrate.d.ts.map +1 -0
  41. package/dist/agent/dreaming/migrate.js +374 -0
  42. package/dist/agent/dreaming/migrate.js.map +1 -0
  43. package/dist/agent/dreaming/report.d.ts +39 -0
  44. package/dist/agent/dreaming/report.d.ts.map +1 -0
  45. package/dist/agent/dreaming/report.js +121 -0
  46. package/dist/agent/dreaming/report.js.map +1 -0
  47. package/dist/agent/dreaming/reviewer.d.ts +43 -0
  48. package/dist/agent/dreaming/reviewer.d.ts.map +1 -0
  49. package/dist/agent/dreaming/reviewer.js +249 -0
  50. package/dist/agent/dreaming/reviewer.js.map +1 -0
  51. package/dist/agent/dreaming/staleness.d.ts +68 -0
  52. package/dist/agent/dreaming/staleness.d.ts.map +1 -0
  53. package/dist/agent/dreaming/staleness.js +281 -0
  54. package/dist/agent/dreaming/staleness.js.map +1 -0
  55. package/dist/agent/dreaming/types.d.ts +130 -0
  56. package/dist/agent/dreaming/types.d.ts.map +1 -0
  57. package/dist/agent/dreaming/types.js +10 -0
  58. package/dist/agent/dreaming/types.js.map +1 -0
  59. package/dist/agent/knowledge/archive-db.d.ts +114 -0
  60. package/dist/agent/knowledge/archive-db.d.ts.map +1 -0
  61. package/dist/agent/knowledge/archive-db.js +474 -0
  62. package/dist/agent/knowledge/archive-db.js.map +1 -0
  63. package/dist/agent/knowledge/chunk.d.ts +21 -0
  64. package/dist/agent/knowledge/chunk.d.ts.map +1 -0
  65. package/dist/agent/knowledge/chunk.js +67 -0
  66. package/dist/agent/knowledge/chunk.js.map +1 -0
  67. package/dist/agent/knowledge/config.d.ts +20 -0
  68. package/dist/agent/knowledge/config.d.ts.map +1 -0
  69. package/dist/agent/knowledge/config.js +143 -0
  70. package/dist/agent/knowledge/config.js.map +1 -0
  71. package/dist/agent/knowledge/graph-demo.d.ts +25 -0
  72. package/dist/agent/knowledge/graph-demo.d.ts.map +1 -0
  73. package/dist/agent/knowledge/graph-demo.js +132 -0
  74. package/dist/agent/knowledge/graph-demo.js.map +1 -0
  75. package/dist/agent/knowledge/index.d.ts +24 -0
  76. package/dist/agent/knowledge/index.d.ts.map +1 -0
  77. package/dist/agent/knowledge/index.js +50 -0
  78. package/dist/agent/knowledge/index.js.map +1 -0
  79. package/dist/agent/knowledge/indexer.d.ts +34 -0
  80. package/dist/agent/knowledge/indexer.d.ts.map +1 -0
  81. package/dist/agent/knowledge/indexer.js +271 -0
  82. package/dist/agent/knowledge/indexer.js.map +1 -0
  83. package/dist/agent/knowledge/lifecycle.d.ts +91 -0
  84. package/dist/agent/knowledge/lifecycle.d.ts.map +1 -0
  85. package/dist/agent/knowledge/lifecycle.js +205 -0
  86. package/dist/agent/knowledge/lifecycle.js.map +1 -0
  87. package/dist/agent/knowledge/provenance.d.ts +15 -0
  88. package/dist/agent/knowledge/provenance.d.ts.map +1 -0
  89. package/dist/agent/knowledge/provenance.js +37 -0
  90. package/dist/agent/knowledge/provenance.js.map +1 -0
  91. package/dist/agent/knowledge/reindex-cli.d.ts +13 -0
  92. package/dist/agent/knowledge/reindex-cli.d.ts.map +1 -0
  93. package/dist/agent/knowledge/reindex-cli.js +53 -0
  94. package/dist/agent/knowledge/reindex-cli.js.map +1 -0
  95. package/dist/agent/knowledge/reindex-spawn.d.ts +30 -0
  96. package/dist/agent/knowledge/reindex-spawn.d.ts.map +1 -0
  97. package/dist/agent/knowledge/reindex-spawn.js +97 -0
  98. package/dist/agent/knowledge/reindex-spawn.js.map +1 -0
  99. package/dist/agent/knowledge/shared-promote.d.ts +18 -0
  100. package/dist/agent/knowledge/shared-promote.d.ts.map +1 -0
  101. package/dist/agent/knowledge/shared-promote.js +29 -0
  102. package/dist/agent/knowledge/shared-promote.js.map +1 -0
  103. package/dist/agent/knowledge/shared-writer.d.ts +24 -0
  104. package/dist/agent/knowledge/shared-writer.d.ts.map +1 -0
  105. package/dist/agent/knowledge/shared-writer.js +97 -0
  106. package/dist/agent/knowledge/shared-writer.js.map +1 -0
  107. package/dist/agent/knowledge/types.d.ts +83 -0
  108. package/dist/agent/knowledge/types.d.ts.map +1 -0
  109. package/dist/agent/knowledge/types.js +12 -0
  110. package/dist/agent/knowledge/types.js.map +1 -0
  111. package/dist/agent/knowledge/wiki.d.ts +107 -0
  112. package/dist/agent/knowledge/wiki.d.ts.map +1 -0
  113. package/dist/agent/knowledge/wiki.js +415 -0
  114. package/dist/agent/knowledge/wiki.js.map +1 -0
  115. package/dist/agent/memory-metrics.d.ts +48 -0
  116. package/dist/agent/memory-metrics.d.ts.map +1 -0
  117. package/dist/agent/memory-metrics.js +156 -0
  118. package/dist/agent/memory-metrics.js.map +1 -0
  119. package/dist/agent/runner.d.ts +24 -1
  120. package/dist/agent/runner.d.ts.map +1 -1
  121. package/dist/agent/runner.js +82 -6
  122. package/dist/agent/runner.js.map +1 -1
  123. package/dist/agent/skill-learning/config.d.ts +18 -0
  124. package/dist/agent/skill-learning/config.d.ts.map +1 -0
  125. package/dist/agent/skill-learning/config.js +71 -0
  126. package/dist/agent/skill-learning/config.js.map +1 -0
  127. package/dist/agent/skill-learning/curator.d.ts +45 -0
  128. package/dist/agent/skill-learning/curator.d.ts.map +1 -0
  129. package/dist/agent/skill-learning/curator.js +171 -0
  130. package/dist/agent/skill-learning/curator.js.map +1 -0
  131. package/dist/agent/skill-learning/index.d.ts +79 -0
  132. package/dist/agent/skill-learning/index.d.ts.map +1 -0
  133. package/dist/agent/skill-learning/index.js +308 -0
  134. package/dist/agent/skill-learning/index.js.map +1 -0
  135. package/dist/agent/skill-learning/metrics.d.ts +13 -0
  136. package/dist/agent/skill-learning/metrics.d.ts.map +1 -0
  137. package/dist/agent/skill-learning/metrics.js +109 -0
  138. package/dist/agent/skill-learning/metrics.js.map +1 -0
  139. package/dist/agent/skill-learning/notifier.d.ts +111 -0
  140. package/dist/agent/skill-learning/notifier.d.ts.map +1 -0
  141. package/dist/agent/skill-learning/notifier.js +398 -0
  142. package/dist/agent/skill-learning/notifier.js.map +1 -0
  143. package/dist/agent/skill-learning/reviewer.d.ts +61 -0
  144. package/dist/agent/skill-learning/reviewer.d.ts.map +1 -0
  145. package/dist/agent/skill-learning/reviewer.js +271 -0
  146. package/dist/agent/skill-learning/reviewer.js.map +1 -0
  147. package/dist/agent/skill-learning/telemetry.d.ts +22 -0
  148. package/dist/agent/skill-learning/telemetry.d.ts.map +1 -0
  149. package/dist/agent/skill-learning/telemetry.js +90 -0
  150. package/dist/agent/skill-learning/telemetry.js.map +1 -0
  151. package/dist/agent/skill-learning/trigger.d.ts +23 -0
  152. package/dist/agent/skill-learning/trigger.d.ts.map +1 -0
  153. package/dist/agent/skill-learning/trigger.js +44 -0
  154. package/dist/agent/skill-learning/trigger.js.map +1 -0
  155. package/dist/agent/skill-learning/types.d.ts +165 -0
  156. package/dist/agent/skill-learning/types.d.ts.map +1 -0
  157. package/dist/agent/skill-learning/types.js +11 -0
  158. package/dist/agent/skill-learning/types.js.map +1 -0
  159. package/dist/agent/skill-learning/writer.d.ts +37 -0
  160. package/dist/agent/skill-learning/writer.d.ts.map +1 -0
  161. package/dist/agent/skill-learning/writer.js +223 -0
  162. package/dist/agent/skill-learning/writer.js.map +1 -0
  163. package/dist/agent/workspace-loader.d.ts +83 -6
  164. package/dist/agent/workspace-loader.d.ts.map +1 -1
  165. package/dist/agent/workspace-loader.js +207 -14
  166. package/dist/agent/workspace-loader.js.map +1 -1
  167. package/dist/api/gateway-router.d.ts +2 -0
  168. package/dist/api/gateway-router.d.ts.map +1 -1
  169. package/dist/api/gateway-router.js +293 -6
  170. package/dist/api/gateway-router.js.map +1 -1
  171. package/dist/api/share-router.d.ts.map +1 -1
  172. package/dist/api/share-router.js +27 -1
  173. package/dist/api/share-router.js.map +1 -1
  174. package/dist/api/skills-router.d.ts +2 -2
  175. package/dist/api/skills-router.d.ts.map +1 -1
  176. package/dist/api/skills-router.js +61 -1
  177. package/dist/api/skills-router.js.map +1 -1
  178. package/dist/apps/agent-manager.d.ts +7 -0
  179. package/dist/apps/agent-manager.d.ts.map +1 -1
  180. package/dist/apps/agent-manager.js +13 -1
  181. package/dist/apps/agent-manager.js.map +1 -1
  182. package/dist/config/migrator.d.ts +2 -0
  183. package/dist/config/migrator.d.ts.map +1 -1
  184. package/dist/config/migrator.js +72 -1
  185. package/dist/config/migrator.js.map +1 -1
  186. package/dist/history/cleanup.d.ts +7 -0
  187. package/dist/history/cleanup.d.ts.map +1 -1
  188. package/dist/history/cleanup.js +27 -0
  189. package/dist/history/cleanup.js.map +1 -1
  190. package/dist/history/db.d.ts +65 -0
  191. package/dist/history/db.d.ts.map +1 -1
  192. package/dist/history/db.js +261 -0
  193. package/dist/history/db.js.map +1 -1
  194. package/dist/index.js +122 -20
  195. package/dist/index.js.map +1 -1
  196. package/dist/session/process.d.ts +10 -0
  197. package/dist/session/process.d.ts.map +1 -1
  198. package/dist/session/process.js +86 -1
  199. package/dist/session/process.js.map +1 -1
  200. package/dist/share/share-store.d.ts +11 -0
  201. package/dist/share/share-store.d.ts.map +1 -1
  202. package/dist/share/share-store.js +3 -1
  203. package/dist/share/share-store.js.map +1 -1
  204. package/dist/skills/loader.d.ts +8 -0
  205. package/dist/skills/loader.d.ts.map +1 -1
  206. package/dist/skills/loader.js +29 -1
  207. package/dist/skills/loader.js.map +1 -1
  208. package/dist/types.d.ts +116 -0
  209. package/dist/types.d.ts.map +1 -1
  210. package/dist/ui/web-ui.d.ts.map +1 -1
  211. package/dist/ui/web-ui.js +1126 -3
  212. package/dist/ui/web-ui.js.map +1 -1
  213. package/mcp/package.json +2 -1
  214. package/mcp/server.ts +2 -0
  215. package/mcp/tools/image/module.ts +114 -9
  216. package/mcp/tools/memory/archive-reader.test.ts +212 -0
  217. package/mcp/tools/memory/archive-reader.ts +253 -0
  218. package/mcp/tools/memory/module.ts +152 -0
  219. package/mcp/tools/memory/retrieval-recorder.ts +66 -0
  220. package/mcp/tools/shared/share-client.ts +20 -1
  221. package/mcp/tools/skills/module.ts +28 -0
  222. package/package.json +1 -1
  223. package/resource/claude_gateway.svg +1038 -112
@@ -0,0 +1,271 @@
1
+ "use strict";
2
+ /**
3
+ * Archive indexer (planning-64 K0).
4
+ *
5
+ * Walks an agent's memory files, chunks each, tags provenance, and writes them
6
+ * into the per-agent `kb.sqlite`. Hash-guarded: an unchanged file is skipped;
7
+ * a changed file is re-chunked and its stale chunks replaced; a file that
8
+ * disappeared is pruned. Deterministic (timestamps come from file mtime, not the
9
+ * wall clock) so a reindex of unchanged files is a true no-op.
10
+ *
11
+ * Synchronous by construction (node:sqlite + fs). Callers MUST invoke this OFF
12
+ * the gateway event loop (nightly dreaming spawn / out-of-process). K0 does not
13
+ * wire it into any gateway runtime path — it is dormant until K1.
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.archiveDbPath = archiveDbPath;
50
+ exports.indexAgentArchive = indexAgentArchive;
51
+ exports.indexSharedArchive = indexSharedArchive;
52
+ const path = __importStar(require("path"));
53
+ const fs = __importStar(require("fs"));
54
+ const crypto = __importStar(require("crypto"));
55
+ const archive_db_1 = require("./archive-db");
56
+ const chunk_1 = require("./chunk");
57
+ const provenance_1 = require("./provenance");
58
+ const lifecycle_1 = require("./lifecycle");
59
+ const config_1 = require("./config");
60
+ const wiki_1 = require("./wiki");
61
+ /** Evergreen core files (indexed even though they live at the workspace root). */
62
+ const EVERGREEN_FILES = ['MEMORY.md', 'USER.md'];
63
+ /** Default location of an agent's archive DB (sibling to history.db). */
64
+ function archiveDbPath(workspaceDir) {
65
+ // workspaceDir = agents/<id>/workspace ; the DB lives at agents/<id>/kb.sqlite
66
+ return path.join(path.dirname(workspaceDir), 'kb.sqlite');
67
+ }
68
+ /** Recursively collect `*.md` files under a directory, as absolute paths. */
69
+ function walkMarkdown(dir) {
70
+ const out = [];
71
+ let entries;
72
+ try {
73
+ entries = fs.readdirSync(dir, { withFileTypes: true });
74
+ }
75
+ catch {
76
+ return out;
77
+ }
78
+ // Sort for deterministic index order across runs/platforms.
79
+ entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
80
+ for (const e of entries) {
81
+ // Skip dotfiles — in particular a `.tmp-*` file left by a crashed shared-note
82
+ // write must never be indexed as a real note.
83
+ if (e.name.startsWith('.'))
84
+ continue;
85
+ const full = path.join(dir, e.name);
86
+ if (e.isDirectory())
87
+ out.push(...walkMarkdown(full));
88
+ else if (e.isFile() && e.name.toLowerCase().endsWith('.md'))
89
+ out.push(full);
90
+ }
91
+ return out;
92
+ }
93
+ /** The set of memory files to index for an agent (absolute paths). */
94
+ function collectSourceFiles(workspaceDir) {
95
+ const files = [];
96
+ for (const name of EVERGREEN_FILES) {
97
+ const p = path.join(workspaceDir, name);
98
+ if (fs.existsSync(p) && fs.statSync(p).isFile())
99
+ files.push(p);
100
+ }
101
+ files.push(...walkMarkdown(path.join(workspaceDir, 'memory')));
102
+ return files;
103
+ }
104
+ function sha256(content) {
105
+ return crypto.createHash('sha256').update(content).digest('hex');
106
+ }
107
+ /** Workspace-relative POSIX path (for storage + provenance classification). */
108
+ function relPosix(workspaceDir, absFile) {
109
+ return path.relative(workspaceDir, absFile).split(path.sep).join('/');
110
+ }
111
+ /** The entry_hash of the block a chunk starts in, or null if it starts outside any. */
112
+ function blockHashForLine(blocks, line) {
113
+ for (const b of blocks) {
114
+ if (line >= b.startLine && line <= b.endLine)
115
+ return b.entryHash;
116
+ }
117
+ return null;
118
+ }
119
+ /**
120
+ * Index one agent's archive. Returns per-run counts. A no-op (returns zeroed
121
+ * counts) when the archive is disabled.
122
+ *
123
+ * @param workspaceDir the agent's workspace dir (agents/<id>/workspace)
124
+ * @param agentCfg per-agent `gateway.knowledge.archive` override
125
+ * @param globalCfg global `gateway.knowledge.archive`
126
+ */
127
+ function indexAgentArchive(workspaceDir, agentCfg, globalCfg) {
128
+ const cfg = (0, config_1.resolveArchiveConfig)(agentCfg, globalCfg);
129
+ const empty = {
130
+ filesSeen: 0,
131
+ filesIndexed: 0,
132
+ filesSkipped: 0,
133
+ filesRemoved: 0,
134
+ chunksWritten: 0,
135
+ };
136
+ if (!cfg.enabled)
137
+ return empty;
138
+ const db = archive_db_1.ArchiveDB.forPath(archiveDbPath(workspaceDir), cfg.tokenizer);
139
+ return reindexInto(db, {
140
+ baseDir: workspaceDir,
141
+ files: collectSourceFiles(workspaceDir),
142
+ chunkTokens: cfg.chunkTokens,
143
+ chunkOverlap: cfg.chunkOverlap,
144
+ originFn: provenance_1.classifyOrigin,
145
+ source: 'memory',
146
+ projectKey: null,
147
+ });
148
+ }
149
+ /**
150
+ * Shared indexing core (used by both the per-agent and shared archives):
151
+ * hash-guarded chunk+provenance write of each file, then prune only files that
152
+ * genuinely disappeared. Deterministic (mtime-based) so unchanged input is a
153
+ * true no-op.
154
+ */
155
+ function reindexInto(db, opts) {
156
+ const result = {
157
+ filesSeen: 0,
158
+ filesIndexed: 0,
159
+ filesSkipped: 0,
160
+ filesRemoved: 0,
161
+ chunksWritten: 0,
162
+ };
163
+ const seenRel = new Set();
164
+ for (const abs of opts.files) {
165
+ let content;
166
+ let stat;
167
+ try {
168
+ stat = fs.statSync(abs);
169
+ content = fs.readFileSync(abs, 'utf8');
170
+ }
171
+ catch {
172
+ continue; // race: file vanished mid-walk — treat as not present
173
+ }
174
+ const rel = relPosix(opts.baseDir, abs);
175
+ seenRel.add(rel);
176
+ result.filesSeen++;
177
+ const hash = sha256(content);
178
+ const existing = db.getSource(rel);
179
+ if (existing && existing.hash === hash) {
180
+ result.filesSkipped++; // hash-guarded: unchanged, no re-chunk
181
+ continue;
182
+ }
183
+ const mtime = Math.floor(stat.mtimeMs);
184
+ const origin = opts.originFn(rel);
185
+ const chunks = (0, chunk_1.chunkMarkdown)(content, opts.chunkTokens, opts.chunkOverlap);
186
+ // Entry-lifecycle identity (planning-66): only archive-tier files get an
187
+ // entry_hash (evergreen Lane-1, pinned files and the shared vault are exempt,
188
+ // so the GC can never consider them). Each FTS chunk inherits the entry_hash of
189
+ // the markdown block it starts in; blocks are the clean, movable unit the GC
190
+ // operates on (chunks are overlapping token windows and must never be moved).
191
+ const blocks = opts.source === 'memory' && (0, lifecycle_1.isArchiveTierPath)(rel) ? (0, lifecycle_1.parseEntryBlocks)(content) : [];
192
+ const rows = chunks.map((c) => ({
193
+ chunk: {
194
+ id: `${rel}#${c.startLine}-${c.endLine}`,
195
+ path: rel,
196
+ startLine: c.startLine,
197
+ endLine: c.endLine,
198
+ text: c.text,
199
+ updatedAt: mtime,
200
+ },
201
+ recall: { importance: null, triggers: null, projectKey: opts.projectKey },
202
+ provenance: {
203
+ originClass: origin,
204
+ sessionKind: 'unknown', // file-indexed content carries no session context
205
+ observedAt: mtime,
206
+ supersedesKey: null,
207
+ },
208
+ entryHash: blocks.length ? blockHashForLine(blocks, c.startLine) : null,
209
+ }));
210
+ db.replaceSource({ path: rel, hash, mtime, size: stat.size, source: opts.source }, rows, blocks.map((b) => ({ entryHash: b.entryHash, firstSeen: mtime })));
211
+ result.filesIndexed++;
212
+ result.chunksWritten += rows.length;
213
+ }
214
+ // Prune sources whose file genuinely disappeared. A file that still exists but
215
+ // whose stat/read threw a TRANSIENT error this run (EMFILE/EACCES/EINTR) is not
216
+ // in `seenRel` either — but it must NOT be pruned, or a live note silently loses
217
+ // its index between runs. Confirm real absence on disk before deleting.
218
+ for (const rel of db.listSourcePaths()) {
219
+ if (seenRel.has(rel))
220
+ continue;
221
+ if (fs.existsSync(path.join(opts.baseDir, rel)))
222
+ continue; // present but unreadable this run — keep
223
+ db.deleteSource(rel);
224
+ result.filesRemoved++;
225
+ }
226
+ return result;
227
+ }
228
+ /**
229
+ * Index the SHARED, cross-agent vault (planning-64 K3): every `*.md` under the
230
+ * project's `notes/` dir is chunked into the shared `kb.sqlite`. Shared notes are
231
+ * authored by the owner's own agents (same trust domain) → provenance `agent`.
232
+ * No-op when shared KB is disabled. Runs OFF the gateway event loop, same as the
233
+ * per-agent indexer.
234
+ */
235
+ function indexSharedArchive(agentCfg, globalCfg) {
236
+ const empty = {
237
+ filesSeen: 0,
238
+ filesIndexed: 0,
239
+ filesSkipped: 0,
240
+ filesRemoved: 0,
241
+ chunksWritten: 0,
242
+ };
243
+ const cfg = (0, config_1.resolveSharedConfig)(agentCfg, globalCfg);
244
+ if (!cfg.enabled)
245
+ return empty;
246
+ const notesDir = (0, config_1.sharedNotesDir)(cfg);
247
+ const db = archive_db_1.ArchiveDB.forPath((0, config_1.sharedDbPath)(cfg), config_1.ARCHIVE_DEFAULTS.tokenizer);
248
+ const result = reindexInto(db, {
249
+ baseDir: notesDir,
250
+ files: walkMarkdown(notesDir),
251
+ chunkTokens: config_1.ARCHIVE_DEFAULTS.chunkTokens,
252
+ chunkOverlap: config_1.ARCHIVE_DEFAULTS.chunkOverlap,
253
+ originFn: () => 'agent',
254
+ source: 'shared',
255
+ projectKey: cfg.project,
256
+ });
257
+ // K5 (opt-in): compile the memory-wiki graph + dashboards over the whole vault.
258
+ // Best-effort — a compile failure never affects indexing. mtime-free determinism
259
+ // is not required here (reports are regenerated each run), so wall-clock `now` is
260
+ // used for the staleness dashboard.
261
+ if (cfg.graph) {
262
+ try {
263
+ (0, wiki_1.compileWiki)((0, config_1.sharedVaultDir)(cfg), Date.now());
264
+ }
265
+ catch {
266
+ /* best-effort */
267
+ }
268
+ }
269
+ return result;
270
+ }
271
+ //# sourceMappingURL=indexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../../src/agent/knowledge/indexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Archive entry lifecycle helpers (planning-66).
3
+ *
4
+ * The Lane-2 archive (`memory/*.md` → `kb.sqlite` → `memory_search`) accumulates
5
+ * stale / superseded entries with no stable per-entry identity to decide staleness
6
+ * from: the FTS chunk id is line-based (`${rel}#${start}-${end}`) and dies on every
7
+ * re-chunk, and `updated_at`/`observed_at` are file mtime (re-stamped on any edit).
8
+ *
9
+ * This module gives every archive ENTRY a reindex-surviving identity — a content
10
+ * hash of its normalized text (`entryHash`) — plus the two pure primitives the GC
11
+ * needs: a markdown-block parser (an "entry" = a top-level bullet or an h3–h6 entry
12
+ * header + its body, the same archivable unit the compactor moves) and deterministic
13
+ * supersession detection (a replacement verb + `#N` marks the older `#N` entry
14
+ * superseded). Everything here is pure — no I/O, no clock — so it is exhaustively
15
+ * testable and safe to call from the indexer and the nightly GC alike.
16
+ *
17
+ * Identity is block-level (not chunk-level) on purpose: FTS chunks are token-window
18
+ * slices with overlap (`chunk.ts`), so moving a chunk's raw lines would corrupt an
19
+ * overlapping neighbour. Blocks are clean markdown units, so the GC moves whole
20
+ * blocks. Each FTS chunk simply inherits the `entryHash` of the block it starts in,
21
+ * which is what the read-path recall counter is keyed to.
22
+ */
23
+ /** Pinned archive files are searchable but structurally exempt from GC. */
24
+ export declare const PINNED_PREFIX = "memory/pinned/";
25
+ /**
26
+ * True when a workspace-relative path is a GC-eligible archive-tier entry source
27
+ * (planning-66). The archive tier is `memory/**.md`, EXCEPT:
28
+ * - evergreen Lane-1 (`MEMORY.md`/`USER.md` at the root) — never touched,
29
+ * - pinned files (`memory/pinned/**`) — searchable but never aged out.
30
+ * Only these files get an `entry_hash` + lifecycle row; everything else (evergreen,
31
+ * pinned, the shared vault) has no lifecycle, so the GC can never consider it.
32
+ */
33
+ export declare function isArchiveTierPath(rel: string): boolean;
34
+ /** A parsed archive entry block with its 1-indexed inclusive line range. */
35
+ export interface EntryBlock {
36
+ text: string;
37
+ startLine: number;
38
+ endLine: number;
39
+ entryHash: string;
40
+ }
41
+ /**
42
+ * Normalize entry text for hashing: collapse every run of whitespace (including
43
+ * newlines) to a single space and trim. A block re-chunked, re-indented, or
44
+ * reflowed keeps the SAME hash — so its lifecycle (age, recall, invalidation)
45
+ * survives cosmetic edits. A genuine content change yields a new hash, which is
46
+ * correct: it is a new fact, so it starts a fresh age.
47
+ */
48
+ export declare function normalizeEntryText(s: string): string;
49
+ /** Stable content identity for an archive entry: sha256 of its normalized text. */
50
+ export declare function entryHash(s: string): string;
51
+ /**
52
+ * Parse an archive markdown file into its entry blocks. An entry is either:
53
+ * - a top-level bullet (`- `/`* ` at column 0) plus its contiguous non-blank,
54
+ * non-header, non-bullet continuation lines, or
55
+ * - an h3–h6 entry header plus its body up to the next header or blank line.
56
+ * h1/h2 section titles, blank lines and free prose are NOT entries (they are
57
+ * structure, never moved). Mirrors the compactor's block model so the GC and the
58
+ * compactor agree on what a movable unit is. Line ranges are 1-indexed inclusive.
59
+ */
60
+ export declare function parseEntryBlocks(content: string): EntryBlock[];
61
+ /**
62
+ * A replacement marker: an explicit supersession verb immediately followed by an
63
+ * issue/PR reference `#N`. Case-INSENSITIVE on the verb but the `#N` is required,
64
+ * so prose like "Closes #12", "merged into develop", or a bare "#12" never
65
+ * matches — only "supersedes #316" / "replaces #12" / "obsoletes #7". Mirrors the
66
+ * compactor's precision-over-recall stance: a false supersession only soft-
67
+ * invalidates (still searchable), never deletes, but we keep it tight anyway.
68
+ */
69
+ export declare const SUPERSEDE_RE: RegExp;
70
+ /** All distinct `#N` numbers a block references (its candidate identities/targets). */
71
+ export declare function referencedIds(text: string): Set<number>;
72
+ /** The `#N` numbers a block declares it supersedes (verb + `#N`). */
73
+ export declare function supersededIds(text: string): Set<number>;
74
+ /** One resolved supersession: `targetHash` is superseded by `bySpec`. */
75
+ export interface Supersession {
76
+ targetHash: string;
77
+ bySpec: string;
78
+ }
79
+ /**
80
+ * Deterministically resolve which entries are superseded, over a set of blocks
81
+ * (the whole archive tier). For every block B that declares "supersedes #N", any
82
+ * OTHER block A that references `#N` is marked superseded-by-B. Precision guards:
83
+ * - the trigger requires the verb+`#N` form (referencing `#N` alone is not a
84
+ * trigger — only a target),
85
+ * - a block never supersedes itself,
86
+ * - a block that itself supersedes something is not eligible to be a target of
87
+ * the same `#N` (the newer, superseding entry stays live).
88
+ * Returns one entry per superseded target hash (last writer wins on conflict).
89
+ */
90
+ export declare function detectSupersessions(blocks: EntryBlock[]): Supersession[];
91
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/agent/knowledge/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,2EAA2E;AAC3E,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKtD;AAED,4EAA4E;AAC5E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3C;AAQD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAqC9D;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,QAA8D,CAAC;AAExF,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAIvD;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAIvD;AAED,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,YAAY,EAAE,CAkBxE"}
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ /**
3
+ * Archive entry lifecycle helpers (planning-66).
4
+ *
5
+ * The Lane-2 archive (`memory/*.md` → `kb.sqlite` → `memory_search`) accumulates
6
+ * stale / superseded entries with no stable per-entry identity to decide staleness
7
+ * from: the FTS chunk id is line-based (`${rel}#${start}-${end}`) and dies on every
8
+ * re-chunk, and `updated_at`/`observed_at` are file mtime (re-stamped on any edit).
9
+ *
10
+ * This module gives every archive ENTRY a reindex-surviving identity — a content
11
+ * hash of its normalized text (`entryHash`) — plus the two pure primitives the GC
12
+ * needs: a markdown-block parser (an "entry" = a top-level bullet or an h3–h6 entry
13
+ * header + its body, the same archivable unit the compactor moves) and deterministic
14
+ * supersession detection (a replacement verb + `#N` marks the older `#N` entry
15
+ * superseded). Everything here is pure — no I/O, no clock — so it is exhaustively
16
+ * testable and safe to call from the indexer and the nightly GC alike.
17
+ *
18
+ * Identity is block-level (not chunk-level) on purpose: FTS chunks are token-window
19
+ * slices with overlap (`chunk.ts`), so moving a chunk's raw lines would corrupt an
20
+ * overlapping neighbour. Blocks are clean markdown units, so the GC moves whole
21
+ * blocks. Each FTS chunk simply inherits the `entryHash` of the block it starts in,
22
+ * which is what the read-path recall counter is keyed to.
23
+ */
24
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ var desc = Object.getOwnPropertyDescriptor(m, k);
27
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
28
+ desc = { enumerable: true, get: function() { return m[k]; } };
29
+ }
30
+ Object.defineProperty(o, k2, desc);
31
+ }) : (function(o, m, k, k2) {
32
+ if (k2 === undefined) k2 = k;
33
+ o[k2] = m[k];
34
+ }));
35
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
36
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
37
+ }) : function(o, v) {
38
+ o["default"] = v;
39
+ });
40
+ var __importStar = (this && this.__importStar) || (function () {
41
+ var ownKeys = function(o) {
42
+ ownKeys = Object.getOwnPropertyNames || function (o) {
43
+ var ar = [];
44
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
45
+ return ar;
46
+ };
47
+ return ownKeys(o);
48
+ };
49
+ return function (mod) {
50
+ if (mod && mod.__esModule) return mod;
51
+ var result = {};
52
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
53
+ __setModuleDefault(result, mod);
54
+ return result;
55
+ };
56
+ })();
57
+ Object.defineProperty(exports, "__esModule", { value: true });
58
+ exports.SUPERSEDE_RE = exports.PINNED_PREFIX = void 0;
59
+ exports.isArchiveTierPath = isArchiveTierPath;
60
+ exports.normalizeEntryText = normalizeEntryText;
61
+ exports.entryHash = entryHash;
62
+ exports.parseEntryBlocks = parseEntryBlocks;
63
+ exports.referencedIds = referencedIds;
64
+ exports.supersededIds = supersededIds;
65
+ exports.detectSupersessions = detectSupersessions;
66
+ const crypto = __importStar(require("crypto"));
67
+ /** Pinned archive files are searchable but structurally exempt from GC. */
68
+ exports.PINNED_PREFIX = 'memory/pinned/';
69
+ /**
70
+ * True when a workspace-relative path is a GC-eligible archive-tier entry source
71
+ * (planning-66). The archive tier is `memory/**.md`, EXCEPT:
72
+ * - evergreen Lane-1 (`MEMORY.md`/`USER.md` at the root) — never touched,
73
+ * - pinned files (`memory/pinned/**`) — searchable but never aged out.
74
+ * Only these files get an `entry_hash` + lifecycle row; everything else (evergreen,
75
+ * pinned, the shared vault) has no lifecycle, so the GC can never consider it.
76
+ */
77
+ function isArchiveTierPath(rel) {
78
+ const p = rel.replace(/\\/g, '/');
79
+ if (p === 'MEMORY.md' || p === 'USER.md')
80
+ return false;
81
+ if (p.startsWith(exports.PINNED_PREFIX))
82
+ return false;
83
+ return p.startsWith('memory/') && p.endsWith('.md');
84
+ }
85
+ /**
86
+ * Normalize entry text for hashing: collapse every run of whitespace (including
87
+ * newlines) to a single space and trim. A block re-chunked, re-indented, or
88
+ * reflowed keeps the SAME hash — so its lifecycle (age, recall, invalidation)
89
+ * survives cosmetic edits. A genuine content change yields a new hash, which is
90
+ * correct: it is a new fact, so it starts a fresh age.
91
+ */
92
+ function normalizeEntryText(s) {
93
+ return s.replace(/\s+/g, ' ').trim();
94
+ }
95
+ /** Stable content identity for an archive entry: sha256 of its normalized text. */
96
+ function entryHash(s) {
97
+ return crypto.createHash('sha256').update(normalizeEntryText(s)).digest('hex');
98
+ }
99
+ const TOP_BULLET_RE = /^[-*] /;
100
+ const HEADER_RE = /^#{1,6} /;
101
+ /** h3–h6 can be a completed-entry header; h1/h2 are structural sections. */
102
+ const ENTRY_HEADER_RE = /^#{3,6} /;
103
+ const BLANK_RE = /^\s*$/;
104
+ /**
105
+ * Parse an archive markdown file into its entry blocks. An entry is either:
106
+ * - a top-level bullet (`- `/`* ` at column 0) plus its contiguous non-blank,
107
+ * non-header, non-bullet continuation lines, or
108
+ * - an h3–h6 entry header plus its body up to the next header or blank line.
109
+ * h1/h2 section titles, blank lines and free prose are NOT entries (they are
110
+ * structure, never moved). Mirrors the compactor's block model so the GC and the
111
+ * compactor agree on what a movable unit is. Line ranges are 1-indexed inclusive.
112
+ */
113
+ function parseEntryBlocks(content) {
114
+ const lines = content.split('\n');
115
+ const blocks = [];
116
+ for (let i = 0; i < lines.length; i++) {
117
+ const line = lines[i];
118
+ if (ENTRY_HEADER_RE.test(line)) {
119
+ const blockLines = [line];
120
+ let j = i + 1;
121
+ while (j < lines.length && !BLANK_RE.test(lines[j]) && !HEADER_RE.test(lines[j])) {
122
+ blockLines.push(lines[j]);
123
+ j++;
124
+ }
125
+ const text = blockLines.join('\n');
126
+ blocks.push({ text, startLine: i + 1, endLine: j, entryHash: entryHash(text) });
127
+ i = j - 1;
128
+ continue;
129
+ }
130
+ if (TOP_BULLET_RE.test(line)) {
131
+ const blockLines = [line];
132
+ let j = i + 1;
133
+ while (j < lines.length &&
134
+ !BLANK_RE.test(lines[j]) &&
135
+ !HEADER_RE.test(lines[j]) &&
136
+ !TOP_BULLET_RE.test(lines[j])) {
137
+ blockLines.push(lines[j]);
138
+ j++;
139
+ }
140
+ const text = blockLines.join('\n');
141
+ blocks.push({ text, startLine: i + 1, endLine: j, entryHash: entryHash(text) });
142
+ i = j - 1;
143
+ continue;
144
+ }
145
+ // h1/h2 section titles, blanks, prose → not an entry.
146
+ }
147
+ return blocks;
148
+ }
149
+ /**
150
+ * A replacement marker: an explicit supersession verb immediately followed by an
151
+ * issue/PR reference `#N`. Case-INSENSITIVE on the verb but the `#N` is required,
152
+ * so prose like "Closes #12", "merged into develop", or a bare "#12" never
153
+ * matches — only "supersedes #316" / "replaces #12" / "obsoletes #7". Mirrors the
154
+ * compactor's precision-over-recall stance: a false supersession only soft-
155
+ * invalidates (still searchable), never deletes, but we keep it tight anyway.
156
+ */
157
+ exports.SUPERSEDE_RE = /\b(?:supersed(?:e|es|ed)|replaces?|obsoletes?)\s+#(\d+)/gi;
158
+ /** All distinct `#N` numbers a block references (its candidate identities/targets). */
159
+ function referencedIds(text) {
160
+ const ids = new Set();
161
+ for (const m of text.matchAll(/#(\d+)\b/g))
162
+ ids.add(Number(m[1]));
163
+ return ids;
164
+ }
165
+ /** The `#N` numbers a block declares it supersedes (verb + `#N`). */
166
+ function supersededIds(text) {
167
+ const ids = new Set();
168
+ for (const m of text.matchAll(exports.SUPERSEDE_RE))
169
+ ids.add(Number(m[1]));
170
+ return ids;
171
+ }
172
+ /**
173
+ * Deterministically resolve which entries are superseded, over a set of blocks
174
+ * (the whole archive tier). For every block B that declares "supersedes #N", any
175
+ * OTHER block A that references `#N` is marked superseded-by-B. Precision guards:
176
+ * - the trigger requires the verb+`#N` form (referencing `#N` alone is not a
177
+ * trigger — only a target),
178
+ * - a block never supersedes itself,
179
+ * - a block that itself supersedes something is not eligible to be a target of
180
+ * the same `#N` (the newer, superseding entry stays live).
181
+ * Returns one entry per superseded target hash (last writer wins on conflict).
182
+ */
183
+ function detectSupersessions(blocks) {
184
+ const out = new Map();
185
+ for (const b of blocks) {
186
+ const supersedes = supersededIds(b.text);
187
+ if (supersedes.size === 0)
188
+ continue;
189
+ for (const a of blocks) {
190
+ if (a.entryHash === b.entryHash)
191
+ continue; // never supersede self
192
+ if (supersededIds(a.text).size > 0)
193
+ continue; // the newer superseding entry stays live
194
+ const aIds = referencedIds(a.text);
195
+ for (const n of supersedes) {
196
+ if (aIds.has(n)) {
197
+ out.set(a.entryHash, b.entryHash);
198
+ break;
199
+ }
200
+ }
201
+ }
202
+ }
203
+ return Array.from(out, ([targetHash, bySpec]) => ({ targetHash, bySpec }));
204
+ }
205
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/agent/knowledge/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Classify the trust/origin of an indexed file by its workspace-relative path.
3
+ *
4
+ * Mirrors openclaw memory-core `resolveMemoryPathClassification`, adapted to our
5
+ * layout. FAIL-CLOSED: anything not explicitly recognized as agent-authored or
6
+ * system-generated is `untrusted` — so later phases (promotion, shared KB) can
7
+ * never auto-promote content whose provenance we could not vouch for.
8
+ *
9
+ * - `DREAMS.md`, `memory/dreaming/*`, `.dreaming/*` → system (machine-generated)
10
+ * - `MEMORY.md`, `USER.md`, `memory/*.md` → agent (self-authored)
11
+ * - everything else (imports, unknown) → untrusted
12
+ */
13
+ import type { OriginClass } from './types';
14
+ export declare function classifyOrigin(relPath: string): OriginClass;
15
+ //# sourceMappingURL=provenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../../src/agent/knowledge/provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAO3C,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAmB3D"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /**
3
+ * Classify the trust/origin of an indexed file by its workspace-relative path.
4
+ *
5
+ * Mirrors openclaw memory-core `resolveMemoryPathClassification`, adapted to our
6
+ * layout. FAIL-CLOSED: anything not explicitly recognized as agent-authored or
7
+ * system-generated is `untrusted` — so later phases (promotion, shared KB) can
8
+ * never auto-promote content whose provenance we could not vouch for.
9
+ *
10
+ * - `DREAMS.md`, `memory/dreaming/*`, `.dreaming/*` → system (machine-generated)
11
+ * - `MEMORY.md`, `USER.md`, `memory/*.md` → agent (self-authored)
12
+ * - everything else (imports, unknown) → untrusted
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.classifyOrigin = classifyOrigin;
16
+ /** Normalize a path to forward-slash, no leading "./". */
17
+ function toPosix(relPath) {
18
+ return relPath.replace(/\\/g, '/').replace(/^\.\//, '');
19
+ }
20
+ function classifyOrigin(relPath) {
21
+ const p = toPosix(relPath).toLowerCase();
22
+ // System: dreaming outputs and the dream diary are machine-generated.
23
+ if (p === 'dreams.md' ||
24
+ p.startsWith('memory/dreaming/') ||
25
+ p.startsWith('.dreaming/') ||
26
+ p.startsWith('memory/.dreams/')) {
27
+ return 'system';
28
+ }
29
+ // Agent: the self-authored memory core + atomic notes under memory/.
30
+ if (p === 'memory.md' || p === 'user.md')
31
+ return 'agent';
32
+ if (p.startsWith('memory/') && p.endsWith('.md'))
33
+ return 'agent';
34
+ // Fail-closed for anything else.
35
+ return 'untrusted';
36
+ }
37
+ //# sourceMappingURL=provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../../src/agent/knowledge/provenance.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;AASH,wCAmBC;AAxBD,0DAA0D;AAC1D,SAAS,OAAO,CAAC,OAAe;IAC9B,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,SAAgB,cAAc,CAAC,OAAe;IAC5C,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IAEzC,sEAAsE;IACtE,IACE,CAAC,KAAK,WAAW;QACjB,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC;QAChC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC;QAC1B,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAC/B,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,qEAAqE;IACrE,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IACzD,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAEjE,iCAAiC;IACjC,OAAO,WAAW,CAAC;AACrB,CAAC"}