skip to main content

NAME

kb-merge — reconcile two knowledge.db files that drifted independently

SYNOPSIS

kb merge -a PATH -b PATH -out PATH [-force]

DESCRIPTION

merge reads two knowledge.db files (e.g. from two machines that have drifted independently) read-only and writes their deduped union to a fresh -out file, which must not already exist. It never modifies -a or -b; placing the merged file into position is left to you. Every table travels — projects, concepts, sources, observations, decision records and record relations, plus the four join tables — so a table that would lose rows says so in the per-table summary rather than merging quietly short. Each side is copied to a scratch file and brought up to the current schema before ATTACHing, so a database predating decision records (or any other table) still merges instead of failing outright.

Unlike every other verb, merge operates entirely on the explicit -a/-b/-out paths — a –db is refused, and it never opens (or creates) the ambient ./agents/knowledge.db.

Both inputs must exist, be non-empty database files, and be two different files; anything else is refused before any file is touched. A mistyped -a therefore fails, instead of merging an empty database in its place and leaving a zero-byte file at the typo. A zero-byte file is refused even when a -wal file sits beside it: SQLite discards that -wal on opening an empty main file, so merge refuses first and leaves the -wal untouched. The exit status says which: 66 for an input that does not exist or is not a file, 65 for a zero-byte file or one that is not a knowledge base, 2 for -a and -b naming the same file, 73 when -out already exists, and 65 for an identity collision reported without -force.

If a project or concept with the same name exists in both files under different internal identities (a collision — typically from before a database’s identifiers were established), merge aborts and lists them unless -force is given, in which case b’s identity is reconciled to a’s so both sides’ observations and links survive under one merged entity. A decision record collides the same way, keyed by its identity — workspace, project, scope and record id — rather than by project_id or the project’s own uuid.

A record held by both files under the same identity but different text is reported as a content divergence (same record, different prose) even when it is not also a collision: the merge keeps a’s copy and never blocks on this, but prints the diverging record ids and checksums so the operator knows which Markdown files to reconcile by hand. With –json, divergences appear as content_divergences alongside collisions_reconciled and the per-table tables summary, instead of the plain-text report.

To find out whether a database and the JSONL dump beside it have drifted, before deciding whether to merge, import or export, use kb-check-db(1). It is read-only and shares merge’s rules for what counts as the same row.

SEE ALSO

kb(1), kb-check-db(1), kb-export(1), kb-import(1)