feat(scoring): claim a due job and drive the request-bound snapshot worker - #233
cursor[bot] wants to merge 38 commits into
Conversation
Cover InvalidCompletionEnvelope on Linux llvm-cov by constructing the variant and asserting its exact Display text and absent source, plus the exact Completion/Outbox wrapper messages.
Add real PostgreSQL cases for the crash-between-old-APIs path this composition exists to repair, and record the envelope's actual source/job/time gate so callers keep event identity stable. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
A crashed worker can replay the same quarantined cause without inventing a score. A different cause fails closed instead of rewriting typed failure evidence. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Quarantine and the bound integration event share one caller-owned transaction. Exact same-cause replay is idempotent, a different cause fails closed, mixed legacy dispositions reconcile, and a late outbox conflict rolls the quarantine back. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Point the active-work slot at the completion-plus-failure successor so reviewers do not treat #69 as a separate landable head. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
A crashed scoring worker must reuse the job-plus-result or job-plus-cause outbox identity instead of minting a second event after an accepted terminal write. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Route fenced completion and permanent failure through the existing outbox helpers only after the envelope reuses the job-plus-result or job-plus-cause event_ref. A minted identity is rejected before write. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Ask ScoringWorkerEngine first, bind the stable job-plus-result or job-plus-cause event identity, then commit through the existing terminal helper so a retry cannot mint a second outbox row. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Keep job and outcome references that contain ':' from sharing one outbox event_ref after concatenation. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Engine or planner errors stay ScoringWorkerCommitError::Planning and leave the leased job untouched. A stale fence after a stable identity check surfaces Completion or Failure without writing a second terminal event. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
A later different result or a cause after accepted completion must fail closed and keep the original stable event_ref as the only terminal row. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Add ScoringRequest::from_persisted so a worker that still has scoring_request_ref can rebuild the AssessmentSpec, instrument, scoring, calibration, and optional norm pin without inventing a score or reloading response events. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Load the reconstructed scoring request, validate the caller envelope before asking a request-bound engine, and persist the immutable result snapshot in the same transaction as the fenced job and stable outbox event. A missing request, planner failure, or snapshot conflict leaves the job leased and does not invent a score. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Complete the worker snapshot inside the unexpired lease window, reject a job that names a different scoring request before the engine runs, and add Display/source plus PostgreSQL evidence for corrupt request, planner failure, snapshot conflict, and engine quarantine without an invented score. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Compose #203's job/request bind with a typed Retryable engine/transport outage so a live miss stays pending: no snapshot, no terminal outbox row, and no invented score. Exhausted retry budget quarantines the same way. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
…orker A hosted worker can now claim one due queued or retry-scheduled job and run the request-bound snapshot path using only the stored pin. A later due claim after a retryable outage persists the real snapshot. A missing job row, an early retry claim, or a retry scheduled before the outage instant fails closed without inventing a score. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
There was a problem hiding this comment.
Verdict: SOUND for a named-job claim, but do not land this in parallel with #234
Exact head 99f2e5e. This head claims one caller-named due job and drives run_scoring_worker_attempt_with_result_snapshot using the stored pin. Missing job, early retry, and InvalidRetryWindow fail closed. That slice is sound.
#234 dc14101 is the hosted landing: it selects the oldest due queued or retry-scheduled row with FOR UPDATE SKIP LOCKED, then scores only the stored pin. A buyer-facing worker cannot require the operator to name the job. Prefer #234 over this head, #217, #214, #203, #200, and #190. Leave those predecessors unmerged.
Independent non-author approval and required checks remain the merge gates on the chosen landing. This review does not approve or merge.
Sent by Cursor Automation: Fix Issues
|
Closing this Draft as the named-job scoring-worker landing superseded by current #234. The independent Cursor review on this exact #233 lineage already classified the slice as sound but explicitly selected #234 as the hosted landing because #234 chooses the oldest due queued/retry-scheduled row with |


Succeeds #214. Prefer this head over #214, #203, #200, #190, #172, #168, #167, #155, #136, #115, and #69; do not land those predecessors separately.
Why
A buyer who finished the items still has no hosted worker that claims a due job and drives the request-bound snapshot path. #214 binds the job to the stored request and schedules retryable outages, but a queued or retry-scheduled row stays idle until a caller already holds a lease and supplies the pin. Landing #214 alone leaves that hosted hole.
What this adds
claim_and_run_scoring_worker_attempt_with_result_snapshotclaims one due queued or retry-scheduled job, scores only the stored request pin, and drivesrun_scoring_worker_attempt_with_result_snapshot.next_attempt_atstaysLeaseNotDuewith no snapshot or outbox.InvalidRetryWindow, job leased, no score.InvalidReference.What this does not add
fast-mlsirmexecutionReviewer action
Review this successor and leave #214, #203, and #200 unmerged. Independent non-author approval and required checks on this unchanged exact head remain the merge gates. Never self-approve.