feat: add the todo domain plugin -- Build With Muse Episode 06
A minimal, real reference domain built live for the episode: one tracked file (todo.txt), one task per line, tasks addressed by their own content rather than line position. Implements the required six-method core protocol only (no address-keyed merge extension, no CRDT) -- starts from muse/plugins/scaffold, most of which is unmodified.
Registered in muse/plugins/registry.py alongside the existing scaffold/ timeline/social/etc. plugins -- no core engine changes needed, per the whole point of the six-method protocol (Episode 05).
Three real bugs were found and fixed while building this on camera for the episode script, kept as regression tests here:
1. snapshot()/merge() initially hashed raw bytes for object IDs. Muse's real object format is blob_id() -- sha256("blob <size>\0" + data), Episode 03's own subject -- not a bare sha256 of the content. This made muse commit fail outright with a content-integrity error.
2. diff()'s ops were originally keyed entirely by task-level address ("todo.txt::<hash>"). muse checkout restores/deletes files by matching op["address"] against the snapshot manifest's *file* paths, so task-level addresses never matched anything -- checkout silently left stale content in the working tree with no error. Fixed by nesting task-level AddressedInsertOp/AddressedDeleteOp entries as child_ops under a single file-level PatchOp keyed by "todo.txt", matching the real pattern already used by richer domains (see the code domain's own patch/child_ops shape from Episode 02/03).
3. drift() never forwarded repo_root into diff(), so _load_tasks saw repo_root=None on both sides and returned empty sets unconditionally -- muse status on a dirty tree would have silently reported zero changes. Caught only by writing tests afterward, not live on camera.
Tests: tests/test_todo_plugin.py -- 12 tests covering schema, snapshot, diff (including regression tests for bugs 1 and 2), merge (including a real two-independent-additions-never-conflict case), and drift (including a regression test for bug 3). Full sweep alongside test_plugin_registry.py, test_domain_command_registry.py, and test_scaffold_plugin.py: 44 passed, no regressions.
Verified end-to-end via muse-dev against a real disposable repo: init, commit, two independent branches, structured diff between them, a real three-way merge with zero conflicts, and status/diff against a dirty working tree.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Semantic Changes
62 symbols
Files Changed
+3
~1
1188 in snapshot
0 comments
muse hub commit comment sha256:832d1ca80cb25129c91d8c8c190ec30af2e638a3e8160431f4704fd881bceaee --body "your comment"
No comments yet. Be the first to start the discussion.