gate: name the commit the floor ratchet resolved, not just the ref - #47
Conversation
`origin/master` means a different commit depending on who runs this. A contributor working from a fork has `origin` pointing at their own fork, whose master can lag the real merge target arbitrarily -- so the comparison runs against a stale floor and PASSES. A false green, which is the worse direction: the refusal path is loud, this one is silent. Printing the resolved SHA does not fix the staleness and is not meant to. It makes it legible. Before, a stale fork and the real target both printed `origin/master` and were indistinguishable in the log: workspace floor 614 >= origin/master 614 at 5b761ed <- real target workspace floor 614 >= 6817148 610 at 6817148 <- stale, now visibly older Applied to all four output paths -- the pass line, both UNCHECKED lines, and the refusal -- because a reader who sees a ref name in one and a SHA in another has to work out which is which. The unresolvable case prints `(unresolved)` rather than omitting the field, so the shape does not change between arms. Four arms re-run on the merged tree rather than cited from the pre-merge branch: real target passes naming 5b761ed, a stale target passes naming 6817148 and its older floor, an unresolvable target reports UNCHECKED and carries it to the verdict line, and a lowered floor exits 1 naming both numbers and the resolved SHA.
There was a problem hiding this comment.
1 issue found across 1 file
You’re at about 93% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/gate.sh">
<violation number="1" location="scripts/gate.sh:267">
P3: The SHA the log names is not guaranteed to be the commit that was actually compared, because `$target_sha` comes from a separate `git rev-parse` run before `git show "$target:scripts/gate.sh"` re-resolves the same ref. A ref that moves between the two calls gets logged under a SHA that was never the comparison input, and the UNCHECKED "cannot resolve" message can even print a valid SHA: `git show` exits 128 when it fails for any reason besides an unresolvable ref (path absent from the target commit, missing blob in a partial clone), so "cannot resolve $target ($target_sha)" can pair a real resolved SHA with the literal `(unresolved)` marker, which only reflects the earlier rev-parse call. Since the PR's whole purpose is making the compared commit legible, resolve once and feed that SHA to `git show` (falling back to `$target` when unresolved) so the printed commit is exactly the one compared, and keep the "cannot resolve"/`(unresolved)` wording for the case where resolution actually failed.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| # legible: a four-week-old commit beside today's is visible where a bare ref name is | ||
| # not. Set CK_GATE_FLOOR_TARGET to compare against the real upstream ref instead. | ||
| local target_sha | ||
| target_sha=$(git rev-parse --short "$target" 2>/dev/null || echo 'unresolved') |
There was a problem hiding this comment.
P3: The SHA the log names is not guaranteed to be the commit that was actually compared, because $target_sha comes from a separate git rev-parse run before git show "$target:scripts/gate.sh" re-resolves the same ref. A ref that moves between the two calls gets logged under a SHA that was never the comparison input, and the UNCHECKED "cannot resolve" message can even print a valid SHA: git show exits 128 when it fails for any reason besides an unresolvable ref (path absent from the target commit, missing blob in a partial clone), so "cannot resolve $target ($target_sha)" can pair a real resolved SHA with the literal (unresolved) marker, which only reflects the earlier rev-parse call. Since the PR's whole purpose is making the compared commit legible, resolve once and feed that SHA to git show (falling back to $target when unresolved) so the printed commit is exactly the one compared, and keep the "cannot resolve"/(unresolved) wording for the case where resolution actually failed.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/gate.sh, line 267:
<comment>The SHA the log names is not guaranteed to be the commit that was actually compared, because `$target_sha` comes from a separate `git rev-parse` run before `git show "$target:scripts/gate.sh"` re-resolves the same ref. A ref that moves between the two calls gets logged under a SHA that was never the comparison input, and the UNCHECKED "cannot resolve" message can even print a valid SHA: `git show` exits 128 when it fails for any reason besides an unresolvable ref (path absent from the target commit, missing blob in a partial clone), so "cannot resolve $target ($target_sha)" can pair a real resolved SHA with the literal `(unresolved)` marker, which only reflects the earlier rev-parse call. Since the PR's whole purpose is making the compared commit legible, resolve once and feed that SHA to `git show` (falling back to `$target` when unresolved) so the printed commit is exactly the one compared, and keep the "cannot resolve"/`(unresolved)` wording for the case where resolution actually failed.</comment>
<file context>
@@ -256,6 +256,16 @@ assert_floor_not_lowered() {
+ # legible: a four-week-old commit beside today's is visible where a bare ref name is
+ # not. Set CK_GATE_FLOOR_TARGET to compare against the real upstream ref instead.
+ local target_sha
+ target_sha=$(git rev-parse --short "$target" 2>/dev/null || echo 'unresolved')
+
ours=$(grep -m1 -oE 'run_expect [0-9]+ "workspace' "$file" | grep -oE '[0-9]+')
</file context>
Follow-up to #46, taking the fork-origin note from its review.
origin/mastermeans a different commit depending on who runs the gate. A contributor working from a fork hasoriginpointing at their fork, whose master can lag the real merge target arbitrarily — so the ratchet compares against a stale floor and passes. That is a false green, which is the worse direction: the refusal path is loud, this one is silent.Printing the resolved SHA does not fix the staleness and is not meant to. It makes it legible. Before, a stale fork and the real target were indistinguishable in the log; now:
Applied to all four output paths — the pass line, both
UNCHECKEDlines, and the refusal — because a reader who sees a ref name in one and a SHA in another has to work out which is which. The unresolvable case prints(unresolved)rather than omitting the field, so the shape does not change between arms.Arms, re-run on the merged tree
Not cited from the pre-merge branch, since #46 landed while this was in hand:
>= origin/master 614 at 5b761ed6817148)>= 6817148 610 at 6817148— the fork case, now self-describingcannot resolve refs/heads/nope (unresolved), carried to the verdict linebut origin/master (5b761ed) carries 614Full gate exit 0.
One note on the arm that was inconclusive first time
The stale-target arm initially printed
exit 1with no ratchet line at all — three full gates back to back had tripped the load-dependent manifest-lock quarantine tests (opencode_files.rs:1403,1423,TTL=100msfixtures sitting 101ms past a boundary), so the gate died before reaching the ratchet. Exit 1 was the result I wanted to see, produced by something else entirely. Re-ran the arm alone on a quiet machine for the evidence above.Those two tests are the same shape as the flake #33 fixed by converting a race into arithmetic. Still flagging rather than fixing — not this PR's scope.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Names the commit the floor ratchet resolved instead of just the ref, so a fork's stale
origin/masterno longer logs identically to the real merge target. The pass line now shows the resolved SHA and floor; a stale fork reads as visibly older instead of silently passing.UNCHECKEDlines, and the refusal.(unresolved)so the output shape stays consistent between arms.CK_GATE_FLOOR_TARGETto the real upstream ref to compare against it.Written for commit eaa16e2. Summary will update on new commits.