hippo-memory 1.15.0 → 1.16.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 (97) hide show
  1. package/README.md +862 -861
  2. package/dist/audit.d.ts +1 -1
  3. package/dist/audit.d.ts.map +1 -1
  4. package/dist/audit.js.map +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +1243 -3
  7. package/dist/cli.js.map +1 -1
  8. package/dist/customer-notes.d.ts +95 -0
  9. package/dist/customer-notes.d.ts.map +1 -0
  10. package/dist/customer-notes.js +296 -0
  11. package/dist/customer-notes.js.map +1 -0
  12. package/dist/db.d.ts.map +1 -1
  13. package/dist/db.js +731 -1
  14. package/dist/db.js.map +1 -1
  15. package/dist/graph-extract.d.ts +39 -0
  16. package/dist/graph-extract.d.ts.map +1 -0
  17. package/dist/graph-extract.js +141 -0
  18. package/dist/graph-extract.js.map +1 -0
  19. package/dist/graph-recall.d.ts +41 -0
  20. package/dist/graph-recall.d.ts.map +1 -0
  21. package/dist/graph-recall.js +246 -0
  22. package/dist/graph-recall.js.map +1 -0
  23. package/dist/graph.d.ts +137 -0
  24. package/dist/graph.d.ts.map +1 -0
  25. package/dist/graph.js +433 -0
  26. package/dist/graph.js.map +1 -0
  27. package/dist/incidents.d.ts +100 -0
  28. package/dist/incidents.d.ts.map +1 -0
  29. package/dist/incidents.js +322 -0
  30. package/dist/incidents.js.map +1 -0
  31. package/dist/index.d.ts +1 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +1 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/memory.d.ts +6 -0
  36. package/dist/memory.d.ts.map +1 -1
  37. package/dist/memory.js +6 -0
  38. package/dist/memory.js.map +1 -1
  39. package/dist/policies.d.ts +149 -0
  40. package/dist/policies.d.ts.map +1 -0
  41. package/dist/policies.js +380 -0
  42. package/dist/policies.js.map +1 -0
  43. package/dist/processes.d.ts +104 -0
  44. package/dist/processes.d.ts.map +1 -0
  45. package/dist/processes.js +330 -0
  46. package/dist/processes.js.map +1 -0
  47. package/dist/project-briefs.d.ts +126 -0
  48. package/dist/project-briefs.d.ts.map +1 -0
  49. package/dist/project-briefs.js +453 -0
  50. package/dist/project-briefs.js.map +1 -0
  51. package/dist/search.d.ts +7 -0
  52. package/dist/search.d.ts.map +1 -1
  53. package/dist/search.js.map +1 -1
  54. package/dist/server.d.ts.map +1 -1
  55. package/dist/server.js +1028 -16
  56. package/dist/server.js.map +1 -1
  57. package/dist/skills.d.ts +98 -0
  58. package/dist/skills.d.ts.map +1 -0
  59. package/dist/skills.js +339 -0
  60. package/dist/skills.js.map +1 -0
  61. package/dist/src/audit.js.map +1 -1
  62. package/dist/src/cli.js +1243 -3
  63. package/dist/src/cli.js.map +1 -1
  64. package/dist/src/customer-notes.js +296 -0
  65. package/dist/src/customer-notes.js.map +1 -0
  66. package/dist/src/db.js +731 -1
  67. package/dist/src/db.js.map +1 -1
  68. package/dist/src/graph-extract.js +141 -0
  69. package/dist/src/graph-extract.js.map +1 -0
  70. package/dist/src/graph-recall.js +246 -0
  71. package/dist/src/graph-recall.js.map +1 -0
  72. package/dist/src/graph.js +433 -0
  73. package/dist/src/graph.js.map +1 -0
  74. package/dist/src/incidents.js +322 -0
  75. package/dist/src/incidents.js.map +1 -0
  76. package/dist/src/index.js +1 -0
  77. package/dist/src/index.js.map +1 -1
  78. package/dist/src/memory.js +6 -0
  79. package/dist/src/memory.js.map +1 -1
  80. package/dist/src/policies.js +380 -0
  81. package/dist/src/policies.js.map +1 -0
  82. package/dist/src/processes.js +330 -0
  83. package/dist/src/processes.js.map +1 -0
  84. package/dist/src/project-briefs.js +453 -0
  85. package/dist/src/project-briefs.js.map +1 -0
  86. package/dist/src/search.js.map +1 -1
  87. package/dist/src/server.js +1028 -16
  88. package/dist/src/server.js.map +1 -1
  89. package/dist/src/skills.js +339 -0
  90. package/dist/src/skills.js.map +1 -0
  91. package/dist/src/version.js +1 -1
  92. package/dist/version.d.ts +1 -1
  93. package/dist/version.js +1 -1
  94. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  95. package/extensions/openclaw-plugin/package.json +1 -1
  96. package/openclaw.plugin.json +1 -1
  97. package/package.json +2 -2
@@ -0,0 +1,330 @@
1
+ /**
2
+ * E2 process first-class object (docs/plans/2026-05-29-e2-process-object.md).
3
+ *
4
+ * A `process` is a "living process map": a named, ordered list of steps that
5
+ * evolves over time. Unlike `incident` (open->resolved->closed, no supersede),
6
+ * `process` REUSES the `decision` supersede path as its delta mechanism: a
7
+ * process evolves by being superseded by a NEW VERSION that records what
8
+ * changed (`change_summary`) and the full new state (`steps`), carrying a
9
+ * server-derived `version` counter. The version chain (walk `superseded_by`)
10
+ * is the changelog. Computed structural step-diffing is a deferred v2 read-side
11
+ * feature; the row stores enough to reconstruct any delta
12
+ * (predecessor.steps + successor.steps + change_summary).
13
+ *
14
+ * The `processes` table is the source of truth: a process stays `active`
15
+ * regardless of memory decay. A memory row mirrors the process for recall but
16
+ * is NOT canonical — memory_id is NULLABLE with ON DELETE SET NULL so
17
+ * forget/consolidate/archive gracefully orphans the process row.
18
+ *
19
+ * Lifecycle: active -> superseded (a newer version replaces it; superseded_by
20
+ * points to the successor) or active -> closed (retired with no successor;
21
+ * only an active head closes).
22
+ *
23
+ * Tenant scoping: every helper requires tenantId. BEFORE INSERT/UPDATE triggers
24
+ * enforce processes.tenant_id == the referenced memory's tenant_id, and a
25
+ * superseded_by same-tenant trigger makes cross-tenant supersession
26
+ * unrepresentable. Mirrors the v30 decisions pattern (src/decisions.ts).
27
+ *
28
+ * Dual-write atomicity: `saveProcess` writes the memory + processes row (and,
29
+ * when superseding, the predecessor's UPDATE) inside writeEntry's SAVEPOINT
30
+ * 'write_entry' via the afterWrite hook, so a failure in any step rolls all of
31
+ * them back. Pattern matches saveDecision (decisions.ts).
32
+ */
33
+ import { openHippoDb, closeHippoDb } from './db.js';
34
+ import { writeEntry, assertTenantId } from './store.js';
35
+ import { createMemory, Layer, PROCESS_HALF_LIFE_DAYS } from './memory.js';
36
+ import { appendAuditEvent } from './audit.js';
37
+ export const VALID_PROCESS_STATES = new Set([
38
+ 'active',
39
+ 'superseded',
40
+ 'closed',
41
+ ]);
42
+ /** DoS / abuse caps on the steps body (untrusted at the HTTP/SDK boundary). */
43
+ export const MAX_PROCESS_STEPS = 200;
44
+ export const MAX_PROCESS_STEP_LEN = 2000;
45
+ // ---------------------------------------------------------------------------
46
+ // steps validation (untrusted input)
47
+ // ---------------------------------------------------------------------------
48
+ /**
49
+ * Validate + normalise the steps body. Returns the trimmed step strings
50
+ * (trim-then-store, so ' x ' is stored as 'x'). Throws on a non-array, a
51
+ * non-string / empty element, or a cap breach. Mirrors the incident DoS-cap
52
+ * discipline.
53
+ */
54
+ export function validateProcessSteps(steps) {
55
+ if (!Array.isArray(steps)) {
56
+ throw new Error('saveProcess: steps must be an array of strings');
57
+ }
58
+ if (steps.length > MAX_PROCESS_STEPS) {
59
+ throw new Error(`saveProcess: steps exceeds the ${MAX_PROCESS_STEPS}-step cap (got ${steps.length})`);
60
+ }
61
+ const out = [];
62
+ for (let i = 0; i < steps.length; i++) {
63
+ const raw = steps[i];
64
+ if (typeof raw !== 'string') {
65
+ throw new Error(`saveProcess: step ${i + 1} is not a string`);
66
+ }
67
+ const trimmed = raw.trim();
68
+ if (trimmed.length === 0) {
69
+ throw new Error(`saveProcess: step ${i + 1} is empty`);
70
+ }
71
+ if (trimmed.length > MAX_PROCESS_STEP_LEN) {
72
+ throw new Error(`saveProcess: step ${i + 1} exceeds the ${MAX_PROCESS_STEP_LEN}-char cap`);
73
+ }
74
+ out.push(trimmed);
75
+ }
76
+ return out;
77
+ }
78
+ /** Defensive parse: a malformed legacy steps value reads back as []. */
79
+ function parseSteps(raw) {
80
+ try {
81
+ const parsed = JSON.parse(raw);
82
+ if (Array.isArray(parsed) && parsed.every((s) => typeof s === 'string')) {
83
+ return parsed;
84
+ }
85
+ return [];
86
+ }
87
+ catch {
88
+ return [];
89
+ }
90
+ }
91
+ function rowToProcess(row) {
92
+ return {
93
+ id: row.id,
94
+ memoryId: row.memory_id,
95
+ tenantId: row.tenant_id,
96
+ processName: row.process_name,
97
+ description: row.description,
98
+ steps: parseSteps(row.steps),
99
+ version: row.version,
100
+ status: row.status,
101
+ supersededBy: row.superseded_by,
102
+ supersededAt: row.superseded_at,
103
+ changeSummary: row.change_summary,
104
+ closedAt: row.closed_at,
105
+ createdAt: row.created_at,
106
+ };
107
+ }
108
+ const PROCESS_COLS = `
109
+ id, memory_id, tenant_id, process_name, description, steps, version, status,
110
+ superseded_by, superseded_at, change_summary, closed_at, created_at
111
+ `;
112
+ /** The recall-surface content for the memory mirror: name + numbered steps +
113
+ * optional description, so `hippo recall` shows the process body. */
114
+ function buildProcessContent(processName, steps, description) {
115
+ const numbered = steps.map((s, i) => `${i + 1}. ${s}`).join('\n');
116
+ let content = processName;
117
+ if (numbered)
118
+ content += `\n\n${numbered}`;
119
+ if (description)
120
+ content += `\n\nDescription: ${description}`;
121
+ return content;
122
+ }
123
+ // ---------------------------------------------------------------------------
124
+ // Public API
125
+ // ---------------------------------------------------------------------------
126
+ /**
127
+ * Create a process (or a new version that supersedes an existing one). Writes
128
+ * the memory mirror + the processes row atomically inside writeEntry's SAVEPOINT
129
+ * 'write_entry'. When supersedesProcessId is given, the referenced ACTIVE row is
130
+ * preflighted (status + version) BEFORE the INSERT, then UPDATEd -> superseded in
131
+ * the SAME SAVEPOINT (CAS: WHERE status='active' AND id != <new id>; throws on
132
+ * changes===0 so a duplicate supersede aborts the whole write). The new row's
133
+ * version = predecessor.version + 1 (server-derived); change_summary carries the
134
+ * delta note. A fresh create has version 1 and change_summary NULL.
135
+ */
136
+ export function saveProcess(hippoRoot, tenantId, opts, actor = 'cli') {
137
+ assertTenantId('saveProcess', tenantId);
138
+ if (!opts.processName || opts.processName.trim().length === 0) {
139
+ throw new Error('saveProcess: processName is required');
140
+ }
141
+ const steps = validateProcessSteps(opts.steps);
142
+ const isSupersede = opts.supersedesProcessId !== undefined;
143
+ // change_summary is only meaningful on a supersession; NULL on a fresh create.
144
+ const changeSummary = isSupersede ? (opts.changeSummary ?? null) : null;
145
+ const now = new Date().toISOString();
146
+ const content = buildProcessContent(opts.processName, steps, opts.description);
147
+ const tags = ['process', ...(opts.extraTags ?? [])];
148
+ const mem = createMemory(content, {
149
+ tags,
150
+ layer: Layer.Semantic,
151
+ confidence: 'verified',
152
+ source: 'process',
153
+ tenantId,
154
+ });
155
+ mem.half_life_days = PROCESS_HALF_LIFE_DAYS;
156
+ let savedRow;
157
+ writeEntry(hippoRoot, mem, {
158
+ actor,
159
+ afterWrite: (db, memoryId) => {
160
+ // Preflight the supersede target BEFORE inserting the new row. The new
161
+ // row's autoincrement id could otherwise collide with a non-existent
162
+ // supersedesProcessId (e.g. superseding id 1 on an empty store), making
163
+ // the row supersede itself. Validating first means the new row is never a
164
+ // candidate for its own supersede UPDATE. Mirrors saveDecision (codex P1
165
+ // 2026-05-28). The same SELECT reads the predecessor version so the
166
+ // successor's version is server-derived, never client-supplied.
167
+ let version = 1;
168
+ if (opts.supersedesProcessId !== undefined) {
169
+ const pred = db.prepare(`SELECT status, version FROM processes WHERE id = ? AND tenant_id = ?`).get(opts.supersedesProcessId, tenantId);
170
+ if (!pred) {
171
+ throw new Error(`saveProcess: process ${opts.supersedesProcessId} to supersede not found for tenant ${tenantId}`);
172
+ }
173
+ if (pred.status !== 'active') {
174
+ throw new Error(`saveProcess: process ${opts.supersedesProcessId} is not active (status='${pred.status}'); only active processes can be superseded.`);
175
+ }
176
+ version = pred.version + 1;
177
+ }
178
+ const result = db.prepare(`
179
+ INSERT INTO processes(
180
+ memory_id, tenant_id, process_name, description, steps, version,
181
+ status, superseded_by, superseded_at, change_summary, closed_at, created_at
182
+ ) VALUES (?, ?, ?, ?, ?, ?, 'active', NULL, NULL, ?, NULL, ?)
183
+ `).run(memoryId, tenantId, opts.processName, opts.description ?? null, JSON.stringify(steps), version, changeSummary, now);
184
+ const processId = Number(result.lastInsertRowid ?? 0);
185
+ if (opts.supersedesProcessId !== undefined) {
186
+ const sup = db.prepare(`
187
+ UPDATE processes
188
+ SET status = 'superseded', superseded_by = ?, superseded_at = ?
189
+ WHERE id = ? AND tenant_id = ? AND status = 'active' AND id != ?
190
+ `).run(processId, now, opts.supersedesProcessId, tenantId, processId);
191
+ if (sup.changes === 0) {
192
+ throw new Error(`saveProcess: process ${opts.supersedesProcessId} could not be superseded (no longer active or self-reference).`);
193
+ }
194
+ appendAuditEvent(db, {
195
+ tenantId,
196
+ actor,
197
+ op: 'process_supersede',
198
+ targetId: String(opts.supersedesProcessId),
199
+ metadata: {
200
+ process_id: opts.supersedesProcessId,
201
+ superseded_by: processId,
202
+ new_version: version,
203
+ },
204
+ });
205
+ }
206
+ const row = db.prepare(`SELECT ${PROCESS_COLS} FROM processes WHERE id = ?`)
207
+ .get(processId);
208
+ if (!row)
209
+ throw new Error('saveProcess: failed to reload saved process row');
210
+ savedRow = row;
211
+ // GDPR-light metadata: ids + counts only, no process_name / step text.
212
+ appendAuditEvent(db, {
213
+ tenantId,
214
+ actor,
215
+ op: 'process_create',
216
+ targetId: String(processId),
217
+ metadata: {
218
+ process_id: processId,
219
+ version,
220
+ step_count: steps.length,
221
+ has_description: opts.description !== undefined && opts.description !== null && opts.description !== '',
222
+ },
223
+ });
224
+ },
225
+ });
226
+ if (!savedRow) {
227
+ throw new Error('saveProcess: afterWrite did not populate the row');
228
+ }
229
+ return rowToProcess(savedRow);
230
+ }
231
+ /**
232
+ * Close (retire) an active process with no successor. Updates the processes row
233
+ * only; the memory mirror is not mutated. CAS guard: WHERE status='active'; 0
234
+ * changes distinguishes not-found from not-active. A superseded row is already
235
+ * terminal in the chain and cannot be closed.
236
+ */
237
+ export function closeProcess(hippoRoot, tenantId, id, actor = 'cli') {
238
+ assertTenantId('closeProcess', tenantId);
239
+ const now = new Date().toISOString();
240
+ const db = openHippoDb(hippoRoot);
241
+ try {
242
+ db.exec('BEGIN IMMEDIATE');
243
+ try {
244
+ const updateResult = db.prepare(`
245
+ UPDATE processes
246
+ SET status = 'closed', closed_at = ?
247
+ WHERE id = ? AND tenant_id = ? AND status = 'active'
248
+ `).run(now, id, tenantId);
249
+ if (updateResult.changes === 0) {
250
+ const existing = db.prepare(`SELECT status FROM processes WHERE id = ? AND tenant_id = ?`).get(id, tenantId);
251
+ if (!existing) {
252
+ throw new Error(`closeProcess: process ${id} not found for tenant ${tenantId}`);
253
+ }
254
+ throw new Error(`closeProcess: process ${id} is not active (status='${existing.status}'); only active processes can be closed.`);
255
+ }
256
+ const row = db.prepare(`SELECT ${PROCESS_COLS} FROM processes WHERE id = ? AND tenant_id = ?`)
257
+ .get(id, tenantId);
258
+ if (!row)
259
+ throw new Error(`closeProcess: process ${id} not found after UPDATE`);
260
+ appendAuditEvent(db, {
261
+ tenantId,
262
+ actor,
263
+ op: 'process_close',
264
+ targetId: String(id),
265
+ metadata: { process_id: id },
266
+ });
267
+ db.exec('COMMIT');
268
+ return rowToProcess(row);
269
+ }
270
+ catch (e) {
271
+ try {
272
+ db.exec('ROLLBACK');
273
+ }
274
+ catch {
275
+ // Ignore rollback failures — the throw below is what matters.
276
+ }
277
+ throw e;
278
+ }
279
+ }
280
+ finally {
281
+ closeHippoDb(db);
282
+ }
283
+ }
284
+ export function loadProcessById(hippoRoot, tenantId, id) {
285
+ assertTenantId('loadProcessById', tenantId);
286
+ const db = openHippoDb(hippoRoot);
287
+ try {
288
+ const row = db.prepare(`SELECT ${PROCESS_COLS} FROM processes WHERE id = ? AND tenant_id = ?`)
289
+ .get(id, tenantId);
290
+ return row ? rowToProcess(row) : null;
291
+ }
292
+ finally {
293
+ closeHippoDb(db);
294
+ }
295
+ }
296
+ export function loadProcesses(hippoRoot, tenantId, opts = {}) {
297
+ assertTenantId('loadProcesses', tenantId);
298
+ const limit = opts.limit ?? 100;
299
+ const db = openHippoDb(hippoRoot);
300
+ try {
301
+ let rows;
302
+ if (opts.status) {
303
+ if (!VALID_PROCESS_STATES.has(opts.status)) {
304
+ throw new Error(`loadProcesses: status must be one of ${Array.from(VALID_PROCESS_STATES).join('|')}; got ${opts.status}`);
305
+ }
306
+ rows = db.prepare(`
307
+ SELECT ${PROCESS_COLS} FROM processes
308
+ WHERE tenant_id = ? AND status = ?
309
+ ORDER BY created_at DESC, id DESC
310
+ LIMIT ?
311
+ `).all(tenantId, opts.status, limit);
312
+ }
313
+ else {
314
+ rows = db.prepare(`
315
+ SELECT ${PROCESS_COLS} FROM processes
316
+ WHERE tenant_id = ?
317
+ ORDER BY created_at DESC, id DESC
318
+ LIMIT ?
319
+ `).all(tenantId, limit);
320
+ }
321
+ return rows.map(rowToProcess);
322
+ }
323
+ finally {
324
+ closeHippoDb(db);
325
+ }
326
+ }
327
+ export function loadActiveProcesses(hippoRoot, tenantId, opts = {}) {
328
+ return loadProcesses(hippoRoot, tenantId, { status: 'active', limit: opts.limit });
329
+ }
330
+ //# sourceMappingURL=processes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processes.js","sourceRoot":"","sources":["../src/processes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * E2 project_brief first-class object
3
+ * (docs/plans/2026-05-30-e2-project-brief-object.md).
4
+ *
5
+ * A `project_brief` is the living, repo-scoped summary of a repository's state: a
6
+ * `summary` body scoped to a `repo`, evolving via the supersede delta lifecycle.
7
+ * "Auto-refreshes from receipts" is scoped to a DETERMINISTIC (no-LLM) assembler:
8
+ * `refreshBrief` gathers the repo's recent receipts (memory rows tagged
9
+ * `path:<repo>`) and assembles them into the brief body. The distinguishing
10
+ * capability is therefore the refresh assembler (analog of skill's export
11
+ * renderer), not an LLM/async pipeline (deferred).
12
+ *
13
+ * Reuses the skill/process supersede machinery verbatim (superseded_by self-FK +
14
+ * CAS + INSERT-preflight + server-derived version + change_summary + supersede
15
+ * tenant-match trigger). It DROPS skill's `skill_name`/`trigger_text` and ADDS
16
+ * `repo` (the repo-scoping dimension) + `summary` (the brief body).
17
+ *
18
+ * The `project_briefs` table is the source of truth (survives memory decay); the
19
+ * memory mirror is for recall. memory_id is NULLABLE with ON DELETE SET NULL.
20
+ *
21
+ * Lifecycle: active -> superseded (a newer version replaces it) or active ->
22
+ * closed (retired).
23
+ */
24
+ export type BriefStatus = 'active' | 'superseded' | 'closed';
25
+ export declare const VALID_BRIEF_STATES: ReadonlySet<BriefStatus>;
26
+ /** Field caps (untrusted at the HTTP/SDK boundary). summary is a body, so a larger
27
+ * cap than the 4096 short-field convention. */
28
+ export declare const MAX_REPO_LEN = 256;
29
+ export declare const MAX_BRIEF_SUMMARY_LEN = 8192;
30
+ export declare const MAX_CHANGE_SUMMARY_LEN = 4096;
31
+ /** Bound the receipts gathered per refresh (a refresh reads memories; cap the scan
32
+ * + the rendered body). Realistic repos have far fewer recent receipts than this. */
33
+ export declare const MAX_BRIEF_RECEIPTS = 50;
34
+ /** Truncate each receipt's headline in the assembled digest. */
35
+ export declare const MAX_RECEIPT_HEADLINE_LEN = 200;
36
+ export interface ProjectBrief {
37
+ id: number;
38
+ /** Nullable: ON DELETE SET NULL lets memory deletion proceed without breaking
39
+ * the brief row. */
40
+ memoryId: string | null;
41
+ tenantId: string;
42
+ /** The repo identifier this brief is scoped to (e.g. `hippo`). */
43
+ repo: string;
44
+ /** The brief body. */
45
+ summary: string;
46
+ /** Server-derived: 1 on a fresh create, predecessor.version + 1 on supersede. */
47
+ version: number;
48
+ status: BriefStatus;
49
+ supersededBy: number | null;
50
+ supersededAt: string | null;
51
+ /** The per-version delta note; set on a successor row only (NULL on a v1). */
52
+ changeSummary: string | null;
53
+ closedAt: string | null;
54
+ createdAt: string;
55
+ }
56
+ export interface SaveProjectBriefOpts {
57
+ repo: string;
58
+ summary: string;
59
+ /** The delta note for a supersession; ignored (stored NULL) on a fresh create. */
60
+ changeSummary?: string;
61
+ /** Table id of an ACTIVE brief this new version supersedes. */
62
+ supersedesBriefId?: number;
63
+ /** Extra memory tags merged after ['project_brief']. */
64
+ extraTags?: string[];
65
+ /** Internal: set by refreshBrief to the receipt count so the audit metadata can
66
+ * mark the write as an auto-refresh (vs a manual supersede) WITHOUT a 4th audit
67
+ * op. Not part of the public CLI/HTTP surface. */
68
+ refreshReceiptCount?: number;
69
+ }
70
+ export interface ListProjectBriefsOpts {
71
+ status?: BriefStatus;
72
+ /** Filter to a single repo. */
73
+ repo?: string;
74
+ limit?: number;
75
+ }
76
+ /**
77
+ * Create a project_brief (or a new version that supersedes an existing one). Writes
78
+ * the memory mirror + the project_briefs row atomically inside writeEntry's
79
+ * SAVEPOINT. When supersedesBriefId is given, the referenced ACTIVE row is
80
+ * preflighted (status + version) BEFORE the INSERT, then CAS-UPDATEd -> superseded
81
+ * in the same SAVEPOINT; the new version = predecessor.version + 1 (server-derived).
82
+ */
83
+ export declare function saveProjectBrief(hippoRoot: string, tenantId: string, opts: SaveProjectBriefOpts, actor?: string): ProjectBrief;
84
+ /**
85
+ * Close (retire) an active brief. CAS guard WHERE status='active'; 0 changes
86
+ * distinguishes not-found from not-active. A superseded row is terminal.
87
+ */
88
+ export declare function closeProjectBrief(hippoRoot: string, tenantId: string, id: number, actor?: string): ProjectBrief;
89
+ export declare function loadProjectBriefById(hippoRoot: string, tenantId: string, id: number): ProjectBrief | null;
90
+ export declare function loadProjectBriefs(hippoRoot: string, tenantId: string, opts?: ListProjectBriefsOpts): ProjectBrief[];
91
+ /**
92
+ * The repo's CURRENT active brief, or null. By convention there is one active brief
93
+ * per (tenant, repo); if an operator created more than one (the DB does not prevent
94
+ * it, consistent with every other E2 object), the MOST-RECENT active row wins.
95
+ */
96
+ export declare function loadActiveBriefForRepo(hippoRoot: string, tenantId: string, repo: string): ProjectBrief | null;
97
+ /**
98
+ * Assemble the repo's recent receipts into a deterministic markdown digest, and
99
+ * return it WITH the receipt count (the count feeds refreshBrief's change_summary +
100
+ * audit metadata). NO LLM. Always returns a non-empty, valid summary (a brief
101
+ * `summary` is NOT NULL), including the zero-receipts case.
102
+ *
103
+ * A "receipt" = a tenant memory row carrying the repo's `path:<repo>` tag. The
104
+ * brief's OWN memory mirror (source='project_brief') is excluded so a brief never
105
+ * becomes its own receipt on the next refresh. The match is against the JSON-array
106
+ * serialization (each element is a double-quoted string `"path:hippo"`); the
107
+ * surrounding quotes are load-bearing — they stop `hip` matching `path:hippo`.
108
+ * `repo` is LIKE-escaped + parameterized (operator-supplied; security.md).
109
+ */
110
+ export declare function assembleBriefFromReceipts(hippoRoot: string, tenantId: string, repo: string): {
111
+ markdown: string;
112
+ receiptCount: number;
113
+ };
114
+ /**
115
+ * Auto-refresh the repo's brief from its receipts: assemble the digest, then create
116
+ * a new version. If the repo already has an active brief it is superseded (the
117
+ * change_summary records the auto-refresh + the audit metadata carries
118
+ * `refreshed: true`); otherwise a v1 is created. Returns the new brief.
119
+ *
120
+ * The assemble (a read of `memories`) happens BEFORE writeEntry opens its SAVEPOINT;
121
+ * a concurrent receipt write landing between the read and the brief write simply
122
+ * appears in the NEXT refresh — the brief is a derived snapshot, not a transactional
123
+ * aggregate, so no consistency invariant is violated.
124
+ */
125
+ export declare function refreshBrief(hippoRoot: string, tenantId: string, repo: string, actor?: string): ProjectBrief;
126
+ //# sourceMappingURL=project-briefs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-briefs.d.ts","sourceRoot":"","sources":["../src/project-briefs.ts"],"names":[],"mappings":"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"}