Always exit 0 on a completed run; verdict lives in summary.verdict#5
Conversation
A FAIL verdict now produces process exit code 0; the verdict travels via `summary.verdict` in the JSON report and the result-sink row's `result_data`. The exit code is reserved for "the validator could not run" (exit 2 on config error). This keeps a Render cron green when the validator successfully evaluated the OBA server but found real server bugs — the caller learns the verdict from the sink, not from a "failed" job status. - `Report.ExitCode()` always returns 0; godoc updated with rationale. - JSON schema tightens `summary.exitCode` from `enum: [0, 1]` to `const: 0` with a description explaining the field is retained for stability. - CLAUDE.md / README.md document the new policy; the severity-model entry no longer claims "Failures set exit code 1". - Adds `TestRunFailVerdictReturnsZero` pinning the policy end-to-end through `run()` (the unit-level test alone wouldn't catch a regression in main.go). Historical design specs under `docs/superpowers/specs/` still describe the old 0/1 contract; left as historical record per the project convention that CLAUDE.md is the living source of truth.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughThis PR redefines the validator's exit-code semantics: exit code 0 now always indicates a report was produced (regardless of PASS or FAIL verdict), while exit code 2 indicates a configuration/usage error. Verdicts are conveyed only via JSON ChangesExit Code Semantics Overhaul
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |



Summary
summary.verdict(JSON) and the result-sink row'sresult_data. Exit 2 is reserved for "the validator could not run" (config/usage error).summary.exitCodetightens fromenum: [0, 1]toconst: 0with a description; the field is kept for schema stability.Test plan
go test ./...greengo vet ./...cleanFAIL (… 9 failed …)and the process exits 0. JSON mode emitssummary.verdict=FAIL,summary.exitCode=0, process exits 0.TestRunFailVerdictReturnsZeropins the policy end-to-end throughcmd/oba-validator.run()— unit-level coverage onReport.ExitCode()alone wouldn't catch a regression inmain.go.TestUsageWhenNoArgs,TestRunJSONConfigErrorEmitsErrorJSON, …) still pin the config-error upper boundary.Review notes
Historical design docs under
docs/superpowers/specs/(2026-05-24-oba-validator-design.md,2026-05-25-render-deployment-design.md,2026-05-25-json-ui-output-design.md,2026-05-25-result-sink-design.md) still describe the old "0/1 on failure" contract. Per the project convention (CLAUDE.mdis the living source of truth), historical specs are left as a record of decisions made at the time rather than retroactively rewritten. Happy to update them if you'd rather have specs reflect current behavior.Backwards-compat note: callers (notably obacloud's reader) that parse
summary.verdictrather than the process exit code or theexitCodefield continue to work unchanged. Any consumer that was branching onexit == 1to mean "FAIL" will need to look atsummary.verdict(or the sink row'sresult_data) instead.Summary by CodeRabbit
Documentation
0now indicates successful report generation (PASS or FAIL), exit code2indicates configuration/usage errors.Bug Fixes
Tests