Skip to content

gate: name the commit the floor ratchet resolved, not just the ref - #47

Merged
ualtinok merged 1 commit into
cortexkit:masterfrom
legion-works:gate/ratchet-names-target
Sep 17, 2026
Merged

ualtinok merged 1 commit into
cortexkit:masterfrom
legion-works:gate/ratchet-names-target

Conversation

@iceteaSA

@iceteaSA iceteaSA commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #46, taking the fork-origin note from its review.

origin/master means a different commit depending on who runs the gate. A contributor working from a fork has origin pointing 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:

workspace floor 614 >= origin/master 614 at 5b761ed     <- real target
workspace floor 614 >= 6817148 610 at 6817148           <- stale, 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.

Arms, re-run on the merged tree

Not cited from the pre-merge branch, since #46 landed while this was in hand:

arm result
real target passes, >= origin/master 614 at 5b761ed
stale target (6817148) passes, >= 6817148 610 at 6817148 — the fork case, now self-describing
unresolvable cannot resolve refs/heads/nope (unresolved), carried to the verdict line
floor lowered to 578 exit 1, but origin/master (5b761ed) carries 614

Full gate exit 0.

One note on the arm that was inconclusive first time

The stale-target arm initially printed exit 1 with 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=100ms fixtures 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.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with 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/master no 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.

  • Applies to all four output paths: the pass line, both UNCHECKED lines, and the refusal.
  • Unresolvable refs print (unresolved) so the output shape stays consistent between arms.
  • Does not fix the staleness itself; set CK_GATE_FLOOR_TARGET to the real upstream ref to compare against it.

Written for commit eaa16e2. Summary will update on new commits.

Review in cubic

`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.

@cubic-dev-ai cubic-dev-ai 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.

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

Comment thread scripts/gate.sh
# 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')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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>

@ualtinok
ualtinok merged commit 249c9bf into cortexkit:master Sep 17, 2026
6 checks passed
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