Schema-aware importer and migration helper for bringing OpenClaw lossless-claw history into Hermes-LCM.
Dry-run by default. Idempotent. Backs up before writes. Redacts credentials. Never copies your database over your database.
Why · Install · Quickstart · Commands · How It Works · Comparison · Verification · Hermes Skill · Contributing
Using OpenClaw
lossless-clawand want that context history available in Hermes-LCM? Whether you are migrating fully, evaluating Hermes, or running both systems side by side, the SQLite schemas are different. This tool imports the data safely without copying onelcm.dbover another.
hermes-lcm is the DAG-based Lossless Context Management plugin for Hermes Agent. It stores raw messages and a summary DAG inside ~/.hermes/lcm.db, and exposes lcm_grep / lcm_describe / lcm_expand / lcm_doctor inside active sessions.
OpenClaw ships its own lossless context engine, lossless-claw, with a similar shape but a different SQLite schema. Users who want to use their OpenClaw lossless-claw history inside Hermes-LCM need a deliberate schema-aware import. The source OpenClaw database stays read-only, and imported rows live alongside Hermes-LCM data.
This tool provides that interoperability bridge, with the safety properties a real import or migration needs:
- Schema-aware — anchor-based detection on both source and target. Refuses to run on unknown schemas with a clear error.
- Dry-run by default —
--applyis opt-in. - Mandatory backup — every
--applyrun takes a timestamped backup of the target database before any write. - Idempotent — re-running with the same conversations is a no-op. The metadata key shape is wire-compatible with the bespoke importer that has already been used in production.
- Redaction by default — credential-shaped patterns and imported encrypted/thinking blocks are scrubbed before write. Toggle off with
--no-redact. - Source-only read — the OpenClaw database is opened in URI
mode=ro. Never modified. - No network, no daemon — pure Python stdlib CLI. Runs offline.
git clone https://github.com/GodsBoy/openclaw-lcm-migrator.git
cd openclaw-lcm-migrator
python3 -m pytest -q # optional: confirm the test suite is green on your boxNo runtime dependencies. Python 3.10 or newer.
See Hermes Skill. The skill is a thin pointer to this repo plus the migration safety rules.
# 1. Copy the example session-map and edit it for your OpenClaw install.
cp templates/session-map.example.json ./session-map.json
$EDITOR ./session-map.json
# 2. Run preflight. No writes. Tells you whether your DBs and mapping look sane.
python3 scripts/preflight.py \
--source ~/.openclaw/lcm.db \
--target ~/.hermes/lcm.db \
--session-map ./session-map.json
# 3. Dry-run the import. Still no writes. Prints a JSON summary of what would happen.
python3 scripts/import_openclaw_lcm_to_hermes_lcm.py \
--source ~/.openclaw/lcm.db \
--target ~/.hermes/lcm.db \
--session-map ./session-map.json
# 4. Apply. Takes a timestamped backup first.
python3 scripts/import_openclaw_lcm_to_hermes_lcm.py \
--source ~/.openclaw/lcm.db \
--target ~/.hermes/lcm.db \
--session-map ./session-map.json \
--backup-dir ./backups \
--applyAfter --apply, verify with the steps in Verification.
Read-only health check. Runs first.
| Flag | Default | Meaning |
|---|---|---|
--source |
required | Path to OpenClaw lcm.db. |
--target |
required | Path to Hermes-LCM lcm.db. |
--session-map |
none | JSON mapping file. Optional but recommended. |
--verbose |
off | More chatty. |
Exits non-zero on any FAIL-level finding.
The importer/migrator itself.
| Flag | Default | Meaning |
|---|---|---|
--source |
required | OpenClaw lcm.db (opened read-only). |
--target |
required | Hermes-LCM lcm.db (writable on --apply). |
--session-map |
required | JSON mapping file. |
--dry-run |
default | Plan only. No writes. |
--apply |
off | Take a backup, then write. Mutually exclusive with --dry-run. |
--backup-dir |
./backups |
Where pre-apply backups land. |
--source-prefix |
openclaw-lcm |
Prefix on the imported messages.source lineage string. |
--limit N |
unlimited | Cap conversations imported per run. |
--no-redact |
off | Disable the default redaction policy. |
--no-fts-rebuild |
off | Skip the post-apply FTS index rebuild. |
--verbose |
off | Per-conversation log lines. |
The CLI prints a JSON summary at the end with conversations_seen, conversations_skipped, messages, summaries, backup_path, and mode.
┌─────────────────────┐
│ OpenClaw lcm.db │ read-only (URI mode=ro)
│ conversations, │
│ messages, │
│ summaries, │
│ summary_messages, │
│ summary_parents │
└──────────┬──────────┘
│
▼
┌───────────────────────────────────────────────────┐
│ scripts/migrator/ │
│ │
│ schema.detect_openclaw / detect_hermes_lcm │
│ mapping.load + validate │
│ importer.plan_imports (dry-run, no writes) │
│ importer.apply_imports (transactional writes) │
│ redaction.scrub (in-line, before insert) │
│ lineage.source_for(session_key, conv_id) │
└────────┬───────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Hermes-LCM lcm.db │
│ messages, │
│ summary_nodes, │
│ lcm_lifecycle_state, │
│ metadata (idempotency key per conversation), │
│ messages_fts / nodes_fts (rebuilt post-import) │
└──────────────────────────────────────────────────┘
For the per-table mapping, see references/schema-mapping.md.
| Capability | This migrator | cp lcm.db (raw copy) |
Manually re-run import script |
|---|---|---|---|
| Schema-aware | yes | no | depends |
| Dry-run by default | yes | n/a | varies |
| Backup before write | yes | manual | manual |
| Idempotent across re-runs | yes | no | varies |
| Pluggable session map | yes | n/a | hard-coded |
| Default redaction | yes | no | no |
| FTS rebuild | yes | no | manual |
| Source DB unchanged | yes | overwritten target | yes |
| Public CI | yes | n/a | n/a |
A raw database copy is tempting because both projects use SQLite, but the schemas differ. Use a schema-aware import instead.
After --apply, run these against your Hermes-LCM database:
# 1. Database integrity.
sqlite3 ~/.hermes/lcm.db 'PRAGMA integrity_check;'
# 2. Imported row counts (LIKE 'openclaw-lcm:%' if you used the default prefix).
sqlite3 ~/.hermes/lcm.db "SELECT COUNT(*) FROM messages WHERE source LIKE 'openclaw-lcm:%';"
sqlite3 ~/.hermes/lcm.db "SELECT COUNT(*) FROM summary_nodes WHERE expand_hint LIKE 'imported from OpenClaw lossless-claw%';"
# 3. Idempotency markers.
sqlite3 ~/.hermes/lcm.db "SELECT COUNT(*) FROM metadata WHERE key LIKE 'openclaw_lcm_import_v1:%';"In an active Hermes session:
lcm_status # confirms LCM is bound to the right DB
lcm_grep "phrase you remember from OpenClaw"
lcm_doctor # benign 'lifecycle_fragmentation' is OK; see references/troubleshooting.md
- Never copy
~/.openclaw/lcm.dbover~/.hermes/lcm.db. Schemas differ. Data loss. - Always run
preflight.pyfirst. - Always keep your backup until you have verified the import.
- Imported rows live alongside live Hermes rows. Search results from
lcm_grepwill mix them. - This migrator does not register imported rows in
~/.hermes/state.db. Hermessession_searchwill not see them;lcm_grepwill. Seereferences/troubleshooting.md.
SKILL.md in this repo can be dropped into a Hermes skills directory (typically ~/.hermes/skills/devops/openclaw-lcm-migrator/) so that an operator's Hermes agent loads the migration safety rules and CLI quick reference automatically.
The skill points back to this repo as the source of truth. Operators clone the repo and run the CLI from there; the skill knows how to find it.
See CONTRIBUTING.md. The bar:
- Tests against temp SQLite fixtures only.
- No silent schema fallthroughs.
- Idempotency is sacred (do not change the metadata key shape).
- Redaction is on by default.
- Backups are mandatory before writes.
For security issues, follow SECURITY.md.
MIT. See LICENSE.