Repository navigation
fix(backend): address Greptile review findings on the orchestrator - #251
Conversation
Four findings from the apex review of PR #247, each pinned by a regression test in test_greptile_followup.py: - Amendment runs hydrated the base packet: RunRecord now carries the accepted packet_uri and hydrate_packet resolves manifest paths under the packet's own prefix (artifacts.py:202). - on_confirmation passed a capture_id string where confirm() expects a Reads record, so device corrections were never applied. It now loads the newest run's reads artifact, applies the answer, and persists the updated record (api.py:173). - A retry inherited the previous attempt's entered_at, so the timeout sweep cancelled the replacement worker before it started. _spawn_one clears the timestamp when a new attempt begins (coordinator.py:266). - Final success always read verdicts/verdict.C.json; it now reads the run's selected profile verdict and falls back to C (coordinator.py:571). The committed jobs.v0.schema.json is regenerated for the new RunRecord.packet_uri field.
|
Important Review skippedBot user detected. To trigger a single review, invoke the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
|
|
Independent review (Obvious, Autobuild + Max) I reviewed this draft as an outside reader: read the body, comments and full diff, checked out head Verdict: readyThe PR does what the body claims, the four regression tests genuinely pin their findings, and I found no regression. Findings below are minor; none block. Findings (ranked by severity)
Notes, not findings: the hook resolves reads from the newest run only, so if the newest run has no What I verified (commands + results)
What I could not verify
|
|
Note Review skipped Codemetrics is installed on this repository, but it hasn't been added to your team yet. To enable AI code reviews for this repo, go to your dashboard and add BaseScanning to your team's repositories. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
[High impact] Modifies orchestrator packet handling and confirmation flow. Fix amendment filename collisions and confirmation timing gaps before merging.
|
| if rel is None: | ||
| continue | ||
| jobs.append((packet_dir / rel, f"captures/{capture_id}/{rel.as_posix()}")) | ||
| jobs.append((packet_dir / rel, f"{base}{rel.as_posix()}")) |
There was a problem hiding this comment.
Amendments still use old photos
When an amendment reuses a base filename such as stills/meter.jpg, _packet_file_jobs copies the base image and adds its path to seen. The manifest loop then skips that filename before using the new amendment prefix. The replacement image is copied under amendments/{id}/ instead of the path named in the manifest, so the worker analyzes the original photo.
Resolve committed records relative to the selected packet. Add a regression test with matching base and amendment filenames.
Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/server/orchestrator/artifacts.py
Line: 280
Comment:
**Amendments still use old photos**
When an amendment reuses a base filename such as `stills/meter.jpg`, `_packet_file_jobs` copies the base image and adds its path to `seen`. The manifest loop then skips that filename before using the new amendment prefix. The replacement image is copied under `amendments/{id}/` instead of the path named in the manifest, so the worker analyzes the original photo.
Resolve committed records relative to the selected packet. Add a regression test with matching base and amendment filenames.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| key = _latest_reads_key(services, capture_id) | ||
| if key is None: | ||
| return |
There was a problem hiding this comment.
Early corrections never reach analysis
The endpoint accepts confirmations during upload and processing, but this hook returns when reads/reads.json does not exist. Nothing applies the saved answer when the reads stage finishes. Retrying the same request also returns before calling the hook, so a successful correction can leave the later analysis using the original value.
Apply saved confirmations when reads are written, and test a confirmation submitted before the run starts.
Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/server/orchestrator/api.py
Line: 169-171
Comment:
**Early corrections never reach analysis**
The endpoint accepts confirmations during upload and processing, but this hook returns when `reads/reads.json` does not exist. Nothing applies the saved answer when the reads stage finishes. Retrying the same request also returns before calling the hook, so a successful correction can leave the later analysis using the original value.
Apply saved confirmations when reads are written, and test a confirmation submitted before the run starts.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| # Persist the corrected record so later results read the answer. | ||
| services.storage.put_bytes(key, updated.model_dump_json().encode(), "application/json") # type: ignore[attr-defined] |
There was a problem hiding this comment.
Results ignore later corrections
Captures in needs_views or manual_review still accept confirmations, but an answer submitted after the result is built changes only reads/reads.json. The result endpoint serves the existing result/result.json, whose meter value was copied from reads earlier. This hook neither rebuilds that result nor reruns criteria that already used the old reads, so users still see the old value after a successful correction.
Refresh the affected outputs after applying the answer, and test a correction followed by a result fetch.
Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/server/orchestrator/api.py
Line: 184-185
Comment:
**Results ignore later corrections**
Captures in `needs_views` or `manual_review` still accept confirmations, but an answer submitted after the result is built changes only `reads/reads.json`. The result endpoint serves the existing `result/result.json`, whose meter value was copied from reads earlier. This hook neither rebuilds that result nor reruns criteria that already used the old reads, so users still see the old value after a successful correction.
Refresh the affected outputs after applying the answer, and test a correction followed by a result fetch.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Stacked on #247 (targets its head branch). Addresses the four findings from the Greptile apex review; each is pinned by a regression test in
server/orchestrator/tests/test_greptile_followup.py.Fixes
Amendment runs hydrated the base packet (artifacts.py:202) —
start_runacceptedpacket_uributRunRecorddropped it andhydrate_packetalways fetchedcaptures/{capture_id}/packet.json, so an amendment run ran against the original packet and manifest-listed files resolved under the wrong prefix.RunRecordnow storespacket_uri,stage_contextpasses it through, and_packet_file_jobsderives the storage prefix from the packet's own key (captures/{cap}/amendments/{amd}/for amendments).Device confirmations never applied (api.py:173) —
on_confirmationpassed thecapture_idstring whereconfirm()expects aReadsrecord; every call raised insidesafe_hookwhile the endpoint returned success. The hook now loads the newest run'sreads/reads.jsonvia the stage-artifact overlay, applies the answer withconfirm(), and persists the updated record so later results read the correction.Retries started already timed out (coordinator.py:266) —
_spawn_oneresetstarted_atbut left the previous attempt'sentered_at, which_sweep_timeoutsuses as the attempt budget, so a replacement worker could be cancelled immediately._spawn_oneclearsentered_atwhen a new attempt begins; the worker's first heartbeat re-sets it on stage entry.Final status read the wrong rules profile (coordinator.py:571) —
_apply_successalways readverdicts/verdict.C.jsoneven when the run selected profile A/B/S. It now reads the run's own profile verdict (C fallback) before deciding the outcome.Checks
make lintclean (import-boundary contracts kept).tests/test_ssr_overlap_check.py, 4 ×server/eval/tests/test_gates.py) reproduce on the pristine base commit and are unrelated — verified by stashing this change.jobs.v0.schema.jsonregenerated for the newpacket_urifield.Authored by Sam Gu 127461594+SamGu-NRX@users.noreply.github.com.