Files
poimen-memory/tasks/M2.8-m2-gate.md
T

4.0 KiB
Raw Blame History

M2.8 — M2 composition gate

Field Value
Phase M2 — Projections
Size M — 13 days
Status Not started
Flags gate
Spec inlined below
Blocks all of M2

Goal

Prove the authority model: the log is sufficient, and both projections are genuinely derived.

Facts (inlined — no spec read needed)

The claim under test — poimen's own principle, applied here:

Nothing derived is authoritative. If it cannot be dropped and rebuilt byte-identically, it has hidden inputs and that is a bug.

The gate is destructive by design: it deletes the vault and truncates the database, rebuilds from the log alone, and diffs. Anything that survives only because it was already there is a hidden input, and this is the only test that finds it.

rm -rf vault/poimen
psql -c "delete from memory_node where project = 'poimen'"
mem rebuild --from-log --project poimen
git -C vault diff --exit-code          # empty diff is the only pass

git diff --exit-code on a tracked vault is the assertion. It compares against what was committed, so it also catches a projector change that was not intended.

Run it twice: once from empty (sufficiency) and once on top of itself (idempotence). Both must produce the same bytes.

Steps

  1. verify/m2.8.sh performing the destructive rebuild above.
  2. Assert the vault diff is empty and the database node counts match the log.
  3. Run mem verify and assert zero violations.
  4. Second rebuild without clearing; assert still empty diff and unchanged row count.
  5. Assert no controller model calls (embeddings are allowed and expected).
  6. Commit expected/m2.8.txt with the count summary; diff against it.

Acceptance

  • Vault rebuilt from nothing is byte-identical to the committed vault.
  • Database node/edge counts match the log's records exactly.
  • mem verify reports zero violations.
  • Second rebuild changes nothing.

Verify

Harness: disposable database, git-tracked vault, real log. Long-running; a nightly or on-demand job.

Integration testverify/m2.8.sh, output diffed against expected/m2.8.txt:

  1. a1_vault_from_empty — delete vault, rebuild, git diff --exit-code empty.
  2. a2_db_from_empty — truncate, rebuild, counts per level equal the log's.
  3. a3_verify_cleanmem verify exits 0.
  4. a4_rebuild_idempotent — rebuild again, diff still empty, row count unchanged.
  5. a5_no_controller_calls — assert zero calls to the chat route during rebuild (count via the record dir from M1.1, or a proxy).
  6. a6_projection_independence--vault-only then --db-only produces the same end state as a combined rebuild.
  7. a7_log_alone_suffices — move the log to a fresh checkout with no vault and no database, rebuild, diff against the committed vault. The strongest form of the claim.

Command: bash verify/m2.8.sh | diff - expected/m2.8.txt

False pass:

  • Running the gate without deleting the vault first. A projector that only writes changed files produces an empty diff trivially, and the hidden input survives.
  • Diffing an untracked vault. git diff on untracked files reports nothing, so the assertion passes vacuously. The vault must be committed, or the script must compare against a committed golden tree explicitly.
  • Allowing controller calls "because it is easier". Rebuild then produces new memory text each run and the gate can never pass — at which point the usual fix is to weaken the gate.

Traps

  • Treating a non-empty diff as a projector bug by default. It is equally likely to be a hash bug: if sha256 includes a timestamp (M0.2), every rebuild produces new nodes and the vault churns. Check identity before blaming rendering.
  • Running against production data with the destructive script and no backup. The log is the record; if that is intact, everything is recoverable — which is exactly why the log must be tracked in git before this gate is first run.

Background: DESIGN.md — Authority model, Verification