@cerefox/memory 1.12.1 → 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 (39) hide show
  1. package/AGENT_GUIDE.md +26 -26
  2. package/AGENT_QUICK_REFERENCE.md +9 -9
  3. package/dist/bin/cerefox.js +7031 -7433
  4. package/dist/frontend/assets/index-InRztcXr.js +121 -0
  5. package/dist/frontend/assets/index-InRztcXr.js.map +1 -0
  6. package/dist/frontend/index.html +1 -1
  7. package/dist/server-assets/_shared/ef-meta/index.ts +3 -3
  8. package/dist/server-assets/_shared/mcp-tools/audit-log.ts +10 -8
  9. package/dist/server-assets/_shared/mcp-tools/delete-document.ts +4 -10
  10. package/dist/server-assets/_shared/mcp-tools/feature-flags.ts +42 -23
  11. package/dist/server-assets/_shared/mcp-tools/get-document.ts +3 -6
  12. package/dist/server-assets/_shared/mcp-tools/get-help-content.ts +3 -3
  13. package/dist/server-assets/_shared/mcp-tools/get-help.ts +3 -6
  14. package/dist/server-assets/_shared/mcp-tools/identity.ts +48 -0
  15. package/dist/server-assets/_shared/mcp-tools/ingest.ts +5 -10
  16. package/dist/server-assets/_shared/mcp-tools/list-metadata-keys.ts +3 -6
  17. package/dist/server-assets/_shared/mcp-tools/list-projects.ts +3 -6
  18. package/dist/server-assets/_shared/mcp-tools/list-versions.ts +3 -6
  19. package/dist/server-assets/_shared/mcp-tools/metadata-search.ts +9 -7
  20. package/dist/server-assets/_shared/mcp-tools/partial-edits.ts +7 -12
  21. package/dist/server-assets/_shared/mcp-tools/relations.ts +11 -12
  22. package/dist/server-assets/_shared/mcp-tools/restore-document.ts +4 -10
  23. package/dist/server-assets/_shared/mcp-tools/search.ts +3 -6
  24. package/dist/server-assets/_shared/mcp-tools/set-document-metadata.ts +4 -10
  25. package/dist/server-assets/_shared/mcp-tools/set-document-projects.ts +3 -6
  26. package/dist/server-assets/db/migrations/0031_review_workflow_toggle.sql +74 -0
  27. package/dist/server-assets/db/rpcs.sql +53 -8
  28. package/dist/server-assets/db/schema.sql +13 -2
  29. package/dist/server-assets/supabase/functions/cerefox-ingest/index.ts +2 -4
  30. package/dist/server-assets/supabase/functions/cerefox-mcp/index.ts +6 -6
  31. package/dist/server-assets/supabase/functions/cerefox-metadata-search/index.ts +12 -2
  32. package/docs/guides/access-paths.md +1 -1
  33. package/docs/guides/cli.md +21 -14
  34. package/docs/guides/configuration.md +75 -18
  35. package/docs/guides/connect-agents.md +10 -6
  36. package/docs/guides/upgrading.md +32 -1
  37. package/package.json +1 -1
  38. package/dist/frontend/assets/index-P1F2Ldl9.js +0 -121
  39. package/dist/frontend/assets/index-P1F2Ldl9.js.map +0 -1
@@ -344,7 +344,8 @@ Deno.serve(async (req: Request) => {
344
344
 
345
345
  const contentHash = await sha256hex(normalizeContent(content));
346
346
  const headers = { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" };
347
- const reviewStatus = author_type === "agent" ? "pending_review" : "approved";
347
+ // review_status is decided by cerefox_ingest_document from author_type and
348
+ // the store's review_workflow_enabled flag (#241); the EF no longer sends it.
348
349
 
349
350
  // ── ID-based update path ────────────────────────────────────────────────────
350
351
  // When document_id is provided, update that exact document regardless of
@@ -424,7 +425,6 @@ Deno.serve(async (req: Request) => {
424
425
  p_source: source,
425
426
  p_content_hash: contentHash,
426
427
  p_metadata: metadata,
427
- p_review_status: reviewStatus,
428
428
  p_chunks: chunkData,
429
429
  p_author: author,
430
430
  p_author_type: author_type,
@@ -543,7 +543,6 @@ Deno.serve(async (req: Request) => {
543
543
  p_source: source,
544
544
  p_content_hash: contentHash,
545
545
  p_metadata: metadata,
546
- p_review_status: reviewStatus,
547
546
  p_chunks: chunkData,
548
547
  p_author: author,
549
548
  p_author_type: author_type,
@@ -655,7 +654,6 @@ Deno.serve(async (req: Request) => {
655
654
  p_source: source,
656
655
  p_content_hash: contentHash,
657
656
  p_metadata: metadata,
658
- p_review_status: reviewStatus,
659
657
  p_chunks: chunkData,
660
658
  p_author: author,
661
659
  p_author_type: author_type,
@@ -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();
@@ -2,6 +2,7 @@ import "jsr:@supabase/functions-js/edge-runtime.d.ts";
2
2
  import { createClient } from "jsr:@supabase/supabase-js@2";
3
3
  import { isVersionRequest, versionResponse } from "../../../_shared/ef-meta/index.ts";
4
4
  import { efAuthGate } from "../../../_shared/ef-auth/index.ts";
5
+ import { reviewWorkflowEnabled } from "../../../_shared/mcp-tools/feature-flags.ts";
5
6
 
6
7
  /**
7
8
  * cerefox-metadata-search -- Supabase Edge Function
@@ -27,7 +28,9 @@ import { efAuthGate } from "../../../_shared/ef-auth/index.ts";
27
28
  * include_content boolean optional Include full text (default: false)
28
29
  * max_bytes number optional Byte budget when include_content=true
29
30
  *
30
- * Response (200): Array of matching documents
31
+ * Response (200): Array of matching documents. `review_status` is present
32
+ * only while the review workflow is on (#241); with the flag
33
+ * off the key is absent, as on every other surface.
31
34
  * Response (400): { error: "..." }
32
35
  */
33
36
 
@@ -160,7 +163,14 @@ Deno.serve(async (req: Request): Promise<Response> => {
160
163
  p_project_id: project_id,
161
164
  })).catch(() => {});
162
165
 
163
- return new Response(JSON.stringify(data ?? []), {
166
+ // Presentation only: the same shared reader every other surface uses.
167
+ const rows = (data ?? []) as Array<Record<string, unknown>>;
168
+ const showReview = await reviewWorkflowEnabled(supabase);
169
+ const out = showReview
170
+ ? rows
171
+ : rows.map(({ review_status: _hidden, ...rest }) => rest);
172
+
173
+ return new Response(JSON.stringify(out), {
164
174
  status: 200,
165
175
  headers: { ...CORS_HEADERS, "Content-Type": "application/json" },
166
176
  });
@@ -265,7 +265,7 @@ before "completing" the parity table by adding purge to agent-facing access path
265
265
  | Tier | Operations | Reversible? | Where exposed |
266
266
  |---|---|---|---|
267
267
  | 1. Reads + soft mutations | search, get, list-*, ingest (create/update), metadata-search, get-audit-log | n/a (reads) / yes (versioned) | All paths — MCP, Edge Functions, CLI, web UI |
268
- | 2. Soft-destructive + recovery | `delete_document` (soft delete to trash), `restore_document` (un-trash), `set_review_status` | yes — delete is restorable; restore recovers | CLI (`cerefox document delete` / `restore`), web UI, and — since v1.7.0 (#208, #210) — MCP (`cerefox_delete_document`, which requires the caller's read-hash, and `cerefox_restore_document`). **Not** the primitive GPT-Actions Edge Functions (deliberately deferred). |
268
+ | 2. Soft-destructive + recovery | `delete_document` (soft delete to trash), `restore_document` (un-trash), `set_review_status` (web only; a `404` while `review_workflow_enabled` is off) | yes — delete is restorable; restore recovers | CLI (`cerefox document delete` / `restore`), web UI, and — since v1.7.0 (#208, #210) — MCP (`cerefox_delete_document`, which requires the caller's read-hash, and `cerefox_restore_document`). **Not** the primitive GPT-Actions Edge Functions (deliberately deferred). |
269
269
  | 3. **Hard-destructive** | `purge_document` (permanent), `set_version_archived` (toggle version retention) | no (purge) | **Web UI only** |
270
270
 
271
271
  ### Why purge is web-UI-only
@@ -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 auto-routed to `pending_review`. |
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
@@ -216,7 +216,7 @@ cerefox document list [OPTIONS]
216
216
  | `--deleted` | flag | off | List soft-deleted (trashed) documents instead of active ones, newest-deleted first. Pair the ids with `cerefox document restore` / `cerefox document delete`. |
217
217
  | `--json` | flag | off | Machine-readable JSON output. |
218
218
 
219
- **Output**: tabular `id | title | source | status | updated_at` listing (or `deleted_at` with `--deleted`).
219
+ **Output**: tabular `id | title | source | status | updated_at` listing (or `deleted_at` with `--deleted`). The `status` column (and the `review_status` key in `--json`) is present only while the review workflow is on — see `review_workflow_enabled` in [configuration.md](configuration.md#review-workflow).
220
220
 
221
221
  **MCP equivalent**: scope-by-project / metadata / time listing maps to [`cerefox_metadata_search`](../../AGENT_GUIDE.md) — e.g. `cerefox_metadata_search(project_name="research")` lists that project's documents (the `metadata_filter` may be empty when another scope is supplied). The `--deleted` (trash) view and unscoped whole-KB listing remain CLI-only.
222
222
 
@@ -506,6 +506,8 @@ cerefox metadata search --metadata-filter '{"type":"decision-log"}' --updated-si
506
506
  cerefox metadata search --metadata-filter '{"status":"active"}' --project-name "research" --include-content
507
507
  ```
508
508
 
509
+ **Output**: a `## title [id: …]` block per document with its metadata, projects, size, review status and update date (plus content with `--include-content`), or JSON with `--json`. As with `document list`, the review status (and the `review_status` key in `--json`) is present only while the review workflow is on — see `review_workflow_enabled` in [configuration.md](configuration.md#review-workflow).
510
+
509
511
  **MCP equivalent**: [`cerefox_metadata_search`](../../AGENT_GUIDE.md).
510
512
 
511
513
  ---
@@ -702,11 +704,16 @@ Agents see 15 tools with the flag off and 19 with it on. See
702
704
 
703
705
  **Synopsis**:
704
706
  ```
705
- cerefox config list # all current key/value pairs
707
+ cerefox config list [--json] # every settable key, grouped, with kind + default (from the shared catalog)
706
708
  cerefox config get KEY
707
709
  cerefox config set KEY VALUE [--author NAME] [--author-type user|agent]
708
710
  ```
709
711
 
712
+ `config list` is derived from the same catalog the web Settings page renders
713
+ (v1.13.0, #239 — the earlier hand-written list had drifted and hid three
714
+ working keys). `--json` returns `{ keys: string[], catalog: [{ key, kind,
715
+ default, group, description }] }`; `keys` keeps its pre-1.13 shape.
716
+
710
717
  Since v1.9.0 every `config set` is recorded in the audit log by the server
711
718
  itself (`config-change`, with the old → new value), in the same transaction
712
719
  as the write — pass `--author` (or set `CEREFOX_AUTHOR_NAME`) so the entry
@@ -766,7 +773,7 @@ These flat commands handle install, configuration, and health. Run any with `--h
766
773
  | Command | Purpose |
767
774
  |---|---|
768
775
  | `cerefox init` | Interactive first-run setup; writes `~/.cerefox/.env`, offers `server deploy` + self-docs ingest. |
769
- | `cerefox doctor` | Diagnose the install (credentials, DB reachability, schema version). |
776
+ | `cerefox doctor` | Diagnose the install (credentials, DB reachability, schema version, whether the review workflow is on). |
770
777
  | `cerefox status` | Show connection + schema status. |
771
778
  | `cerefox configure-agent --tool <client>` | Write MCP client config (`claude-code`, `claude-desktop`, `cursor`, `codex`, `gemini`). |
772
779
  | `cerefox token generate` / `rotate` / `list` | Manage the Cerefox access token (`cfx_pat_…`) — the Edge Function Bearer credential (remote MCP, GPT Actions, curl). See the [`cerefox token`](#cerefox-token-generate--cerefox-token-rotate--cerefox-token-list) section above. |
@@ -804,21 +811,21 @@ Every MCP parameter has an exact-name CLI flag (kebab-cased). Short forms exist
804
811
 
805
812
  | MCP tool | CLI command |
806
813
  |---|---|
807
- | `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>` |
808
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>` |
809
816
  | `cerefox_ingest(...)` (paste) | `printf '...' \| cerefox document ingest --paste --title "<t>"` (same flags) |
810
- | `cerefox_get_document(document_id, version_id, outline, requestor)` | `cerefox document get <id> --version-id <vid> --outline --requestor <name>` |
811
- | `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>` |
812
- | `cerefox_edit(document_id, operations, expected_content_hash, requestor)` | `cerefox document edit-parts <id> -o <json\|-\|@file> --expected-hash <hash> --requestor <name>` |
813
- | `cerefox_list_versions(document_id, requestor)` | `cerefox document version list <id> --requestor <name>` |
814
- | `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>` |
815
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) |
816
823
  | `cerefox_list_metadata_keys()` | `cerefox metadata keys` |
817
- | `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>` |
818
- | `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>` |
819
826
  | `cerefox_set_document_metadata(document_id, metadata, replace, author)` | `cerefox document set-metadata <id> --set key=value` (also `--remove key`, `--json '<json>'`, `--replace`) |
820
- | `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) |
821
- | `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>` |
822
829
 
823
830
  ## CLI ↔ MCP parity matrix
824
831
 
@@ -378,9 +378,13 @@ enable it.
378
378
  ### How it works
379
379
 
380
380
  A `cerefox_config` table in Postgres stores runtime configuration as key-value
381
- pairs. The allow-list lives in the `cerefox_set_config` RPC; run `cerefox config
382
- list` (or open **Settings** in the web UI) for the current set — today that is
383
- usage tracking, the two requestor-identity keys, three retrieval tunables, and
381
+ pairs. Every key is declared once in the shared catalog
382
+ (`_shared/config-catalog/index.ts`: kind, default, group, description); the
383
+ `cerefox_set_config` RPC's allow-list stays authoritative for writes and a unit
384
+ test pins the two together. Run `cerefox config list` (or open **Settings** in
385
+ the web UI) for the current set — today that is usage tracking, the two
386
+ requestor-identity keys, three retrieval tunables, two version-retention keys,
387
+ the document-size warning threshold, `review_workflow_enabled` and
384
388
  `relations_enabled`. Usage logging is the illustrative case below: every logging
385
389
  call goes through the
386
390
  `cerefox_log_usage` RPC, which checks this config value first:
@@ -414,15 +418,17 @@ cerefox config get usage_tracking_enabled
414
418
 
415
419
  **Via the web UI:** `cerefox web` → **Settings**. Every runtime key is listed
416
420
  with its description, current value and default, grouped into Retrieval,
417
- Governance and Features.
421
+ Retention, Governance and Features.
418
422
 
419
423
  Two things the page does deliberately:
420
424
 
421
425
  - **Keys that change what agents see require confirmation.** Turning on
422
- `relations_enabled` adds four tools to every connected agent's tool list, and
426
+ `relations_enabled` adds four tools to every connected agent's tool list,
423
427
  `require_requestor_identity` starts rejecting agents that don't identify
424
- themselves. Neither is a bare toggle you get a dialog naming the
425
- consequence first.
428
+ themselves, `review_workflow_enabled` hides or reveals the review status on
429
+ every surface, and `version_cleanup_enabled` decides whether old versions are
430
+ pruned. None is a bare toggle — you get a dialog naming the consequence
431
+ first.
426
432
  - **Retired `.env` lines are flagged.** If a variable that used to control a
427
433
  setting is still present in the server's environment, the row says so — it no
428
434
  longer does anything, and the value shown is what actually runs. The page
@@ -474,14 +480,20 @@ cerefox config get usage_tracking_enabled
474
480
 
475
481
  ## Requestor Identity Enforcement
476
482
 
477
- By default, the `requestor` parameter on MCP read tools (and `author` on ingest) is
478
- optional. When omitted, it defaults to `"mcp-agent"`. This means the usage log shows
479
- `"mcp-agent"` for all calls that don't explicitly identify themselves, making analytics
480
- 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.
481
487
 
482
- You can optionally enforce caller identification so that MCP tool calls must include
483
- a requestor/author identity. Calls without identity receive a JSON-RPC `-32602` error
484
- 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.
485
497
 
486
498
  ### What it actually covers
487
499
 
@@ -510,7 +522,7 @@ tenth copy of the same block. Raise an issue rather than assuming it is there.
510
522
  ### Enabling enforcement
511
523
 
512
524
  ```bash
513
- # Require all MCP tool calls to include requestor/author
525
+ # Require all MCP tool calls to include author (or the requestor alias)
514
526
  cerefox config set require_requestor_identity true
515
527
 
516
528
  # Optionally override the default naming format (regex)
@@ -526,7 +538,7 @@ cerefox config set requestor_identity_format "^[a-z]+:[a-z]+$"
526
538
  | `^[a-z]+:[a-z]+$` | `conclave:agent` format only | Multi-conclave setups (e.g., `personal:steward`) |
527
539
  | (empty string) | Any non-empty string | No format restriction |
528
540
 
529
- 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).
530
542
 
531
543
  ### Disabling enforcement
532
544
 
@@ -534,14 +546,59 @@ The format is applied to both `requestor` (read tools) and `author` (ingest).
534
546
  cerefox config set require_requestor_identity false
535
547
  ```
536
548
 
537
- 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.
538
550
  This is the default state -- no configuration needed for backward compatibility.
539
551
 
540
552
  ---
541
553
 
554
+ ## Review Workflow
555
+
556
+ Cerefox can queue agent-authored writes for a person to approve: with the
557
+ workflow **on**, a document written with `author_type: agent` lands as
558
+ `pending_review`, a human write lands as `approved`, and every surface shows the
559
+ status (a pill on the document page, badges on the dashboard, a search filter,
560
+ a `status` column in the CLI, the field in API and MCP output). Review status
561
+ never gates retrieval — a pending document is exactly as searchable as an
562
+ approved one — it is a governance signal, nothing more.
563
+
564
+ Since v1.13.0 the workflow is a store-level switch, `review_workflow_enabled`,
565
+ kept in `cerefox_config` like every other store setting so two clients on one
566
+ database cannot disagree about whether it exists:
567
+
568
+ | Situation | Value |
569
+ |---|---|
570
+ | Fresh install (v1.13.0+) | **`false`** — most single-operator stores never review anything |
571
+ | Upgraded from an earlier version | **`true`** — an upgrade never changes what your store does |
572
+
573
+ ```bash
574
+ cerefox config get review_workflow_enabled
575
+ cerefox config set review_workflow_enabled true # or false; also in Settings → Governance
576
+ cerefox doctor # prints "review workflow ON …" / "OFF …"
577
+ ```
578
+
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.
596
+
597
+ Design: [`docs/specs/review-workflow-toggle.md`](../specs/review-workflow-toggle.md).
598
+
542
599
  ## Checking Your Configuration
543
600
 
544
- Run the doctor to verify everything is connected (credentials, DB reachability, schema version):
601
+ Run the doctor to verify everything is connected (credentials, DB reachability, schema version, review workflow on/off):
545
602
 
546
603
  ```bash
547
604
  cerefox doctor # or: cerefox status
@@ -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.3.0
641
+ version: 3.4.1
642
642
  servers:
643
643
  - url: https://<your-project-ref>.supabase.co/functions/v1
644
644
  paths:
@@ -798,8 +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
- Controls review_status auto-transition: agent writes set
802
- the document to pending_review, user writes set it to 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.
803
805
  responses:
804
806
  '200':
805
807
  description: >
@@ -1033,9 +1035,11 @@ paths:
1033
1035
  '200':
1034
1036
  description: >
1035
1037
  Array of matching documents:
1036
- [{ document_id, title, doc_metadata, review_status, source, created_at,
1038
+ [{ document_id, title, doc_metadata, source, created_at,
1037
1039
  updated_at, total_chars, chunk_count, project_ids, project_names,
1038
- version_count, content_hash, content }].
1040
+ version_count, content_hash, content }], plus review_status
1041
+ only while the store's review workflow is on (the key is absent
1042
+ when it is off).
1039
1043
  content_hash is the concurrency token — pass it back as
1040
1044
  expected_content_hash when updating via ingestNote.
1041
1045
  ```
@@ -11,7 +11,7 @@ cerefox guides ingest # 3. the bundled guides, into your KB
11
11
  ```
12
12
 
13
13
  The order matters: a release may require its own schema (the version notes
14
- say so — v1.9.x is one), and until `server deploy` runs, the freshly updated
14
+ say so — v1.9.x and v1.13.0 are two), and until `server deploy` runs, the freshly updated
15
15
  client is talking to the previous release's server. That is why
16
16
  `self-update` no longer runs the guides sync automatically — it used to fire
17
17
  at the one moment in the upgrade where it cannot succeed against a
@@ -60,6 +60,32 @@ schema-requiring release.
60
60
 
61
61
  ## End-user upgrade
62
62
 
63
+ > ### Upgrading to v1.13.0 — `cerefox server deploy` is required
64
+ >
65
+ > v1.13.0 makes the review workflow optional and moves the "agent writes land
66
+ > `pending_review`" decision out of the clients and into the
67
+ > `cerefox_ingest_document` RPC (#241). A v1.13.0 client no longer decides
68
+ > the status itself, so against an older server every agent write would
69
+ > silently land `approved` — a behaviour change, not a missing feature — and
70
+ > the new review-status search filter would fail outright. The **minimum
71
+ > supported schema is therefore `0.16.0`**: until you run `cerefox server
72
+ > deploy`, `cerefox web` refuses to start and `doctor` says exactly why.
73
+ >
74
+ > Migration 0031 seeds `review_workflow_enabled = true` on every existing
75
+ > store, so **your store keeps behaving exactly as before**. The flag now
76
+ > exists and `cerefox doctor` prints its state; flip it with
77
+ > `cerefox config set review_workflow_enabled false` (or Settings → Governance)
78
+ > if nobody reviews the queue. See
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.
88
+
63
89
  > ### Upgrading to v1.1.0 — `cerefox server deploy` is required
64
90
  >
65
91
  > Most releases let you postpone the server step. **This one does not.** Until
@@ -166,6 +192,11 @@ knowing about:
166
192
  that ingested fine before now need deduplication, or are refused on edit.
167
193
  - **v1.7.0 — trashed documents refuse content updates.** A soft-deleted
168
194
  document must be restored before its content can be updated.
195
+ - **v1.13.0 — the review workflow is a store setting.** Upgraded stores keep
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.
169
200
 
170
201
  ## Notable: v1.8.0 storage reclaim (migration 0027)
171
202
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cerefox/memory",
3
- "version": "1.12.1",
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",