@cerefox/memory 1.13.0 → 1.13.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/AGENT_GUIDE.md +26 -26
- package/AGENT_QUICK_REFERENCE.md +9 -9
- package/dist/bin/cerefox.js +93 -113
- package/dist/server-assets/_shared/ef-meta/index.ts +3 -3
- package/dist/server-assets/_shared/mcp-tools/audit-log.ts +10 -8
- package/dist/server-assets/_shared/mcp-tools/delete-document.ts +4 -10
- package/dist/server-assets/_shared/mcp-tools/feature-flags.ts +4 -3
- package/dist/server-assets/_shared/mcp-tools/get-document.ts +3 -6
- package/dist/server-assets/_shared/mcp-tools/get-help-content.ts +3 -3
- package/dist/server-assets/_shared/mcp-tools/get-help.ts +3 -6
- package/dist/server-assets/_shared/mcp-tools/identity.ts +48 -0
- package/dist/server-assets/_shared/mcp-tools/ingest.ts +3 -6
- package/dist/server-assets/_shared/mcp-tools/list-metadata-keys.ts +3 -6
- package/dist/server-assets/_shared/mcp-tools/list-projects.ts +3 -6
- package/dist/server-assets/_shared/mcp-tools/list-versions.ts +3 -6
- package/dist/server-assets/_shared/mcp-tools/metadata-search.ts +3 -6
- package/dist/server-assets/_shared/mcp-tools/partial-edits.ts +5 -10
- package/dist/server-assets/_shared/mcp-tools/relations.ts +11 -12
- package/dist/server-assets/_shared/mcp-tools/restore-document.ts +4 -10
- package/dist/server-assets/_shared/mcp-tools/search.ts +3 -6
- package/dist/server-assets/_shared/mcp-tools/set-document-metadata.ts +4 -10
- package/dist/server-assets/_shared/mcp-tools/set-document-projects.ts +3 -6
- package/dist/server-assets/db/migrations/0031_review_workflow_toggle.sql +4 -2
- package/dist/server-assets/db/rpcs.sql +19 -12
- package/dist/server-assets/db/schema.sql +4 -4
- package/dist/server-assets/supabase/functions/cerefox-mcp/index.ts +6 -6
- package/docs/guides/cli.md +11 -11
- package/docs/guides/configuration.md +33 -24
- package/docs/guides/connect-agents.md +6 -6
- package/docs/guides/upgrading.md +11 -0
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import { logUsage } from "./_utils.ts";
|
|
16
16
|
import { McpInvalidParams, type ToolContext, type ToolDefinition } from "./types.ts";
|
|
17
17
|
import type { MCPSupabaseClient } from "./types.ts";
|
|
18
|
+
import { AUTHOR_PARAM_READ, AUTHOR_PARAM_WRITE, DEFAULT_IDENTITY, callerIdentity } from "./identity.ts";
|
|
18
19
|
|
|
19
20
|
/** Relation types that carry behaviour; any other string is accepted too. */
|
|
20
21
|
const KNOWN_TYPES =
|
|
@@ -44,7 +45,7 @@ async function setHandler(
|
|
|
44
45
|
p_source_id: source,
|
|
45
46
|
p_target_id: target,
|
|
46
47
|
p_rel_type: relType,
|
|
47
|
-
p_author: (args
|
|
48
|
+
p_author: callerIdentity(args) ?? DEFAULT_IDENTITY,
|
|
48
49
|
p_author_type: "agent",
|
|
49
50
|
p_metadata: (args.metadata as Record<string, unknown> | undefined) ?? {},
|
|
50
51
|
});
|
|
@@ -57,7 +58,7 @@ async function setHandler(
|
|
|
57
58
|
logUsage(supabase, {
|
|
58
59
|
operation: "set_relation",
|
|
59
60
|
accessPath: ctx.accessPath,
|
|
60
|
-
requestor: args
|
|
61
|
+
requestor: callerIdentity(args),
|
|
61
62
|
document_id: source,
|
|
62
63
|
});
|
|
63
64
|
|
|
@@ -103,8 +104,7 @@ export const setRelationTool: ToolDefinition = {
|
|
|
103
104
|
type: "object",
|
|
104
105
|
description: "Optional JSON context for the edge (note, confidence, …)",
|
|
105
106
|
},
|
|
106
|
-
author:
|
|
107
|
-
requestor: { type: "string", description: "Name of the agent making this request" },
|
|
107
|
+
author: AUTHOR_PARAM_WRITE,
|
|
108
108
|
},
|
|
109
109
|
},
|
|
110
110
|
handler: setHandler,
|
|
@@ -126,7 +126,7 @@ async function deleteHandler(
|
|
|
126
126
|
p_source_id: source,
|
|
127
127
|
p_target_id: target,
|
|
128
128
|
p_rel_type: relType,
|
|
129
|
-
p_author: (args
|
|
129
|
+
p_author: callerIdentity(args) ?? DEFAULT_IDENTITY,
|
|
130
130
|
p_author_type: "agent",
|
|
131
131
|
});
|
|
132
132
|
if (error) throw new Error(`RPC error: ${error.message}`);
|
|
@@ -135,7 +135,7 @@ async function deleteHandler(
|
|
|
135
135
|
logUsage(supabase, {
|
|
136
136
|
operation: "delete_relation",
|
|
137
137
|
accessPath: ctx.accessPath,
|
|
138
|
-
requestor: args
|
|
138
|
+
requestor: callerIdentity(args),
|
|
139
139
|
document_id: source,
|
|
140
140
|
});
|
|
141
141
|
|
|
@@ -166,8 +166,7 @@ export const deleteRelationTool: ToolDefinition = {
|
|
|
166
166
|
source_id: { type: "string", description: "UUID of the source document" },
|
|
167
167
|
target_id: { type: "string", description: "UUID of the target document" },
|
|
168
168
|
rel_type: { type: "string", description: "Relation type to remove" },
|
|
169
|
-
author:
|
|
170
|
-
requestor: { type: "string", description: "Name of the agent making this request" },
|
|
169
|
+
author: AUTHOR_PARAM_WRITE,
|
|
171
170
|
},
|
|
172
171
|
},
|
|
173
172
|
handler: deleteHandler,
|
|
@@ -197,7 +196,7 @@ async function getRelationsHandler(
|
|
|
197
196
|
logUsage(supabase, {
|
|
198
197
|
operation: "get_relations",
|
|
199
198
|
accessPath: ctx.accessPath,
|
|
200
|
-
requestor: args
|
|
199
|
+
requestor: callerIdentity(args),
|
|
201
200
|
document_id: docId,
|
|
202
201
|
result_count: rows.length,
|
|
203
202
|
});
|
|
@@ -231,7 +230,7 @@ export const getRelationsTool: ToolDefinition = {
|
|
|
231
230
|
required: ["document_id"],
|
|
232
231
|
properties: {
|
|
233
232
|
document_id: { type: "string", description: "UUID of the document" },
|
|
234
|
-
|
|
233
|
+
author: AUTHOR_PARAM_READ,
|
|
235
234
|
},
|
|
236
235
|
},
|
|
237
236
|
handler: getRelationsHandler,
|
|
@@ -268,7 +267,7 @@ async function getNeighborsHandler(
|
|
|
268
267
|
logUsage(supabase, {
|
|
269
268
|
operation: "get_neighbors",
|
|
270
269
|
accessPath: ctx.accessPath,
|
|
271
|
-
requestor: args
|
|
270
|
+
requestor: callerIdentity(args),
|
|
272
271
|
document_id: docId,
|
|
273
272
|
result_count: rows.length,
|
|
274
273
|
});
|
|
@@ -307,7 +306,7 @@ export const getNeighborsTool: ToolDefinition = {
|
|
|
307
306
|
from_time: { type: "string", description: "ISO-8601: only neighbours created on/after" },
|
|
308
307
|
to_time: { type: "string", description: "ISO-8601: only neighbours created on/before" },
|
|
309
308
|
limit: { type: "integer", description: "Max documents to return (default 50, max 200)" },
|
|
310
|
-
|
|
309
|
+
author: AUTHOR_PARAM_READ,
|
|
311
310
|
},
|
|
312
311
|
},
|
|
313
312
|
handler: getNeighborsHandler,
|
|
@@ -21,6 +21,7 @@ import type { MCPSupabaseClient } from "./types.ts";
|
|
|
21
21
|
|
|
22
22
|
import { isDocumentNotFoundError, isMissingFunctionError, logUsage } from "./_utils.ts";
|
|
23
23
|
import { McpInvalidParams, type ToolContext, type ToolDefinition } from "./types.ts";
|
|
24
|
+
import { AUTHOR_PARAM_WRITE, DEFAULT_IDENTITY, callerIdentity } from "./identity.ts";
|
|
24
25
|
|
|
25
26
|
async function handler(
|
|
26
27
|
supabase: MCPSupabaseClient,
|
|
@@ -32,7 +33,7 @@ async function handler(
|
|
|
32
33
|
|
|
33
34
|
if (!document_id) throw new McpInvalidParams("document_id is required");
|
|
34
35
|
|
|
35
|
-
const author = (args
|
|
36
|
+
const author = callerIdentity(args);
|
|
36
37
|
// Derived from the transport, never taken from the caller: an agent must not
|
|
37
38
|
// be able to record itself as a user. Matches the delete handler.
|
|
38
39
|
const authorType = ctx.accessPath === "cli" ? "user" : "agent";
|
|
@@ -81,7 +82,7 @@ async function handler(
|
|
|
81
82
|
logUsage(supabase, {
|
|
82
83
|
operation: "restore",
|
|
83
84
|
accessPath: ctx.accessPath,
|
|
84
|
-
requestor:
|
|
85
|
+
requestor: author,
|
|
85
86
|
document_id,
|
|
86
87
|
result_count: 1,
|
|
87
88
|
});
|
|
@@ -116,14 +117,7 @@ export const restoreDocumentTool: ToolDefinition = {
|
|
|
116
117
|
description:
|
|
117
118
|
"Why this document is being restored. Recorded in the audit-log entry. Short and specific beats long.",
|
|
118
119
|
},
|
|
119
|
-
author:
|
|
120
|
-
type: "string",
|
|
121
|
-
description: "Who is making this change. Recorded in the audit log.",
|
|
122
|
-
},
|
|
123
|
-
requestor: {
|
|
124
|
-
type: "string",
|
|
125
|
-
description: "Name of the agent or user making this request. Recorded in the usage log.",
|
|
126
|
-
},
|
|
120
|
+
author: AUTHOR_PARAM_WRITE,
|
|
127
121
|
},
|
|
128
122
|
},
|
|
129
123
|
handler,
|
|
@@ -22,6 +22,7 @@ import { applyByteBudget, getConfiguredMinSearchScore, getConfiguredSearchAlpha,
|
|
|
22
22
|
getMaxResponseBytes, getMinTermCoverage, logUsage } from "./_utils.ts";
|
|
23
23
|
import { lookupProjectId } from "./_projects.ts";
|
|
24
24
|
import { McpInvalidParams, type ToolContext, type ToolDefinition } from "./types.ts";
|
|
25
|
+
import { AUTHOR_PARAM_READ, callerIdentity } from "./identity.ts";
|
|
25
26
|
|
|
26
27
|
async function handler(
|
|
27
28
|
supabase: MCPSupabaseClient,
|
|
@@ -135,7 +136,7 @@ async function handler(
|
|
|
135
136
|
logUsage(supabase, {
|
|
136
137
|
operation: "search",
|
|
137
138
|
accessPath: ctx.accessPath,
|
|
138
|
-
requestor: args
|
|
139
|
+
requestor: callerIdentity(args),
|
|
139
140
|
query_text: query,
|
|
140
141
|
project_id: projectId,
|
|
141
142
|
result_count: accepted.length,
|
|
@@ -244,11 +245,7 @@ export const searchTool: ToolDefinition = {
|
|
|
244
245
|
description:
|
|
245
246
|
"Optional response size budget in bytes. Results are dropped whole until the budget is satisfied; a truncated flag is set when results are dropped. Defaults to the server maximum (200000). Pass a smaller value if your context window is limited. Values above the server maximum are silently capped.",
|
|
246
247
|
},
|
|
247
|
-
|
|
248
|
-
type: "string",
|
|
249
|
-
description:
|
|
250
|
-
'Name of the agent or user making this request (e.g., "Claude Code", "archiver"). Recorded in the usage log for attribution. Defaults to "mcp-agent" if not provided. May be enforced via server config.',
|
|
251
|
-
},
|
|
248
|
+
author: AUTHOR_PARAM_READ,
|
|
252
249
|
},
|
|
253
250
|
},
|
|
254
251
|
handler,
|
|
@@ -21,6 +21,7 @@ import type { MCPSupabaseClient } from "./types.ts";
|
|
|
21
21
|
|
|
22
22
|
import { logUsage } from "./_utils.ts";
|
|
23
23
|
import { McpInvalidParams, type ToolContext, type ToolDefinition } from "./types.ts";
|
|
24
|
+
import { AUTHOR_PARAM_WRITE, DEFAULT_IDENTITY, callerIdentity } from "./identity.ts";
|
|
24
25
|
|
|
25
26
|
async function handler(
|
|
26
27
|
supabase: MCPSupabaseClient,
|
|
@@ -48,7 +49,7 @@ async function handler(
|
|
|
48
49
|
);
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
const author = (args
|
|
52
|
+
const author = callerIdentity(args);
|
|
52
53
|
// Derived from the transport, never taken from the caller: an agent must not
|
|
53
54
|
// be able to record itself as a user. Matches the partial-edit handlers.
|
|
54
55
|
const authorType = ctx.accessPath === "cli" ? "user" : "agent";
|
|
@@ -71,7 +72,7 @@ async function handler(
|
|
|
71
72
|
logUsage(supabase, {
|
|
72
73
|
operation: "update_metadata",
|
|
73
74
|
accessPath: ctx.accessPath,
|
|
74
|
-
requestor:
|
|
75
|
+
requestor: author,
|
|
75
76
|
document_id,
|
|
76
77
|
result_count: 1,
|
|
77
78
|
});
|
|
@@ -119,14 +120,7 @@ export const setDocumentMetadataTool: ToolDefinition = {
|
|
|
119
120
|
description:
|
|
120
121
|
"Set the metadata to EXACTLY this object, discarding any key not listed. Defaults to false (merge). Use only when you mean to reset a document's tags wholesale.",
|
|
121
122
|
},
|
|
122
|
-
author:
|
|
123
|
-
type: "string",
|
|
124
|
-
description: "Who is making this change. Recorded in the audit log.",
|
|
125
|
-
},
|
|
126
|
-
requestor: {
|
|
127
|
-
type: "string",
|
|
128
|
-
description: "Name of the agent or user making this request. Recorded in the usage log.",
|
|
129
|
-
},
|
|
123
|
+
author: AUTHOR_PARAM_WRITE,
|
|
130
124
|
},
|
|
131
125
|
},
|
|
132
126
|
handler,
|
|
@@ -13,6 +13,7 @@ import type { MCPSupabaseClient } from "./types.ts";
|
|
|
13
13
|
|
|
14
14
|
import { replaceDocumentProjects } from "./_projects.ts";
|
|
15
15
|
import { McpInvalidParams, type ToolContext, type ToolDefinition } from "./types.ts";
|
|
16
|
+
import { AUTHOR_PARAM_WRITE, DEFAULT_IDENTITY, callerIdentity } from "./identity.ts";
|
|
16
17
|
|
|
17
18
|
async function handler(
|
|
18
19
|
supabase: MCPSupabaseClient,
|
|
@@ -21,7 +22,7 @@ async function handler(
|
|
|
21
22
|
): Promise<string> {
|
|
22
23
|
const document_id = (args.document_id as string | undefined)?.trim();
|
|
23
24
|
const project_names_raw = args.project_names;
|
|
24
|
-
const author = (args
|
|
25
|
+
const author = callerIdentity(args) ?? DEFAULT_IDENTITY;
|
|
25
26
|
|
|
26
27
|
if (!document_id) {
|
|
27
28
|
throw new McpInvalidParams(
|
|
@@ -96,11 +97,7 @@ export const setDocumentProjectsTool: ToolDefinition = {
|
|
|
96
97
|
description:
|
|
97
98
|
"Explicit list of project names. Each created if absent. Order is preserved. Empty list = remove from all projects.",
|
|
98
99
|
},
|
|
99
|
-
author:
|
|
100
|
-
type: "string",
|
|
101
|
-
description:
|
|
102
|
-
'Agent or tool name recorded in the audit log. Defaults to "mcp-agent". May be enforced via server config.',
|
|
103
|
-
},
|
|
100
|
+
author: AUTHOR_PARAM_WRITE,
|
|
104
101
|
},
|
|
105
102
|
},
|
|
106
103
|
handler,
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
-- write ever overrides a value an operator has set (ON CONFLICT DO NOTHING).
|
|
8
8
|
--
|
|
9
9
|
-- The decision "agent write → pending_review" moves out of the six client call
|
|
10
|
-
-- sites and into cerefox_ingest_document
|
|
11
|
-
--
|
|
10
|
+
-- sites and into cerefox_ingest_document. That RPC lives in rpcs.sql, which
|
|
11
|
+
-- `cerefox server deploy` re-applies. (0.16.0 also had the RPC read this flag
|
|
12
|
+
-- on write and store 'approved' for everyone while off; 0.16.1 removed that —
|
|
13
|
+
-- the flag governs visibility only, the stored value follows author_type.)
|
|
12
14
|
--
|
|
13
15
|
-- #240: cerefox_hybrid_search / cerefox_search_docs gain p_review_status so a
|
|
14
16
|
-- filtered search is applied before the limit, not after. A new argument is a
|
|
@@ -1395,9 +1395,10 @@ $$;
|
|
|
1395
1395
|
-- update keeps the existing metadata (v0.11.1). Pass '{}'
|
|
1396
1396
|
-- explicitly to clear all metadata.
|
|
1397
1397
|
-- p_review_status : ACCEPTED AND IGNORED since 0.16.0 (#241). The status is
|
|
1398
|
-
-- decided here from p_author_type
|
|
1399
|
-
--
|
|
1400
|
-
-- behaves the same
|
|
1398
|
+
-- decided here from p_author_type alone (agent →
|
|
1399
|
+
-- pending_review, user → approved), so every transport
|
|
1400
|
+
-- behaves the same. The `review_workflow_enabled` flag
|
|
1401
|
+
-- only governs what surfaces show (0.16.1).
|
|
1401
1402
|
-- Kept in the signature so no caller breaks.
|
|
1402
1403
|
-- p_chunks : JSONB array of chunk objects, each with:
|
|
1403
1404
|
-- chunk_index, heading_path, heading_level, title,
|
|
@@ -1583,15 +1584,17 @@ BEGIN
|
|
|
1583
1584
|
USING ERRCODE = '22023'; -- deterministic; never a retryable SQLSTATE
|
|
1584
1585
|
END IF;
|
|
1585
1586
|
|
|
1586
|
-
-- Review status is decided HERE, not by the caller (#241)
|
|
1587
|
-
--
|
|
1588
|
-
--
|
|
1589
|
-
--
|
|
1590
|
-
--
|
|
1591
|
-
--
|
|
1592
|
-
--
|
|
1587
|
+
-- Review status is decided HERE, not by the caller (#241), from the
|
|
1588
|
+
-- author type alone: an agent write is 'pending_review', a person's is
|
|
1589
|
+
-- 'approved'. The `review_workflow_enabled` flag is deliberately NOT
|
|
1590
|
+
-- consulted (0.16.1): it governs what the surfaces show and enforce, not
|
|
1591
|
+
-- what is stored, so a store that turns the workflow off and later back on
|
|
1592
|
+
-- sees exactly the statuses it would have had all along. 0.16.0 wrote
|
|
1593
|
+
-- 'approved' for every author while the flag was off; that made a stored
|
|
1594
|
+
-- 'approved' mean two different things depending on when it was written.
|
|
1595
|
+
-- p_review_status is not consulted either — six clients used to compute
|
|
1596
|
+
-- it and they could not have agreed on a store-level policy.
|
|
1593
1597
|
v_status := CASE
|
|
1594
|
-
WHEN NOT cerefox_config_bool('review_workflow_enabled', FALSE) THEN 'approved'
|
|
1595
1598
|
WHEN p_author_type = 'agent' THEN 'pending_review'
|
|
1596
1599
|
ELSE 'approved'
|
|
1597
1600
|
END;
|
|
@@ -3088,6 +3091,10 @@ SET search_path = public, pg_catalog
|
|
|
3088
3091
|
AS $$
|
|
3089
3092
|
-- Keep in lockstep with the `@version:` marker in schema.sql (cut_release.ts
|
|
3090
3093
|
-- enforces it). Bump whenever schema.sql OR rpcs.sql changes.
|
|
3094
|
+
-- 0.16.1 (v1.13.1): cerefox_ingest_document no longer consults
|
|
3095
|
+
-- `review_workflow_enabled` — review_status follows author_type whatever
|
|
3096
|
+
-- the flag says; the flag governs visibility/enforcement only. RPC-only,
|
|
3097
|
+
-- no migration (server deploy re-applies rpcs.sql).
|
|
3091
3098
|
-- 0.16.0 (#241, #240): `review_workflow_enabled` config key (seeded false
|
|
3092
3099
|
-- on fresh installs, true by migration 0031 on existing ones);
|
|
3093
3100
|
-- cerefox_ingest_document decides review_status itself from author_type
|
|
@@ -3117,7 +3124,7 @@ AS $$
|
|
|
3117
3124
|
-- 0.11.0 supersedes 0.10.6 (v1.2.1, #191): this branch carries that fix plus
|
|
3118
3125
|
-- the partial-edit surface, and both migrations (0019, 0020) are in the
|
|
3119
3126
|
-- sequence, so a store deploying this gets everything from both lines.
|
|
3120
|
-
SELECT '0.16.
|
|
3127
|
+
SELECT '0.16.1'::TEXT;
|
|
3121
3128
|
$$;
|
|
3122
3129
|
|
|
3123
3130
|
-- ── cerefox_find_dead_links ──────────────────────────────────────────────────
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
-- Requires extensions: vector (pgvector), uuid-ossp
|
|
6
6
|
-- These are enabled at the top of db_deploy.py before this file is applied.
|
|
7
7
|
--
|
|
8
|
-
-- @version: 0.16.
|
|
8
|
+
-- @version: 0.16.1
|
|
9
9
|
-- The `@version` marker above is read by the schema-version-mismatch banner
|
|
10
10
|
-- (see /api/v1/schema-version). Bump it whenever schema.sql OR rpcs.sql
|
|
11
11
|
-- changes in a way that requires `cerefox server deploy` to be re-run —
|
|
@@ -56,9 +56,9 @@ CREATE TABLE IF NOT EXISTS cerefox_documents (
|
|
|
56
56
|
-- review_status: human governance flag. 'approved' = validated by human,
|
|
57
57
|
-- 'pending_review' = modified by agent, not yet reviewed.
|
|
58
58
|
-- Content is searchable in both states. Written ONLY by
|
|
59
|
-
-- cerefox_ingest_document,
|
|
60
|
-
-- (#241)
|
|
61
|
-
--
|
|
59
|
+
-- cerefox_ingest_document, from author_type alone. The store-level
|
|
60
|
+
-- `review_workflow_enabled` flag (#241) governs whether any surface shows
|
|
61
|
+
-- or enforces the column; it never changes what is stored (0.16.1).
|
|
62
62
|
review_status TEXT NOT NULL DEFAULT 'approved',
|
|
63
63
|
-- lifecycle_status: where this document stands relative to the graph —
|
|
64
64
|
-- 'active' | 'superseded' | 'stale' | 'archived'. Distinct from
|
|
@@ -105,12 +105,12 @@ async function handleToolsCall(
|
|
|
105
105
|
|
|
106
106
|
// Configurable caller identity enforcement.
|
|
107
107
|
// When require_requestor_identity is "true" in cerefox_config, all tool calls
|
|
108
|
-
// must include
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const identityValue = args
|
|
108
|
+
// must include the caller's identity; when requestor_identity_format is set,
|
|
109
|
+
// the value must match the regex. Since v1.13.1 every tool takes `author`
|
|
110
|
+
// and silently accepts `requestor` as the pre-1.13.1 alias (mirrors
|
|
111
|
+
// `callerIdentity()` in _shared/mcp-tools/identity.ts).
|
|
112
|
+
const identityParam = "author";
|
|
113
|
+
const identityValue = (args.author ?? args.requestor) as string | undefined;
|
|
114
114
|
|
|
115
115
|
// deno-lint-ignore no-explicit-any
|
|
116
116
|
const supabase: any = makeSupabaseClient();
|
package/docs/guides/cli.md
CHANGED
|
@@ -50,7 +50,7 @@ cerefox document ingest --paste --title "<title>" [OPTIONS] # stdin
|
|
|
50
50
|
| `--last-write-wins` | — | flag | off | Skip the concurrency check and overwrite regardless of concurrent changes. For re-sync flows where an external source of truth makes conflicts meaningless. Recorded in the audit log. |
|
|
51
51
|
| `--source` | — | str | `paste` / `file` | Source label recorded on the document. |
|
|
52
52
|
| `--author` | — | str | `CEREFOX_AUTHOR_NAME` or `unknown` | Audit-log author identity. |
|
|
53
|
-
| `--author-type` | — | `user`\|`agent` | `CEREFOX_AUTHOR_TYPE` or `user` | Caller type. Agent writes
|
|
53
|
+
| `--author-type` | — | `user`\|`agent` | `CEREFOX_AUTHOR_TYPE` or `user` | Caller type. Agent writes are recorded `pending_review`, user writes `approved`; the store's `review_workflow_enabled` flag decides whether that status is shown. |
|
|
54
54
|
|
|
55
55
|
**Examples**:
|
|
56
56
|
```bash
|
|
@@ -811,21 +811,21 @@ Every MCP parameter has an exact-name CLI flag (kebab-cased). Short forms exist
|
|
|
811
811
|
|
|
812
812
|
| MCP tool | CLI command |
|
|
813
813
|
|---|---|
|
|
814
|
-
| `cerefox_search(query, match_count, project_name, metadata_filter,
|
|
814
|
+
| `cerefox_search(query, match_count, project_name, metadata_filter, author)` | `cerefox search "<q>" --match-count N --project-name <name> --metadata-filter '<json>' --requestor <name>` |
|
|
815
815
|
| `cerefox_ingest(title, content, project_name, metadata, update_if_exists, document_id, expected_content_hash, last_write_wins, source, author, author_type)` (file) | `cerefox document ingest <path> --title <t> --project-name <n> --metadata '<json>' --update-if-exists\|--document-id <uuid> --expected-content-hash <hash>\|--last-write-wins --source <s> --author <a> --author-type <t>` |
|
|
816
816
|
| `cerefox_ingest(...)` (paste) | `printf '...' \| cerefox document ingest --paste --title "<t>"` (same flags) |
|
|
817
|
-
| `cerefox_get_document(document_id, version_id, outline,
|
|
818
|
-
| `cerefox_insert(document_id, text, position, anchor_heading, section_part, expected_content_hash,
|
|
819
|
-
| `cerefox_edit(document_id, operations, expected_content_hash,
|
|
820
|
-
| `cerefox_list_versions(document_id,
|
|
821
|
-
| `cerefox_list_projects(
|
|
817
|
+
| `cerefox_get_document(document_id, version_id, outline, author)` | `cerefox document get <id> --version-id <vid> --outline --requestor <name>` |
|
|
818
|
+
| `cerefox_insert(document_id, text, position, anchor_heading, section_part, expected_content_hash, author)` | `cerefox document insert <id> -t <text\|-\|@file> -p <position> -a <anchor> --section-part <part> --expected-hash <hash> --requestor <name>` |
|
|
819
|
+
| `cerefox_edit(document_id, operations, expected_content_hash, author)` | `cerefox document edit-parts <id> -o <json\|-\|@file> --expected-hash <hash> --requestor <name>` |
|
|
820
|
+
| `cerefox_list_versions(document_id, author)` | `cerefox document version list <id> --requestor <name>` |
|
|
821
|
+
| `cerefox_list_projects(author)` | `cerefox project list --requestor <name>` |
|
|
822
822
|
| `cerefox_set_document_projects(document_id, project_names, author)` | `cerefox document set-projects <id> <name...> --author <a> --author-type <t>` (or `--clear` to remove all) |
|
|
823
823
|
| `cerefox_list_metadata_keys()` | `cerefox metadata keys` |
|
|
824
|
-
| `cerefox_metadata_search(metadata_filter, project_name, updated_since, created_since, limit, include_content,
|
|
825
|
-
| `cerefox_get_audit_log(document_id,
|
|
824
|
+
| `cerefox_metadata_search(metadata_filter, project_name, updated_since, created_since, limit, include_content, author)` | `cerefox metadata search --metadata-filter '<json>' --project-name <n> --updated-since <iso> --created-since <iso> --limit N --include-content --requestor <name>` |
|
|
825
|
+
| `cerefox_get_audit_log(document_id, by_author, operation, since, until, limit, author)` | `cerefox audit list --document-id <id> --author <a> --operation <op> --since <iso> --until <iso> --limit N --requestor <name>` |
|
|
826
826
|
| `cerefox_set_document_metadata(document_id, metadata, replace, author)` | `cerefox document set-metadata <id> --set key=value` (also `--remove key`, `--json '<json>'`, `--replace`) |
|
|
827
|
-
| `cerefox_delete_document(document_id, expected_content_hash, reason, author
|
|
828
|
-
| `cerefox_restore_document(document_id, reason, author
|
|
827
|
+
| `cerefox_delete_document(document_id, expected_content_hash, reason, author)` | `cerefox document delete <id> --reason <text> --author <a> --author-type <t> --yes` (confirms interactively instead of requiring the hash) |
|
|
828
|
+
| `cerefox_restore_document(document_id, reason, author)` | `cerefox document restore <id> --reason <text> --author <a> --author-type <t>` |
|
|
829
829
|
|
|
830
830
|
## CLI ↔ MCP parity matrix
|
|
831
831
|
|
|
@@ -480,14 +480,20 @@ cerefox config get usage_tracking_enabled
|
|
|
480
480
|
|
|
481
481
|
## Requestor Identity Enforcement
|
|
482
482
|
|
|
483
|
-
By default, the `
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
483
|
+
By default, the `author` parameter on the MCP tools is optional. When omitted, it
|
|
484
|
+
defaults to `"mcp-agent"`. This means the usage log shows `"mcp-agent"` for all calls
|
|
485
|
+
that don't explicitly identify themselves, making analytics less useful in
|
|
486
|
+
multi-agent setups.
|
|
487
487
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
488
|
+
Since v1.13.1 every MCP tool takes the caller's identity as **`author`**, reads and
|
|
489
|
+
writes alike; `requestor` (the pre-1.13.1 name on most tools) is still accepted as
|
|
490
|
+
a silent alias. (On `cerefox_get_audit_log` the entries filter, formerly `author`,
|
|
491
|
+
is now `by_author`.) The primitive Edge Functions used by GPT Actions keep their
|
|
492
|
+
original body fields (`requestor` on reads, `author` on ingest).
|
|
493
|
+
|
|
494
|
+
You can optionally enforce caller identification so that tool calls must include
|
|
495
|
+
an identity. Calls without one receive a JSON-RPC `-32602` error with a helpful
|
|
496
|
+
message telling the agent what to provide.
|
|
491
497
|
|
|
492
498
|
### What it actually covers
|
|
493
499
|
|
|
@@ -516,7 +522,7 @@ tenth copy of the same block. Raise an issue rather than assuming it is there.
|
|
|
516
522
|
### Enabling enforcement
|
|
517
523
|
|
|
518
524
|
```bash
|
|
519
|
-
# Require all MCP tool calls to include requestor
|
|
525
|
+
# Require all MCP tool calls to include author (or the requestor alias)
|
|
520
526
|
cerefox config set require_requestor_identity true
|
|
521
527
|
|
|
522
528
|
# Optionally override the default naming format (regex)
|
|
@@ -532,7 +538,7 @@ cerefox config set requestor_identity_format "^[a-z]+:[a-z]+$"
|
|
|
532
538
|
| `^[a-z]+:[a-z]+$` | `conclave:agent` format only | Multi-conclave setups (e.g., `personal:steward`) |
|
|
533
539
|
| (empty string) | Any non-empty string | No format restriction |
|
|
534
540
|
|
|
535
|
-
The format is applied to
|
|
541
|
+
The format is applied to whichever identity field the call carries (`author`, or the `requestor` alias).
|
|
536
542
|
|
|
537
543
|
### Disabling enforcement
|
|
538
544
|
|
|
@@ -540,7 +546,7 @@ The format is applied to both `requestor` (read tools) and `author` (ingest).
|
|
|
540
546
|
cerefox config set require_requestor_identity false
|
|
541
547
|
```
|
|
542
548
|
|
|
543
|
-
When disabled, the
|
|
549
|
+
When disabled, the identity parameter remains optional with the `"mcp-agent"` default.
|
|
544
550
|
This is the default state -- no configuration needed for backward compatibility.
|
|
545
551
|
|
|
546
552
|
---
|
|
@@ -570,20 +576,23 @@ cerefox config set review_workflow_enabled true # or false; also in Settings
|
|
|
570
576
|
cerefox doctor # prints "review workflow ON …" / "OFF …"
|
|
571
577
|
```
|
|
572
578
|
|
|
573
|
-
**With the workflow off, the feature is
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
anything and flipping it on does not
|
|
584
|
-
`pending_review` are still pending, and
|
|
585
|
-
|
|
586
|
-
|
|
579
|
+
**With the workflow off, the feature is hidden, not dimmed.** No surface
|
|
580
|
+
shows or enforces a `review_status`: the web pill, badges and search chip do
|
|
581
|
+
not render; the CLI drops its `status` column; API, MCP and Edge Function rows
|
|
582
|
+
carry no `review_status` key; `GET /api/v1/search?review_status=…` is a `400`;
|
|
583
|
+
and `POST /api/v1/documents/{id}/review-status` is a `404`.
|
|
584
|
+
|
|
585
|
+
**The flag hides; it never rewrites.** Writes are recorded the same way in
|
|
586
|
+
both states — agent writes `pending_review`, user writes `approved`, decided
|
|
587
|
+
once inside the `cerefox_ingest_document` RPC so every access path (CLI, local
|
|
588
|
+
and remote MCP, Edge Functions, web) behaves alike, including older clients.
|
|
589
|
+
Flipping the flag off does not approve anything and flipping it on does not
|
|
590
|
+
queue anything; documents that were `pending_review` are still pending, and a
|
|
591
|
+
document an agent wrote while the workflow was off is pending too, shown as
|
|
592
|
+
such the moment the flag is on again. (v1.13.0 stored `approved` for every
|
|
593
|
+
write while off; v1.13.1 corrected that.) Attribution and the audit log are
|
|
594
|
+
unaffected in both states — who wrote what is always recorded. Config changes
|
|
595
|
+
are audited too.
|
|
587
596
|
|
|
588
597
|
Design: [`docs/specs/review-workflow-toggle.md`](../specs/review-workflow-toggle.md).
|
|
589
598
|
|
|
@@ -221,7 +221,7 @@ You have access to a personal knowledge base via Cerefox MCP tools.
|
|
|
221
221
|
When answering questions, always call cerefox_search first with a relevant query.
|
|
222
222
|
Cite doc_title for every claim drawn from the knowledge base.
|
|
223
223
|
Use cerefox_ingest to save anything the user asks you to remember.
|
|
224
|
-
Always set
|
|
224
|
+
Always set the author parameter to identify yourself.
|
|
225
225
|
For the full tool reference, search Cerefox for "How AI Agents Use Cerefox".
|
|
226
226
|
```
|
|
227
227
|
|
|
@@ -638,7 +638,7 @@ In the action editor, paste this schema (replace `<your-project-ref>`):
|
|
|
638
638
|
openapi: 3.1.0
|
|
639
639
|
info:
|
|
640
640
|
title: Cerefox Knowledge Base
|
|
641
|
-
version: 3.4.
|
|
641
|
+
version: 3.4.1
|
|
642
642
|
servers:
|
|
643
643
|
- url: https://<your-project-ref>.supabase.co/functions/v1
|
|
644
644
|
paths:
|
|
@@ -798,10 +798,10 @@ paths:
|
|
|
798
798
|
default: agent
|
|
799
799
|
description: >
|
|
800
800
|
Whether this write is from a human user or an AI agent.
|
|
801
|
-
Always recorded for attribution.
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
801
|
+
Always recorded for attribution. Agent writes are recorded
|
|
802
|
+
pending_review and user writes approved; the store's review
|
|
803
|
+
workflow flag (review_workflow_enabled) only decides whether
|
|
804
|
+
that status is shown.
|
|
805
805
|
responses:
|
|
806
806
|
'200':
|
|
807
807
|
description: >
|
package/docs/guides/upgrading.md
CHANGED
|
@@ -77,6 +77,14 @@ schema-requiring release.
|
|
|
77
77
|
> `cerefox config set review_workflow_enabled false` (or Settings → Governance)
|
|
78
78
|
> if nobody reviews the queue. See
|
|
79
79
|
> [configuration.md → Review Workflow](configuration.md#review-workflow).
|
|
80
|
+
>
|
|
81
|
+
> **v1.13.1** (schema 0.16.1) corrects one thing in the above: the flag
|
|
82
|
+
> governs only what is *shown*. v1.13.0 also stored `approved` for every
|
|
83
|
+
> write while the flag was off; v1.13.1 records agent writes as
|
|
84
|
+
> `pending_review` regardless, so turning the workflow back on shows the
|
|
85
|
+
> statuses the store would have had all along. It is an RPC-only change —
|
|
86
|
+
> `cerefox server deploy` (or `--schema-only`) picks it up; nothing refuses
|
|
87
|
+
> to run until you do, but a 0.16.0 server keeps the v1.13.0 write behaviour.
|
|
80
88
|
|
|
81
89
|
> ### Upgrading to v1.1.0 — `cerefox server deploy` is required
|
|
82
90
|
>
|
|
@@ -186,6 +194,9 @@ knowing about:
|
|
|
186
194
|
document must be restored before its content can be updated.
|
|
187
195
|
- **v1.13.0 — the review workflow is a store setting.** Upgraded stores keep
|
|
188
196
|
it on; fresh installs start with it off. See the callout above.
|
|
197
|
+
- **v1.13.1 — the flag hides, it does not rewrite.** Agent writes are
|
|
198
|
+
recorded `pending_review` whether or not the workflow is shown (v1.13.0
|
|
199
|
+
stored `approved` while off). Redeploy to pick it up.
|
|
189
200
|
|
|
190
201
|
## Notable: v1.8.0 storage reclaim (migration 0027)
|
|
191
202
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cerefox/memory",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.1",
|
|
4
4
|
"description": "Cerefox — user-owned shared memory for AI agents. CLI + stdio MCP server + web UI + ingestion for a knowledge base on your own Supabase project (or fully self-hosted with Cerefox Local).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/fstamatelopoulos/cerefox",
|