package console import ( "go/ast" "go/parser" "go/token" "os" "path/filepath" "sort" "strings" "testing" ) // TestClaimSQLSeamCallers keeps the gate's trusted seams where they are: // // - the claim restore and materialization files never touch a Store's db, // pool or boot field, and never call bootDB: every write goes through // WithAppMutation and its canonical grants; // - the raw handles (Store.rawPool, Store.rawBoot) are named only in // store.go and store_gate.go: every other file reaches SQL through s.db, // which inside WithAppMutation is the bound view; // - withClaimSQL (the permit engine) is called only by WithAppMutation; // - bootDB is called only by the boot seam; // - sqlGrant values are built only in claim_sql_grants.go; // - ControlWriter.AbandonRestore and RecoverRestore are called only by the // restore issuer and its sweep (claim_restore.go). // // A new caller fails here before it can ship. func TestClaimSQLSeamCallers(t *testing.T) { noRawSQL := map[string]bool{"claim_restore.go": true, "claim_materialize.go": true, "claim_sql_grants.go": true} allowed := map[string]map[string]bool{ "rawPool": {"store.go": true, "store_gate.go": true}, "rawBoot": {"store.go": true, "store_gate.go": true, "claim_sql_receipts.go": true}, "withClaimSQL": {"claim_sql_grants.go": true}, "withPreparedClaimSQL": {"claim_sql_grants.go": true, "store_gate.go": true}, "bootDB": {"store_gate.go": true, "claim_app_identity.go": true}, "AbandonRestore": {"claim_restore.go": true}, "RecoverRestore": {"claim_restore.go": true}, "sqlGrant-composite": {"claim_sql_grants.go": true}, } files, err := filepath.Glob("*.go") if err != nil { t.Fatal(err) } fset := token.NewFileSet() var bad []string for _, name := range files { if strings.HasSuffix(name, "_test.go") { continue } src, err := os.ReadFile(name) if err != nil { t.Fatal(err) } f, err := parser.ParseFile(fset, name, src, 0) if err != nil { t.Fatal(err) } ast.Inspect(f, func(n ast.Node) bool { switch x := n.(type) { case *ast.SelectorExpr: sel := x.Sel.Name if noRawSQL[name] && (sel == "db" || sel == "rawPool" || sel == "rawBoot" || sel == "bootDB") { bad = append(bad, fset.Position(x.Pos()).String()+": raw SQL handle ."+sel) } if ok, listed := allowed[sel]; listed && !ok[name] { bad = append(bad, fset.Position(x.Pos()).String()+": "+sel+" outside its seam") } case *ast.CompositeLit: if id, ok := x.Type.(*ast.Ident); ok && id.Name == "sqlGrant" && !allowed["sqlGrant-composite"][name] { bad = append(bad, fset.Position(x.Pos()).String()+": sqlGrant built outside claim_sql_grants.go") } } return true }) } sort.Strings(bad) for _, b := range bad { t.Error(b) } }