Files
poimen-memory/tasks/M2.6-rebuild-from-log.md
T

99 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M2.6 — `mem rebuild --from-log`
| Field | Value |
|---|---|
| Phase | M2 — Projections |
| Size | M — 13 days |
| Status | ⬜ Not started |
| Flags | — |
| Spec | inlined below |
| Blocks | M2.4, M2.5 |
## Goal
Drop both projections and rebuild them from the log alone — the command that
makes "the log is authoritative" a testable claim instead of a slogan.
## Facts (inlined — no spec read needed)
```
mem rebuild --from-log --project poimen # both projections
mem rebuild --from-log --project poimen --vault-only
mem rebuild --from-log --project poimen --db-only
```
The claim: **anything not reconstructible from the log has a hidden input, and
that is a bug.** Rebuild is the executable form of that claim. If it needs the
existing vault or database to produce correct output, something is being carried
across that is not in the record.
Rebuild does **no model calls except embeddings**. Gate decisions, memory text and
provenance are all in the log already; re-running the controller would produce
different text and defeat the purpose.
Order matters: clear → insert all nodes → insert all edges → project vault. Edges
before nodes violates the foreign key (M2.4).
Embeddings are the expensive part. Cache by `sha256` so a rebuild after a vault
template change does not re-embed unchanged nodes.
## Steps
1. `mem rebuild --from-log --project P`.
2. Read every log file for the project, in run-id order.
3. `clear_project`, then two-pass node/edge insert, batching embeddings.
4. Project the vault (M2.5), overwriting.
5. Embedding cache keyed by sha, on disk under `.cache/`, so it survives runs.
6. Report counts: nodes by level, edges, embeddings computed vs cached.
7. Refuse to run if any log file is incomplete (no `run_end`) unless `--allow-partial`
— rebuilding from a half-run silently produces a half-memory.
## Acceptance
- Rebuild from an empty database and empty vault produces the full state.
- Rebuild twice produces identical database rows and identical vault bytes.
- No controller model calls occur.
- An incomplete log is refused by default.
## Verify
**Harness:** log fixture, disposable Postgres, temp vault. A controller client
that panics if called.
**Integration test**`tests/it_rebuild.rs`:
1. `a1_from_empty` — drop everything, rebuild, assert node counts per level match
the log's records.
2. `a2_idempotent_db` — rebuild twice, assert row count unchanged and no
`created_at` churn on existing rows.
3. `a3_idempotent_vault` — rebuild twice, assert vault bytes identical.
4. `a4_no_controller_calls` — inject a panicking chat client; assert rebuild
succeeds.
5. `a5_embedding_cache` — second rebuild computes zero embeddings.
6. `a6_edge_order` — a log whose first memory references a later-inserted parent
still rebuilds, proving two-pass.
7. `a7_incomplete_refused` — a log with no `run_end` exits non-zero; with
`--allow-partial` it succeeds.
8. `a8_log_is_sufficient` — delete the vault and the database entirely, rebuild,
and assert the result equals a committed golden. This is the authority claim.
**Command:** `cargo test -p mem-cli rebuild`
**False pass:**
- Rebuilding on top of existing state. It masks every hidden input, because the
missing piece is already there from the previous run. Assertions 1 and 8 must
start from nothing.
- Asserting row counts only. A rebuild that inserts the right number of rows with
wrong `parents` passes; assertion 6 and M2.7's edge closure are what check the
graph.
## Traps
- Re-running the controller during rebuild. It produces different memory text
every time, the vault never stabilises, and M2.8 can never pass.
- Caching embeddings by node id rather than content hash. Ids change between
rebuilds; hashes do not, which is the whole point of content identity.
---
Background: [DESIGN.md](../DESIGN.md) — Authority model