Skip to content

perf(guardrails): start reference-verify ranges at the nearest pushed ref so stacked branches skip re-verifying - #10829

Merged
melodic-automation-lanes[bot] merged 5 commits into
mainfrom
work-resolve-issue/issue-9861-40797493453-1
Oct 29, 2026
Merged

melodic-automation-lanes[bot] merged 5 commits into
mainfrom
work-resolve-issue/issue-9861-40797493453-1

Conversation

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor

Closes #9861

Summary

Opened by the work-resolve-issue lane. The run's own summary:

The pre-push reference-verify entry now moves each range's base up to the nearest of the remote's tracking refs that the tip contains and that contains the base. A new branch stacked on a pushed branch is then verified only on what it adds over that branch, not on every file the branches below it changed, which the recorded decision chose over a time bound or a skip. The README documents the ssh ServerAliveInterval workaround for the dropped-connection silent push; lefthook.yml's refetch_frequency was already 1h on main.

Not verified

  • plugins/guardrails/git-hooks/reference-verify.test.sh was not executed: this lane runs no interpreter or test runner, so the new stacked-branch cases and the existing suite are left to the PR's CI
  • The decision asked to time the current hook on a stacked fixture before changing the range; no timing could run here. The range was bounded on the 2026-10-28 owner measurement (87 s and 188 s in reference-verify on current main), and the new test checks what is verified, not how long it takes
  • Person check from the decision: a small push on the dev host finishes reference-verify in under a minute; a lane cannot push to GitHub
  • The 2026-10-28 comment's unverified reading that a plain push on a non-stacked branch pays for the whole branch diff is not addressed: for an existing branch the lib's range is already remote-sha..local-sha, so that cost is per changed file in the push; a person may want a profiling follow-up
  • Review note, accepted by design: the base now comes from local tracking refs, so a stale tracking ref, or a colleague's branch pushed with --no-verify, can mark commits as already checked that this clone's hook never judged. This is the 'nearest already-pushed ancestor ref' the recorded decision cho
  • tidy: passes 1-3 ran (no code simplification or comment deletion found; write-for-humans split the README ssh sentence and the fragment's last sentence). Pass 4's ai-slop detector (detect.sh) is not among the commands this lane may run, so the changed markdown lines got a rubric read only and no det
  • Untracked files in the working tree that this run did not create and did not touch: .bash_profile, .bashrc, .gitconfig, .idea, .mcp.json, .profile, .ripgreprc, .vscode, .zprofile, .zshrc (sandbox artifacts, not part of this change)

Fix

  • plugins/guardrails/git-hooks/reference-verify.sh: new nearest_pushed_base (git for-each-ref --merged=<tip> --contains=<base> over refs/remotes/<remote>/, picks the ref fewest commits behind the tip), called first for each pushed range; header comment describes it
  • plugins/guardrails/git-hooks/reference-verify.test.sh: stacked-branch fixture: phase2 on an unpushed phase1 still blocks on phase1's bogus flag; once phase1 is pushed, phase2's new-branch push passes; a bogus line phase2 adds still blocks at phase2.sh:1; header comment updated
  • plugins/guardrails/README.md: reference-verify row says where a range starts (merge-base, then nearest tracking ref) and documents ServerAliveInterval for long pushes over ssh
  • .changes/guardrails/perf-reference-verify-stacked-range-9861a1c3.md: patch changelog fragment for guardrails

Verification

The runner ran each check from the base copy against a84bc78:

  • scripts/check-changelog-fragments.sh --check: passed

The run reports:

  • read lefthook.yml:33-38 on the checkout: the claude-code-plugins remote already has refetch_frequency: 1h, so acceptance criterion 1 is met on main and needed no edit
  • read https: //man.openbsd.org/ssh_config: ServerAliveInterval sends a server-alive message after that many seconds with no data from the server (default 0, disabled); ServerAliveCountMax defaults to 3; Host blocks scope settings to matching hosts
  • check-changelog-fragments: All 4 changelog fragment(s) under .changes/ are valid (run before and after tidy and review fixes)
  • check-affected: 12 passed, 6 skipped over 4 changed files (run three times, last after the review fixes)
  • cant-fail-scan --file plugins/guardrails/git-hooks/reference-verify.test.sh --lines 326-345 --check: PASS, no gating findings
  • fresh-context review subagent over the whole diff: no correctness bugs; existing tests keep their outcomes; two prose findings (README said only new branches move, header sentence read as fallback-only) fixed
  • The lane run: https://github.com/melodic-software/claude-code-plugins/actions/runs/40797493453

Left out: the items under Not verified.

Related

#9861

Lane-Activity: work-resolve-issue/resolve-issue

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

claude-security-review: 1 inline finding(s) on a84bc78e4fe2bf0521d94bc15db321187fc65d70; the summary is in this lane's pull request comment.

claude-lane: claude-security-review

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed 16c79a95000c2c30cd94175691a1c80d635f89d3: 0 finding(s), 0 as inline comments.

Incremental security review of 16c79a9 (changes since 35bddf8): no security findings.

The incremental change touches two files, .changes/guardrails/perf-reference-verify-stacked-range-9861a1c3.md and plugins/guardrails/README.md. Both are documentation only. They add one sentence saying the reference-verify pre-push entry trusts the remote's tracking refs as already verified, including another author's branch fetched into the clone and pushed with --no-verify.

  • Code: No executable code, workflow, manifest, trust control or hold path changed in this increment. None of the trusted-path globs match the two files. I did not re-read the hook code itself because it is unchanged since the last review.
  • What the text does: It documents a limit of an advisory pre-push check. That limit is not a new bypass, and the check is client-side and already skippable with --no-verify. The disclosure narrows no standing instruction and removes no control.
  • Instruction-surface lens: The edit adds a caveat and deletes nothing, so there is no rule to check against the exception register.
  • Manifests: No plugin.json or marketplace.json change, so no manifest <field> lines apply.
  • Spend: None.

critical-findings: 0

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed 16c79a95000c2c30cd94175691a1c80d635f89d3: 0 finding(s), 0 as inline comments.

Incremental review of the change since 35bddf8: two documentation edits, plugins/guardrails/README.md and the changelog fragment. I read them and found nothing to flag.

  • README reference-verify row: the new sentence says the remote's tracking refs are trusted as verified without a check. That includes another author's branch, fetched into this clone, that was pushed with --no-verify. This matches nearest_pushed_base in reference-verify.sh, which uses any refs/remotes/<remote>/ ref that holds the base and is merged into the tip. The added README text is accurate and makes the PR's accepted-by-design trade-off visible to readers.
  • Changelog fragment: the fragment is still bump: patch, and its added sentence matches the README. The fragment's format is unchanged.
  • Not run: I did not run the hook tests or the changelog-fragment check. This lane has no shell, so I made no independent check of the code. The code files are unchanged since the last review.
  • Closing issue perf(guardrails): pre-push reference-verify takes 8-17 min on stacked branches and pushes fail silently #9861: nothing in this incremental change affects the acceptance criteria. The stacked-branch fixture test and the refetch_frequency: 1h check were covered in the earlier review.
  • Spend: none. No hold.

@melodic-automation-lanes

melodic-automation-lanes Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor Author

The pr-unblock lane stopped address-feedback on this pull request: the pull request has an unresolved review thread the lane does not take (a reviewer it does not act on, a review of an older head, or a thread it already answered), so nothing will resolve it. The lane sets no label: the run ends in a failing pr-unblock/address-feedback status on the head the lane gated.

When a retry on this head can change the outcome, the lane runs one on its own, up to its per-head cap, and edits this comment if it stops again; a run that does not stop clears the status. When no retry can (a review thread the lane does not take or settle, or a failing check after the retries are spent), a person resolves the threads or gets the checks green, then dispatches the workflow below: that run finds the cause gone and clears the status. On a pull request the lanes App opened, the dispatchers start that run once per stop; on any other, a person does. A new commit to the branch starts clean.

To run it again on this head now, dispatch the pr-unblock workflow:

gh workflow run pr-unblock.yml -R melodic-software/claude-code-plugins -f pr-number=10829 -f activity=address-feedback

Lane-Activity: pr-unblock/resolve-conflicts
@melodic-automation-lanes melodic-automation-lanes Bot added the needs-human Human-in-the-loop required; autonomous sessions must not resolve items carrying this. label Oct 29, 2026
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The pr-unblock lane stopped on this pull request and needs a person: the lane could fix a failing check only by weakening a required check, which a person decides.

  • Reason: ci-fix-weaken-required
  • Resume key: afa9b3c340a578d24b6fa5c0aec8877689616fcb (the head the lane stopped on)

To resume, deal with the reason above, remove the needs-human label (and do-not-merge, if set), then dispatch the pr-unblock workflow with pr-number=10829 and activity=fix-ci:

gh workflow run pr-unblock.yml -R melodic-software/claude-code-plugins -f pr-number=10829 -f activity=fix-ci

The two new stacked-branch cases expected their finding at line 1, but
report() places a finding at the first judged line of the tip's text
that holds the flag, and a new file is judged whole. faketool --bogus
sits on line 2 of phase1.sh and line 3 of phase2.sh, so the hook
reports phase1.sh:2 and phase2.sh:3.

The values were wrong when written; the range-start change does not
move them: main's reference-verify.sh reports the same lines for the
same fixtures. The assertions stay exact, and the full stderr of each
case confirms coverage: the unpushed phase1.sh is still flagged when
phase2 is pushed, and once phase1 is pushed only phase2.sh's added
line is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton

Copy link
Copy Markdown
Member

test-bash (0) failed on two of the new stacked-branch cases in reference-verify.test.sh. The fix is 35bddf8, which corrects the expected line numbers. It does not weaken either assertion.

  • What failed: both cases expected the finding at line 1 (phase1.sh:1, phase2.sh:1). The hook reported phase1.sh:2 and phase2.sh:3.
  • Why the new values are correct: report() in reference-verify.sh places a finding at the first judged line of the tip's text that holds the flag, and a new file is judged whole. faketool --bogus is on line 2 of phase1.sh and on line 3 of phase2.sh.
  • The perf change does not move these values. The :1 expectations were wrong when they were written. With the same fixtures, main's reference-verify.sh also reports the flag at line 2 of a new file.
  • Coverage still holds. The full stderr of each case shows:
    • When phase2 is pushed with phase1 unpushed, phase1.sh:2 is still flagged.
    • Once phase1 is pushed, only phase2.sh:3 is flagged, the line phase2 adds.
  • The assertions are still exact string matches.
  • Local runs: reference-verify passes 53 of 53, and every other plugins/guardrails *.test.sh passes.

… verified

The stacked-range base moves to the nearest remote-tracking ref without
checking that ref's commits, so a branch another author pushed with
--no-verify is trusted too. The README row and the changelog fragment
now say so, as the security-review thread on this pull request asked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton kyle-sexton removed the needs-human Human-in-the-loop required; autonomous sessions must not resolve items carrying this. label Oct 29, 2026
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The unattended merge path armed native auto-merge at head 16c79a95000c2c30cd94175691a1c80d635f89d3.

@melodic-automation-lanes
melodic-automation-lanes Bot added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 7e6187b Oct 29, 2026
56 of 57 checks passed
@melodic-automation-lanes
melodic-automation-lanes Bot deleted the work-resolve-issue/issue-9861-40797493453-1 branch October 29, 2026 12:37
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.

perf(guardrails): pre-push reference-verify takes 8-17 min on stacked branches and pushes fail silently

1 participant