@oortmem/core 0.5.1 → 0.5.2

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.
@@ -218,6 +218,43 @@ export interface DecisionController {
218
218
  obs: Observation;
219
219
  candidates: Memory[];
220
220
  }[]): Promise<ReconcileDecision[][]>;
221
+ /**
222
+ * Judgment memory (CON-71): which verdict the expert behind `req.precedents` would most likely
223
+ * give `req.item`, as a choice over `req.verdicts` with a probability per verdict. Optional; a
224
+ * controller without it leaves judging at precedents only.
225
+ */
226
+ judge?(req: JudgeRequest): Promise<JudgeChoice>;
227
+ }
228
+ /** One past decision as the controller sees it: the expert's reason verbatim. */
229
+ export interface JudgePrecedent {
230
+ subject: string;
231
+ ref?: string;
232
+ verdict: string;
233
+ reason: string;
234
+ criteria: string[];
235
+ decidedAt: string;
236
+ /** How close it is to the item, 0 to 1 (dense cosine, or lexical overlap). */
237
+ similarity: number;
238
+ }
239
+ /** What `DecisionController.judge` is asked. */
240
+ export interface JudgeRequest {
241
+ item: {
242
+ summary: string;
243
+ details?: string;
244
+ ref?: string;
245
+ domain?: string;
246
+ };
247
+ /** The verdicts to choose from; the precedents' own verdicts are among them. */
248
+ verdicts: string[];
249
+ /** Nearest first. Never empty. */
250
+ precedents: JudgePrecedent[];
251
+ }
252
+ /** The controller's answer: the likeliest verdict, its probability, and every verdict's. */
253
+ export interface JudgeChoice {
254
+ verdict: string;
255
+ probability: number;
256
+ probabilities: Record<string, number>;
257
+ decisions: Decision[];
221
258
  }
222
259
  /** One memory as the writer authors it. */
223
260
  export interface WrittenMemory {
package/dist/config.d.ts CHANGED
@@ -43,6 +43,11 @@ export declare const OortConfig: z.ZodObject<{
43
43
  queryCacheTtlSec: z.ZodDefault<z.ZodNumber>;
44
44
  staleAfterDays: z.ZodDefault<z.ZodNumber>;
45
45
  specificityPrior: z.ZodDefault<z.ZodNumber>;
46
+ promptMode: z.ZodDefault<z.ZodEnum<{
47
+ fast: "fast";
48
+ full: "full";
49
+ lexical: "lexical";
50
+ }>>;
46
51
  }, z.core.$strict>>;
47
52
  project: z.ZodDefault<z.ZodObject<{
48
53
  id: z.ZodOptional<z.ZodString>;
@@ -52,6 +57,10 @@ export declare const OortConfig: z.ZodObject<{
52
57
  autostart: z.ZodDefault<z.ZodBoolean>;
53
58
  idleMinutes: z.ZodDefault<z.ZodNumber>;
54
59
  }, z.core.$strict>>;
60
+ judge: z.ZodDefault<z.ZodObject<{
61
+ experts: z.ZodDefault<z.ZodArray<z.ZodString>>;
62
+ operator: z.ZodOptional<z.ZodString>;
63
+ }, z.core.$strict>>;
55
64
  }, z.core.$strict>;
56
65
  export type OortConfig = z.infer<typeof OortConfig>;
57
66
  export type ConfigSource = 'project' | 'home' | 'default';
@@ -60,7 +69,8 @@ export type ResolvedConfig = OortConfig & {
60
69
  sources: Record<string, ConfigSource>;
61
70
  /**
62
71
  * Keys a project's `oort.config.json` set that only the home config may set (`serve`: a
63
- * repository must not start processes on this machine). Ignored; absent when there are none.
72
+ * repository must not start processes on this machine; `judge`: nor name experts). Ignored;
73
+ * absent when there are none.
64
74
  */
65
75
  ignoredProjectKeys?: string[];
66
76
  };
package/dist/config.js CHANGED
@@ -75,6 +75,13 @@ const recall = z
75
75
  * Galaxy 0). 0, the default, turns it off: it is turned on only if the eval shows a gain.
76
76
  */
77
77
  specificityPrior: z.number().min(0).max(1).default(0),
78
+ /**
79
+ * How the prompt hook (Claude Code's UserPromptSubmit) recalls, locally and in Oort Cloud
80
+ * (CON-101): `full` embeds the prompt and reranks; `fast` skips the reranker (fusion and the
81
+ * relevance gate rank); `lexical` skips the query embedding too (no model call at all). `oort
82
+ * recall`, MCP and SessionStart always recall in full.
83
+ */
84
+ promptMode: z.enum(['full', 'fast', 'lexical']).default('full'),
78
85
  })
79
86
  .default({
80
87
  lexicalK: 50,
@@ -91,6 +98,7 @@ const recall = z
91
98
  queryCacheTtlSec: 600,
92
99
  staleAfterDays: 30,
93
100
  specificityPrior: 0,
101
+ promptMode: 'full',
94
102
  });
95
103
  const project = z
96
104
  .strictObject({
@@ -111,6 +119,20 @@ const serve = z
111
119
  idleMinutes: z.number().int().min(1).max(1440).default(30),
112
120
  })
113
121
  .default({ autostart: false, idleMinutes: 30 });
122
+ /**
123
+ * Judgment memory (CON-71). Read from the home config only: a repository's `oort.config.json`
124
+ * cannot name who counts as an expert.
125
+ * - `experts`: the expert ids an agent may record judgments for over MCP (`record_judgment`).
126
+ * Empty (the default): MCP recording is refused.
127
+ * - `operator`: who withdraws, confirms or purges judgments from this machine (`--by` overrides);
128
+ * default `local-user`.
129
+ */
130
+ const judge = z
131
+ .strictObject({
132
+ experts: z.array(z.string().trim().min(1).max(128)).max(200).default([]),
133
+ operator: z.string().trim().min(1).max(128).optional(),
134
+ })
135
+ .default({ experts: [] });
114
136
  export const OortConfig = z.strictObject({
115
137
  embed,
116
138
  rerank,
@@ -120,9 +142,10 @@ export const OortConfig = z.strictObject({
120
142
  recall,
121
143
  project,
122
144
  serve,
145
+ judge,
123
146
  });
124
147
  /** Keys read from the home config only; a project file's value is ignored (and reported). */
125
- const HOME_ONLY_KEYS = new Set(['serve']);
148
+ const HOME_ONLY_KEYS = new Set(['serve', 'judge']);
126
149
  const CONFIG_KEYS = Object.keys(OortConfig.shape);
127
150
  function findProjectConfig(cwd) {
128
151
  let dir = path.resolve(cwd);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Characters that must never reach a terminal or a person deciding something as they are: C0 and
3
+ * C1 controls, the bidi controls (Trojan Source) and zero-width or other invisible format
4
+ * characters. One source for the CLI's `shown()`/`safeJson()` and for judgment memory's input
5
+ * checks (CON-71), so the two never drift. Written as escapes: no literal one sits in this file.
6
+ */
7
+ export declare const DISPLAY_UNSAFE_SOURCE = "[\\u0000-\\u001f\\u007f-\\u009f\\u061c\\u200b-\\u200f\\u202a-\\u202e\\u2060-\\u2064\\u2066-\\u2069\\ufeff]";
8
+ /** DISPLAY_UNSAFE_SOURCE without C0 and C1: the bidi and invisible format characters alone. */
9
+ export declare const INVISIBLE_SOURCE = "[\\u061c\\u200b-\\u200f\\u202a-\\u202e\\u2060-\\u2064\\u2066-\\u2069\\ufeff]";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Characters that must never reach a terminal or a person deciding something as they are: C0 and
3
+ * C1 controls, the bidi controls (Trojan Source) and zero-width or other invisible format
4
+ * characters. One source for the CLI's `shown()`/`safeJson()` and for judgment memory's input
5
+ * checks (CON-71), so the two never drift. Written as escapes: no literal one sits in this file.
6
+ */
7
+ export const DISPLAY_UNSAFE_SOURCE = '[\\u0000-\\u001f\\u007f-\\u009f\\u061c\\u200b-\\u200f\\u202a-\\u202e\\u2060-\\u2064\\u2066-\\u2069\\ufeff]';
8
+ /** DISPLAY_UNSAFE_SOURCE without C0 and C1: the bidi and invisible format characters alone. */
9
+ export const INVISIBLE_SOURCE = '[\\u061c\\u200b-\\u200f\\u202a-\\u202e\\u2060-\\u2064\\u2066-\\u2069\\ufeff]';
10
+ //# sourceMappingURL=display.js.map
@@ -38,7 +38,10 @@ export interface HiddenLinkFlags {
38
38
  export declare class ExportFormatError extends Error {
39
39
  constructor(message: string);
40
40
  }
41
- /** True when version 1 can hold `m`: a Planet memory whose author is its scope's agent. */
41
+ /**
42
+ * True when version 1 can hold `m`: a Planet memory whose author is its scope's agent, and not a
43
+ * judgment (CON-71; version 1 readers know four memory types and no `judgment` field).
44
+ */
42
45
  export declare function fitsVersion1(m: Memory): boolean;
43
46
  /**
44
47
  * One memory as an export line of `version`: the embedding as base64 of its
@@ -16,10 +16,15 @@ export class ExportFormatError extends Error {
16
16
  }
17
17
  }
18
18
  const base64 = (v) => Buffer.from(v.buffer, v.byteOffset, v.byteLength).toString('base64');
19
- /** True when version 1 can hold `m`: a Planet memory whose author is its scope's agent. */
19
+ /**
20
+ * True when version 1 can hold `m`: a Planet memory whose author is its scope's agent, and not a
21
+ * judgment (CON-71; version 1 readers know four memory types and no `judgment` field).
22
+ */
20
23
  export function fitsVersion1(m) {
21
24
  const author = authorOf(m);
22
- return (addressOf(m).level === 'user' &&
25
+ return (m.type !== 'judgment' &&
26
+ m.judgment === undefined &&
27
+ addressOf(m).level === 'user' &&
23
28
  author.accountRef === undefined &&
24
29
  author.agentId === m.scope.agentId &&
25
30
  (m.provenance === undefined || m.provenance === null));
package/dist/fusion.d.ts CHANGED
@@ -9,6 +9,8 @@ export interface TemporalView {
9
9
  asOf?: string;
10
10
  /** For `known-at`: the instant in transaction time. */
11
11
  knownAt?: string;
12
+ /** Also show withdrawn judgments (CON-71); every mode leaves them out by default. */
13
+ includeWithdrawn?: boolean;
12
14
  }
13
15
  /**
14
16
  * Weight of the activation boost: fused = rrf * (1 + ACTIVATION_BOOST * sigmoid(A)). With one RRF
package/dist/fusion.js CHANGED
@@ -54,6 +54,9 @@ const t = (iso) => Date.parse(iso);
54
54
  * - history: every version of a fact, except corrected ones.
55
55
  */
56
56
  export function isVisible(m, now, v) {
57
+ // A withdrawn judgment no longer counts in any slice of time: the expert took it back.
58
+ if (m.judgment?.withdrawn !== undefined && v.includeWithdrawn !== true)
59
+ return false;
57
60
  switch (v.mode) {
58
61
  case 'current':
59
62
  return isCurrent(m, now);
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const VERSION = "0.5.1";
1
+ export declare const VERSION = "0.5.2";
2
2
  export * from './model.js';
3
3
  export * from './address.js';
4
4
  export * from './export-format.js';
@@ -25,3 +25,5 @@ export * from './cap.js';
25
25
  export * from './consolidate.js';
26
26
  export * from './errors.js';
27
27
  export * from './private-fs.js';
28
+ export * from './judgment.js';
29
+ export * from './display.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export const VERSION = '0.5.1';
1
+ export const VERSION = '0.5.2';
2
2
  export * from './model.js';
3
3
  export * from './address.js';
4
4
  export * from './export-format.js';
@@ -25,4 +25,6 @@ export * from './cap.js';
25
25
  export * from './consolidate.js';
26
26
  export * from './errors.js';
27
27
  export * from './private-fs.js';
28
+ export * from './judgment.js';
29
+ export * from './display.js';
28
30
  //# sourceMappingURL=index.js.map