Skip to content

Guided tour

FabrCore 2.0 · Release and package availability

These guides track the current 2.0 source. Stable 2.0.0 publication is pending; package commands show the release target. Until it is published, follow the source quick start or use a matching available prerelease set. Release migration · Runtime modes

MODULE 06 · LESSON 6.5

Resume sessions and handle lost work

Restore harness plans while reporting work that cannot be recovered.

Lesson 37 of 86 · FabrCore 2.0

Overview

Harness snapshots hold todos, modes and delegation records; chat messages remain in the history provider. In-flight tasks are live process objects and cannot simply be serialized back into execution. Restoring a plan and replaying a side effect are different operations.

A snapshot preserves state, not live tasks

A harness snapshot can retain todos, mode and delegation records across turns. Chat history is retained separately by its provider. A live Task object executing an external request cannot be recreated merely by deserializing a snapshot. After process loss, a delegation can be recorded as lost even while an external system already completed its effect.

Reconcile before replaying an uncertain effect

An interrupted “close request” operation is not equivalent to an operation that was never sent. Inspect its stable operation identifier or authoritative business record before retrying. A recovery response should name lost work and the next decision needed, rather than re-run every unfinished todo automatically. Durable storage is required to test process restart recovery meaningfully.

Resume a saved investigation

  1. Run through the wrapper and leave session persistence enabled. Inspect remaining todos before ending the turn.
  2. After enabling persistent Orleans storage, restart between turns and verify restored plan/session state. Include DescribeLostDelegations in the user-visible recovery report.
  3. Choose an explicit retry/reconciliation path for Lost work. For uncertain external effects, query the recorded operation/result before attempting anything again.
Reporting Honestly · reference snippet
public override async Task<AgentMessage> OnMessage(AgentMessage message)
{
    SetStatusMessage("Planning...");

    var run = await harness.RunAsync(message);
    var text = run.Text;

    // Delegations stranded by a restart — see references/durability.md.
    if (harness.DescribeLostDelegations() is { } lost)
    {
        text += $"{Environment.NewLine}{Environment.NewLine}{lost}";
    }

    var remaining = await harness.GetRemainingTodosAsync();
    if (remaining.Count > 0)
    {
        text += $"{Environment.NewLine}{Environment.NewLine}Not completed within the iteration budget:{Environment.NewLine}"
            + string.Join(Environment.NewLine, remaining.Select(item => $"- {item.Title}"));
    }

    SetStatusMessage(string.Empty);

    var response = message.Response();
    response.Message = text;
    return response;
}

Restart between turns, then during work

  1. With durable storage configured, complete one fixture step, leave another todo open and restart between turns. Read the restored todo/session state and continue without recreating the finished step.
  2. In a separate controlled run, interrupt a delegation while its result is outstanding. Inspect lost-delegation reporting after recovery.
  3. Check the external fixture's operation record before any retry. If it already completed, reconcile the result into the investigation; if its outcome is unknown, retain that uncertainty visibly.

You have tested state restoration and uncertain-execution handling separately. A restored todo list does not establish that all background work resumed safely.

If the result is different

Standalone process restart loses the backing state. Changing a thread ID selects a different snapshot; clearing/resetting/evicting affects different parts of the lifecycle.

Go deeper

Explore the related documentation.