Documentation
¶
Overview ¶
Package gate is the pre-execution and pre-edit policy engine (RFC-001 §5.5): commands are parsed with a real shell parser (never regex), classified against the effect catalogue, and evaluated against CEL rules over the declared environment. Every decision is appended to an audit log.
Index ¶
Constants ¶
const ( VerdictAllow = "allow" VerdictApproval = "require_approval" VerdictDeny = "deny" )
Decision severities, weakest to strongest.
Variables ¶
var ErrBlocked = errors.New("blocked by policy")
ErrBlocked marks decisions that must stop the caller (enforce mode); the CLI maps it to a distinct exit code for hooks and CI.
Functions ¶
func Audit ¶
Audit appends the decision to <root>/.seamark/audit.jsonl (0600, rotated by size and age). The default entry stores the normalized command names, a SHA-256 of the input, the verdict and the policy hash — never the raw input, which frequently carries tokens, passwords and connection strings. Opting in via policy.yaml (`audit:` → `raw: true`) persists the input line with best-effort secret redaction.
func ChangedPaths ¶ added in v0.2.0
ChangedPaths lists the repo-relative files a unified diff touches, in first-appearance order — the same header parsing EvalDiff trusts, so an advisory surface (lessons on `check`) can never disagree with the verdict about which files changed.
Types ¶
type Decision ¶
type Decision struct {
Verdict string `json:"verdict"` // strongest of the matches
Mode string `json:"mode"` // warn | enforce
Effects []string `json:"effects"`
Matches []Match `json:"matches,omitempty"`
// Commands are the normalized command names found in the input
// (wrappers unwrapped, interpreter payloads included) — what the
// audit log stores instead of the raw command line.
Commands []string `json:"commands,omitempty"`
// PolicySHA identifies the exact policy text that produced this
// decision.
PolicySHA string `json:"policy_sha256,omitempty"`
// Notes carry uncertainty the verdict alone would hide — e.g.
// changed files the index has no symbols for. A note never changes
// the verdict; it changes how much the verdict may be trusted.
Notes []string `json:"notes,omitempty"`
}
Decision is the gate's answer for one input.
func EvalCommand ¶
EvalCommand parses a shell command line, classifies every command in it (pipelines, &&-chains, substitutions, and interpreter payloads like `bash -c "…"` included) against the catalogue, and evaluates the policy. Parse failures fail closed with an error — a gate that shrugs at unparseable input is a bypass.
type Match ¶
type Match struct {
RuleID string `json:"rule"`
Verdict string `json:"verdict"`
Message string `json:"message"`
}
Match is one rule that fired.
type Policy ¶
type Policy struct {
// Mode "warn" reports verdicts without blocking; "enforce" makes deny
// and require_approval binding. Warn is the default (§10: a policy
// layer that cries wolf gets disabled).
Mode string `yaml:"mode"`
Environment struct {
Detect []string `yaml:"detect"`
ProdMarkers []string `yaml:"prod_markers"`
} `yaml:"environment"`
// Audit configures decision logging. Raw opts into persisting the
// input line (secret patterns redacted best-effort); the default
// entry carries only a SHA-256 of the input, because command lines
// frequently embed tokens, passwords and connection strings.
Audit struct {
Raw bool `yaml:"raw"`
} `yaml:"audit"`
Deny []Rule `yaml:"deny"`
RequireApproval []Rule `yaml:"require_approval"`
// Hash is the SHA-256 of the policy source that produced this rule
// set: audit entries carry it so a decision can be correlated with
// the exact policy text that made it.
Hash string `yaml:"-"`
}
Policy is the loaded rule set.
func LoadPolicy ¶
LoadPolicy returns the workspace policy at .seamark/policy.yaml, or the embedded warn-mode default when absent. The workspace file REPLACES the default rule set (policy is a whole, not a patch — partial merges would make the effective rules unreviewable). All CEL expressions compile at load time so a broken rule fails loudly, not at decision time.