Skip to content

ateapi: resolve the resume boot source and wire scope once in loadActorForResume - #1492

Open
Zoe Zhao (zoez7) wants to merge 1 commit into
agent-substrate:mainfrom
zoez7:resume-refactor
Open

ateapi: resolve the resume boot source and wire scope once in loadActorForResume#1492
Zoe Zhao (zoez7) wants to merge 1 commit into
agent-substrate:mainfrom
zoez7:resume-refactor

Conversation

@zoez7

@zoez7 Zoe Zhao (zoez7) commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Refactored loadActorForResume to resolve the boot source and wire scope once, in 4 rules:

  1. If the ActorTemplate was updated since the capture, restore data only from the existing snapshot or checkpoint. [Based on 1492] Resume with Golden+DurDir when ActorTemplate updated. #1461 PR will only change this code path to use golden+data.
  2. If the actor was resuming from Paused state, use the Local checkpoint at the scope recorded on the checkpoint, falling back to the template's onPause scope for legacy checkpoints that predate the recorded scope. If that scope is Data and onResume.FromData is golden, use golden+data.
  3. If the actor was resuming from Suspended state, use the External snapshot at its captured scope. If that scope is Data and onResume.FromData is golden, use golden+data.
  4. An actor with no snapshot restores the template's golden when one exists, and cold boots from the spec otherwise. An explicit boot request skips only the golden fallback.

The restore step now dispatches on the resolved kind and fails with Internal on an unhandled kind instead of silently cold booting.

Behavior changes

  • A resume after an ActorTemplate update now restores data-only from the existing snapshot or checkpoint — including a Paused actor holding only a local checkpoint — and no longer consults the Golden policy, so an absent or invalid golden no longer fails it with FailedPrecondition. This is a temporary placeholder until [Based on 1492] Resume with Golden+DurDir when ActorTemplate updated. #1461 switches this path to golden+data.

  • A Paused resume no longer validates inputs the local restore never consumes: an unusable golden no longer fails it (intentional bugfix), and the shadowed durable ExternalSnapshot.SnapshotUri is no longer parsed, so an unparseable record no longer fails it with DataLoss.

  • Tests pass

  • Appropriate changes to documentation are included in the PR - Not required

Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go Outdated
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go Outdated
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go Outdated
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go Outdated
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go
Comment thread cmd/ateapi/internal/controlapi/workflow_resume_test.go
@zoez7
Zoe Zhao (zoez7) force-pushed the resume-refactor branch 3 times, most recently from 5a9e4e7 to b23df34 Compare September 4, 2026 23:36
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go Outdated
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go Outdated
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go Outdated
Comment thread cmd/ateapi/internal/controlapi/workflow_resume.go Outdated
@zoez7
Zoe Zhao (zoez7) force-pushed the resume-refactor branch 3 times, most recently from e23cedf to 330a02c Compare September 5, 2026 20:09
The resume path decided the boot source in two places that agreed only
by hand-mirrored ordering. loadActorForResume picked a snapshot URI
(the actor's own, else the template's golden), a content scope, and a
template-replaced flag; ensureAteletRestored then re-derived the rest
in every branch: local-vs-durable from LocalSnapshotInfo, cold boot
from an empty SnapshotURI, the telemetry snapshot kind from the
actor's external snapshot record, and the wire scope from a
three-case switch repeated per branch.

Resolve everything in loadActorForResume as a first-match rule list:
updated template, paused actor, own durable snapshot, then golden
fallback or cold boot (with an explicit boot request skipping only the
golden fallback, as before). resumeSnapshotSource now carries the
resolved restoreKind and wire scope; ensureAteletRestored dispatches
on the kind, maps the telemetry labels from it, and fails with
Internal on an unhandled kind instead of silently cold booting. The
golden snapshot's validation and URI parsing, previously duplicated
between the no-snapshot fallback and the Golden data-resume policy,
collapse into resolveGoldenSnapshot; the per-branch scope fallbacks
fold into resolveRestoreScope. A paused actor's restore scope now
comes from pausedContentScope — the scope recorded on the checkpoint,
with the template's onPause standing in for legacy checkpoints — the
same derivation suspend uses. GoldenSnapshotURI becomes
GoldenForDataSnapshotURI, since it only ever names the guest half of a
data-only combined restore, never the boot snapshot itself. A golden
boot now gets its own log line (it used to log as a durable-snapshot
restore) and an explicitly FULL wire scope (it used to echo the
golden's recorded content scope).

Four behavior changes ride along, all on paths where the old code
resolved or demanded state the restore would not use:

- An actor whose ActorTemplate was updated restores its data alone,
  but the old resolution still consulted the Golden resume policy for
  its Data-scoped capture and failed with FailedPrecondition (or
  DataLoss) when the template recorded no valid golden. Rule 1 now
  returns before the policy is consulted.

- The template update was only detected when the actor held a durable
  snapshot. An actor resuming from a local pause checkpoint alone
  restored at the template's onPause scope, carrying guest state built
  on the previous template; it now gets the same data-only restore as
  every other actor whose template was updated.

- The golden fallback is only resolved for an actor with no snapshot
  of its own. A paused actor without a durable snapshot used to run
  the fallback resolution anyway — its local checkpoint restore
  ignored the result, but a legacy-scoped or unparseable golden failed
  the resume.

- A paused actor's shadowed durable snapshot URI was parsed even
  though the local restore never consumes it, so an unparseable URI
  failed the resume with DataLoss. The URI is now parsed exactly when
  the durable snapshot is the boot source.

Tests pin the rule list: the updated-template bypass of the Golden
policy, boot skipping only the golden fallback, the golden fallback's
FULL scope, the recorded pause scope outranking the template's
onPause, DataLoss on an unparseable durable snapshot URI only when it
is the boot source, and the kind-to-telemetry mapping.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants