fix: gate go-licensing rules on real repo visibility - #105
Merged
Conversation
check_license_file_required was a bare [ ! -f LICENSE ] test. Its message claimed 'Public Go projects must have a root LICENSE file', but nothing in the function determined whether the repo was public, so the licensing guide's private-repo exemption was documented and never implemented. check_readme_license_section had the same gap. Visibility now comes from the repo's own isPrivate flag via gh, memoised and only consulted when a finding would otherwise be emitted. Both rules fail open when visibility cannot be determined: these are MUST-tier, so a false positive blocks every PR in an org, while a missed finding on a public repo is caught at the next review. license-file-required is now Go-scoped as its own docs already claimed. The guide's host-based heuristic is replaced too — the Octopus migration moved 73 private repos onto github.com, so host stopped implying visibility. 69 of 73 non-archived Seibert-Data repos carry no LICENSE by design, so the rule was blocking essentially every PR org-wide.
There was a problem hiding this comment.
{
"verdict": "approve",
"summary": "Clean fix. The PR correctly gates both go-licensing MUST rules on real repo visibility (via `gh repo view --json isPrivate`) instead of the broken host-based heuristic, bringing the enforcement in line with what the rule's own `applies_when` always stated. Fail-open is documented and intentional. The go.mod scoping on `license-file-required` aligns with the rule's docs. Conventional-prefix changelog entries are correct. Shellcheck passed with zero findings.",
"comments": [],
"concerns_addressed": [
"correctness: fail-open behavior on 'unknown' visibility is documented intentional design — MUST-tier false positives block all PRs, missed findings on public repos surface at next review",
"correctness: license-file-required now requires go.mod (Go-scoped per its own docs) — narrowing scope away from non-Go repos with LICENSE files is the correct behavior",
"correctness: REPO_VISIBILITY_CACHE is a single-run script with correct short-circuit on cache hit — no stale-cache issue in practice"
]
}
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
check_license_file_required(scripts/rule-checks.sh) was a bare[ ! -f "$TARGET_DIR/LICENSE" ]. Its emitted message reads "Public Go projects must have a root LICENSE file", but nothing in the function ever determined whether the repo was public — sodocs/go-licensing-guide.md's private-repo exemption was documented and never implemented.check_readme_license_sectionhad the same gap.Two further defects in the same rule:
github.com→ public") predates the Octopus migration, which moved 73 privateSeibert-Datarepos ontogithub.com. Host stopped implying visibility.Measured impact: 4 of 73 non-archived
Seibert-Datarepos have a LICENSE. This MUST-tier rule was firing on essentially every repo in the org, on every PR. Seibert-Data/agent#7 had to be admin-merged to get past it.Change
repo_visibility()— readsgh repo view --json isPrivate, memoised (one call per run at most) and consulted only when a finding would otherwise fire, so the common path stays cheap.repo_is_public()— true only when the repo is known public. Fails open on unknown (nogh, no remote, offline, not a repo): a MUST-tier false positive blocks every PR in an org, while a missed finding on a public repo surfaces at the next review.license-file-requirednow also requiresgo.mod, matching its documented Go scope.isPrivateflag, with an explicit "do NOT infer visibility from the host" note and the fail-open behaviour documented.Verification
make precommitpasses (30 rule-coverage tests, 225 bench tests). Six behavioural cases run against real clones:go.mod, no LICENSEgo.mod, no LICENSElicense-file-required## License## Licensego.modThe regression cases matter as much as the fix: this must not silently disable licensing enforcement on public repos, and it doesn't.