You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Separate process-side task registration from session-bound TaskManager
construction/startup for golden memory snapshots.
Replaces #49485. That draft was stacked on feature/agentserver-core-lifecycle-hooks. GitHub closed it when #49217 merged
and its base branch was deleted, and a closed PR cannot be retargeted or
reopened. This PR carries the same change on main (based on 037e8b7, which
contains #49217), so nothing is stacked any more.
The change is otherwise identical to #49485's final head (4540307). Rebasing
onto the merged lifecycle code and running the full Core and Responses
suites (#49485 was validated with targeted selectors only) needed these
adjustments:
After-restore rollback (Core). The merged lifecycle code snapshots the
whole AgentConfig for rollback and no longer captures the previous session
ID/GUID that the worker-quiesce check compares with the task runtime binding.
The two captures are restored next to the new snapshot. Without them both
rollback paths raised NameError; eight targeted tests caught it.
TaskManager.shutdown(wait_for_workers=False).AgentServer: integrate resilient tasks with memory snapshot session activation #49485 always awaited the
cancelled workers. That made a grace-expired shutdown persist suspended
instead of leaving the record in_progress, which breaks the existing test_grace_expires_treated_like_crash. Waiting is now requested only by the
pre-rollback quiesce; ordinary shutdown keeps its existing contract.
Rollback additionally preserves unfinished records/inputs: it joins workers
under their current binding before expiring leases, allowing the original
task to recover on retry rather than becoming terminal cancellation.
Responses fallback. With FOUNDRY_MEMORY_SNAPSHOT_ENABLED absent or false, a missing
task runtime keeps the existing in-process fallback (the orchestrator already
documents it for in-process clients whose lifespan never runs). The
enabled-but-uninitialized error applies only while startup is deferred (true).
Absence uses the cold-start path directly, including local/in-process clients.
Deferred-start failures remove only the exact caller-scoped execution before
propagating the platform error, rather than retaining work that never started.
Test isolation.test_snapshot_task_activation.py restores os.environ
after each test (a restored session ID leaked into test_tracing.py) and pins
the logger level in its one log assertion (test_logger.py leaves azure.ai.agentserver at ERROR).
Responses tests use a per-test cold-start env fixture instead of global setdefault, so inherited capture-mode configuration cannot change ordinary
tests. Snapshot and absent-mode tests explicitly override that default.
Lint and format. Pragmas or extraction keep the three touched source files
pylint-clean (they are clean on main); _manager.py is reflowed to the
repository's Black width.
Housekeeping. CHANGELOG entries are merged into the existing Core 2.3.0b1 and Responses 2.4.0b1 sections. Responses _version.py and api.metadata.yml no longer change because main already carries 2.4.0b1.
The spec covers lifecycle ordering, trigger/enablement separation, phase retry,
owned runtime cleanup, compatibility, persistence boundaries, validation, and
the unresolved startup-task alternatives.
Implementation
Keep task definitions and Responses task registration in process memory.
FOUNDRY_MEMORY_SNAPSHOT_ENABLED=true defers enabled tasks in capture;
absent/false uses normal cold/local session initialization.
set_resilient_tasks_enabled(False) disables the subsystem at both startup
and after-restore regardless of the environment signal.
After-restore activates requested tasks after session hydration and existing
dependency callbacks, before successful restore commit.
Retain restore-ID initialization phases, serialize startup, and ensure one
periodic recovery scanner.
Preserve immediate best-effort recovery and existing lease/filter/fencing
behavior.
Own late-created runtimes through shutdown and wait for workers to stop before
incompatible configuration rollback.
While startup is deferred, propagate enabled-but-uninitialized Responses
errors instead of silently falling back; intentional resilience opt-out and
cold startup remain non-durable/in-process as before.
Compatibility and scope
Updated launcher contract: every temporary capture sandbox must set the
variable to true. Ordinary cold/local launchers may omit it or set false.
After-restore activates enabled tasks while the captured true value remains;
no flag override is required.
Platform opt-in is separately definition.enable_memory_snapshot, as proposed
by Azure/azure-rest-api-specs#46759. The SDK variable alone does not enable
platform snapshots.
No new HTTP 503 mapping, startup submission queue/replay, public session-start
callback, worker/lease policy, storage backend, or .NET change is included.
Q3 remains open: the spec offers an explicit session-start callback and a
startup launch-intent registry as unselected alternatives.
Controlled wheel labels/strict local-version pins are not published in this PR.
Responses requires the lifecycle-enabled Core version (>=2.3.0b2); no package
release is requested.
Retain the original environment/configuration rollback snapshots when worker
cleanup fails. After pending cleanup succeeds, restore those snapshots before
computing incoming overrides, including when cleanup completed during a
cancelled retry or host shutdown. Clear them only after rollback or successful
restore, so failed values cannot leak into omitted overrides or become the
captured baseline when an override is repeated.
Expanded the cleanup fault matrix to 28 cases, checking omitted/repeated
endpoint overrides and a later restore returning to the original baseline.
Both omission/repetition regressions failed before this fix.
1,276 passed, 64 skipped across the full Core suite and Responses
startup-failure contracts; all 80 activation cases pass.
Black and Python 3.10 mypy pass. Pylint reports only the three unchanged
logging diagnostics in _base.py; no new findings.
This follow-up is locally qualified; the hosted campaign remains pinned to
its earlier source.
Rollback retains reconciliation handles across transient provider read/claim
failures. A later restore finishes shielded cleanup under the original binding
before rehydrating configuration or invoking callbacks, then disposes the
stopped manager before starting a replacement. Ordinary shutdown preserves
pending cleanup rather than discarding queued work.
14 new fault-injection cases pass: read/claim failures once and twice,
a claim committed before its error, same/new restore IDs and GUIDs,
cancellation during cleanup retry, and ordinary shutdown.
The promoted input executes once; the following queued input remains intact.
Repeated successful hooks still reuse the activated runtime.
787 focused tests passed, 51 skipped, covering snapshot lifecycle, all
Core task tests and Responses startup-failure contracts.
After extracting shutdown-handle retention, 98 final focused tests passed,
including all 66 snapshot activation cases.
Black, Python 3.10 mypy and whitespace checks pass. Pylint has no new findings:
four logging diagnostics reproduce unchanged on the previous head.
This follow-up has local fault-injection qualification; the hosted campaign
below remains pinned to its earlier source, not this cleanup-retry fix.
Validated after merging current main, using Core, Responses and Invocations
source from this worktree (no foreign editable-package imports):
Full Core: 1,230 passed, 64 skipped, 0 failed.
Recovery/rollback records the restore ID before startup, owns workers until
they actually finish even after their active task entry disappears, and joins
them before rebinding configuration. A completed steering turn can durably
stage the next queued input as recoverable without executing it during cleanup.
Responses requires Core 2.3.0b2.
Full Responses, with capture env true inherited: 2,309 passed, 83 skipped,
0 failed. The previously reported sample-8 import failures disappeared when
the sibling Invocations source was loaded from the correct worktree.
52 snapshot activation cases pass, including matching-binding retries,
cooperative exits, completed handlers with blocked renewals, queued-input
recovery after normal return, and original task/input recovery. 39 existing cancellation/timeout cases pass.
Sequential lifespans reset startup admission. Rollback reconciles a queued
transition interrupted after turn suspension, claims and expires its lease,
and resumes queued input on retry without executing it during cleanup.
18 Responses contract cases pass with the external snapshot variable
unset and with it set to true. Four new scoped-runtime cleanup cases and
per-test environment isolation failed before their fixes.
Black, pylint and mypy (Python 3.10 target) pass for the changed code.
The startup truth table, restore callback ordering, ordinary shutdown and
explicit task cancellation are unchanged.
West US 2 retest on 72d7822002d8
The fresh r4 controlled-image campaign passed the full matrix on exact source 72d7822002d8a36d14c05f6eacf64bc7385c2e31, including the repeated-lifespan and
interrupted-drain fixes. Core 2.3.0b2, Responses 2.4.0b1 and Invocations 1.2.0 were packaged into fresh immutable images; staged-source, wheel and
runtime hashes matched:
A: 7/7 passed: six resilience/env combinations plus an independent
restored session; actual capture/restore state and loaded source hashes
match; enabled jobs renew leases and disabled cases create no task records.
B passed: stored sync/background, foreground/background streaming,
non-durable store=false streaming, GET/input-items/DELETE, and cancellation
with persisted cancelled state and no reappearance within 30 seconds.
C passed: hard crash after checkpoints 1 and 2; the original task was
autonomously reclaimed with generation 0->1 and a new fenced worker before
GET/new ingress. Recovery read the response-store checkpoint, retained output
IDs/content and executed the remaining phases.
D passed: 360-second quiet interval after completed work, then one
same-session invocation; new restore ID/worker, preserved heap and renewed lease.
Cleanup: 18/18 owned sessions verified idle/stopped; zero failures.
The initial 3-second crash observer missed the short generation-1 reclaim window
before ephemeral task deletion. That evidence was retained; both crash cases
passed on fresh sessions with 250-ms polling and unchanged acceptance criteria.
This does not qualify active jobs crossing idle/freeze, pre-suspend cleanup,
automatic regional service env injection, or a startup launch registry. The
earlier r3 campaign on 16a16b1bae0a also passed, with 16/16 sessions cleaned;
r4 supplies hosted qualification for the latest follow-up fixes.
Earlier contract qualification
Updated capture-only contract (Python 3.14, source imports from this PR):
Core: 1,021 passed, 59 skipped. An initial OTLP gRPC subprocess timeout
passed two isolated reruns and the full rerun.
Responses: 1,865 passed, 83 skipped, with the same two sample-8 import
failures described below.
Targeted suites: 31 Core and 13 Responses cases passed, including all six
enabled/disabled x absent/false/true startup/restore combinations, retained
capture flag with no restore override, and rejection of cross-session
rebinding. Both streaming and non-streaming absent-mode fallbacks pass.
Black with eng/black-pyproject.toml and pylint on changed production code
pass.
Coordinated service tests: 15 focused signal cases, 10,555 HostedAgents and
env-constant tests, and 37 header guards pass.
Earlier West US 2 hosted SDK qualification: 7/7 passed, using immutable images
built from b213b1e71747 and verified loaded Core/Responses source-byte hashes.
All six enabled/disabled x absent/false/true combinations passed, plus a second
true-enabled restored session. Actual before-snapshot/after-restore evidence
showed no capture runtime and retained true; enabled runtime activation followed
restore callbacks. Independent sessions shared the golden heap marker but had
distinct restore/session IDs. Enabled jobs renewed backend leases under the
correct task/owner/native-session scope; disabled cases created no task records.
All seven owned sessions were stopped and verified idle.
The regional task API observations had empty heartbeat fields; renewal was
proved directly by increasing lease expiry for the same in-progress task.
The initial harness false-negative is preserved separately from the fresh
passing run. This qualifies the SDK with controlled-image signals, not
automatic injection by the service PR, which is not regionally deployed.
The table below records the earlier retarget validation, before the capture-only
contract update. Local, Python 3.14, clean environment (no FOUNDRY_MEMORY_SNAPSHOT_ENABLED),
compared against main (037e8b7) in a separate worktree:
Suite
main
This PR
Core tests
990 passed, 59 skipped
1016 passed, 59 skipped
Responses tests
1858 passed, 83 skipped, 2 failed
1862 passed, 83 skipped, 2 failed
Invocations tests
647 passed, 6 skipped
647 passed, 6 skipped
Optimization tests
197 passed
197 passed
Activity tests
95 passed, 11 failed, 1 skipped
95 passed, 11 failed, 1 skipped
The 2 Responses failures (test_sample8_mixin_composition_both_protocols and test_sample_module_imports_and_registers[sample_08_mixin_composition.py]) and
the Activity failures are present on main in this environment and were not
investigated; azure-ai-agentserver-ghcopilot has the same 2 collection errors
on both.
mypy (Python 3.10 target) on Core _base.py and tasks/_manager.py and
Responses hosting/_orchestrator.py: no issues.
pylint (repository pylintrc) on the same three files: no messages, as on main.
git diff --check: clean.
The broader crash/idle/concurrency evidence below comes from an earlier
controlled build and was not re-run for this contract update. The separately
built controlled packages were exercised with the
existing resilient streaming sample in a hosted test:
Cold and initial snapshot activation with real lease acquisition/renewal.
Autonomous hard crash after checkpoints 1 and 2, without a new invocation
during the orphan interval.
Retained golden heap marker, new restore ID/worker, incremented fencing
generation, checkpoint re-entry, and original response completion.
Independent sessions, two concurrent tasks sharing one runtime, and
cancellation without resurrection during the observation window.
Natural idle/resume with a 120-second policy: after six quiet minutes,
same logical session/capture with a new restore ID and worker, renewed
leases, and completed outputs. Management still reported active; runtime
evidence established restoration. Exact suspension timing was not measured.
Those packages predate the final lifecycle prerequisite changes and the revised
capture-only signal contract, so they support the design but do not verify this
exact commit. Startup task submissions remain untested. This is not release
qualification.
…ctivation
Separate process-side task registration from session-bound TaskManager construction and startup, so golden memory snapshots can be captured without a session-bound task runtime and activated after restore.
- FOUNDRY_MEMORY_SNAPSHOT_ENABLED=false starts tasks during ordinary startup; absent or true defers startup to the after-restore hook.
- Checkpoint initialization phases by restore ID, keep best-effort recovery, and wait for owned workers to stop before incompatible configuration rollback.
- Responses propagates enabled-but-uninitialized task errors while activation is deferred and keeps the in-process fallback otherwise.
- Add the design specification and compatibility notes.
Replaces Azure#49485, which was closed when its base branch was deleted after Azure#49217 merged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e5a89f7-9dbe-4a5f-b98a-19c3246dc318
Azure Pipelines:
Successfully started running 1 pipeline(s).
10 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.
Package READMEs are published to PyPI, and the repository link guidance rejects relative links in them. Link to the specification with the same absolute blob/main form the Core README already uses for its other documents.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e5a89f7-9dbe-4a5f-b98a-19c3246dc318
… opt-out
Only true defers enabled tasks until after-restore. Missing and false use ordinary startup. Align Responses fallback, cover all six flag/value combinations and active-session binding guards, and update capture-time signaling design and documentation.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e5a89f7-9dbe-4a5f-b98a-19c3246dc318
Record the materialization restore ID before recovery startup. Retain worker and lease handles before shutdown signalling so cooperative exits cannot bypass joining or lease release. Suppress steering promotion during rollback while preserving queued input for retry. Raise Responses minimum Core version to 2.3.0b2. Add matching-binding, cooperative shutdown, retained renewal and steering rollback regressions; update design and dependency documentation.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e5a89f7-9dbe-4a5f-b98a-19c3246dc318
Track execution, renewal, scanner and watchdog workers independently of active task entries so rollback joins workers whose handlers already completed. Reuse durable steering promotion to stage queued input for recovery without dispatching a new turn during cleanup. Add completed-handler renewal and normal-return queue regressions, and clarify lifecycle guarantees.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e5a89f7-9dbe-4a5f-b98a-19c3246dc318
Reset task shutdown admission when a host enters a new lifespan. After rollback joins workers, reconcile suspended steering chains whose queued-input transition was cancelled. Reuse fenced drain bookkeeping with an explicit inactive lease claim, then expire that lease before restoring configuration. Add sequential lifespan and interrupted-drain regressions without dispatching another turn during cleanup.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e5a89f7-9dbe-4a5f-b98a-19c3246dc318
Retain rollback reconciliation owners across transient storage errors and finish shielded cleanup under the original binding before rehydration or replacement startup. Cover repeated failures, committed claims, cancellation and shutdown without losing queued inputs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e5a89f7-9dbe-4a5f-b98a-19c3246dc318
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Intertwined restore and cancellation paths require human review, and cleanup retries still lose the original environment/configuration rollback snapshots.
Persist original environment and configuration through failed worker cleanup, restoring them before a retry computes its sparse override baseline. Cover omitted and repeated overrides across read/claim failures, cancellation, shutdown and later restores.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e5a89f7-9dbe-4a5f-b98a-19c3246dc318
Move this feature entry to the unreleased 2.3.0b2 Features Added section. It currently advertises capture-time task deferral under 2.3.0b1, although this implementation ships in b2 and Responses explicitly requires b2. This could lead consumers to use b1 expecting the flag to prevent eager task initialization.
Reinitialize disposed runtime before acknowledging cached restores
Runtime disposal leaves completed_restore_ids intact. Reuse a snapshot-enabled host in a second lifespan and send the same successful restore payload: startup defers tasks, then the completed-ID guard returns 200 without recreating the manager or recovery scanner. Resilient requests subsequently fail with TaskManagerNotInitialized. The sequential-lifespan test misses this because each cycle uses a different restore ID. Track runtime activation separately from callback completion, or re-establish the missing runtime before acknowledging cached restore success, without replaying completed callbacks. Add a same-payload lifespan regression.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Separate process-side task registration from session-bound TaskManager
construction/startup for golden memory snapshots.
Replaces #49485. That draft was stacked on
feature/agentserver-core-lifecycle-hooks. GitHub closed it when #49217 mergedand its base branch was deleted, and a closed PR cannot be retargeted or
reopened. This PR carries the same change on
main(based on037e8b7, whichcontains #49217), so nothing is stacked any more.
Differences from #49485
The change is otherwise identical to #49485's final head (
4540307). Rebasingonto the merged lifecycle code and running the full Core and Responses
suites (#49485 was validated with targeted selectors only) needed these
adjustments:
whole
AgentConfigfor rollback and no longer captures the previous sessionID/GUID that the worker-quiesce check compares with the task runtime binding.
The two captures are restored next to the new snapshot. Without them both
rollback paths raised
NameError; eight targeted tests caught it.TaskManager.shutdown(wait_for_workers=False). AgentServer: integrate resilient tasks with memory snapshot session activation #49485 always awaited thecancelled workers. That made a grace-expired shutdown persist
suspendedinstead of leaving the record
in_progress, which breaks the existingtest_grace_expires_treated_like_crash. Waiting is now requested only by thepre-rollback quiesce; ordinary shutdown keeps its existing contract.
Rollback additionally preserves unfinished records/inputs: it joins workers
under their current binding before expiring leases, allowing the original
task to recover on retry rather than becoming terminal cancellation.
FOUNDRY_MEMORY_SNAPSHOT_ENABLEDabsent or false, a missingtask runtime keeps the existing in-process fallback (the orchestrator already
documents it for in-process clients whose lifespan never runs). The
enabled-but-uninitialized error applies only while startup is deferred (
true).Absence uses the cold-start path directly, including local/in-process clients.
Deferred-start failures remove only the exact caller-scoped execution before
propagating the platform error, rather than retaining work that never started.
test_snapshot_task_activation.pyrestoresos.environafter each test (a restored session ID leaked into
test_tracing.py) and pinsthe logger level in its one log assertion (
test_logger.pyleavesazure.ai.agentserveratERROR).Responses tests use a per-test cold-start env fixture instead of global
setdefault, so inherited capture-mode configuration cannot change ordinarytests. Snapshot and absent-mode tests explicitly override that default.
pylint-clean (they are clean on
main);_manager.pyis reflowed to therepository's Black width.
2.3.0b1and Responses2.4.0b1sections. Responses_version.pyandapi.metadata.ymlno longer change becausemainalready carries2.4.0b1.Design specification
Resilient tasks with memory snapshots
The spec covers lifecycle ordering, trigger/enablement separation, phase retry,
owned runtime cleanup, compatibility, persistence boundaries, validation, and
the unresolved startup-task alternatives.
Implementation
FOUNDRY_MEMORY_SNAPSHOT_ENABLED=truedefers enabled tasks in capture;absent/false uses normal cold/local session initialization.
set_resilient_tasks_enabled(False)disables the subsystem at both startupand after-restore regardless of the environment signal.
dependency callbacks, before successful restore commit.
periodic recovery scanner.
behavior.
incompatible configuration rollback.
errors instead of silently falling back; intentional resilience opt-out and
cold startup remain non-durable/in-process as before.
Compatibility and scope
Updated launcher contract: every temporary capture sandbox must set the
variable to true. Ordinary cold/local launchers may omit it or set false.
After-restore activates enabled tasks while the captured true value remains;
no flag override is required.
Coordinate rollout with service PR
https://msdata.visualstudio.com/Vienna/_git/vienna/pullrequest/2357422.
An unmarked capture would initialize enabled tasks eagerly. The earlier SDK
prototype treated absence as deferred, so service and SDK changes must be
reviewed together.
Platform opt-in is separately
definition.enable_memory_snapshot, as proposedby Azure/azure-rest-api-specs#46759. The SDK variable alone does not enable
platform snapshots.
No new HTTP 503 mapping, startup submission queue/replay, public session-start
callback, worker/lease policy, storage backend, or .NET change is included.
Q3 remains open: the spec offers an explicit session-start callback and a
startup launch-intent registry as unselected alternatives.
Controlled wheel labels/strict local-version pins are not published in this PR.
Responses requires the lifecycle-enabled Core version (
>=2.3.0b2); no packagerelease is requested.
Validation
Environment rollback retry fix (October 20,
9f833dca90b4)Retain the original environment/configuration rollback snapshots when worker
cleanup fails. After pending cleanup succeeds, restore those snapshots before
computing incoming overrides, including when cleanup completed during a
cancelled retry or host shutdown. Clear them only after rollback or successful
restore, so failed values cannot leak into omitted overrides or become the
captured baseline when an override is repeated.
endpoint overrides and a later restore returning to the original baseline.
Both omission/repetition regressions failed before this fix.
startup-failure contracts; all 80 activation cases pass.
logging diagnostics in
_base.py; no new findings.its earlier source.
Cleanup failure retry fix (October 20,
c9e8e8139f5b)Rollback retains reconciliation handles across transient provider read/claim
failures. A later restore finishes shielded cleanup under the original binding
before rehydrating configuration or invoking callbacks, then disposes the
stopped manager before starting a replacement. Ordinary shutdown preserves
pending cleanup rather than discarding queued work.
a claim committed before its error, same/new restore IDs and GUIDs,
cancellation during cleanup retry, and ordinary shutdown.
Repeated successful hooks still reuse the activated runtime.
Core task tests and Responses startup-failure contracts.
including all 66 snapshot activation cases.
four logging diagnostics reproduce unchanged on the previous head.
This follow-up has local fault-injection qualification; the hosted campaign
below remains pinned to its earlier source, not this cleanup-retry fix.
Previous full-suite baseline (October 19,
72d7822002d8)Validated after merging current
main, using Core, Responses and Invocationssource from this worktree (no foreign editable-package imports):
they actually finish even after their active task entry disappears, and joins
them before rebinding configuration. A completed steering turn can durably
stage the next queued input as recoverable without executing it during cleanup.
Responses requires Core 2.3.0b2.
trueinherited: 2,309 passed, 83 skipped,0 failed. The previously reported sample-8 import failures disappeared when
the sibling Invocations source was loaded from the correct worktree.
cooperative exits, completed handlers with blocked renewals, queued-input
recovery after normal return, and original task/input recovery.
39 existing cancellation/timeout cases pass.
transition interrupted after turn suspension, claims and expires its lease,
and resumes queued input on retry without executing it during cleanup.
unset and with it set to true. Four new scoped-runtime cleanup cases and
per-test environment isolation failed before their fixes.
The startup truth table, restore callback ordering, ordinary shutdown and
explicit task cancellation are unchanged.
West US 2 retest on
72d7822002d8The fresh r4 controlled-image campaign passed the full matrix on exact source
72d7822002d8a36d14c05f6eacf64bc7385c2e31, including the repeated-lifespan andinterrupted-drain fixes. Core
2.3.0b2, Responses2.4.0b1and Invocations1.2.0were packaged into fresh immutable images; staged-source, wheel andruntime hashes matched:
restored session; actual capture/restore state and loaded source hashes
match; enabled jobs renew leases and disabled cases create no task records.
non-durable
store=falsestreaming, GET/input-items/DELETE, and cancellationwith persisted cancelled state and no reappearance within 30 seconds.
autonomously reclaimed with generation 0->1 and a new fenced worker before
GET/new ingress. Recovery read the response-store checkpoint, retained output
IDs/content and executed the remaining phases.
same-session invocation; new restore ID/worker, preserved heap and renewed lease.
The initial 3-second crash observer missed the short generation-1 reclaim window
before ephemeral task deletion. That evidence was retained; both crash cases
passed on fresh sessions with 250-ms polling and unchanged acceptance criteria.
This does not qualify active jobs crossing idle/freeze, pre-suspend cleanup,
automatic regional service env injection, or a startup launch registry. The
earlier r3 campaign on
16a16b1bae0aalso passed, with 16/16 sessions cleaned;r4 supplies hosted qualification for the latest follow-up fixes.
Earlier contract qualification
Updated capture-only contract (Python 3.14, source imports from this PR):
passed two isolated reruns and the full rerun.
failures described below.
enabled/disabled x absent/false/true startup/restore combinations, retained
capture flag with no restore override, and rejection of cross-session
rebinding. Both streaming and non-streaming absent-mode fallbacks pass.
eng/black-pyproject.tomland pylint on changed production codepass.
env-constant tests, and 37 header guards pass.
Earlier West US 2 hosted SDK qualification: 7/7 passed, using immutable images
built from
b213b1e71747and verified loaded Core/Responses source-byte hashes.All six enabled/disabled x absent/false/true combinations passed, plus a second
true-enabled restored session. Actual before-snapshot/after-restore evidence
showed no capture runtime and retained true; enabled runtime activation followed
restore callbacks. Independent sessions shared the golden heap marker but had
distinct restore/session IDs. Enabled jobs renewed backend leases under the
correct task/owner/native-session scope; disabled cases created no task records.
All seven owned sessions were stopped and verified idle.
The regional task API observations had empty heartbeat fields; renewal was
proved directly by increasing lease expiry for the same in-progress task.
The initial harness false-negative is preserved separately from the fresh
passing run. This qualifies the SDK with controlled-image signals, not
automatic injection by the service PR, which is not regionally deployed.
The table below records the earlier retarget validation, before the capture-only
contract update. Local, Python 3.14, clean environment (no
FOUNDRY_MEMORY_SNAPSHOT_ENABLED),compared against
main(037e8b7) in a separate worktree:mainteststeststeststeststestsThe 2 Responses failures (
test_sample8_mixin_composition_both_protocolsandtest_sample_module_imports_and_registers[sample_08_mixin_composition.py]) andthe Activity failures are present on
mainin this environment and were notinvestigated;
azure-ai-agentserver-ghcopilothas the same 2 collection errorson both.
_base.pyandtasks/_manager.pyandResponses
hosting/_orchestrator.py: no issues.pylintrc) on the same three files: no messages, as onmain.git diff --check: clean.The broader crash/idle/concurrency evidence below comes from an earlier
controlled build and was not re-run for this contract update. The separately
built controlled packages were exercised with the
existing resilient streaming sample in a hosted test:
during the orphan interval.
generation, checkpoint re-entry, and original response completion.
cancellation without resurrection during the observation window.
same logical session/capture with a new restore ID and worker, renewed
leases, and completed outputs. Management still reported active; runtime
evidence established restoration. Exact suspension timing was not measured.
Those packages predate the final lifecycle prerequisite changes and the revised
capture-only signal contract, so they support the design but do not verify this
exact commit. Startup task submissions remain untested. This is not release
qualification.