Docs target current release v0.7.0.v0.7.1 is under review

Forking

Run.fork(from_step_id) creates a new run containing the selected step and every ancestor needed to reach it. Descendants and sibling branches are excluded.

fork.py
1from pathlib import Path
2from opentine import Run
3
4run = Run.load("failed.tine")
5last_good = run.steps[19]
6
7forked = run.fork(
8    from_step_id=last_good.id,
9    branch="recovery",
10    intent={"reason": "use the alternate source"},
11)
12
13# Use the ID returned by fork().
14forked.save(Path(f"{forked.id}.tine"))
15
16assert forked.steps[-1].id == last_good.id
17assert forked.metadata["forked_from"] == run.id
18assert forked.metadata["fork_point"] == last_good.id
19assert forked.metadata["fork"]["branch"] == "recovery"

Fork identity in v0.4

A default portable fork ID identifies one fork act, not only the parent and fork point. Its recorded basis includes source lineage, retained history, branch, declared intent, and a random nonce. Two ordinary forks from the same step are therefore distinct by default.

identity.py
1# Default: a new intervention with a fresh nonce and ID
2first = run.fork(last_good.id)
3second = run.fork(last_good.id)
4assert first.id != second.id
5
6# Explicit opt-in: deterministic identity for idempotent work
7cached_a = run.fork(last_good.id, nonce="")
8cached_b = run.fork(last_good.id, nonce="")
9assert cached_a.id == cached_b.id

Cached replay deliberately takes the deterministic path. Explicitnew_run_id remains available for compatibility, but new code should use the ID returned by fork() instead of predicting it.

What is preserved

  • Retained steps keep their original full content-addressed IDs.
  • The new run starts in running state with its fork-act ID.
  • The manifest, policies, retained transcript, and fork provenance are copied.
  • Tags are intentionally not inherited by the new artifact.

Continue a native run

Run.fork() changes the artifact; it does not call a model. For opentine-native runs, continue with Agent.resume() orAgent.resume_sync(). Resume is allowed only when the manifest declares support.

continue.py
1# The native Agent API reconstructs messages from the retained transcript,
2# forks at the selected step, appends the new prompt, and continues execution.
3fixed = agent.resume_sync(
4    run,
5    from_step=last_good.id,
6    prompt="Use the alternate source and continue.",
7)
8fixed.save("retry-complete.tine")

Cost semantics

The fork records the cost already incurred by its retained steps. Continuing from it avoids repeating those calls, but it does not erase the original run's spend or guarantee future calls will be cheaper.

See the v0.4 upgrade guide for compatibility details.