Set up local infrastructure
Use SHAFT's setup surface to inspect external prerequisites or install supported
tools into SHAFT-owned user directories. The safe default is EXTERNAL: SHAFT
diagnoses the host without downloading, installing, or starting anything.
The setup catalog includes web, mobile, Grid, reporting, OCR, agent-tool, and
local-AI profiles. Managed installation is currently available for
REPORTING and OCR. Reporting installs SHA-256-verified portable Node and Allure 3 artifacts. OCR installs a reviewed set of pinned tessdata models; its default bundle is eng and ara.
The other profiles are cataloged for the shared contract but currently return
unsupported from provider-backed diagnosis and lifecycle commands.
Inspect the catalog and host
Install shaft-cli through the
shaft-cli installation flow, then list the setup
profiles:
shaft-cli setup catalog
shaft-cli setup doctor --profile REPORTING
shaft-cli setup status --profile REPORTING
shaft-cli setup status --profile OCR
Add --json to catalog, doctor, status, or verify when a script needs a
versioned machine-readable result. Readiness commands exit with 0 when ready
and 3 when the profile is missing or degraded.
Review and approve an installation
Create an exact plan before allowing any mutation. Use an absolute path for the plan file:
shaft-cli setup plan \
--profile REPORTING \
--mode MANAGED \
--output /absolute/path/reporting-plan.json
Review the JSON plan and copy the printed sha256: digest. Apply that exact
plan with the same policy options used to create it:
shaft-cli setup install \
--plan /absolute/path/reporting-plan.json \
--approve sha256:<digest>
shaft-cli setup verify --profile REPORTING
apply and update are aliases for install. SHAFT rejects a changed or stale
plan, a mismatched policy, a missing license acceptance, or an artifact whose
checksum does not match before publishing it as installed.
Treat the plan digest as a one-plan approval, not a general consent switch. Changing a version, source, checksum, destination, timeout, or policy option changes the digest and requires a new review.
For OCR, omit --language to use the baseline bundle, or repeat exact Tesseract codes on plan and selected status/verify commands. Install recovers them from the reviewed plan:
shaft-cli setup plan --profile OCR --mode MANAGED \
--language fra --language deu \
--output /absolute/path/ocr-plan.json
shaft-cli setup install --plan /absolute/path/ocr-plan.json \
--approve sha256:<reviewed-digest>
shaft-cli setup verify --profile OCR --language fra --language deu
The reviewed actions bind the normalized component set. Repeating --language during install is optional and must match when supplied. OCR has no start, stop, or logs lifecycle.
Keep policy options identical
Plan and install accept the same execution policy:
| Option | Default | Effect |
|---|---|---|
--offline | false | Require verified cached artifacts and disable network access. |
--auto-start | false | Bind a startup request for providers that own a service. |
--prefer-system-tools=true|false | true | Bind whether a provider may prefer a compatible host tool. |
--reuse-owned-processes=true|false | true | Bind whether a provider may reuse compatible SHAFT-owned processes. |
--startup-timeout <duration> | PT2M | Bind a positive ISO-8601 startup timeout for providers with lifecycle support. |
--shutdown-timeout <duration> | PT30S | Bind a positive ISO-8601 shutdown timeout for providers with lifecycle support. |
Pass any non-default option to both commands. You may also pass an absolute
--cache-root and --data-root pair to both commands; SHAFT rejects a single
root or a relative path.
The REPORTING and OCR providers enforce --offline. OCR accepts an already verified installed model, a verified legacy model, or a verified artifact-cache entry without network access. Reporting has no owned service,
so auto-start, process reuse, and lifecycle timeouts are policy-bound for
provider parity but do not change a reporting install. Reporting installs
SHAFT-owned portable tools rather than adopting system Node or Allure.
Custom roots become mutable SHAFT-owned storage. Use dedicated, user-scoped directories. Do not point them at a repository, shared or system directory, or a path reached through a symlink alias.
Use the Java API
Configure the same policy through SHAFT.Properties.infrastructure, then plan
and explicitly approve the immutable result:
import com.shaft.driver.SHAFT;
import com.shaft.infrastructure.SetupMode;
import com.shaft.infrastructure.SetupPlan;
import com.shaft.infrastructure.SetupPlanStore;
import com.shaft.infrastructure.SetupProfile;
import java.nio.file.Path;
public final class ReportingInfrastructure {
public static void main(String[] args) throws Exception {
SHAFT.Properties.infrastructure.set()
.profile(SetupProfile.REPORTING)
.mode(SetupMode.MANAGED)
.offline(false)
.autoStart(false);
SetupPlan plan = SHAFT.Infrastructure.plan();
SetupPlanStore.write(Path.of(args[0]).toAbsolutePath(), plan);
// Stop this phase and review the written JSON plus this digest.
System.out.println(plan.digest());
}
}
Run the mutation in a separate phase. Supply the digest you reviewed instead of deriving it from a newly generated plan:
import com.shaft.driver.SHAFT;
import com.shaft.infrastructure.SetupApproval;
import com.shaft.infrastructure.SetupMode;
import com.shaft.infrastructure.SetupPlan;
import com.shaft.infrastructure.SetupPlanStore;
import com.shaft.infrastructure.SetupProfile;
import com.shaft.infrastructure.SetupReceipt;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Set;
public final class InstallReviewedReportingPlan {
public static void main(String[] args) throws Exception {
SetupPlan plan = SetupPlanStore.read(Path.of(args[0]).toAbsolutePath());
String reviewedDigest = System.getenv("SHAFT_APPROVED_SETUP_DIGEST");
// Recreate every policy value used by the planning phase.
SHAFT.Properties.infrastructure.set()
.profile(SetupProfile.REPORTING)
.mode(SetupMode.MANAGED)
.offline(false)
.autoStart(false);
if (!plan.executionPolicyDigest().equals(
SHAFT.Infrastructure.options().policyDigest())) {
throw new IllegalStateException(
"Current setup policy differs from the reviewed plan");
}
SetupApproval approval = new SetupApproval(
reviewedDigest, Instant.now(), Set.of());
SetupReceipt receipt = SHAFT.Infrastructure.install(plan, approval);
System.out.println(receipt.planDigest());
}
}
Use SHAFT.Infrastructure.catalog(), doctor(), status(), and verify() for
read-only inspection. install(...) and start(...) require both the exact
plan and its approval; there is no unapproved mutation overload.
Use an absolute plan path in both Java phases. Reproduce every property and path from the planning phase before installation; schema 3 rejects even a single policy or destination difference.
The configuration defaults are:
infrastructure.mode=EXTERNAL
infrastructure.profile=REPORTING
infrastructure.cacheDirectory=
infrastructure.offline=false
infrastructure.autoStart=false
infrastructure.preferSystemTools=true
infrastructure.reuseOwnedProcesses=true
infrastructure.startupTimeout=PT2M
infrastructure.shutdownTimeout=PT30S
Set infrastructure.cacheDirectory only to an absolute path. An empty value
uses the platform-specific SHAFT cache and application-data locations.
Understand remote precedence
An explicit remote execution address keeps endpoint-backed profiles external,
even when infrastructure.mode=MANAGED. This applies to web, Selenium Grid,
mobile, and Healenium profiles, so a remote test configuration cannot
unexpectedly provision local infrastructure. It does not change unrelated
profiles such as REPORTING.
Interpret CLI failures
| Exit code | Meaning |
|---|---|
0 | Ready or successful. |
2 | Invalid input, policy, or approval. |
3 | Missing or degraded readiness. |
4 | No provider supports the requested operation. |
5 | Execution or integrity failure. |
An install is atomic per action, not across the entire plan. If a later action fails, an earlier verified action can remain installed while the final profile receipt is absent. Fix the failure and retry the same approved plan; SHAFT re-verifies compatible completed state before continuing.
If setup reports that both an artifact destination and its .quarantine recovery file exist, preserve both files and stop. Verify each against the reviewed action checksum, then deliberately retain the valid copy before retrying. Never blindly delete the quarantine: it may be the only known-good pre-replacement artifact.
start and stop return unsupported for profiles without an owned service.
SHAFT does not adopt or stop an unknown process. Use
shaft-cli setup logs --profile REPORTING to read an existing provider log;
it returns 3 when no owned log exists.