Three non-blocking findings from the #57 code review, deferred so v2.10.1 could ship. None affect correctness for normal use today.
R3 - deploy-phone.sh pkill patterns are broad
scripts/deploy-phone.sh Step 7 restarts services with pkill -9 -f '<pattern>' against the full command line. The web/mcp mutual exclusivity (node server.js vs node dist/server.js) is sound, but the patterns would also kill any future second node service, or a second cloudflared tunnel. SIGKILL skips graceful shutdown (acceptable - runit auto-restarts, SQLite WAL is crash-safe).
- Fix direction: anchor on absolute binary path, or use the runit supervise pidfile instead of
pkill -f.
R4 - dueBefore/dueAfter typed DateTime but contract is date-only
TasksController.cs GetAll. Date-only input works correctly (tested). Risk: create_task.deadline is an unvalidated z.string(), so an LLM could store a deadline WITH a time or Z suffix; then dueBefore="2026-06-01" (binds to midnight) silently excludes a task due that day at 15:00, and a Z suffix can shift the calendar date on bind.
- Fix direction: normalize deadlines to date-only on write, OR compare on
.Date with dueBefore exclusive-of-next-day, OR validate/reject time components in create_task. Needs a small design decision on deadline storage.
R8 - ProjectLayout sessionStorage merge doesn't coerce non-string text
frontend/src/components/ProjectLayout.tsx. The { ...EMPTY_FILTER, ...JSON.parse(saved) } merge correctly backfills a missing text key, but a corrupted "text": null in sessionStorage would override "" and crash downstream .trim(). Edge case only (the app always writes a string).
- Fix direction:
text: typeof parsed.text === "string" ? parsed.text : "" after parse.
Source: code review of #57 (feature/mcp-search-and-tool-improvements).
Three non-blocking findings from the #57 code review, deferred so v2.10.1 could ship. None affect correctness for normal use today.
R3 - deploy-phone.sh pkill patterns are broad
scripts/deploy-phone.shStep 7 restarts services withpkill -9 -f '<pattern>'against the full command line. The web/mcp mutual exclusivity (node server.jsvsnode dist/server.js) is sound, but the patterns would also kill any future second node service, or a secondcloudflared tunnel. SIGKILL skips graceful shutdown (acceptable - runit auto-restarts, SQLite WAL is crash-safe).pkill -f.R4 - dueBefore/dueAfter typed DateTime but contract is date-only
TasksController.csGetAll. Date-only input works correctly (tested). Risk:create_task.deadlineis an unvalidatedz.string(), so an LLM could store a deadline WITH a time orZsuffix; thendueBefore="2026-06-01"(binds to midnight) silently excludes a task due that day at 15:00, and aZsuffix can shift the calendar date on bind..Datewith dueBefore exclusive-of-next-day, OR validate/reject time components in create_task. Needs a small design decision on deadline storage.R8 - ProjectLayout sessionStorage merge doesn't coerce non-string text
frontend/src/components/ProjectLayout.tsx. The{ ...EMPTY_FILTER, ...JSON.parse(saved) }merge correctly backfills a missingtextkey, but a corrupted"text": nullin sessionStorage would override""and crash downstream.trim(). Edge case only (the app always writes a string).text: typeof parsed.text === "string" ? parsed.text : ""after parse.Source: code review of #57 (feature/mcp-search-and-tool-improvements).