Internal

internal/adapters/providers

Package providers adapts external model providers to scafld review dossiers.

import "github.com/nilstate/scafld/v2/internal/adapters/providers"

Package providers adapts external model providers to scafld review dossiers.

Constants

Source: internal/adapters/providers/provider.go:126

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"
)

Variables

ErrProviderFailed wraps provider transport and execution failures.

Source: internal/adapters/providers/provider.go:19

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

Functions

func AutoProviderInfo(opts Selection) (AutoProvider, error)

Source: internal/adapters/providers/provider.go:502

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.

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

Source: internal/adapters/providers/evidence_sandbox.go:47

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

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

Source: internal/adapters/providers/clients.go:392

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.

func ClaudeEventName(line string) string

Source: internal/adapters/providers/invoke.go:210

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

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

Source: internal/adapters/providers/clients.go:438

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

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

Source: internal/adapters/providers/clients.go:555

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

func DetectHostAgent(environ []string) string

Source: internal/adapters/providers/provider.go:637

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.

func DetectHostAgentMarker(environ []string) string

Source: internal/adapters/providers/provider.go:652

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.

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

Source: internal/adapters/providers/clients.go:459

GeminiArgs builds the argv for restricted Gemini execution.

func GeminiEventName(line string) string

Source: internal/adapters/providers/invoke.go:227

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

func GeminiPolicyTOML(tool SubmitTool) string

Source: internal/adapters/providers/clients.go:485

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

func GeminiPrompt(prompt string, tool SubmitTool) string

Source: internal/adapters/providers/clients.go:546

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

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

Source: internal/adapters/providers/clients.go:503

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.

func HardenDossierSchemaJSON() string

Source: internal/adapters/providers/schema.go:16

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

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

Source: internal/adapters/providers/provider.go:484

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.

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

Source: internal/adapters/providers/provider.go:450

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

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

Source: internal/adapters/providers/provider.go:410

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.

func ResolveReceiptGradeBinary(path string) (ReceiptGradeBinary, error)

Source: internal/adapters/providers/env_scrub.go:102

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

func ReviewDossierSchemaJSON() string

Source: internal/adapters/providers/schema.go:10

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

func ScrubProviderEnv(input ProviderEnvInput) (ProviderEnvResult, error)

Source: internal/adapters/providers/env_scrub.go:44

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

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

Source: internal/adapters/providers/provider.go:138

Select returns the configured review provider implementation.

func SelectAgent(opts Selection) (Agent, error)

Source: internal/adapters/providers/provider.go:169

SelectAgent returns the configured protocol-neutral provider implementation.

func SelectGateReviewer(opts Selection) (GateReviewerSelection, error)

Source: internal/adapters/providers/provider.go:220

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.

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

Source: internal/adapters/providers/invoke.go:18

SelectHarden returns the configured harden provider implementation.

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

Source: internal/adapters/providers/provider.go:280

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

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

Source: internal/adapters/providers/provider.go:286

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

Types

type Agent

Source: internal/adapters/providers/provider.go:61

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

type Agent interface {
	InvokeAgent(context.Context, AgentRequest) (AgentResponse, error)
}
Methods
  • InvokeAgent func(context.Context, AgentRequest) (AgentResponse, error)

type AgentRequest

Source: internal/adapters/providers/provider.go:35

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

type AgentRequest struct {
	TaskID           string
	Prompt           string
	SchemaName       string
	SchemaJSON       string
	StrictSchemaJSON string
	SubmitTool       SubmitTool
}
Fields
  • TaskID string
  • Prompt string
  • SchemaName string
  • SchemaJSON string
  • StrictSchemaJSON string
  • SubmitTool SubmitTool

type AgentResponse

Source: internal/adapters/providers/provider.go:45

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

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
}
Fields
  • 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

type AutoProvider

Source: internal/adapters/providers/provider.go:95

AutoProvider describes the concrete provider selected for provider:auto.

type AutoProvider struct {
	Provider string
	Model    string
}
Fields
  • Provider string
  • Model string

type ClaudeProvider

Source: internal/adapters/providers/clients.go:109

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

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
}
Fields
  • 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

func Invoke(ctx context.Context, req review.Request) (review.Dossier, error)

Source: internal/adapters/providers/clients.go:190

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

func InvokeAgent(ctx context.Context, req AgentRequest) (AgentResponse, error)

Source: internal/adapters/providers/clients.go:130

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

type CodexProvider

Source: internal/adapters/providers/clients.go:195

CodexProvider invokes Codex in read-only ephemeral review mode.

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
}
Fields
  • 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

func Invoke(ctx context.Context, req review.Request) (review.Dossier, error)

Source: internal/adapters/providers/clients.go:271

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

func InvokeAgent(ctx context.Context, req AgentRequest) (AgentResponse, error)

Source: internal/adapters/providers/clients.go:215

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

type CommandProvider

Source: internal/adapters/providers/clients.go:52

CommandProvider invokes an operator-supplied review command.

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

func Invoke(ctx context.Context, req review.Request) (review.Dossier, error)

Source: internal/adapters/providers/clients.go:103

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

func InvokeAgent(ctx context.Context, req AgentRequest) (AgentResponse, error)

Source: internal/adapters/providers/clients.go:76

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

type EvidenceSandbox

Source: internal/adapters/providers/evidence_sandbox.go:34

EvidenceSandbox is the materialized scratch directory and its cleanup owner.

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

type GateReviewerSelection

Source: internal/adapters/providers/provider.go:108

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

type GateReviewerSelection struct {
	Provider     string
	Binary       string
	Model        string
	Independence Independence
}
Fields
  • Provider string
  • Binary string
  • Model string
  • Independence Independence

type GeminiProvider

Source: internal/adapters/providers/clients.go:277

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

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
}
Fields
  • 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

func Invoke(ctx context.Context, req review.Request) (review.Dossier, error)

Source: internal/adapters/providers/clients.go:384

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

func InvokeAgent(ctx context.Context, req AgentRequest) (AgentResponse, error)

Source: internal/adapters/providers/clients.go:298

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

type HardenProvider

Source: internal/adapters/providers/invoke.go:29

HardenProvider adapts shared agent transport to the harden dossier protocol.

type HardenProvider struct {
	Agent Agent
}
Fields
  • Agent Agent

func Invoke(ctx context.Context, req coreharden.Request) (coreharden.Dossier, error)

Source: internal/adapters/providers/invoke.go:34

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

type Independence

Source: internal/adapters/providers/provider.go:101

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

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

type LocalProvider

Source: internal/adapters/providers/clients.go:18

LocalProvider emits deterministic local review dossiers for development smoke tests.

type LocalProvider struct {
	Messages []string
}
Fields
  • Messages []string

func Invoke(ctx context.Context, req review.Request) (review.Dossier, error)

Source: internal/adapters/providers/clients.go:47

Invoke returns a dossier from configured local messages.

func InvokeAgent(ctx context.Context, req AgentRequest) (AgentResponse, error)

Source: internal/adapters/providers/clients.go:23

InvokeAgent returns a deterministic local payload for development smoke tests.

type ProviderEnvInput

Source: internal/adapters/providers/env_scrub.go:17

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

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
}
Fields
  • 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.

type ProviderEnvResult

Source: internal/adapters/providers/env_scrub.go:32

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

type ProviderEnvResult struct {
	Env          []string
	EndpointHost string
}
Fields
  • Env []string
  • EndpointHost string

type ReceiptGradeBinary

Source: internal/adapters/providers/env_scrub.go:38

ReceiptGradeBinary is the absolute reviewer binary path and byte digest.

type ReceiptGradeBinary struct {
	Path   string
	SHA256 string
}
Fields
  • Path string
  • SHA256 string

type ReceiptGradeReviewInput

Source: internal/adapters/providers/provider.go:264

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

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

type ReceiptGradeReviewResult

Source: internal/adapters/providers/provider.go:273

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

type ReceiptGradeReviewResult struct {
	Response     AgentResponse
	RuntimeFacts RuntimeFacts
}
Fields
  • Response AgentResponse
  • RuntimeFacts RuntimeFacts

type Runner

Source: internal/adapters/providers/provider.go:22

Runner is the process execution port required by external providers.

type Runner interface {
	Run(context.Context, execution.Request) (execution.Result, error)
}
Methods
  • Run func(context.Context, execution.Request) (execution.Result, error)

type RuntimeFacts

Source: internal/adapters/providers/provider.go:117

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

type RuntimeFacts struct {
	BinarySHA256       string
	EndpointHost       string
	EvidenceProvenance []reviewevidence.Provenance
	SandboxPolicy      SandboxPolicy
}
Fields
  • BinarySHA256 string
  • EndpointHost string
  • EvidenceProvenance []reviewevidence.Provenance
  • SandboxPolicy SandboxPolicy

type SandboxArgsPolicy

Source: internal/adapters/providers/evidence_sandbox.go:27

SandboxArgsPolicy records provider-specific evidence sandbox controls.

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

type SandboxPolicy

Source: internal/adapters/providers/evidence_sandbox.go:14

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

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"`
}
Fields
  • 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"`

type Selection

Source: internal/adapters/providers/provider.go:66

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

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
	CommandExists             func(string) bool
}
Fields
  • 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
  • CommandExists func(string) bool

type SubmitTool

Source: internal/adapters/providers/provider.go:27

SubmitTool describes the provider-side structured submission channel.

type SubmitTool struct {
	Name        string
	Title       string
	Description string
	Command     string
}
Fields
  • Name string
  • Title string
  • Description string
  • Command string