Reads & Writes
Write Policies: append, overwrite, mergeByKey
Write Policies: append, overwrite, mergeByKey
Three write policies control how new content interacts with existing content in a slate file. The policy is declared via the on: field on slateWrite and gated writes. The default is append.
append (default)
New content is appended to the end of the existing file content. The existing content is preserved; the new content is added below it.
slateWrite:
to: { slate: "Memory", folder: facts, file: core.md }
on: append
match: { ... }Use when: Accumulating findings over time. Each verified fact is appended to the running list. The file grows with each call.
# Before: core.md
Surface codes are the dominant QEC family.
# After append:
Surface codes are the dominant QEC family.
Shor codes are optimal for small qubit counts.If on: is omitted entirely, append is the default. This makes append the safe choice — new data is added without destroying existing data.
overwrite
New content replaces the existing file content entirely. The old content is discarded.
slateWrite:
to: { slate: "Memory", folder: state, file: current.md }
on: overwrite
match: { ... }Use when: The file holds a snapshot that should always reflect the latest state. Each call replaces the previous snapshot.
# Before: current.md
{"status": "draft", "version": 2}
# After overwrite:
{"status": "final", "version": 3}Overwrite is destructive. Use it only when the new content is a complete replacement for the old, not when it's an addition.
mergeByKey
For JSON array files, mergeByKey updates items by a key field rather than appending or replacing the entire file. If an item with the same key already exists, it is replaced. If not, it is appended.
slateWrite:
to: { slate: "Data", folder: records, file: index.md }
on: mergeByKey
key: id
match:
type: array
items:
type: object
required: [id, name]
properties:
id: { type: string }
name: { type: string }How it works:
- The existing file content is loaded and parsed as a JSON array.
- The new content (also a JSON array or single object) is normalized to an array.
- For each new item:
- If an existing item has the same value for the
keyfield, the existing item is replaced. - If no existing item matches, the new item is appended.
- If an existing item has the same value for the
- The merged array is written back as formatted JSON.
# Before: index.md
[
{ "id": "a", "name": "Alice", "role": "admin" },
{ "id": "b", "name": "Bob", "role": "user" }
]
# New write: { "id": "b", "name": "Bob", "role": "moderator" }
# (key: "id", matches existing item "b")
# After mergeByKey:
[
{ "id": "a", "name": "Alice", "role": "admin" },
{ "id": "b", "name": "Bob", "role": "moderator" }
]Use when: Maintaining a keyed collection (records, entities, configs) where updates should replace by identity rather than duplicate. The key field must be a string inside the JSON objects.
Requirements:
- The existing file must contain valid JSON (or be empty — treated as
[]). - The new content must pass the
matchschema validation. - The
key:field must be declared and must be a string field in the JSON objects.
Items that don't have the key field are appended without replacement (treated as new entries).