Document Versioning
All documents retain history on update. Previous versions are archived automatically.
Strings
Every note is a string — a linear chain of versions that grows each time you update it.
Your working context (now) accumulates a string of intentions as you work.
When a string of work is complete, keep move extracts matching versions by tag
and strings them into a named note.
This isn't version control (no branches, no merges) and it isn't an append-only log (you can reorganize). It's the temporal dimension of how knowledge evolved — and unlike other memory stores, you can re-string it by meaning.
Version identifiers
Append @V{N} to any ID to specify a version:
ID@V{0}— current versionID@V{1}— previous versionID@V{2}— two versions agoID@V{-1}— oldest archived versionID@V{-2}— second-oldest archived version
keep get "%a1b2c3d4@V{1}" # Previous version
keep get "now@V{2}" # Two versions ago of nowdoc
keep get "now@V{-1}" # Oldest archived nowdocAccessing versions
keep get ID -V 1 # Previous version (equivalent to @V{1})
keep get ID -V -1 # Oldest archived (equivalent to @V{-1})
keep get ID --history # List all versions
keep now -V 1 # Previous intentions
keep now --history # List all nowdoc versionsHistory output
--history shows versions as summary lines with version identifiers:
now 2026-01-16 Current summary...
now@V{1} 2026-01-15 Previous summary...
now@V{2} 2026-01-14 Older summary...With --ids, outputs version identifiers for piping:
keep --ids now --history
# now@V{0}
# now@V{1}
# now@V{2}Version navigation in output
When viewing a single item (keep get, keep now), the output includes prev: and next: navigation:
---
id: %a1b2c3d4
prev:
- @V{1} 2026-01-14 Previous summary text...
---
Current summary here...Content-addressed IDs
Text-mode updates use content-addressed IDs for versioning:
keep put "my note" # Creates %a1b2c3d4e5f6
keep put "my note" -t done # Same ID, new version (tag change)
keep put "different note" # Different ID (new document)Same content = same ID = enables versioning via tag changes.
Deleting and reverting
keep del has revert semantics when versions exist:
keep del ID # If versions exist: reverts to previous version
# If no versions: removes item entirelyPipe composition
keep --ids now --history | xargs -I{} keep get "{}" # Get all versions
diff <(keep get doc:1) <(keep get "doc:1@V{1}") # Diff current vs previousPython API
kp.get_version(id, offset=1) # Previous version
kp.get_version(id, offset=2) # Two versions ago
kp.list_versions(id, limit=10) # Archived versions (newest first)See PYTHON-API.md for complete Python API reference.
Parts vs versions
Versions and parts are complementary dimensions:
- Versions (
@V{N}) are temporal — eachputadds a version - Parts (
@P{N}) are structural —analyzedecomposes content into sections
Versions accumulate (each one happened). Parts replace (each analyze produces
a fresh decomposition). Both use tag-based metadata and appear in search results.
See KEEP-ANALYZE.md for details on structural decomposition.
See Also
- KEEP-GET.md — Retrieving items and versions
- KEEP-NOW.md — Nowdoc version history
- KEEP-ANALYZE.md — Structural decomposition into parts
- REFERENCE.md — Quick reference index