Files
poimen-memory/tasks/M0.1-cargo-workspace.md
T

3.5 KiB

M0.1 — Cargo workspace + crate skeletons

Field Value
Phase M0 — Read-only spine
Size S — under 1 day
Status Not started
Flags
Spec inlined below
Blocks

Goal

The six-crate workspace, building clean, with the dependency direction fixed before any code exists to violate it.

Facts (inlined — no spec read needed)

crates/
  mem-core/     domain types; Level; gate-response parser; the gated loop
  mem-chunk/    RecordSource trait; ChunkPolicy; FlushTrigger
  mem-llm/      gateway client — chat, embeddings, rerank
  mem-ingest/   source adapters: pi sessions, claude transcripts
  mem-store/    JSONL log; pgvector repo; Obsidian projector
  mem-cli/      binary `mem`

Dependency direction, enforced from the start:

mem-cli  ->  mem-ingest, mem-store, mem-llm, mem-chunk, mem-core
mem-store ->  mem-core
mem-ingest -> mem-chunk, mem-core
mem-chunk ->  mem-core
mem-llm   ->  mem-core
mem-core  ->  (nothing in this workspace)

mem-core depends on no sibling. It holds the types every other crate speaks, so a dependency out of it is a cycle waiting to happen.

Workspace deps to pin now, so versions do not drift per crate: tokio, futures, serde, serde_json, serde_yaml, anyhow, thiserror, sha2, clap, reqwest, tracing.

Steps

  1. Cargo.toml at the repo root with [workspace] members = [...] and a [workspace.dependencies] block holding every shared crate version.
  2. Six member crates, each declaring deps as foo.workspace = true.
  3. mem-cli is the only [[bin]]; the rest are libraries.
  4. Add rust-toolchain.toml pinning a version, so CI and laptop agree.
  5. .gitignore: target/, vault/ — but not log/ and not memory-tasks/. The log is authoritative and the board carries acceptance criteria; both are tracked.
  6. Wire a CI job running cargo build --workspace and cargo clippy --workspace -- -D warnings.

Acceptance

  • cargo build --workspace succeeds from a clean checkout.
  • cargo clippy --workspace -- -D warnings is clean.
  • mem-core has zero intra-workspace dependencies.

Verify

Harness: cargo itself, plus a dependency assertion that does not trust the manifests to be read by a human.

Integration testtests/it_workspace.rs in the root:

  1. a1_all_members_build — shell out to cargo build --workspace, assert exit 0.
  2. a2_mem_core_has_no_sibling_deps — parse crates/mem-core/Cargo.toml, assert no dependency name starts with mem-.
  3. a3_dependency_direction — parse every member manifest, build the edge set, assert it is a subset of the table above and that the graph is acyclic.
  4. a4_log_and_tasks_are_tracked — assert .gitignore matches neither log/ nor memory-tasks/.

Command: cargo test --workspace workspace

False pass:

  • Asserting the graph is acyclic only. Acyclic permits mem-core -> mem-store, which is backwards and still acyclic. Assertion 3 must check the edge set against the table, not just for cycles.
  • A CI job that runs cargo build in the root without --workspace. It builds the virtual manifest and can miss a member that does not compile.

Traps

  • Per-crate dependency versions instead of workspace.dependencies. They drift, and two versions of serde in one tree is a confusing type error much later.
  • Gitignoring log/. It is the authoritative record; ignoring it makes the whole authority model a fiction.

Background: DESIGN.md — Repository layout