Documentation
¶
Overview ¶
Package verify governs command execution for a mission: which argv may run, and under which limits. Deny-by-default, and the policy never comes from the request being judged.
Index ¶
- Constants
- func RegisterTool(server *mcp.Server, root string)
- func RegisterToolWithTaskManager(server *mcp.Server, root string, manager *TaskManager)
- func RetainTasksAt(root string, now time.Time) error
- func Run(ctx context.Context, root string, in Input) capabilityruntime.Result
- func RunWithManager(ctx context.Context, root string, in Input, manager *TaskManager) capabilityruntime.Result
- func SearchPath(pathDirs []string) []string
- func ValidTaskID(taskID string) bool
- type Allowlist
- type Config
- type Data
- type Entry
- type Envelope
- type Execution
- type Input
- type RawTaskExecutor
- type Result
- type RunCommandInput
- type Runner
- type Task
- type TaskConfig
- type TaskExecutor
- type TaskInfo
- type TaskManager
- func (manager *TaskManager) Cancel(taskID string) (TaskInfo, error)
- func (manager *TaskManager) Get(taskID string, includeResult bool) (TaskSnapshot, error)
- func (manager *TaskManager) List(includeResult bool) ([]TaskSnapshot, error)
- func (manager *TaskManager) RegisterRawExecutor(capability string, executor RawTaskExecutor) error
- func (manager *TaskManager) RetainTasks() error
- func (manager *TaskManager) Start(ctx context.Context, input Input) (TaskInfo, error)
- func (manager *TaskManager) StartRaw(ctx context.Context, capability, runID string, input json.RawMessage) (TaskInfo, error)
- type TaskSnapshot
- type TaskStatus
Constants ¶
const ( VerdictPass = "pass" VerdictFail = "fail" VerdictTimeout = "timeout" VerdictBlocked = "blocked" VerdictNotRun = "not_run" )
Aggregate verdicts. not_run is in the enum on purpose, against the four-value draft of the phase plan: a verify that ran nothing is not an approval, and a cancelled batch reported as failures becomes N phantom remediations downstream. The autonomy policy requires verdict == pass, literally.
const ( StatusPassed = "passed" StatusFailed = "failed" StatusTimedOut = "timed_out" StatusBlocked = "blocked" StatusNotRun = "not_run" )
Per-command outcome. The verdict is a struct, never a formatted string: the previous product decided error by comparing the summary to a literal phrase, so adding the duration to the formatter would have silently inverted the verdict of every successful command.
const ConfigPath = ".jacu/verify-allowlist.json"
ConfigPath is where a project declares its policy. It is read from the project root and never from a run worktree: the worktree is writable by the model, and a policy the governed object can edit is not a policy.
const CurrentTaskSchemaVersion = "2"
const (
ToolName = "jacu_verify"
)
Variables ¶
This section is empty.
Functions ¶
func RegisterTool ¶
func RegisterToolWithTaskManager ¶
func RegisterToolWithTaskManager(server *mcp.Server, root string, manager *TaskManager)
func RetainTasksAt ¶
RetainTasksAt applies the durable task retention policy for root at now. It is shared with explicit storage lifecycle actions; callers never need to reproduce task classification or deletion decisions.
func RunWithManager ¶ added in v0.4.0
func RunWithManager(ctx context.Context, root string, in Input, manager *TaskManager) capabilityruntime.Result
func SearchPath ¶
SearchPath exposes the verifier's reconstructed search path to read-only preflight checks so they predict the environment in which verification runs.
func ValidTaskID ¶
Types ¶
type Allowlist ¶
type Allowlist struct {
// contains filtered or unexported fields
}
Allowlist is the effective policy: the curated global list plus the project allowances, minus the project denials.
func New ¶
New composes the effective allowlist. Deny wins over allow and over the global list, always — it is the only precedence that cannot loosen policy by accident.
func (Allowlist) Check ¶
Check applies the rejection order of the phase design. The first rule that matches decides, and every refusal names its own reason: every later gate would also refuse, so a caller reading only "refused" cannot tell which door is locked.
The first rule of the design — a command passed as a single string instead of an argv array — is enforced by the tool schema, which has no string command field to send.
func (Allowlist) KnowsProgram ¶
type Config ¶
type Config struct {
Allow []Entry `json:"allow,omitempty"`
Deny []string `json:"deny,omitempty"`
PathDirs []string `json:"path_dirs,omitempty"`
}
Config is the per-project policy, read from the project root.
func LoadConfig ¶
LoadConfig reads the project policy. An absent file is normal and means the global list applies alone; a malformed file is an error, because a broken policy must not degrade into no policy.
type Data ¶
type Data struct {
Verdict string `json:"verdict"`
Commands []Result `json:"commands"`
EvidenceDigest string `json:"evidence_digest"`
TotalDurationMs int64 `json:"total_duration_ms"`
Task *TaskInfo `json:"task,omitempty"`
}
Data is the stable result contract that phases 07 and 09 consume.
type Entry ¶
type Entry struct {
Program string `json:"program"`
RequiredArgPrefix []string `json:"required_arg_prefix,omitempty"`
}
Entry authorizes a program and, optionally, a required prefix of arguments. The prefix authorizes a prefix, not the whole line: {go, [test]} allows `go test ./... -race` and does not allow `go build`.
type Envelope ¶
type Envelope struct {
Status string `json:"status"`
Summary string `json:"summary"`
Data Data `json:"data"`
Warnings []string `json:"warnings"`
NextActions []string `json:"next_actions"`
}
Envelope mirrors the runtime result the capability layer wraps.
func RunCommand ¶
func RunCommand(ctx context.Context, root string, in RunCommandInput) Envelope
RunCommand executes a single diagnostic command inside a run worktree.
type Execution ¶
Execution is the verify-owned batch seam shared by jacu_verify and jacu_apply. Refusal is non-empty only when policy or executor setup blocks the batch before ordinary command-result aggregation.
func ExecuteCommands ¶
func ExecuteCommands(ctx context.Context, root string, run runstate.Run, commands [][]string) Execution
ExecuteCommands applies the complete verify policy and bounded executor to an authoritative command batch. The whole batch is checked before the first spawn, so a refused later argv cannot leave effects from an earlier one.
type Input ¶
type Input struct {
RunID string `json:"run_id,omitempty"`
ArgV []string `json:"argv,omitempty"`
Async bool `json:"async,omitempty"`
TaskID string `json:"task_id,omitempty"`
Cancel bool `json:"cancel,omitempty"`
}
Input is the whole surface: no command, no timeout, no allowlist. The argv comes from the compiled mission, and limits are runtime policy, never a parameter of the object being governed.
type RawTaskExecutor ¶
type RawTaskExecutor func(context.Context, json.RawMessage) (json.RawMessage, error)
RawTaskExecutor is used by a registered capability that has its own stable JSON result. Registration is explicit; this is not a generic dispatch or shell execution hook.
type Result ¶
type Result struct {
ArgV []string `json:"argv"`
Status string `json:"status"`
ExitCode *int `json:"exit_code,omitempty"`
DurationMs int64 `json:"duration_ms"`
StdoutTail string `json:"stdout_tail"`
StderrTail string `json:"stderr_tail"`
Truncated bool `json:"truncated"`
BytesOut int64 `json:"bytes_out"`
Digest string `json:"digest"`
Reason string `json:"reason,omitempty"`
}
Result is one command's outcome. not_run is a first-class state: a cancelled run that reports N failures produces N phantom remediations downstream.
type RunCommandInput ¶
type RunCommandInput = Input
RunCommandInput is the one place a command may be named by the caller. It is still not a shell: argv is an array, it faces the same allowlist and the same limits as verification, and there is no timeout or policy parameter. RunCommandInput is retained as an internal source-compatibility alias while callers migrate to Input and the single jacu_verify MCP door.
type Runner ¶
type Runner struct {
// Worktree is the working directory and the boundary: a program resolved
// inside it is refused, because a verifier supplied by the thing being
// verified is not verification.
Worktree string
// PathDirs are the project-declared directories, highest precedence in the
// reconstructed PATH.
PathDirs []string
// ToolchainHome is the synthetic HOME. Dropping HOME entirely breaks every
// toolchain that needs a cache; passing the real one hands the command
// ~/.aws and ~/.config/gh.
ToolchainHome string
// ScratchDir becomes TMPDIR, outside the worktree.
ScratchDir string
Timeout time.Duration
TailBytes int
}
Runner executes one allowlisted command under the phase limits.
type Task ¶
type Task struct {
SchemaVersion string `json:"schema_version"`
TaskID string `json:"task_id"`
Capability string `json:"capability"`
RunID string `json:"run_id"`
Input json.RawMessage `json:"input,omitempty"`
Status TaskStatus `json:"status"`
CreatedAt time.Time `json:"created_at"`
StartedAt time.Time `json:"started_at,omitempty"`
FinishedAt time.Time `json:"finished_at,omitempty"`
Reason string `json:"reason,omitempty"`
Result *Envelope `json:"result,omitempty"`
ResultRaw json.RawMessage `json:"result_raw,omitempty"`
ResultDigest string `json:"result_digest,omitempty"`
ExpiresAt time.Time `json:"expires_at,omitempty"`
PayloadPrunedAt time.Time `json:"payload_pruned_at,omitempty"`
}
Task is the durable record. Input is normalized before persistence: the worker must never re-enter the async/cancel dispatch path when it resumes.
func (*Task) Transition ¶
func (task *Task) Transition(next TaskStatus) error
type TaskConfig ¶
type TaskInfo ¶
type TaskInfo struct {
TaskID string `json:"task_id"`
RunID string `json:"run_id"`
Status TaskStatus `json:"status"`
Reason string `json:"reason,omitempty"`
ResultDigest string `json:"result_digest,omitempty"`
}
TaskInfo is the bounded metadata returned by async start and cancellation. The result is intentionally separate so callers can distinguish task state from the verdict produced by verify.
type TaskManager ¶
type TaskManager struct {
// contains filtered or unexported fields
}
func NewTaskManager ¶
func NewTaskManager(root string) (*TaskManager, error)
func NewTaskManagerWithConfig ¶
func NewTaskManagerWithConfig(root string, config TaskConfig) (*TaskManager, error)
func (*TaskManager) Get ¶
func (manager *TaskManager) Get(taskID string, includeResult bool) (TaskSnapshot, error)
func (*TaskManager) List ¶
func (manager *TaskManager) List(includeResult bool) ([]TaskSnapshot, error)
func (*TaskManager) RegisterRawExecutor ¶
func (manager *TaskManager) RegisterRawExecutor(capability string, executor RawTaskExecutor) error
RegisterRawExecutor installs one named internal capability executor. The name is still persisted in the task record and is never supplied as an MCP command by the caller.
func (*TaskManager) RetainTasks ¶
func (manager *TaskManager) RetainTasks() error
RetainTasks compacts expired payloads and bounds terminal metadata. It is explicitly invoked at startup/list time; no background collector is used.
func (*TaskManager) StartRaw ¶
func (manager *TaskManager) StartRaw(ctx context.Context, capability, runID string, input json.RawMessage) (TaskInfo, error)
type TaskSnapshot ¶
type TaskStatus ¶
type TaskStatus string
const ( TaskQueued TaskStatus = "queued" TaskRunning TaskStatus = "running" TaskDone TaskStatus = "done" TaskFailed TaskStatus = "failed" TaskCancelled TaskStatus = "cancelled" TaskTimeout TaskStatus = "timeout" )