Exec block
Purpose: runtime-wide defaults, pricing/policy wiring, retries, and cost attribution.
Start Here
For local commands, configure the workspace environment
with ACTSPAN_PORTAL_DISABLED=1 in its .actspan.env. Run from that
workspace directory and keep the selected provider credentials configured.
Use exec for Actspan runtime behavior around provider calls. Provider-native
request fields belong in the provider action or prompt instead.
After changing exec, run:
actspan validate workspace.yaml
actspan preview workspace.yaml
actspan lock --check
Expected result: preview identifies the selected policy, pricing source, region, and effective runtime assumptions; lock check reports whether reviewed inputs changed.
Syntax (summary)
exec:
default_provider: primary # fallback when prompts/agents omit provider
region: us # policy/pricing metadata, not proof of residency
policy_file: ./governance/policies.yaml # optional
policy_env: dev # optional
policy_env_map: {} # optional env->overlay map
policy_overrides: {} # tighten-only unless policy_allow_weakening=true
policy_allow_weakening: false
pricing_csv: ./model_pricing.csv # or pricing: { csv: ... }
retry: # optional retry/backoff
enabled: true
max_attempts: 3
initial_wait_seconds: 1.0
backoff_multiplier: 2.0
max_wait_seconds: 60.0
jitter: true
respect_retry_after: true
attribution: # optional cost/ownership tags
team_id: platform
project: lead-enrichment
cost_center: R&D
environment: prod
customer_id: acme
custom:
feature: chatbot
Field notes
default_provider(string): provider alias used when a prompt/agent omitsprovider.region(string): policy/pricing metadata surfaced in meta/admission; it does not prove physical processing or retention location.policy_file(path): base policy file. If governance is required, set this.policy_env(string): which env/overlay to use (dev/prod/etc.).policy_env_map(map): env → overlay file path.policy_overrides(object): tighten-only overrides applied after env overlay (unlesspolicy_allow_weakening: true).pricing_csv/pricing.csv: explicit pricing-table path; see the resolution order below.retry(object, optional): retry/backoff for provider calls; honors Retry-After when set.attribution(object, optional): tags persisted with every run (team/project/cost_center/environment/customer_id/custom).tool_paths/tool_map: optional tool discovery helpers (string paths or name→import spec).
Execution status and automation
Distinguish the execution status from its business outcome. A completed workflow
may legitimately return outcome: blocked; a pending review is an explicit pause,
while invalid output evidence is an execution failure.
| Situation | Current source contract |
|---|---|
| Successful execution, including a blocked business outcome | Exit 0, success: true; inspect the business output separately. |
| Waiting for input/review/handoff | Explicit pending state; not converted to an execution failure. |
Execution status error or failed |
Nonzero exit, success: false and a structured error; existing nonzero codes are preserved. |
| SDK execution failure | A typed error is raised before a successful result is tracked. |
The source correction applies to native run/call and workflow continuation;
receipt failures retain OUTPUT_EVIDENCE_UNSUPPORTED_CLAIM. This correction
requires the next qualified release. Published 0.2.0 is unchanged: on the
documented direct-prompt receipt path it can return exit 0/outer success while
nested execution failed. Check nested status and recorded error when using that
artifact; the deterministic refund exercise
demonstrates the precise boundary. This observation does not establish identical
behavior for every older command or integration.
Rejecting a final claim does not reverse a completed tool write. Inspect the downstream record before retrying a failed action.
CLI JSON envelope
Use --format json on commands that support it. The CLI result envelope carries
command outcome separately from the operation's nested payload. This abridged
public 0.2.0 verify example shows incomplete coverage, not a provider failure:
{
"object": "actspan.cli.result",
"contract_version": "1.0",
"command": "verify",
"success": false,
"exit_code": 2,
"result": {"object": "actspan.verification", "status": "incomplete"},
"error": null
}
error: null does not override an incomplete/failed nested report. Read the
command's documented status and constraints; pending review is not final
completion, and a blocked business outcome can be successful execution. Actual
run IDs come from the recorded result, not generated prose. Preserve stderr and
shell exit as well as JSON for diagnostics.
The public 0.2.0 direct-prompt receipt exception above still applies: its outer success and shell exit are insufficient. The refund checker exercises same-run nested failure and receipt evidence. A current source contract is not proof that an already published binary contains the correction.
Pricing tables
Pricing tables provide local cost estimates. Actspan selects the CSV in this order:
- The explicit
exec.pricing_csvorexec.pricing.csvpath. ACTSPAN_PRICING_CSV, when it points to an existing file.<workspace>/data/model_pricing.csv, when present.- The packaged
actspan/data/model_pricing.csv.
A missing explicit file raises an error; a missing environment override falls through to the next source.
The legacy model-based format requires exactly these columns, in any order:
provider,model,in_usd_per_tok,out_usd_per_tok,effective_date
Rates are USD per token, and effective_date uses YYYY-MM-DD. Within the
provider's rows, selection prefers an exact model match with the latest date
no later than today. If no eligible exact match exists, it uses the latest
eligible row whose model is a prefix of the requested model. For example,
gpt-4o-mini can match gpt-4o-mini-2024-08-06. The legacy lookup also resolves
aliases such as auto:openai/chat/fast to gpt-4o-mini before matching.
The pattern-based format instead requires exactly these columns:
provider,region,pattern,input_per_mtok_usd,output_per_mtok_usd
Here pattern is a regular expression matched against the model. Within the
provider's rows, the first matching row for the requested region wins, followed
by the first matching wildcard-region (*) row. The current estimator applies
these rates per 1,000 tokens, despite the historical per_mtok column names.
Do not enter per-million prices directly into those columns. This is existing
compatibility behavior, not a change to the estimator.
For a pattern row with input 0.001 and output 0.002, an estimate of 2,000
input tokens and 500 output tokens is (2000 / 1000 × 0.001) + (500 / 1000 × 0.002) = $0.003. Those rates correspond to $1 and $2 per million tokens.
In the legacy exact-model table, the equivalent values are 0.000001 and
0.000002 USD per token. Review the selected format, units and model identity
before relying on admission. Catalog filenames and the word mtok alone do not
establish a unit or the active price source.
To record which table a preview used, run:
actspan preview workspace.yaml --write-pricing-meta
This writes metadata beside the selected CSV, replacing .csv with
.meta.json (for example, model_pricing.meta.json). The metadata records the
source path, selection method, generation time, columns, SHA-1, entry count,
and cache token.
Examples
Minimal:
exec:
default_provider: primary
region: us
With policy and pricing override:
exec:
default_provider: primary
region: us
policy_file: ./governance/policies.yaml
policy_env: prod
pricing_csv: ./data/model_pricing.csv
Retries + attribution:
exec:
default_provider: primary
retry:
max_attempts: 4
initial_wait_seconds: 0.5
max_wait_seconds: 10
jitter: true
attribution:
team_id: eng-platform
project: routing
environment: staging
Validation
actspan validate workspace.yaml— full schema checks (including policy/pricing pointers, retry/attribution structure).actspan preview workspace.yaml --format json— renders pricing/policy status without calling providers.