# internal/adapters/providers

Package providers adapts external model providers to scafld review dossiers.

## HostAgentCodex

```go
const (
	// HostAgentCodex identifies Codex as the agent currently driving scafld.
	HostAgentCodex = "codex"
	// HostAgentClaude identifies Claude as the agent currently driving scafld.
	HostAgentClaude = "claude"
	// HostAgentGemini identifies Gemini as the agent currently driving scafld.
	HostAgentGemini = "gemini"
	// IndependenceIsolationOnly is the always-available same-context-isolated floor.
	IndependenceIsolationOnly = "isolation_only"
	// IndependenceCrossVendor is the stronger known-different-vendor classification.
	IndependenceCrossVendor = "cross_vendor"
)
```

## HostAgentClaude

```go
const (
	// HostAgentCodex identifies Codex as the agent currently driving scafld.
	HostAgentCodex = "codex"
	// HostAgentClaude identifies Claude as the agent currently driving scafld.
	HostAgentClaude = "claude"
	// HostAgentGemini identifies Gemini as the agent currently driving scafld.
	HostAgentGemini = "gemini"
	// IndependenceIsolationOnly is the always-available same-context-isolated floor.
	IndependenceIsolationOnly = "isolation_only"
	// IndependenceCrossVendor is the stronger known-different-vendor classification.
	IndependenceCrossVendor = "cross_vendor"
)
```

## HostAgentGemini

```go
const (
	// HostAgentCodex identifies Codex as the agent currently driving scafld.
	HostAgentCodex = "codex"
	// HostAgentClaude identifies Claude as the agent currently driving scafld.
	HostAgentClaude = "claude"
	// HostAgentGemini identifies Gemini as the agent currently driving scafld.
	HostAgentGemini = "gemini"
	// IndependenceIsolationOnly is the always-available same-context-isolated floor.
	IndependenceIsolationOnly = "isolation_only"
	// IndependenceCrossVendor is the stronger known-different-vendor classification.
	IndependenceCrossVendor = "cross_vendor"
)
```

## IndependenceIsolationOnly

```go
const (
	// HostAgentCodex identifies Codex as the agent currently driving scafld.
	HostAgentCodex = "codex"
	// HostAgentClaude identifies Claude as the agent currently driving scafld.
	HostAgentClaude = "claude"
	// HostAgentGemini identifies Gemini as the agent currently driving scafld.
	HostAgentGemini = "gemini"
	// IndependenceIsolationOnly is the always-available same-context-isolated floor.
	IndependenceIsolationOnly = "isolation_only"
	// IndependenceCrossVendor is the stronger known-different-vendor classification.
	IndependenceCrossVendor = "cross_vendor"
)
```

## IndependenceCrossVendor

```go
const (
	// HostAgentCodex identifies Codex as the agent currently driving scafld.
	HostAgentCodex = "codex"
	// HostAgentClaude identifies Claude as the agent currently driving scafld.
	HostAgentClaude = "claude"
	// HostAgentGemini identifies Gemini as the agent currently driving scafld.
	HostAgentGemini = "gemini"
	// IndependenceIsolationOnly is the always-available same-context-isolated floor.
	IndependenceIsolationOnly = "isolation_only"
	// IndependenceCrossVendor is the stronger known-different-vendor classification.
	IndependenceCrossVendor = "cross_vendor"
)
```

## ErrProviderFailed

```go
var ErrProviderFailed = errors.New("provider failed")
```

ErrProviderFailed wraps provider transport and execution failures.

## AutoProviderInfo

```go
func AutoProviderInfo(opts Selection) (AutoProvider, error)
```

AutoProviderInfo returns the concrete external provider selected by auto.

When scafld can tell which agent is currently driving the task, auto prefers the other installed provider for independent review/hardening. With the default disabled fallback policy, auto refuses to use the host provider as its own challenger.

## BuildEvidenceSandbox

```go
func BuildEvidenceSandbox(files []reviewevidence.EvidenceFile) (EvidenceSandbox, error)
```

BuildEvidenceSandbox verifies and materializes canonical file evidence into a scratch directory that is safe to expose to a reviewer subprocess.

## ClaudeArgs

```go
func ClaudeArgs(binary string, model string, effort string, sessionID string, mcpConfig string, tool SubmitTool, readRoots []string) []string
```

ClaudeArgs builds the argv for restricted Claude execution. readRoots scopes file access to the evidence sandbox via --add-dir; the reviewer also runs with CWD set to that root and a sandbox HOME so no other directory or user-global memory is reachable.

## ClaudeEventName

```go
func ClaudeEventName(line string) string
```

ClaudeEventName extracts a liveness event name from one Claude stream frame.

## ClaudeMCPConfig

```go
func ClaudeMCPConfig(scafldBinary string, submissionPath string, tool SubmitTool) string
```

ClaudeMCPConfig returns the single-tool MCP config used by the Claude provider.

## CodexArgs

```go
func CodexArgs(binary string, root string, outputPath string, model string, modelReasoningEffort string, schemaPath string) []string
```

CodexArgs builds the argv for read-only Codex review execution.

## DetectHostAgent

```go
func DetectHostAgent(environ []string) string
```

DetectHostAgent infers whether scafld is being driven by Codex or Claude. SCAFLD\_HOST\_AGENT can be set to codex or claude when the host does not expose a recognizable environment marker.

## DetectHostAgentMarker

```go
func DetectHostAgentMarker(environ []string) string
```

DetectHostAgentMarker infers the host vendor from genuine environment markers only, ignoring the self-declared SCAFLD\_HOST\_AGENT. The gate uses this for the independence stamp and recorded host vendor so a host cannot manufacture a cross\_vendor classification by lying about which agent is driving it. It returns "" when no marker is present, which classifies as isolation\_only.

## GeminiArgs

```go
func GeminiArgs(binary string, model string, tool SubmitTool, policyPath string) []string
```

GeminiArgs builds the argv for restricted Gemini execution.

## GeminiEventName

```go
func GeminiEventName(line string) string
```

GeminiEventName extracts a liveness event name from one Gemini stream frame.

## GeminiPolicyTOML

```go
func GeminiPolicyTOML(tool SubmitTool) string
```

GeminiPolicyTOML allows exactly the scafld submit tool in Gemini plan mode.

## GeminiPrompt

```go
func GeminiPrompt(prompt string, tool SubmitTool) string
```

GeminiPrompt adds the provider-specific MCP tool name Gemini exposes for the scafld submit channel.

## GeminiSettingsJSON

```go
func GeminiSettingsJSON(scafldBinary string, submissionPath string, tool SubmitTool, policyOpt ...SandboxPolicy) string
```

GeminiSettingsJSON returns an isolated single-server MCP configuration for Gemini CLI. It is passed through GEMINI\_CLI\_SYSTEM\_SETTINGS\_PATH so scafld does not mutate project or user Gemini settings during review.

## HardenDossierSchemaJSON

```go
func HardenDossierSchemaJSON() string
```

HardenDossierSchemaJSON returns the strict structured-output schema used by providers that require every property to be listed in required.

## InvokeReceiptGradeDossier

```go
func InvokeReceiptGradeDossier(ctx context.Context, input ReceiptGradeReviewInput, req review.Request) (review.Dossier, RuntimeFacts, error)
```

InvokeReceiptGradeDossier runs the gate-only sandboxed reviewer and returns a parsed dossier plus the runtime facts stamped into the receipt. The reviewer reads only the evidence sandbox; env, binary, memory home, and read roots are pinned by SelectReceiptGradeAgentWithEvidence, and the sandbox is cleaned up by the wrapped agent.

## InvokeReceiptGradeReview

```go
func InvokeReceiptGradeReview(ctx context.Context, input ReceiptGradeReviewInput) (ReceiptGradeReviewResult, error)
```

InvokeReceiptGradeReview runs the gate-only provider path and returns stamped runtime facts alongside the raw response.

## ReceiptGradeAuthAvailable

```go
func ReceiptGradeAuthAvailable(provider string, hostEnviron []string) bool
```

ReceiptGradeAuthAvailable reports whether the host exposes credentials that can survive the receipt-grade environment scrub. It checks presence only; provider invocation remains the authority on whether credentials are valid.

## ResolveReceiptGradeBinary

```go
func ResolveReceiptGradeBinary(path string) (ReceiptGradeBinary, error)
```

ResolveReceiptGradeBinary fails closed unless path is absolute, executable, and hashable without PATH lookup.

## ReviewDossierSchemaJSON

```go
func ReviewDossierSchemaJSON() string
```

ReviewDossierSchemaJSON returns the strict structured-output schema used by providers that require every property to be listed in required.

## ScrubProviderEnv

```go
func ScrubProviderEnv(input ProviderEnvInput) (ProviderEnvResult, error)
```

ScrubProviderEnv returns the exact env for a receipt-grade reviewer process.

## Select

```go
func Select(opts Selection) (interface {
	Invoke(context.Context, review.Request) (review.Dossier, error)
}, error)
```

Select returns the configured review provider implementation.

## SelectAgent

```go
func SelectAgent(opts Selection) (Agent, error)
```

SelectAgent returns the configured protocol-neutral provider implementation.

## SelectGateReviewer

```go
func SelectGateReviewer(opts Selection) (GateReviewerSelection, error)
```

SelectGateReviewer chooses a runnable reviewer for the receipt gate. Unlike AutoProviderInfo, it does not stall when only the host vendor is available: isolation\_only still catches context contamination, self-congratulation, drift, forgotten acceptance criteria, and claimed-but-not-done work, while it forfeits protection against correlated blind spots and same-model-wrong-twice.

## SelectHarden

```go
func SelectHarden(opts Selection) (interface {
	Invoke(context.Context, coreharden.Request) (coreharden.Dossier, error)
}, error)
```

SelectHarden returns the configured harden provider implementation.

## SelectReceiptGradeAgent

```go
func SelectReceiptGradeAgent(opts Selection, hostEnviron []string) (Agent, RuntimeFacts, error)
```

SelectReceiptGradeAgent returns a provider configured for exact-env, content-hash-pinned gate review. Ordinary review/harden paths do not call it.

## SelectReceiptGradeAgentWithEvidence

```go
func SelectReceiptGradeAgentWithEvidence(opts Selection, hostEnviron []string, evidence []reviewevidence.EvidenceFile) (Agent, RuntimeFacts, error)
```

SelectReceiptGradeAgentWithEvidence additionally materializes the evidence sandbox and points the reviewer at that scratch root.

## Agent

```go
type Agent interface {
	InvokeAgent(context.Context, AgentRequest) (AgentResponse, error)
}
```

Agent is the shared provider transport used by protocol-specific adapters.

- `InvokeAgent: func(context.Context, AgentRequest) (AgentResponse, error)`: 

## AgentRequest

```go
type AgentRequest struct {
	TaskID     string
	Prompt     string
	SchemaName string
	// SchemaJSON is the one provider-facing wire schema. It is strict because
	// MCP and Codex must advertise the same packet contract; semantically
	// optional values are represented as null on the wire.
	SchemaJSON string
	SubmitTool SubmitTool
}
```

AgentRequest is the protocol-neutral prompt request used by review and harden.

- `TaskID: string`: 
- `Prompt: string`: 
- `SchemaName: string`: 
- `SchemaJSON: string`: SchemaJSON is the one provider-facing wire schema. It is strict because MCP and Codex must advertise the same packet contract; semantically optional values are represented as null on the wire.
- `SubmitTool: SubmitTool`: 

## AgentResponse

```go
type AgentResponse struct {
	Text               string
	Provider           string
	Model              string
	SessionID          string
	OutputFormat       string
	BinarySHA256       string
	EndpointHost       string
	EvidenceProvenance []reviewevidence.Provenance
	SandboxPolicy      SandboxPolicy
	EventSummary       map[string]int
	Result             execution.Result
	RunErr             error
}
```

AgentResponse is the raw structured payload produced by an agent provider.

- `Text: string`: 
- `Provider: string`: 
- `Model: string`: 
- `SessionID: string`: 
- `OutputFormat: string`: 
- `BinarySHA256: string`: 
- `EndpointHost: string`: 
- `EvidenceProvenance: []reviewevidence.Provenance`: 
- `SandboxPolicy: SandboxPolicy`: 
- `EventSummary: map[string]int`: 
- `Result: execution.Result`: 
- `RunErr: error`: 

## AutoProvider

```go
type AutoProvider struct {
	Provider string
	Model    string
}
```

AutoProvider describes the concrete provider selected for provider:auto.

- `Provider: string`: 
- `Model: string`: 

## ClaudeProvider

```go
type ClaudeProvider struct {
	Binary                 string
	Model                  string
	Effort                 string
	SessionID              string
	ScafldBinary           string
	SubmissionPath         string
	CWD                    string
	Env                    []string
	EnvMode                execution.EnvMode
	BinarySHA256           string
	EndpointHost           string
	ReadRoots              []string
	MemoryAutoloadDisabled bool
	SandboxPolicy          SandboxPolicy
	Runner                 Runner
	Timeout                time.Duration
	IdleTimeout            time.Duration
}
```

ClaudeProvider invokes Claude with a restricted read-only toolset and a scafld-owned MCP submit tool for the final dossier.

- `Binary: string`: 
- `Model: string`: 
- `Effort: string`: 
- `SessionID: string`: 
- `ScafldBinary: string`: 
- `SubmissionPath: string`: 
- `CWD: string`: 
- `Env: []string`: 
- `EnvMode: execution.EnvMode`: 
- `BinarySHA256: string`: 
- `EndpointHost: string`: 
- `ReadRoots: []string`: 
- `MemoryAutoloadDisabled: bool`: 
- `SandboxPolicy: SandboxPolicy`: 
- `Runner: Runner`: 
- `Timeout: time.Duration`: 
- `IdleTimeout: time.Duration`: 

## Invoke

```go
func (p ClaudeProvider) Invoke(ctx context.Context, req review.Request) (review.Dossier, error)
```

Invoke sends the review prompt to Claude and parses the resulting dossier.

## InvokeAgent

```go
func (p ClaudeProvider) InvokeAgent(ctx context.Context, req AgentRequest) (AgentResponse, error)
```

InvokeAgent sends the prompt to Claude and reads the scafld MCP submission.

## CodexProvider

```go
type CodexProvider struct {
	Binary                 string
	Model                  string
	ModelReasoningEffort   string
	SchemaPath             string
	OutputPath             string
	CWD                    string
	Env                    []string
	EnvMode                execution.EnvMode
	BinarySHA256           string
	EndpointHost           string
	ReadRoots              []string
	MemoryAutoloadDisabled bool
	SandboxPolicy          SandboxPolicy
	Runner                 Runner
	Timeout                time.Duration
	IdleTimeout            time.Duration
}
```

CodexProvider invokes Codex in read-only ephemeral review mode.

- `Binary: string`: 
- `Model: string`: 
- `ModelReasoningEffort: string`: 
- `SchemaPath: string`: 
- `OutputPath: string`: 
- `CWD: string`: 
- `Env: []string`: 
- `EnvMode: execution.EnvMode`: 
- `BinarySHA256: string`: 
- `EndpointHost: string`: 
- `ReadRoots: []string`: 
- `MemoryAutoloadDisabled: bool`: 
- `SandboxPolicy: SandboxPolicy`: 
- `Runner: Runner`: 
- `Timeout: time.Duration`: 
- `IdleTimeout: time.Duration`: 

## Invoke

```go
func (p CodexProvider) Invoke(ctx context.Context, req review.Request) (review.Dossier, error)
```

Invoke sends the review prompt to Codex and parses the resulting dossier.

## InvokeAgent

```go
func (p CodexProvider) InvokeAgent(ctx context.Context, req AgentRequest) (AgentResponse, error)
```

InvokeAgent sends the prompt to Codex and reads its structured output.

## CommandProvider

```go
type CommandProvider struct {
	Command     string
	CWD         string
	Env         []string
	Runner      Runner
	Timeout     time.Duration
	IdleTimeout time.Duration
}
```

CommandProvider invokes an operator-supplied review command.

- `Command: string`: 
- `CWD: string`: 
- `Env: []string`: 
- `Runner: Runner`: 
- `Timeout: time.Duration`: 
- `IdleTimeout: time.Duration`: 

## Invoke

```go
func (p CommandProvider) Invoke(ctx context.Context, req review.Request) (review.Dossier, error)
```

Invoke sends the review prompt to the command and parses stdout as a dossier.

## InvokeAgent

```go
func (p CommandProvider) InvokeAgent(ctx context.Context, req AgentRequest) (AgentResponse, error)
```

InvokeAgent sends the prompt to the command and returns stdout as the payload.

## EvidenceSandbox

```go
type EvidenceSandbox struct {
	CWD        string
	Home       string
	ReadRoots  []string
	Env        []string
	ArgsPolicy SandboxArgsPolicy
	Provenance []reviewevidence.Provenance
	Policy     SandboxPolicy
	Cleanup    func()
}
```

EvidenceSandbox is the materialized scratch directory and its cleanup owner.

- `CWD: string`: 
- `Home: string`: 
- `ReadRoots: []string`: 
- `Env: []string`: 
- `ArgsPolicy: SandboxArgsPolicy`: 
- `Provenance: []reviewevidence.Provenance`: 
- `Policy: SandboxPolicy`: 
- `Cleanup: func()`: 

## GateReviewerSelection

```go
type GateReviewerSelection struct {
	Provider     string
	Binary       string
	Model        string
	Independence Independence
}
```

GateReviewerSelection is the provider adapter contract consumed by the gate path before receipt-grade sandboxing and invocation.

- `Provider: string`: 
- `Binary: string`: 
- `Model: string`: 
- `Independence: Independence`: 

## GeminiProvider

```go
type GeminiProvider struct {
	Binary                 string
	Model                  string
	ScafldBinary           string
	SubmissionPath         string
	SettingsPath           string
	PolicyPath             string
	CWD                    string
	Env                    []string
	EnvMode                execution.EnvMode
	BinarySHA256           string
	EndpointHost           string
	ReadRoots              []string
	MemoryAutoloadDisabled bool
	SandboxPolicy          SandboxPolicy
	Runner                 Runner
	Timeout                time.Duration
	IdleTimeout            time.Duration
}
```

GeminiProvider invokes Gemini CLI in read-only plan mode with a scafld-owned MCP submit tool for the final dossier.

- `Binary: string`: 
- `Model: string`: 
- `ScafldBinary: string`: 
- `SubmissionPath: string`: 
- `SettingsPath: string`: 
- `PolicyPath: string`: 
- `CWD: string`: 
- `Env: []string`: 
- `EnvMode: execution.EnvMode`: 
- `BinarySHA256: string`: 
- `EndpointHost: string`: 
- `ReadRoots: []string`: 
- `MemoryAutoloadDisabled: bool`: 
- `SandboxPolicy: SandboxPolicy`: 
- `Runner: Runner`: 
- `Timeout: time.Duration`: 
- `IdleTimeout: time.Duration`: 

## Invoke

```go
func (p GeminiProvider) Invoke(ctx context.Context, req review.Request) (review.Dossier, error)
```

Invoke sends the review prompt to Gemini and parses the resulting dossier.

## InvokeAgent

```go
func (p GeminiProvider) InvokeAgent(ctx context.Context, req AgentRequest) (AgentResponse, error)
```

InvokeAgent sends the prompt to Gemini and reads the scafld MCP submission.

## HardenProvider

```go
type HardenProvider struct {
	Agent Agent
}
```

HardenProvider adapts shared agent transport to the harden dossier protocol.

- `Agent: Agent`: 

## Invoke

```go
func (p HardenProvider) Invoke(ctx context.Context, req coreharden.Request) (coreharden.Dossier, error)
```

Invoke returns a typed harden dossier from the shared provider transport.

## Independence

```go
type Independence struct {
	Level    string `json:"level"`
	Distinct bool   `json:"distinct"`
}
```

Independence stamps how separate the selected reviewer is from the host.

- `Level: string` (json:"level"): 
- `Distinct: bool` (json:"distinct"): 

## LocalProvider

```go
type LocalProvider struct {
	Messages []string
}
```

LocalProvider emits deterministic local review dossiers for development smoke tests.

- `Messages: []string`: 

## Invoke

```go
func (p LocalProvider) Invoke(ctx context.Context, req review.Request) (review.Dossier, error)
```

Invoke returns a dossier from configured local messages.

## InvokeAgent

```go
func (p LocalProvider) InvokeAgent(ctx context.Context, req AgentRequest) (AgentResponse, error)
```

InvokeAgent returns a deterministic local payload for development smoke tests.

## ProviderEnvInput

```go
type ProviderEnvInput struct {
	Provider     string
	HostEnviron  []string
	ExtraEnv     []string
	EndpointURL  string
	EndpointHost string
	RequireAuth  bool
	// MemoryHome, when set, overrides HOME and XDG_CONFIG_HOME with a clean
	// sandbox-owned directory so the reviewer cannot autoload host user-global
	// agent memory.
	MemoryHome string
}
```

ProviderEnvInput describes the host environment and committed endpoint pins allowed to reach a receipt-grade reviewer subprocess.

- `Provider: string`: 
- `HostEnviron: []string`: 
- `ExtraEnv: []string`: 
- `EndpointURL: string`: 
- `EndpointHost: string`: 
- `RequireAuth: bool`: 
- `MemoryHome: string`: MemoryHome, when set, overrides HOME and XDG\_CONFIG\_HOME with a clean sandbox-owned directory so the reviewer cannot autoload host user-global agent memory.

## ProviderEnvResult

```go
type ProviderEnvResult struct {
	Env          []string
	EndpointHost string
}
```

ProviderEnvResult is the exact process env plus the endpoint host stamped into receipt runtime facts.

- `Env: []string`: 
- `EndpointHost: string`: 

## ReceiptGradeBinary

```go
type ReceiptGradeBinary struct {
	Path   string
	SHA256 string
}
```

ReceiptGradeBinary is the absolute reviewer binary path and byte digest.

- `Path: string`: 
- `SHA256: string`: 

## ReceiptGradeReviewInput

```go
type ReceiptGradeReviewInput struct {
	Selection   Selection
	HostEnviron []string
	Evidence    []reviewevidence.EvidenceFile
	Request     AgentRequest
}
```

ReceiptGradeReviewInput is the gate-only request shape for an isolated, receipt-stamped provider run.

- `Selection: Selection`: 
- `HostEnviron: []string`: 
- `Evidence: []reviewevidence.EvidenceFile`: 
- `Request: AgentRequest`: 

## ReceiptGradeReviewResult

```go
type ReceiptGradeReviewResult struct {
	Response     AgentResponse
	RuntimeFacts RuntimeFacts
}
```

ReceiptGradeReviewResult returns provider output plus the facts later signed by host-gate.

- `Response: AgentResponse`: 
- `RuntimeFacts: RuntimeFacts`: 

## Runner

```go
type Runner interface {
	Run(context.Context, execution.Request) (execution.Result, error)
}
```

Runner is the process execution port required by external providers.

- `Run: func(context.Context, execution.Request) (execution.Result, error)`: 

## RuntimeFacts

```go
type RuntimeFacts struct {
	BinarySHA256       string
	EndpointHost       string
	EvidenceProvenance []reviewevidence.Provenance
	SandboxPolicy      SandboxPolicy
}
```

RuntimeFacts carries receipt-grade provider facts that are stamped into the later signed gate receipt.

- `BinarySHA256: string`: 
- `EndpointHost: string`: 
- `EvidenceProvenance: []reviewevidence.Provenance`: 
- `SandboxPolicy: SandboxPolicy`: 

## SandboxArgsPolicy

```go
type SandboxArgsPolicy struct {
	ReadRoots              []string `json:"read_roots"`
	MemoryAutoloadDisabled bool     `json:"memory_autoload_disabled"`
	Provider               string   `json:"provider,omitempty"`
}
```

SandboxArgsPolicy records provider-specific evidence sandbox controls.

- `ReadRoots: []string` (json:"read_roots"): 
- `MemoryAutoloadDisabled: bool` (json:"memory_autoload_disabled"): 
- `Provider: string` (json:"provider,omitempty"): 

## SandboxPolicy

```go
type SandboxPolicy struct {
	ReadRoots []string `json:"read_roots"`
	// ReadRootsEnforced is true only when the provider CLI hard-confines the
	// reviewer's reads to ReadRoots (Claude --add-dir, Gemini includeDirectories).
	// For Codex it is false: its read-only sandbox plus working directory prevent
	// writes and default reads outside ReadRoots, but do not jail them, so the
	// receipt records best-effort confinement honestly rather than claiming a jail.
	ReadRootsEnforced       bool     `json:"read_roots_enforced"`
	MemoryAutoloadDisabled  bool     `json:"memory_autoload_disabled"`
	AgentInstructionBlocked []string `json:"agent_instruction_blocked,omitempty"`
}
```

SandboxPolicy describes the provider-visible limits applied to a receipt-grade review run.

- `ReadRoots: []string` (json:"read_roots"): 
- `ReadRootsEnforced: bool` (json:"read_roots_enforced"): ReadRootsEnforced is true only when the provider CLI hard-confines the reviewer's reads to ReadRoots (Claude --add-dir, Gemini includeDirectories). For Codex it is false: its read-only sandbox plus working directory prevent writes and default reads outside ReadRoots, but do not jail them, so the receipt records best-effort confinement honestly rather than claiming a jail.
- `MemoryAutoloadDisabled: bool` (json:"memory_autoload_disabled"): 
- `AgentInstructionBlocked: []string` (json:"agent_instruction_blocked,omitempty"): 

## Selection

```go
type Selection struct {
	Provider                  string
	Command                   string
	Binary                    string
	Model                     string
	CodexModel                string
	CodexModelReasoningEffort string
	ClaudeModel               string
	ClaudeEffort              string
	GeminiModel               string
	CodexBinary               string
	ClaudeBinary              string
	GeminiBinary              string
	CodexEndpointURL          string
	ClaudeEndpointURL         string
	GeminiEndpointURL         string
	CodexEndpointHost         string
	ClaudeEndpointHost        string
	GeminiEndpointHost        string
	CWD                       string
	Runner                    Runner
	Timeout                   time.Duration
	Idle                      time.Duration
	FallbackPolicy            string
	HostAgent                 string
	ReadRoots                 []string
	CommandExists             func(string) bool
}
```

Selection contains provider choice, model, timeout, and runner configuration.

- `Provider: string`: 
- `Command: string`: 
- `Binary: string`: 
- `Model: string`: 
- `CodexModel: string`: 
- `CodexModelReasoningEffort: string`: 
- `ClaudeModel: string`: 
- `ClaudeEffort: string`: 
- `GeminiModel: string`: 
- `CodexBinary: string`: 
- `ClaudeBinary: string`: 
- `GeminiBinary: string`: 
- `CodexEndpointURL: string`: 
- `ClaudeEndpointURL: string`: 
- `GeminiEndpointURL: string`: 
- `CodexEndpointHost: string`: 
- `ClaudeEndpointHost: string`: 
- `GeminiEndpointHost: string`: 
- `CWD: string`: 
- `Runner: Runner`: 
- `Timeout: time.Duration`: 
- `Idle: time.Duration`: 
- `FallbackPolicy: string`: 
- `HostAgent: string`: 
- `ReadRoots: []string`: 
- `CommandExists: func(string) bool`: 

## SubmitTool

```go
type SubmitTool struct {
	Name        string
	Title       string
	Description string
	Command     string
}
```

SubmitTool describes the provider-side structured submission channel.

- `Name: string`: 
- `Title: string`: 
- `Description: string`: 
- `Command: string`:
