Documentation
¶
Overview ¶
Package safety provides safety gate functionality for the agent loop.
The safety gate validates proposed changes before they are executed, checking for potential issues like dangerous patterns, sensitive file modifications, or security vulnerabilities.
Thread Safety:
All types in this package are designed for concurrent use.
Index ¶
- Constants
- func IsSafetyError(errMsg string) bool
- type ChangeMetadata
- type Checker
- type CommandChecker
- type DefaultGate
- type FileSizeChecker
- type Gate
- type GateConfig
- type Issue
- type LineRange
- type MockGate
- type PathChecker
- type ProposedChange
- type Result
- type SafetyConstraint
- type Severity
- type SupplyChainChecker
Constants ¶
const SafetyBlockedError = "blocked by safety check"
SafetyBlockedError is the error string prefix for safety-blocked operations.
Variables ¶
This section is empty.
Functions ¶
func IsSafetyError ¶
IsSafetyError returns true if the error message indicates a safety violation.
Description:
Detects if an error was caused by the safety gate blocking an operation. This allows the CDCL algorithm to classify safety violations as hard signals and learn to avoid patterns that trigger safety blocks.
Inputs:
errMsg - The error message to check.
Outputs:
bool - True if this is a safety violation error.
Types ¶
type ChangeMetadata ¶
type ChangeMetadata struct {
// Reason explains why this change is being made.
Reason string `json:"reason,omitempty"`
// ToolName is the tool that initiated this change.
ToolName string `json:"tool_name,omitempty"`
// InvocationID links to the tool invocation.
InvocationID string `json:"invocation_id,omitempty"`
// OldContent is the previous content (for modifications).
OldContent string `json:"old_content,omitempty"`
// LineRange specifies the affected lines (for partial edits).
LineRange *LineRange `json:"line_range,omitempty"`
// Permissions are the requested file permissions (for creates).
Permissions string `json:"permissions,omitempty"`
}
ChangeMetadata contains additional typed information about a proposed change.
type Checker ¶
type Checker interface {
// Name returns the checker name.
Name() string
// Check runs the safety check.
Check(ctx context.Context, change *ProposedChange) []Issue
}
Checker is a single safety check.
type CommandChecker ¶
type CommandChecker struct {
// contains filtered or unexported fields
}
CommandChecker validates shell commands against blocked patterns.
Description:
Checks if proposed shell commands contain blocked patterns defined in the configuration (e.g., "rm -rf", "chmod 777"). Returns critical issues for any blocked command matches.
Thread Safety:
CommandChecker is safe for concurrent use as it only reads config.
func (*CommandChecker) Check ¶
func (c *CommandChecker) Check(ctx context.Context, change *ProposedChange) []Issue
Check implements Checker.
type DefaultGate ¶
type DefaultGate struct {
// contains filtered or unexported fields
}
DefaultGate implements the Gate interface with configurable checks.
Thread Safety: DefaultGate is safe for concurrent use.
func NewDefaultGate ¶
func NewDefaultGate(config *GateConfig) *DefaultGate
NewDefaultGate creates a new safety gate with the provided config.
Description:
Creates a DefaultGate instance with the specified configuration. Registers default checkers: PathChecker, CommandChecker, and FileSizeChecker. If config is nil, uses DefaultGateConfig().
Inputs:
config - Gate configuration. If nil, uses defaults.
Outputs:
*DefaultGate - The configured gate with default checkers registered.
Example:
gate := NewDefaultGate(&GateConfig{
Enabled: true,
BlockOnCritical: true,
BlockedPaths: []string{".git", ".env"},
})
func (*DefaultGate) Check ¶
func (g *DefaultGate) Check(ctx context.Context, changes []ProposedChange) (*Result, error)
Check implements Gate.
func (*DefaultGate) GenerateWarnings ¶
func (g *DefaultGate) GenerateWarnings(result *Result) []string
GenerateWarnings implements Gate.
func (*DefaultGate) RegisterChecker ¶
func (g *DefaultGate) RegisterChecker(checker Checker)
RegisterChecker adds a checker to the gate.
func (*DefaultGate) ShouldBlock ¶
func (g *DefaultGate) ShouldBlock(result *Result) bool
ShouldBlock implements Gate.
type FileSizeChecker ¶
type FileSizeChecker struct {
// contains filtered or unexported fields
}
FileSizeChecker validates file write sizes against configured limits.
Description:
Checks if proposed file write content exceeds the maximum file size limit defined in the configuration. Returns a warning for oversized files.
Thread Safety:
FileSizeChecker is safe for concurrent use as it only reads config.
func (*FileSizeChecker) Check ¶
func (c *FileSizeChecker) Check(ctx context.Context, change *ProposedChange) []Issue
Check implements Checker.
type Gate ¶
type Gate interface {
// Check validates the proposed changes.
//
// Inputs:
// ctx - Context for cancellation.
// changes - The changes to validate.
//
// Outputs:
// *Result - The check result.
// error - Non-nil if the check itself fails.
Check(ctx context.Context, changes []ProposedChange) (*Result, error)
// ShouldBlock determines if the result should block execution.
//
// Inputs:
// result - The check result.
//
// Outputs:
// bool - True if execution should be blocked.
ShouldBlock(result *Result) bool
// GenerateWarnings creates human-readable warnings from issues.
//
// Inputs:
// result - The check result.
//
// Outputs:
// []string - Warning messages.
GenerateWarnings(result *Result) []string
}
Gate is the safety gate interface.
Implementations validate proposed changes before execution.
type GateConfig ¶
type GateConfig struct {
// Enabled determines if safety checks are enabled.
Enabled bool
// BlockOnCritical determines if critical issues block execution.
BlockOnCritical bool
// BlockOnWarning determines if warnings also block execution.
BlockOnWarning bool
// AllowedPaths are paths that are always allowed to be modified.
AllowedPaths []string
// BlockedPaths are paths that are never allowed to be modified.
BlockedPaths []string
// AllowedCommands are shell commands that are always allowed.
AllowedCommands []string
// BlockedCommands are shell commands that are never allowed.
BlockedCommands []string
// MaxFileSize is the maximum allowed file size for writes.
MaxFileSize int64
// AllowPackageInstall permits package installation commands when true.
// When false (default), commands like "npm install", "pip install",
// "cargo install", etc. are blocked to prevent supply chain attacks.
// Set to true only when explicitly requested by user (e.g., --allow-install flag).
AllowPackageInstall bool
}
GateConfig configures the safety gate behavior.
func DefaultGateConfig ¶
func DefaultGateConfig() GateConfig
DefaultGateConfig returns sensible defaults.
type Issue ¶
type Issue struct {
// Severity indicates how serious the issue is.
Severity Severity `json:"severity"`
// Code is a machine-readable issue code.
Code string `json:"code"`
// Message is a human-readable description.
Message string `json:"message"`
// Change is the change that triggered this issue.
Change *ProposedChange `json:"change,omitempty"`
// Suggestion is an optional suggested fix.
Suggestion string `json:"suggestion,omitempty"`
}
Issue represents a safety issue found during checking.
type MockGate ¶
type MockGate struct {
// CheckFunc overrides Check behavior.
CheckFunc func(ctx context.Context, changes []ProposedChange) (*Result, error)
// ShouldBlockFunc overrides ShouldBlock behavior.
ShouldBlockFunc func(result *Result) bool
// Calls records all Check calls.
Calls [][]ProposedChange
// contains filtered or unexported fields
}
MockGate is a mock implementation for testing.
func (*MockGate) GenerateWarnings ¶
GenerateWarnings implements Gate.
func (*MockGate) ShouldBlock ¶
ShouldBlock implements Gate.
type PathChecker ¶
type PathChecker struct {
// contains filtered or unexported fields
}
PathChecker validates file operations against blocked path patterns.
Description:
Checks if proposed file operations (writes, deletes) target paths that match blocked patterns defined in the configuration. Returns critical issues for any blocked path matches.
Thread Safety:
PathChecker is safe for concurrent use as it only reads config.
func (*PathChecker) Check ¶
func (c *PathChecker) Check(ctx context.Context, change *ProposedChange) []Issue
Check implements Checker.
type ProposedChange ¶
type ProposedChange struct {
// Type is the kind of change (e.g., "file_write", "file_delete", "shell_command").
Type string `json:"type"`
// Target is the target of the change (e.g., file path, command).
Target string `json:"target"`
// Content is the proposed content (for writes).
Content string `json:"content,omitempty"`
// Metadata contains additional typed information about the change.
Metadata *ChangeMetadata `json:"metadata,omitempty"`
}
ProposedChange represents a change the agent wants to make.
type Result ¶
type Result struct {
// Passed is true if no blocking issues were found.
Passed bool `json:"passed"`
// Issues contains all issues found during checking.
Issues []Issue `json:"issues,omitempty"`
// CriticalCount is the number of critical issues.
CriticalCount int `json:"critical_count"`
// WarningCount is the number of warnings.
WarningCount int `json:"warning_count"`
// ChecksRun is the number of safety checks that were executed.
ChecksRun int `json:"checks_run"`
}
Result contains the result of a safety check.
func (*Result) HasCritical ¶
HasCritical returns true if there are critical issues.
func (*Result) HasWarnings ¶
HasWarnings returns true if there are warnings.
func (*Result) ToErrorMessage ¶
ToErrorMessage converts a Result to an error message for learning.
Description:
Creates a detailed error message from safety issues that can be used by CDCL for conflict analysis. The message includes issue codes for pattern matching.
Inputs:
result - The safety check result.
Outputs:
string - The error message for learning.
type SafetyConstraint ¶
type SafetyConstraint struct {
// IssueCode is the safety issue code (e.g., "SUPPLY_CHAIN_INSTALL").
IssueCode string
// Pattern describes what triggered the violation.
Pattern string
// ConflictingNodes are the MCTS nodes involved in the violation.
ConflictingNodes []string
// Reason explains why this is blocked.
Reason string
}
SafetyConstraint represents a constraint derived from a safety violation.
This is used to feed safety violations to CDCL as learning signals. When the safety gate blocks an action, the constraint encodes what pattern should be avoided.
func ExtractConstraints ¶
func ExtractConstraints(result *Result, nodeID string) []SafetyConstraint
ExtractConstraints extracts learning constraints from safety issues.
Description:
Converts safety issues into constraints that CDCL can learn from. Each constraint encodes a pattern that should be avoided in future search iterations.
Inputs:
result - The safety check result containing issues. nodeID - The MCTS node ID that triggered the check.
Outputs:
[]SafetyConstraint - Constraints derived from the issues.
type SupplyChainChecker ¶
type SupplyChainChecker struct {
// contains filtered or unexported fields
}
SupplyChainChecker validates shell commands against supply chain attack patterns.
Description:
Blocks package manager installation commands that could introduce malicious dependencies. Commands like "npm install", "pip install", "cargo install" are blocked by default because postinstall scripts can execute arbitrary code. Safe subcommands (test, build, run) are always allowed.
Thread Safety:
SupplyChainChecker is safe for concurrent use as it only reads config.
func (*SupplyChainChecker) Check ¶
func (c *SupplyChainChecker) Check(ctx context.Context, change *ProposedChange) []Issue
Check implements Checker.
Description:
Validates shell commands against supply chain attack patterns. Blocks package installation commands unless AllowPackageInstall is set.
Inputs:
ctx - Context for cancellation (unused but required by interface). change - The proposed change to validate.
Outputs:
[]Issue - List of issues found. Empty if command is allowed.
func (*SupplyChainChecker) Name ¶
func (c *SupplyChainChecker) Name() string
Name implements Checker.