fix(check): honor --base scope when workspace is a repo subdirectory#130
Merged
Connorrmcd6 merged 1 commit intoJun 15, 2026
Merged
Conversation
) * fix(check): honor --base scope when workspace is a repo subdirectory git diff --name-only reports repo-root-relative paths, but anchor files are workspace-root-relative. When surf.toml lives in a subdirectory of the git repo, the two never intersect, so check --base silently scoped the gate to zero claims and exited 0 despite real drift — the exact diff-scoped mode action.yml recommends for PR gating. Pass --relative so git emits workspace-root-relative paths (a no-op when the workspace is the repo root). Adds a regression test that fails without the fix. https://claude.ai/code/session_01T3Z35bgg6cvWzBDfyh6pQ8 * style: rustfmt subdir-base regression test * docs(hub): update changed_files claim for workspace-relative scoping The --base fix changes changed_files to emit workspace-root-relative paths (git diff --relative). Surface's own dogfood gate flagged the stale hash + prose, which still described repo-relative paths. Update the claim text and re-stamp the hash. (cherry picked from commit b20de8b)
Connorrmcd6
approved these changes
Jun 15, 2026
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.
Severity: HIGH — silent gate bypass
surf check --base <ref>can pass (exit 0) despite real, anchored drift wheneversurf.tomllives in a subdirectory of the git repo (the monorepo / nested-packagelayout). This is the exact diff-scoped mode
action.ymlrecommends for PR gating, so thebypass lands squarely on the CI path.
Root cause
git::changed_filesrunsgit diff --name-only <base>. Without--relative, git emitsrepo-root-relative paths (e.g.
proj/src/x.rs), whileAnchor.fileisworkspace-root-relative (
src/x.rs). The two sets never intersect, soScope::includesfilters out every claim → zero claims checked → clean exit.
Reproduction (before fix)
With
a + bcommitted and the working tree changed toa - b:surf check→ exit 1 (DIVERGED) ✅surf check --base HEAD→ exit 0 ("all anchored spans match") ❌ bypassWhen the workspace is the repo root, both report exit 1 — which is why the existing
base_scope_limits_to_changedtest never caught it.Fix
Add
--relativeto the diff so git emits workspace-root-relative paths. It is a no-op whenthe workspace is the repo root, and it additionally drops changes outside the workspace
(which can never be anchored). One-line change in
surf-cli/src/git.rs.Test
Adds
base_scope_works_when_workspace_is_a_repo_subdir, which initializes the repo at theparent of the workspace and asserts a working-tree drift still fails
check --base. Itfails without the fix (
left == rightassertion: 0 vs 1) and passes with it.cargo clippy --all-targetsclean; full suite green (180 tests).Part of an ongoing security/correctness review of Surface.
🤖 Generated with Claude Code