fix(ci): show why the gate said revise, not just that it did - #374
Conversation
The first run of the gate that had working tools returned `revise` — and the job log contained the single word "revise". `--json` suppresses the human report by design, and SARIF carries only findings that have a file and line, so feedback and unlocated issues — often the whole of a `revise` — appeared nowhere at all. An operator got a verdict with no way to act on it, which is most of the value of the gate missing. The document is now rendered into the step log and the GitHub job summary: decision, feedback, issues, and follow-ups with their locations. The exit-1 message quotes the actual decision rather than asserting "rejected", so it cannot misreport if that mapping ever widens.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e12b10cf3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Both from review of the previous commit, and the first one is a hole that commit opened. Rendering the review document into the step log meant printing model-generated text — written after reading an untrusted diff — straight to stdout. GitHub turns any stdout line beginning with `::` into a workflow command, so injected prose could forge annotations, or emit `::stop-commands::` and silence the rest of the step including the verdict itself. The block is now wrapped in stop-commands with a random token the writer cannot predict, which is GitHub's documented fence. Verified against a review whose feedback contains both an `::error::` and a `::stop-commands::`: they render as text, and the `::notice::` after the closing token still executes, so the fence closes cleanly. The summary file is Markdown and is not parsed for commands, so it takes the text as-is. `suggestions` was also being dropped. It is part of the ReviewJson contract and the normal report renders it, so a failing `revise` could still withhold the proposed fix — which is the whole thing this change exists to surface.
|
Both findings addressed — the first was a hole this PR opened, which is a fair catch on a change whose entire subject is making a gate honest. P2 · workflow commands in review prose. Rendering the document to the step log meant printing model-generated text, written after reading an untrusted diff, straight to stdout. Any stdout line starting with Verified against a review whose feedback contains both Both forgeries render as text, and the real P2 · dropped suggestions. Correct, and it defeated the point: |
The first run of the gate with working tools returned
revise. The job log contained the single word "revise".--jsonsuppresses the human report by design, and SARIF carries only findings that have a file and line — the analysis for that run uploaded 0 results. So the feedback and any unlocated issues, which is often the whole of arevise, appeared nowhere. An operator gets a verdict and no way to act on it, which is most of the gate's value missing.Fix
The review document is rendered into both the step log and the GitHub job summary: decision, feedback, issues, and follow-ups with locations.
The exit-1 message now quotes the actual decision instead of asserting "rejected this change", so it cannot misreport if that mapping ever widens beyond reject.
Verification
Exercised against the local fixture harness with a
revisedocument carrying feedback, an unlocated issue, and two follow-ups (one with a location, one without). All of it reaches the log and$GITHUB_STEP_SUMMARY;bash -nand YAML parse clean.