Skip to content

feat(scoring): commit successful completion with outbox atomically - #69

Closed
seonghobae wants to merge 15 commits into
mainfrom
feat/scoring-completion-outbox-20260814-1817
Closed

seonghobae wants to merge 15 commits into
mainfrom
feat/scoring-completion-outbox-20260814-1817

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Why

Protected main persists fenced scoring-job completion and transactional outbox evidence, but those APIs can still be called in separate commits. A crash between accepting an immutable result and enqueuing its integration evidence can therefore leave downstream consumers permanently unaware of a valid completed result.

What

  • Add a bounded postgres_scoring_completion composition that executes the existing fenced completion transition and existing outbox insert in the same caller-owned READ COMMITTED transaction.
  • Preserve exact-replay dispositions independently so legacy exact partial state can be reconciled without rewriting immutable history.
  • Add real PostgreSQL tests proving completion/outbox commit together, exact replay stays idempotent, a late outbox conflict rolls the completion back to the leased state, and completion failures enqueue nothing.
  • Keep event schema/tenant/subject/correlation semantics with the caller's versioned integration contract; no new psychometric math, migration, or external event schema is invented here.

Verification intent

  • cargo test --test postgres_scoring_completion_outbox
  • full Runtime CI, exact statement/branch coverage, docs, security and independent review on the exact head

Base at branch creation: cc5850a0d1eacbbf16d03075534fce460a8286e6.

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f5fb23c6-1636-430d-bbca-0bace2d9c365


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 43845df9266024348bfebd54e2e98d277c3db070.

  • Head SHA: 43845df9266024348bfebd54e2e98d277c3db070

  • Workflow run: 31851486961

  • Workflow attempt: 1

Coverage evidence

Coverage Decision

  • Result: FAIL
  • Test evidence: not proven passing
  • Docstring evidence: not proven passing when configured
  • Failure count: 1

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (2 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (2 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Test (2 files)"]
  S2 --> I2["regression suite"]
  I2 --> R2["Review risk: Test (2 files)"]
  R2 --> V2["targeted test run"]
Loading

@opencode-agent

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: 43845df9266024348bfebd54e2e98d277c3db070
  • Workflow run: 31851486961
  • Workflow attempt: 1
  • Gate result: REQUEST_CHANGES (approval step)

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 43845df9266024348bfebd54e2e98d277c3db070.

  • Head SHA: 43845df9266024348bfebd54e2e98d277c3db070

  • Workflow run: 31851486961

  • Workflow attempt: 1

Coverage evidence

Coverage Decision

  • Result: FAIL
  • Test evidence: not proven passing
  • Docstring evidence: not proven passing when configured
  • Failure count: 1

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (2 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (2 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Test (2 files)"]
  S2 --> I2["regression suite"]
  I2 --> R2["Review risk: Test (2 files)"]
  R2 --> V2["targeted test run"]
Loading

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.
Keep postgres_scoring_completion beside the landed result-snapshot
adapter. Restore Active PR #69 after the stale #76 heading, and seed the
#81 claim deadline on the inherited #72 recovery fixture so exact-head CI
can classify the processing restore row.
@cursor

cursor Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

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>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (HEAD cda680c)

This head closes the crash window it claims: fenced successful completion and the bound outbox insert share one caller-owned READ COMMITTED transaction. Exact replay and both mixed legacy dispositions now have real PostgreSQL proof. A late outbox ConflictingReplay rolls the job back to leased. A missing job never reaches enqueue. Foreign source, subject, or completion time is rejected before any write.

OpenCode REQUEST_CHANGES on 43845df is stale coverage-evidence, not a current-head defect.

Do not enlarge this PR

  • Do not bind ResultSnapshot or invent an envelope field for scoring_result_ref. The job row already stores result_ref. Result publication stays a later worker/schema slice (UML persists that snapshot after narrative provenance).
  • Do not add a completed_at migration here. Duplicate completion still cannot verify historical time; that is pre-existing on scoring_job_state.

Land this head when

  1. Runtime CI, exact statement/branch coverage, docs, and security checks are terminal-success on this exact SHA.
  2. An independent non-author review approves this exact SHA.

Next product slice after merge

Wire the scoring worker to this helper with a stable event_ref (job + result identity). A retry that mints a new event_ref after an accepted completion will insert a second outbox row. Permanent failure still has no atomic outbox composition and is not exact-replay idempotent; that is the next reliability hole, not a reason to block this PR.

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

) -> Result<(), ScoringCompletionOutboxError> {
if completion_event.source() != SOURCE_REF
|| completion_event.subject_ref() != scoring_job_ref
|| completion_event.occurred_at_unix_ms() != completed_at_unix_ms

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bind set is source + job + occurred_at / completed_at. Leave ResultSnapshot and scoring_result_ref to the worker/schema PR. Keep event_ref stable across retries: a new identity after Duplicate completion inserts a second outbox row rather than reconciling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants