Run and sessions
Execute now, observe progress, and attribute inputs and outputs without changing data truth.
Run starts a session immediately. A session is an observability record named by its start timestamp and stable ID. Its timestamp is for display only; it never decides which value or relationship wins.
started = workspace.run(
"news-events",
"v2",
incremental_tasks=("group-events",),
max_cost_usd=10.0,
)
session = workspace.session(started["session_id"])
print(session["status"], session.get("metrics", {}).get("cost_usd", 0.0))
max_cost_usd is the hard
model-usage ceiling for this session. Hosted Relifold also has a service maximum. Omitting the
field uses that hosted maximum; you may choose a smaller value but cannot raise it. Set it to
0 for a deterministic or fully reusable run: cached and prior-backed work may
continue, while any paid model call is rejected before it starts.Task states
A session is queued while it waits for hosted worker capacity and becomes running only after a worker is acquired. Queued sessions remain observable and stoppable, and all of their tasks remain Not begun.
Queue time and execution time
queue_time_seconds measures admission through worker acquisition.
execution_wall_time_seconds measures worker acquisition through completion.
data_wall_time_seconds measures worker acquisition until every data task has durably
committed; data_ready_at records that boundary while review may continue.
wall_time_seconds remains the complete end-to-end duration and therefore includes
both. Relifold never estimates compute time by adding task durations because parallel tasks
overlap. Older sessions retain their exact end-to-end duration and omit the newer split.
Each completed task also reports execution_started_at and
execution_completed_at as Unix seconds. These boundaries let clients measure actual
parallel-branch overlap. Older task results omit the boundaries rather than estimating them.
Session pages use Not begun, In progress, Finished, Failed, and Stopped. Exact progress is shown where the amount of work is known in advance. Iterative one-space semantic operations show an explicitly estimated percentage from the work planned so far; it may decrease when a later round reveals more work. Live task details show elapsed time and settled model spend to date. Relifold does not project task completion time; complete-run cost forecasts belong to the version and Workbench estimate APIs.
What a session records
- source rows supplied, exact rows consumed, and output rows emitted;
- model calls, cached calls, skipped work, and calls that still failed after retries;
- cost, wall-clock time, and task state;
- automated review observations attributable to the session;
- links to bounded pages of relational task output.
Browse these ledgers from the session page or read the same bounded pages through the API:
page = workspace.session_rows(
started["session_id"],
"inputs", # sources, inputs, or outputs
space="headlines",
limit=200,
)
for row in page["rows"]:
print(row["data"], row["produced_by_sessions"])
Continue from next_offset until it is null. Reading these rows is observability
only; it cannot select inputs for another run or change any Space.
Read review metrics precisely
A reviewed proposition and a review decision are not always the same count. A multi-label
relationship pair is one proposition, but a per-class reviewer may answer one label question for
each available relationship label. Session responses therefore report
unique_propositions, review_decisions,
label_decisions, and accuracy_unit separately. Reviewer accuracy is the
fraction of those review decisions marked correct; it is not population precision or recall unless
your evaluation hand was explicitly designed to measure those quantities.
Incremental refresh
Select incremental refresh per task when new data should build on compatible prior results. The task evaluates what is new or unresolved and still emits a complete current structure. If two independent sessions produce different relationships, both session outputs remain observable; one does not overwrite the other. Read the incremental-refresh guide.
Stop safely
Stopping a session prevents new work from starting. Output already emitted remains available and is attributed to the stopped session. A queued session has no running work, so it becomes Stopped immediately instead of waiting for worker capacity. A running session finishes only its current safe unit before stopping.
stopped = workspace.stop(started["session_id"])
print(stopped["status"], stopped["stopped_early"])