carlos / platform Public

fix/moves-copy-gate-scope

Squashed from fix/moves-copy-gate-scope into main.
claude agent, operated by paul@keymail.dev e5adf3291b59686fb5e85506e519d247539537e8 parent cfdb4e1
1 file changed, +33 −6
  • approved_moves_copy_test.go +33 −6

CI passed — run details

diff --git a/approved_moves_copy_test.go b/approved_moves_copy_test.go
index 54633a34a..084d8e5a8 100644
--- a/approved_moves_copy_test.go
+++ b/approved_moves_copy_test.go
@@ -627,9 +627,17 @@ func resolveMovesScanBase(lookup func() (string, error), pinned string) (base, f
}
// movesScanBaseRef is the base for this run, logged so a failure says which.
+//
+// Where git cannot name the merge base (a CI checkout with no origin/main),
+// the checks that need it skip rather than diff from the pinned commit: a
+// stale pin turns every commit main gained since into a false finding on
+// every other branch.
func movesScanBaseRef(t *testing.T) string {
t.Helper()
base, from := resolveMovesScanBase(movesMergeBase, movesScanBase)
+ if base == movesScanBase && from == "the pinned movesScanBase" {
+ t.Skip("no merge base with origin/main in this checkout; the diff checks run where git can name it")
+ }
t.Logf("scan base %s, from %s", base, from)
return base
}
@@ -907,20 +915,34 @@ func movesProductionGoFile(path string) bool {
// movesUncovered returns the production files in changed that listed lacks.
// exists says whether a path is still in the tree (a deleted file needs no
// entry).
-func movesUncovered(changed, listed []string, exists func(string) bool) []string {
+func movesUncovered(changed, listed []string, exists, movesCode func(string) bool) []string {
have := map[string]bool{}
for _, f := range listed {
have[f] = true
}
var out []string
for _, f := range changed {
- if movesProductionGoFile(f) && exists(f) && !have[f] {
+ if movesProductionGoFile(f) && exists(f) && movesCode(f) && !have[f] {
out = append(out, f)
}
}
return out
}
+// movesCodeFile is a Go file the moves series owns or speaks through: one in
+// internal/moves, or one that imports it. Another branch's change to a file
+// with no tie to moves is not this gate's to inventory.
+func movesCodeFile(path string) bool {
+ if strings.HasPrefix(path, "internal/moves/") {
+ return true
+ }
+ body, err := os.ReadFile(path)
+ if err != nil {
+ return true // unreadable: inventory it rather than pass it
+ }
+ return strings.Contains(string(body), `"github.com/carlosframework/platform/internal/moves`)
+}
+
func TestMovesScanFilesInventoryRules(t *testing.T) {
exists := func(p string) bool { return p != "internal/gone.go" }
changed := []string{
@@ -931,10 +953,15 @@ func TestMovesScanFilesInventoryRules(t *testing.T) {
"internal/gone.go", // deleted
"docs/superpowers/plans/2026-10-06-copy.md", // not Go
"internal/moves/listed.go", // listed
+ "internal/host/usesmoves.go", // imports moves: needs an entry
+ "internal/changelog/other.go", // another branch's file, no tie to moves
+ }
+ movesCode := func(p string) bool {
+ return strings.HasPrefix(p, "internal/moves/") || p == "internal/host/usesmoves.go"
}
- got := movesUncovered(changed, []string{"internal/moves/listed.go"}, exists)
- if len(got) != 1 || got[0] != "internal/moves/new.go" {
- t.Errorf("uncovered = %q, want only internal/moves/new.go", got)
+ got := movesUncovered(changed, []string{"internal/moves/listed.go"}, exists, movesCode)
+ if len(got) != 2 || got[0] != "internal/moves/new.go" || got[1] != "internal/host/usesmoves.go" {
+ t.Errorf("uncovered = %q, want internal/moves/new.go and internal/host/usesmoves.go", got)
}
}
@@ -977,7 +1004,7 @@ func TestMovesScanFilesCoverTheDiff(t *testing.T) {
t.Skipf("git diff %s..HEAD: %v", base, err)
}
exists := func(p string) bool { _, err := os.Stat(p); return err == nil }
- for _, f := range movesUncovered(strings.Fields(string(out)), movesScanFiles, exists) {
+ for _, f := range movesUncovered(strings.Fields(string(out)), movesScanFiles, exists, movesCodeFile) {
t.Errorf("%s changed since %s and is not in movesScanFiles", f, base)
}
for _, f := range movesScanFiles {