Files
poimen-memory/tasks/M0.8-m0-gate.md
T

88 lines
3.5 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.
# M0.8 — M0 composition gate
| Field | Value |
|---|---|
| Phase | M0 — Read-only spine |
| Size | M — 13 days |
| Status | ⬜ Not started |
| Flags | gate |
| Spec | inlined below |
| Blocks | all of M0 |
## Goal
Prove the parts compose and that the swappable part is genuinely swappable —
the properties no single M0 task owns.
## Facts (inlined — no spec read needed)
The claim this phase makes: **a new input kind is added by implementing
`RecordSource`, and nothing downstream changes.** If that is false, the crate
split bought nothing and the streaming work later will be a rewrite.
The gate proves it by adding a third source that resembles nothing already
supported, and asserting the rest of the pipeline is untouched.
Second claim: the whole phase is free. No model calls, so the gate is a CI job
that runs on every push without a gateway or credentials.
## Steps
1. Implement `SyntheticSource` in the test tree only — generates records from a
seed, has no file format, and deliberately produces a record larger than the
chunk budget and a run of empty-text records.
2. Assert `chunks()` handles it with **no change** to `mem-chunk`.
3. Assert dependency direction still holds (M0.1 assertion 3) after three sources
exist — this is when someone is tempted to reach backwards.
4. Run `mem ingest --dry-run` over all three sources for one project and diff the
summary against a committed expected file.
5. Wire the whole thing as a required CI job.
## Acceptance
- Three sources, one `RecordSource`, zero source-specific branches in `mem-chunk`
or `mem-cli`.
- Dry-run summary diffs empty against the committed expectation.
- CI job passes with no network and no credentials.
## Verify
**Harness:** committed expected-output file, diffed. The script's output is the
review artifact.
**Integration test**`tests/it_m0_gate.rs`:
1. `a1_third_source_needs_no_downstream_change``SyntheticSource` flows through
`chunks()`; assert `git diff --stat crates/mem-chunk crates/mem-cli` is empty
for the commit that added it (enforced by a CI step, not by the test binary).
2. `a2_no_source_specific_branches` — grep `crates/mem-chunk` and `crates/mem-cli`
for the strings `pi:`, `claude:`, `sessionId`, `toolResult`; assert none
appear outside `mem-ingest`.
3. `a3_dry_run_golden` — run the dry run over all three sources, diff against
`expected/m0-gate.txt`; empty diff is the only pass.
4. `a4_offline` — the entire gate runs with networking disabled.
5. `a5_lossless_end_to_end` — records in equals records out, across all three
sources composed.
**Command:** `cargo test --workspace m0_gate`
**False pass:**
- Adding `SyntheticSource` in a way that mirrors the pi format. It then exercises
the same code path and proves nothing about generality. It must have no file,
no header line, and an oversized record.
- Assertion 3 passing because the expected file was regenerated in the same
commit. A changed `expected/` file in a diff is a claim that the contract
changed, and must be reviewed as one.
## Traps
- Skipping assertion 2 because "obviously there are no source-specific branches".
There will be — the first `if provenance.starts_with("pi:")` gets added to fix
a real bug and is entirely reasonable in isolation.
- Letting the gate need credentials. The value of an offline gate is that it runs
on every push; the moment it needs a gateway key it becomes a nightly job that
nobody watches.
---
Background: [DESIGN.md](../DESIGN.md) — `mem-chunk`, Verification