Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3bea1ec
Document and reproduce the opt-in cross-kind worker wake
durable-workflow-ops Oct 14, 2026
d8f10ca
Bind both wake and sweep to the explicit recipe namespace
durable-workflow-ops Oct 14, 2026
981342a
Merge remote-tracking branch 'origin/main' into rust-325-parity-artif…
durable-workflow-ops Oct 14, 2026
3bbb01e
Wake opted-in mixed workers for scoped queue changes
durable-workflow-ops Oct 14, 2026
c11bd93
Merge branch 'rust-325-parity-artifact-hygiene' into rust-325-cross-k…
durable-workflow-ops Oct 14, 2026
2ca56ad
Bind poll-wake observations to the original workflow run
durable-workflow-ops Oct 14, 2026
90452f2
Integrate qualified memo foundation with scoped poll wake
durable-workflow-ops Oct 14, 2026
29d461b
Qualify poll wake against pending continuation and payload slices
durable-workflow-ops Oct 14, 2026
ec54486
Integrate qualified PHP query source and external consumer profile
durable-workflow-ops Oct 14, 2026
5c0c508
Merge commit '37d1d3dea644793adfe036ac860dd59612faaded' into rust-325…
durable-workflow-ops Oct 14, 2026
4a81a11
Define the next activity completion upload parity slice
durable-workflow-ops Oct 14, 2026
253af8a
Exercise the published activity completion upload lifecycle
durable-workflow-ops Oct 15, 2026
594eb45
Implement scoped activity result completion upload authority
durable-workflow-ops Oct 15, 2026
d503580
Preserve distinct malformed and unsupported completion diagnostics
durable-workflow-ops Oct 15, 2026
de7fb6d
Cover canonical task IDs and namespace boundaries on completion uploads
durable-workflow-ops Oct 15, 2026
a26901b
Bind completion upload allowances to exact stored task identities
durable-workflow-ops Oct 15, 2026
38c99ce
Merge remote-tracking branch 'origin/test/rust-325-external-databases…
durable-workflow-ops Oct 15, 2026
b104775
Accept bounded UTF-8 completion contexts without changing lease identity
durable-workflow-ops Oct 15, 2026
d2bb7ff
Merge remote-tracking branch 'origin/rust-325-cross-kind-poll-wake' i…
durable-workflow-ops Oct 15, 2026
20cadd2
Keep the original Unicode worker identity in the cold reader
durable-workflow-ops Oct 15, 2026
29f5ba8
Compare exact reference fields independently of JSON member order
durable-workflow-ops Oct 15, 2026
1fa1cc2
Merge remote-tracking branch 'origin/test/rust-325-external-databases…
durable-workflow-ops Oct 15, 2026
483a1ca
Merge remote-tracking branch 'origin/rust-325-cross-kind-poll-wake' i…
durable-workflow-ops Oct 15, 2026
7909fc6
Merge remote-tracking branch 'origin/main' into rust-325-activity-com…
durable-workflow-ops Oct 15, 2026
93368d2
Keep the combined stack and remaining upgrade gates explicit
durable-workflow-ops Oct 15, 2026
3a26820
Merge commit 'ed803519000fac6f5b9a5039387e841293f8ecc7' into rust-325…
durable-workflow-ops Oct 15, 2026
8af001f
Separate stalled upload deadlines from fresh capacity controls
durable-workflow-ops Oct 15, 2026
bae0df9
Merge commit '35cd3642825488e5b193260155889e5c4257cd95' into rust-325…
durable-workflow-ops Oct 15, 2026
3409a77
Record the complete failed upload cohort and qualified PHP integration
durable-workflow-ops Oct 15, 2026
e790fe8
Merge commit '1f994962b597e4cd24a4121a8a5c21b9c5ba1d27' into rust-325…
durable-workflow-ops Oct 15, 2026
688ee3e
Record exact qualified PHP source in upload integration
durable-workflow-ops Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/server-parity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ jobs:
-v "$PWD:/source:ro" -w /source "$image" \
scripts/conformance/server-parity/mysql-schema.php compare php_ref native_ref > parity-evidence/catalog-comparison.json
- name: Compare three runtimes, recover killed native nodes and refuse published PHP takeover
id: prepare_runtime_comparison
run: |
set -euo pipefail
image=$(jq -r '.server.images["linux/amd64"] | sub("^durableworkflow/server@"; "ghcr.io/durable-workflow/server@")' tests/Fixtures/ServerParityBaselines/php-2.5.14.json)
Expand Down Expand Up @@ -627,7 +628,7 @@ jobs:
- name: Compare separate configured role-token cohort
run: bash scripts/conformance/server-parity/role-profile.sh mysql
- name: Compare corrected markers, ranges, clocks and activity expiry
if: ${{ !cancelled() }}
if: ${{ !cancelled() && steps.prepare_runtime_comparison.outcome == 'success' }}
# The preceding process-loss case deliberately kills native-a.
run: bash scripts/conformance/server-parity/corrected-marker-shared-profile.sh mysql http://parity-native-b:8080
- name: Retire corrected cohort resources
Expand Down Expand Up @@ -839,6 +840,7 @@ jobs:
-v "$PWD:/source:ro" -w /source "$image" \
scripts/conformance/server-parity/postgres-schema.php compare php_ref native_ref > parity-evidence/catalog-comparison.json
- name: Compare three runtimes, recover killed native nodes and refuse published PHP takeover
id: prepare_runtime_comparison
env:
POSTGRES_IMAGE: ${{ matrix.image }}
run: |
Expand Down Expand Up @@ -1067,7 +1069,7 @@ jobs:
POSTGRES_IMAGE: ${{ matrix.image }}
run: bash scripts/conformance/server-parity/role-profile.sh pgsql
- name: Compare corrected markers, ranges, clocks and activity expiry
if: ${{ !cancelled() }}
if: ${{ !cancelled() && steps.prepare_runtime_comparison.outcome == 'success' }}
env:
POSTGRES_IMAGE: ${{ matrix.image }}
# The preceding process-loss case deliberately kills native-a.
Expand Down Expand Up @@ -1272,6 +1274,7 @@ jobs:
cargo run --locked --offline --example codec-fixtures -- \
../tests/Fixtures/ServerParity/Codec/v1.json /evidence/php-codec.json > parity-evidence/cross-decode.json
- name: Execute and compare Rust, published PHP and embedded fixtures
id: prepare_runtime_comparison
env:
RESOURCE_SCOPE: dw-parity-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }}
run: |
Expand Down Expand Up @@ -1491,7 +1494,7 @@ jobs:
RESOURCE_SCOPE: dw-parity-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }}
run: bash scripts/conformance/server-parity/role-profile.sh sqlite
- name: Compare corrected markers, ranges, clocks and activity expiry
if: ${{ !cancelled() }}
if: ${{ !cancelled() && steps.prepare_runtime_comparison.outcome == 'success' }}
env:
RESOURCE_SCOPE: dw-parity-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }}
run: bash scripts/conformance/server-parity/corrected-marker-shared-profile.sh sqlite http://parity-recovered:8080
Expand Down
107 changes: 69 additions & 38 deletions docs/rust-server-port.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ The unpublished Rust crate has an Avro foundation and an opt-in SQLite/PostgreSQ
execution slice. Full runtime parity, migration, performance improvement and
cutover remain unqualified.

The latest merged foundation is [#450](https://github.com/durable-workflow/server/pull/450),
at `e603a245e`, following #445's memo transaction preparation, #446's bounded
continuation and #448's SDK memo authoring. Each exact candidate tree passes
its own 13-job shared suite across six databases. Separate fresh-main
qualification remains pending; no result is carried across changed trees.
The delivered native foundation is [#450](https://github.com/durable-workflow/server/pull/450),
following memo transactions, activity/continuation replay and SDK memo authoring
in #445/#446/#448. Their exact fresh-main trees pass all 13 shared jobs across
six databases. #446's first failed main query remains failed and unexplained;
its unchanged second attempt reran all 13 jobs, rather than one database.
The consumer runner [#457](https://github.com/durable-workflow/server/pull/457)
is merged as `303ffc633` with its qualified candidate tree. All six candidate
execution logs have 45 passing records; separate fresh-main qualification
[38668891437](https://github.com/durable-workflow/server/actions/runs/38668891437)
remains pending. No result is carried across changed trees.
The merged native development runtime enables memo upserts, while full external
transport discovery stays unadvertised. Frozen published PHP, embedded and SDK tuples
remain separate from current PHP release work. Representative timer, signal,
Expand All @@ -20,45 +25,54 @@ failed; later qualifying runs are separate observations.

## Work order and current status

The active integration order is:

- [#445](https://github.com/durable-workflow/server/pull/445): canonical memo
transaction foundation merged `bb199cb71`; its separate fresh-main 13-job
qualification passes in 38645794230, with every database log audited.
This preparation kept the memo-update gate disabled.
- [#446](https://github.com/durable-workflow/server/pull/446): cold continue-as-new
after a genuine activity, merged `dff9e846`. Its identical whole tree passes
all 13 candidate jobs after one unchanged MariaDB retry. The original hosted
runner loss remains failed without an established cause. Fresh main is pending.
- [#448](https://github.com/durable-workflow/server/pull/448): actual SDK memo
authoring and continuation inheritance, merged `284f5b822`. Its exact whole
tree passes all 13 candidate jobs and required source checks. Fresh main and
external-memo policy remain pending.
- [#450](https://github.com/durable-workflow/server/pull/450): verified local
external input, workflow/activity results and activity arguments. Installed
PHP/native originals, including a two-activity batch and cold parent, complete.
Two-reference atomic rollback/cold delivery controls pass. Its exact whole
tree is merged as `e603a245e` after all 13 candidate jobs and required source
checks pass. Fresh main is pending. Those regression jobs do not imply new
external-consumer execution on every database. One local 100 ms transfer control
failed; three isolated controls and an unchanged full repeat pass, with the
original cause still unknown.
The pending #455/#458 stack will be promoted through #458 after its combined
main candidate passes all required checks. This delivers the reviewed parent
in the same tested main tree. Earlier admitted matrices remain separate
observations and continue; strict branch protection is preserved.

- [#455](https://github.com/durable-workflow/server/pull/455): opt-in,
namespace/queue-scoped null-task poll wake. Its combined matrix remains
pending. An earlier component's SQLite PHP target failed after an activity
namespace/queue-scoped null-task poll hint without claim or lease authority.
The earlier component passes all 13 jobs in 38647001027. Current combined
qualification remains pending in #458. Both PHP query middleware additions
and combined OpenAPI revision 55 stay intact. An earlier component failed after an activity
completion response when the Rust actor's registration DELETE returned
lock-pressure 503; later refusal/repair phases were not reached. That original
stays failed. Idle/query cost and matched performance remain open.
- [#457](https://github.com/durable-workflow/server/pull/457): extend the actual
installed external consumers to separate PHP/native databases in all six
configurations. Its first local SQLite recipe completes five originals per
target and cold reads with exact typed values. Other database execution,
final-head hosted qualification and promotion remain pending. This does not
qualify automatic policy, S3 or completion-upload authority.
- [#458](https://github.com/durable-workflow/server/pull/458): version-1 activity
result completion uploads, combined with the parent poll hints. It has 70
passing library tests (18 explicit ignores), 113 SQLite HTTP cases and three
focused authority/race controls on MySQL 8.4 and PostgreSQL 17. Actual 36
published-PHP/native originals and strict readers pass across those three
local databases with genuine Unicode ownership, original deadlines, exact
payload hashes and cold parent completion. Full current-main/all-six
qualification and promotion remain pending. Initial Unicode, MySQL identity,
JSON member-order and 100ms control failures stay recorded in the PR.
The complete combined `3a268200` run `38680689284` includes qualified PHP
`ed803519`, passes twelve jobs and fails PostgreSQL 17 at the independent
fresh upload still using the preceding stalled request's 100 ms test policy.
All six small execution summaries were independently read: five cells pass
113 execution tests; PostgreSQL 17 has 112 passes and that one failure.
That original remains failed.
The next fixture revision keeps the stalled deadline and shared semaphore,
then uses normal policy for the separate fresh upload. Recovered-target
checks will require their actual preparation step to succeed, preventing
dependent absence from looking like an execution failure. The next combined
source also integrates separately qualified PHP empty-command-contract
correction `35cd3642`; it needs its own full qualification.
No workflow/query/prepared
context, pressure-bypass or full transport capability is advertised.
- [#460](https://github.com/durable-workflow/server/pull/460): read-only upgrade
source inventory. Four actual published PHP 2.8.0 profiles pass locally, with
eight original pending runs, twelve refusals and unchanged source state.
WAL SQLite refuses before opening; all backup/quiescence/representation/
takeover flags remain false. Combined hosted qualification and actual
conversion/backup/continuation gates remain ahead.

Full transport discovery stays unadvertised. Complete batch workflow semantics,
memo/query reference ingress, upload allowances, automatic result policy, S3,
cleanup/backup/restart and full database/consumer qualification remain open.
Current PHP 2.8 query-authority and activity-result-inspection parity also
require separate native qualification.
Broader runtime/operational parity, safe sequential PHP database takeover,
matched performance measurements and release/cutover preparation remain #325
requirements. No native release or deployment is qualified.
Expand Down Expand Up @@ -317,8 +331,17 @@ exact outputs and zero task repairs. They do not qualify a performance gain:
PHP has two idle API timeouts and a forced scheduler shutdown, while native
workflow tails vary. The original idle reader also rejects protocol-permitted
`timeout` replies. Separate reader and scheduler controls pass, with original
failures preserved. Next diagnose native tails with a bounded published-worker
control, then repeat the corrected matched profile before a gain claim.
failures preserved. Separate installed-worker controls identify a native poll
wake gap: published PHP interrupts an opted-in activity/query wait when new
workflow work arrives, while the native baseline consumes the remaining waits.
This does not establish the cause of every earlier tail. The
[scoped correction in #455](../scripts/conformance/server-parity/CROSS-KIND-POLL-WAKE.md)
keeps task/lease authority in ordinary claims. Its five focused HTTP test groups
pass locally on SQLite, PostgreSQL 17 and MySQL 8.4; the unchanged native baseline
fails all three positive groups. Installed-worker activity/query controls also
pass on PHP and native SQLite with the original workflow/run identities.
Six-cell qualification of the new combined tree remains required before
repeating the corrected matched profile or claiming a gain.

The #444 original MySQL 8.4 matrix on `95cd4efa` exposed a native activity
clock disagreement: a retry was recorded 101 ms before its durable
Expand Down Expand Up @@ -2880,3 +2903,11 @@ final result; native keeps those inline under its unadvertised automatic policy.
Both containers stop with 137 and no OOM. All local databases, provider objects,
SDK dependencies, compiler output and task resources are removed after this
audit. Hosted all-database external semantics remain pending.

The upload/poll-hint candidate now incorporates exact qualified PHP source
`1f994962` and its `applyStickyCacheClaim` primary-key correction, including
the current PHP release metadata and numeric declaration normalization. Its
WorkerController bytes match the qualified PHP handoff. This combined tree
requires fresh normal and six-database qualification. The preceding `3409a776`
component pass, its MySQL-only retry, and all failed originals remain their
separate records; none qualifies this integration or a native release.
20 changes: 18 additions & 2 deletions resources/platform-protocol-specs/worker-protocol-api.openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: durable-workflow.v2.worker-protocol-api
version: "54"
version: "55"
summary: Durable Workflow worker-plane HTTP+JSON API
description: >
Normative OpenAPI specification for the worker-plane HTTP+JSON API:
Expand All @@ -23,6 +23,14 @@ x-durable-workflow-catalog-entry: worker_protocol_api
x-durable-workflow-catalog-schema: durable-workflow.v2.platform-protocol-specs.catalog
x-durable-workflow-catalog-version: 16
x-durable-workflow-evolution-rule: additive_minor_breaking_major
x-durable-workflow-cross-kind-poll-wake:
opt_in_worker_capability: cross_kind_poll_wake
scope: [namespace, task_queue]
reply: { task: null, poll_status: task_queue_changed }
authority: hint_only
allocates_task_or_lease: false
changes_acceptance_or_deadline: false
non_opted_workers: preserve_existing_behavior
x-durable-workflow-cancellation-scope-admission:
minimum_protocol_version: "1.20"
status: unfrozen_candidate_membership_only
Expand Down Expand Up @@ -1965,7 +1973,15 @@ components:
required: [task]
properties:
task: { type: "null" }
poll_status: { type: string, enum: [timeout, empty] }
poll_status:
type: string
enum: [timeout, empty, task_queue_changed]
description: >
task_queue_changed is an optional hint for workers registered
with cross_kind_poll_wake. It interrupts an empty wait after
work is published in that namespace and task queue so the worker
can sweep its task kinds again. It grants no task, lease or
acceptance authority and does not renew an existing deadline.
DrainingPoll:
allOf:
- $ref: "#/components/schemas/WorkerEnvelope"
Expand Down
11 changes: 7 additions & 4 deletions rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,9 @@ The development external-payload routes upload/fetch verified encoded bytes at
`/api/external-payloads/v1`, with authenticated namespace binding, local policy,
object/byte quota admission and an independent request size/timeout bound.
`PUT /api/namespaces/{namespace}/external-storage` is admin-only and currently
supports the local driver. Completion-upload allowance headers refuse until
their original task/lease authority is implemented. Full transport discovery
supports the local driver. Version-1 activity-result completion uploads require
the original task/attempt/owner and preserve a bounded allowance without renewing
the lease. Workflow/query/prepared completion contexts remain refused. Full transport discovery
stays unadvertised pending real workflow resolution/retention, cleanup/backup,
restart, all database families and S3 qualification. The actual byte probe is
`scripts/conformance/server-parity/external-payload-http.py`; run it only against
Expand All @@ -300,8 +301,10 @@ result-upload/public task-completion recipe and separate cold SDK reader are in
`scripts/conformance/server-parity/external-result-client.php`. Its
`activity-author` and `activity-reader` phases use explicit activity-result HTTP
completion and a separate installed SDK workflow-history reader. These recipes
do not establish automatic SDK upload discovery. Memo/query ingress,
completion-upload allowances and automatic external result policy remain
do not establish automatic SDK upload discovery. The separate raw HTTP recipe
`scripts/conformance/server-parity/activity-completion-upload-probe.php` covers
the activity completion-upload context, including real UTF-8 JSON. Memo/query
ingress, broader completion contexts and automatic external result policy remain
unqualified. Apache's schema-aware validation patch is recorded in
`vendor/apache-avro/PATCHES.md`.

Expand Down
Loading
Loading