Merged
Conversation
Seven findings, batched into one cleanup PR. PR #3 (file-watcher) findings: * watcher.py:30 — drop unused ``import time``. * watcher.py:336 — type ``_log_future_exception`` parameter as ``concurrent.futures.Future`` (NOT ``asyncio.Future``); that's what ``asyncio.run_coroutine_threadsafe`` returns. Catch its cancellation/state errors plus the asyncio variants so the callback can't itself crash on a concurrent cancellation. * main.py:560 — surface stderr/stdout when watcher mine returns non-zero. The rc alone hides 'No mempalace.yaml found' / python tracebacks operators need to diagnose. * main.py:1202 — ``GET /watch`` now double-checks ``watcher.is_running`` so a thread crash that flips is_running to False between startup and now is reflected in the endpoint response. Lifespan still gates publication; this adds defense in depth. PR #4 (mine-queue) findings: * main.py drain replay — re-apply optional ``extract`` and ``limit`` fields. The prior drain dropped them silently, so a queue entry with those fields got replayed without. Live /mine accepts them; replay must too. * main.py drain replay — enforce the same safety guards as the live /mine endpoint: ``isinstance(dir, str)``, absolute-path, no ``..`` traversal, ``mode in {convos, projects}``, ``extract in {exchange, general}`` if set, ``limit`` int-coercible if set. Without these a queue entry could smuggle through values the live endpoint would 400. Tests: +2 — replay-extract-and-limit (asserts the new fields make it onto the subprocess argv) and skips-invalid-payload-fields (5 invalid-payload variants, each correctly skipped pre-spawn). 35 daemon tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR addresses previously identified review findings across the watcher service and the pending-mine queue drain path, focusing on correctness of cross-thread future handling, better operator diagnostics, and ensuring queued mine replays are validated consistently with live /mine requests.
Changes:
- Fix watcher future callback typing/exception handling for
asyncio.run_coroutine_threadsafe()(useconcurrent.futures.Future) and remove an unused import. - Improve subprocess failure logging (surface stderr/stdout) and make
GET /watchreflect watcher thread crashes by re-checkingis_running. - Ensure pending-mine drain replay preserves
extract/limitand enforces the same validation guards as the live/mineendpoint; add tests for these cases.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| watcher.py | Corrects the future type/exception handling for cross-thread coroutine scheduling and removes an unused import. |
| main.py | Hardens pending-mine drain replay validation, preserves optional replay fields, improves subprocess failure logs, and tightens /watch running-state reporting. |
| tests/test_mine_queue.py | Adds coverage to ensure drain replay preserves extract/limit and skips invalid queued payloads without spawning subprocesses. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+388
to
+393
| # Same valid-mode/extract sets as the live /mine endpoint — | ||
| # apply them on replay too so a queue entry can't smuggle through | ||
| # a value the live endpoint would reject (Copilot finding on | ||
| # jphein/palace-daemon#4). | ||
| VALID_MODES = {"convos", "projects"} | ||
| VALID_EXTRACTS = {"exchange", "general"} |
| "drain-mine: replay returned %s for %s\n stderr: %s", | ||
| proc.returncode, | ||
| directory, | ||
| (stderr or b"").decode(errors="replace")[:300], |
Comment on lines
+716
to
+717
| (stderr or b"").decode(errors="replace")[:500], | ||
| (stdout or b"").decode(errors="replace")[-500:], |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Batches 7 Copilot findings across PR #3 (file-watcher) and PR #4 (mine-queue).
PR #3:
timeimport_log_future_exceptioncorrectly (concurrent.futures.Future, not asyncio.Future) + catch concurrent.futures.CancelledErrorPR #4:
+2 new tests (replay-extract-and-limit, skips-invalid-payload-fields). 35 daemon tests pass.
🤖 Generated with Claude Code