Operate
← Relifold documentation

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))
Bound every run. 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

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"])