@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.
Files changed (31) hide show
  1. package/AGENT_GUIDE.md +26 -26
  2. package/AGENT_QUICK_REFERENCE.md +9 -9
  3. package/dist/bin/cerefox.js +93 -113
  4. package/dist/server-assets/_shared/ef-meta/index.ts +3 -3
  5. package/dist/server-assets/_shared/mcp-tools/audit-log.ts +10 -8
  6. package/dist/server-assets/_shared/mcp-tools/delete-document.ts +4 -10
  7. package/dist/server-assets/_shared/mcp-tools/feature-flags.ts +4 -3
  8. package/dist/server-assets/_shared/mcp-tools/get-document.ts +3 -6
  9. package/dist/server-assets/_shared/mcp-tools/get-help-content.ts +3 -3
  10. package/dist/server-assets/_shared/mcp-tools/get-help.ts +3 -6
  11. package/dist/server-assets/_shared/mcp-tools/identity.ts +48 -0
  12. package/dist/server-assets/_shared/mcp-tools/ingest.ts +3 -6
  13. package/dist/server-assets/_shared/mcp-tools/list-metadata-keys.ts +3 -6
  14. package/dist/server-assets/_shared/mcp-tools/list-projects.ts +3 -6
  15. package/dist/server-assets/_shared/mcp-tools/list-versions.ts +3 -6
  16. package/dist/server-assets/_shared/mcp-tools/metadata-search.ts +3 -6
  17. package/dist/server-assets/_shared/mcp-tools/partial-edits.ts +5 -10
  18. package/dist/server-assets/_shared/mcp-tools/relations.ts +11 -12
  19. package/dist/server-assets/_shared/mcp-tools/restore-document.ts +4 -10
  20. package/dist/server-assets/_shared/mcp-tools/search.ts +3 -6
  21. package/dist/server-assets/_shared/mcp-tools/set-document-metadata.ts +4 -10
  22. package/dist/server-assets/_shared/mcp-tools/set-document-projects.ts +3 -6
  23. package/dist/server-assets/db/migrations/0031_review_workflow_toggle.sql +4 -2
  24. package/dist/server-assets/db/rpcs.sql +19 -12
  25. package/dist/server-assets/db/schema.sql +4 -4
  26. package/dist/server-assets/supabase/functions/cerefox-mcp/index.ts +6 -6
  27. package/docs/guides/cli.md +11 -11
  28. package/docs/guides/configuration.md +33 -24
  29. package/docs/guides/connect-agents.md +6 -6
  30. package/docs/guides/upgrading.md +11 -0
  31. 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.author as string | undefined) ?? "mcp-agent",
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.requestor as string | undefined,
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: { type: "string", description: "Who is creating this relation" },
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.author as string | undefined) ?? "mcp-agent",
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.requestor as string | undefined,
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: { type: "string", description: "Who is removing this relation" },
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.requestor as string | undefined,
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
- requestor: { type: "string", description: "Name of the agent making this request" },
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.requestor as string | undefined,
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
- requestor: { type: "string", description: "Name of the agent making this request" },
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.author as string | undefined) ?? (args.requestor as string | undefined);
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: args.requestor as string | undefined,
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.requestor as string | undefined,
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
- requestor: {
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.author as string | undefined) ?? (args.requestor as string | undefined);
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: args.requestor as string | undefined,
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.author as string | undefined) ?? "mcp-agent";
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, which reads this flag. That RPC
11
- -- lives in rpcs.sql, which `cerefox server deploy` re-applies.
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 and the store's
1399
- -- `review_workflow_enabled` flag, so every transport
1400
- -- behaves the same and a toggle needs no client change.
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). With the
1587
- -- workflow on, an agent write is queued for a person to look at; with it
1588
- -- off, every write lands approved and no surface shows the column. The
1589
- -- fallback FALSE matches the fresh-install seed; migration 0031 seeds TRUE
1590
- -- on stores that predate the flag, so it only applies if the row is gone.
1591
- -- p_review_status is deliberately not consulted six clients used to
1592
- -- compute it and they could not have agreed on a store-level policy.
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.0'::TEXT;
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.0
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, which consults `review_workflow_enabled`
60
- -- (#241): with the workflow off every write lands 'approved' and every
61
- -- surface hides the column; existing values are left as they are.
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 a requestor (reads) or author (writes) parameter.
109
- // When requestor_identity_format is set, the value must match the regex.
110
- const identityParam = toolName === "cerefox_ingest" || toolName === "cerefox_set_document_projects"
111
- ? "author"
112
- : "requestor";
113
- const identityValue = args[identityParam] as string | undefined;
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();
@@ -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 land `pending_review` while the review workflow is on (`review_workflow_enabled`); `approved` otherwise. |
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, requestor)` | `cerefox search "<q>" --match-count N --project-name <name> --metadata-filter '<json>' --requestor <name>` |
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, requestor)` | `cerefox document get <id> --version-id <vid> --outline --requestor <name>` |
818
- | `cerefox_insert(document_id, text, position, anchor_heading, section_part, expected_content_hash, requestor)` | `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, requestor)` | `cerefox document edit-parts <id> -o <json\|-\|@file> --expected-hash <hash> --requestor <name>` |
820
- | `cerefox_list_versions(document_id, requestor)` | `cerefox document version list <id> --requestor <name>` |
821
- | `cerefox_list_projects(requestor)` | `cerefox project list --requestor <name>` |
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, requestor)` | `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, author, operation, since, until, limit, requestor)` | `cerefox audit list --document-id <id> --author <a> --operation <op> --since <iso> --until <iso> --limit N --requestor <name>` |
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, requestor)` | `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, requestor)` | `cerefox document restore <id> --reason <text> --author <a> --author-type <t>` |
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 `requestor` parameter on MCP read tools (and `author` on ingest) is
484
- optional. When omitted, it defaults to `"mcp-agent"`. This means the usage log shows
485
- `"mcp-agent"` for all calls that don't explicitly identify themselves, making analytics
486
- less useful in multi-agent setups.
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
- You can optionally enforce caller identification so that MCP tool calls must include
489
- a requestor/author identity. Calls without identity receive a JSON-RPC `-32602` error
490
- with a helpful message telling the agent what to provide.
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/author
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 both `requestor` (read tools) and `author` (ingest).
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 requestor parameter remains optional with the `"mcp-agent"` default.
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 absent, not dimmed.** Every write lands
574
- `approved` whoever wrote it the decision is made once, inside the
575
- `cerefox_ingest_document` RPC, so every access path (CLI, local and remote MCP,
576
- Edge Functions, web) obeys the same setting, including older clients. No surface
577
- shows a `review_status`: the web pill, badges and search chip do not render;
578
- the CLI drops its `status` column; API, MCP and Edge Function rows carry no
579
- `review_status` key; `GET /api/v1/search?review_status=…` is a `400`; and
580
- `POST /api/v1/documents/{id}/review-status` is a `404`.
581
-
582
- **Toggling never touches stored data.** Flipping the flag off does not approve
583
- anything and flipping it on does not queue anything; documents that were
584
- `pending_review` are still pending, and are shown as such the moment the flag
585
- is on again. Attribution and the audit log are unaffected in both states — who
586
- wrote what is always recorded. Config changes are audited too.
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 your requestor/author parameter to identify yourself.
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.0
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. While the store's review
802
- workflow is on (review_workflow_enabled), agent writes land
803
- pending_review and user writes approved; with it off every
804
- write lands approved.
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: >
@@ -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.0",
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",