This page is the authoritative inventory of Jaiph configuration keys: every key, its value type, default, environment-variable equivalent, and precedence. For environment-variable details (defaults, scopes, sandbox forwarding) see Environment variables. For the CLI flags that front-end the same knobs see CLI.
Configuration sources, in priority order:
config { … } — applies for the duration of that workflow.config { … } — applies to all workflows in that file unless overridden.Docker enablement uses a separate, env-only resolution; see Docker enablement.
| Aspect | Rule |
|---|---|
| Module-level | At most one config { … } block per .jh file. May appear anywhere among top-level constructs. |
| Workflow-level | At most one nested config { … } per workflow body. Must be the first non-comment construct in the body. |
| Allowed module keys | agent.*, run.*, runtime.*, module.*, and trusted_envs. |
| Allowed workflow keys | agent.*, run.*, and trusted_envs. runtime.* and module.* are E_PARSE. |
| Duplicate block | E_PARSE duplicate config block (only one allowed per file) / E_PARSE duplicate config block inside workflow (only one allowed per workflow). |
| Unknown key | E_PARSE unknown config key: <key>. Allowed: … (lists every allowed key). |
| Wrong value type | E_PARSE. |
Global rule: Every Jaiph string position accepts three equivalent forms:
| Form | Example | Stored as |
|---|---|---|
| Bare identifier | model |
${model} |
| Double-quoted string | "${model}" or "prefix-${model}" |
string content as-is |
| Bare interpolation ref | ${model} or ${model.field} |
${model} / ${model.field} |
All three resolve identically at runtime. The only interpolation Jaiph understands is ${name} / ${name.field} — shell expansion forms (${var:-default}, ${var//…}, ${#var}) are not. Written as a bare config value they fail with E_PARSE (config value must be a quoted string, bare identifier, or true/false); written inside a double-quoted config value they are stored as literal text and never expanded.
| Type | Format | Example |
|---|---|---|
| String | Double-quoted; supports \\, \n, \t, \", and ${name} interpolation |
"gpt-4", "${model}" |
| String (bare identifier sugar) | Bare identifier — stored as ${name} and resolved at runtime |
model |
| String (bare ref sugar) | Bare ${name} or ${name.field} — stored as-is and resolved at runtime |
${model}, ${model.field} |
| Boolean | Bare true / false |
true |
| Integer | Unsigned decimal digits | 300 |
String config values support the same ${identifier} interpolation as orchestration strings (log, prompt, return, etc.). A bare identifier or bare ${name} on the RHS is sugar for a single ${identifier} reference (for example agent.model = model, agent.model = ${model}, and agent.model = "${model}" are all equivalent).
Interpolation scope:
| Config level | Available identifiers |
|---|---|
| Module-level | Module const values and environment variables |
| Workflow-level | Module const values, environment variables, and that workflow’s parameters |
Interpolation runs when the config scope is applied (workflow entry for workflow-level keys; CLI startup for module-level keys). Environment variables still win over in-file config when locked.
| Key | Type | Default | Env equivalent | Notes |
|---|---|---|---|---|
agent.model |
string | — | JAIPH_AGENT_MODEL (env only) |
Model for prompt steps in this scope. Resolved at each prompt invocation and passed as a per-call --model flag — it does not set JAIPH_AGENT_MODEL in the workflow environment, so scripts and other steps do not see it. Set JAIPH_AGENT_MODEL in the shell to override all prompts in a run. |
agent.command |
string | cursor-agent |
JAIPH_AGENT_COMMAND |
Cursor backend command. Basename other than cursor-agent enables custom-command mode (stdin → command → stdout). Entry module only — imported modules cannot set this key by default (see Import trust boundary). |
agent.backend |
string (cursor | claude | codex) |
cursor |
JAIPH_AGENT_BACKEND |
Backend selector. Entry module only — imported modules cannot set this key by default (see Import trust boundary). |
agent.trusted_workspace |
string (path) | workspace root | JAIPH_AGENT_TRUSTED_WORKSPACE |
Directory passed to Cursor as --trust. When unset, defaults to JAIPH_WORKSPACE. A relative path in the entry module’s module-level config is resolved against the workspace root to an absolute path at CLI startup. Values applied at runtime — a workflow-level block or an imported module — are assigned to the env var exactly as authored (not normalized). |
agent.cursor_flags |
string | — | JAIPH_AGENT_CURSOR_FLAGS |
Extra flags appended to Cursor invocations (whitespace-split). |
agent.claude_flags |
string | — | JAIPH_AGENT_CLAUDE_FLAGS |
Extra flags appended to Claude invocations (whitespace-split). |
| Key | Type | Default | Env equivalent | Notes |
|---|---|---|---|---|
run.logs_dir |
string (path) | .jaiph/runs |
JAIPH_RUNS_DIR |
Step log directory. Relative paths join the workspace root; absolute paths are used as-is. |
run.debug |
boolean | false |
JAIPH_DEBUG |
Enable debug tracing. |
run.recover_limit |
integer | 10 |
— (no env override) | Maximum attempts for run … recover loops before the step fails. Resolves via workflow > module > default. |
Informational metadata only; does not affect execution. Allowed in module-level config only — any module.* key inside a workflow-level config is E_PARSE.
| Key | Type | Default |
|---|---|---|
module.name |
string | — |
module.version |
string | — |
module.description |
string | — |
trusted_envs)trusted_envs = "GITHUB_TOKEN NPM_TOKEN" declares which host environment variables a workflow’s trusted run steps receive — the declarative alternative to remembering jaiph run --env GITHUB_TOKEN …. The value is a quoted, space-separated list of env var names.
| Scope | Effect |
|---|---|
Module-level config |
Sugar: applies to every workflow in the file. |
Workflow-level config |
Scopes the keys to that workflow only. |
| Imported (non-entry) module | Ignored (warned at pre-flight) — an imported module must not be able to pull arbitrary host secrets into its own steps. Mirrors the import trust boundary for agent.command / agent.backend. |
config { trusted_envs = "NPM_TOKEN" } # module-level: every workflow's run steps
workflow publish {
config { trusted_envs = "GITHUB_TOKEN" } # only publish's run steps also see GITHUB_TOKEN
run release()
}
Semantics:
trusted_envs itself.run-step script subprocesses of the declaring workflow. They are never forwarded to prompt agent subprocesses — the prompt env stays the fail-closed allowlist described in Sandboxing, in every sandbox mode.run steps see it.--env override) aborts before anything is spawned (E_ENV_MISSING). Reserved keys (the --env E_ENV_RESERVED set, including JAIPH_DOCKER_*) are rejected at parse time.--env KEY=VALUE remains the imperative override: it wins over the host-snapshot value for the same key.-e channel as --env pairs — but only when the operator opts in with JAIPH_TRUSTED_ENVS=1. Authoring the entry file is a trust boundary equal to --env: an untrusted or model-edited entry could name arbitrary host secrets (AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN) and pull them across the allowlist the sandbox exists to enforce (finding M-7). Absent the opt-in, the entry file’s trusted_envs is ignored under Docker (with a pre-flight warning) and nothing is forwarded. Host modes have no allowlist to bypass (the runner inherits the host env directly), so they honour the declaration regardless. See JAIPH_TRUSTED_ENVS.These configure the Docker sandbox. Allowed in module-level config only. They are read by the host CLI when it considers a Docker launch (resolveDockerConfig in src/runtime/docker.ts) and never affect NodeWorkflowRuntime directly. Docker on/off is not a runtime.* key — see Docker enablement.
| Key | Type | Default | Env equivalent | Notes |
|---|---|---|---|---|
runtime.docker_image |
string | ghcr.io/jaiphlang/jaiph-runtime:<version> |
JAIPH_DOCKER_IMAGE |
Container image. Must already contain jaiph (E_DOCKER_NO_JAIPH otherwise). Host-controlled: an in-file value is rejected (E_DOCKER_IMAGE_HOST_ONLY) when Docker is the active sandbox; set a non-default image only through JAIPH_DOCKER_IMAGE. |
runtime.docker_network |
string | default |
JAIPH_DOCKER_NETWORK |
docker run --network value. none disables egress. Host-controlled for isolation-breaking values: an in-file host, container:*, or ns:* is rejected (E_DOCKER_NETWORK_HOST_ONLY) when Docker is the active sandbox — these dissolve the sandbox network boundary. Host-safe in-file values (default, none, a named bridge network) are honoured; the operator may still select any value, including host, through JAIPH_DOCKER_NETWORK. |
runtime.docker_timeout_seconds |
integer | 14400 |
JAIPH_DOCKER_TIMEOUT |
Container execution timeout in seconds. 0 disables. Negative or invalid env value produces E_DOCKER_TIMEOUT. |
In-file runtime.docker_enabled is not supported (E_PARSE); use the env-only enablement below. In the same spirit, runtime.docker_image and isolation-breaking runtime.docker_network values are host-controlled: a repo- or model-supplied entry file cannot point the sandbox at an arbitrary image or gut its network isolation (finding M-6). When Docker is off (host / JAIPH_UNSAFE mode) these keys are inert and not enforced.
The default official image is also pinned by manifest digest. The expected digest ships with the release, and every run verifies the local image against it and fails closed on a mismatch. There is no config-file key for the digest, so set or override it with the JAIPH_DOCKER_IMAGE_DIGEST environment variable, which also lets you pin a custom JAIPH_DOCKER_IMAGE.
Checks are applied top to bottom; the first match wins.
| Check | Result |
|---|---|
Platform is Windows (win32) |
Docker off (host-only mode, with a one-line notice). Overrides everything below, including JAIPH_DOCKER_ENABLED=true. |
JAIPH_DOCKER_ENABLED is set to exact true |
Docker on. |
JAIPH_DOCKER_ENABLED is set to any other value |
Docker off. |
JAIPH_DOCKER_ENABLED is unset and JAIPH_UNSAFE=true |
Docker off. |
| Default (no env) | Docker on. |
CI=true does not change this default. Host jaiph run --raw never consults this branch — the workflow runner is local in that path. On Windows the Docker sandbox is out of scope, so jaiph run resolves to host-only mode automatically without probing docker or failing on a missing daemon — see Sandboxing — Windows runs host-only for the full model.
| Layer | Effect |
|---|---|
Environment (JAIPH_AGENT_*, JAIPH_RUNS_DIR, JAIPH_DEBUG) |
Locked when present in the parent env; cannot be overridden by module- or workflow-level config. |
Workflow-level config |
Applies for the workflow body; restored on exit. |
Module-level config |
Applies to workflows without their own block. |
| Built-in defaults | Lowest priority. |
| Layer | Effect |
|---|---|
CLI flags (--inplace, --unsafe, --yes on jaiph run / jaiph serve / jaiph mcp) |
Set the corresponding JAIPH_* variable on the launched env for that process, so the env layer below stays the single source of truth. |
Environment (JAIPH_DOCKER_*, JAIPH_UNSAFE, JAIPH_INPLACE) |
Highest env-layer priority for image, network, timeout, and sandbox posture. |
Module-level config (runtime.*) |
Applies when no env override is set. |
| Built-in defaults | Lowest priority. |
Workflow-level config cannot set runtime.* keys. Contradictory posture (--inplace/JAIPH_INPLACE together with --unsafe/JAIPH_UNSAFE) is rejected with E_FLAG_CONFLICT before anything is spawned rather than resolved by precedence — see Environment variables — Precedence.
| Call type | Scope behaviour |
|---|---|
Root entry (jaiph run file.jh) |
Full module + workflow metadata applied with normal precedence. |
Same-module run |
Callee’s workflow-level config is layered on top of the caller’s effective env. Module-level config is not re-applied. |
Cross-module run (e.g. run alias.default()) |
Callee’s module-level config is layered, then workflow-level on top — same as root-entry precedence, respecting ${NAME}_LOCKED. agent.command and agent.backend are not applied from imported modules (see Import trust boundary). |
Same-module ensure |
Caller’s scope is reused verbatim. |
Cross-module ensure |
Callee module’s agent.* / run.* are merged on top of the current env (respecting locks). Workflow-level config does not apply to rules. |
After any nested call returns, the caller’s scope is restored exactly as before.
When the host CLI builds the runner environment, any of these variables already present in process.env gets a matching ${NAME}_LOCKED=1 flag set on the child env. The runtime refuses to overwrite a locked value from later metadata merges.
Locked names: JAIPH_AGENT_BACKEND, JAIPH_AGENT_MODEL, JAIPH_AGENT_COMMAND, JAIPH_AGENT_TRUSTED_WORKSPACE, JAIPH_AGENT_CURSOR_FLAGS, JAIPH_AGENT_CLAUDE_FLAGS, JAIPH_RUNS_DIR, JAIPH_DEBUG.
agent.command and agent.backend are execution-binary keys — they determine which process runs prompt steps. To prevent a third-party .jh library from silently redirecting execution to a different binary, these two keys may only be set from the entry module’s config {} block (module-level or workflow-level). Imported modules that declare agent.command or agent.backend in their config {} are silently ignored for these keys.
trusted_envs carries the same entry-only restriction: declarations in imported modules are ignored (with a pre-flight warning) so a library cannot pull host secrets into its own steps.
All other config keys (agent.model, agent.trusted_workspace, agent.cursor_flags, agent.claude_flags, run.logs_dir, run.debug) are not restricted and follow the normal scoping rules for cross-module calls.
Advanced unlock (use with caution): to allow an imported module to override these keys, set one or both of the following environment variables before the run:
| Variable | Effect |
|---|---|
JAIPH_AGENT_COMMAND_IMPORT_UNLOCK=1 |
Allow any imported module to set agent.command. |
JAIPH_AGENT_BACKEND_IMPORT_UNLOCK=1 |
Allow any imported module to set agent.backend. |
The existing JAIPH_AGENT_COMMAND_LOCKED=1 / JAIPH_AGENT_BACKEND_LOCKED=1 flags still apply on top — a locked key cannot be changed regardless of the source.
| In-file key | Environment variable |
|---|---|
agent.model |
(prompt-scoped only — does not set JAIPH_AGENT_MODEL) |
agent.command |
JAIPH_AGENT_COMMAND |
agent.backend |
JAIPH_AGENT_BACKEND |
agent.trusted_workspace |
JAIPH_AGENT_TRUSTED_WORKSPACE |
agent.cursor_flags |
JAIPH_AGENT_CURSOR_FLAGS |
agent.claude_flags |
JAIPH_AGENT_CLAUDE_FLAGS |
run.logs_dir |
JAIPH_RUNS_DIR |
run.debug |
JAIPH_DEBUG |
run.recover_limit |
(no env override) |
runtime.docker_image |
JAIPH_DOCKER_IMAGE |
runtime.docker_network |
JAIPH_DOCKER_NETWORK |
runtime.docker_timeout_seconds |
JAIPH_DOCKER_TIMEOUT |
module.name |
(no env override) |
module.version |
(no env override) |
module.description |
(no env override) |
Variables with no in-file equivalent: JAIPH_CODEX_API_URL (codex endpoint), JAIPH_PROMPT_RETRY / JAIPH_PROMPT_RETRY_DELAYS (prompt-retry schedule), OPENAI_API_KEY (codex credential). Full inventory in Environment variables.
| Backend | Required credential | Endpoint / CLI |
|---|---|---|
cursor (default) |
CURSOR_API_KEY (or stored cursor-agent login on host runs) |
Runs agent.command (default cursor-agent) with stream-json framing. |
claude |
ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN (or stored Claude CLI login on host runs) |
Runs claude on PATH. |
codex |
OPENAI_API_KEY |
Calls the OpenAI Chat Completions endpoint directly (JAIPH_CODEX_API_URL overrides the URL). No CLI-login fallback. |
Backend-specific flags come from agent.cursor_flags / agent.claude_flags (or the matching env vars). There is no per-prompt backend override.
Before jaiph run spawns the workflow runner or Docker container, the host CLI runs a credential pre-flight (src/cli/run/preflight-credentials.ts). It collects the distinct backend(s) declared in the entry file’s module-level config block and each workflow-level block, plus the effective default (JAIPH_AGENT_BACKEND env, or cursor when unset). Deeper per-import overrides resolved at runtime are not followed.
| Backend | Required credential | Host run (no Docker) | Docker run (any mode incl. inplace) |
|---|---|---|---|
codex |
OPENAI_API_KEY |
hard error (E_AGENT_CREDENTIALS) |
hard error (E_AGENT_CREDENTIALS) |
claude |
ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN |
warn (CLI login may still work) | hard error (E_AGENT_CREDENTIALS) |
cursor |
CURSOR_API_KEY |
warn (CLI login may still work) | hard error (E_AGENT_CREDENTIALS) |
Hard errors exit non-zero with no runner or container launched. Warnings go to stderr and the run proceeds. Skip cases: entry file declares no explicit backend and uses no prompt step → no pre-flight; jaiph run --raw → no pre-flight; JAIPH_UNSAFE=true / --unsafe → no pre-flight (host escape hatch — runtime backend guards remain).
Every error and warning names: the backend; the model when agent.model is set; the entry .jh file; the config scope (module config, workflow <name>, JAIPH_AGENT_BACKEND env, or default); and the concrete remedy. Docker-mode messages also note that the variable must be set on the host so it gets forwarded.
Resolution order for a prompt step:
| Step | Source | Notes |
|---|---|---|
| 1 | User env — JAIPH_AGENT_MODEL non-empty. |
model_reason: explicit. Applies to every prompt in the run. |
| 2 | In-file config — agent.model from workflow-level then module-level metadata (interpolated at prompt time). |
model_reason: explicit. Applies to that prompt invocation only; passed as --model to the backend CLI without writing JAIPH_AGENT_MODEL. |
| 3 | Flags model — --model <name> inside agent.cursor_flags / agent.claude_flags. |
model_reason: flags. Codex has no flag channel; this step does not apply. |
| 4 | Backend default — Cursor/Claude binaries pick their own. Codex defaults to gpt-4o in code. |
model_reason: backend-default. |
For the Claude backend, when agent.model is set and agent.claude_flags does not already contain --model, Jaiph passes --model <value> to the Claude CLI automatically. If both are set, the value in agent.claude_flags wins (appended last).
PROMPT_START / PROMPT_END records in run_summary.jsonl carry model (resolved string, or null when the backend auto-selects) and model_reason (explicit, flags, backend-default, or none for a custom agent command, which has no model concept).
NodeWorkflowRuntime retries transport-failed prompt invocations on an escalating backoff schedule before propagating the failure to any enclosing recover / catch.
| Attempt | Delay before this attempt |
|---|---|
| 1 | (none — initial call) |
| 2 | 15s |
| 3 | 1m |
| 4 | 10m |
| 5 | 30m |
| 6 | 2h |
Total worst-case wall-clock: ~2h41m. Under Docker, runtime.docker_timeout_seconds caps this.
Only transport failures are retried (non-zero exit from cursor/claude, codex HTTP error, spawn failure). Deterministic post-processing failures — invalid JSON, schema validation — fail on the first attempt and return { ok: false }.
Each attempt emits its own PROMPT_START / PROMPT_END and STEP_START / STEP_END. Each failure logs a LOGERR line; the final termination logs another. The captured value reflects the successful attempt.
| Variable | Effect |
|---|---|
JAIPH_PROMPT_RETRY=0 |
Disable retry entirely (one attempt, fail on transport failure). |
JAIPH_PROMPT_RETRY_DELAYS |
Comma-separated list of non-negative integer milliseconds. Invalid entries abort the prompt. |
jaiph test defaults JAIPH_PROMPT_RETRY=0. Backoff sleep is interruptible: workflow abort, SIGINT, or SIGTERM cancels the pending wait without further backend calls.
The retry backoff above handles a backend that fails. A separate set of watchdogs handles a backend that hangs — it never exits, so without them the runtime would block on the subprocess indefinitely (no commit, no queue progress, no retry). Each prompt invocation installs three independent layers over the spawned backend process:
| Layer | Variable | Default | Trigger | Outcome |
|---|---|---|---|---|
| Completion grace | JAIPH_PROMPT_COMPLETION_GRACE_SECONDS |
30 |
The backend emitted its terminal result event (work is done) but the process has not exited within the grace window. |
Terminate the process, return success with the captured answer. |
| Idle timeout | JAIPH_PROMPT_IDLE_TIMEOUT_SECONDS |
900 (15m) |
No stdout/stderr for the whole window — the backend is stuck mid-work. | Terminate the process, return failure → feeds the retry backoff. |
| Absolute cap | JAIPH_PROMPT_MAX_SECONDS |
7200 (2h) |
Total wall-clock for the single invocation exceeds the cap, regardless of activity. | Terminate the process, return failure → feeds the retry backoff. |
Set any variable to 0 to disable that layer. The idle timer resets on every chunk of backend output, so a slow-but-active run is bounded only by the absolute cap.
The completion-grace layer specifically addresses the known claude -p failure mode where the CLI streams its final answer (and the terminal result event) but the process never exits — often because a descendant it spawned is still holding the output pipe open. When a watchdog fires it terminates the backend’s whole process tree (via killProcessTree; see Architecture) with SIGTERM, escalating to SIGKILL after 5s, and tears down the runtime’s handles on the child’s stdio so a lingering descendant cannot keep the run alive. On Windows the tree is force-killed with taskkill /T on the first signal, so the SIGKILL escalation is a no-op. Under Docker, runtime.docker_timeout_seconds remains the outer backstop for the whole container.
The prompt watchdogs above bound a single backend call. Jaiph also has two controls that bound the whole run, and both are off by default, so existing runs behave as before.
JAIPH_RUN_TIMEOUT sets a parent-enforced wall-clock cap, in seconds, for a host-mode run. Host mode means a jaiph run --unsafe or host-only run, and the host spawn that a jaiph serve or jaiph mcp call uses. Without this cap, the only automatic stop for a host run is a manual Ctrl-C, because the host spawn installs only SIGINT and SIGTERM handlers and the prompt watchdogs cover a single backend call. When the cap is reached, the parent terminates the run child’s whole process group with SIGTERM and escalates to SIGKILL after a short grace period (via killProcessTree; see Architecture), so the run stops without a manual Ctrl-C, and the failure footer shows E_RUN_TIMEOUT. Set it to 0, leave it empty, or give it an invalid value to disable it, which restores the earlier behaviour where only a manual SIGINT or SIGTERM stops a host run. Docker mode does not use this variable, because a Docker run is already bounded by runtime.docker_timeout_seconds (JAIPH_DOCKER_TIMEOUT) inside the container.
JAIPH_MAX_STEPS sets an optional max-step circuit breaker in the runtime. When you set it to a positive integer, the runtime counts every executed step across the whole run, and it counts loop iterations and nested or recursive calls but skips trivia. Once the count goes past the cap, the runtime logs E_MAX_STEPS, aborts the run, and returns a failure, so a runaway workflow stops on its own without a manual signal. Set it to 0, leave it empty, or give it an invalid value to disable the breaker.
The prompt watchdogs bound a single backend call, and the run timeout and step cap bound the whole run. A separate watchdog bounds one leaf step by how long it stays silent. A leaf step is a script step or a prompt step, and the watchdog watches its stdout and stderr. It catches a script step that the prompt watchdogs never see, such as an overnight npm run test:ci that stops producing output but never exits. The runtime checks for silence on a poll interval set by JAIPH_STEP_IDLE_WARN_CHECK_MS (default 5000 milliseconds, floor 250).
JAIPH_STEP_IDLE_WARN_SEC (default 180 seconds; 0 disables) sets how long a leaf step can go without any stdout or stderr before the runtime emits a LOGWARN. The warning repeats on the same cadence while the step stays silent, so at 180 seconds, then 360, then 540, and so on. Any new output resets the clock. The warning does not fail the step, and it only surfaces a stalled backend or a long-running command.
JAIPH_STEP_IDLE_KILL_SEC (default 3600 seconds, one hour; 0 disables) sets a hard limit for a script step. When a script step goes that long without any stdout or stderr, the runtime emits a LOGERR naming the step and how long it was silent, terminates the step’s subprocess with SIGTERM and then SIGKILL (via killProcessTreeEscalating; see Architecture), and fails the step. Any new output resets this clock too. The warn cadence and the kill limit run off the same idle clock but fire independently. The kill applies to script steps only, because a prompt step’s backend is already bounded by the prompt watchdogs above, so a prompt step still gets the idle warnings but is never killed by this limit.
agent.command is consumed by the cursor backend only. For claude and codex, Jaiph always invokes the Claude CLI or the codex HTTP path, regardless of agent.command.
When agent.backend = "cursor" and agent.command’s basename is anything other than cursor-agent, Jaiph treats it as a custom agent command:
| Channel | Behaviour |
|---|---|
| stdin | Prompt text piped to the command. |
| stdout | Captured as the prompt response (raw text, no JSON framing). |
| stderr | Passes through to the terminal. |
Cursor-specific flags (--output-format, --stream-partial-output, --workspace, …) |
Not appended. |
| Step display name | Command basename instead of cursor. |
Custom commands still participate in PROMPT_START / PROMPT_END, write artifacts, and apply returns schema validation when configured.
jaiph test does not call resolveRuntimeEnv. The test runner spreads process.env, then sets JAIPH_TEST_MODE, JAIPH_WORKSPACE, JAIPH_RUNS_DIR (ephemeral), JAIPH_SCRIPTS, and mock fields (JAIPH_MOCK_RESPONSES_JSON, JAIPH_MOCK_PROMPT_ARMS_JSON). JAIPH_*_LOCKED flags are not set unless inherited from the parent env. NodeWorkflowRuntime still applies in-file config via applyMetadataScope with the same lock rules.
Agent and run settings are visible inside workflows, rules, and scripts as JAIPH_* environment variables. In orchestration strings, ${IDENT} resolves against workflow bindings first, then against the process environment.
JAIPH_DOCKER_* variables are not populated from in-file runtime.* inside the workflow runner. Docker config is consumed when the CLI spawns the runner (or container); if a script needs Docker-related variables in its environment, export them from the parent shell.
jaiph initjaiph init creates .jaiph/bootstrap.jh, .jaiph/SKILL.md, and .jaiph/.gitignore. There is no separate config file — config { … } blocks live in workflow source. See CLI — jaiph init.
config block syntax in the formal grammar.