Skip to content

Merged upstream main into the external stream Core. - #22

Closed
moedash wants to merge 87 commits into
moe/AI-198-if-ext-core-6-channel-wakefrom
moe/AI-198-st-ext-core-unified
Closed

moedash wants to merge 87 commits into
moe/AI-198-if-ext-core-6-channel-wakefrom
moe/AI-198-st-ext-core-unified

Conversation

@moedash

@moedash moedash commented Oct 3, 2026

Copy link
Copy Markdown
Owner

This PR merges upstream main into the external stream Core and adapts the call sites the merge breaks.

What changed?

  • The upstream commits in the list are upstream's own. What's up for review is the merge resolution and the two small commits on top.
  • The merge keeps both sides in five files. managed_run.rs follows upstream's WftFailureKind reporting and keeps the external stream state. The wake Signal filter keeps working with upstream's SignalWorkflow::from((attrs, event_id)). Upstream's dev-server flags for completion pagination stay on. The coverage reporter lists NexusOperationMachine next to the external stream and channel machines.
  • The envelope's compile root moves into upstream's protos list, since upstream gathered the roots into one variable.
  • Five call sites are adapted inside the merge commit, so every commit builds. add_cmd_to_wf_task takes its annotations by value, at the external marker, at the two subscribe and unsubscribe commands Core issues and at the two lang-issued channel arms. The stray-command arm stops naming the variant upstream moves out before it runs.
  • A follow-up commit names the leaked command in that fatal! again, through a binding on the arm.
  • A note at the WorkflowStreamProgress ordering rule says why completion pagination can't move the marker. Pages carry the same command list in order, the server buffers only the intermediate ones, and the final page commits them as one.

Part of AI-198 (epic AI-37).

Why?

The external stream lineage sits on Max's older base, while the native stream commits are written against current upstream main. Merging the same upstream main the main lineage is built on means the native commits replay here without fighting upstream drift. The Python bridge also needs the 1.0 crates from the newer base to compile.

How did you test it?

Link to a test plan if any -

  • Unit Tests
  • Staging
  • End to End Tests

The whole workspace lib suite passes at the head. cargo fmt --check, cargo lint, cargo test-lint and the CI cargo doc check are clean. The tree was compared with the earlier unified branch. The differences are only the older stream api this branch no longer carries, the renumbered channel values and the channel machines aligned with the main lineage.

maciejdudko and others added 30 commits August 14, 2026 11:13
* Prefactor activity execution traits

* Prefactor ephemeral server APIs

* Add SDK test environments

* Address SDK testing review feedback

* self review

* self review: better heartbeating

* fix merge

* fixup merge conflict

* pr feedback

* rename

* add back error msg part

* pr feedback

* support saa
* chore(sdk): release 0.7.0

* Apply suggestions from code review

Co-authored-by: Chris Olszewski <chrisdolszewski@gmail.com>
* feat(client): allow setting memo on workflow start

`WorkflowStartOptions` had no memo field, so there was no way to attach a
memo when starting a workflow from the client. The read side and the
workflow side already exist - continue-as-new can set one, and
`WorkflowExecutionDescription::memo()` reads one back - it was only the
client start path that was missing.

Adds `memo: Option<ProtoMemo>` and wires it into both
`StartWorkflowExecutionRequest` and `SignalWithStartWorkflowExecutionRequest`.

Uses the proto type directly, matching the existing `header: Option<Header>`
field. Both are `map<string, Payload>` and the caller has to convert values
either way. Imported as `ProtoMemo` so it doesn't collide with the
re-exported `temporalio_common::Memo`, which is the read-side wrapper.

Two integ tests in workflow_client_tests.rs: one that a memo set at start
comes back through describe, one that it's empty when unset.

* feat(client): use MemoValues for memo on workflow start

Per review, the client shouldn't ask callers to build the proto Memo
themselves. It now takes `MemoValues`, the same type the workflow surface
already uses for continue-as-new and `upsert_memo`.

`MemoValue`/`MemoValues` move out of `temporalio_workflow` and into
common-wasm, next to the existing `Memo` read wrapper. That's where they
have to go for both sides to reach them... `temporalio_workflow` depends on
common-wasm, not common. Re-exported from `temporalio_common`,
`temporalio_workflow` and `temporalio_sdk`, so existing imports still work.

`MemoValue` holds its value in an `Arc` now instead of an `Rc`, and wants
`Send + Sync`. `WorkflowStartOptions` travels through the interceptor chain
inside a `Send` future and an `Rc` can't cross that. Same shape as
`DataConverter`, which already erases its converters as
`Arc<dyn ... + Send + Sync>`.

Also runs the memo through the payload codec, not just the payload
converter. The read side already codec-decodes it... describe and list both
run `decode_payloads` over the memo. So converter-only encoding broke the
round trip for anyone with a real codec. Caught this after wiring up the
tests below, the two client tests fail without it.

Client unit tests cover start and signal-with-start under a codec, plus the
serialization failure path. Integ tests moved over to `MemoValues`.

* Address review feedback on memo

`MemoValue` implements `TemporalSerializable` instead of exposing a doc
hidden `to_payload`, so callers serialize it through the normal converter
path. It also picks up the caller's serialization context now rather than
hardcoding `Workflow`.

`MemoValues::encode` is gone in favour of documented `get`/`iter`. The
three callers build the payload map themselves. That is a few duplicated
lines each, but nothing doc hidden in the public API.

Test cleanups from the review... dropped the `memo_with` helper, the
`assert_ne!` on the raw bytes that the following assertion already covers,
and the empty-memo integ test that the client unit test covers.

* fixup changelog

---------

Co-authored-by: Chris Olszewski <chrisdolszewski@gmail.com>
* fix(sdk): typed signal_with_start_workflow

* fix: rebase memo fixes
…oralio#1511)

* Stabilize legacy query activation order

* Clarify legacy query ordering comment

SDK-Sentinel-Request: temporalio#1511/comment-5398459129
* Move changelog release notes helper to its own crate

* Select the changelog for release notes
* Allow including LA arguments in marker

* Expose option in Rust SDK
…oralio#1483)

* Add envconfig integration test mode

* Add isolated Cloud namespace helper

* Test envconfig harness in isolated Cloud namespace

* Clarify envconfig snapshot comment

* Move Cloud namespace commands into integration runner
…1525)

Updates the requirements on [base64](https://github.com/marshallpierce/rust-base64) to permit the latest version.
- [Changelog](https://github.com/marshallpierce/rust-base64/blob/master/RELEASE-NOTES.md)
- [Commits](marshallpierce/rust-base64@v0.22.0...v0.23.1)

---
updated-dependencies:
- dependency-name: base64
  dependency-version: 0.23.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…io#1536)

* chore(sdk): mark incoming error as non_exhaustive

* chore(sdk/envconfig): add new SDK owned envconfig structs instead of reexporting from core

* chore(sdk): mark schedule aspects with nonexhaustive

* chore(sdk): remove legacy ActExtiValue

* chore(sdk): move FailOnNondeterminismInterceptor to tests

* chore(sdk): non_exhaust data converter types

* chore(sdk): mark SerializationContext as non_exhaustive

* chore(sdk): make TaskToken bytes private

* chore(sdk): make ActivityCloseTimeouts non exhaustive

* chore(sdk): mark workflow execution info with non_exhaustive

* chore(sdk): WorkerCallbacks is nonexhaustive

* chore(sdk): make Priority and WorkflowDeploymentVersion nonexhaustive

* changelog fixups

* chore(sdk): mark envconfig as non_exhaustive

* fix lint

* fix docs

* .
chris-olszewski and others added 22 commits September 4, 2026 12:01
…nt (temporalio#1584)

* fix(sdk): add sdk owned wrappers for some proto types exposed in client

* self review
* remove public preview warnings

* chore: update release scripts

* flip over to 1.0

* fixup changelog merge
* Add Cloud test exclusion annotation

* Classify integration tests for Cloud

* Run Cloud eligible integration tests in CI
* Respect sticky poller target

* renames

* make target observable, stop sticky before permit acquisition
…mporalio#1601)

Updates the requirements on [wit-bindgen](https://github.com/bytecodealliance/wit-bindgen) to permit the latest version.
- [Release notes](https://github.com/bytecodealliance/wit-bindgen/releases)
- [Commits](bytecodealliance/wit-bindgen@v0.57.1...v0.61.1)

---
updated-dependencies:
- dependency-name: wit-bindgen
  dependency-version: 0.61.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Cancelled and deadline-exceeded polls already retain their slots during
backoff. Keep their targets unchanged so transient failures do not leave
polling concurrency reduced until a later server scale-up.
…o#1608)

`temporalio-common`'s build script emits `payload_visitor_impl.rs` by iterating
`PayloadModel::payload_containing`, a `HashSet<String>`, and orders each message's
fields by iterating `oneof_fields`, a `HashMap<i32, _>`. Both use the default
`RandomState`, which is seeded per process, so the generated file holds the same
implementations in a different order on every build.

The file is a compile input, so its content is part of what a compilation cache
keys on. sccache therefore misses `temporalio-common` on every build, and — because
each miss changes the crate's own output — misses every crate downstream of it too.
In a workspace using the Rust SDK that is `temporalio-client`, `temporalio-sdk-core`
and `temporalio-sdk`, plus the user's own crates that link them.

Collect both into a `Vec` and sort before emitting, matching what the payload-limits
generator in the same file already does for its roots, generated names and oneof
indices.

Validation: five consecutive build-script runs against the patched tree produce
byte-identical `payload_visitor_impl.rs` and `payload_limits_impl.rs`; three runs
against the unpatched tree produce three different files. The generated content is
unchanged — sorting the unpatched output's lines yields the patched output.
* Update API definitions

* Fix API definition update

* Classify callback context as a blob

* Order callback context limit classification
Brings the external stream lineage onto the upstream Core the main lineage is built on, so the
native stream commits replay onto the same base. The merge also adapts the five call sites
upstream broke: `add_cmd_to_wf_task` takes its annotations by value, and the stray-command arm
no longer names the variant upstream moves out before it runs.
Pages carry the same command list in order, only the intermediate ones
are buffered, and the final page merges them, so the completion still
reaches History as one commit.
@moedash

moedash commented Oct 5, 2026

Copy link
Copy Markdown
Owner Author

Replaced by #36 in the v4 series: one lineage through the channel and the interface, with Max's Option 7 prototype replayed onto it. The branch stays as a pin.

@moedash moedash closed this Oct 5, 2026
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.