@cerefox/memory 1.15.3 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT_GUIDE.md +1 -1
- package/AGENT_QUICK_REFERENCE.md +1 -1
- package/dist/bin/cerefox.js +114 -25
- package/dist/frontend/assets/{index-DWeD_pcf.js → index-C5878rMW.js} +27 -27
- package/dist/frontend/assets/{index-DWeD_pcf.js.map → index-C5878rMW.js.map} +1 -1
- package/dist/frontend/index.html +1 -1
- package/dist/server-assets/_shared/ef-meta/index.ts +3 -3
- package/dist/server-assets/_shared/mcp-tools/delete-document.ts +11 -2
- package/dist/server-assets/_shared/mcp-tools/get-help-content.ts +2 -2
- package/dist/server-assets/db/migrations/0033_trash_auto_purge.sql +288 -0
- package/dist/server-assets/db/rpcs.sql +101 -3
- package/dist/server-assets/db/schema.sql +10 -1
- package/docs/api/openapi.json +28 -3
- package/docs/guides/access-paths.md +16 -0
- package/docs/guides/api.md +2 -2
- package/docs/guides/configuration.md +47 -0
- package/package.json +2 -2
|
@@ -1103,6 +1103,82 @@ AS $$
|
|
|
1103
1103
|
ORDER BY created_at DESC;
|
|
1104
1104
|
$$;
|
|
1105
1105
|
|
|
1106
|
+
-- ── cerefox_purge_expired_trash (#251, 0.17.0) ───────────────────────────────
|
|
1107
|
+
-- Permanently purges documents that have been in the trash longer than
|
|
1108
|
+
-- `trash_retention_days`, when `trash_auto_purge_enabled` is exactly 'true'.
|
|
1109
|
+
-- Called by cerefox_delete_document after every real soft delete: the write
|
|
1110
|
+
-- that adds to the trash also sweeps it. There is no scheduler, by decision
|
|
1111
|
+
-- (docs/specs/trash-auto-purge.md): the trash only grows through deletes, so
|
|
1112
|
+
-- this keeps it bounded on every deployment without pg_cron or a daemon.
|
|
1113
|
+
--
|
|
1114
|
+
-- Safeguards, each load-bearing:
|
|
1115
|
+
-- * at most p_max documents per call, oldest first (partial index on
|
|
1116
|
+
-- deleted_at), so a large first backlog drains over several deletes;
|
|
1117
|
+
-- * FOR UPDATE SKIP LOCKED, so concurrent deletes sweep disjoint rows;
|
|
1118
|
+
-- * an unparsable or < 1 retention purges NOTHING (never "purge everything");
|
|
1119
|
+
-- * one audit entry per purge, authored 'trash-retention' / 'user': the
|
|
1120
|
+
-- authority is the operator's setting, not whoever's delete triggered it.
|
|
1121
|
+
-- Not exposed on MCP, the Edge Functions or the CLI: there is still no
|
|
1122
|
+
-- agent-callable purge (access-paths.md → trust model).
|
|
1123
|
+
CREATE OR REPLACE FUNCTION cerefox_purge_expired_trash(
|
|
1124
|
+
p_max INT DEFAULT 100
|
|
1125
|
+
)
|
|
1126
|
+
RETURNS INT
|
|
1127
|
+
LANGUAGE plpgsql
|
|
1128
|
+
SECURITY DEFINER
|
|
1129
|
+
SET search_path = public, pg_catalog
|
|
1130
|
+
AS $$
|
|
1131
|
+
DECLARE
|
|
1132
|
+
v_enabled TEXT;
|
|
1133
|
+
v_days_txt TEXT;
|
|
1134
|
+
v_days INT;
|
|
1135
|
+
v_cutoff TIMESTAMPTZ;
|
|
1136
|
+
v_count INT := 0;
|
|
1137
|
+
r RECORD;
|
|
1138
|
+
BEGIN
|
|
1139
|
+
SELECT value INTO v_enabled FROM cerefox_config WHERE key = 'trash_auto_purge_enabled';
|
|
1140
|
+
IF v_enabled IS DISTINCT FROM 'true' THEN
|
|
1141
|
+
RETURN 0;
|
|
1142
|
+
END IF;
|
|
1143
|
+
|
|
1144
|
+
SELECT value INTO v_days_txt FROM cerefox_config WHERE key = 'trash_retention_days';
|
|
1145
|
+
IF v_days_txt IS NULL OR BTRIM(v_days_txt) !~ '^[0-9]{1,6}$' THEN
|
|
1146
|
+
RETURN 0;
|
|
1147
|
+
END IF;
|
|
1148
|
+
v_days := BTRIM(v_days_txt)::INT;
|
|
1149
|
+
IF v_days < 1 THEN
|
|
1150
|
+
RETURN 0;
|
|
1151
|
+
END IF;
|
|
1152
|
+
v_cutoff := NOW() - make_interval(days => v_days);
|
|
1153
|
+
|
|
1154
|
+
FOR r IN
|
|
1155
|
+
SELECT id, title, total_chars, deleted_at
|
|
1156
|
+
FROM cerefox_documents
|
|
1157
|
+
WHERE deleted_at IS NOT NULL AND deleted_at < v_cutoff
|
|
1158
|
+
ORDER BY deleted_at
|
|
1159
|
+
LIMIT GREATEST(COALESCE(p_max, 0), 0)
|
|
1160
|
+
FOR UPDATE SKIP LOCKED
|
|
1161
|
+
LOOP
|
|
1162
|
+
PERFORM cerefox_create_audit_entry(
|
|
1163
|
+
p_document_id := r.id,
|
|
1164
|
+
p_operation := 'delete',
|
|
1165
|
+
p_author := 'trash-retention',
|
|
1166
|
+
p_author_type := 'user',
|
|
1167
|
+
p_size_before := r.total_chars,
|
|
1168
|
+
p_size_after := 0,
|
|
1169
|
+
p_description := 'Auto-purged from the trash (trash_retention_days = ' || v_days ||
|
|
1170
|
+
'; trashed ' || to_char(r.deleted_at AT TIME ZONE 'UTC', 'YYYY-MM-DD') ||
|
|
1171
|
+
'): ' || COALESCE(r.title, '(untitled)') ||
|
|
1172
|
+
' (' || COALESCE(r.total_chars, 0) || ' chars)'
|
|
1173
|
+
);
|
|
1174
|
+
DELETE FROM cerefox_documents WHERE id = r.id;
|
|
1175
|
+
v_count := v_count + 1;
|
|
1176
|
+
END LOOP;
|
|
1177
|
+
|
|
1178
|
+
RETURN v_count;
|
|
1179
|
+
END;
|
|
1180
|
+
$$;
|
|
1181
|
+
|
|
1106
1182
|
-- ── cerefox_delete_document (soft delete) ────────────────────────────────────
|
|
1107
1183
|
-- Soft-deletes a document by setting deleted_at = NOW(). The document, its
|
|
1108
1184
|
-- chunks, and versions remain in the database but are excluded from search.
|
|
@@ -1123,6 +1199,12 @@ $$;
|
|
|
1123
1199
|
--
|
|
1124
1200
|
-- Deleting an already-deleted document is a reported no-op: the original
|
|
1125
1201
|
-- deleted_at is preserved and no duplicate audit entry is written.
|
|
1202
|
+
--
|
|
1203
|
+
-- 0.17.0 (#251): a real soft delete then sweeps the trash
|
|
1204
|
+
-- (cerefox_purge_expired_trash) and reports how many documents it purged as
|
|
1205
|
+
-- `auto_purged`. The sweep runs in its own sub-block: if it fails, only its
|
|
1206
|
+
-- savepoint rolls back, a WARNING is raised, and the delete commits exactly as
|
|
1207
|
+
-- it would with auto-purge off. A sweep can never fail a delete.
|
|
1126
1208
|
|
|
1127
1209
|
DROP FUNCTION IF EXISTS cerefox_delete_document(UUID, TEXT, TEXT, TEXT, TEXT);
|
|
1128
1210
|
DROP FUNCTION IF EXISTS cerefox_delete_document(UUID, TEXT, TEXT);
|
|
@@ -1144,6 +1226,7 @@ DECLARE
|
|
|
1144
1226
|
v_total_chars INT;
|
|
1145
1227
|
v_current_hash TEXT;
|
|
1146
1228
|
v_deleted_at TIMESTAMPTZ;
|
|
1229
|
+
v_auto_purged INT := 0;
|
|
1147
1230
|
BEGIN
|
|
1148
1231
|
-- FOR UPDATE: makes the hash check atomic with the delete — a concurrent
|
|
1149
1232
|
-- content update serializes here, and a stale deleter sees its hash.
|
|
@@ -1202,12 +1285,21 @@ BEGIN
|
|
|
1202
1285
|
COALESCE('; reason: ' || NULLIF(BTRIM(p_reason), ''), '')
|
|
1203
1286
|
);
|
|
1204
1287
|
|
|
1288
|
+
BEGIN
|
|
1289
|
+
v_auto_purged := cerefox_purge_expired_trash(100);
|
|
1290
|
+
EXCEPTION WHEN OTHERS THEN
|
|
1291
|
+
v_auto_purged := 0;
|
|
1292
|
+
RAISE WARNING 'cerefox: trash auto-purge skipped after deleting %: % (%)',
|
|
1293
|
+
p_document_id, SQLERRM, SQLSTATE;
|
|
1294
|
+
END;
|
|
1295
|
+
|
|
1205
1296
|
RETURN jsonb_build_object(
|
|
1206
1297
|
'document_id', p_document_id,
|
|
1207
1298
|
'title', v_title,
|
|
1208
1299
|
'total_chars', v_total_chars,
|
|
1209
1300
|
'deleted_at', v_deleted_at,
|
|
1210
|
-
'already_deleted', FALSE
|
|
1301
|
+
'already_deleted', FALSE,
|
|
1302
|
+
'auto_purged', v_auto_purged
|
|
1211
1303
|
);
|
|
1212
1304
|
END;
|
|
1213
1305
|
$$;
|
|
@@ -2742,7 +2834,10 @@ DECLARE
|
|
|
2742
2834
|
-- (0 = off). Partial edits make writes cheap, so an insert-only agent
|
|
2743
2835
|
-- never assembles the document and never sees it grow past its split
|
|
2744
2836
|
-- point. A signal in the write's response, never a refusal.
|
|
2745
|
-
'document_size_warning_chars'
|
|
2837
|
+
'document_size_warning_chars',
|
|
2838
|
+
-- #251: trash auto-purge, off by default; read by
|
|
2839
|
+
-- cerefox_purge_expired_trash on every soft delete.
|
|
2840
|
+
'trash_auto_purge_enabled', 'trash_retention_days'
|
|
2746
2841
|
];
|
|
2747
2842
|
v_old TEXT;
|
|
2748
2843
|
BEGIN
|
|
@@ -3091,6 +3186,9 @@ SET search_path = public, pg_catalog
|
|
|
3091
3186
|
AS $$
|
|
3092
3187
|
-- Keep in lockstep with the `@version:` marker in schema.sql (cut_release.ts
|
|
3093
3188
|
-- enforces it). Bump whenever schema.sql OR rpcs.sql changes.
|
|
3189
|
+
-- 0.17.0 (#251): trash auto-purge. New cerefox_purge_expired_trash, called
|
|
3190
|
+
-- by cerefox_delete_document after a real soft delete (which now returns
|
|
3191
|
+
-- `auto_purged`); two config keys, off by default. Migration 0033.
|
|
3094
3192
|
-- 0.16.2 (#26 follow-up): the Data API grant list is DERIVED from pg_class
|
|
3095
3193
|
-- rather than a hand-written array that has to match the set of tables. The
|
|
3096
3194
|
-- array had drifted (cerefox_document_relations), which only a FRESH cloud
|
|
@@ -3129,7 +3227,7 @@ AS $$
|
|
|
3129
3227
|
-- 0.11.0 supersedes 0.10.6 (v1.2.1, #191): this branch carries that fix plus
|
|
3130
3228
|
-- the partial-edit surface, and both migrations (0019, 0020) are in the
|
|
3131
3229
|
-- sequence, so a store deploying this gets everything from both lines.
|
|
3132
|
-
SELECT '0.
|
|
3230
|
+
SELECT '0.17.0'::TEXT;
|
|
3133
3231
|
$$;
|
|
3134
3232
|
|
|
3135
3233
|
-- ── 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.
|
|
8
|
+
-- @version: 0.17.0
|
|
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 —
|
|
@@ -413,6 +413,15 @@ ON CONFLICT (key) DO NOTHING;
|
|
|
413
413
|
INSERT INTO cerefox_config (key, value)
|
|
414
414
|
VALUES ('review_workflow_enabled', 'false')
|
|
415
415
|
ON CONFLICT (key) DO NOTHING;
|
|
416
|
+
-- Trash auto-purge (#251): OFF by default. When on, the soft delete that adds
|
|
417
|
+
-- to the trash also purges documents trashed more than trash_retention_days
|
|
418
|
+
-- ago (cerefox_purge_expired_trash). Design: docs/specs/trash-auto-purge.md.
|
|
419
|
+
INSERT INTO cerefox_config (key, value)
|
|
420
|
+
VALUES ('trash_auto_purge_enabled', 'false')
|
|
421
|
+
ON CONFLICT (key) DO NOTHING;
|
|
422
|
+
INSERT INTO cerefox_config (key, value)
|
|
423
|
+
VALUES ('trash_retention_days', '60')
|
|
424
|
+
ON CONFLICT (key) DO NOTHING;
|
|
416
425
|
|
|
417
426
|
|
|
418
427
|
-- ── Usage log ────────────────────────────────────────────────────────────────
|
package/docs/api/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Cerefox /api/v1",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.2.0",
|
|
6
6
|
"description": "The HTTP API served by `cerefox web`. Intended for callers that embed Cerefox rather than\nusing MCP or the CLI — MCP remains the recommended path for AI agents.\n\nGENERATED by `bun scripts/gen_openapi.ts`; do not edit by hand. Paths and every input a route\nreads come from the route handlers, summaries from the endpoint table in docs/guides/api.md,\nand body shapes from the zod schemas in `_shared/schemas/` (responses verified against a live\nserver by `api-schema-truth.test.ts`).\n\nAUTH: a request arriving on loopback needs no credential. From any other interface, an\n`X-API-Key` (or `Authorization: Bearer`) matching `CEREFOX_API_KEY` is required.\nSee docs/guides/securing-local-access.md.\n\nIDENTITY: send `X-Cerefox-Author` (and optionally `X-Cerefox-Author-Type`) to be recorded as\nyourself. Without them you are recorded as the bundled web UI.\n\nCONCURRENCY: read before you write. A content update (`POST /ingest` with `document_id` or\n`update_if_exists`, `POST /documents/{id}/edit`, `/upload`) needs the `content_hash` you read\nas `expected_content_hash`, or an explicit `last_write_wins`. `DELETE /documents/{id}` needs it\ntoo when you identify yourself, as `X-Cerefox-Expected-Content-Hash` or a query parameter.\nNeither is a 400 (`CEREFOX_TOKEN_REQUIRED`); a stale hash is a 409 carrying `current_hash`.\nRestore and purge take no hash.\n\nDISCOVERY: this document is served at `GET /api/v1/openapi.json` by the server it describes,\nand every /api/v1 response carries `Link: </api/v1/openapi.json>; rel=\"service-desc\"` (RFC 8631)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
@@ -1289,6 +1289,11 @@
|
|
|
1289
1289
|
},
|
|
1290
1290
|
"already_deleted": {
|
|
1291
1291
|
"type": "boolean"
|
|
1292
|
+
},
|
|
1293
|
+
"auto_purged": {
|
|
1294
|
+
"type": "integer",
|
|
1295
|
+
"minimum": -9007199254740991,
|
|
1296
|
+
"maximum": 9007199254740991
|
|
1292
1297
|
}
|
|
1293
1298
|
},
|
|
1294
1299
|
"required": [
|
|
@@ -3096,7 +3101,7 @@
|
|
|
3096
3101
|
},
|
|
3097
3102
|
"/api/v1/documents/trash": {
|
|
3098
3103
|
"get": {
|
|
3099
|
-
"summary": "Soft-deleted documents, newest first, `limit` ≤ 500. The exact total is in the `X-Total-Count` response header (v1.14.1).",
|
|
3104
|
+
"summary": "Soft-deleted documents, newest first, `limit` ≤ 500. The exact total is in the `X-Total-Count` response header (v1.14.1). `deleted_before=<ISO timestamp>` restricts both to documents trashed before then.",
|
|
3100
3105
|
"operationId": "get_documents_trash",
|
|
3101
3106
|
"parameters": [
|
|
3102
3107
|
{
|
|
@@ -3110,6 +3115,16 @@
|
|
|
3110
3115
|
"maximum": 500,
|
|
3111
3116
|
"default": 50
|
|
3112
3117
|
}
|
|
3118
|
+
},
|
|
3119
|
+
{
|
|
3120
|
+
"name": "deleted_before",
|
|
3121
|
+
"in": "query",
|
|
3122
|
+
"required": false,
|
|
3123
|
+
"description": "Only documents trashed before this instant; `X-Total-Count` then counts exactly those. With now minus `trash_retention_days`, it is what trash auto-purge would make eligible.",
|
|
3124
|
+
"schema": {
|
|
3125
|
+
"type": "string",
|
|
3126
|
+
"format": "date-time"
|
|
3127
|
+
}
|
|
3113
3128
|
}
|
|
3114
3129
|
],
|
|
3115
3130
|
"responses": {
|
|
@@ -3194,6 +3209,16 @@
|
|
|
3194
3209
|
}
|
|
3195
3210
|
}
|
|
3196
3211
|
},
|
|
3212
|
+
"400": {
|
|
3213
|
+
"description": "The request is malformed or incomplete: a bad parameter or body, an unknown body field, a blank identity header, or a content update with no `expected_content_hash` and no `last_write_wins` (`CEREFOX_TOKEN_REQUIRED`).",
|
|
3214
|
+
"content": {
|
|
3215
|
+
"application/json": {
|
|
3216
|
+
"schema": {
|
|
3217
|
+
"$ref": "#/components/schemas/Error"
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
3220
|
+
}
|
|
3221
|
+
},
|
|
3197
3222
|
"401": {
|
|
3198
3223
|
"description": "An API key is required: a non-loopback request while `CEREFOX_API_KEY` is set. See docs/guides/securing-local-access.md.",
|
|
3199
3224
|
"content": {
|
|
@@ -5777,7 +5802,7 @@
|
|
|
5777
5802
|
"x-cerefox-coverage": {
|
|
5778
5803
|
"routes": 40,
|
|
5779
5804
|
"withResponseSchema": 36,
|
|
5780
|
-
"queryParameters":
|
|
5805
|
+
"queryParameters": 42,
|
|
5781
5806
|
"note": "Routes without a response schema are listed with their parameters and summary only. Nothing is invented; see `uncovered`.",
|
|
5782
5807
|
"nonJson": [
|
|
5783
5808
|
"GET /openapi.json",
|
|
@@ -295,6 +295,22 @@ states the count, with a Stop button and a per-document audit entry; there is no
|
|
|
295
295
|
server-side "purge everything" endpoint, on purpose, because `/api/v1` is
|
|
296
296
|
reachable by anything holding the local key.
|
|
297
297
|
|
|
298
|
+
**Trash auto-purge (v1.16.0, opt-in) does not weaken this either, and here is exactly
|
|
299
|
+
why.** With `trash_auto_purge_enabled` on, every soft delete (including an agent's) also
|
|
300
|
+
purges documents that have been in the trash longer than `trash_retention_days`. So an
|
|
301
|
+
agent's action can *trigger* a purge. It stays within the model because:
|
|
302
|
+
|
|
303
|
+
- **a human turned the policy on and chose the period**: that period is the review
|
|
304
|
+
window of step 2, decided in advance instead of per document;
|
|
305
|
+
- the sweep purges only documents **older than that period**, never the one being
|
|
306
|
+
deleted and never anything an agent selects;
|
|
307
|
+
- there is still **no agent-callable purge**: the sweep function is not exposed over MCP
|
|
308
|
+
or the Edge Functions, has no CLI verb, and, like every RPC, is callable over the
|
|
309
|
+
Data API only with the service-role key.
|
|
310
|
+
|
|
311
|
+
With the setting off (the default), nothing here changes. Design:
|
|
312
|
+
[`docs/specs/trash-auto-purge.md`](../specs/trash-auto-purge.md).
|
|
313
|
+
|
|
298
314
|
A `cerefox purge-doc` CLI command, a `cerefox_purge_document` MCP tool, or a
|
|
299
315
|
`/documents/{id}/purge` HTTP endpoint accessible via the Cerefox token would each break this
|
|
300
316
|
property. **Do not add them without a governance design that replaces the human-in-the-
|
package/docs/guides/api.md
CHANGED
|
@@ -189,7 +189,7 @@ default; Cerefox Local picks its own port and `cerefox-local status` prints it).
|
|
|
189
189
|
| `GET /documents/{id}/versions` | Version history. |
|
|
190
190
|
| `POST /documents/{id}/versions/{version_id}/archive` | Archive or unarchive one stored version (body `{ "archived": true\|false }`). Archiving strips a version's search artifacts; its content is kept as the safety copy. |
|
|
191
191
|
| `GET /documents/{id}/download` | Raw markdown. |
|
|
192
|
-
| `GET /documents/trash` | Soft-deleted documents, newest first, `limit` ≤ 500. The exact total is in the `X-Total-Count` response header (v1.14.1). |
|
|
192
|
+
| `GET /documents/trash` | Soft-deleted documents, newest first, `limit` ≤ 500. The exact total is in the `X-Total-Count` response header (v1.14.1). `deleted_before=<ISO timestamp>` restricts both to documents trashed before then. |
|
|
193
193
|
| `POST /documents/metadata-search` | Query by metadata / project / time, no text query. |
|
|
194
194
|
| `GET /metadata-keys` | Metadata keys with counts and example values. |
|
|
195
195
|
| `GET /resolve-link`, `GET /check-filename` | Link and title resolution helpers. |
|
|
@@ -197,7 +197,7 @@ default; Cerefox Local picks its own port and `cerefox-local status` prints it).
|
|
|
197
197
|
| `POST /ingest/file` | Create from a multipart file upload. |
|
|
198
198
|
| `POST /documents/{id}/upload` | Replace a document's content from a file. |
|
|
199
199
|
| `POST /documents/{id}/edit` | Update title, content, metadata, projects. Unknown fields are a `400`. |
|
|
200
|
-
| `DELETE /documents/{id}` | Soft-delete (to trash). |
|
|
200
|
+
| `DELETE /documents/{id}` | Soft-delete (to trash). Returns `auto_purged`: documents this delete purged because they had outlived `trash_retention_days` (only while trash auto-purge is on). |
|
|
201
201
|
| `POST /documents/{id}/restore` | Restore from trash. |
|
|
202
202
|
| `DELETE /documents/{id}/purge` | Permanent delete. Irreversible. |
|
|
203
203
|
| `POST /documents/{id}/review-status` | Approve or re-queue for review. `404` while the review workflow is off. |
|
|
@@ -270,6 +270,53 @@ cerefox document get <document-id> --version-id <version-id>
|
|
|
270
270
|
|
|
271
271
|
---
|
|
272
272
|
|
|
273
|
+
## Trash auto-purge
|
|
274
|
+
|
|
275
|
+
Deleting a document moves it to the trash, where it stays until someone restores or
|
|
276
|
+
purges it. On a store where agents create and delete a lot, the trash grows without
|
|
277
|
+
bound. Since v1.16.0 you can have Cerefox purge old trash automatically. It is
|
|
278
|
+
**off by default**.
|
|
279
|
+
|
|
280
|
+
| Setting | Default | What it does |
|
|
281
|
+
|---|---|---|
|
|
282
|
+
| `trash_auto_purge_enabled` | `false` | Turn automatic purging on or off. |
|
|
283
|
+
| `trash_retention_days` | `60` | How long a document stays in the trash before it may be purged: your window to restore it. Whole days, 1 to 3650. |
|
|
284
|
+
|
|
285
|
+
Set them from **Settings** (Retention) or the CLI:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
cerefox config set trash_retention_days 60
|
|
289
|
+
cerefox config set trash_auto_purge_enabled true
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**When it runs.** Cerefox has no scheduler. The trash only grows when a document is
|
|
293
|
+
deleted, so that is when it is swept: each delete also purges documents that have been
|
|
294
|
+
in the trash longer than `trash_retention_days`, up to 100 per delete, oldest first.
|
|
295
|
+
A document therefore becomes *eligible* after the retention period and is removed by
|
|
296
|
+
**the next delete after that**. If nothing is deleted, expired documents stay, and
|
|
297
|
+
nothing new arrives in the trash either.
|
|
298
|
+
|
|
299
|
+
**What you can rely on.**
|
|
300
|
+
|
|
301
|
+
- Only documents already older than the retention period are purged, never the one
|
|
302
|
+
being deleted.
|
|
303
|
+
- A failure while sweeping never fails the delete: the delete completes, and the sweep
|
|
304
|
+
is retried on the next one.
|
|
305
|
+
- Every purge is in the audit log (author `trash-retention`), naming the retention in
|
|
306
|
+
force and the day the document was trashed.
|
|
307
|
+
- A delete reports how many documents it purged: `auto_purged` in the
|
|
308
|
+
`/api/v1` response, a line in the CLI and MCP output.
|
|
309
|
+
- `cerefox doctor` shows whether it is on and with which period.
|
|
310
|
+
- Settings asks for confirmation and tells you how many documents already in the trash
|
|
311
|
+
the next delete would purge. Shortening the period while it is on gets the same
|
|
312
|
+
confirmation.
|
|
313
|
+
|
|
314
|
+
Purged documents cannot be restored. Turning this on for a store with a large, old
|
|
315
|
+
trash purges it over the next few deletes; check the Trash page first if anything
|
|
316
|
+
there matters.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
273
320
|
## Storage & Backup
|
|
274
321
|
|
|
275
322
|
| Variable | Default | Description |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cerefox/memory",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "Cerefox \u2014 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",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"typescript": "^6.0.3"
|
|
66
66
|
},
|
|
67
67
|
"scripts": {
|
|
68
|
-
"build": "bun run bundle-server-assets && bun build src/bin/cerefox.ts --outdir dist/bin --target node --format esm --external @huggingface/transformers --external onnxruntime-node",
|
|
68
|
+
"build": "bun run bundle-server-assets && bun run bundle-docs && bun build src/bin/cerefox.ts --outdir dist/bin --target node --format esm --external @huggingface/transformers --external onnxruntime-node",
|
|
69
69
|
"clean": "rm -rf dist docs AGENT_GUIDE.md AGENT_QUICK_REFERENCE.md",
|
|
70
70
|
"bundle-docs": "bun run ../../scripts/bundle_package_docs.ts",
|
|
71
71
|
"bundle-server-assets": "bun run ../../scripts/bundle_server_assets.ts",
|