Skip to content

chore(release): 0.30.3 - #1043

Closed
client-software-ci wants to merge 2 commits into
mainlinefrom
bump/0.30.3
Closed

chore(release): 0.30.3#1043
client-software-ci wants to merge 2 commits into
mainlinefrom
bump/0.30.3

Conversation

@client-software-ci

@client-software-ci client-software-ci commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

0.30.3 (2026-08-10)

Features

Bug Fixes

Signed-off-by: client-software-ci <129794699+client-software-ci@users.noreply.github.com>
@client-software-ci
client-software-ci requested a review from a team as a code owner August 10, 2026 17:18
@github-actions github-actions Bot added the waiting-on-maintainers Waiting on the maintainers to review. label Aug 10, 2026
Comment thread CHANGELOG.md Outdated
Comment on lines +12 to +14
* Fixed the agent terminating on transient network errors (connection closed, connect timeout, endpoint connection, read timeout) during UpdateWorkerSchedule calls. These are now retried with exponential backoff. (`af02f3f`)
* Fixed an unrecoverable error exit when credentials expire mid-flight due to machine hibernate/sleep. The agent now detects the time-jump scenario and retries with bootstrap credentials. (`528cd41`)
* Fixed the service's `runtimeHint` wire values (`pythonexpr` and `rust`) not being recognized. They are now correctly mapped to the corresponding session runtimes. (`ddca05f`)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why there are only hash id but not PR link for these commits?

Comment thread CHANGELOG.md Outdated
### Features
* Added a Rust session runtime adapter, allowing sessions to run using the OpenJD v1 Rust runtime in addition to the existing Python runtime. (#1002)
* The worker agent now consumes the `runtimeHint` from UpdateWorkerSchedule responses to select the session runtime (Python or Rust) per session. The service can signal which runtime to use; absent hints default to Python. (#1016)
* Added `select_runtime()` to resolve session runtime mode based on configuration (`python`, `rust`, or `service-selected`) and the service's runtime hint. (`d38c21c`)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why there are only hash id but not PR link for this?

Comment thread CHANGELOG.md
## 0.30.3 (2026-08-10)

### Features
* Added a Rust session runtime adapter, allowing sessions to run using the OpenJD v1 Rust runtime in addition to the existing Python runtime. (#1002)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These release notes omit the required-dependency floor raises that ship with 0.30.3. Between 290e493 (0.30.2) and this commit, pyproject.toml changed:

  • openjd-model: >= 0.8.1, < 0.11>= 0.11.1, < 0.12
  • openjd-sessions: == 0.10.10== 0.10.13
  • deadline-job-attachments: == 0.1.2== 0.1.3

The openjd-model change is the notable one: it raises the minimum across two minor versions, so anyone installing the worker agent into an environment that also pins openjd-model < 0.11 (a constraint that was valid for every prior release) will now get a resolution conflict on upgrade rather than a working install. That is exactly the kind of thing a reader consults a changelog for, and it is not derivable from any entry here.

Suggest adding a line under Features (or a ### Dependencies subsection) noting the openjd-model minimum moved to >= 0.11.1, < 0.12.

Comment thread CHANGELOG.md

### Features
* Added a Rust session runtime adapter, allowing sessions to run using the OpenJD v1 Rust runtime in addition to the existing Python runtime. (#1002)
* The worker agent now consumes the `runtimeHint` from UpdateWorkerSchedule responses to select the session runtime (Python or Rust) per session. The service can signal which runtime to use; absent hints default to Python. (#1016)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This release makes the session_runtime setting take effect for the first time, and that is a silent behavior change on upgrade that the notes do not mention.

At 0.30.2 (290e493), session_runtime was already documented in worker.toml.example and already parsed by config/config_file.py and --session-runtime in config/cli_args.py — but startup/entrypoint.py never forwarded it, Worker.__init__ had no such parameter, and scheduler.py contained no reference to runtime at all. So on 0.30.2 a user could set session_runtime = "rust" (or "service-selected") and it was accepted and completely inert. 03f9ef7 wires it through (entrypoint.py:203, worker.py:97), so that same unchanged worker.toml now actually switches the session backend on upgrade to 0.30.3.

Anyone who set the value while experimenting on 0.30.1/0.30.2 and saw no effect will get a runtime switch they did not ask for in this release. Worth an explicit note — the current Features entries read as "a new capability was added", not "an existing config key that was previously ignored now takes effect".

Comment thread CHANGELOG.md
* Runtime selection and failure telemetry events are now emitted (opt-out respected via `[telemetry] opt_out` in worker.toml), providing visibility into which runtime is chosen and any selection/construction failures. (#1021)

### Bug Fixes
* Fixed `step_name` not being passed through to `run_task`, which caused jobs with wrap environments to fail because OpenJD could not resolve `WrappedStep.Name`. (#1039)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This entry says the missing step_name "caused jobs with wrap environments to fail", which reads as a defect users hit in 0.30.2 and earlier. The commit message for 66ecb5c says otherwise:

No wrap-action job can reach either runtime today, since the service does not yet accept extension requests at job submission.

So the code path was latent, not reachable. Recommend softening to something like "step_name is now threaded through to run_task so OpenJD can resolve WrappedStep.Name for wrap environments" and dropping the claim that jobs were failing — otherwise operators will go looking for failures in their fleet history that cannot have occurred.

Comment thread CHANGELOG.md
* Added a Rust session runtime adapter, allowing sessions to run using the OpenJD v1 Rust runtime in addition to the existing Python runtime. (#1002)
* The worker agent now consumes the `runtimeHint` from UpdateWorkerSchedule responses to select the session runtime (Python or Rust) per session. The service can signal which runtime to use; absent hints default to Python. (#1016)
* Added `select_runtime()` to resolve session runtime mode based on configuration (`python`, `rust`, or `service-selected`) and the service's runtime hint. (`d38c21c`)
* Runtime selection and failure telemetry events are now emitted (opt-out respected via `[telemetry] opt_out` in worker.toml), providing visibility into which runtime is chosen and any selection/construction failures. (#1021)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The telemetry entry describes the purpose of the new events but not what they transmit, and the new events carry identifiers that prior worker-agent telemetry did not send.

record_runtime_selection_telemetry_event / record_runtime_failure_telemetry_event (aws/deadline/__init__.py:919 and :952) both include farm_id, queue_id, session_id, and region in event_details. At 0.30.2 the telemetry surface in that module carried queue_id only (_record_attachment_download_filesystem_event, record_sync_inputs_telemetry_event, record_sync_outputs_telemetry_event); farm_id, session_id, and region are new to telemetry with this release.

For a public agent where telemetry is on by default and opt-out is the user's responsibility, the set of identifiers leaving the host is the material fact — "providing visibility into which runtime is chosen" understates it. Suggest naming the fields in the entry so operators can make an informed opt-out decision without reading the source.

Credit where due: the implementation is careful about not leaking free text — the scheduler deliberately sends a constant failure_reason for bad hints and only OSError.strerror (never str(e)) for construction failures, with a comment explaining the path-as-PII risk (scheduler/scheduler.py:1189 and :1263), plus a 200-char cap. This note is only about the identifier fields.

Comment thread CHANGELOG.md Outdated
* Fixed `step_name` not being passed through to `run_task`, which caused jobs with wrap environments to fail because OpenJD could not resolve `WrappedStep.Name`. (#1039)
* Fixed `step_name` not being forwarded on the Rust runtime path, so `WrappedStep.Name` now resolves correctly for Rust sessions as well. (#1040)
* Fixed the agent terminating on transient network errors (connection closed, connect timeout, endpoint connection, read timeout) during UpdateWorkerSchedule calls. These are now retried with exponential backoff. (`af02f3f`)
* Fixed an unrecoverable error exit when credentials expire mid-flight due to machine hibernate/sleep. The agent now detects the time-jump scenario and retries with bootstrap credentials. (`528cd41`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The agent now detects the time-jump scenario" overstates what 528cd41 implements, and the commit author says so in an in-code note (aws_credentials/worker_boto3_session.py):

are_expired() is a heuristic, not proof of the failure's cause. We can't tell from the error alone whether it was caused by expiry, so we infer it from the clock. A genuine AccessDeniedException (e.g. policy change, role deletion) that happens to coincide with expiry will also be retried here rather than surfacing immediately.

The condition is credentials_object.are_expired() and session is not self._bootstrap_session — a clock check, not detection of a time jump. The user-visible consequence runs the other way from what the entry implies: a real permissions failure (fleet role policy revoked, role deleted) that lands near the credential expiry boundary is now retried against bootstrap credentials instead of surfacing immediately, which can turn a crisp AccessDeniedException into a more confusing second failure. Someone debugging a broken IAM policy would want to know that.

Suggest wording closer to the code, e.g. "if fleet-role credentials are found to have expired after a failed refresh, the agent retries once using bootstrap credentials," and dropping "detects the time-jump scenario."

Comment thread CHANGELOG.md Outdated
### Bug Fixes
* Fixed `step_name` not being passed through to `run_task`, which caused jobs with wrap environments to fail because OpenJD could not resolve `WrappedStep.Name`. (#1039)
* Fixed `step_name` not being forwarded on the Rust runtime path, so `WrappedStep.Name` now resolves correctly for Rust sessions as well. (#1040)
* Fixed the agent terminating on transient network errors (connection closed, connect timeout, endpoint connection, read timeout) during UpdateWorkerSchedule calls. These are now retried with exponential backoff. (`af02f3f`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This entry lists four specific error types, but af02f3f does not match on those four — it catches two botocore base classes:

_TRANSIENT_NETWORK_EXCEPTIONS = (BotocoreConnectionError, HTTPClientError)

Per the implementation's own comment (aws/deadline/__init__.py:51), that also covers ResponseStreamingError, ProxyConnectionError, and SSLError. SSLError is the one worth calling out: a persistent TLS problem (expired CA bundle, cert verification failure, MITM proxy) is not transient, and it will now be retried 5 times with backoff before surfacing rather than failing fast. That is a defensible tradeoff, but the changelog's four-item list tells an operator their TLS misconfiguration still fails immediately, which is no longer true.

Suggest describing the actual scope ("transport-level botocore errors — connection failures, timeouts, streaming and TLS errors — are now retried up to 5 times with exponential backoff") rather than enumerating a subset.

Signed-off-by: Sean Tang <171081544+seant-aws@users.noreply.github.com>
Comment thread CHANGELOG.md
* Fixed `step_name` not being forwarded on the Rust runtime path, so `WrappedStep.Name` now resolves correctly for Rust sessions as well. (#1040)
* Fixed the agent terminating on transient network errors (connection closed, connect timeout, endpoint connection, read timeout) during UpdateWorkerSchedule calls. These are now retried with exponential backoff. (#1013)
* Fixed an unrecoverable error exit when credentials expire mid-flight due to machine hibernate/sleep. The agent now detects the time-jump scenario and retries with bootstrap credentials. (#1014)
* Fixed the service's `runtimeHint` wire values (`pythonexpr` and `rust`) not being recognized. They are now correctly mapped to the corresponding session runtimes. (#1009)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that this entry is attributed to a PR instead of a bare hash, it is visible that it cites the same PR as the select_runtime() feature entry on line 6 — and that makes it a bug fix for a defect no user could have encountered.

PR #1009 landed as two commits: d38c21c ("add select_runtime()") and ddca05f ("accept service RuntimeMode wire values as runtimeHint"). d38c21c's parent is 290e493, the 0.30.2 release commit, so the incorrect runtimeHint wire-value mapping was introduced after 0.30.2 and corrected within the same unreleased PR. It was never present in any published version.

Listing it under ### Bug Fixes tells operators that a version they may be running mis-handles pythonexpr/rust hints and that upgrading fixes it. Neither is true — 0.30.2 and earlier had no runtimeHint handling at all. Suggest folding the correct wire values into the line 6 feature entry (e.g. note that select_runtime() maps the service's pythonexpr and rust values) and dropping this line, so the two entries do not describe one PR as both a feature and a regression fix.

Comment thread CHANGELOG.md

### Bug Fixes
* Fixed `step_name` not being passed through to `run_task`, which caused jobs with wrap environments to fail because OpenJD could not resolve `WrappedStep.Name`. (#1039)
* Fixed `step_name` not being forwarded on the Rust runtime path, so `WrappedStep.Name` now resolves correctly for Rust sessions as well. (#1040)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same category as the #1009 duplication on line 14: this is listed as a bug fix, but the code it fixes was introduced in this very release and never shipped.

The Rust runtime path did not exist in 0.30.2 — the adapter arrived in 5262f98 (#1002), which is itself a ### Features entry on line 4 of this same release. So "step_name not being forwarded on the Rust runtime path" was a defect that existed only between two unreleased commits. There is no published version where a user could observe it, and nothing to "fix" from their perspective.

Combined with line 10 (already noted separately), the Bug Fixes section currently reads as though 0.30.3 repairs two step_name/WrappedStep.Name regressions in the field, when one path is brand new in this release and the other is unreachable. Suggest dropping this entry and letting the #1002 feature entry describe the Rust adapter as shipping complete.

Comment thread CHANGELOG.md
## 0.30.3 (2026-08-10)

### Features
* Added a Rust session runtime adapter, allowing sessions to run using the OpenJD v1 Rust runtime in addition to the existing Python runtime. (#1002)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This entry presents the Rust runtime as simply available, but it can be absent at runtime and the failure mode is deliberately hard — worth a caveat here.

rust.py imports openjd._openjd_rs, openjd.expr, openjd.sessions._v1, and openjd.model._v1, while pyproject.toml declares only openjd-sessions == 0.10.13 and openjd-model >= 0.11.1, < 0.12 with no extra for the binding, and neither README nor DEVELOPMENT.md documents how to obtain it. The design anticipates it being missing: _factory.py:40 wraps the import and raises NotImplementedError, and test_import_failure.py explicitly asserts there is no silent downgrade to Python (test_rust_import_failure_does_not_fall_back_to_python).

The consequence for an operator: setting session_runtime = "rust" on a host where the binding is unavailable does not degrade to Python — scheduler.py:1248 catches the NotImplementedError, calls _fail_all_actions, and continues. Every session that worker picks up fails, one after another, while the agent stays up and keeps claiming work. That is a reasonable design choice, but it is the opposite of what "in addition to the existing Python runtime" suggests, and a reader deciding whether to flip the setting will not discover it from these notes.

Suggest a sentence stating the requirement (or that the setting is opt-in/experimental) and that sessions fail rather than falling back when the runtime is unavailable. Same applies to worker.toml.example, where the "rust" option is listed with no prerequisite.

Comment thread CHANGELOG.md
### Bug Fixes
* Fixed `step_name` not being passed through to `run_task`, which caused jobs with wrap environments to fail because OpenJD could not resolve `WrappedStep.Name`. (#1039)
* Fixed `step_name` not being forwarded on the Rust runtime path, so `WrappedStep.Name` now resolves correctly for Rust sessions as well. (#1040)
* Fixed the agent terminating on transient network errors (connection closed, connect timeout, endpoint connection, read timeout) during UpdateWorkerSchedule calls. These are now retried with exponential backoff. (#1013)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parenthesised list understates the scope of what is now retried, and one omission is operationally significant.

The implementation does not enumerate those four leaf types — it catches two botocore base classes (aws/deadline/__init__.py:57):

_TRANSIENT_NETWORK_EXCEPTIONS = (BotocoreConnectionError, HTTPClientError)

Per the comment directly above it, that also covers ResponseStreamingError and, notably, SSLError (a botocore.exceptions.ConnectionError subclass). A persistent TLS failure — expired/untrusted CA bundle, a misconfigured TLS-terminating proxy — is not a transient blip; it now consumes 5 retries (~15s per the comment at :60) on every UpdateWorkerSchedule cycle and surfaces as a repeating "Transient network error" warning rather than a clear TLS misconfiguration error. An operator debugging a proxy or certificate problem, reading this changelog line, would not expect certificate errors to be in scope.

Also worth noting for readers: the retry budget is finite. After _MAX_TRANSIENT_NETWORK_RETRIES the code still raises DeadlineRequestUnrecoverableError (:216), so the agent does terminate on a sustained outage — "the agent no longer terminates on transient network errors" is true only for outages shorter than the window. Suggest saying "transport-level connection and timeout errors" rather than the four-item list, and mentioning the bounded retry window.

Comment thread CHANGELOG.md
* Fixed `step_name` not being passed through to `run_task`, which caused jobs with wrap environments to fail because OpenJD could not resolve `WrappedStep.Name`. (#1039)
* Fixed `step_name` not being forwarded on the Rust runtime path, so `WrappedStep.Name` now resolves correctly for Rust sessions as well. (#1040)
* Fixed the agent terminating on transient network errors (connection closed, connect timeout, endpoint connection, read timeout) during UpdateWorkerSchedule calls. These are now retried with exponential backoff. (#1013)
* Fixed an unrecoverable error exit when credentials expire mid-flight due to machine hibernate/sleep. The agent now detects the time-jump scenario and retries with bootstrap credentials. (#1014)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The agent now detects the time-jump scenario" claims a precision the implementation explicitly disclaims, and the difference matters for anyone diagnosing an auth failure.

worker_boto3_session.py retries whenever credentials_object.are_expired() happens to be true at the moment DeadlineRequestUnrecoverableError is caught, and the author documented exactly what that does and does not mean:

NOTE: are_expired() is a heuristic, not proof of the failure's cause. We can't tell from the error alone whether it was caused by expiry, so we infer it from the clock. A genuine AccessDeniedException (e.g. policy change, role deletion) that happens to coincide with expiry will also be retried here rather than surfacing immediately.

So a real IAM problem — fleet role deleted, trust policy edited, permission boundary tightened — that lands near a credential expiry boundary is now silently retried with bootstrap credentials and logged as "possible hibernate/sleep", instead of surfacing as the access-denied error it is. Bootstrap credentials often carry different permissions than the fleet role, so the retry may even succeed and mask a misconfiguration that will resurface later.

Suggest matching the code's own hedging: "…retries with bootstrap credentials when credentials are found to have expired during the call" and dropping "detects the time-jump scenario". Operators who see the new warning should know it can also mean a genuine permissions failure.

Comment thread CHANGELOG.md
* Added a Rust session runtime adapter, allowing sessions to run using the OpenJD v1 Rust runtime in addition to the existing Python runtime. (#1002)
* The worker agent now consumes the `runtimeHint` from UpdateWorkerSchedule responses to select the session runtime (Python or Rust) per session. The service can signal which runtime to use; absent hints default to Python. (#1016)
* Added `select_runtime()` to resolve session runtime mode based on configuration (`python`, `rust`, or `service-selected`) and the service's runtime hint. (#1009)
* Runtime selection and failure telemetry events are now emitted (opt-out respected via `[telemetry] opt_out` in worker.toml), providing visibility into which runtime is chosen and any selection/construction failures. (#1021)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One gap in the otherwise careful PII handling behind this entry, worth flagging while the release is still open: runtime_hint is forwarded to telemetry raw and unbounded.

failure_reason is capped (aws/deadline/__init__.py:974):

"failure_reason": failure_reason[:_FAILURE_REASON_MAX_LEN],   # 200

but runtime_hint in the same event_details dict gets no cap and no validation, in both new events (:942 and :976). Its value originates from session_spec["metadata"]["runtimeHint"] (scheduler/scheduler.py:1170) — a service-supplied string the worker treats as opaque. _select.py validates it only as a dict-key lookup and, on the failure path, scheduler.py:1195 passes the rejected value through deliberately ("the offending value is already carried verbatim in the runtime_hint field").

That is exactly the path where the value is known not to be one of pythonexpr/rust. So the one branch that forwards an arbitrary, unvalidated string is the one with no length bound — a malformed or oversized runtimeHint (version skew, a service bug, a corrupted response) is relayed verbatim to the telemetry endpoint. The 200-char cap applied next to it shows the bound was considered worthwhile for the other free-form field.

Applying [:_FAILURE_REASON_MAX_LEN] to runtime_hint too (or a dedicated small cap, since valid values are under 12 chars) would close it. Low severity — the source is the Deadline service, not an end user — but it is cheap and the surrounding code already sets the precedent.

Comment thread CHANGELOG.md
* Fixed the agent terminating on transient network errors (connection closed, connect timeout, endpoint connection, read timeout) during UpdateWorkerSchedule calls. These are now retried with exponential backoff. (#1013)
* Fixed an unrecoverable error exit when credentials expire mid-flight due to machine hibernate/sleep. The agent now detects the time-jump scenario and retries with bootstrap credentials. (#1014)
* Fixed the service's `runtimeHint` wire values (`pythonexpr` and `rust`) not being recognized. They are now correctly mapped to the corresponding session runtimes. (#1009)
* Rust runtime panics (BaseException from PyO3) no longer kill the session thread silently. They are now converted to `SessionRuntimeCrashError` at the adapter boundary, allowing proper failure reporting and cleanup. (#1026)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing blank line between the last bullet and the ## 0.30.2 heading that follows on line 16. Every other section boundary in this file follows the same pattern (0.30.20.30.1 at line 22-23, 0.30.00.29.2 at line 38-39), so this is pre-existing generator behavior rather than something introduced here — but since this release block is being hand-edited anyway, adding the newline is free.

Some strict CommonMark renderers require a blank line before an ATX heading that directly follows a list item, in which case ## 0.30.2 (2026-07-14) renders as literal text appended to the last bullet instead of as a heading. GitHub tolerates it; other changelog consumers may not.

@seant-aws seant-aws closed this Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-on-maintainers Waiting on the maintainers to review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants