@sentry/junior-memory 0.79.0 → 0.80.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/store.d.ts CHANGED
@@ -8,6 +8,11 @@ declare const createMemoryInputSchema: z.ZodObject<{
8
8
  content: z.ZodString;
9
9
  expiresAtMs: z.ZodOptional<z.ZodNumber>;
10
10
  idempotencyKey: z.ZodString;
11
+ kind: z.ZodEnum<{
12
+ preference: "preference";
13
+ procedure: "procedure";
14
+ knowledge: "knowledge";
15
+ }>;
11
16
  }, z.core.$strict>;
12
17
  declare const listMemoriesInputSchema: z.ZodObject<{
13
18
  limit: z.ZodOptional<z.ZodNumber>;
@@ -20,6 +25,9 @@ declare const archiveMemoryInputSchema: z.ZodObject<{
20
25
  id: z.ZodString;
21
26
  reason: z.ZodOptional<z.ZodString>;
22
27
  }, z.core.$strict>;
28
+ declare const archiveExpiredMemoriesInputSchema: z.ZodObject<{
29
+ limit: z.ZodOptional<z.ZodNumber>;
30
+ }, z.core.$strict>;
23
31
  declare const memoryRecordSchema: z.ZodObject<{
24
32
  archivedAtMs: z.ZodOptional<z.ZodNumber>;
25
33
  archiveReason: z.ZodOptional<z.ZodString>;
@@ -39,15 +47,10 @@ declare const memoryRecordSchema: z.ZodObject<{
39
47
  }>;
40
48
  supersededAtMs: z.ZodOptional<z.ZodNumber>;
41
49
  supersededById: z.ZodOptional<z.ZodString>;
42
- type: z.ZodEnum<{
50
+ kind: z.ZodEnum<{
43
51
  preference: "preference";
44
- identity: "identity";
45
- relationship: "relationship";
52
+ procedure: "procedure";
46
53
  knowledge: "knowledge";
47
- context: "context";
48
- event: "event";
49
- task: "task";
50
- observation: "observation";
51
54
  }>;
52
55
  }, z.core.$strict>;
53
56
  export type MemoryRecord = z.output<typeof memoryRecordSchema>;
@@ -60,6 +63,10 @@ export interface CreateMemoryResult {
60
63
  export type ListMemoriesInput = z.output<typeof listMemoriesInputSchema>;
61
64
  export type SearchMemoriesInput = z.output<typeof searchMemoriesInputSchema>;
62
65
  export type ArchiveMemoryInput = z.output<typeof archiveMemoryInputSchema>;
66
+ export type ArchiveExpiredMemoriesInput = z.output<typeof archiveExpiredMemoriesInputSchema>;
67
+ export interface ArchiveExpiredMemoriesResult {
68
+ archivedCount: number;
69
+ }
63
70
  export interface MemoryEmbeddingProvider {
64
71
  /** Embed normalized memory text for derived vector retrieval. */
65
72
  embedTexts(input: {
@@ -77,6 +84,8 @@ export interface MemoryStoreOptions {
77
84
  }
78
85
  /** Context-bound storage operations for visible long-term memories. */
79
86
  export interface MemoryStore {
87
+ /** Archive expired memories visible in the current runtime context. */
88
+ archiveExpiredMemories(input?: ArchiveExpiredMemoriesInput): Promise<ArchiveExpiredMemoriesResult>;
80
89
  /** Archive a visible memory in the current runtime context. */
81
90
  archiveMemory(input: ArchiveMemoryInput): Promise<MemoryRecord>;
82
91
  /** Store a personal memory for the current requester. */
package/dist/types.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { z } from "zod";
2
- export declare const MEMORY_TYPES: readonly ["preference", "identity", "relationship", "knowledge", "context", "event", "task", "observation"];
2
+ export declare const MEMORY_KINDS: readonly ["preference", "procedure", "knowledge"];
3
3
  export declare const MEMORY_SCOPES: readonly ["personal", "conversation"];
4
4
  export declare const MEMORY_SUBJECT_TYPES: readonly ["user", "conversation", "general"];
5
5
  export declare const MEMORY_SOURCE_PLATFORMS: readonly ["slack", "local"];
6
6
  export declare const MEMORY_EMBEDDING_METRICS: readonly ["cosine"];
7
7
  export declare const MEMORY_EMBEDDING_DIMENSIONS = 1536;
8
- export type MemoryType = (typeof MEMORY_TYPES)[number];
8
+ export type MemoryKind = (typeof MEMORY_KINDS)[number];
9
9
  export type MemoryScope = (typeof MEMORY_SCOPES)[number];
10
10
  export type MemorySubjectType = (typeof MEMORY_SUBJECT_TYPES)[number];
11
11
  export type MemorySourcePlatform = (typeof MEMORY_SOURCE_PLATFORMS)[number];
@@ -0,0 +1,12 @@
1
+ ALTER TABLE "junior_memory_memories" DROP CONSTRAINT "junior_memory_memories_type_check";--> statement-breakpoint
2
+ UPDATE "junior_memory_memories"
3
+ SET "type" = CASE
4
+ WHEN "type" = 'task' THEN 'procedure'
5
+ WHEN "type" IN ('identity', 'relationship', 'context', 'event', 'observation') THEN 'knowledge'
6
+ ELSE "type"
7
+ END;--> statement-breakpoint
8
+ ALTER TABLE "junior_memory_memories" ADD CONSTRAINT "junior_memory_memories_kind_check" CHECK ("junior_memory_memories"."type" IN (
9
+ 'preference',
10
+ 'procedure',
11
+ 'knowledge'
12
+ ));
@@ -0,0 +1,348 @@
1
+ {
2
+ "id": "e915b537-996a-488c-a828-7cf4da06be44",
3
+ "prevId": "2f78c37c-9c80-4f92-92f8-7eaa1951862b",
4
+ "version": "7",
5
+ "dialect": "postgresql",
6
+ "tables": {
7
+ "public.junior_memory_embeddings": {
8
+ "name": "junior_memory_embeddings",
9
+ "schema": "",
10
+ "columns": {
11
+ "memory_id": {
12
+ "name": "memory_id",
13
+ "type": "text",
14
+ "primaryKey": true,
15
+ "notNull": true
16
+ },
17
+ "provider": {
18
+ "name": "provider",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true
22
+ },
23
+ "model": {
24
+ "name": "model",
25
+ "type": "text",
26
+ "primaryKey": false,
27
+ "notNull": true
28
+ },
29
+ "dimensions": {
30
+ "name": "dimensions",
31
+ "type": "integer",
32
+ "primaryKey": false,
33
+ "notNull": true
34
+ },
35
+ "metric": {
36
+ "name": "metric",
37
+ "type": "text",
38
+ "primaryKey": false,
39
+ "notNull": true
40
+ },
41
+ "content_hash": {
42
+ "name": "content_hash",
43
+ "type": "text",
44
+ "primaryKey": false,
45
+ "notNull": true
46
+ },
47
+ "embedding": {
48
+ "name": "embedding",
49
+ "type": "vector(1536)",
50
+ "primaryKey": false,
51
+ "notNull": true
52
+ },
53
+ "created_at_ms": {
54
+ "name": "created_at_ms",
55
+ "type": "bigint",
56
+ "primaryKey": false,
57
+ "notNull": true
58
+ }
59
+ },
60
+ "indexes": {
61
+ "junior_memory_embeddings_model_idx": {
62
+ "name": "junior_memory_embeddings_model_idx",
63
+ "columns": [
64
+ {
65
+ "expression": "provider",
66
+ "isExpression": false,
67
+ "asc": true,
68
+ "nulls": "last"
69
+ },
70
+ {
71
+ "expression": "model",
72
+ "isExpression": false,
73
+ "asc": true,
74
+ "nulls": "last"
75
+ },
76
+ {
77
+ "expression": "dimensions",
78
+ "isExpression": false,
79
+ "asc": true,
80
+ "nulls": "last"
81
+ },
82
+ {
83
+ "expression": "metric",
84
+ "isExpression": false,
85
+ "asc": true,
86
+ "nulls": "last"
87
+ }
88
+ ],
89
+ "isUnique": false,
90
+ "concurrently": false,
91
+ "method": "btree",
92
+ "with": {}
93
+ }
94
+ },
95
+ "foreignKeys": {
96
+ "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk": {
97
+ "name": "junior_memory_embeddings_memory_id_junior_memory_memories_id_fk",
98
+ "tableFrom": "junior_memory_embeddings",
99
+ "tableTo": "junior_memory_memories",
100
+ "columnsFrom": ["memory_id"],
101
+ "columnsTo": ["id"],
102
+ "onDelete": "cascade",
103
+ "onUpdate": "no action"
104
+ }
105
+ },
106
+ "compositePrimaryKeys": {},
107
+ "uniqueConstraints": {},
108
+ "policies": {},
109
+ "checkConstraints": {
110
+ "junior_memory_embeddings_metric_check": {
111
+ "name": "junior_memory_embeddings_metric_check",
112
+ "value": "\"junior_memory_embeddings\".\"metric\" IN ('cosine')"
113
+ },
114
+ "junior_memory_embeddings_dimensions_check": {
115
+ "name": "junior_memory_embeddings_dimensions_check",
116
+ "value": "\"junior_memory_embeddings\".\"dimensions\" = 1536"
117
+ }
118
+ },
119
+ "isRLSEnabled": false
120
+ },
121
+ "public.junior_memory_memories": {
122
+ "name": "junior_memory_memories",
123
+ "schema": "",
124
+ "columns": {
125
+ "id": {
126
+ "name": "id",
127
+ "type": "text",
128
+ "primaryKey": true,
129
+ "notNull": true
130
+ },
131
+ "scope": {
132
+ "name": "scope",
133
+ "type": "text",
134
+ "primaryKey": false,
135
+ "notNull": true
136
+ },
137
+ "scope_key": {
138
+ "name": "scope_key",
139
+ "type": "text",
140
+ "primaryKey": false,
141
+ "notNull": true
142
+ },
143
+ "type": {
144
+ "name": "type",
145
+ "type": "text",
146
+ "primaryKey": false,
147
+ "notNull": true
148
+ },
149
+ "subject_type": {
150
+ "name": "subject_type",
151
+ "type": "text",
152
+ "primaryKey": false,
153
+ "notNull": true
154
+ },
155
+ "subject_key": {
156
+ "name": "subject_key",
157
+ "type": "text",
158
+ "primaryKey": false,
159
+ "notNull": false
160
+ },
161
+ "content": {
162
+ "name": "content",
163
+ "type": "text",
164
+ "primaryKey": false,
165
+ "notNull": true
166
+ },
167
+ "source_platform": {
168
+ "name": "source_platform",
169
+ "type": "text",
170
+ "primaryKey": false,
171
+ "notNull": true
172
+ },
173
+ "source_key": {
174
+ "name": "source_key",
175
+ "type": "text",
176
+ "primaryKey": false,
177
+ "notNull": true
178
+ },
179
+ "idempotency_key": {
180
+ "name": "idempotency_key",
181
+ "type": "text",
182
+ "primaryKey": false,
183
+ "notNull": false
184
+ },
185
+ "observed_at_ms": {
186
+ "name": "observed_at_ms",
187
+ "type": "bigint",
188
+ "primaryKey": false,
189
+ "notNull": true
190
+ },
191
+ "created_at_ms": {
192
+ "name": "created_at_ms",
193
+ "type": "bigint",
194
+ "primaryKey": false,
195
+ "notNull": true
196
+ },
197
+ "expires_at_ms": {
198
+ "name": "expires_at_ms",
199
+ "type": "bigint",
200
+ "primaryKey": false,
201
+ "notNull": false
202
+ },
203
+ "superseded_at_ms": {
204
+ "name": "superseded_at_ms",
205
+ "type": "bigint",
206
+ "primaryKey": false,
207
+ "notNull": false
208
+ },
209
+ "superseded_by_id": {
210
+ "name": "superseded_by_id",
211
+ "type": "text",
212
+ "primaryKey": false,
213
+ "notNull": false
214
+ },
215
+ "archived_at_ms": {
216
+ "name": "archived_at_ms",
217
+ "type": "bigint",
218
+ "primaryKey": false,
219
+ "notNull": false
220
+ },
221
+ "archive_reason": {
222
+ "name": "archive_reason",
223
+ "type": "text",
224
+ "primaryKey": false,
225
+ "notNull": false
226
+ }
227
+ },
228
+ "indexes": {
229
+ "junior_memory_memories_visible_idx": {
230
+ "name": "junior_memory_memories_visible_idx",
231
+ "columns": [
232
+ {
233
+ "expression": "scope",
234
+ "isExpression": false,
235
+ "asc": true,
236
+ "nulls": "last"
237
+ },
238
+ {
239
+ "expression": "scope_key",
240
+ "isExpression": false,
241
+ "asc": true,
242
+ "nulls": "last"
243
+ },
244
+ {
245
+ "expression": "created_at_ms",
246
+ "isExpression": false,
247
+ "asc": false,
248
+ "nulls": "last"
249
+ },
250
+ {
251
+ "expression": "id",
252
+ "isExpression": false,
253
+ "asc": true,
254
+ "nulls": "last"
255
+ }
256
+ ],
257
+ "isUnique": false,
258
+ "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL",
259
+ "concurrently": false,
260
+ "method": "btree",
261
+ "with": {}
262
+ },
263
+ "junior_memory_memories_expiration_idx": {
264
+ "name": "junior_memory_memories_expiration_idx",
265
+ "columns": [
266
+ {
267
+ "expression": "expires_at_ms",
268
+ "isExpression": false,
269
+ "asc": true,
270
+ "nulls": "last"
271
+ }
272
+ ],
273
+ "isUnique": false,
274
+ "where": "\"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"expires_at_ms\" IS NOT NULL",
275
+ "concurrently": false,
276
+ "method": "btree",
277
+ "with": {}
278
+ },
279
+ "junior_memory_memories_idempotency_idx": {
280
+ "name": "junior_memory_memories_idempotency_idx",
281
+ "columns": [
282
+ {
283
+ "expression": "scope",
284
+ "isExpression": false,
285
+ "asc": true,
286
+ "nulls": "last"
287
+ },
288
+ {
289
+ "expression": "scope_key",
290
+ "isExpression": false,
291
+ "asc": true,
292
+ "nulls": "last"
293
+ },
294
+ {
295
+ "expression": "idempotency_key",
296
+ "isExpression": false,
297
+ "asc": true,
298
+ "nulls": "last"
299
+ }
300
+ ],
301
+ "isUnique": true,
302
+ "where": "\"junior_memory_memories\".\"idempotency_key\" IS NOT NULL AND \"junior_memory_memories\".\"archived_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_at_ms\" IS NULL AND \"junior_memory_memories\".\"superseded_by_id\" IS NULL",
303
+ "concurrently": false,
304
+ "method": "btree",
305
+ "with": {}
306
+ }
307
+ },
308
+ "foreignKeys": {},
309
+ "compositePrimaryKeys": {},
310
+ "uniqueConstraints": {},
311
+ "policies": {},
312
+ "checkConstraints": {
313
+ "junior_memory_memories_scope_check": {
314
+ "name": "junior_memory_memories_scope_check",
315
+ "value": "\"junior_memory_memories\".\"scope\" IN ('personal', 'conversation')"
316
+ },
317
+ "junior_memory_memories_kind_check": {
318
+ "name": "junior_memory_memories_kind_check",
319
+ "value": "\"junior_memory_memories\".\"type\" IN (\n 'preference',\n 'procedure',\n 'knowledge'\n )"
320
+ },
321
+ "junior_memory_memories_subject_type_check": {
322
+ "name": "junior_memory_memories_subject_type_check",
323
+ "value": "\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation', 'general')"
324
+ },
325
+ "junior_memory_memories_subject_key_check": {
326
+ "name": "junior_memory_memories_subject_key_check",
327
+ "value": "(\"junior_memory_memories\".\"subject_type\" = 'general' AND \"junior_memory_memories\".\"subject_key\" IS NULL) OR (\"junior_memory_memories\".\"subject_type\" IN ('user', 'conversation') AND \"junior_memory_memories\".\"subject_key\" IS NOT NULL AND length(\"junior_memory_memories\".\"subject_key\") > 0)"
328
+ },
329
+ "junior_memory_memories_source_platform_check": {
330
+ "name": "junior_memory_memories_source_platform_check",
331
+ "value": "\"junior_memory_memories\".\"source_platform\" IN ('slack', 'local')"
332
+ }
333
+ },
334
+ "isRLSEnabled": false
335
+ }
336
+ },
337
+ "enums": {},
338
+ "schemas": {},
339
+ "sequences": {},
340
+ "roles": {},
341
+ "policies": {},
342
+ "views": {},
343
+ "_meta": {
344
+ "columns": {},
345
+ "schemas": {},
346
+ "tables": {}
347
+ }
348
+ }
@@ -29,6 +29,13 @@
29
29
  "when": 1782582311997,
30
30
  "tag": "0003_public_slack_workspace_memory",
31
31
  "breakpoints": true
32
+ },
33
+ {
34
+ "idx": 4,
35
+ "version": "7",
36
+ "when": 1782676852768,
37
+ "tag": "0004_gigantic_celestials",
38
+ "breakpoints": true
32
39
  }
33
40
  ]
34
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-memory",
3
- "version": "0.79.0",
3
+ "version": "0.80.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -27,7 +27,7 @@
27
27
  "commander": "^14.0.3",
28
28
  "drizzle-orm": "^0.45.2",
29
29
  "zod": "^4.4.3",
30
- "@sentry/junior-plugin-api": "0.79.0"
30
+ "@sentry/junior-plugin-api": "0.80.1"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^25.9.1",
package/src/agent.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  import type { PluginModel } from "@sentry/junior-plugin-api";
2
2
  import { z } from "zod";
3
- import { memoryRuntimeContextSchema } from "./types";
3
+ import { MEMORY_KINDS, memoryRuntimeContextSchema } from "./types";
4
4
 
5
- const memoryTargetSchema = z.enum(["requester", "conversation"]);
6
- const memoryKindSchema = z.enum(["preference", "procedure", "fact"]);
5
+ const memoryKindSchema = z.enum(MEMORY_KINDS);
7
6
  const memoryRejectReasonSchema = z.enum([
8
7
  "not_public_shareable",
9
8
  "secret_or_credential",
@@ -75,7 +74,7 @@ const memoryReviewDecisionSchema = z.discriminatedUnion("decision", [
75
74
  z
76
75
  .object({
77
76
  decision: z.literal("store"),
78
- target: memoryTargetSchema,
77
+ kind: memoryKindSchema,
79
78
  content: z.string().min(1),
80
79
  expiresAtMs: z.number().finite().optional(),
81
80
  })
@@ -92,7 +91,7 @@ const memoryReviewResponseSchema = z.discriminatedUnion("decision", [
92
91
  .object({
93
92
  decision: z.literal("store"),
94
93
  kind: memoryKindSchema.describe(
95
- "Use preference only for requester-owned personal preferences, opinions, habits, or workflows. Use procedure for reusable task or process instructions. Use fact for shared project, channel, operational, or runbook knowledge.",
94
+ "Use preference only for requester-owned personal preferences, opinions, habits, or workflows. Use procedure for reusable task or process instructions. Use knowledge for shared project, channel, operational, or runbook facts.",
96
95
  ),
97
96
  canonicalFact: z
98
97
  .string()
@@ -113,7 +112,7 @@ const memoryReviewResponseSchema = z.discriminatedUnion("decision", [
113
112
  const extractedMemorySchema = z
114
113
  .object({
115
114
  kind: memoryKindSchema.describe(
116
- "Use preference only for requester-owned personal preferences, opinions, habits, or workflows. Use procedure for reusable task or process instructions. Use fact for shared project, channel, operational, or runbook knowledge.",
115
+ "Use preference only for requester-owned personal preferences, opinions, habits, or workflows. Use procedure for reusable task or process instructions. Use knowledge for shared project, channel, operational, or runbook facts.",
117
116
  ),
118
117
  canonicalFact: z
119
118
  .string()
@@ -124,6 +123,13 @@ const extractedMemorySchema = z
124
123
  expiresAtMs: expiresAtMsSchema,
125
124
  })
126
125
  .strict();
126
+ const extractedMemoryResultSchema = z
127
+ .object({
128
+ content: z.string().min(1),
129
+ expiresAtMs: expiresAtMsSchema,
130
+ kind: memoryKindSchema,
131
+ })
132
+ .strict();
127
133
  const extractMemoriesResponseSchema = z
128
134
  .object({
129
135
  memories: z
@@ -138,20 +144,13 @@ const extractMemoriesResponseSchema = z
138
144
  type MemoryReviewResponse = z.output<typeof memoryReviewResponseSchema>;
139
145
  type ExtractMemoriesResponse = z.output<typeof extractMemoriesResponseSchema>;
140
146
 
141
- export type MemoryTarget = z.output<typeof memoryTargetSchema>;
142
- type MemoryKind = z.output<typeof memoryKindSchema>;
143
-
144
147
  export type MemoryReview = z.output<typeof memoryReviewDecisionSchema>;
145
148
 
146
149
  export type CreateMemoryRequest = z.output<typeof createMemoryRequestSchema>;
147
150
  export type ExtractSessionRequest = z.output<
148
151
  typeof extractSessionRequestSchema
149
152
  >;
150
- export interface ExtractedMemory {
151
- content: string;
152
- expiresAtMs: number | null;
153
- target: MemoryTarget;
154
- }
153
+ export type ExtractedMemory = z.output<typeof extractedMemoryResultSchema>;
155
154
 
156
155
  export interface MemoryAgent {
157
156
  extractSessionMemories(
@@ -186,13 +185,6 @@ const CANONICAL_CONTENT_RULES = [
186
185
  "- Remove requester names, display names, requester/user labels, first- or second-person wording, thread labels, channel labels, and source labels.",
187
186
  ];
188
187
 
189
- function targetForKind(kind: MemoryKind): MemoryTarget {
190
- if (kind === "preference") {
191
- return "requester";
192
- }
193
- return "conversation";
194
- }
195
-
196
188
  function escapeXml(value: string): string {
197
189
  return value
198
190
  .replaceAll("&", "&amp;")
@@ -259,7 +251,7 @@ function memoryKindsContext(): string {
259
251
  "<memory-kinds>",
260
252
  "- preference: a durable first-person personal preference, opinion, habit, or workflow owned by the current requester. Stored as requester memory.",
261
253
  "- procedure: reusable instructions for how a task, lookup, investigation, process, triage flow, or runbook should be done. Store the method, source-of-truth, prerequisite, or decision path when it took effort to discover. Stored as conversation memory.",
262
- "- fact: stable shared project, channel, operational, or runbook knowledge that is not a personal requester preference. Direct answers to user inquiries qualify only when they are durable beyond this run. Stored as conversation memory.",
254
+ "- knowledge: stable shared project, channel, operational, or runbook fact that is not a personal requester preference. Direct answers to user inquiries qualify only when they are durable beyond this run. Stored as conversation memory.",
263
255
  "</memory-kinds>",
264
256
  ].join("\n");
265
257
  }
@@ -279,14 +271,14 @@ function reviewPrompt(request: CreateMemoryRequest): string {
279
271
  "",
280
272
  "<rules>",
281
273
  "- Return store only when the candidate is public/shareable, durable, and self-contained.",
282
- "- First classify the memory kind: preference, procedure, or fact.",
274
+ "- First classify the memory kind: preference, procedure, or knowledge.",
283
275
  "- Use kind=preference only for first-person facts authored by the current requester about their own preference, opinion, habit, identity, or workflow.",
284
276
  "- Reject named third-person personal facts such as another person's preference, opinion, habit, identity, relationship, or workflow. Do not assume a named person is the current requester.",
285
277
  "- Use kind=procedure for reusable task/process/runbook instructions.",
286
- "- Use kind=fact for shared project, channel, operational, or runbook knowledge.",
278
+ "- Use kind=knowledge for shared project, channel, operational, or runbook facts.",
287
279
  "- When current-user-message contains an explicit memory request with a concrete fact or procedure, extract from current-user-message even if the candidate is vague, incomplete, or phrased as an instruction.",
288
280
  "- A candidate may be badly phrased by an outer assistant or extraction pass. When current-user-message contains the requester's own first-person memory fact, treat that as requester-authored source evidence and canonicalize the fact instead of rejecting for third-person wording.",
289
- "- When candidate wording personalizes a shared task, process, runbook, project, channel, or operational fact, use current-user-message to recover the shared fact and classify it as procedure or fact.",
281
+ "- When candidate wording personalizes a shared task, process, runbook, project, channel, or operational fact, use current-user-message to recover the shared fact and classify it as procedure or knowledge.",
290
282
  "- Explicit procedure requests are valid when the source text contains both task context and action. Canonicalize them as shared procedure facts instead of rejecting them as vague.",
291
283
  "- Store content as person-less, source-less canonical knowledge. Ownership and source live in structured metadata, not prose.",
292
284
  "- For requester memories, omit the subject and write the content as a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.",
@@ -349,7 +341,7 @@ function sessionExtractionPrompt(request: ExtractSessionRequest): string {
349
341
  "- Do not store the fact that the user asked for advice, search, recall, planning, listing, inspection, or removal. Store only stable knowledge discovered in response, such as a reusable method or source-of-truth.",
350
342
  "- A user question asking how, what, where, or whether to do something is not source evidence for the answer. Store the answer only when supported by a user-authored factual statement or a tool result.",
351
343
  "- Set kind=procedure for reusable task/process/runbook instructions.",
352
- "- Set kind=fact for shared team, project, channel, runbook, or operational knowledge.",
344
+ "- Set kind=knowledge for shared team, project, channel, runbook, or operational facts.",
353
345
  "- Set kind=preference only for clear durable first-person facts authored by the current requester about their own preference, opinion, habit, identity, or workflow.",
354
346
  "- Reject named third-person personal facts such as another person's preference, opinion, habit, identity, relationship, or workflow. Do not assume a named person is the current requester.",
355
347
  "- User-authored task instructions are procedures, not preferences, unless they explicitly describe the requester's personal preference or habit.",
@@ -398,7 +390,7 @@ function memoryReviewFromResponse(
398
390
  if (response.decision === "store") {
399
391
  return parseMemoryReview({
400
392
  decision: "store",
401
- target: targetForKind(response.kind),
393
+ kind: response.kind,
402
394
  content: response.canonicalFact,
403
395
  ...(response.expiresAtMs !== null
404
396
  ? { expiresAtMs: response.expiresAtMs }
@@ -416,14 +408,20 @@ function extractedMemoriesFromResponse(
416
408
  ): ExtractedMemory[] {
417
409
  const toMemory = (
418
410
  memory: z.output<typeof extractedMemorySchema>,
419
- ): ExtractedMemory => ({
420
- content: memory.canonicalFact,
421
- expiresAtMs: memory.expiresAtMs,
422
- target: targetForKind(memory.kind),
423
- });
411
+ ): ExtractedMemory =>
412
+ parseExtractedMemory({
413
+ content: memory.canonicalFact,
414
+ expiresAtMs: memory.expiresAtMs,
415
+ kind: memory.kind,
416
+ });
424
417
  return response.memories.map(toMemory);
425
418
  }
426
419
 
420
+ /** Parse the canonical extracted-memory shape stored across task retries. */
421
+ export function parseExtractedMemory(memory: unknown): ExtractedMemory {
422
+ return extractedMemoryResultSchema.parse(memory);
423
+ }
424
+
427
425
  /** Parse the structured decision returned by the memory agent. */
428
426
  export function parseMemoryReview(result: unknown): MemoryReview {
429
427
  return memoryReviewDecisionSchema.parse(result);
package/src/cli/format.ts CHANGED
@@ -17,7 +17,7 @@ export function formatMemory(
17
17
  `scope_key=${row.scopeKey}`,
18
18
  `subject_type=${row.subjectType}`,
19
19
  ...(row.subjectKey ? [`subject_key=${row.subjectKey}`] : []),
20
- `type=${row.type}`,
20
+ `kind=${row.kind}`,
21
21
  `created_at=${formatDate(row.createdAtMs)}`,
22
22
  `observed_at=${formatDate(row.observedAtMs)}`,
23
23
  `expires_at=${formatDate(row.expiresAtMs)}`,
package/src/db/schema.ts CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  MEMORY_SCOPES,
22
22
  MEMORY_SOURCE_PLATFORMS,
23
23
  MEMORY_SUBJECT_TYPES,
24
- MEMORY_TYPES,
24
+ MEMORY_KINDS,
25
25
  } from "../types";
26
26
 
27
27
  export const juniorMemoryMemories = pgTable(
@@ -30,7 +30,7 @@ export const juniorMemoryMemories = pgTable(
30
30
  id: text("id").primaryKey(),
31
31
  scope: text("scope", { enum: MEMORY_SCOPES }).notNull(),
32
32
  scopeKey: text("scope_key").notNull(),
33
- type: text("type", { enum: MEMORY_TYPES }).notNull(),
33
+ kind: text("type", { enum: MEMORY_KINDS }).notNull(),
34
34
  subjectType: text("subject_type", { enum: MEMORY_SUBJECT_TYPES }).notNull(),
35
35
  subjectKey: text("subject_key"),
36
36
  content: text("content").notNull(),
@@ -68,16 +68,11 @@ export const juniorMemoryMemories = pgTable(
68
68
  sql`${table.scope} IN ('personal', 'conversation')`,
69
69
  ),
70
70
  check(
71
- "junior_memory_memories_type_check",
72
- sql`${table.type} IN (
71
+ "junior_memory_memories_kind_check",
72
+ sql`${table.kind} IN (
73
73
  'preference',
74
- 'identity',
75
- 'relationship',
76
- 'knowledge',
77
- 'context',
78
- 'event',
79
- 'task',
80
- 'observation'
74
+ 'procedure',
75
+ 'knowledge'
81
76
  )`,
82
77
  ),
83
78
  check(