@cerefox/memory 1.3.0 → 1.4.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 CHANGED
@@ -124,7 +124,7 @@ Retrieve the complete text of a document by its UUID.
124
124
  | `outline` | No | `true` returns the document's **structure instead of its content**: heading paths, levels, per-section sizes, plus `content_hash` and total size. Much cheaper than a full read. The paths are exactly what the edit tools take as `anchor_heading`. |
125
125
  | `requestor` | No | Your agent name. |
126
126
 
127
- Use this when search returns partial results, or to read a previous version before restoring it. The response header includes the document's current `content_hash` — pass it back as `expected_content_hash` when updating via `cerefox_ingest` or editing via `cerefox_insert` / `cerefox_edit`.
127
+ Use this when search returns partial results, or to read a previous version before restoring it. Pass `outline: true` for the heading structure without the body, or `section: "## Heading"` for one section's text — which is exactly what a `replace_section` on that anchor would overwrite, so read it before replacing a section you did not write yourself. The response header includes the document's current `content_hash` — pass it back as `expected_content_hash` when updating via `cerefox_ingest` or editing via `cerefox_insert` / `cerefox_edit`.
128
128
 
129
129
  **Before editing a document you have not read this session, call it with `outline: true` first.** It answers the three questions an edit needs — what are the anchors, how big is each section, what is the current hash — without pulling the body into your context.
130
130
 
@@ -157,7 +157,7 @@ Change parts of a document: **one to many operations applied atomically in a sin
157
157
  | Parameter | Required | Description |
158
158
  |-----------|----------|-------------|
159
159
  | `document_id` | Yes | UUID of the document. |
160
- | `operations` | Yes | Array of operations, applied **in order, all-or-nothing**. Each is `{op, ...}` with `op` one of `insert` (same fields as `cerefox_insert`), `replace_section` (`anchor_heading`, `text`; swaps the body, keeps the heading), `delete_section` (`anchor_heading`, optional `scope`: `body_only` default keeps the heading, `heading_and_body` removes it too). |
160
+ | `operations` | Yes | Array of operations, applied **in order, all-or-nothing**. Each is `{op, ...}` with `op` one of `insert` (same fields as `cerefox_insert`), `replace_section` (`anchor_heading`, `text`; swaps the body, keeps the heading), `delete_section` (`anchor_heading`, optional `scope`: `body_only` default keeps the heading, `heading_and_body` removes it too), `rename_section` (`anchor_heading`, `new_heading`; changes the heading TEXT only — body and position untouched, and the level must stay the same, since changing it would re-parent everything nested underneath). |
161
161
  | `expected_content_hash` | **Yes** | One token for the whole call. No `last_write_wins`. |
162
162
  | `requestor` | No | Your agent name. |
163
163
 
@@ -169,22 +169,25 @@ heading, and the footer — that is a whole-document change wearing a local
169
169
  disguise, and `cerefox_ingest` is the right tool. Section-scoped edits would take
170
170
  several calls, each individually valid, with the document briefly inconsistent
171
171
  between them. An agent hit exactly this and correctly stopped rather than
172
- contorting the tools. Related: **a heading's own text cannot be changed** —
173
- `replace_section` preserves it by design so a stale date inside a heading needs
174
- a re-ingest too.
172
+ contorting the tools. (Related, and **fixed in v1.4.0**: a heading's own text
173
+ used to be unchangeable, because `replace_section` preserves it by design, so a
174
+ stale date inside a heading forced a re-ingest. `rename_section` now changes the
175
+ heading and nothing else.)
175
176
 
176
177
  **One sharp edge worth knowing.** A section runs to the next heading of the same
177
178
  or higher level — **or to the end of the document**. So the last section owns
178
179
  everything appended after it: an `end_of_document` insert becomes part of that
179
180
  section's body, and a later `replace_section` or `delete_section` on that heading
180
181
  removes it along with the rest. This is correct addressing, not a bug, but it is
181
- silent. If a write reports a large shrink, that is the warning; the previous
182
- content is in `cerefox_list_versions`. To append somewhere a later section edit
182
+ silent. Since v1.4.0 any edit that removes content says so with the amount, and
183
+ a replace or delete on the LAST section gets the full explanation whatever the
184
+ size — the loss that matters here is *small* precisely because it was just
185
+ added. The previous content is in `cerefox_list_versions`. To append somewhere a later section edit
183
186
  cannot swallow, give the appended material its own heading.
184
187
 
185
188
  **To change a single line**, `replace_section` on its smallest enclosing heading and resend just that section. That is the intended granularity — line-level anchors were deliberately excluded because they silently edit the wrong place.
186
189
 
187
- The audit trail records each operation distinctly (`insert` / `replace-section` / `delete-section`), so *added to*, *rewrote* and *removed* stay distinguishable from a full rewrite.
190
+ The audit trail records each operation distinctly (`insert` / `replace-section` / `delete-section` / `rename-section`), so *added to*, *rewrote* and *removed* stay distinguishable from a full rewrite.
188
191
 
189
192
  ---
190
193
 
@@ -9,8 +9,8 @@ Cerefox is a persistent, shared knowledge base. You have **16 MCP tools** (15 of
9
9
  | `cerefox_search` | Find documents (hybrid FTS + semantic) | `query` (required), `project_name`, `metadata_filter`, `requestor` |
10
10
  | `cerefox_ingest` | Save or update a document | `title`, `content` (required), `document_id` (update by ID), `expected_content_hash` (**required on content updates** — see rule 9), `last_write_wins`, `update_if_exists`, `project_name` (single, non-destructive add on update), `project_names` (list, destructive replace on update), `metadata` (omit on update to keep existing tags; `{}` clears), `author` |
11
11
  | `cerefox_insert` | **Add** to a document without resending it. Cannot destroy content. | `document_id`, `text`, `position` (`end_of_document`/`end_of_section`/`after_heading`/`before_heading`), `expected_content_hash` (required), `anchor_heading` (unless `end_of_document`), `section_part` |
12
- | `cerefox_edit` | **Change** parts of a document: 1..n operations applied atomically | `document_id`, `operations` (`insert`/`replace_section`/`delete_section`), `expected_content_hash` (required) |
13
- | `cerefox_get_document` | Get full document by ID (header includes `content_hash` — the update token), or with `outline: true` just its heading paths, sizes and hash | `document_id` (required), `outline` |
12
+ | `cerefox_edit` | **Change** parts of a document: 1..n operations applied atomically | `document_id`, `operations` (`insert`/`replace_section`/`delete_section`/`rename_section`), `expected_content_hash` (required) |
13
+ | `cerefox_get_document` | Get full document by ID (header includes `content_hash` — the update token), or with `outline: true` just its heading paths, sizes and hash, or with `section: "## Heading"` one section's text | `document_id` (required), `outline`, `section`, `section_part` |
14
14
  | `cerefox_list_versions` | Version history of a document | `document_id` (required) |
15
15
  | `cerefox_set_relation` ⚑ | Link two documents (`source --rel_type--> target`) | `source_id`, `target_id`, `rel_type` (required), `metadata`, `author` |
16
16
  | `cerefox_delete_relation` ⚑ | Remove a relation | `source_id`, `target_id`, `rel_type` |
@@ -41,12 +41,19 @@ diff. Use the partial-edit tools instead:
41
41
  2. **Add** → `cerefox_insert`. `end_of_document` is a plain append;
42
42
  `end_of_section` adds inside a named section. It is structurally incapable of
43
43
  removing anything, so "I meant to append" cannot become "I replaced the file".
44
- 3. **Change or remove** `cerefox_edit`. Put changes that belong together in
44
+ 3. **Look before you overwrite** `cerefox_get_document(document_id,
45
+ section: "## Heading")` returns exactly the text a `replace_section` on that
46
+ anchor would destroy. The outline gives you a section's *size*, never its
47
+ *text*, so on a document you did not write yourself this is the difference
48
+ between a replace and a blind overwrite.
49
+ 4. **Change or remove** → `cerefox_edit`. Put changes that belong together in
45
50
  ONE call: they apply atomically, so a table row and the total it feeds cannot
46
51
  end up disagreeing. To change a single line, `replace_section` on its
47
52
  smallest enclosing heading — that is the intended granularity, not a
48
- workaround.
49
- 4. Both require `expected_content_hash` and **have no last-write-wins**. A
53
+ workaround. To fix a stale heading (`## OPEN TODOs (as of ...)`), use
54
+ `rename_section`: it changes the heading text and leaves the body and
55
+ position alone.
56
+ 5. All of them require `expected_content_hash` and **have no last-write-wins**. A
50
57
  conflict means someone else changed the document; re-read and decide, do not
51
58
  force it.
52
59