- catalog: Store trait (FsStore: temp+fsync+rename+dir fsync; MemStore), Journal: CRC-checked JSON-lines op log with sequence numbers + atomic snapshots; torn final record dropped and truncated, stale records after a snapshot skipped, mid-log damage preserved as catalog.log.damaged-N. - PushHistory op so each edit logs one history step (not the full history). - engine: Session::open_library/persist/close_library; every top-level command is fsynced before returning; presets.json + view.json; library.info / library.compact commands. - app: default library ~/Pictures/LightCraft Library (LIGHTCRAFT_LIBRARY or --library DIR override), --memory for throwaway sessions, snapshot on quit. - tests: proptest replay(log)==state with random snapshots/reopens, every truncation of the last record, stale log, mid-log damage, FsStore, engine restart without close. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README showcase
The screenshots in docs/images/ are captured by driving LightCraft over its control channel.
# public-domain set (downloaded into the gitignored corpus/, see assets/ATTRIBUTION.md for sources)
cargo run --release -p lightcraft -- --memory --control 7980 corpus/images/pd &
python3 docs/showcase/run.py docs/showcase/pd-edits.jsonl
# procedural demo library
cargo run --release -p lightcraft -- --memory --control 7980 &
python3 docs/showcase/run.py docs/showcase/demo.jsonl
# compress for the repo (macOS)
for f in docs/images/*.png; do sips -s format jpeg -s formatOptions 82 "$f" --out "${f%.png}.jpg" && rm "$f"; done
run.py sends each JSON line ({"method":…,"params":…} or {"sleep": seconds}) to 127.0.0.1:7980.