Documentation
¶
Index ¶
- Constants
- func ExitCodeForError(err error) int
- func ExitCodeFromError(err error) (int, bool)
- func ExitStatus(err error, stderr io.Writer) int
- func NewExtractCmd(stdout, stderr io.Writer) *cobra.Command
- func Run(args []string, stdout, stderr io.Writer) error
- func SetClockForTest(at time.Time) (restore func())
- type CheckCompatibilityUseCase
- type Container
- type DiffDirectivesUseCase
- type DiffInterfaceUseCase
- type DiffLicenseUseCase
- type DiffScanRunsUseCase
- type DiffWalksUseCase
- type ExecuteWalkUseCase
- type ExtractCallGraphUseCase
- type ExtractExampleUseCase
- type ExtractFIPSUseCase
- type ExtractInterfaceUseCase
- type ExtractLicenseUseCase
- type ExtractLocalCallGraphUseCase
- type ExtractStdlibCallGraphUseCase
- type ExtractUseCase
- type FetchModuleUseCase
- type GenerateNoticeUseCase
- type GenerateSBOMUseCase
- type QueryCallGraphUseCase
- type QueryDirectivesUseCase
- type QueryExamplesUseCase
- type QueryExtractionUseCase
- type QueryFIPSUseCase
- type QueryFetchUseCase
- type QueryInterfaceUseCase
- type QueryLicenseUseCase
- type QuerySBOMUseCase
- type QueryScanRunsUseCase
- type QueryVulnUseCase
- type QueryWalksUseCase
- type RegisteredCommand
- type RescanWalkUseCase
- type ScanModuleUseCase
- type ScanWalkUseCase
- type StdlibCustodyLister
- type StdlibCustodyReader
Constants ¶
const ( ExitOK = exitcode.OK ExitPartial = exitcode.Partial ExitFailed = exitcode.Failed ExitCancelled = exitcode.Cancelled ExitNotFound = exitcode.NotFound ExitPolicy = exitcode.Policy ExitIntegrity = exitcode.Integrity ExitConfig = exitcode.Config )
Exit codes; the taxonomy is documented in package exitcode.
const ( // StoreIntentRead answers from records some other run wrote. It must not // create the store root: a root created by a read answers "nothing // recorded here", which is true of the empty store it just made and false // about the store the caller meant. // // A command that writes but cannot be the first command against a store — // `store clean` has nothing to clean, and every extract needs a walk — // declares read as well. What the value governs is creation, not writing. StoreIntentRead = "read" // StoreIntentCreate writes records, so it creates the root when it is // absent. A first fetch, walk, extract or inspect on a clean machine must // not need a preparatory step. StoreIntentCreate = "create" // StoreIntentNone touches no store at all, so neither answer applies: // refusing it for a store root it never opens would be a refusal with no // subject. Only the commands that genuinely open nothing qualify. StoreIntentNone = "none" )
The values annotationStoreIntent takes. A command declares exactly one.
const ( // NetworkNever opens no network under any invocation. Everything it needs // is the store, the working tree, or a module cache already on disk — and // where it drives the go toolchain it does so under an environment that // pins GOPROXY=off, so the child cannot reach one either. NetworkNever = "never" // NetworkAlways reaches the network as part of answering and offers no flag // that withdraws it. An invocation of one of these that happens to answer // offline did so because the store already held what it would have fetched, // not because the command declined to fetch — so nothing may be measured // hermetically on the strength of it. NetworkAlways = "always" // NetworkAvoidable reaches the network by default and has named flags that // make it answer offline instead. The flags are declared in // annotationOfflineFlags on the same command, so a caller — or a test — // applies them from the tree rather than from somebody remembering which // ones they were. NetworkAvoidable = "avoidable" )
The values annotationNetworkUse takes. A command declares exactly one.
const TestBinaryIsCLIEnv = "KANONARION_TEST_BINARY_IS_THE_CLI"
TestBinaryIsCLIEnv marks a process tree in which os.Executable() resolves to a Go TEST binary rather than to the kanonarion binary.
The callgraph and extract stages run as a fresh child of os.Executable(), so that a child holding a multi-gigabyte SSA closure dies with its work. Inside a test that drives Run in process, os.Executable() is the test binary, and a test binary handed `callgraph <module>@<version>` does not run the CLI: Go's testing package stops flag parsing at the first non-flag argument, finds no -run filter, and runs the WHOLE suite — including the test whose Run call caused the spawn, which spawns again. It is a fork bomb, and it is not theoretical: one filled a 31G tmpfs with 1025 half-built stores and cost 254 OOM kills.
A TestMain that may spawn itself therefore sets this variable for its children and, when it sees the variable already set, answers as the CLI instead of as a second copy of the suite. The variable is named here, beside the command registry, so the two TestMains that honour it cannot drift onto different spellings of it.
Variables ¶
This section is empty.
Functions ¶
func ExitCodeForError ¶
ExitCodeForError maps a Run error onto the process exit code. It honours an explicit exit-code carrier on the chain first (so categories like ExitNotFound survive), then the evidence-in-doubt sentinels, and otherwise falls back to ExitConfig. Shared by every main package so the binary's exit semantics are defined once here rather than duplicated per entry point.
A store-schema refusal — this binary meeting a store a newer one wrote — lands on ExitConfig, and does so by both routes: the CLI's own gate carries ExitConfig explicitly on the chain, and composition.ErrStoreSchemaNewer from the shared driver surface reaches the same code through the fallback. That is the intended classification, not an accident of the default: the store is intact and a current binary reads it fine, so it is a precondition failure and must not be reported as ExitIntegrity, which says the recorded evidence is in doubt.
func ExitCodeFromError ¶
ExitCodeFromError reports the exit code carried by err's chain, if any. Used by main to translate categorised errors (e.g. ExitNotFound) into distinct process exit codes rather than the catch-all ExitConfig.
func ExitStatus ¶ added in v0.16.1
ExitStatus prints err as the binary reports a failed command and returns the process exit code; nil prints nothing and is ExitOK.
func SetClockForTest ¶
SetClockForTest pins the CLI's wall clock to at, and returns the function that restores the system clock.
It is exported because the golden-output tests live outside this package: a recorded copy of a command's output can only be compared against a later run if every "now" the command consulted is the same in both. Nothing in the operating path calls it, and the production default is the system clock, so a build that never runs a test never leaves it.
Types ¶
type CheckCompatibilityUseCase ¶
type CheckCompatibilityUseCase interface {
CheckCompatibilityForWalk(ctx context.Context, walkID string, root coordinate.ModuleCoordinate, targetSPDX string, overrides licensedomain.LicenseOverrideSet) (licensedomain.ClosureCompatibilityReport, error)
}
CheckCompatibilityUseCase is the interface for the license compatibility engine.
type Container ¶
type Container struct {
// Config is the resolved store configuration for this invocation.
// Preferences have already been applied to logLevel/jsonOut by root's
// PersistentPreRunE; this field is provided for use-case layers that need
// access to license_policy, license_overrides, or callgraph settings.
Config domain.Config
// fetch
FetchModule QueryFetchUseCase // query-only; full fetch is done by runFetch directly
QueryFetch QueryFetchUseCase
// identity. Signer is the published substitution port for
// keyed attestation; the default is the OSS no-op (no attestation).
// Pipeline call sites are wired in a later subtask.
Signer fetchports.Signer
// walk
ExecuteWalk ExecuteWalkUseCase
QueryWalks QueryWalksUseCase
DiffWalks DiffWalksUseCase
// extract
Extract ExtractUseCase
QueryExtract QueryExtractionUseCase
// CallgraphBound is the subprocess bound this invocation adopted and what
// decided it. It is on the container because it is resolved when the
// extractor is built and a command that reports it must report the value the
// run is actually using — resolving it a second time reads the host again and
// can produce a different number from the one in force.
CallgraphBound extextractor.CallgraphBound
// license
ExtractLicense ExtractLicenseUseCase
QueryLicense QueryLicenseUseCase
DiffLicense DiffLicenseUseCase
GenerateNotice GenerateNoticeUseCase
CheckCompatibility CheckCompatibilityUseCase
LicenseOverrides licports.LicenseOverrideStore
// StdlibCustody is the recorded chain of custody for the standard library,
// which carries its licence on the acquisition rather than in a licence
// record. Every command asked about the stdlib coordinate reads it here, so
// the answer is the one audit and the SBOM already give.
StdlibCustody StdlibCustodyReader
// iface
ExtractInterface ExtractInterfaceUseCase
QueryInterface QueryInterfaceUseCase
DiffInterface DiffInterfaceUseCase
// callgraph
ExtractCallGraph ExtractCallGraphUseCase
ExtractLocalCallGraph ExtractLocalCallGraphUseCase
ExtractStdlibCallGraph ExtractStdlibCallGraphUseCase
QueryCallGraph QueryCallGraphUseCase
// examples
ExtractExample ExtractExampleUseCase
QueryExamples QueryExamplesUseCase
// vuln
ScanModule ScanModuleUseCase
ScanWalk ScanWalkUseCase
// SetAside is where the scans state the stored generations their writes and
// reuse reads set aside; a scanning command points it at its stderr.
SetAside *setAsideRelay
RescanWalk RescanWalkUseCase
QueryVuln QueryVulnUseCase
QueryScanRuns QueryScanRunsUseCase
DiffScanRuns DiffScanRunsUseCase
VulnStore vulnports.VulnerabilityStore
VulnPipelineVersion string
// NegativeSearch is the read-time call-graph search over stored negatives.
// QueryVuln already applies it; this is for the read paths that go to the
// vuln store directly rather than through the query use case, and for the
// records a fresh scan prints without reading them back.
NegativeSearch *reachability.NegativeSearcher
// sbom
GenerateSBOM GenerateSBOMUseCase
QuerySBOM QuerySBOMUseCase
// directive
ExtractDirectives *dirapp.ExtractDirectivesUseCase
QueryDirectives QueryDirectivesUseCase
DiffDirectives DiffDirectivesUseCase
// DirectiveParser reads a project's replace/exclude directives without
// recording a scan. A diagnostic needs the local-replace fact to name a
// remedy that can work, and reading it here keeps that answer coming from
// the directive context instead of a second go.mod parser. Nil means the
// question cannot be asked, which is not the same as answering "no".
DirectiveParser dirports.DirectiveParser
// godebug
ExtractGoDebug *gdapp.ExtractGoDebugUseCase
QueryGoDebug *gdapp.QueryGoDebugUseCase
// vendor
ExtractVendor *venapp.ExtractVendorUseCase
QueryVendor *venapp.QueryVendorUseCase
// fips
ExtractFIPS ExtractFIPSUseCase
QueryFIPS QueryFIPSUseCase
// native — the third-party C/C++ library a cgo module compiles into the
// binary from source it ships in its own zip.
ExtractNative *nativeapp.ExtractNativeUseCase
QueryNative *nativeapp.QueryNativeUseCase
// staleness. The ledger of latest-version lookups, read and written by
// every command that reports how far behind a dependency is.
StalenessLedger staleports.Ledger
// Audit is the backend's assurance log; ConfigHashes is its memory of the
// last config hash that log recorded, nil when it keeps none.
Audit fetchports.AuditSink
ConfigHashes configports.ConfigHashLedger
// contains filtered or unexported fields
}
Container is the composition root for the CLI. It wires every adapter over one storage value and exposes all use cases as interface fields.
func NewContainer ¶
func NewContainer(storeRoot, goproxy, goBinary string, skipVCSVerify bool, cfg domain.Config, logger *slog.Logger) (*Container, func() error, error)
NewContainer opens the store under storeRoot and returns the populated Container together with a cleanup function that closes the store.
cfg is the resolved store configuration; callers should pass activeConfig from the CLI layer. goBinary may be empty (falls back to PATH). skipVCSVerify is forwarded to the fetch use case for the walk pipeline.
func NewContainerFrom ¶
func NewContainerFrom(st *storage.Storage, storeRoot, goproxy, goBinary string, skipVCSVerify bool, cfg domain.Config, logger *slog.Logger) (*Container, func() error, error)
NewContainerFrom wires every adapter over st and returns the Container with a cleanup that closes st. It owns st: a refusal closes it before returning.
storeRoot is where the checksum-database cache and the call-graph child's --store-root live, not where records are stored.
type DiffDirectivesUseCase ¶
type DiffDirectivesUseCase interface {
Diff(ctx context.Context, scanIDA, scanIDB string) (directivedomain.DirectiveDiff, error)
}
DiffDirectivesUseCase is the interface for diffing two directive scans.
type DiffInterfaceUseCase ¶
type DiffInterfaceUseCase interface {
Diff(ctx context.Context, coordA, coordB coordinate.ModuleCoordinate) (ifacedomain.InterfaceDiff, error)
}
DiffInterfaceUseCase is the interface for diffing two stored interface records.
type DiffLicenseUseCase ¶
type DiffLicenseUseCase interface {
Diff(ctx context.Context, coordA, coordB coordinate.ModuleCoordinate) (licensedomain.LicenseDiff, error)
}
DiffLicenseUseCase is the interface for diffing two stored license records.
type DiffScanRunsUseCase ¶
type DiffScanRunsUseCase interface {
Diff(ctx context.Context, runIDA, runIDB string) (vulndomain.ScanRunDiff, error)
}
DiffScanRunsUseCase is the interface for diffing two scan runs.
type DiffWalksUseCase ¶
type DiffWalksUseCase interface {
Diff(ctx context.Context, idA, idB string) (walkapp.WalkDiff, error)
}
DiffWalksUseCase is the interface for diffing two walk records.
type ExecuteWalkUseCase ¶
type ExecuteWalkUseCase interface {
Execute(ctx context.Context, req walkapp.WalkRequest) (walkapp.ExecuteWalkResult, error)
}
ExecuteWalkUseCase is the interface for running a dependency walk.
type ExtractCallGraphUseCase ¶
type ExtractCallGraphUseCase interface {
Execute(ctx context.Context, req cgapp.ExtractRequest) (cgapp.ExtractResult, error)
}
ExtractCallGraphUseCase is the interface for extracting call graphs.
type ExtractExampleUseCase ¶
type ExtractExampleUseCase interface {
Execute(ctx context.Context, req exapp.ExtractRequest) (exapp.ExtractResult, error)
}
ExtractExampleUseCase is the interface for extracting examples.
type ExtractFIPSUseCase ¶
type ExtractFIPSUseCase interface {
Extract(ctx context.Context, goModPath string, policy configdomain.FIPSPolicy, configHash string) (fipsdomain.Record, error)
}
ExtractFIPSUseCase is the interface for running a FIPS assessment.
type ExtractInterfaceUseCase ¶
type ExtractInterfaceUseCase interface {
Execute(ctx context.Context, req ifaceapp.ExtractRequest) (ifaceapp.ExtractResult, error)
}
ExtractInterfaceUseCase is the interface for extracting module interfaces.
type ExtractLicenseUseCase ¶
type ExtractLicenseUseCase interface {
Execute(ctx context.Context, req licapp.ExtractRequest) (licapp.ExtractResult, error)
GetLicenseStore() licenseports.LicenseStore
}
ExtractLicenseUseCase is the interface for extracting license information.
type ExtractLocalCallGraphUseCase ¶
type ExtractLocalCallGraphUseCase interface {
Execute(ctx context.Context, req cgapp.LocalExtractRequest) (cgapp.ExtractResult, error)
}
ExtractLocalCallGraphUseCase is the interface for extracting the call graph of a local working tree.
type ExtractStdlibCallGraphUseCase ¶
type ExtractStdlibCallGraphUseCase interface {
Execute(ctx context.Context, req cgapp.ExtractRequest) (cgapp.ExtractResult, error)
}
ExtractStdlibCallGraphUseCase is the interface for extracting the call graph of the Go standard library from an installed toolchain's own source tree.
type ExtractUseCase ¶
type ExtractUseCase interface {
Execute(ctx context.Context, req extractapp.ExtractRequest) (extractdomain.ExtractionRun, error)
}
ExtractUseCase is the interface for running extraction stages.
type FetchModuleUseCase ¶
type FetchModuleUseCase interface {
Execute(ctx context.Context, req fetchapp.FetchRequest) (fetchapp.FetchResult, error)
}
FetchModuleUseCase is the interface for executing a module fetch.
type GenerateNoticeUseCase ¶
type GenerateNoticeUseCase interface {
Generate(ctx context.Context, req licapp.NoticeRequest) (licapp.NoticeResult, error)
}
GenerateNoticeUseCase is the interface for generating THIRD-PARTY-LICENSES attribution documents.
type GenerateSBOMUseCase ¶
type GenerateSBOMUseCase interface {
Generate(ctx context.Context, req sbomapp.SBOMRequest) (sbomdomain.SBOMRecord, error)
}
GenerateSBOMUseCase is the interface for generating SBOMs.
type QueryCallGraphUseCase ¶
type QueryCallGraphUseCase interface {
GetCallGraphRecord(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string) (callgraphdomain.CallGraphRecord, bool, error)
GetCallGraphRecordFrom(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string, req callgraphdomain.ComposeRequest) (callgraphdomain.CallGraphRecord, bool, error)
CallGraphHistory(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string) ([]callgraphdomain.CallGraphRecord, error)
ListCallGraphRecords(ctx context.Context, filter cgports.CallGraphFilter) ([]cgports.CallGraphSummary, error)
// ListCallGraphCoordinates answers "which modules has the store analysed, and
// at what versions" from the ledger's keys. It is what the resolution helpers
// ask, and it is separate from ListCallGraphRecords because that one answers
// the different question "what does the served generation say" — and pays a
// composition per multi-generation coordinate to do it.
ListCallGraphCoordinates(ctx context.Context, filter cgports.CallGraphFilter) ([]cgports.CallGraphCoordinate, error)
// ForeignModulesBuilt names the modules OTHER than the analysed one whose
// packages the served record for a coordinate built with bodies. It is read
// from the store's own column, never from a composed record: an edge query is
// answered out of the edge table without decoding anything, and qualifying
// that answer must not turn it into a query that does.
//
// found is false when the store holds no served generation. That is not an
// empty set and is never rendered as one.
ForeignModulesBuilt(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string, toolchain gotoolchain.Version) ([]callgraphdomain.ForeignModule, bool, error)
FindCallers(ctx context.Context, symbolID, pipelineVersion string, scope coordinate.ModuleSet, opts cgports.EdgeQueryOptions) ([]cgports.CallEdgeRef, error)
FindCallees(ctx context.Context, symbolID, pipelineVersion string, scope coordinate.ModuleSet, opts cgports.EdgeQueryOptions) ([]cgports.CallEdgeRef, error)
// TraverseCallers and TraverseCallees walk the graph transitively. The
// result carries whether the walk stopped at its depth bound holding
// symbols it had not expanded — the CLI states that and must not re-derive
// it, because the only thing outside this layer that could stand in for the
// unexpanded frontier is a comparison against a second, unbounded run.
TraverseCallers(ctx context.Context, req cgapp.TraversalRequest) (cgapp.TraversalResult, error)
TraverseCallees(ctx context.Context, req cgapp.TraversalRequest) (cgapp.TraversalResult, error)
// NotSearchedByCallers, NotSearchedByCallees and UnservedCoordinates name
// the coordinates an edge query could not read because they hold no
// generation at the served pipeline.
NotSearchedByCallers(ctx context.Context, symbolIDs []string, pipelineVersion string, scope coordinate.ModuleSet, opts cgports.EdgeQueryOptions) ([]cgports.UnservedCoordinate, error)
NotSearchedByCallees(ctx context.Context, symbolIDs []string, pipelineVersion string, scope coordinate.ModuleSet, opts cgports.EdgeQueryOptions) ([]cgports.UnservedCoordinate, error)
UnservedCoordinates(ctx context.Context, coords []coordinate.ModuleCoordinate, pipelineVersion string) ([]cgports.UnservedCoordinate, error)
}
QueryCallGraphUseCase is the interface for querying call graph records.
type QueryDirectivesUseCase ¶
type QueryDirectivesUseCase interface {
GetScan(ctx context.Context, scanID string) (directivedomain.Record, bool, error)
ListScans(ctx context.Context, projectModulePath string, limit, offset int) ([]directivedomain.Record, error)
// CountScans sizes the whole store, which ListScans cannot: it is keyed on
// a project, so an empty page can only speak for that project's history.
CountScans(ctx context.Context) (int, error)
// ListScanProjects names each project the store holds scans of; ok is
// false when the store cannot enumerate them.
ListScanProjects(ctx context.Context) (projects []string, ok bool, err error)
}
QueryDirectivesUseCase is the interface for reading stored directive scans.
type QueryExamplesUseCase ¶
type QueryExamplesUseCase interface {
GetExampleRecord(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string) (exampledomain.ExampleRecord, bool, error)
ExampleHistory(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string) ([]exampledomain.ExampleRecord, error)
PipelinesHeld(ctx context.Context, coord coordinate.ModuleCoordinate) ([]string, error)
ListExampleRecords(ctx context.Context, filter exampleports.ExampleFilter) ([]exampleports.ExampleSummary, error)
FindBySymbol(ctx context.Context, symbol, pipelineVersion string, scope coordinate.ModuleSet) ([]exampleports.ExampleRef, error)
FindBySymbolInModule(ctx context.Context, coord coordinate.ModuleCoordinate, symbol, pipelineVersion string) ([]exampleports.ExampleRef, error)
}
QueryExamplesUseCase is the interface for querying example records.
type QueryExtractionUseCase ¶
type QueryExtractionUseCase interface {
GetExtractionRun(ctx context.Context, id string) (extractdomain.ExtractionRun, error)
ListExtractionRuns(ctx context.Context, filter extractports.ExtractionRunFilter) ([]extractports.ExtractionRunSummary, error)
}
QueryExtractionUseCase is the interface for querying extraction runs.
type QueryFIPSUseCase ¶
type QueryFIPSUseCase interface {
Get(ctx context.Context, projectModulePath string) (fipsdomain.Record, bool, error)
}
QueryFIPSUseCase is the interface for querying stored FIPS records.
type QueryFetchUseCase ¶
type QueryFetchUseCase interface {
GetFetchRecord(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string) (fetchdomain.CompositeRecord, bool, error)
ComposeFetchRecord(ctx context.Context, coord coordinate.ModuleCoordinate) (fetchdomain.CompositeRecord, bool, error)
}
QueryFetchUseCase is the interface for querying fetch records.
Reporting commands use ComposeFetchRecord: they are asking what the ledger has measured about an artefact, and the generation of the fetch pipeline that measured it is not a property of the artefact. GetFetchRecord remains for the one caller that legitimately asks about a single generation.
type QueryInterfaceUseCase ¶
type QueryInterfaceUseCase interface {
GetInterfaceRecord(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string) (ifacedomain.InterfaceRecord, bool, error)
InterfaceHistory(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string) ([]ifacedomain.InterfaceRecord, error)
ListInterfaceRecords(ctx context.Context, filter ifaceports.InterfaceFilter) ([]ifaceports.InterfaceSummary, error)
ListInterfaceGenerations(ctx context.Context) ([]ifaceports.InterfaceGeneration, error)
FindSymbol(ctx context.Context, symbolName, pipelineVersion string, scope coordinate.ModuleSet) ([]ifaceports.SymbolRef, error)
}
QueryInterfaceUseCase is the interface for querying interface records.
type QueryLicenseUseCase ¶
type QueryLicenseUseCase interface {
GetLicenseRecord(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string) (licensedomain.LicenseRecord, bool, error)
ListLicenseRecords(ctx context.Context, filter licenseports.LicenseFilter) ([]licenseports.LicenseSummary, error)
LicenseHistory(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string) ([]licensedomain.LicenseRecord, error)
PipelinesHeld(ctx context.Context, coord coordinate.ModuleCoordinate) ([]string, error)
ResolveForWalk(ctx context.Context, walkID string, target coordinate.ModuleCoordinate, extractFn func(context.Context, coordinate.ModuleCoordinate) (licensedomain.LicenseRecord, error)) ([]licapp.DepLicenseResult, error)
}
QueryLicenseUseCase is the interface for querying license records.
type QuerySBOMUseCase ¶
type QuerySBOMUseCase interface {
GetSBOMRecord(ctx context.Context, id string) (sbomdomain.SBOMRecord, error)
ListSBOMRecords(ctx context.Context, walkID string) ([]sbomdomain.SBOMRecord, error)
}
QuerySBOMUseCase is the interface for querying SBOM records.
type QueryScanRunsUseCase ¶
type QueryScanRunsUseCase interface {
GetRun(ctx context.Context, id string) (vulndomain.WalkScanRun, bool, error)
ListRunsForWalk(ctx context.Context, walkID string) ([]vulndomain.WalkScanRun, error)
ListAllRuns(ctx context.Context) ([]vulndomain.WalkScanRun, error)
// UnresolvedWalks names the walks among runs that the store no longer holds,
// so a listing can say that those runs' inputs cannot be resolved instead of
// printing a walk id that looks like a live reference.
UnresolvedWalks(ctx context.Context, runs []vulndomain.WalkScanRun) (map[string]bool, error)
// WalkPresent answers the same question for a walk a caller named directly,
// where there may be no run to derive the id from.
WalkPresent(ctx context.Context, walkID string) (bool, error)
ListSnapshots(ctx context.Context) ([]vulndomain.DatabaseSnapshot, error)
GetLatestSnapshot(ctx context.Context) (vulndomain.DatabaseSnapshot, bool, error)
}
QueryScanRunsUseCase is the interface for querying scan runs and snapshots.
type QueryVulnUseCase ¶
type QueryVulnUseCase interface {
// ListRecordsForModuleInWalk returns a walk's candidate records for a
// coordinate, unranked. Every caller ranks them within a named frame — see
// recordInWalkFrame — because a walk's candidates span every frame the
// coordinate was measured in, including other projects' builds.
ListRecordsForModuleInWalk(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string, walkID string) ([]vulndomain.VulnerabilityRecord, error)
ListRecordsForModule(ctx context.Context, coord coordinate.ModuleCoordinate, pipelineVersion string) ([]vulndomain.VulnerabilityRecord, error)
// ListRecordsForModuleAllGenerations is the same listing with the generation
// lifted out of the key: every record the store holds for the coordinate,
// whatever pipeline version wrote it. It serves the history listing, which
// asks what has ever been recorded rather than what this build would answer,
// and it is the only read here a superseded record may reach a reader
// through — marked as superseded where it does.
ListRecordsForModuleAllGenerations(ctx context.Context, coord coordinate.ModuleCoordinate) ([]vulndomain.VulnerabilityRecord, error)
ListRecordsByFindingID(ctx context.Context, findingID, walkID string) ([]vulndomain.VulnerabilityRecord, error)
ListRecordsForRun(ctx context.Context, runID string) ([]vulndomain.VulnerabilityRecord, error)
// ListRecordGenerationsForModule is the census behind every empty answer:
// which pipeline versions the store holds this coordinate at, whatever
// version this build serves. The reads above all key on the version, so an
// empty result from them cannot tell "never scanned" from "scanned under
// logic this build has superseded". Nothing is answered from it.
ListRecordGenerationsForModule(ctx context.Context, coord coordinate.ModuleCoordinate) ([]vulnports.VulnerabilityRecordGeneration, error)
// FindingTimelines is vuln-by-id --timeline's answer, unreadable rows
// returned beside it as the listings above return theirs.
FindingTimelines(ctx context.Context, findingID, walkID string) ([]vulndomain.FindingTimeline, error)
}
QueryVulnUseCase is the interface for querying vulnerability records.
type QueryWalksUseCase ¶
type QueryWalksUseCase interface {
GetWalk(ctx context.Context, id string) (walkdomain.WalkRecord, error)
ListWalks(ctx context.Context, filter walkports.WalkFilter) ([]walkports.WalkSummary, error)
}
QueryWalksUseCase is the interface for querying walk records.
type RegisteredCommand ¶
type RegisteredCommand struct {
// Path is the command as a caller types it after "kanonarion": ["store",
// "info"] for `kanonarion store info`. Its last element is the name.
Path []string
// Aliases are the spellings accepted in place of Path's last element —
// "licence" for "license".
Aliases []string
// Runnable reports whether the path executes on its own. A grouping
// command such as "store" does not, so naming it alone is a broken
// instruction rather than a command.
Runnable bool
// Children names the subcommands registered under this path.
Children []string
// Flags are the long flag names accepted here, without their dashes,
// including the persistent flags inherited from parent commands: a caller
// can write --json on any command, and --help on all of them.
Flags []string
// HiddenFlags are the members of Flags the command registers but does not
// offer: a flag is hidden here when it is registered to be EXPLAINED rather
// than accepted, so that a caller who types it is told why instead of being
// shown cobra's "unknown flag".
//
// It is reported separately because Flags cannot carry the distinction and a
// guard needs it: a command's flag set answers "yes" for a flag the command
// refuses at runtime, so documentation advertising that flag passes any check
// that only asks what the tree accepts.
HiddenFlags []string
// StoreIntent is what the command declared about the store root: "create"
// if running it may bring that directory into existence, "read" if it must
// not, "none" if it opens no store at all, and "" if it declared nothing.
//
// The empty string is reported rather than folded into "read" so a guard
// can tell a command that decided from one that never did. At runtime both
// refuse — the default is the safe one — but only one of them is a bug.
StoreIntent string
}
RegisteredCommand describes one command in the CLI's command tree.
func RegisteredCommands ¶
func RegisteredCommands() []RegisteredCommand
RegisteredCommands returns every command the CLI registers, parents before children, so a caller can ask what exists rather than keeping a list.
The default help and completion commands are installed first. Cobra adds them during Execute, so a tree assembled without executing is two commands short of what a caller can actually type. Hidden commands are left out: the completion protocol's `__complete` is not a command anyone runs.
type RescanWalkUseCase ¶
type RescanWalkUseCase interface {
Rescan(ctx context.Context, req vulnapp.RescanRequest) (vulndomain.WalkScanRun, error)
}
RescanWalkUseCase is the interface for re-gating a walk against a new snapshot.
type ScanModuleUseCase ¶
type ScanModuleUseCase interface {
Scan(ctx context.Context, params vulnapp.ScanModuleParams) (vulndomain.VulnerabilityRecord, error)
}
ScanModuleUseCase is the interface for scanning a single module.
type ScanWalkUseCase ¶
type ScanWalkUseCase interface {
Scan(ctx context.Context, params vulnapp.ScanWalkParams) (vulndomain.WalkScanRun, error)
// ReusableRun reports a completed stored run that already answers what a new
// Scan of this walk against the current snapshot would ask. The caller
// decides whether to serve it; Scan itself always measures.
//
// projectDir is the working tree this invocation would scan, exactly as it
// is passed to Scan — empty when the caller names none, in which case the
// walk's own record of where it was taken from is used. It is an input to
// the decision, not to the answer: a stored run may only be served while
// that directory still requires the module versions the walk resolved, so
// the caller must hand over the same directory it would have scanned.
ReusableRun(ctx context.Context, walkID, projectDir string) (vulndomain.WalkScanRun, bool, error)
// ServeReusableRun witnesses in the assurance log that a stored run was
// handed back instead of measured. It is separate from ReusableRun because
// asking whether a run could serve is not serving it: some callers ask only
// to narrate, and some ask and then discard the answer.
ServeReusableRun(run vulndomain.WalkScanRun, surface string) error
// RefreshSnapshot brings the advisory database up to date for the named walk,
// downloading the body only when something that walk is judged on has
// changed, and reports what it established.
RefreshSnapshot(ctx context.Context, walkID string) (vulnapp.SnapshotRefresh, error)
// JudgeToolchain derives whether the stored snapshot's toolchain key covers
// the toolchain version a walk was built under. It reads the stored snapshot
// and records nothing.
JudgeToolchain(ctx context.Context, snapshot vulndomain.DatabaseSnapshot, toolchainVersion string) (vulndomain.ToolchainJudgment, error)
}
ScanWalkUseCase is the interface for scanning a full walk.
type StdlibCustodyLister ¶
type StdlibCustodyLister interface {
ListFactsFor(ctx context.Context, goVersion string) ([]stdlibdomain.Facts, error)
}
StdlibCustodyLister is the optional history read: every measurement the ledger holds for one toolchain version, oldest first. Callers type-assert for it, on the same terms as the licence ledger's own history read.
type StdlibCustodyReader ¶
type StdlibCustodyReader interface {
// Get returns the composed measurement for a canonical Go version
// ("go1.26.5"). The bool is false when the ledger holds none.
Get(ctx context.Context, goVersion string) (stdlibdomain.Facts, bool, error)
}
StdlibCustodyReader reads the recorded standard-library chain of custody for one toolchain version. It is the read half of the stdlib fact ledger: a command that reports a licence never writes to it, so it is declared here narrowly rather than taken as the whole store port.
Source Files
¶
- advisory_remedy.go
- audit.go
- audit_runfacts.go
- buildscope.go
- buildtarget.go
- buildvendoring.go
- callgraph.go
- callgraph_diff.go
- callgraph_foreign.go
- callgraph_frame.go
- callgraph_implementers.go
- callgraph_list.go
- callgraph_notsearched.go
- callgraph_resolution.go
- callgraph_show.go
- callgraph_traverse.go
- callgraphbound.go
- capability.go
- capability_json.go
- capability_text.go
- clock.go
- commands.go
- config.go
- config_effective.go
- confighash.go
- consumerjoin.go
- container.go
- context.go
- context_build.go
- context_capability.go
- context_gomod.go
- context_local.go
- context_render.go
- context_render_full.go
- context_size.go
- context_vuln.go
- context_walk.go
- dependents.go
- dependents_root.go
- derivation.go
- directives.go
- directives_diff.go
- examples.go
- exitcodes.go
- extract.go
- fetch.go
- fips.go
- flag_remedy.go
- flagalias.go
- flagscope.go
- godebug.go
- inspect.go
- interface.go
- interface_diff.go
- interface_render.go
- interface_resolution.go
- jsonout.go
- latest.go
- license.go
- license_compat.go
- license_diff.go
- license_list_scope.go
- license_remedy.go
- license_view.go
- listgeneration.go
- listtrunc.go
- listzero.go
- local.go
- manifestdrift.go
- native.go
- native_coverage.go
- native_list.go
- notice.go
- policy.go
- premodules.go
- private.go
- progress.go
- provenance.go
- provenance_basis.go
- reachability.go
- reachability_remedy.go
- root.go
- rootclass.go
- runenvelope.go
- sbom.go
- scopetests.go
- setaside.go
- shared.go
- sourcelimit.go
- staleness.go
- stdliblicence.go
- store.go
- store_ledger.go
- superseded_history.go
- superseded_pipeline.go
- symbolcontext.go
- testbinary.go
- tinygoframe.go
- toolchain.go
- toolchainlocator.go
- usage.go
- use.go
- usecases.go
- vendor.go
- verification_coverage_cmd.go
- verificationcoverage.go
- version.go
- vuln.go
- vuln_json.go
- vuln_query.go
- vuln_reuse.go
- vuln_scan.go
- vuln_scan_diff_view.go
- vuln_scan_query.go
- vuln_scan_reachability.go
- vuln_searched.go
- vuln_snapshot.go
- vuln_superseded.go
- vuln_timeline.go
- vuln_unscan_display.go
- vulnframe.go
- walk.go
- walk_buildlist.go
- walk_diff.go
- walk_errors.go
- walk_list.go
- walk_platform.go
- walk_show.go
- walkchoice.go
- walkcontainment.go
- walkid_lookup.go
- walkidarg.go