Skip to content

fix(reviewer): bind failed checks to actionable source evidence - #548

Merged
seonghobae merged 97 commits into
mainfrom
codex/noema-failed-check-source-rca
Sep 7, 2026
Merged

fix(reviewer): bind failed checks to actionable source evidence#548
seonghobae merged 97 commits into
mainfrom
codex/noema-failed-check-source-rca

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Scope

Bind failed checks to actionable current-head source evidence while keeping provider/model routing, quarantine/security and outbound authority outside Noema. Finding.line remains an exact positive integer or None.

Current exact authority — 2026-09-07 KST

Protected Noema is GitHub-verified main@4c1d174adae3a3cc1ced54913ac2515d768647ef after normal #536 integration. Protected central .github/main is GitHub-verified 78a4937c684a54ca8e415822c913742f41c6efc4 after #2009.

#548 is ordinary/non-force converged onto the protected Noema foundation. Helper #557 merged protected main@4c1d174... into the feature branch with the normal merge method, producing unchanged exact head fb44888bd571cae61dbfc93c1b46675855fbfc9c. This preserves both histories; no force push, destructive rebase, squash, or predecessor-GREEN reuse occurred.

The failed-check/source-binding delta remains valid: current-head failed checks bind to actionable source evidence and Finding.line retains the exact positive-integer-or-None contract. The merge preserves #536's provider-neutral noema-core Shared Kernel and its package/install/test wiring together with #548's source-provenance schema, parser/sandbox contract, prompt evidence fields, tests and documentation. No provider/model discovery, retry/failover, quarantine/security, outbound authority or gate threshold is moved into this lane.

Fresh exact-head verification

For unchanged exact fb44888bd571cae61dbfc93c1b46675855fbfc9c:

  • ci 34097045395: terminal success;
  • reviewer-ci 34097045410: terminal success;
  • required Security Scan 34097045483: terminal success;
  • patch-validator-image 34097045443: in progress.

The image job is assigned to GitHub-hosted runner 1001738797; exact checkout, stale-head refusal, Trivy/Syft/Grype setup, exact dependency materialization, and Buildx setup completed successfully. Build exact-head patch-validator image remains the active step. No terminal image GREEN is claimed.

Fresh review-thread authority is clean. Keep Draft until the unchanged exact head receives terminal-success image verification and protected Noema/central identities are rechecked immediately before normal integration. Predecessor checks do not transfer.

Summary by CodeRabbit

  • 새로운 기능

    • 리뷰 결과에 우선순위, 증거 유형, 관찰 가능한 영향, 트리거, 회귀 명령, 수정 제안 등 실행 가능한 정보가 포함됩니다.
    • 실패한 체크마다 정확한 체크 이름과 현재 코드 위치에 연결된 원인 분석을 요구합니다.
    • 유효한 코드 라인에 인라인 수정 제안을 게시할 수 있습니다.
  • 버그 수정

    • 실패한 체크의 증거가 부족하거나 수정 제안이 올바른 변경 라인에 연결되지 않으면 리뷰가 차단됩니다.
    • GitHub Actions 로그 조회 실패 시 체크 실행 주석을 대체 증거로 활용합니다.
  • 문서

    • 새로운 리뷰 계약과 차단 조건을 문서화했습니다.

Signed-off-by: Seongho Bae <me@seonghobae.me>
@seonghobae
seonghobae marked this pull request as draft September 4, 2026 09:20
@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 476567b2-5da2-4411-bfbb-875c2ad97741

📥 Commits

Reviewing files that changed from the base of the PR and between 4c1d174 and fb44888.

📒 Files selected for processing (18)
  • docs/noema-agent-sandbox-plan.md
  • reviewer/README.md
  • reviewer/noema_reviewer/__init__.py
  • reviewer/noema_reviewer/agent.py
  • reviewer/noema_reviewer/gating.py
  • reviewer/noema_reviewer/github_io.py
  • reviewer/noema_reviewer/models.py
  • reviewer/tests/test_agent.py
  • reviewer/tests/test_check_run_pagination.py
  • reviewer/tests/test_deterministic_finding_identity.py
  • reviewer/tests/test_failed_check_causal_binding.py
  • reviewer/tests/test_failed_check_coverage_edges.py
  • reviewer/tests/test_finding_line_contract.py
  • reviewer/tests/test_gating.py
  • reviewer/tests/test_github_io.py
  • reviewer/tests/test_models.py
  • reviewer/tests/test_non_success_check_gate.py
  • reviewer/tests/test_verdict_invariants.py

📝 Walkthrough

Walkthrough

Finding 계약을 확장하고, 실패한 현재 헤드 검사에 대한 개별 RCA 바인딩과 제안 diff 앵커 검증을 추가했습니다. GitHub Actions 로그 수집은 검증된 job URL을 사용하며, 리뷰 본문과 인라인 suggestion 게시 형식도 확장했습니다.

Changes

리뷰 계약 및 게이트

Layer / File(s) Summary
Finding 계약과 공개 모델
reviewer/noema_reviewer/models.py, reviewer/noema_reviewer/__init__.py, reviewer/noema_reviewer/agent.py, docs/noema-agent-sandbox-plan.md, reviewer/README.md
Finding에 우선순위, 증거 유형, 영향, 트리거, 회귀 명령, 검사명과 제안 diff를 추가했습니다. 양의 정수 라인, 회귀 명령, Markdown fence를 검증합니다.
에이전트 지침과 결정론적 게이트
reviewer/noema_reviewer/gating.py
실패한 검사마다 자체 source-bound RCA를 요구합니다. 현재 헤드 오른쪽 diff 라인에 연결되지 않은 suggestion과 actionable RCA가 없는 실패 검사를 BLOCKED로 처리합니다.
GitHub 증거 수집과 리뷰 게시
reviewer/noema_reviewer/github_io.py, reviewer/README.md
repository-bound details_url에서 Actions job ID를 추출합니다. 로그 실패 시 동일 Check Run의 annotations를 사용합니다. 구조화된 finding과 RIGHT side inline suggestion을 게시합니다.
게이트 및 모델 회귀 검증
reviewer/tests/*
검사별 RCA 바인딩, diff 앵커, 모델 필드 검증, job ID 분리, annotation fallback, 리뷰 게시 형식을 검증합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant apply_gates
  participant GitHub
  Agent->>apply_gates: 구조화된 Finding과 suggested_diff 제출
  apply_gates->>apply_gates: 실패 검사 RCA와 diff 앵커 검증
  apply_gates-->>GitHub: 검증된 verdict 게시
  GitHub-->>GitHub: RIGHT-side suggestion comment 생성
Loading
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/noema-failed-check-source-rca

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.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

* feat(reviewer): enforce actionable finding contract

Signed-off-by: Seongho Bae <me@seonghobae.me>

* test(reviewer): align causal findings with action contract

Signed-off-by: Seongho Bae <me@seonghobae.me>

---------

Signed-off-by: Seongho Bae <me@seonghobae.me>
@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Head commit changed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Preserve current protected main and the #548 failed-check/source-binding delta by ordinary non-force merge after #536 integration.
@seonghobae
seonghobae marked this pull request as ready for review September 7, 2026 11:39
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@seonghobae
seonghobae merged commit e6de53a into main Sep 7, 2026
16 of 18 checks passed
@seonghobae
seonghobae deleted the codex/noema-failed-check-source-rca branch September 7, 2026 11:40

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 3 potential issues.

Devin Review

Comment on lines +64 to +65
elif line[0] != "-":
line_number = None

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 No-newline patches reject valid suggestions

A standard no-newline marker resets _right_side_diff_lines before the replacement line. Valid suggestions then block the entire review as unanchored.

Prompt for agents
Update reviewer/noema_reviewer/gating.py so _right_side_diff_lines handles the standard unified-diff `\ No newline at end of file` metadata without terminating the active hunk. The marker does not consume either side's line number and can appear between a deleted line and its added replacement. Add a regression test using an actual one-line replacement where both old and new files lack a trailing newline, and verify the new-side line remains a valid suggestion anchor.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +259 to +267
actionable_checks = {
finding.check_name
for finding in verdict.findings
if finding.check_name is not None
and finding.severity in BLOCKING_SEVERITIES
and finding.path in changed_paths
and isinstance(finding.line, int)
and not isinstance(finding.line, bool)
and finding.line > 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Unrelated evidence clears failed checks

A finding with any evidence_type can clear a failed check by copying its name. The gate never requires failed-check or log evidence.

Suggested change
actionable_checks = {
finding.check_name
for finding in verdict.findings
if finding.check_name is not None
and finding.severity in BLOCKING_SEVERITIES
and finding.path in changed_paths
and isinstance(finding.line, int)
and not isinstance(finding.line, bool)
and finding.line > 0
actionable_checks = {
finding.check_name
for finding in verdict.findings
if finding.check_name is not None
and finding.severity in BLOCKING_SEVERITIES
and finding.evidence_type is EvidenceType.FAILED_CHECK
and finding.path in changed_paths
and isinstance(finding.line, int)
and not isinstance(finding.line, bool)
and finding.line > 0
}
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +259 to +269
actionable_checks = {
finding.check_name
for finding in verdict.findings
if finding.check_name is not None
and finding.severity in BLOCKING_SEVERITIES
and finding.path in changed_paths
and isinstance(finding.line, int)
and not isinstance(finding.line, bool)
and finding.line > 0
}
unresolved = [name for name in failed if name not in actionable_checks]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Duplicate failures share one finding

Two failed runs with the same name are both cleared by one finding. actionable_checks loses occurrence counts because it is a set.

Prompt for agents
Preserve multiplicity when matching failed Check Runs to findings in reviewer/noema_reviewer/gating.py. Each blocking finding must consume at most one failed check occurrence, even when multiple CheckConclusion entries share the same name. Add a regression test with two failed checks named identically and one bound finding, which must leave one blocker unresolved.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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

Labels

bug Something isn't working priority: medium Normal-priority or P2 work status: draft Draft pull request type: bug Defect or incorrect behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant