Help us shape the future of Go! Take the 2026 Go Developer Survey

api

package
v7.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Overview

Package api is the public, library-shaped surface of Semantic Firewall. The CLI in cmd/sfw and the MCP server in the sibling semantic_firewall_mcp repo both consume it; everything in internal/cli is implementation glue that orchestrates flag parsing and process boundaries on top of the entry points defined here.

The entry points return the same JSON-serialisable types from pkg/models that the CLI prints, so callers can either marshal them directly or inspect the structured values in-process.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CalculateTopologyDelta

func CalculateTopologyDelta(oldT, newT *topology.FunctionTopology) (string, int)

CalculateTopologyDelta diffs two function topologies and returns the topology_delta and risk_score Diff reports for the change. A nil oldT means the function was added, a nil newT that it was removed. Newly reached capabilities (process execution, raw syscalls, plugins, network, reflective invocation, filesystem mutation), new goroutines, obfuscation and the deletion signals each reach models.RiskScoreHigh on their own; ordinary call, loop and branch churn is capped below it. Removing structure is neutral, except a check.

func CompareFunctions

func CompareFunctions(funcName string, oldResult, newResult diff.FingerprintResult) models.FunctionDiff

CompareFunctions reduces two FingerprintResult values to a FunctionDiff. A function is preserved only when its canonical IR is unchanged with every literal kept: the default fingerprint masks strings and larger integers, so on its own it would report a changed URL, command, size limit or permission mode as preserved. Any other function is modified; the Zipper only supplies the instruction-level evidence. Its alignment is driven by data flow, so it must not decide the status: a swapped branch or a call moved out of its guard aligns completely.

func DepsDiff

func DepsDiff(oldDir, newDir string) (*models.DepsDiffOutput, error)

DepsDiff compares the third-party code compiled into the module rooted at oldDir with that compiled into the module rooted at newDir. Both trees are loaded with the hardened loader environment (GOPROXY=off), so every module either build needs must already be in the module cache.

A module is compared when its version or replacement differs between the trees, or when its code can change without either: replaced by a local directory, a module of the go.work that governs the tree (the go command builds with it; see diff.WorkspaceFile), or vendored (a tree with vendor/modules.txt is loaded from its vendor directory, as the go command builds it). For each such module the diff reports changed functions (paired and scored as in Diff), exported functions and package initializers that newly reach a capability class, and changes to files the analysis cannot see. Modules only in the new tree, and packages the new tree newly builds from an unchanged module, are reported with the capability classes their exported functions and initializers can reach.

func Diff

func Diff(oldPath, newPath string) (*models.DiffOutput, error)

Diff is the convenience entry point: it computes a semantic diff between two on-disk Go source files using the real filesystem. Either path may be empty or non-existent to represent an added or removed file.

func DiffBatch

func DiffBatch(pairs []DiffPair) []*models.DiffOutput

DiffBatch diffs every pair and returns one result per pair, in order. Each result is what Diff(pair.Old, pair.New) returns; a pair Diff would fail on has the error in its ErrorMessage and no functions.

The files of each side are loaded together: all files under one module root, governed by the same go.work, take one go/packages call, so a package and its import graph are loaded once however many of its files are diffed. A file outside any module, a file the module's default build leaves out, a file of a package that does not type-check, and every file of a group whose load or SSA build fails are loaded on their own, exactly as Diff loads them.

func DiffBatchWithFS

func DiffBatchWithFS(fsys FileSystem, pairs []DiffPair) []*models.DiffOutput

DiffBatchWithFS is DiffBatch against the supplied FileSystem. With any FileSystem but RealFileSystem, each file is loaded on its own, so each result is what DiffWithFS returns for its pair.

func DiffBatchWithOptions added in v7.4.0

func DiffBatchWithOptions(fsys FileSystem, pairs []DiffPair, opts BatchOptions) []*models.DiffOutput

DiffBatchWithOptions is DiffBatchWithFS with opts.

func DiffWithFS

func DiffWithFS(fsys FileSystem, oldPath, newPath string) (*models.DiffOutput, error)

DiffWithFS performs a semantic diff against the supplied FileSystem so tests can drive the pipeline without touching disk. Behaviour is identical to Diff otherwise.

func FingerprintFiles

func FingerprintFiles(fsys FileSystem, paths []string, strict bool) map[string]FileFingerprints

FingerprintFiles fingerprints the functions declared in each file at paths. The result has one entry per distinct path, keyed by the path as given. Each entry is what a load of that file alone gives: its functions and its package's initializer, not its package siblings', or the error that load fails with. Unlike DiffBatch's inputs, every path must name a file: an empty path, a missing file, a file with only whitespace, a file over models.MaxSourceFileSize and a path that cannot be resolved are errors. Results is nil or empty when Err is set.

With RealFileSystem, files are loaded as DiffBatch loads them: all files under one module root and governed by the same go.work with one go/packages call, so a package is loaded and canonicalized once however many of its files are listed, and the results of one package share their SSA functions. Any other FileSystem, every file the grouped load cannot cover (outside a module, excluded by the default build, in an ill-typed package), and every file of a group whose load or fingerprinting fails, is loaded on its own.

With strict, an SSA instruction the canonicalizer does not handle fails the file ("panic while fingerprinting <path>: STRICT MODE: ...") instead of rendering as a placeholder. A panic in the FileSystem fails its file too.

func ResultName

func ResultName(r diff.FingerprintResult) string

ResultName is the name reported for a fingerprinted function: its SSAFunctionName, or ShortFunctionName of its full name when the result carries no SSA function.

func SSAFunctionName

func SSAFunctionName(fn *ssa.Function) string

SSAFunctionName returns fn's name relative to its own package: "F", "(*T).M", "F$1". Unlike ShortFunctionName it does not have to guess where the package path ends, so a package whose last path element contains a dot ("gopkg.in/yaml.v3", "example.com/lib.v2") is stripped completely.

func ShortFunctionName

func ShortFunctionName(fullName string) string

ShortFunctionName strips package paths and qualifying identifiers from a Go SSA function name so it is readable in diffs and reports. Given only the string, it takes the text up to the first dot after the last slash as the package name; prefer SSAFunctionName when the function is at hand.

It handles three shapes:

  • "fmt.Println" -> "Println"
  • "pkg.(*Type).Method" / "(*pkg.Type).Method" -> "(*Type).Method"
  • Generics like "pkg.Func[a/b.T]" -> "Func[a/b.T]"

Brackets and parens are tracked so qualified types inside generic parameters or receiver positions are preserved verbatim.

Types

type BatchOptions added in v7.4.0

type BatchOptions struct {
	// NonGo has a pair with no Go file on either side reported by what the
	// build makes of the file (see nonGoDiff), rather than loaded as Go.
	NonGo bool
}

BatchOptions adjusts DiffBatchWithOptions.

type DiffPair

type DiffPair struct {
	Old string
	New string
}

DiffPair names the two versions of one file. An empty path, a missing or empty file, or /dev/null stands for the absent side of an added or removed file, as in Diff.

type FileFingerprints

type FileFingerprints struct {
	Results []diff.FingerprintResult
	Err     error
	// contains filtered or unexported fields
}

FileFingerprints is one file's fingerprinted functions, or why there are none.

type FileSystem

type FileSystem interface {
	Stat(name string) (os.FileInfo, error)
	Open(name string) (fs.File, error)
	Getwd() (string, error)
	Abs(path string) (string, error)
	WalkDir(root string, fn fs.WalkDirFunc) error
	ReadFile(name string) ([]byte, error)
}

FileSystem abstracts the OS file operations the analysis pipeline needs. Production code uses RealFileSystem; tests can substitute a mock to drive the pipeline without touching disk.

type RealFileSystem

type RealFileSystem struct{}

RealFileSystem is the production FileSystem implementation backed by the os and filepath packages. ReadFile bounds the read at models.MaxSourceFileSize so a hostile/oversize input cannot exhaust memory.

func (RealFileSystem) Abs

func (RealFileSystem) Abs(path string) (string, error)

func (RealFileSystem) Getwd

func (RealFileSystem) Getwd() (string, error)

func (RealFileSystem) Open

func (RealFileSystem) Open(name string) (fs.File, error)

func (RealFileSystem) ReadFile

func (RealFileSystem) ReadFile(name string) ([]byte, error)

func (RealFileSystem) Stat

func (RealFileSystem) Stat(name string) (os.FileInfo, error)

func (RealFileSystem) WalkDir

func (RealFileSystem) WalkDir(root string, fn fs.WalkDirFunc) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL