memhouse 0.9.0 → 0.11.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/README.md CHANGED
@@ -76,7 +76,7 @@ memhouse update [--check] upgrade, restart daemons, check the s
76
76
  memhouse start | stop dashboard + shipper as daemons
77
77
  memhouse service install | uninstall survive a reboot
78
78
  memhouse deploy --local | --down stand up (or remove) a local house
79
- memhouse plugins install claude /memhouse:search, :sessions, :sql —
79
+ memhouse plugins install claude /mem:search, :sessions, :sql —
80
80
  into every Claude Code config dir found
81
81
  memhouse prompt memory snippet for an agent's system prompt
82
82
  memhouse prompt --install an install prompt, rendered for this machine
@@ -89,7 +89,7 @@ an agent — so an agent can install its own memory unattended.
89
89
  config directory on the machine** — `~/.claude`, whatever `CLAUDE_CONFIG_DIR` points
90
90
  at, and each Kommander-style playbook under `~/.claude-playbooks/`. All are selected by
91
91
  default; answer with numbers to narrow it, or pass `--target DIR` for exactly one.
92
- Installing into just the default config is how `/memhouse:search` ends up missing from
92
+ Installing into just the default config is how `/mem:search` ends up missing from
93
93
  the instance you actually work in, silently, since a missing skill never announces
94
94
  itself.
95
95
 
@@ -199,24 +199,43 @@ which is also why joining a ClickHouse someone else runs (a kernel's, a team's)
199
199
  no negotiation beyond a database and a credential. Housemates are collaborators;
200
200
  groups that should not see each other get separate houses.
201
201
 
202
- ### Imported history is protected
203
-
204
- Rows carry an `origin`. The shipper clears a session before re-inserting it, so a
205
- shorter re-parse can't leave a stale tail behind — but that clear only removes rows
206
- the shipper itself wrote (`origin='ship'`). Anything you imported from an older
207
- house, another product, or a machine that no longer exists survives a re-ship.
208
-
209
- `origin` is in the sorting key of `messages` and `tool_calls` too, so
210
- ReplacingMergeTree can't quietly collapse an imported row against a shipped one. Both
211
- halves matter: guarding only the delete still loses data, through the merge instead of
212
- the mutation.
213
-
214
- `sessions` is the deliberate exception — one row per session, no `origin` in its key.
215
- A session's metadata has a single current version, and keying it on origin gives the
216
- same session two rows, which makes every rollup count its messages twice.
217
-
218
- The shipper checks both directions before it writes and prints the rebuild if a house
219
- has it wrong, so an old house cannot be corrupted by a new shipper.
202
+ ### The house never destroys what it cannot rebuild
203
+
204
+ **The shipper is insert-only.** It runs no `DELETE`, no `TRUNCATE`, no mutation of any
205
+ kind, so no privilege it holds can lose you a row.
206
+
207
+ That is not free, because ReplacingMergeTree is a dedupe engine, not a diff engine: a
208
+ re-parse yielding *fewer* messages leaves the old higher-`seq` rows with nothing written
209
+ over them. The shipper used to delete the session's rows first to clear that tail — and
210
+ a shorter re-parse has two indistinguishable causes. Either an adapter bug was fixed and
211
+ the extra rows are junk, or Claude Code **compacted** the transcript, or the retention
212
+ window (`cleanupPeriodDays`, 30 days by default) took it. In the last two cases the house
213
+ holds the only surviving copy, and the delete destroyed it.
214
+
215
+ So rows carry an `epoch`: which parse of the session they belong to.
216
+
217
+ - **Nothing changed** (the common case, including ordinary growth): same epoch, rows
218
+ dedupe exactly as before, no extra storage.
219
+ - **Shorter, or rewritten at a position the house already holds**: the new parse goes to
220
+ `epoch + 1`. The old one stays complete and readable. You pay storage only when the old
221
+ rows are irreplaceable.
222
+
223
+ Reads show one parse per session — the newest — so counts, tokens and cost are unchanged.
224
+ `/mem:sql` and any hand-written query should filter the same way; the skill carries
225
+ the clause.
226
+
227
+ **Imported history is protected the same way.** `origin` says who wrote a row, and it is
228
+ in the sorting key of `messages` and `tool_calls`, so ReplacingMergeTree cannot collapse
229
+ an imported row against a shipped one. Anything you imported from an older house, another
230
+ product, or a machine that no longer exists survives every re-ship. `sessions` is the
231
+ deliberate exception — one row per session, no `origin` and no `epoch` in its key, because
232
+ a session's metadata has a single current version and a second row makes every rollup
233
+ count its messages twice.
234
+
235
+ The shipper verifies the sorting keys before it writes and refuses if they are wrong, so
236
+ an old house cannot be corrupted by a new shipper. `memhouse migrate-rooms` rebuilds it:
237
+ copy, atomic swap, and the old room kept as `<room>_pre_epoch` for you to drop. The house
238
+ records the move in `house_events`, and `memhouse doctor` reads it back.
220
239
 
221
240
  ## Troubleshooting
222
241