pythonprogram

package
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package pythonprogram defines the deterministic, source-only semantic facts used by Python Tier-2 reachability and value-flow taint. The model is parser-independent: tree-sitter is confined to the synapse-ast infrastructure sidecar and every document is validated here before a use case trusts it.

Index

Constants

View Source
const (
	// SchemaVersion is the only semantic-facts wire version this build understands.
	SchemaVersion = 2
)

Variables

This section is empty.

Functions

func ValidSubscriptKey

func ValidSubscriptKey(key string) bool

ValidSubscriptKey reports whether a captured subscript key is within the facts bound and printable. It is the single source of truth shared by the trust-boundary validator (validateSubscript) and the extractor, which consults it to WIDEN (emit a dynamic key) rather than emit a key that would fail validation and reject the whole document. A structural selector is length-bounded and carries no control characters.

Types

type Argument

type Argument struct {
	Keyword string    `json:"keyword,omitempty"`
	Star    bool      `json:"star,omitempty"`
	Value   Reference `json:"value"`
	ValueID string    `json:"value_id,omitempty"`
	Pos     Position  `json:"position,omitempty"`
}

Argument is one positional or keyword call argument. Starred values carry Star=true; double-starred values carry Keyword="**". Value is a bounded reference summary.

type Assignment

type Assignment struct {
	ScopeID   string      `json:"scope_id"`
	Targets   []Reference `json:"targets"`
	TargetIDs []string    `json:"target_ids,omitempty"`
	Value     Reference   `json:"value"`
	ValueID   string      `json:"value_id,omitempty"`
	Pos       Position    `json:"position"`
}

Assignment captures a binding/value relationship without retaining expression text.

type Call

type Call struct {
	ID       string    `json:"id"`
	CallerID string    `json:"caller_id"`
	Callee   Reference `json:"callee"`
	// BoundedCallees is a producer assertion that every possible direct local callable has been
	// enumerated from an immutable dispatch source and copied out of mutable extractor state. A
	// producer that cannot prove both properties must omit this field and retain the normal gap.
	BoundedCallees  []Reference `json:"bounded_callees,omitempty"`
	Arguments       []Argument  `json:"arguments,omitempty"`
	ResultID        string      `json:"result_id,omitempty"`
	ReceiverValueID string      `json:"receiver_value_id,omitempty"`
	Pos             Position    `json:"position"`
	Await           bool        `json:"await,omitempty"`
}

Call is one syntactic call expression owned by CallerID. Callee is a name/attribute reference when statically expressible, otherwise ReferenceUnknown and a matching coverage gap is required. BoundedCallees is present only when an immutable literal mapping selects from a finite set of local callables. It does not make the call statically resolved: each candidate remains subject-local uncertainty for negative proofs.

type CallResolutionStatus

type CallResolutionStatus string

CallResolutionStatus records whether one syntactic call has a unique semantic target. Ambiguous calls retain every conservative candidate but make negative reachability incomplete.

const (
	CallResolved   CallResolutionStatus = "resolved"
	CallExternal   CallResolutionStatus = "external"
	CallAmbiguous  CallResolutionStatus = "ambiguous"
	CallUnresolved CallResolutionStatus = "unresolved"
)

type CoverageGap

type CoverageGap struct {
	Kind     GapKind  `json:"kind"`
	SymbolID string   `json:"symbol_id,omitempty"`
	Detail   string   `json:"detail,omitempty"`
	Pos      Position `json:"position"`
}

CoverageGap is an explicit reason a complete negative is unsafe. Detail is a trusted closed label, not parser stderr or target source.

type Document

type Document struct {
	SchemaVersion int              `json:"schema_version"`
	Modules       []Module         `json:"modules"`
	Symbols       []Symbol         `json:"symbols"`
	Imports       []Import         `json:"imports"`
	Calls         []Call           `json:"calls"`
	Assignments   []Assignment     `json:"assignments"`
	Returns       []Return         `json:"returns"`
	Values        []Value          `json:"values"`
	Flows         []ValueFlow      `json:"flows"`
	Entrypoints   []EntrypointHint `json:"entrypoint_hints"`
	CoverageGaps  []CoverageGap    `json:"coverage_gaps"`
	FilesSeen     int              `json:"files_seen"`
	FilesParsed   int              `json:"files_parsed"`
	NodesSeen     int              `json:"nodes_seen"`
	Truncated     bool             `json:"truncated"`
}

Document is the complete versioned facts result for one source root.

func (Document) Complete

func (d Document) Complete() bool

Complete reports whether the document can support a negative proof.

func (*Document) SortCanonical

func (d *Document) SortCanonical()

SortCanonical makes serialization and downstream graph construction independent of map/parser order.

func (Document) Validate

func (d Document) Validate() error

Validate rejects malformed or unbounded sidecar output at the trust boundary.

type EntrypointHint

type EntrypointHint struct {
	SymbolID string   `json:"symbol_id"`
	Kind     string   `json:"kind"`
	Pos      Position `json:"position"`
}

EntrypointHint is a syntactic framework/application entrypoint cue. Resolution decides whether it is usable; extraction does not silently promote an arbitrary decorator into an entrypoint.

type GapKind

type GapKind string

GapKind is a closed reason code explaining why absence cannot be treated as proof.

const (
	GapParseRecovery        GapKind = "parse_recovery"
	GapDynamicImport        GapKind = "dynamic_import"
	GapDynamicExecution     GapKind = "dynamic_execution"
	GapWildcardImport       GapKind = "wildcard_import"
	GapUnresolvedImport     GapKind = "unresolved_import"
	GapUnresolvedCall       GapKind = "unresolved_call"
	GapUnresolvedValue      GapKind = "unresolved_value"
	GapDynamicAttribute     GapKind = "dynamic_attribute"
	GapUnsupportedDecorator GapKind = "unsupported_decorator"
	GapUnsupportedNotebook  GapKind = "unsupported_notebook"
	GapBudget               GapKind = "budget"
	GapUnreadable           GapKind = "unreadable"
)

func (GapKind) Valid

func (k GapKind) Valid() bool

type Import

type Import struct {
	ScopeID  string   `json:"scope_id"`
	Module   string   `json:"module"`
	Name     string   `json:"name,omitempty"`
	Alias    string   `json:"alias,omitempty"`
	Level    int      `json:"level,omitempty"`
	Wildcard bool     `json:"wildcard,omitempty"`
	Pos      Position `json:"position"`
}

Import records one import binding. ScopeID is the module/function/class lexical owner. For `from ..pkg import item`, Module="pkg", Name="item", and Level=2.

type Module

type Module struct {
	Name string   `json:"name"`
	File string   `json:"file"`
	Pos  Position `json:"position"`
}

Module associates a canonical module candidate with its source file.

type Parameter

type Parameter struct {
	Name    string        `json:"name"`
	Kind    ParameterKind `json:"kind"`
	ValueID string        `json:"value_id,omitempty"`
	Pos     Position      `json:"position"`
}

Parameter is one callable parameter in declaration order.

type ParameterKind

type ParameterKind string

ParameterKind preserves Python's argument-binding semantics without carrying annotations/default text.

const (
	ParameterPositional  ParameterKind = "positional"
	ParameterVarArgs     ParameterKind = "varargs"
	ParameterKwArgs      ParameterKind = "kwargs"
	ParameterKeywordOnly ParameterKind = "keyword_only"
)

func (ParameterKind) Valid

func (k ParameterKind) Valid() bool

type Position

type Position struct {
	File   string `json:"file"`
	Line   int    `json:"line"`
	Column int    `json:"column"`
}

Position is a normalized, relative source location. Column is zero-based, Line is one-based.

type Reference

type Reference struct {
	Kind     ReferenceKind `json:"kind"`
	Segments []string      `json:"segments,omitempty"`
}

Reference is a safe expression summary such as ["request", "args", "get"]. No source body or literal value is retained. Literal references only carry Kind, not their value.

type ReferenceKind

type ReferenceKind string

ReferenceKind describes a bounded expression shape. It intentionally excludes arbitrary source text.

const (
	ReferenceName       ReferenceKind = "name"
	ReferenceAttribute  ReferenceKind = "attribute"
	ReferenceCall       ReferenceKind = "call"
	ReferenceExpression ReferenceKind = "expression"
	ReferenceLiteral    ReferenceKind = "literal"
	ReferenceUnknown    ReferenceKind = "unknown"
)

func (ReferenceKind) Valid

func (k ReferenceKind) Valid() bool

type Resolution

type Resolution struct {
	Graph                  callgraph.Graph `json:"-"`
	Calls                  []ResolvedCall  `json:"calls"`
	Gaps                   []CoverageGap   `json:"coverage_gaps"`
	ClosedWorldEntrypoints []string        `json:"closed_world_entrypoints"`
	BoundedUncertainNodes  []string        `json:"bounded_uncertain_nodes,omitempty"`
	CompleteExceptBounded  bool            `json:"complete_except_bounded"`
	Complete               bool            `json:"complete"`
}

Resolution is the pure Tier-2 result. Graph remains useful for positive evidence when Complete is false; callers must require Complete before treating absence of a path as a negative proof. A finite literal-mapping dispatch is retained separately: it prevents analysis-wide completeness, but a target outside every finite candidate and its downstream graph closure may still be eligible for a local negative.

func Resolve

func Resolve(document Document) (Resolution, error)

Resolve builds a deterministic, conservative Python call graph without filesystem or interpreter I/O.

type ResolvedCall

type ResolvedCall struct {
	CallID    string               `json:"call_id"`
	CallerID  string               `json:"caller_id"`
	Callees   []string             `json:"callees,omitempty"`
	Status    CallResolutionStatus `json:"status"`
	Pos       Position             `json:"position"`
	Ambiguous bool                 `json:"ambiguous,omitempty"`
}

ResolvedCall connects a source call fact to its deterministic semantic candidates.

type Return

type Return struct {
	ScopeID string    `json:"scope_id"`
	Value   Reference `json:"value"`
	ValueID string    `json:"value_id,omitempty"`
	SlotID  string    `json:"slot_id,omitempty"`
	Pos     Position  `json:"position"`
}

Return captures a function return expression summary.

type Symbol

type Symbol struct {
	ID            string      `json:"id"`
	Module        string      `json:"module"`
	QualifiedName string      `json:"qualified_name"`
	Name          string      `json:"name"`
	ParentID      string      `json:"parent_id,omitempty"`
	Kind          SymbolKind  `json:"kind"`
	Pos           Position    `json:"position"`
	Parameters    []Parameter `json:"parameters,omitempty"`
	Decorators    []Reference `json:"decorators,omitempty"`
	Bases         []Reference `json:"bases,omitempty"`
	Async         bool        `json:"async,omitempty"`
}

Symbol is a module, class, function, method, or lambda declaration.

type SymbolKind

type SymbolKind string

SymbolKind identifies a Python declaration that owns a lexical scope or can appear in a call graph.

const (
	SymbolModule   SymbolKind = "module"
	SymbolClass    SymbolKind = "class"
	SymbolFunction SymbolKind = "function"
	SymbolMethod   SymbolKind = "method"
	SymbolLambda   SymbolKind = "lambda"
)

func (SymbolKind) Valid

func (k SymbolKind) Valid() bool

type Value

type Value struct {
	ID      string    `json:"id"`
	ScopeID string    `json:"scope_id"`
	Kind    ValueKind `json:"kind"`
	Name    string    `json:"name,omitempty"`
	Ref     Reference `json:"reference"`
	Pos     Position  `json:"position"`
	// SubKey and SubDyn describe a subscript-container appearance of a simple local name so the taint
	// engine can refine per-literal-key when a container provably cannot alias or escape. SubKey holds the
	// literal key text of container[literal] (a structural selector, not a scalar value); SubDyn marks
	// container[<non-literal>], which forces the engine to widen back to whole-container taint. Both are set
	// only on a Reference/Binding whose Ref is a single bare name; a bare use of the name leaves both zero,
	// which the engine reads as an escape. They never appear together.
	SubKey string `json:"subscript_key,omitempty"`
	SubDyn bool   `json:"subscript_dynamic,omitempty"`
}

Value is one stable value slot. Ref carries only a bounded semantic shape; source text is never kept.

type ValueFlow

type ValueFlow struct {
	FromID string        `json:"from_id"`
	ToID   string        `json:"to_id"`
	Kind   ValueFlowKind `json:"kind"`
	Pos    Position      `json:"position"`
}

ValueFlow says a value can propagate from one slot to another inside the same Python function.

type ValueFlowKind

type ValueFlowKind string

ValueFlowKind is a closed intra-procedural propagation operation emitted by the sidecar.

const (
	FlowExpression ValueFlowKind = "expression"
	FlowAttribute  ValueFlowKind = "attribute"
	FlowAssignment ValueFlowKind = "assignment"
	FlowReturn     ValueFlowKind = "return"
)

func (ValueFlowKind) Valid

func (k ValueFlowKind) Valid() bool

type ValueKind

type ValueKind string

ValueKind identifies a source-level value slot used by the interprocedural taint engine.

const (
	ValueParameter  ValueKind = "parameter"
	ValueBinding    ValueKind = "binding"
	ValueReference  ValueKind = "reference"
	ValueCallResult ValueKind = "call_result"
	ValueExpression ValueKind = "expression"
	ValueLiteral    ValueKind = "literal"
	ValueReturn     ValueKind = "return"
)

func (ValueKind) Valid

func (k ValueKind) Valid() bool

Jump to

Keyboard shortcuts

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