neotoma 0.22.2 → 0.23.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.
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +49 -50
- package/dist/actions.js.map +1 -1
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +79 -3
- package/dist/config.js.map +1 -1
- package/dist/docs/developer/mcp/compact_instructions.md +2 -0
- package/dist/docs/developer/mcp/instructions.md +30 -3
- package/dist/docs/developer/mcp/proxy.md +6 -4
- package/dist/docs/operations/configuration.md +54 -42
- package/dist/docs/specs/MCP_SPEC.md +1 -1
- package/dist/docs/subsystems/conflict_resolution.md +11 -6
- package/dist/docs/subsystems/observation_architecture.md +2 -2
- package/dist/docs/subsystems/reducer.md +29 -3
- package/dist/docs/subsystems/schema_registry.md +11 -0
- package/dist/docs/testing/automated_test_catalog.md +13 -6
- package/dist/mcp_http_session.d.ts +51 -0
- package/dist/mcp_http_session.d.ts.map +1 -0
- package/dist/mcp_http_session.js +173 -0
- package/dist/mcp_http_session.js.map +1 -0
- package/dist/reducers/observation_reducer.d.ts.map +1 -1
- package/dist/reducers/observation_reducer.js +24 -6
- package/dist/reducers/observation_reducer.js.map +1 -1
- package/dist/server.d.ts +7 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +117 -10
- package/dist/server.js.map +1 -1
- package/dist/services/field_canonicalization.d.ts +1 -0
- package/dist/services/field_canonicalization.d.ts.map +1 -1
- package/dist/services/field_canonicalization.js +15 -9
- package/dist/services/field_canonicalization.js.map +1 -1
- package/dist/services/interpretation.d.ts +2 -0
- package/dist/services/interpretation.d.ts.map +1 -1
- package/dist/services/interpretation.js +2 -1
- package/dist/services/interpretation.js.map +1 -1
- package/dist/services/schema_definitions.d.ts.map +1 -1
- package/dist/services/schema_definitions.js +108 -0
- package/dist/services/schema_definitions.js.map +1 -1
- package/dist/services/schema_registry.d.ts +1 -0
- package/dist/services/schema_registry.d.ts.map +1 -1
- package/dist/services/schema_registry.js.map +1 -1
- package/dist/services/skills/instance_skills.d.ts +137 -0
- package/dist/services/skills/instance_skills.d.ts.map +1 -0
- package/dist/services/skills/instance_skills.js +381 -0
- package/dist/services/skills/instance_skills.js.map +1 -0
- package/dist/tool_definitions.js +1 -1
- package/dist/tool_definitions.js.map +1 -1
- package/docs/developer/mcp/instructions.md +30 -3
- package/package.json +2 -2
package/dist/config.d.ts
CHANGED
|
@@ -23,6 +23,25 @@ export declare const config: {
|
|
|
23
23
|
mcpTokenEncryptionKey: string;
|
|
24
24
|
/** When true, MCP clients receive the compact instruction block (same body as runtime fallback) instead of the full fenced block from docs — for dual-host setups that already load workspace Neotoma rules. */
|
|
25
25
|
mcpCompactInstructions: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* When false, MCP `initialize` skips the graph-stored skill lookup entirely
|
|
28
|
+
* and the instructions block is byte-identical to what it was before
|
|
29
|
+
* instance skill hints existed (#2046).
|
|
30
|
+
*
|
|
31
|
+
* Defaults to ON, unlike `mcpCompactInstructions` above. The feature exists
|
|
32
|
+
* because a hosted instance's skills are otherwise undiscoverable to an
|
|
33
|
+
* MCP-only client, and a discovery fix that an operator has to find and
|
|
34
|
+
* enable does not fix discovery. Instances with no `skill` rows already
|
|
35
|
+
* render nothing, so the default costs them one bounded read and no
|
|
36
|
+
* instruction bytes; the flag is the escape hatch for an operator who wants
|
|
37
|
+
* the section gone regardless.
|
|
38
|
+
*
|
|
39
|
+
* Note the polarity: this reads the env var for an explicit OFF, where the
|
|
40
|
+
* compact flag reads it for an explicit ON. Only `0`/`false` disable it, so
|
|
41
|
+
* an unset or unparseable value keeps the documented default rather than
|
|
42
|
+
* silently turning the feature off.
|
|
43
|
+
*/
|
|
44
|
+
mcpInstanceSkillHints: boolean;
|
|
26
45
|
oauthClientId: string;
|
|
27
46
|
/**
|
|
28
47
|
* Additional exact callback URLs an operator trusts to receive an authorization
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAgUA,eAAO,MAAM,MAAM;;;;eAIO,QAAQ,GAAG,QAAQ;IAC3C,0FAA0F;;IAE1F,6DAA6D;;;;;;;;;;;;;;;;IA4B7D,gNAAgN;;IAIhN;;;;;;;;;;;;;;;;;OAiBG;;;IAMH;;;;;;;;;;;OAWG;;;;;;;;;;;;;;;;CAgCJ,CAAC;AAEF;;;GAGG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAsBpC"}
|
package/dist/config.js
CHANGED
|
@@ -16,21 +16,77 @@ function resolveUserEnvPath() {
|
|
|
16
16
|
return null;
|
|
17
17
|
return join(homeDir, ".config", "neotoma", ".env");
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Is this process test-shaped (issue #2387)?
|
|
21
|
+
*
|
|
22
|
+
* `VITEST` is set by the vitest runner in workers; `NODE_ENV=test` is set by
|
|
23
|
+
* `vitest.global_setup.ts` and is the conventional signal a child process
|
|
24
|
+
* inherits. `NEOTOMA_REQUIRE_EXPLICIT_DATA_DIR=1` lets any caller demand the
|
|
25
|
+
* same strictness without pretending to be a test.
|
|
26
|
+
*/
|
|
27
|
+
function requiresExplicitDataDir() {
|
|
28
|
+
if (process.env.NEOTOMA_REQUIRE_EXPLICIT_DATA_DIR?.trim() === "1")
|
|
29
|
+
return true;
|
|
30
|
+
if (process.env.VITEST?.trim())
|
|
31
|
+
return true;
|
|
32
|
+
return process.env.NODE_ENV?.trim() === "test";
|
|
33
|
+
}
|
|
34
|
+
/** Deliberate opt-in that re-permits the user-level fallback under test (issue #2387). */
|
|
35
|
+
function userEnvFallbackAllowedInTest() {
|
|
36
|
+
return process.env.NEOTOMA_ALLOW_USER_ENV_IN_TEST?.trim() === "1";
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Refuse the `~/.config/neotoma/.env` data-directory fallback in a test-shaped
|
|
40
|
+
* process (issue #2387).
|
|
41
|
+
*
|
|
42
|
+
* A CLI child spawned by a test does not necessarily inherit `NEOTOMA_DATA_DIR`.
|
|
43
|
+
* Without this guard such a child hydrated the variable from the user-level
|
|
44
|
+
* config and then read and wrote the data directory it names — the operator's
|
|
45
|
+
* real database — silently and with exit code 0. A test that passes against
|
|
46
|
+
* residue in real data is green for the wrong reason twice over, and the write
|
|
47
|
+
* itself is invisible because nothing fails.
|
|
48
|
+
*
|
|
49
|
+
* So: stop, name the variable to set, and exit non-zero. Non-test processes are
|
|
50
|
+
* untouched — the interactive CLI and the server keep hydrating exactly as
|
|
51
|
+
* before — and `NEOTOMA_ALLOW_USER_ENV_IN_TEST=1` re-permits it for the rare
|
|
52
|
+
* test that genuinely means to exercise the fallback.
|
|
53
|
+
*/
|
|
54
|
+
function refuseUserEnvFallbackUnderTest(userEnvPath, configuredDataDir) {
|
|
55
|
+
const message = [
|
|
56
|
+
"[neotoma] Refusing to resolve the data directory from the user-level config while running under test.",
|
|
57
|
+
` A test-shaped process (VITEST / NODE_ENV=test / NEOTOMA_REQUIRE_EXPLICIT_DATA_DIR=1) has no explicit NEOTOMA_DATA_DIR,`,
|
|
58
|
+
` so ${userEnvPath} would have pointed it at a data directory holding real data.`,
|
|
59
|
+
"",
|
|
60
|
+
" Set NEOTOMA_DATA_DIR to a test-scoped directory in the environment of this process",
|
|
61
|
+
" (and pass it explicitly to any CLI child process the test spawns).",
|
|
62
|
+
" To exercise the user-level fallback on purpose, set NEOTOMA_ALLOW_USER_ENV_IN_TEST=1.",
|
|
63
|
+
].join("\n");
|
|
64
|
+
process.stderr.write(`${message}\n`);
|
|
65
|
+
// Length, not content: the configured path may name a real operator directory.
|
|
66
|
+
process.stderr.write(`[neotoma] (refused user-level data directory: ${configuredDataDir.length} chars, not used)\n`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
19
69
|
function hydrateDataDirFromUserEnvConfig() {
|
|
20
70
|
if (process.env.NEOTOMA_DATA_DIR?.trim())
|
|
21
71
|
return;
|
|
22
72
|
const userEnvPath = resolveUserEnvPath();
|
|
23
73
|
if (!userEnvPath || !existsSync(userEnvPath))
|
|
24
74
|
return;
|
|
75
|
+
let configuredDataDir;
|
|
25
76
|
try {
|
|
26
77
|
const parsed = dotenv.parse(readFileSync(userEnvPath, "utf-8"));
|
|
27
|
-
|
|
28
|
-
if (configuredDataDir)
|
|
29
|
-
process.env.NEOTOMA_DATA_DIR = configuredDataDir;
|
|
78
|
+
configuredDataDir = parsed.NEOTOMA_DATA_DIR?.trim();
|
|
30
79
|
}
|
|
31
80
|
catch {
|
|
32
81
|
// Ignore invalid user env files and continue with existing fallbacks.
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (!configuredDataDir)
|
|
85
|
+
return;
|
|
86
|
+
if (requiresExplicitDataDir() && !userEnvFallbackAllowedInTest()) {
|
|
87
|
+
refuseUserEnvFallbackUnderTest(userEnvPath, configuredDataDir);
|
|
33
88
|
}
|
|
89
|
+
process.env.NEOTOMA_DATA_DIR = configuredDataDir;
|
|
34
90
|
}
|
|
35
91
|
function isNeotomaRepoRoot(candidate) {
|
|
36
92
|
if (!candidate)
|
|
@@ -272,6 +328,26 @@ export const config = {
|
|
|
272
328
|
/** When true, MCP clients receive the compact instruction block (same body as runtime fallback) instead of the full fenced block from docs — for dual-host setups that already load workspace Neotoma rules. */
|
|
273
329
|
mcpCompactInstructions: (process.env.NEOTOMA_MCP_COMPACT_INSTRUCTIONS || "").toLowerCase() === "1" ||
|
|
274
330
|
(process.env.NEOTOMA_MCP_COMPACT_INSTRUCTIONS || "").toLowerCase() === "true",
|
|
331
|
+
/**
|
|
332
|
+
* When false, MCP `initialize` skips the graph-stored skill lookup entirely
|
|
333
|
+
* and the instructions block is byte-identical to what it was before
|
|
334
|
+
* instance skill hints existed (#2046).
|
|
335
|
+
*
|
|
336
|
+
* Defaults to ON, unlike `mcpCompactInstructions` above. The feature exists
|
|
337
|
+
* because a hosted instance's skills are otherwise undiscoverable to an
|
|
338
|
+
* MCP-only client, and a discovery fix that an operator has to find and
|
|
339
|
+
* enable does not fix discovery. Instances with no `skill` rows already
|
|
340
|
+
* render nothing, so the default costs them one bounded read and no
|
|
341
|
+
* instruction bytes; the flag is the escape hatch for an operator who wants
|
|
342
|
+
* the section gone regardless.
|
|
343
|
+
*
|
|
344
|
+
* Note the polarity: this reads the env var for an explicit OFF, where the
|
|
345
|
+
* compact flag reads it for an explicit ON. Only `0`/`false` disable it, so
|
|
346
|
+
* an unset or unparseable value keeps the documented default rather than
|
|
347
|
+
* silently turning the feature off.
|
|
348
|
+
*/
|
|
349
|
+
mcpInstanceSkillHints: !((process.env.NEOTOMA_MCP_INSTANCE_SKILL_HINTS || "").toLowerCase() === "0" ||
|
|
350
|
+
(process.env.NEOTOMA_MCP_INSTANCE_SKILL_HINTS || "").toLowerCase() === "false"),
|
|
275
351
|
oauthClientId: process.env.NEOTOMA_OAUTH_CLIENT_ID || "",
|
|
276
352
|
/**
|
|
277
353
|
* Additional exact callback URLs an operator trusts to receive an authorization
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAE9C,kFAAkF;AAClF,uEAAuE;AACvE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,aAAa,CAAC;AAErD,uFAAuF;AACvF,+FAA+F;AAC/F,8EAA8E;AAC9E,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,SAAS,kBAAkB;IACzB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAC5D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,+BAA+B;IACtC,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE;QAAE,OAAO;IACjD,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;IACzC,IAAI,CAAC,WAAW,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO;IACrD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;QAChE,MAAM,iBAAiB,GAAG,MAAM,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;QAC1D,IAAI,iBAAiB;YAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,iBAAiB,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;IACxE,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAoC;IAC7D,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7B,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAsB,CAAC;QACvF,OAAO,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAC5D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;IACtE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAG1D,CAAC;QACF,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC;QACtD,OAAO,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,6BAA6B;IACpC,IAAI,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,CAAC;QACxD,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAC1C,CAAC;IACD,IAAI,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAAE,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3D,MAAM,kBAAkB,GAAG,4BAA4B,EAAE,CAAC;IAC1D,IAAI,kBAAkB;QAAE,OAAO,kBAAkB,CAAC;IAClD,mFAAmF;IACnF,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9F,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC5F,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,WAAW,GAAG,6BAA6B,EAAE,CAAC;AAEpD,oFAAoF;AACpF,2FAA2F;AAC3F,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;IACzB,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,8EAA8E;IAC9E,+EAA+E;IAC/E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,4BAA4B;AACnG,CAAC;KAAM,CAAC;IACN,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,yFAAyF;AACzF,+BAA+B,EAAE,CAAC;AAElC,SAAS,eAAe;IACtB,2EAA2E;IAC3E,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED,wFAAwF;AACxF,MAAM,eAAe,GAAG,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/D,MAAM,QAAQ,GAAG,QAAQ,CACvB,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,eAAe,EACzE,EAAE,CACH,CAAC;AACF,MAAM,cAAc,GAAG,OAAO,CAAC;AAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAC1E,MAAM,gBAAgB,GAAG,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,MAAM,UAAU,GAAG,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC1E,+EAA+E;AAC/E,MAAM,gBAAgB,GAAG,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC;AACjF,MAAM,YAAY,GAChB,OAAO,CAAC,GAAG,CAAC,sBAAsB;IAClC,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB;QAChC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,gBAAgB,CAAC;QAC3D,CAAC,CAAC,IAAI,CAAC;IACT,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAE1C;;;GAGG;AACH,SAAS,iBAAiB,CAAC,QAAgB,EAAE,kBAA2B;IACtE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACvB,iBAAyB,CAAC,WAAW,GAAG,EAAE,GAAG,EAAE,oBAAoB,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAC7F,OAAO,oBAAoB,QAAQ,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,WAAW,GAAG;QAClB,wBAAwB,EAAE,8BAA8B;QACxD,6BAA6B,EAAE,kCAAkC;KAClE,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC/C,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBAClC,4CAA4C;oBAC3C,iBAAyB,CAAC,WAAW,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;oBACvD,OAAO,GAAG,CAAC;gBACb,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,qDAAqD;QACvD,CAAC;IACH,CAAC;IAED,2CAA2C;IAC1C,iBAAyB,CAAC,WAAW,GAAG,EAAE,GAAG,EAAE,oBAAoB,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC7F,OAAO,oBAAoB,QAAQ,EAAE,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;AAC7E,IAAI,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;IACrD,MAAM,IAAI,KAAK,CACb,+BAA+B,OAAO,CAAC,GAAG,CAAC,kBAAkB,kCAAkC,CAChG,CAAC;AACJ,CAAC;AAED,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAE1F;;;GAGG;AACH,SAAS,6BAA6B,CAAC,KAAa;IAClD,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,iHAAiH,CAAC;IAC3H,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC5C,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClD,OAAO,WAAW,QAAQ,yEAAyE,CAAC;IACtG,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,OAAO,+GAA+G,CAAC;IACzH,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,IAAI,QAAQ,KAAK,OAAO,IAAI,CAAC,6BAA6B,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,OAAO,2GAA2G,CAAC;IACrH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,wBAAwB,CAAC,GAAuB;IACvD,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;SACxB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAG,OAAO;SACpB,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACpB,MAAM,MAAM,GAAG,6BAA6B,CAAC,KAAK,CAAC,CAAC;QACpD,wEAAwE;QACxE,0EAA0E;QAC1E,yDAAyD;QACzD,OAAO,MAAM,CAAC,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC,MAAM,iBAAiB,CAAC,KAAK,CAAC,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3F,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,MAAM,EAAoB,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;IAEzD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,gDAAgD,OAAO,CAAC,MAAM,OAAO,OAAO,CAAC,MAAM,GAAG;YACpF,2DAA2D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACjF,sFAAsF;YACtF,qFAAqF;YACrF,uFAAuF;YACvF,2DAA2D,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,oFAAoF;AACpF,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,OAAO,CAAC,wCAAwC,EAAE,eAAe,CAAC,CAAC;AAClF,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,WAAW;IACX,cAAc;IACd,OAAO;IACP,SAAS,EAAE,SAAgC;IAC3C,0FAA0F;IAC1F,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE;IACvC,6DAA6D;IAC7D,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE;IACpD,UAAU,EACR,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAC/B,IAAI,CAAC,OAAO,EAAE,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC;IACxE,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACrF,YAAY;IACZ,OAAO;IACP,qBAAqB,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,MAAM;IACtE,iGAAiG;IACjG,aAAa,EAAE,EAAE;IACjB,cAAc,EAAE,EAAE;IAClB,YAAY,EAAE,eAAe,EAAE;IAC/B,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC;IAC1E,QAAQ;IACR,WAAW,EAAE,GAAG;IAChB,0BAA0B,EACxB,GAAG,KAAK,YAAY;QACpB,CAAC,OAAO,CAAC,GAAG,CAAC,wCAAwC,IAAI,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM;IAC5F,OAAO,EACL,OAAO,CAAC,GAAG,CAAC,gBAAgB;QAC5B,iBAAiB,CACf,QAAQ,EACR,GAAG,KAAK,YAAY;YAClB,CAAC,OAAO,CAAC,GAAG,CAAC,wCAAwC,IAAI,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAC7F;IACH,qBAAqB,EACnB,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,EAAE;IAC5F,gNAAgN;IAChN,sBAAsB,EACpB,CAAC,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,GAAG;QAC1E,CAAC,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM;IAC/E,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,EAAE;IACxD;;;;;;;;;;;OAWG;IACH,wBAAwB,EAAE,wBAAwB,CAChD,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAChD;IACD,kBAAkB,EAChB,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO;IACjF,sCAAsC;IACtC,UAAU,EAAE;QACV,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B,KAAK,MAAM;QAC1D,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE;QACpD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;QAC5C,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,EAAE;QACjE,oBAAoB,EAAE,OAAO,CAAC,GAAG,CAAC,8BAA8B,KAAK,MAAM;KAC5E;IAED,2BAA2B;IAC3B,cAAc,EAAE;QACd,OAAO,EACL,CAAC,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;YACpF,OAAO;QACT,mBAAmB,EAAE,UAAU,CAC7B,OAAO,CAAC,GAAG,CAAC,uCAAuC;YACjD,OAAO,CAAC,GAAG,CAAC,+BAA+B;YAC3C,KAAK,CACR;QACD,KAAK,EACH,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,QAAQ;QAC5F,QAAQ,EAAE,QAAQ,CAChB,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,EAC3E,EAAE,CACH;KACF;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,UAAU,GAAI,iBAAyB,CAAC,WAAW,CAAC;IAE1D,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,qDAAqD,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACrF,CAAC;SAAM,IAAI,CAAC,MAAM,CAAC,0BAA0B,EAAE,CAAC;QAC9C,OAAO,CAAC,GAAG,CACT,mDAAmD,MAAM,CAAC,WAAW,qBAAqB,MAAM,CAAC,QAAQ,EAAE,CAC5G,CAAC;IACJ,CAAC;SAAM,IAAI,UAAU,EAAE,IAAI,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CACT,sEAAsE,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,GAAG,EAAE,CAC3G,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CACT,mFAAmF,MAAM,CAAC,QAAQ,EAAE,CACrG,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gCAAgC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,6BAA6B,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,6 +47,8 @@ The Neotoma server has two compact-mode payloads:
|
|
|
47
47
|
|
|
48
48
|
Both contain the same `MCP_INTERACTION_INSTRUCTIONS_COMPACT_BODY_LINES` content. The header line differs so agents and operators can distinguish an intentional compact deployment from a fallback caused by a broken doc path.
|
|
49
49
|
|
|
50
|
+
Compact mode also narrows the `[INSTANCE SKILLS]` section appended for graph-stored skills: names are listed without descriptions, and the section header says so while still instructing agents to match ordinary user intent against the catalog before fetching the selected skill body. See the `Instance-stored skills` entry under `[INITIALIZATION]` in [`instructions.md`](./instructions.md) for both rendered examples. That section is controlled independently by `NEOTOMA_MCP_INSTANCE_SKILL_HINTS` (default on; set `0` to omit it entirely).
|
|
51
|
+
|
|
50
52
|
---
|
|
51
53
|
|
|
52
54
|
## Setting the environment variable
|
|
@@ -54,7 +54,7 @@ Entities **`entities[]` shape:** put every intended observation field at the **t
|
|
|
54
54
|
MCP tool choice: prefer **`store`** for all writes (entities-only, file-only, or combined). Deprecated MCP aliases `store_structured` and `store_unstructured` call the same handler as **`store`** until removed; use **`store`** in new prompts and configs.
|
|
55
55
|
Relationship batching: define ALL known links in the **`store`** `relationships` array whenever possible. Use { relationship_type, source_index, target_index } for entities in the same request, or { relationship_type, source_entity_id, target_entity_id } for existing entities already known by id. If you need to link an existing conversation/message/source entity to newly created entities, prefer re-including the existing entity in `entities` by stable identity fields and linking by index, or use id-based relationship entries in the same store call. If relationships must be created after a store response, use create_relationships with a relationships array; do not issue one create_relationship call per link when batching is possible.
|
|
56
56
|
Interpretation batching: when an agent extracts entities from a stored source (file, email, API detail payload, transcript, or other raw artifact), prefer one **`store`** call with `interpretation: { source_id | source_ref, interpretation_config }` plus any `relationships`. Use `source_ref: "unstructured"` for the raw file source in a combined file+entities store, and `source_ref: "structured"` only when intentionally interpreting the generated JSON source. Use `create_interpretation` when the source already exists and you are adding a post-hoc interpretation; use list_interpretations to review interpretation runs for a source. Omit `interpretation` for ordinary user-stated/chat-native structured facts; those observations intentionally keep `interpretation_id = NULL`.
|
|
57
|
-
Immutability: observations and sources are immutable after creation. correct creates a new priority-1000 observation
|
|
57
|
+
Immutability: observations and sources are immutable after creation. correct creates a new priority-1000 observation; it does not edit or delete prior observations. The correction supersedes lower-priority observations, while a higher-priority source remains authoritative and an equal-priority tie follows the schema's source-kind precedence before deterministic recency. After correct, independently retrieve the entity snapshot and field provenance; verify the intended value and the new correction observation materialized before claiming the correction took effect.
|
|
58
58
|
Turn identity: use host conversation_id/thread_id/session_id and turn_id when available. If the host does not provide them, derive ONE stable synthetic conversation id for the visible chat/thread and reuse it for every turn in that thread; combine it with a monotonically increasing turn index or per-turn timestamp. Put that stable value on the `conversation` entity as `conversation_id`; set message `turn_key = "{conversation_id}:{turn_id}"`; set idempotency_key unique per turn (e.g. conversation-{conversation_id}-{turn_id}-{timestamp_ms}). conversation_id MUST be unique per conversation but stable within that conversation; do not mint a new conversation entity for each user message in the same visible chat. Unscoped turn_keys like "cursor:1" cause cross-conversation entity collisions where unrelated messages merge into the same agent_message entity. When the host provides only a generic session prefix, append a conversation-distinguishing suffix (e.g. timestamp of first message, or a short hash of the conversation title) and keep that suffix stable for the thread.
|
|
59
59
|
Session UUID bridge (Claude Code): in Claude Code contexts the SessionStart hook creates a `conversation` entity keyed by the raw session UUID while the MCP agent creates a slug-keyed entity (conversation_id = derived slug). Call `get_session_identity` once per session — at user-phase Step 2 retrieval or Step 3 store time — and include `session_uuid: <UUID returned by get_session_identity>` on the slug-keyed `conversation` entity. This cross-references the hook-created UUID entity and the agent-created slug entity so timeline events, observations, and conversation_turn rows written by hooks can be correlated with the MCP conversation without server-side coalescing. FORBIDDEN: omitting `session_uuid` on the `conversation` entity in Claude Code contexts when `get_session_identity` is available and returns a session UUID.
|
|
60
60
|
Fallback IDs: if the host provides no conversation_id/turn_id at all, derive a stable synthetic conversation id from the visible thread context (e.g. "chat-<topic-or-first-message-hash>-<session-start-timestamp>") and reuse it; use idempotency_key "conversation-{synthetic_conversation_id}-<turn>-<timestamp_ms>" and turn_key "{synthetic_conversation_id}:<turn>" (e.g. chat-neotoma-hooks-2026-05-05:5). When no topic or thread context is available, use a session-epoch-scoped fallback: turn_key "chat-<session_epoch_ms>:<turn>" (e.g. chat-1747344000000:1) and idempotency_key "conversation-chat-<session_epoch_ms>-<turn>-<timestamp_ms>", where session_epoch_ms is the millisecond timestamp of the first message in the current session (fixed for the session lifetime). FORBIDDEN: using a fresh fallback conversation id or generic "chat:<turn>" prefix for every message in one UI conversation. FORBIDDEN: using bare "chat:<turn>" (without a session-epoch or other session-distinguishing suffix) as a turn_key fallback — bare chat:N values reuse across sessions and cause cross-session entity merges.
|
|
@@ -280,10 +280,37 @@ Forward compatibility: treat an unrecognized `reason_code` as a hard denial and
|
|
|
280
280
|
|
|
281
281
|
[INITIALIZATION]
|
|
282
282
|
Session orientation: at the start of every session, call `get_session_identity` to obtain the authenticated user and session UUID (used to cross-reference hook-created conversation entities — see [STORE RECIPES] Session UUID bridge). Call `list_entity_types` (no keyword) to warm the session type cache so entity-type reuse and schema checks run against known types without a discovery round-trip mid-task. Both calls are bounded reads; execute them together before the first user-message store.
|
|
283
|
-
Available skills:
|
|
284
|
-
Skills loaded at initialize:
|
|
283
|
+
Available skills: `serverInfo._neotoma.available_skills` is an array of skill name strings that this session may use. It is a UNION of two sources that are invoked differently, so the array alone tells you a skill EXISTS, not how to run it. A name that also appears in the instructions block's `[INSTANCE SKILLS]` section is graph-stored and its body must be fetched before use (see `Instance-stored skills` below). Every other name is a local skill, already installed and linked into the harness skills directory — invoke it directly by name (e.g. `/store-data`, `/remember-codebase`) when the user's request matches its purpose, and do not re-discover or re-install it. If `available_skills` is absent or empty, skills may still be present: check the harness skills directory or ask the user. If `serverInfo._neotoma.skills_unavailable` is true, the graph-stored skill lookup FAILED for this session — an empty or local-only array then means unknown, not none; say so rather than telling the user this instance has no skills.
|
|
284
|
+
Skills loaded at initialize: the LOCAL half of `available_skills` is installed by `neotoma setup` and already linked into the harness skills directory. It typically covers: `ensure-neotoma` (self-check and setup), `query-memory` (search and retrieve entities), `store-data` (structured entity storage with provenance), `remember-codebase` (index a repo into Neotoma), `remember-contacts`, `remember-conversations`, `remember-email`, `remember-finances`, `remember-calendar`, `remember-meetings`, `recover-sqlite-database` (corruption repair). The active list may differ — prefer the `available_skills` array from `initialize` over this static enumeration, and note that on a hosted instance none of these may be present locally.
|
|
285
285
|
Skill auto-loading at session start. On every MCP `initialize`, the harness MUST detect available skills in the active workspace (`.claude/skills/`, `.cursor/skills/`, `.codex/skills/`, or the harness's documented skill registry path) and ensure they are registered with the agent context. If skills are already detected, this is a no-op. Emit a log/trace entry naming auto-loaded vs already-present skills. This requirement is idempotent and applies regardless of whether the user explicitly invoked a skill in the prior turn.
|
|
286
286
|
Instance skills / scripts materialization (CLI-only, no MCP tool — writing files to the invoking machine's local filesystem has no server-side equivalent; see `docs/developer/cli_reference.md` and `docs/skills/skill_strategy.md`): `neotoma skills sync --include-instance-skills` / `--include-instance-scripts` / `--approve-scripts` (deprecated hidden alias: `--approve`) fetch instance-stored `skill` entities (and their `EMBEDS`'d script attachments, hash-pin gated) into the local harness skill directories. There is no MCP-side equivalent tool for this capability; do not infer one exists.
|
|
287
|
+
Instance-stored skills: skills stored in the graph as `skill` entities have NO body on disk, so they cannot be invoked by name the way a local skill can. When the instructions block carries an `[INSTANCE SKILLS]` section, every name listed there is graph-stored, and the section gives names and descriptions ONLY. Use that catalog for ordinary intent matching first: the user does not need to say Neotoma, Ateles, a skill name, or an entity ID. Resolve the authorized instance context from the session; if one listed skill clearly matches the user's request, select it, and if several could match, clarify only that ambiguity. Before running the selected skill, fetch its full markdown body with `retrieve_entity_by_identifier` using `entity_type: "skill"`, `by: "name"`, and `identifier` set to the skill name; the body is the snapshot's `content` field. Follow that body's constraints, execution steps, and readback requirements once fetched. Do not assume a graph-stored skill has a local file, and do not attempt to materialize any script it references — fetch and follow the markdown only. The fetch call shape is:
|
|
288
|
+
|
|
289
|
+
{ "name": "retrieve_entity_by_identifier",
|
|
290
|
+
"arguments": { "entity_type": "skill", "by": "name", "identifier": "audit-graph" } }
|
|
291
|
+
|
|
292
|
+
A rendered section looks like this (full mode). The count in the header is the number of skills the instance holds, which may exceed the number of lines listed:
|
|
293
|
+
|
|
294
|
+
[INSTANCE SKILLS]
|
|
295
|
+
This instance stores 2 skills as `skill` entities in the graph. They are available to this session even though no local skills directory is present. Names and descriptions only are listed below. Match ordinary user intent against this catalog; the user does not need to say Neotoma, Ateles, a skill name, or an entity id. If one skill clearly matches the authorized instance context, select it; if several could match, clarify only that ambiguity. To run one, first fetch its full body with retrieve_entity_by_identifier with entity_type "skill", by "name", and identifier set to the skill name, then follow that body's constraints, execution steps, and readback requirements.
|
|
296
|
+
- audit-graph — Audit the graph for undeclared fragments.
|
|
297
|
+
- capture-meeting — (no description)
|
|
298
|
+
|
|
299
|
+
Under `NEOTOMA_MCP_COMPACT_INSTRUCTIONS`, descriptions are omitted and the header says so:
|
|
300
|
+
|
|
301
|
+
[INSTANCE SKILLS]
|
|
302
|
+
This instance stores 2 skills as `skill` entities in the graph. They are available to this session even though no local skills directory is present. Names only are listed below. Match ordinary user intent against this catalog; the user does not need to say Neotoma, Ateles, a skill name, or an entity id. If one skill clearly matches the authorized instance context, select it; if several could match, clarify only that ambiguity. To run one, first fetch its full body with retrieve_entity_by_identifier with entity_type "skill", by "name", and identifier set to the skill name, then follow that body's constraints, execution steps, and readback requirements.
|
|
303
|
+
- audit-graph
|
|
304
|
+
- capture-meeting
|
|
305
|
+
|
|
306
|
+
The list is capped, and truncation is stated rather than silent — a 5-skill instance rendered at a cap of 3 ends with an explicit remainder line:
|
|
307
|
+
|
|
308
|
+
- audit-graph — Audit the graph for undeclared fragments.
|
|
309
|
+
- capture-meeting — Record a meeting into the graph.
|
|
310
|
+
- draft-reply — Draft a reply from stored context.
|
|
311
|
+
…and 2 more (fetch by name as above).
|
|
312
|
+
|
|
313
|
+
If the section is replaced by a note saying the skills could not be read, the lookup failed: treat this instance's skills as unknown, do not report that it has none, and retry on a later connection. The section is emitted by default and can be turned off with `NEOTOMA_MCP_INSTANCE_SKILL_HINTS=0`, in which case the instructions carry no `[INSTANCE SKILLS]` section at all.
|
|
287
314
|
|
|
288
315
|
[ONBOARDING]
|
|
289
316
|
Discovery flow: when Neotoma has little or no data (first run or empty state), follow the onboarding sequence from install.md — (1) ask the user which data types matter most (project files, chat transcripts, meeting notes, notes/journals, code context, email, financial docs, custom paths) and which mode they prefer (quick win, guided, power user); (2) discover high-value local files by scanning shallowly — rank by entity density, temporal signals, recency, and relationship potential per docs/foundation/file_ranking_heuristic.md; (3) group results into domains (not file counts) and explain why each was selected and what timeline value it could unlock; (4) let the user confirm per-folder or per-file with an expected reconstruction preview; (5) ingest confirmed files and reconstruct the strongest timeline with provenance (each event traced to a specific source file); (6) show the timeline immediately — not a file count; (7) offer one follow-up query specific to the reconstructed entity and 2–4 leveraged next actions; (8) demonstrate correction. See docs/developer/agent_onboarding_confirmation.md for the full specification.
|
|
@@ -73,14 +73,16 @@ HTTP and stdio transports share the same **`NeotomaServer`** `initialize` behavi
|
|
|
73
73
|
|
|
74
74
|
Streamable HTTP MCP keeps each session in **process memory** (`mcpTransports` in `src/actions.ts`). The stdio proxy captures **`mcp-session-id`** from the **`initialize`** response and attaches it to later tool calls.
|
|
75
75
|
|
|
76
|
-
As of neotoma#
|
|
76
|
+
As of neotoma#2100, an **authenticated** `POST /mcp` that carries an unknown/expired `mcp-session-id` **recovers in place**: the server mints a new in-memory transport, completes a server-side initialize handshake, serves the original JSON-RPC call, and returns a **new** `mcp-session-id`. Sessions are still **not** persisted to SQLite — a restart clears the map, and the next authenticated POST heals without forcing a client restart. `GET`/`DELETE` with an unknown session, and POST with no session header on a non-`initialize` body, still return 404/400.
|
|
77
|
+
|
|
78
|
+
As of neotoma#1923, remaining unknown/expired session errors return **404** (not 503), per the [MCP Streamable HTTP session management spec](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#session-management) — this lets spec-compliant clients auto-reinitialize instead of treating the server as unavailable. Servers predating that fix return 503 for the same condition; `neotoma mcp proxy` recognizes both.
|
|
77
79
|
|
|
78
80
|
| Symptom | Typical cause | What to do |
|
|
79
81
|
| ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
80
82
|
| **400** — no session header on a non-`initialize` POST | Proxy never stored an id (failed init, stripped response header) or client skipped `initialize` | Restart the MCP server in the IDE; confirm proxy stderr shows a successful downstream `initialize` and that your reverse proxy **forwards** `mcp-session-id` on responses and requests (custom headers are not hop-by-hop but some templates hide unknown headers). |
|
|
81
|
-
| **404** (or, against an older server, **503**) — session header present but unknown on this instance | **
|
|
82
|
-
| **404** (or **503**) — same, while using **`neotoma mcp proxy`** | Transient
|
|
83
|
-
| **404** / **503** / **400** after deploy or restart | In-memory map cleared |
|
|
83
|
+
| **404** (or, against an older server, **503**) — session header present but unknown on this instance | **Process restart** cleared in-memory sessions, or a stale client id after recover failed | Prefer a server with #2100 recover-in-place (authenticated POST heals and returns a new `mcp-session-id`). Otherwise restart the MCP client so `initialize` runs again. Multi-replica sticky sessions only apply if you actually run multiple `/mcp` workers. |
|
|
84
|
+
| **404** (or **503**) — same, while using **`neotoma mcp proxy`** | Transient API restart after the IDE finished `initialize` (or an older server without #2100) | The proxy **replays `initialize` to downstream once** (without emitting a second `initialize` on stdout), captures a fresh `mcp-session-id`, and **retries the failing RPC once**. If the second attempt still fails, fix infra or restart the MCP client. |
|
|
85
|
+
| **404** / **503** / **400** after deploy or restart | In-memory map cleared | With #2100, the next authenticated tool call should recover transparently. Without it, restart the MCP client once so `initialize` runs again. |
|
|
84
86
|
| `handshake_unreachable` — the first `initialize` never reached a server (CONNECT_TIMEOUT, ECONNREFUSED, socket closed) | Backend down, restarting, or the wrong `--downstream-url` | The proxy already retried with backoff (neotoma#2321) and the backend stayed unreachable for the whole window. Check `/health` and the downstream URL, then restart the MCP client once the backend answers. |
|
|
85
87
|
| `handshake_server_error` — the first `initialize` reached the server, which failed internally (5xx, or `-32603` through a 200) | Substrate crash surfacing through the handshake (e.g. neotoma#2316's "DB request aborted by caller") | Also already retried. The server is broken rather than refusing you: check server logs and `/health`, redeploy if needed, then restart the MCP client. |
|
|
86
88
|
| `handshake_auth_rejected` — the first `initialize` was refused for authentication (401) | Invalid/expired bearer, encryption-mode token required, unauthenticated POST, or invalid `X-Connection-Id` | **Not retried, deliberately** — a replay cannot fix a credential. Fix the credential: re-run `neotoma auth mcp-token`, or remove `Authorization` / `X-Connection-Id` from `mcp.json` and reconnect. |
|
|
@@ -18,25 +18,37 @@ All state lives under one directory you control, set by `NEOTOMA_DATA_DIR` (defa
|
|
|
18
18
|
|
|
19
19
|
Resolution order for the data directory and variables: a project-local `.env`, then `~/.config/neotoma/.env`, then built-in defaults.
|
|
20
20
|
|
|
21
|
+
### Under test, the user-level step is refused
|
|
22
|
+
|
|
23
|
+
A test-shaped process — one with `VITEST` set, `NODE_ENV=test`, or `NEOTOMA_REQUIRE_EXPLICIT_DATA_DIR=1` — does **not** fall back to `~/.config/neotoma/.env` for its data directory. If it reaches that step it stops and exits non-zero, naming the variable to set.
|
|
24
|
+
|
|
25
|
+
The reason is that the user-level config names the data directory holding real data. A test process, or a CLI child a test spawns without passing `NEOTOMA_DATA_DIR` through, would otherwise read and write that directory silently and succeed — so the mistake is invisible, and a test can pass on residue left in real data rather than on the code under test.
|
|
26
|
+
|
|
27
|
+
So set `NEOTOMA_DATA_DIR` to a test-scoped directory, and pass it explicitly to every CLI child process a test spawns rather than relying on inheritance. To exercise the user-level fallback deliberately, set `NEOTOMA_ALLOW_USER_ENV_IN_TEST=1`.
|
|
28
|
+
|
|
29
|
+
Nothing changes for normal operation: the interactive CLI, the server, and every non-test entry point resolve the data directory exactly as the order above describes.
|
|
30
|
+
|
|
21
31
|
## Environments
|
|
22
32
|
|
|
23
33
|
`NEOTOMA_ENV` selects the profile: `development` (default) or `production`. The profiles use separate database files, source directories, and logs so a dev stack never touches prod data. Production also changes default ports and tightens auth expectations.
|
|
24
34
|
|
|
25
35
|
## Core variables
|
|
26
36
|
|
|
27
|
-
| Variable
|
|
28
|
-
|
|
|
29
|
-
| `NEOTOMA_ENV`
|
|
30
|
-
| `NEOTOMA_DATA_DIR`
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
37
|
+
| Variable | Purpose | Default |
|
|
38
|
+
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
|
|
39
|
+
| `NEOTOMA_ENV` | `development` or `production` | `development` |
|
|
40
|
+
| `NEOTOMA_DATA_DIR` | Root data directory | local `data/` |
|
|
41
|
+
| `NEOTOMA_REQUIRE_EXPLICIT_DATA_DIR` | `1` demands an explicit `NEOTOMA_DATA_DIR`: refuse the `~/.config/neotoma/.env` fallback and exit non-zero. Implied by `VITEST` / `NODE_ENV=test` | unset |
|
|
42
|
+
| `NEOTOMA_ALLOW_USER_ENV_IN_TEST` | `1` re-permits that fallback in a test-shaped process, for a test that means to exercise it | unset |
|
|
43
|
+
| `NEOTOMA_SQLITE_PATH` | Explicit database file path | `{dataDir}/neotoma.db` (dev) |
|
|
44
|
+
| `NEOTOMA_DB_BACKEND` | DB driver: `sqlite` (synchronous, zero-config) or `libsql` (concurrent — statements run off the event loop via worker-hosted driver for local files, or @libsql/client for remote sqld/Turso, so slow queries can't freeze the server; recommended for hosted/agent-heavy/shared instances) | `sqlite` |
|
|
45
|
+
| `NEOTOMA_DB_URL` | libsql connection URL (`file:` for embedded local, `http(s)://`/`libsql://` for remote sqld/Turso) | `file:{NEOTOMA_SQLITE_PATH}` |
|
|
46
|
+
| `NEOTOMA_DB_AUTH_TOKEN` | Auth token for remote libsql connections | unset |
|
|
47
|
+
| `NEOTOMA_DB_READER_WORKERS` | Read-only worker connections for the local `libsql` backend (WAL lets them run concurrently with the writer). Reads go to the least-loaded reader, so raising this adds capacity rather than just slots | `2` |
|
|
48
|
+
| `NEOTOMA_DB_STATEMENT_TIMEOUT_MS` | Per-statement budget for reads on that reader pool. On expiry the reader is terminated (the synchronous driver cannot be interrupted mid-statement) and respawns on the next read, so one runaway query cannot hold a pool slot indefinitely. Writes and statements inside a transaction are never timed out. `0` disables | `30000` |
|
|
49
|
+
| `NEOTOMA_RAW_STORAGE_DIR` | Content-addressed source files | `{dataDir}/sources` |
|
|
50
|
+
| `NEOTOMA_LOGS_DIR` / `NEOTOMA_EVENT_LOG_PATH` | Log directory and event log file | under `{dataDir}/logs` |
|
|
51
|
+
| `NEOTOMA_HOST_URL` / `NEOTOMA_PUBLIC_BASE_URL` | Public URL of this instance | auto-discovered or unset |
|
|
40
52
|
|
|
41
53
|
### When to opt into `NEOTOMA_DB_BACKEND=libsql`
|
|
42
54
|
|
|
@@ -49,22 +61,22 @@ Before flipping the variable on an existing database, run `npx tsx scripts/valid
|
|
|
49
61
|
|
|
50
62
|
## Server and ports
|
|
51
63
|
|
|
52
|
-
| Variable
|
|
53
|
-
|
|
|
64
|
+
| Variable | Purpose | Default |
|
|
65
|
+
| ------------------------------------ | -------------------------- | ----------------------- |
|
|
54
66
|
| `NEOTOMA_HTTP_PORT` (or `HTTP_PORT`) | HTTP API and HTTP MCP port | `3080` dev, `3180` prod |
|
|
55
|
-
| `WS_PORT`
|
|
67
|
+
| `WS_PORT` | WebSocket MCP bridge port | `8280` |
|
|
56
68
|
|
|
57
69
|
See [Running the Server](running_the_server.md) for transports and processes.
|
|
58
70
|
|
|
59
71
|
## Auth and access
|
|
60
72
|
|
|
61
|
-
| Variable
|
|
62
|
-
|
|
|
63
|
-
| `NEOTOMA_REQUIRE_KEY_FOR_OAUTH`
|
|
64
|
-
| `NEOTOMA_OAUTH_CLIENT_ID`
|
|
73
|
+
| Variable | Purpose |
|
|
74
|
+
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
75
|
+
| `NEOTOMA_REQUIRE_KEY_FOR_OAUTH` | Require a key for OAuth connections |
|
|
76
|
+
| `NEOTOMA_OAUTH_CLIENT_ID` | MCP OAuth client id (hosted mode) |
|
|
65
77
|
| `NEOTOMA_OAUTH_TRUSTED_CALLBACK_URLS` | Comma-separated **exact** callback URLs additionally trusted to receive an authorization code when the authorize request arrives via a tunnel. Empty by default. See below. |
|
|
66
|
-
| `NEOTOMA_SANDBOX_MODE`
|
|
67
|
-
| `NEOTOMA_REFUSE_MODE`
|
|
78
|
+
| `NEOTOMA_SANDBOX_MODE` | Opt into the public hosted-sandbox profile |
|
|
79
|
+
| `NEOTOMA_REFUSE_MODE` | `warn` or `enforce` when a no-auth, non-loopback topology is detected |
|
|
68
80
|
|
|
69
81
|
### Trusted OAuth callback URLs
|
|
70
82
|
|
|
@@ -86,14 +98,14 @@ Several entries are comma-separated. Rules worth knowing before you set it:
|
|
|
86
98
|
|
|
87
99
|
A redirect is accepted when the request's callback and a configured entry agree on **scheme, host, port and path** — all four. In detail:
|
|
88
100
|
|
|
89
|
-
| Part
|
|
90
|
-
|
|
|
91
|
-
| Scheme
|
|
92
|
-
| Host
|
|
93
|
-
| Port
|
|
94
|
-
| Path
|
|
95
|
-
| Query and fragment | **Ignored on both sides**, so the usual `?code=...&state=...` callback matches.
|
|
96
|
-
| Userinfo
|
|
101
|
+
| Part | How it is compared |
|
|
102
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
103
|
+
| Scheme | Must match. `https` does not authorise its `http` twin. |
|
|
104
|
+
| Host | Case-**insensitive**. `APP.EXAMPLE.COM` matches `app.example.com`. |
|
|
105
|
+
| Port | Must match, but a default port is equivalent to none: `https://app.example.com` = `https://app.example.com:443`. |
|
|
106
|
+
| Path | Case-**sensitive**. `/Auth/Callback` does **not** match `/auth/callback`. A trailing slash is insignificant in either direction. Dot segments resolve first, so `/auth/callback/../admin` is compared as `/auth/admin`. An encoded slash (`%2F`) is not a path separator. |
|
|
107
|
+
| Query and fragment | **Ignored on both sides**, so the usual `?code=...&state=...` callback matches. |
|
|
108
|
+
| Userinfo | Any URL carrying `user:password@` is rejected. |
|
|
97
109
|
|
|
98
110
|
If a redirect is refused, the `400` response names the callback URL the server actually compared (scheme, host and path — query and fragment are stripped) and says how many entries are configured. That is usually enough to tell a near miss — a trailing slash, a port, a case difference — from a typo or an unset variable, without needing server logs.
|
|
99
111
|
|
|
@@ -111,23 +123,23 @@ See [Deployment Modes](deployment.md) and [Agent Access Control](agent_access_co
|
|
|
111
123
|
|
|
112
124
|
## Encryption
|
|
113
125
|
|
|
114
|
-
| Variable
|
|
115
|
-
|
|
|
116
|
-
| `NEOTOMA_ENCRYPTION_ENABLED`
|
|
117
|
-
| `NEOTOMA_KEY_FILE_PATH`
|
|
118
|
-
| `NEOTOMA_MNEMONIC` / `NEOTOMA_MNEMONIC_PASSPHRASE` | BIP-39 mnemonic key source
|
|
119
|
-
| `NEOTOMA_LOG_ENCRYPTION_ENABLED`
|
|
120
|
-
| `NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY`
|
|
126
|
+
| Variable | Purpose |
|
|
127
|
+
| -------------------------------------------------- | --------------------------------------------- |
|
|
128
|
+
| `NEOTOMA_ENCRYPTION_ENABLED` | Turn on AES-256-GCM at-rest column encryption |
|
|
129
|
+
| `NEOTOMA_KEY_FILE_PATH` | Path to a 32-byte key file |
|
|
130
|
+
| `NEOTOMA_MNEMONIC` / `NEOTOMA_MNEMONIC_PASSPHRASE` | BIP-39 mnemonic key source |
|
|
131
|
+
| `NEOTOMA_LOG_ENCRYPTION_ENABLED` | Encrypt the event log |
|
|
132
|
+
| `NEOTOMA_MCP_TOKEN_ENCRYPTION_KEY` | Encrypt stored MCP OAuth tokens |
|
|
121
133
|
|
|
122
134
|
See [Encryption and Key Management](encryption.md).
|
|
123
135
|
|
|
124
136
|
## Search, inspector, and docs
|
|
125
137
|
|
|
126
|
-
| Variable
|
|
127
|
-
|
|
|
128
|
-
| `OPENAI_API_KEY`
|
|
129
|
-
| `NEOTOMA_INSPECTOR_DISABLE` / `NEOTOMA_PUBLIC_INSPECTOR_URL` / `NEOTOMA_INSPECTOR_BASE_PATH` | Control the bundled Inspector
|
|
130
|
-
| `NEOTOMA_DOCS_SHOW_INTERNAL`
|
|
138
|
+
| Variable | Purpose |
|
|
139
|
+
| -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
140
|
+
| `OPENAI_API_KEY` | Enables semantic vector search (embeddings); keyword search works without it |
|
|
141
|
+
| `NEOTOMA_INSPECTOR_DISABLE` / `NEOTOMA_PUBLIC_INSPECTOR_URL` / `NEOTOMA_INSPECTOR_BASE_PATH` | Control the bundled Inspector |
|
|
142
|
+
| `NEOTOMA_DOCS_SHOW_INTERNAL` | Show `visibility: internal` docs in the in-app `/docs` browser |
|
|
131
143
|
|
|
132
144
|
## Limits and mirror
|
|
133
145
|
|
|
@@ -1412,7 +1412,7 @@ This enables full explainability: for any fact in the system, you can trace it b
|
|
|
1412
1412
|
|
|
1413
1413
|
### 3.12 `correct`
|
|
1414
1414
|
|
|
1415
|
-
**Purpose:** Create
|
|
1415
|
+
**Purpose:** Create a priority-1000 correction [observation](../vocabulary/canonical_terms.md#observation) to override lower-priority AI-[extracted](../vocabulary/canonical_terms.md#extraction) fields. Higher-priority sources remain authoritative; equal-priority ties follow configured source-kind precedence and deterministic recency in [entity snapshot](../vocabulary/canonical_terms.md#entity-snapshot) computation. Read the snapshot and field provenance back before claiming the correction took effect.
|
|
1416
1416
|
|
|
1417
1417
|
**Request Schema:**
|
|
1418
1418
|
|
|
@@ -53,8 +53,8 @@ obs_b: { status: "complete", observed_at: "2026-01-02T09:00:00Z" }
|
|
|
53
53
|
|
|
54
54
|
- Primary sort: `source_priority DESC`.
|
|
55
55
|
- Secondary sort (within the same priority tier): `observation_source` rank ASC (schema-configurable; sensors and workflow outputs rank above LLM summaries by default).
|
|
56
|
-
-
|
|
57
|
-
- Implementation: `highestPriority()`
|
|
56
|
+
- Same-priority ordering: after numeric priority and source-kind rank tie, the reducer chooses `observed_at DESC`, then `created_at DESC`, then `id ASC` as the final stable fallback. This applies even when the field declares `tie_breaker: "source_priority"`; source priority is already the primary trust axis, and same-tier scalar corrections still express replacement intent.
|
|
57
|
+
- Implementation: `highestPriority()` in `src/reducers/observation_reducer.ts`.
|
|
58
58
|
|
|
59
59
|
Use `highest_priority` when some sources are inherently more trustworthy than others —
|
|
60
60
|
official documents over extracted receipts, sensor data over user text, corrections over
|
|
@@ -230,10 +230,15 @@ regardless of which was written more recently.
|
|
|
230
230
|
|
|
231
231
|
### `tie_breaker` options
|
|
232
232
|
|
|
233
|
-
| Value |
|
|
234
|
-
| ------------------------- |
|
|
235
|
-
| `"observed_at"` (default) |
|
|
236
|
-
| `"source_priority"` |
|
|
233
|
+
| Value | `highest_priority` behavior after the priority and source-kind tiers tie | `most_specific` behavior after specificity ties |
|
|
234
|
+
| ------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------- |
|
|
235
|
+
| `"observed_at"` (default) | Newest `observed_at`, then newest `created_at`, then `id ASC` | Source-kind rank, then newest `observed_at` |
|
|
236
|
+
| `"source_priority"` | Same as `"observed_at"`; retained as a compatibility spelling | Numeric source priority, source-kind rank, then newest `observed_at` |
|
|
237
|
+
|
|
238
|
+
For `highest_priority`, numeric source priority is already the primary trust axis, so
|
|
239
|
+
the two configured values intentionally converge once that tier ties. The distinction
|
|
240
|
+
remains meaningful for `most_specific`, where `"source_priority"` adds numeric source
|
|
241
|
+
priority between specificity and source-kind rank.
|
|
237
242
|
|
|
238
243
|
---
|
|
239
244
|
|
|
@@ -103,14 +103,14 @@ const correctionObservation = {
|
|
|
103
103
|
interpretation_id: null, // No interpretation
|
|
104
104
|
observed_at: new Date(),
|
|
105
105
|
specificity_score: 1.0, // Maximum specificity
|
|
106
|
-
source_priority: 1000, //
|
|
106
|
+
source_priority: 1000, // Overrides lower-priority observations
|
|
107
107
|
fields: {
|
|
108
108
|
name: "Acme Corporation", // Corrected value
|
|
109
109
|
},
|
|
110
110
|
user_id: "user_123",
|
|
111
111
|
};
|
|
112
112
|
```
|
|
113
|
-
**Key property:** Corrections persist across reinterpretation. Even if a source is reinterpreted with a new model, the correction observation remains and continues to override AI-extracted values.
|
|
113
|
+
**Key property:** Corrections persist across reinterpretation. Even if a source is reinterpreted with a new model, the correction observation remains and continues to override lower-priority AI-extracted values. Higher-priority sources remain authoritative; equal-priority ties follow the schema's source-kind precedence before deterministic recency.
|
|
114
114
|
### 2.2 Observation Storage
|
|
115
115
|
Observations are stored in `observations` table:
|
|
116
116
|
- Immutable once created
|
|
@@ -106,9 +106,12 @@ function highestPriority(
|
|
|
106
106
|
field: string,
|
|
107
107
|
observations: Observation[]
|
|
108
108
|
): { value: any; source_observation_id: string } {
|
|
109
|
-
const sorted = observations.sort((a, b) =>
|
|
110
|
-
b.source_priority - a.source_priority ||
|
|
111
|
-
|
|
109
|
+
const sorted = observations.sort((a, b) =>
|
|
110
|
+
b.source_priority - a.source_priority ||
|
|
111
|
+
observationSourceRank(a) - observationSourceRank(b) ||
|
|
112
|
+
b.observed_at.getTime() - a.observed_at.getTime() ||
|
|
113
|
+
b.created_at.getTime() - a.created_at.getTime() ||
|
|
114
|
+
a.id.localeCompare(b.id)
|
|
112
115
|
);
|
|
113
116
|
return {
|
|
114
117
|
value: sorted[0].fields[field],
|
|
@@ -116,6 +119,29 @@ function highestPriority(
|
|
|
116
119
|
};
|
|
117
120
|
}
|
|
118
121
|
```
|
|
122
|
+
|
|
123
|
+
Same-priority scalar corrections use that same order. A correction does not need
|
|
124
|
+
to invent priority `1001` to replace an earlier normal correction: two correction
|
|
125
|
+
observations at priority `1000` keep higher `observation_source` precedence, then
|
|
126
|
+
the later `observed_at`/`created_at` wins, with `id ASC` used only when both
|
|
127
|
+
timestamps are equal. Correction receipts should still be followed by independent
|
|
128
|
+
snapshot readback; a response status alone is not proof of the effective value.
|
|
129
|
+
|
|
130
|
+
This ordering applies to every field whose active built-in or custom schema
|
|
131
|
+
declares `highest_priority`, and to every same-priority observation on that
|
|
132
|
+
field; it is not limited to observations created by the correction tools. The
|
|
133
|
+
change does not alter `most_specific` fields. Deploying the reducer does not
|
|
134
|
+
rewrite existing snapshots in bulk. A later store or correction recomputes the
|
|
135
|
+
entity it touches, while untouched snapshots keep their prior projection until
|
|
136
|
+
they are explicitly recomputed. For a deliberate rollout, first call
|
|
137
|
+
`POST /recompute_snapshots_by_type` with `dry_run: true`, then recompute each
|
|
138
|
+
affected entity type and verify the returned counts and errors plus representative
|
|
139
|
+
snapshot values and provenance. To roll back, revert the reducer before further
|
|
140
|
+
bulk recomputation. If snapshots were already recomputed, recompute the affected
|
|
141
|
+
types again after the rollback to restore the prior projection. Observations are
|
|
142
|
+
immutable, so this changes which value is materialized without deleting source
|
|
143
|
+
history.
|
|
144
|
+
|
|
119
145
|
**Use Cases:**
|
|
120
146
|
- `vendor_name` in invoices (official documents > receipts)
|
|
121
147
|
- `merchant_name` in receipts (bank statements > receipts)
|