Documentation
¶
Overview ¶
Package review implements jcode's LLM approval reviewer: a background "guardian" that adjudicates tool calls which would otherwise interrupt the user with an approval prompt. It runs a small, dedicated model against a risk policy and returns allow / deny / escalate.
The reviewer is active in Auto session mode and built lazily by ApprovalState. Settings such as model, policy, timeout, investigate, reuse_session, and audit_path are tunable via the approval_review config block, but there is no on/off switch — Auto mode itself is the switch.
Design layers (see internal-doc/approval-review-design.md):
- V1: one non-streaming Generate call, strict-JSON verdict, fail-open to the user on any error/timeout, per-turn denial circuit breaker.
- V2: optional read-only investigation (the reviewer may run read/grep/glob to gather evidence before deciding).
- V3: a reused reviewer conversation so the large policy prefix is served from the provider's prompt cache, kept fully separate from the main conversation's cache.
Index ¶
Constants ¶
const DefaultTimeout = 60 * time.Second
DefaultTimeout is the per-review time budget used when TimeoutSeconds is unset. Exported so settings UIs can show the effective value rather than restating it.
Variables ¶
This section is empty.
Functions ¶
func DefaultAuditPath ¶
func DefaultAuditPath() string
DefaultAuditPath returns the verdict-log location used when AuditPath is unset. Exported for the same reason as DefaultTimeout — a settings UI should show the real resolved path, not a hardcoded guess at it.
Types ¶
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine is the concrete Reviewer.
func New ¶
New builds a reviewer Engine from Options. It never returns nil; a misconfigured model surfaces per-review as an Escalate (fall back to user).
type Msg ¶
Msg is one entry of conversation context handed to the reviewer as evidence.
func MsgsFromHistory ¶
MsgsFromHistory converts the tail of an agent conversation into reviewer evidence: the last maxHistoryMsgs non-empty messages, with the system prompt dropped (it is jcode's own instructions, not evidence of user intent).
All three frontends (ACP, TUI, web) feed the reviewer through this one function so their notion of "recent conversation" cannot drift. Callers are responsible for holding whatever lock guards their history slice.
type Options ¶
type Options struct {
Config *config.Config
ModelRef string // "provider/model" or "small"; "" resolves to small→main
Policy string // extra workspace policy text appended to the base policy
Timeout time.Duration
AuditPath string // JSONL verdict log; "" → <config dir>/approval-review.jsonl
Investigate bool // V2: allow read-only tool use during review
ReuseCache bool // V3: reuse a cached reviewer conversation
Platform string // V2: platform string for the read-only Env
}
Options configure a reviewer Engine.
type Outcome ¶
type Outcome int
Outcome is the reviewer's verdict for one tool call.
const ( // Escalate means the reviewer could not (or should not) decide — the caller // falls back to prompting the user. This is the safe default on any failure. Escalate Outcome = iota // Allow means the action may run without a user prompt. Allow // Deny means the action must not run; the rationale is surfaced to the agent. Deny )
type Request ¶
type Request struct {
ToolName string
ToolArgs string
Cwd string
IsExternal bool // touches a path outside the workspace
Transcript []Msg // recent conversation tail (untrusted evidence)
}
Request is a single tool call to adjudicate.
type Result ¶
type Result struct {
Outcome Outcome
RiskLevel string
Rationale string
// Failed is true when the review could not complete (model error, timeout,
// unparseable output). Outcome is then always Escalate. Callers use this to
// distinguish "reviewer chose to escalate" from "reviewer broke".
Failed bool
}
Result is the reviewer's decision.
type Reviewer ¶
Reviewer adjudicates tool calls. ApprovalState holds one (or nil).
func BuildFromConfig ¶
BuildFromConfig constructs a Reviewer from config. It never returns nil: when approval_review settings are absent it falls back to sensible defaults (small alias model, default timeout, no investigation, no session reuse). Callers install the returned Reviewer on ApprovalState whenever the session is in Auto mode.