Conversation
…folk#110) Implement a foreground poll-based directory watcher that automatically ingests new files into mem with per-cycle import reports. Key behaviors: - Poll loop with configurable --interval (default 30s) - Stability gate: new files must be unchanged across two consecutive scans before upload (prevents half-written file ingestion) - Change detection: (size, mtime) cost gate, sha256 authority - Changed files are reported but NOT re-ingested (file plane has no version model; re-ingest is Phase 2 sync-drive scope) - Local deletions produce local_gone reports with zero delete calls (no write-back, no deletion propagation) - Per-cycle report with closed vocabulary: scanned/ingested/deduped/ unchanged/local_gone/failed, persisted as capped JSONL - Single-instance advisory lock per watched root (flock LOCK_NB) - Graceful SIGINT/SIGTERM handling (exit 0 between cycles) - Give-up after 10 consecutive all-fail cycles with mapped exit codes - Deduped items carry server-returned id/path (not assumed --to folder) Closes bytefolk#110
Review: two blockersReviewed Blocker 1 —
|
|
Closing under the fork-workflow decision recorded on 2026-09-03: repository #110. This close is about order, not quality. It is the only one of the nine that adds So the sequence #110 needs is #139 merged, #111 settled, and then a watcher The commits are not lost. A closed fork PR keeps its head ref: git fetch https://github.com/bytefolk/mem.git refs/pull/150/head:pr-150Every file in this branch was therefore available to the re-doing work, whether |
Summary
mem put <path> --watch— a foreground poll-based directory watcher that automatically ingests new files into mem with per-cycle import reportsscanned/ingested/deduped/unchanged/local_gone/failed), persisted as capped JSONL (200 lines)Closes #110
Test plan
TestWatchNonExistentRoot— exit 2 for missing rootTestWatchUploadsNewFiles— new files uploaded after stability gateTestWatchStabilityRequiresTwoScans— file must survive two consecutive scansTestWatchChangedHashReportsOnly— modified file →changed, no re-uploadTestWatchLocalGoneNoDelete— deleted file →local_gone, zero DELETE callsTestWatchDedupedCarriesServerPath— dedup response carries server-returned id/pathTestWatchReportPersistence— JSONL report file created and populatedTestWatchSingleInstanceLock— second watcher fails fast (exit 1)TestWatchFormatJSON—--format jsonproduces structured outputTestWatchGiveUpAfterTenFailCycles— 10 consecutive all-fail cycles → exit with mapped codego vetclean