Optional AI providers
SHAFT Pilot separates provider-neutral contracts from optional direct model access:
shaft-pilot-corecontains immutable request/response records, approval and redaction policies, budgets, safe audit metadata, provider capabilities,ServiceLoaderdiscovery, and deterministic fallback.shaft-aicontains direct HTTP adapters for OpenAI, Anthropic, Google Gemini, and local Ollama. It uses JDKHttpClient; no provider SDK type is exposed.shaft-engineexposes only thread-localSHAFT.Properties.pilotconfiguration. It has no dependency on either Pilot module.
shaft-capture and shaft-doctor depend on shaft-pilot-core. Add
shaft-ai only when direct provider calls are required. Capture creation,
validation, migration, and redaction remain deterministic with
pilot.ai.enabled=false.
SHAFT Doctor uses these contracts for an optional separately rendered advisory.
It submits only minimized evidence from an already-redacted EvidenceBundle
plus the deterministic diagnosis. Provider output cannot replace the baseline,
must cite only submitted evidence IDs, and falls back safely for provider,
budget, timeout, or validation failures. See SHAFT Doctor.
Safe defaults
AI is off unless both settings are changed:
pilot.ai.enabled=false
pilot.ai.provider=none
Provider models default to blank, remote and local consent default to false,
and no evidence category is approved by default. Disabled or unavailable AI
returns the request's deterministicFallback and makes no network call.
Credentials are read only from environment variables:
| Provider | Default variable |
|---|---|
| OpenAI | OPENAI_API_KEY |
| Anthropic | ANTHROPIC_API_KEY |
| Gemini | GEMINI_API_KEY |
| Ollama | none |
The environment variable names are configurable, but credential values are
never SHAFT properties. Provider endpoints and models are configured through
SHAFT.Properties.pilot; no model is selected implicitly.
Approval and evidence
Every request carries an ApprovalPolicy, and the effective SHAFT properties
must independently approve the same processing location and all submitted
EvidenceCategory values. Remote calls require
pilot.ai.consent.remote=true. Ollama requires
pilot.ai.consent.local=true; a loopback endpoint is not trusted
automatically.
Before provider execution, AiExecutionService:
- checks provider capabilities and availability;
- enforces request size, token, cost, timeout, concurrency, and circuit-breaker limits;
- rejects unapproved evidence categories;
- redacts authorization and cookie headers, password/secret assignments, common tokens, configured DOM selectors, attributes, and patterns;
- validates provider JSON against the requested schema;
- returns deterministic fallback for every failure.
Audit events contain only request ID, purpose, provider/model identifiers, redaction counts, duration, and status. Prompts, evidence, credentials, raw responses, and original secret values are excluded.
Example
SHAFT.Properties.pilot.set()
.enabled(true)
.provider("ollama")
.localConsent(true)
.allowedEvidenceCategories("TEXT")
.ollamaModel("your-local-model");
var schema = JsonNodeFactory.instance.objectNode()
.put("type", "object");
schema.putObject("properties")
.putObject("summary")
.put("type", "string");
schema.putArray("required").add("summary");
var approval = new ApprovalPolicy(
true,
false,
Set.of(EvidenceCategory.TEXT));
var request = AiRequest.builder("doctor-summary", schema)
.text(redactedDiagnosticText)
.approvalPolicy(approval)
.deterministicFallback(deterministicDiagnosis)
.build();
AiResponse response = new AiExecutionService().execute(request);
Call SHAFT.Properties.clearForCurrentThread() at lifecycle boundaries after
setting per-thread Pilot properties.
Direct providers and external agents
Direct provider adapters are separate from MCP clients. OpenAI, Anthropic, and
Gemini API credentials apply only to shaft-ai direct calls. GitHub/Microsoft
Copilot is supported through SHAFT MCP and retains its own client
authentication; SHAFT does not request or define a generic Copilot model API
key.
Credential-free MCP configuration fixtures are under
the downloadable Pilot examples. See
SHAFT MCP for transport
and deployment details. The representative doctor_analyze fixture covers
ChatGPT, Codex, Claude, Gemini, and GitHub Copilot without embedding any client
or provider credential.
Provider request mappings follow the official OpenAI structured output, Anthropic structured output, Gemini structured output, and Ollama chat contracts.