From 398d73f9ced2528a7ee4f25efe16c7751e64c001 Mon Sep 17 00:00:00 2001
From: Richard McDaniel <1130888+rmcdaniel@users.noreply.github.com>
Date: Fri, 13 Nov 2026 14:28:47 +0000
Subject: [PATCH 1/2] Document qualified PHP 3.18.1 and native storage
admission
---
docs/polyglot/php.md | 25 +++++++++++++++++++++
docs/polyglot/server-config-reference.md | 28 +++++++++++++++++++-----
static/stable-releases.json | 2 +-
3 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/docs/polyglot/php.md b/docs/polyglot/php.md
index 8e9909daaa2..84a08c2f923 100644
--- a/docs/polyglot/php.md
+++ b/docs/polyglot/php.md
@@ -285,6 +285,31 @@ service-mode bridge, including drain and rollback. Use
[Deployment Modes](/docs/polyglot/deployment-modes/) for the wider runtime
boundary comparison.
+## Read an accepted update later {#read-an-update-outcome}
+
+The selected PHP SDK 3.18.1 supports reading a retained update by its stable ID
+without admitting it again. `Client::updateOutcome($workflowId, $updateId)`
+defaults to `waitFor: 'completed'`: pending work throws `UpdateStillPending`;
+a completed result may legitimately be `null`. `updateOutcomeReceipt()` defaults
+to `waitFor: 'accepted'` and returns the Server receipt so callers can inspect
+`update_status` and `wait_timed_out` separately from a completed result.
+
+These GET reads require the `update_outcome_reads` capability (native Server
+3.6.0 and later). Without it, the SDK throws `LogicException` and does not
+resubmit the update. An initial `updateWorkflow()` pending exception retains
+the caller's request ID. A pending GET read retains `updateId`, but its original
+request key may be unavailable: `$pending->requestId` is then `''`, meaning
+unknown. Continue reading with that update ID; never submit an empty, inferred
+or internal hashed key as the original request ID.
+
+The [published PHP guide](https://php.durable-workflow.com/build/messages/#apply-a-tracked-update)
+shows the workflow-side handler and client journey. [Installed PHP 3.18.1 /
+native Server 3.9.1 controls](https://github.com/durable-workflow/sdk-php/pull/411#issuecomment-6855609359)
+verify pending-to-completed-null reads without a second update admission, plus
+[completion-size handling](./server-config-reference.md#workflow-task-completion-size).
+This evidence does not establish full request-key acceptance under shared #216
+or native timeout-cleanup support.
+
## Upgrade to PHP SDK 3.12 through 3.14 {#upgrade-to-3-12-through-3-14}
PHP `^8.1`, the Laravel bridge floors, worker protocol `1.20` and control plane
diff --git a/docs/polyglot/server-config-reference.md b/docs/polyglot/server-config-reference.md
index e3c6f5c4f03..4fdb601699b 100644
--- a/docs/polyglot/server-config-reference.md
+++ b/docs/polyglot/server-config-reference.md
@@ -69,7 +69,6 @@ Native refuses these settings unless they keep the listed value:
| Native has no namespace durable-state limits | `DW_NAMESPACE_DURABLE_HARD_LIMITS`: unset or `{}`
`DW_NAMESPACE_DURABLE_LIMITS`: unset or `{}`
`DW_NAMESPACE_DURABLE_OVERRIDES`: unset or `{}` |
| Native has no namespace request admission limits | `DW_NAMESPACE_ADMISSION_OVERRIDES`: unset or `{}`
`DW_NAMESPACE_HARD_MAX_CONCURRENT_REQUESTS`: unset or empty
`DW_NAMESPACE_HARD_MAX_REQUESTS_PER_MINUTE`: unset or empty
`DW_NAMESPACE_MAX_CONCURRENT_REQUESTS`: unset or empty
`DW_NAMESPACE_MAX_REQUESTS_PER_MINUTE`: unset or empty |
| Native has no service boundary policy | `DW_SERVICE_BOUNDARY_CROSS_NAMESPACE_DEFAULT`: unset or `allow`
`DW_SERVICE_BOUNDARY_HARD_MAX_IN_FLIGHT`: unset or empty
`DW_SERVICE_BOUNDARY_HARD_RATE_LIMIT_PER_MINUTE`: unset or empty
`DW_SERVICE_BOUNDARY_MAX_IN_FLIGHT`: unset or empty
`DW_SERVICE_BOUNDARY_NAMESPACE_MAX_IN_FLIGHT`: unset or empty
`DW_SERVICE_BOUNDARY_NAMESPACE_OVERRIDES`: unset or `{}`
`DW_SERVICE_BOUNDARY_NAMESPACE_RATE_LIMIT_PER_MINUTE`: unset or empty
`DW_SERVICE_BOUNDARY_RATE_LIMIT_PER_MINUTE`: unset or empty |
-| Native has no storage admission file | `DW_STORAGE_ADMISSION_FILE`: unset or empty
`DW_STORAGE_ADMISSION_SOURCE`: unset or empty |
| Native has no task admission limits | `DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: unset, empty or not a positive number
`DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: unset, empty or not a positive number
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE`: unset, empty or not a positive number
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: unset, empty or not a positive number
`DW_TASK_QUEUE_ADMISSION_OVERRIDES`: unset or `{}`
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: unset, empty or not a positive number
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: unset, empty or not a positive number
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE`: unset, empty or not a positive number
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: unset, empty or not a positive number |
| Native implements one worker protocol version | `DW_WORKER_PROTOCOL_VERSION`: unset or `1.20` |
| Native never trusts forwarded attribution headers | `DW_TRUST_FORWARDED_ATTRIBUTION_HEADERS`: unset or `false` |
@@ -80,7 +79,21 @@ Native refuses these settings unless they keep the listed value:
| Native stores external payloads only on its local disk | `DW_EXTERNAL_PAYLOAD_S3_BUCKET`: unset or empty |
| Native supports only its token authentication | `DW_AUTH_BACKWARD_COMPATIBLE`: unset or `true`
`DW_AUTH_PROVIDER`: unset or empty
`DW_PRINCIPAL_TOKENS`: unset or empty |
-Native accepts but ignores: `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+Native accepts but ignores: `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+
+Native 3.9.1 supports opt-in storage admission from an operator-published local
+observation. Set `DW_STORAGE_ADMISSION_FILE` to its absolute path and
+`DW_STORAGE_ADMISSION_SOURCE` to the expected source identity;
+`DW_STORAGE_ADMISSION_MAX_AGE_SECONDS` defaults to 15 (allowed range 1–300).
+With both path and source unset it is disabled. Missing, invalid or stale
+observations refuse new work with `503 storage_admission_unavailable`;
+`draining` or `fenced` observations refuse it with `503 storage_pressure`.
+Readiness also returns 503 while database health can remain 200. The
+[published 3.9.1 file-consumer controls](https://github.com/durable-workflow/server/issues/951#issuecomment-6853859351)
+verify these cases and recovery after atomic file replacement. They do not
+qualify physical quota measurement or a production Cloud mapping. This is
+admission control, not a write fence or byte reservation. Owner-UID hardening
+and draining completion-upload work remain separate from this published scope.
Native has no server-side task-queue lease or dispatch caps, budget groups,
namespace request admission, namespace durable-state quotas or held-poll caps,
@@ -472,9 +485,14 @@ Published Python SDK 2.17.1 with qualified native Server 3.9.1
[actual installed-worker controls](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512):
300 × 10 KB within-cap fan-out, one typed 413 and one structural failure with
zero partial activities for an oversized completion, then a successful task on
-the same worker. This qualifies that exact Python/Server tuple. PHP requires its own installed
-acceptance; Rust 4.16 is qualified below. Shared #228 remains open. Request-key
-acceptance under shared #216 is separate.
+the same worker. This qualifies that exact Python/Server tuple.
+
+[Published PHP SDK 3.18.1 / native Server 3.9.1 controls](https://github.com/durable-workflow/.github/issues/228#issuecomment-6855610551)
+(PHP 8.3.36, linux/amd64, SQLite) also pass 300 × 10 KB without external storage,
+one typed 413 and one structural failure with zero partial activities for a
+60 × 450 KB completion, then fresh work on the same Worker. This qualifies that
+exact PHP/Server tuple; Rust 4.16 is qualified below. Cross-product closure under
+shared #228 and request-key acceptance under shared #216 remain separate.
To keep a completion within the limit:
diff --git a/static/stable-releases.json b/static/stable-releases.json
index 43219720623..418bcaa0b93 100644
--- a/static/stable-releases.json
+++ b/static/stable-releases.json
@@ -5,7 +5,7 @@
"artifacts": {
"cli": "2.8.0",
"helm-chart": "1.7.0",
- "sdk-php": "3.18.0",
+ "sdk-php": "3.18.1",
"sdk-python": "2.17.1",
"sdk-rust": "4.16.0",
"server": "3.9.1",
From eabcb40de6234710d94da7a905f56828fcd645fb Mon Sep 17 00:00:00 2001
From: Richard McDaniel <1130888+rmcdaniel@users.noreply.github.com>
Date: Fri, 13 Nov 2026 14:34:31 +0000
Subject: [PATCH 2/2] Translate PHP retained reads and native admission
guidance
---
.../current/polyglot/php.md | 8 ++++++++
.../current/polyglot/server-config-reference.md | 9 ++++++---
i18n/de/source-hashes.json | 4 ++--
.../current/polyglot/php.md | 8 ++++++++
.../current/polyglot/server-config-reference.md | 9 ++++++---
i18n/es/source-hashes.json | 4 ++--
.../current/polyglot/php.md | 8 ++++++++
.../current/polyglot/server-config-reference.md | 9 ++++++---
i18n/fr/source-hashes.json | 4 ++--
.../current/polyglot/php.md | 8 ++++++++
.../current/polyglot/server-config-reference.md | 9 ++++++---
i18n/ja/source-hashes.json | 4 ++--
.../current/polyglot/php.md | 8 ++++++++
.../current/polyglot/server-config-reference.md | 9 ++++++---
i18n/pt-BR/source-hashes.json | 4 ++--
.../current/polyglot/php.md | 8 ++++++++
.../current/polyglot/server-config-reference.md | 9 ++++++---
i18n/uk/source-hashes.json | 4 ++--
.../current/polyglot/php.md | 8 ++++++++
.../current/polyglot/server-config-reference.md | 9 ++++++---
i18n/zh-Hans/source-hashes.json | 4 ++--
21 files changed, 112 insertions(+), 35 deletions(-)
diff --git a/i18n/de/docusaurus-plugin-content-docs/current/polyglot/php.md b/i18n/de/docusaurus-plugin-content-docs/current/polyglot/php.md
index a4e5e83e0d3..fa0af8b95df 100644
--- a/i18n/de/docusaurus-plugin-content-docs/current/polyglot/php.md
+++ b/i18n/de/docusaurus-plugin-content-docs/current/polyglot/php.md
@@ -292,6 +292,14 @@ ausgelieferten Service-Modus-Brücke, einschließlich Auslaufen und Rollback.
[Bereitstellungsmodi](/docs/polyglot/deployment-modes/) vergleicht die
Laufzeitgrenzen umfassender.
+## Ein akzeptiertes Update später lesen {#read-an-update-outcome}
+
+Das ausgewählte PHP SDK 3.18.1 liest ein aufbewahrtes Update anhand seiner stabilen ID, ohne es erneut anzunehmen. `Client::updateOutcome($workflowId, $updateId)` verwendet standardmäßig `waitFor: 'completed'`: Ausstehende Arbeit löst `UpdateStillPending` aus; ein abgeschlossenes Ergebnis darf `null` sein. `updateOutcomeReceipt()` verwendet standardmäßig `waitFor: 'accepted'` und liefert den Server-Beleg, sodass `update_status` und `wait_timed_out` getrennt vom abgeschlossenen Ergebnis geprüft werden können.
+
+Diese GET-Lesezugriffe benötigen die Capability `update_outcome_reads` (nativer Server ab 3.6.0). Ohne sie wirft das SDK `LogicException` und sendet das Update nicht erneut. Eine ausstehende erste `updateWorkflow()`-Annahme behält die Request-ID des Aufrufers. Ein ausstehender GET-Lesezugriff behält `updateId`, aber der ursprüngliche Request-Key kann fehlen: `$pending->requestId` ist dann `''`, also unbekannt. Lesen Sie mit dieser Update-ID weiter; senden Sie niemals einen leeren, abgeleiteten oder internen gehashten Schlüssel als ursprüngliche Request-ID.
+
+Der [veröffentlichte PHP-Leitfaden](https://php.durable-workflow.com/build/messages/#apply-a-tracked-update) zeigt Handler und Client-Ablauf. [Kontrollen mit installiertem PHP 3.18.1 / nativem Server 3.9.1](https://github.com/durable-workflow/sdk-php/pull/411#issuecomment-6855609359) prüfen den Übergang von ausstehend zu abgeschlossenem null ohne zweite Update-Annahme sowie die [Behandlung der Completion-Größe](./server-config-reference.md#workflow-task-completion-size). Diese Nachweise belegen weder die vollständige Request-Key-Akzeptanz unter dem gemeinsamen #216 noch native Timeout-Cleanup-Unterstützung.
+
## Upgrade auf PHP-SDK 3.12 bis 3.14 {#upgrade-to-3-12-through-3-14}
PHP `^8.1`, die Mindestanforderungen der Laravel-Bridge, Worker-Protokoll `1.20` und Steuerungsebene `2` sind gegenüber 3.11 unverändert. Prüfen Sie vor dem Deployment diese Verhaltensänderungen:
diff --git a/i18n/de/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md b/i18n/de/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
index 5789d46c1af..1858b10d24e 100644
--- a/i18n/de/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
+++ b/i18n/de/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
@@ -50,7 +50,6 @@ Der native Server lehnt diese Einstellungen ab, sofern sie nicht den aufgeführt
| Der native Server hat keine Limits für dauerhaften Namespace-Zustand | `DW_NAMESPACE_DURABLE_HARD_LIMITS`: nicht gesetzt oder `{}`
`DW_NAMESPACE_DURABLE_LIMITS`: nicht gesetzt oder `{}`
`DW_NAMESPACE_DURABLE_OVERRIDES`: nicht gesetzt oder `{}` |
| Der native Server hat keine Limits für die Anfragezulassung pro Namespace | `DW_NAMESPACE_ADMISSION_OVERRIDES`: nicht gesetzt oder `{}`
`DW_NAMESPACE_HARD_MAX_CONCURRENT_REQUESTS`: nicht gesetzt oder leer
`DW_NAMESPACE_HARD_MAX_REQUESTS_PER_MINUTE`: nicht gesetzt oder leer
`DW_NAMESPACE_MAX_CONCURRENT_REQUESTS`: nicht gesetzt oder leer
`DW_NAMESPACE_MAX_REQUESTS_PER_MINUTE`: nicht gesetzt oder leer |
| Der native Server hat keine Service-Grenzrichtlinie | `DW_SERVICE_BOUNDARY_CROSS_NAMESPACE_DEFAULT`: nicht gesetzt oder `allow`
`DW_SERVICE_BOUNDARY_HARD_MAX_IN_FLIGHT`: nicht gesetzt oder leer
`DW_SERVICE_BOUNDARY_HARD_RATE_LIMIT_PER_MINUTE`: nicht gesetzt oder leer
`DW_SERVICE_BOUNDARY_MAX_IN_FLIGHT`: nicht gesetzt oder leer
`DW_SERVICE_BOUNDARY_NAMESPACE_MAX_IN_FLIGHT`: nicht gesetzt oder leer
`DW_SERVICE_BOUNDARY_NAMESPACE_OVERRIDES`: nicht gesetzt oder `{}`
`DW_SERVICE_BOUNDARY_NAMESPACE_RATE_LIMIT_PER_MINUTE`: nicht gesetzt oder leer
`DW_SERVICE_BOUNDARY_RATE_LIMIT_PER_MINUTE`: nicht gesetzt oder leer |
-| Der native Server hat keine Speicherzulassungsdatei | `DW_STORAGE_ADMISSION_FILE`: nicht gesetzt oder leer
`DW_STORAGE_ADMISSION_SOURCE`: nicht gesetzt oder leer |
| Der native Server hat keine Limits für die Aufgabenzulassung | `DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: nicht gesetzt, leer oder keine positive Zahl
`DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: nicht gesetzt, leer oder keine positive Zahl
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE`: nicht gesetzt, leer oder keine positive Zahl
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: nicht gesetzt, leer oder keine positive Zahl
`DW_TASK_QUEUE_ADMISSION_OVERRIDES`: nicht gesetzt oder `{}`
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: nicht gesetzt, leer oder keine positive Zahl
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: nicht gesetzt, leer oder keine positive Zahl
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE`: nicht gesetzt, leer oder keine positive Zahl
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: nicht gesetzt, leer oder keine positive Zahl |
| Der native Server implementiert eine einzige Worker-Protokollversion | `DW_WORKER_PROTOCOL_VERSION`: nicht gesetzt oder `1.20` |
| Der native Server vertraut weitergeleiteten Zuordnungsheadern nie | `DW_TRUST_FORWARDED_ATTRIBUTION_HEADERS`: nicht gesetzt oder `false` |
@@ -61,7 +60,9 @@ Der native Server lehnt diese Einstellungen ab, sofern sie nicht den aufgeführt
| Der native Server speichert externe Payloads nur auf seinem lokalen Datenträger | `DW_EXTERNAL_PAYLOAD_S3_BUCKET`: nicht gesetzt oder leer |
| Der native Server unterstützt nur seine eigene Token-Authentifizierung | `DW_AUTH_BACKWARD_COMPATIBLE`: nicht gesetzt oder `true`
`DW_AUTH_PROVIDER`: nicht gesetzt oder leer
`DW_PRINCIPAL_TOKENS`: nicht gesetzt oder leer |
-Der native Server akzeptiert, ignoriert aber: `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+Der native Server akzeptiert, ignoriert aber: `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+
+Native 3.9.1 unterstützt optionale Storage-Admission anhand einer vom Betreiber veröffentlichten lokalen Beobachtung. Setzen Sie `DW_STORAGE_ADMISSION_FILE` auf den absoluten Pfad und `DW_STORAGE_ADMISSION_SOURCE` auf die erwartete Quellidentität. `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS` ist standardmäßig 15 (Bereich 1–300). Sind Pfad und Quelle beide nicht gesetzt, ist die Funktion deaktiviert. Fehlende, ungültige oder veraltete Beobachtungen verweigern neue Arbeit mit `503 storage_admission_unavailable`; `draining` oder `fenced` verweigern sie mit `503 storage_pressure`. Readiness liefert ebenfalls 503, während der Datenbankzustand 200 bleiben kann. Die [veröffentlichten Dateiverbraucher-Kontrollen für 3.9.1](https://github.com/durable-workflow/server/issues/951#issuecomment-6853859351) prüfen diese Fälle und die Erholung nach atomarem Dateiaustausch. Sie qualifizieren weder physische Kontingentmessung noch eine produktive Cloud-Zuordnung. Dies ist Admission-Control, keine Schreibsperre oder Byte-Reservierung. Owner-UID-Härtung und Completion-Uploads beim Draining bleiben außerhalb dieses veröffentlichten Umfangs.
Der native Server hat keine serverseitigen Lease- oder Zustellungsgrenzen für Task-Warteschlangen, keine Budgetgruppen, keine Anfragezulassung pro Namespace, keine Kontingente für dauerhaften Namespace-Zustand und keine Grenzen für gehaltene Polls; ein natives Gegenstück gibt es dafür noch nicht. Jeder native Server-Prozess öffnet höchstens vier Datenbankverbindungen. Abfrageaufgaben haben eine feste Grenze von 16 ausstehenden oder geleasten Aufgaben pro Namespace; darüber hinaus werden neue Abfragen wie bei PHP mit HTTP `429` und `query_task_queue_full` abgelehnt. Diese Grenze ist nicht konfigurierbar. Um die Task-Nebenläufigkeit auf dem nativen Server zu begrenzen, dimensionieren Sie die Slots jedes SDK-Workers und die Anzahl der Worker. [Task-Warteschlangenzulassung](/docs/polyglot/task-queue-admission) beschreibt die Steuerungen von PHP 2.x.
@@ -359,7 +360,9 @@ Ein größerer Abschluss wird mit `413 payload_too_large` und `limit_kind: workf
Python SDK 2.17 und Rust SDK 4.15 behandeln die typisierte Ablehnung. Auf Server 3.8.0 traf ein veröffentlichter Python-Kontrolllauf vor HTTP 413 auf `httpx.ReadError` und ließ den Workflow offen. Native 3.9.1 korrigiert diesen Antwortpfad durch begrenztes Verwerfen der Anfrage: höchstens 64 MiB verbleibende Upload-Daten und höchstens zwei Sekunden, bevor die ursprüngliche Ablehnung zurückgegeben und die Verbindung geschlossen wird. Außerhalb dieser Grenzen können weiterhin Transportfehler auftreten.
-Das veröffentlichte Python SDK 2.17.1 mit qualifiziertem nativem Server 3.9.1 (linux/amd64, SQLite) besteht nun die [Kontrollen mit tatsächlich installiertem Worker](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512): Fan-out von 300 × 10 KB innerhalb der Grenze, genau ein typisiertes 413 und ein struktureller Fehler ohne teilweise gestartete Aktivitäten bei übergroßer Completion, danach eine erfolgreiche Aufgabe auf demselben Worker. Dies qualifiziert genau dieses Python/Server-Paar. PHP benötigt einen eigenen installierten Akzeptanznachweis; Rust 4.16 ist unten qualifiziert. Das gemeinsame #228 bleibt offen. Die Request-Key-Akzeptanz unter dem gemeinsamen #216 ist separat.
+Das veröffentlichte Python SDK 2.17.1 mit qualifiziertem nativem Server 3.9.1 (linux/amd64, SQLite) besteht nun die [Kontrollen mit tatsächlich installiertem Worker](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512): Fan-out von 300 × 10 KB innerhalb der Grenze, genau ein typisiertes 413 und ein struktureller Fehler ohne teilweise gestartete Aktivitäten bei übergroßer Completion, danach eine erfolgreiche Aufgabe auf demselben Worker. Dies qualifiziert genau dieses Python/Server-Paar.
+
+[Kontrollen für veröffentlichtes PHP SDK 3.18.1 / nativen Server 3.9.1](https://github.com/durable-workflow/.github/issues/228#issuecomment-6855610551) (PHP 8.3.36, linux/amd64, SQLite) bestehen ebenfalls 300 × 10 KB ohne externen Speicher, genau ein typisiertes 413 und einen strukturellen Fehler ohne teilweise gestartete Aktivitäten für eine Completion von 60 × 450 KB, danach neue Arbeit auf demselben Worker. Dies qualifiziert genau dieses PHP/Server-Paar; Rust 4.16 ist unten qualifiziert. Der produktübergreifende Abschluss unter dem gemeinsamen #228 und die Request-Key-Akzeptanz unter dem gemeinsamen #216 bleiben separat.
So bleibt ein Abschluss innerhalb der Grenze:
diff --git a/i18n/de/source-hashes.json b/i18n/de/source-hashes.json
index be578197d37..70453603f07 100644
--- a/i18n/de/source-hashes.json
+++ b/i18n/de/source-hashes.json
@@ -80,7 +80,7 @@
"polyglot/invocable-carrier.md": "00bcf878b7bac1be90718b73f0a626a99cf0e111414ac0854c6491d159798c01",
"polyglot/invocable-php-handler.md": "3b678eb1d69fe32dfcfdc05d36b33e49e01b79d7216bd784f6a61a6f1c3c3a13",
"polyglot/namespace-auth-workers.md": "fee5e52a18637814f60aeb419f7ebc99ce4927089dfb748073697a8218bd47bb",
- "polyglot/php.md": "309e83622754b9d9abc65807280f2dab175a009054a001456ef1316776f11101",
+ "polyglot/php.md": "744b184b50b5de82f2d287beac0aa491c21b41b6287c2aed63ed7eb123f2e02a",
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
@@ -89,7 +89,7 @@
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "2cc511074e6d0ce8ababa0ccd6acbdaa7df3bf5d8c67ae5ef2fa07d75a05d2e7",
"polyglot/server-api-reference.md": "8bac825f11f7aa3f2a335cf3d1dcdc951219f11d6702e9fe3502d3803fd1e2a5",
- "polyglot/server-config-reference.md": "86cdcdac61326d12675b645bca90b2b18b107ee3d9ab8d839aef2eca823c40f0",
+ "polyglot/server-config-reference.md": "e7dc68015e9c1e43b102aa657c0dd2bc12487ef344cb10bdb2379c297114431f",
"polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2",
"polyglot/server.md": "55d5962ff5da8e29fbe0d568635c4d88ce539e39fdddce292df04b95b3561546",
"polyglot/service-operations.md": "a2ee46ac8d2e4f18aed4e3cb47a4f0b36f51ccc67f1e841efb99f0297391cf27",
diff --git a/i18n/es/docusaurus-plugin-content-docs/current/polyglot/php.md b/i18n/es/docusaurus-plugin-content-docs/current/polyglot/php.md
index d7ba8bedb50..260f3bd7d21 100644
--- a/i18n/es/docusaurus-plugin-content-docs/current/polyglot/php.md
+++ b/i18n/es/docusaurus-plugin-content-docs/current/polyglot/php.md
@@ -290,6 +290,14 @@ mismo caso representativo en v1, v2 integrado y este puente de modo servicio,
incluidos drenaje y reversión. Utiliza [Modos de despliegue](/docs/polyglot/deployment-modes/)
para una comparación más amplia de límites del runtime.
+## Leer una actualización aceptada más tarde {#read-an-update-outcome}
+
+El PHP SDK 3.18.1 seleccionado permite leer una actualización retenida por su ID estable sin admitirla de nuevo. `Client::updateOutcome($workflowId, $updateId)` usa por defecto `waitFor: 'completed'`: el trabajo pendiente lanza `UpdateStillPending`; un resultado completado puede ser legítimamente `null`. `updateOutcomeReceipt()` usa por defecto `waitFor: 'accepted'` y devuelve el recibo del Server para inspeccionar `update_status` y `wait_timed_out` por separado del resultado completado.
+
+Estas lecturas GET requieren la capacidad `update_outcome_reads` (Server nativo 3.6.0 y posteriores). Sin ella, el SDK lanza `LogicException` y no reenvía la actualización. Una excepción pendiente del `updateWorkflow()` inicial conserva el ID de solicitud del llamador. Una lectura GET pendiente conserva `updateId`, pero la clave de solicitud original puede faltar: `$pending->requestId` es entonces `''`, que significa desconocida. Siga leyendo con ese ID de actualización; nunca envíe una clave vacía, inferida o con hash interno como ID de solicitud original.
+
+La [guía PHP publicada](https://php.durable-workflow.com/build/messages/#apply-a-tracked-update) muestra el manejador y el recorrido del cliente. Los [controles con PHP 3.18.1 instalado / Server nativo 3.9.1](https://github.com/durable-workflow/sdk-php/pull/411#issuecomment-6855609359) verifican lecturas de pendiente a completado con null sin una segunda admisión, además del [manejo del tamaño de finalización](./server-config-reference.md#workflow-task-completion-size). Esta evidencia no establece aceptación completa de claves bajo el #216 compartido ni soporte nativo de limpieza por timeout.
+
## Actualizar a PHP SDK 3.12 a 3.14 {#upgrade-to-3-12-through-3-14}
PHP `^8.1`, los mínimos del puente Laravel, el protocolo de workers `1.20` y el plano de control `2` no cambian respecto a 3.11. Revise estos cambios de comportamiento antes de desplegar:
diff --git a/i18n/es/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md b/i18n/es/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
index 72a1f574959..17dc861a2c3 100644
--- a/i18n/es/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
+++ b/i18n/es/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
@@ -50,7 +50,6 @@ El Server nativo rechaza estos ajustes salvo que conserven el valor indicado:
| El Server nativo no tiene límites de estado duradero por namespace | `DW_NAMESPACE_DURABLE_HARD_LIMITS`: sin definir o `{}`
`DW_NAMESPACE_DURABLE_LIMITS`: sin definir o `{}`
`DW_NAMESPACE_DURABLE_OVERRIDES`: sin definir o `{}` |
| El Server nativo no tiene límites de admisión de solicitudes por namespace | `DW_NAMESPACE_ADMISSION_OVERRIDES`: sin definir o `{}`
`DW_NAMESPACE_HARD_MAX_CONCURRENT_REQUESTS`: sin definir o vacío
`DW_NAMESPACE_HARD_MAX_REQUESTS_PER_MINUTE`: sin definir o vacío
`DW_NAMESPACE_MAX_CONCURRENT_REQUESTS`: sin definir o vacío
`DW_NAMESPACE_MAX_REQUESTS_PER_MINUTE`: sin definir o vacío |
| El Server nativo no tiene política de límites de servicio | `DW_SERVICE_BOUNDARY_CROSS_NAMESPACE_DEFAULT`: sin definir o `allow`
`DW_SERVICE_BOUNDARY_HARD_MAX_IN_FLIGHT`: sin definir o vacío
`DW_SERVICE_BOUNDARY_HARD_RATE_LIMIT_PER_MINUTE`: sin definir o vacío
`DW_SERVICE_BOUNDARY_MAX_IN_FLIGHT`: sin definir o vacío
`DW_SERVICE_BOUNDARY_NAMESPACE_MAX_IN_FLIGHT`: sin definir o vacío
`DW_SERVICE_BOUNDARY_NAMESPACE_OVERRIDES`: sin definir o `{}`
`DW_SERVICE_BOUNDARY_NAMESPACE_RATE_LIMIT_PER_MINUTE`: sin definir o vacío
`DW_SERVICE_BOUNDARY_RATE_LIMIT_PER_MINUTE`: sin definir o vacío |
-| El Server nativo no tiene archivo de admisión de almacenamiento | `DW_STORAGE_ADMISSION_FILE`: sin definir o vacío
`DW_STORAGE_ADMISSION_SOURCE`: sin definir o vacío |
| El Server nativo no tiene límites de admisión de tareas | `DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: sin definir, vacío o no es un número positivo
`DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: sin definir, vacío o no es un número positivo
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE`: sin definir, vacío o no es un número positivo
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: sin definir, vacío o no es un número positivo
`DW_TASK_QUEUE_ADMISSION_OVERRIDES`: sin definir o `{}`
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: sin definir, vacío o no es un número positivo
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: sin definir, vacío o no es un número positivo
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE`: sin definir, vacío o no es un número positivo
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: sin definir, vacío o no es un número positivo |
| El Server nativo implementa una sola versión del protocolo de workers | `DW_WORKER_PROTOCOL_VERSION`: sin definir o `1.20` |
| El Server nativo nunca confía en cabeceras de atribución reenviadas | `DW_TRUST_FORWARDED_ATTRIBUTION_HEADERS`: sin definir o `false` |
@@ -61,7 +60,9 @@ El Server nativo rechaza estos ajustes salvo que conserven el valor indicado:
| El Server nativo solo almacena cargas externas en su disco local | `DW_EXTERNAL_PAYLOAD_S3_BUCKET`: sin definir o vacío |
| El Server nativo solo admite su autenticación por token | `DW_AUTH_BACKWARD_COMPATIBLE`: sin definir o `true`
`DW_AUTH_PROVIDER`: sin definir o vacío
`DW_PRINCIPAL_TOKENS`: sin definir o vacío |
-El Server nativo acepta pero ignora: `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+El Server nativo acepta pero ignora: `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+
+El runtime nativo 3.9.1 admite control de admisión de almacenamiento opcional mediante una observación local publicada por el operador. Configure `DW_STORAGE_ADMISSION_FILE` con su ruta absoluta y `DW_STORAGE_ADMISSION_SOURCE` con la identidad de origen esperada; `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS` vale 15 por defecto (rango 1–300). Si ruta y origen no están definidos, se desactiva. Las observaciones ausentes, inválidas o caducadas rechazan trabajo nuevo con `503 storage_admission_unavailable`; `draining` o `fenced` lo rechazan con `503 storage_pressure`. Readiness también devuelve 503 mientras la salud de la base puede seguir en 200. Los [controles publicados del consumidor de archivos 3.9.1](https://github.com/durable-workflow/server/issues/951#issuecomment-6853859351) verifican estos casos y la recuperación tras reemplazar el archivo atómicamente. No cualifican medición física de cuotas ni un mapeo de Cloud en producción. Esto controla la admisión; no es una barrera de escritura ni una reserva de bytes. El endurecimiento del UID propietario y las cargas de finalización durante draining quedan fuera de este alcance publicado.
El Server nativo no tiene límites del lado del servidor para leases ni despachos de colas de tareas, grupos de presupuesto, admisión de peticiones por namespace, cuotas de estado duradero por namespace ni límites de sondeos retenidos, y todavía no existe un equivalente nativo. Cada proceso de Server nativo abre como máximo cuatro conexiones de base de datos. Las tareas de consulta tienen un límite fijo de 16 tareas pendientes o arrendadas por namespace; por encima de él, las nuevas consultas se rechazan con HTTP `429` y `query_task_queue_full`, como en PHP. Este límite no es configurable. Para acotar la concurrencia de tareas en el Server nativo, dimensione los slots de cada worker del SDK y el número de workers. [Admisión en colas de tareas](/docs/polyglot/task-queue-admission) describe los controles de PHP 2.x.
@@ -348,7 +349,9 @@ Una finalización mayor se rechaza con `413 payload_too_large` y `limit_kind: wo
Python SDK 2.17 y Rust SDK 4.15 incluyen el manejo del rechazo tipado. En Server 3.8.0, un control publicado de Python obtuvo `httpx.ReadError` antes de recibir HTTP 413 y dejó el workflow pendiente. El runtime nativo 3.9.1 corrige esa respuesta descartando datos de forma acotada: como máximo 64 MiB de la subida restante durante dos segundos, antes de devolver el rechazo original y cerrar la conexión. Las subidas que superen cualquiera de esos límites aún pueden sufrir errores de transporte.
-Python SDK 2.17.1 publicado con Server nativo 3.9.1 cualificado (linux/amd64, SQLite) supera ahora los [controles con el Worker instalado real](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512): fan-out de 300 × 10 KB dentro del límite, un único 413 tipado y un único fallo estructural sin actividades parciales para una finalización sobredimensionada, y después una tarea correcta en el mismo Worker. Esto cualifica ese par exacto Python/Server. PHP requiere su propia aceptación instalada; Rust 4.16 se cualifica abajo. El #228 compartido sigue abierto. La aceptación de claves de solicitud del #216 compartido es independiente.
+Python SDK 2.17.1 publicado con Server nativo 3.9.1 cualificado (linux/amd64, SQLite) supera ahora los [controles con el Worker instalado real](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512): fan-out de 300 × 10 KB dentro del límite, un único 413 tipado y un único fallo estructural sin actividades parciales para una finalización sobredimensionada, y después una tarea correcta en el mismo Worker. Esto cualifica ese par exacto Python/Server.
+
+Los [controles de PHP SDK 3.18.1 publicado / Server nativo 3.9.1](https://github.com/durable-workflow/.github/issues/228#issuecomment-6855610551) (PHP 8.3.36, linux/amd64, SQLite) también superan 300 × 10 KB sin almacenamiento externo, un único 413 tipado y un fallo estructural sin actividades parciales para una finalización de 60 × 450 KB, y después trabajo nuevo en el mismo Worker. Esto cualifica ese par exacto PHP/Server; Rust 4.16 se cualifica abajo. El cierre entre productos bajo el #228 compartido y la aceptación de claves bajo el #216 compartido siguen siendo independientes.
Para mantener una finalización dentro del límite:
diff --git a/i18n/es/source-hashes.json b/i18n/es/source-hashes.json
index be578197d37..70453603f07 100644
--- a/i18n/es/source-hashes.json
+++ b/i18n/es/source-hashes.json
@@ -80,7 +80,7 @@
"polyglot/invocable-carrier.md": "00bcf878b7bac1be90718b73f0a626a99cf0e111414ac0854c6491d159798c01",
"polyglot/invocable-php-handler.md": "3b678eb1d69fe32dfcfdc05d36b33e49e01b79d7216bd784f6a61a6f1c3c3a13",
"polyglot/namespace-auth-workers.md": "fee5e52a18637814f60aeb419f7ebc99ce4927089dfb748073697a8218bd47bb",
- "polyglot/php.md": "309e83622754b9d9abc65807280f2dab175a009054a001456ef1316776f11101",
+ "polyglot/php.md": "744b184b50b5de82f2d287beac0aa491c21b41b6287c2aed63ed7eb123f2e02a",
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
@@ -89,7 +89,7 @@
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "2cc511074e6d0ce8ababa0ccd6acbdaa7df3bf5d8c67ae5ef2fa07d75a05d2e7",
"polyglot/server-api-reference.md": "8bac825f11f7aa3f2a335cf3d1dcdc951219f11d6702e9fe3502d3803fd1e2a5",
- "polyglot/server-config-reference.md": "86cdcdac61326d12675b645bca90b2b18b107ee3d9ab8d839aef2eca823c40f0",
+ "polyglot/server-config-reference.md": "e7dc68015e9c1e43b102aa657c0dd2bc12487ef344cb10bdb2379c297114431f",
"polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2",
"polyglot/server.md": "55d5962ff5da8e29fbe0d568635c4d88ce539e39fdddce292df04b95b3561546",
"polyglot/service-operations.md": "a2ee46ac8d2e4f18aed4e3cb47a4f0b36f51ccc67f1e841efb99f0297391cf27",
diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/php.md b/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/php.md
index c9293cbdf28..b2e1f9f7a41 100644
--- a/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/php.md
+++ b/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/php.md
@@ -295,6 +295,14 @@ mode service livré, y compris le drainage et le retour arrière.
Les [modes de déploiement](/docs/polyglot/deployment-modes/) comparent plus
largement les frontières du runtime.
+## Lire plus tard une mise à jour acceptée {#read-an-update-outcome}
+
+Le PHP SDK 3.18.1 sélectionné permet de lire une mise à jour conservée par son ID stable sans l’admettre à nouveau. `Client::updateOutcome($workflowId, $updateId)` utilise par défaut `waitFor: 'completed'` : un travail en attente lève `UpdateStillPending` ; un résultat terminé peut légitimement être `null`. `updateOutcomeReceipt()` utilise par défaut `waitFor: 'accepted'` et renvoie le reçu du Server pour examiner `update_status` et `wait_timed_out` séparément du résultat terminé.
+
+Ces lectures GET exigent la capacité `update_outcome_reads` (Server natif 3.6.0 et suivants). Sans elle, le SDK lève `LogicException` et ne renvoie pas la mise à jour. Une exception d’attente du premier `updateWorkflow()` conserve l’ID de requête de l’appelant. Une lecture GET en attente conserve `updateId`, mais la clé d’origine peut manquer : `$pending->requestId` vaut alors `''`, soit inconnue. Continuez la lecture avec cet ID de mise à jour ; ne soumettez jamais de clé vide, déduite ou hachée interne comme ID de requête d’origine.
+
+Le [guide PHP publié](https://php.durable-workflow.com/build/messages/#apply-a-tracked-update) présente le gestionnaire et le parcours client. Les [contrôles avec PHP 3.18.1 installé / Server natif 3.9.1](https://github.com/durable-workflow/sdk-php/pull/411#issuecomment-6855609359) vérifient le passage d’attente à un résultat terminé null sans seconde admission, ainsi que le [traitement de la taille de finalisation](./server-config-reference.md#workflow-task-completion-size). Ces preuves n’établissent ni l’acceptation complète des clés du #216 partagé, ni le nettoyage natif après timeout.
+
## Mettre à niveau vers le SDK PHP 3.12 à 3.14 {#upgrade-to-3-12-through-3-14}
PHP `^8.1`, les planchers du pont Laravel, le protocole de worker `1.20` et le plan de contrôle `2` sont inchangés depuis 3.11. Vérifiez ces changements de comportement avant le déploiement :
diff --git a/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md b/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
index 80b29382cb4..6d43cb420e3 100644
--- a/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
+++ b/i18n/fr/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
@@ -50,7 +50,6 @@ Le natif refuse ces paramètres sauf s’ils conservent la valeur indiquée :
| Le natif n’a pas de limites d’état durable par namespace | `DW_NAMESPACE_DURABLE_HARD_LIMITS` : non définie ou `{}`
`DW_NAMESPACE_DURABLE_LIMITS` : non définie ou `{}`
`DW_NAMESPACE_DURABLE_OVERRIDES` : non définie ou `{}` |
| Le natif n’a pas de limites d’admission des requêtes par namespace | `DW_NAMESPACE_ADMISSION_OVERRIDES` : non définie ou `{}`
`DW_NAMESPACE_HARD_MAX_CONCURRENT_REQUESTS` : non définie ou vide
`DW_NAMESPACE_HARD_MAX_REQUESTS_PER_MINUTE` : non définie ou vide
`DW_NAMESPACE_MAX_CONCURRENT_REQUESTS` : non définie ou vide
`DW_NAMESPACE_MAX_REQUESTS_PER_MINUTE` : non définie ou vide |
| Le natif n’a pas de politique de frontière de service | `DW_SERVICE_BOUNDARY_CROSS_NAMESPACE_DEFAULT` : non définie ou `allow`
`DW_SERVICE_BOUNDARY_HARD_MAX_IN_FLIGHT` : non définie ou vide
`DW_SERVICE_BOUNDARY_HARD_RATE_LIMIT_PER_MINUTE` : non définie ou vide
`DW_SERVICE_BOUNDARY_MAX_IN_FLIGHT` : non définie ou vide
`DW_SERVICE_BOUNDARY_NAMESPACE_MAX_IN_FLIGHT` : non définie ou vide
`DW_SERVICE_BOUNDARY_NAMESPACE_OVERRIDES` : non définie ou `{}`
`DW_SERVICE_BOUNDARY_NAMESPACE_RATE_LIMIT_PER_MINUTE` : non définie ou vide
`DW_SERVICE_BOUNDARY_RATE_LIMIT_PER_MINUTE` : non définie ou vide |
-| Le natif n’a pas de fichier d’admission du stockage | `DW_STORAGE_ADMISSION_FILE` : non définie ou vide
`DW_STORAGE_ADMISSION_SOURCE` : non définie ou vide |
| Le natif n’a pas de limites d’admission des tâches | `DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE` : non définie, vide ou non strictement positive
`DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_QUEUE` : non définie, vide ou non strictement positive
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE` : non définie, vide ou non strictement positive
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE` : non définie, vide ou non strictement positive
`DW_TASK_QUEUE_ADMISSION_OVERRIDES` : non définie ou `{}`
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE` : non définie, vide ou non strictement positive
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_QUEUE` : non définie, vide ou non strictement positive
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE` : non définie, vide ou non strictement positive
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE` : non définie, vide ou non strictement positive |
| Le natif implémente une seule version du protocole worker | `DW_WORKER_PROTOCOL_VERSION` : non définie ou `1.20` |
| Le natif ne fait jamais confiance aux en-têtes d’attribution transférés | `DW_TRUST_FORWARDED_ATTRIBUTION_HEADERS` : non définie ou `false` |
@@ -61,7 +60,9 @@ Le natif refuse ces paramètres sauf s’ils conservent la valeur indiquée :
| Le natif stocke les payloads externes uniquement sur son disque local | `DW_EXTERNAL_PAYLOAD_S3_BUCKET` : non définie ou vide |
| Le natif ne prend en charge que son authentification par jeton | `DW_AUTH_BACKWARD_COMPATIBLE` : non définie ou `true`
`DW_AUTH_PROVIDER` : non définie ou vide
`DW_PRINCIPAL_TOKENS` : non définie ou vide |
-Paramètres acceptés mais ignorés par le natif : `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+Paramètres acceptés mais ignorés par le natif : `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+
+Le runtime natif 3.9.1 prend en charge l’admission de stockage optionnelle à partir d’une observation locale publiée par l’opérateur. Définissez `DW_STORAGE_ADMISSION_FILE` avec son chemin absolu et `DW_STORAGE_ADMISSION_SOURCE` avec l’identité de source attendue ; `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS` vaut 15 par défaut (plage 1–300). Sans chemin ni source, la fonction est désactivée. Une observation absente, invalide ou périmée refuse le nouveau travail avec `503 storage_admission_unavailable` ; `draining` ou `fenced` le refuse avec `503 storage_pressure`. Readiness renvoie aussi 503 tandis que la santé de la base peut rester à 200. Les [contrôles publiés du consommateur de fichier 3.9.1](https://github.com/durable-workflow/server/issues/951#issuecomment-6853859351) vérifient ces cas et la reprise après remplacement atomique du fichier. Ils ne qualifient ni la mesure physique des quotas, ni un mappage Cloud en production. Il s’agit d’un contrôle d’admission, pas d’une barrière d’écriture ou d’une réservation d’octets. Le durcissement de l’UID propriétaire et les téléversements de finalisation pendant draining restent distincts de ce périmètre publié.
Le natif n’a ni plafonds côté serveur de baux ou de distribution des files de tâches, ni groupes de budget, ni admission des requêtes par namespace, ni quotas d’état durable par namespace, ni plafonds des polls en attente, et il n’en existe encore aucun équivalent natif. Chaque processus Server natif ouvre au plus quatre connexions à la base de données. Les tâches de requête de lecture ont une borne fixe de 16 tâches en attente ou louées par namespace ; au-delà, les nouvelles requêtes de lecture sont refusées avec HTTP `429` et `query_task_queue_full`, comme sur PHP. Cette borne n’est pas configurable. Pour borner la concurrence des tâches sur le natif, dimensionnez les emplacements de chaque worker SDK et le nombre de workers. [Admission des files de tâches](/docs/polyglot/task-queue-admission) décrit les contrôles de PHP 2.x.
@@ -348,7 +349,9 @@ Un achèvement plus grand est refusé avec `413 payload_too_large` et `limit_kin
Python SDK 2.17 et Rust SDK 4.15 gèrent le refus typé. Sur Server 3.8.0, un contrôle Python publié rencontrait `httpx.ReadError` avant HTTP 413 et laissait le workflow en attente. Le runtime natif 3.9.1 corrige cette réponse par une lecture puis un abandon bornés du reste de la requête : au plus 64 MiB pendant deux secondes avant de renvoyer le refus original et fermer la connexion. Au-delà de l’une de ces bornes, des erreurs de transport restent possibles.
-Le SDK Python 2.17.1 publié avec le Server natif 3.9.1 qualifié (linux/amd64, SQLite) réussit désormais les [contrôles sur le Worker réellement installé](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512) : fan-out de 300 × 10 KB dans la limite, un seul 413 typé et un seul échec structurel sans activité partielle pour une finalisation trop grande, puis une tâche réussie sur le même Worker. Cela qualifie ce couple exact Python/Server. PHP nécessite sa propre preuve sur installation ; Rust 4.16 est qualifié ci-dessous. Le #228 partagé reste ouvert. L’acceptation des clés de requête du #216 partagé est distincte.
+Le SDK Python 2.17.1 publié avec le Server natif 3.9.1 qualifié (linux/amd64, SQLite) réussit désormais les [contrôles sur le Worker réellement installé](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512) : fan-out de 300 × 10 KB dans la limite, un seul 413 typé et un seul échec structurel sans activité partielle pour une finalisation trop grande, puis une tâche réussie sur le même Worker. Cela qualifie ce couple exact Python/Server.
+
+Les [contrôles du PHP SDK 3.18.1 publié / Server natif 3.9.1](https://github.com/durable-workflow/.github/issues/228#issuecomment-6855610551) (PHP 8.3.36, linux/amd64, SQLite) réussissent aussi 300 × 10 KB sans stockage externe, un seul 413 typé et un échec structurel sans activité partielle pour une finalisation de 60 × 450 KB, puis un nouveau travail sur le même Worker. Cela qualifie ce couple exact PHP/Server ; Rust 4.16 est qualifié ci-dessous. La clôture interproduits du #228 partagé et l’acceptation des clés du #216 partagé restent distinctes.
Pour garder un achèvement sous la limite :
diff --git a/i18n/fr/source-hashes.json b/i18n/fr/source-hashes.json
index be578197d37..70453603f07 100644
--- a/i18n/fr/source-hashes.json
+++ b/i18n/fr/source-hashes.json
@@ -80,7 +80,7 @@
"polyglot/invocable-carrier.md": "00bcf878b7bac1be90718b73f0a626a99cf0e111414ac0854c6491d159798c01",
"polyglot/invocable-php-handler.md": "3b678eb1d69fe32dfcfdc05d36b33e49e01b79d7216bd784f6a61a6f1c3c3a13",
"polyglot/namespace-auth-workers.md": "fee5e52a18637814f60aeb419f7ebc99ce4927089dfb748073697a8218bd47bb",
- "polyglot/php.md": "309e83622754b9d9abc65807280f2dab175a009054a001456ef1316776f11101",
+ "polyglot/php.md": "744b184b50b5de82f2d287beac0aa491c21b41b6287c2aed63ed7eb123f2e02a",
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
@@ -89,7 +89,7 @@
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "2cc511074e6d0ce8ababa0ccd6acbdaa7df3bf5d8c67ae5ef2fa07d75a05d2e7",
"polyglot/server-api-reference.md": "8bac825f11f7aa3f2a335cf3d1dcdc951219f11d6702e9fe3502d3803fd1e2a5",
- "polyglot/server-config-reference.md": "86cdcdac61326d12675b645bca90b2b18b107ee3d9ab8d839aef2eca823c40f0",
+ "polyglot/server-config-reference.md": "e7dc68015e9c1e43b102aa657c0dd2bc12487ef344cb10bdb2379c297114431f",
"polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2",
"polyglot/server.md": "55d5962ff5da8e29fbe0d568635c4d88ce539e39fdddce292df04b95b3561546",
"polyglot/service-operations.md": "a2ee46ac8d2e4f18aed4e3cb47a4f0b36f51ccc67f1e841efb99f0297391cf27",
diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/php.md b/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/php.md
index 3aa35f3fb13..737fbed583b 100644
--- a/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/php.md
+++ b/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/php.md
@@ -187,6 +187,14 @@ Worker は `workflow_entry_arguments_validation` を自動的に通知します
これらのブリッジは、`durable-workflow/workflow` によって Laravel アプリケーション自体が永続状態を所有し Laravel キューで実行する[組み込み Laravel ワークフロー](/docs/installation/)とは別です。ドレインとロールバックを含め、v1、v2 組み込み、同梱サービスモードブリッジで同じ代表的な Laravel ユースケースを比較するには、[Laravel の採用とランタイム移行](/docs/laravel-adoption/)を参照してください。より広いランタイム境界の比較には[デプロイモード](/docs/polyglot/deployment-modes/)を使います。
+## 受理済み Update を後から読む {#read-an-update-outcome}
+
+選択中の PHP SDK 3.18.1 は、保持された Update を安定した ID で読み取り、再度受理させずに結果を取得できます。`Client::updateOutcome($workflowId, $updateId)` の既定値は `waitFor: 'completed'` です。保留中は `UpdateStillPending` を投げ、完了した結果は正当に `null` になり得ます。`updateOutcomeReceipt()` の既定値は `waitFor: 'accepted'` で、Server のレシートを返すため、`update_status` と `wait_timed_out` を完了結果と分けて確認できます。
+
+これらの GET 読み取りには `update_outcome_reads` capability(native Server 3.6.0 以降)が必要です。非対応なら SDK は `LogicException` を投げ、Update を再送しません。最初の `updateWorkflow()` が保留中の例外には呼び出し元のリクエスト ID が残ります。保留中の GET 読み取りでも `updateId` は保持されますが、元のリクエストキーが不明な場合があります。そのとき `$pending->requestId` は `''`(不明)です。その Update ID で読み取りを続け、空、推測値、内部ハッシュのキーを元のリクエスト ID として送信しないでください。
+
+[公開済み PHP ガイド](https://php.durable-workflow.com/build/messages/#apply-a-tracked-update)にハンドラーとクライアントの手順があります。[インストール済み PHP 3.18.1 / native Server 3.9.1 の検証](https://github.com/durable-workflow/sdk-php/pull/411#issuecomment-6855609359)は、2 回目の Update 受理なしで保留から完了 null への読み取りと、[完了サイズの処理](./server-config-reference.md#workflow-task-completion-size)を確認しています。この証拠は共有 #216 のリクエストキー全体の検証や native timeout-cleanup 対応を意味しません。
+
## PHP SDK 3.12 から 3.14 へのアップグレード {#upgrade-to-3-12-through-3-14}
PHP `^8.1`、Laravel ブリッジの下限、ワーカープロトコル `1.20`、コントロールプレーン `2` は 3.11 から変わりません。デプロイ前に次の動作の変更を確認してください。
diff --git a/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md b/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
index acde7d099fe..ff735873b5c 100644
--- a/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
+++ b/i18n/ja/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
@@ -50,7 +50,6 @@ PHP 2.x Server は `DB_*`、`REDIS_*`、`QUEUE_CONNECTION`、`CACHE_STORE` な
| ネイティブには Namespace の永続状態の制限がありません | `DW_NAMESPACE_DURABLE_HARD_LIMITS`:未設定または `{}`
`DW_NAMESPACE_DURABLE_LIMITS`:未設定または `{}`
`DW_NAMESPACE_DURABLE_OVERRIDES`:未設定または `{}` |
| ネイティブには Namespace のリクエスト受付制限がありません | `DW_NAMESPACE_ADMISSION_OVERRIDES`:未設定または `{}`
`DW_NAMESPACE_HARD_MAX_CONCURRENT_REQUESTS`:未設定または空
`DW_NAMESPACE_HARD_MAX_REQUESTS_PER_MINUTE`:未設定または空
`DW_NAMESPACE_MAX_CONCURRENT_REQUESTS`:未設定または空
`DW_NAMESPACE_MAX_REQUESTS_PER_MINUTE`:未設定または空 |
| ネイティブにはサービス境界のポリシーがありません | `DW_SERVICE_BOUNDARY_CROSS_NAMESPACE_DEFAULT`:未設定または `allow`
`DW_SERVICE_BOUNDARY_HARD_MAX_IN_FLIGHT`:未設定または空
`DW_SERVICE_BOUNDARY_HARD_RATE_LIMIT_PER_MINUTE`:未設定または空
`DW_SERVICE_BOUNDARY_MAX_IN_FLIGHT`:未設定または空
`DW_SERVICE_BOUNDARY_NAMESPACE_MAX_IN_FLIGHT`:未設定または空
`DW_SERVICE_BOUNDARY_NAMESPACE_OVERRIDES`:未設定または `{}`
`DW_SERVICE_BOUNDARY_NAMESPACE_RATE_LIMIT_PER_MINUTE`:未設定または空
`DW_SERVICE_BOUNDARY_RATE_LIMIT_PER_MINUTE`:未設定または空 |
-| ネイティブにはストレージ受付ファイルがありません | `DW_STORAGE_ADMISSION_FILE`:未設定または空
`DW_STORAGE_ADMISSION_SOURCE`:未設定または空 |
| ネイティブにはタスクの受付制限がありません | `DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`:未設定、空、または正の数以外
`DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`:未設定、空、または正の数以外
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE`:未設定、空、または正の数以外
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`:未設定、空、または正の数以外
`DW_TASK_QUEUE_ADMISSION_OVERRIDES`:未設定または `{}`
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`:未設定、空、または正の数以外
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`:未設定、空、または正の数以外
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE`:未設定、空、または正の数以外
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`:未設定、空、または正の数以外 |
| ネイティブが実装する Worker プロトコルのバージョンは一つだけです | `DW_WORKER_PROTOCOL_VERSION`:未設定または `1.20` |
| ネイティブは転送された実行主体ヘッダーを決して信頼しません | `DW_TRUST_FORWARDED_ATTRIBUTION_HEADERS`:未設定または `false` |
@@ -61,7 +60,9 @@ PHP 2.x Server は `DB_*`、`REDIS_*`、`QUEUE_CONNECTION`、`CACHE_STORE` な
| ネイティブは外部ペイロードをローカルディスクにだけ保存します | `DW_EXTERNAL_PAYLOAD_S3_BUCKET`:未設定または空 |
| ネイティブは独自のトークン認証だけに対応します | `DW_AUTH_BACKWARD_COMPATIBLE`:未設定または `true`
`DW_AUTH_PROVIDER`:未設定または空
`DW_PRINCIPAL_TOKENS`:未設定または空 |
-ネイティブが受け付けるが無視する設定:`DW_ADMIN_SIGNATURE_KEY`、`DW_AUTH_METHOD_HEADER`、`DW_AUTH_STATUS_HEADER`、`DW_BOOTSTRAP_DELAY_SECONDS`、`DW_BOOTSTRAP_RETRIES`、`DW_CALLER_LABEL_HEADER`、`DW_CALLER_TYPE_HEADER`、`DW_COMPRESSION_ENABLED`、`DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`、`DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`、`DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`、`DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`、`DW_EXTERNAL_PAYLOAD_S3_REGION`、`DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`、`DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`、`DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`、`DW_MAX_HISTORY_EVENTS`、`DW_MAX_TASKS_PER_POLL`、`DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`、`DW_OBSERVABILITY_CONTEXT_ENABLED`、`DW_OPERATOR_SIGNATURE_KEY`、`DW_PACKAGE_PROVENANCE_PATH`、`DW_POLLING_CACHE_PATH`、`DW_QUERY_TASK_POLL_MAX_CONCURRENT`、`DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`、`DW_SIGNATURE_KEY`、`DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`、`DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`、`DW_STORAGE_ADMISSION_MAX_AGE_SECONDS`、`DW_V2_CACHE_VALIDATION_MODE`、`DW_V2_GUARDRAILS_BOOT`、`DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`、`DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`、`DW_V2_MATCHING_ROLE_QUEUE_WAKE`、`DW_V2_TASK_DISPATCH_MODE`、`DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`、`DW_V2_TENANCY_ENVIRONMENT`、`DW_V2_TENANCY_ORGANIZATION`、`DW_V2_TENANCY_PROJECT`、`DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`、`DW_V2_VALIDATE_CACHE_BACKEND`、`DW_WAKE_SIGNAL_TTL_SECONDS`、`DW_WORKER_LONG_POLL_MAX_CONCURRENT`、`DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`、`DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`、`DW_WORKER_POLL_INTERVAL_MS`、`DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`、`DW_WORKER_SIGNATURE_KEY`。
+ネイティブが受け付けるが無視する設定:`DW_ADMIN_SIGNATURE_KEY`、`DW_AUTH_METHOD_HEADER`、`DW_AUTH_STATUS_HEADER`、`DW_BOOTSTRAP_DELAY_SECONDS`、`DW_BOOTSTRAP_RETRIES`、`DW_CALLER_LABEL_HEADER`、`DW_CALLER_TYPE_HEADER`、`DW_COMPRESSION_ENABLED`、`DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`、`DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`、`DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`、`DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`、`DW_EXTERNAL_PAYLOAD_S3_REGION`、`DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`、`DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`、`DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`、`DW_MAX_HISTORY_EVENTS`、`DW_MAX_TASKS_PER_POLL`、`DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`、`DW_OBSERVABILITY_CONTEXT_ENABLED`、`DW_OPERATOR_SIGNATURE_KEY`、`DW_PACKAGE_PROVENANCE_PATH`、`DW_POLLING_CACHE_PATH`、`DW_QUERY_TASK_POLL_MAX_CONCURRENT`、`DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`、`DW_SIGNATURE_KEY`、`DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`、`DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`、`DW_V2_CACHE_VALIDATION_MODE`、`DW_V2_GUARDRAILS_BOOT`、`DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`、`DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`、`DW_V2_MATCHING_ROLE_QUEUE_WAKE`、`DW_V2_TASK_DISPATCH_MODE`、`DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`、`DW_V2_TENANCY_ENVIRONMENT`、`DW_V2_TENANCY_ORGANIZATION`、`DW_V2_TENANCY_PROJECT`、`DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`、`DW_V2_VALIDATE_CACHE_BACKEND`、`DW_WAKE_SIGNAL_TTL_SECONDS`、`DW_WORKER_LONG_POLL_MAX_CONCURRENT`、`DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`、`DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`、`DW_WORKER_POLL_INTERVAL_MS`、`DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`、`DW_WORKER_SIGNATURE_KEY`。
+
+Native 3.9.1 は、オペレーターが公開するローカル観測ファイルによる任意のストレージ受け入れ制御に対応します。`DW_STORAGE_ADMISSION_FILE` に絶対パス、`DW_STORAGE_ADMISSION_SOURCE` に期待するソース識別子を設定します。`DW_STORAGE_ADMISSION_MAX_AGE_SECONDS` は既定 15、範囲 1–300 です。パスとソースの両方が未設定なら無効です。観測が欠落、不正、期限切れなら新しい処理を `503 storage_admission_unavailable` で拒否し、`draining` または `fenced` なら `503 storage_pressure` で拒否します。Readiness も 503 になりますが、DB health は 200 のままの場合があります。[公開済み 3.9.1 ファイル読み取りの検証](https://github.com/durable-workflow/server/issues/951#issuecomment-6853859351)では、これらのケースとファイルのアトミックな置換後の復旧を確認しています。物理的な容量制限の計測や本番 Cloud の対応付けを検証したものではありません。これは受け入れ制御であり、書き込みフェンスやバイト予約ではありません。所有者 UID の強化と draining 中の完了アップロードは、この公開済み範囲とは別です。
ネイティブには、Server 側のタスクキューのリース上限・ディスパッチ上限、予算グループ、namespace のリクエスト受付制限、namespace の永続状態クォータ、保持中の poll の上限がなく、現時点ではネイティブの代替手段もありません。ネイティブ Server の各プロセスは最大4本のデータベース接続を開きます。クエリタスクには namespace ごとに保留中またはリース中16件という固定の上限があり、それを超える新規クエリは、PHP と同様に HTTP `429` と `query_task_queue_full` で拒否されます。この上限は設定できません。ネイティブでタスクの並行数を制限するには、各 SDK Worker のスロット数と Worker 数を調整してください。PHP 2.x の制御は[タスクキューの受け入れ制御](/docs/polyglot/task-queue-admission)で説明しています。
@@ -334,7 +335,9 @@ Rust SDK 4.16 の完了プランナーは、通常の上限より小さくても
Python SDK 2.17 と Rust SDK 4.15 には型付き拒否の処理があります。Server 3.8.0 の公開済み Python 検証では HTTP 413 を受け取る前に `httpx.ReadError` が発生し、workflow が保留されました。native 3.9.1 は、残りのアップロードを最大 64 MiB、最大 2 秒間だけ破棄してから元の拒否を返し、接続を閉じることで応答経路を修正します。どちらかの境界を超えるアップロードでは、引き続きトランスポートエラーが起こり得ます。
-公開済み Python SDK 2.17.1 と検証済み native Server 3.9.1(linux/amd64、SQLite)は、[実際にインストールした Worker の検証](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512)に合格しました。上限内の 300 × 10 KB fan-out、大きすぎる完了に対する型付き 413 が 1 回と構造的失敗が 1 回、部分的な Activity がゼロ、その後の同じ Worker でのタスク成功を確認しています。この特定の Python/Server 組み合わせの検証です。PHP には独自のインストール済み検証が必要です。Rust 4.16 の検証は下記に示します。共有 #228 は未完了です。共有 #216 のリクエストキー検証は別です。
+公開済み Python SDK 2.17.1 と検証済み native Server 3.9.1(linux/amd64、SQLite)は、[実際にインストールした Worker の検証](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512)に合格しました。上限内の 300 × 10 KB fan-out、大きすぎる完了に対する型付き 413 が 1 回と構造的失敗が 1 回、部分的な Activity がゼロ、その後の同じ Worker でのタスク成功を確認しています。この特定の Python/Server 組み合わせの検証です。
+
+[公開済み PHP SDK 3.18.1 / native Server 3.9.1 の検証](https://github.com/durable-workflow/.github/issues/228#issuecomment-6855610551)(PHP 8.3.36、linux/amd64、SQLite)でも、外部ストレージなしの 300 × 10 KB、60 × 450 KB の完了に対する型付き 413 が 1 回と構造的失敗が 1 回、部分的な Activity がゼロ、その後の同じ Worker での新しい処理に合格しています。この特定の PHP/Server 組み合わせの検証です。Rust 4.16 の検証は下記に示します。共有 #228 の製品横断での完了と共有 #216 のリクエストキー検証は別です。
完了を上限内に収めるには:
diff --git a/i18n/ja/source-hashes.json b/i18n/ja/source-hashes.json
index be578197d37..70453603f07 100644
--- a/i18n/ja/source-hashes.json
+++ b/i18n/ja/source-hashes.json
@@ -80,7 +80,7 @@
"polyglot/invocable-carrier.md": "00bcf878b7bac1be90718b73f0a626a99cf0e111414ac0854c6491d159798c01",
"polyglot/invocable-php-handler.md": "3b678eb1d69fe32dfcfdc05d36b33e49e01b79d7216bd784f6a61a6f1c3c3a13",
"polyglot/namespace-auth-workers.md": "fee5e52a18637814f60aeb419f7ebc99ce4927089dfb748073697a8218bd47bb",
- "polyglot/php.md": "309e83622754b9d9abc65807280f2dab175a009054a001456ef1316776f11101",
+ "polyglot/php.md": "744b184b50b5de82f2d287beac0aa491c21b41b6287c2aed63ed7eb123f2e02a",
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
@@ -89,7 +89,7 @@
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "2cc511074e6d0ce8ababa0ccd6acbdaa7df3bf5d8c67ae5ef2fa07d75a05d2e7",
"polyglot/server-api-reference.md": "8bac825f11f7aa3f2a335cf3d1dcdc951219f11d6702e9fe3502d3803fd1e2a5",
- "polyglot/server-config-reference.md": "86cdcdac61326d12675b645bca90b2b18b107ee3d9ab8d839aef2eca823c40f0",
+ "polyglot/server-config-reference.md": "e7dc68015e9c1e43b102aa657c0dd2bc12487ef344cb10bdb2379c297114431f",
"polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2",
"polyglot/server.md": "55d5962ff5da8e29fbe0d568635c4d88ce539e39fdddce292df04b95b3561546",
"polyglot/service-operations.md": "a2ee46ac8d2e4f18aed4e3cb47a4f0b36f51ccc67f1e841efb99f0297391cf27",
diff --git a/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/php.md b/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/php.md
index a8bcca1210c..82f8b946366 100644
--- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/php.md
+++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/php.md
@@ -294,6 +294,14 @@ modo de serviço distribuída, incluindo drenagem e rollback. Use
[Modos de implantação](/docs/polyglot/deployment-modes/) para a comparação
mais ampla dos limites de runtime.
+## Ler uma atualização aceita mais tarde {#read-an-update-outcome}
+
+O PHP SDK 3.18.1 selecionado permite ler uma atualização retida pelo ID estável sem admiti-la novamente. `Client::updateOutcome($workflowId, $updateId)` usa `waitFor: 'completed'` por padrão: trabalho pendente lança `UpdateStillPending`; um resultado concluído pode legitimamente ser `null`. `updateOutcomeReceipt()` usa `waitFor: 'accepted'` por padrão e retorna o recibo do Server para inspecionar `update_status` e `wait_timed_out` separadamente do resultado concluído.
+
+Essas leituras GET exigem a capability `update_outcome_reads` (Server nativo 3.6.0 ou posterior). Sem ela, o SDK lança `LogicException` e não reenvia a atualização. Uma exceção pendente do `updateWorkflow()` inicial preserva o ID de requisição do chamador. Uma leitura GET pendente preserva `updateId`, mas a chave original pode estar indisponível: `$pending->requestId` então é `''`, ou seja, desconhecida. Continue lendo com esse ID de atualização; nunca envie uma chave vazia, inferida ou com hash interno como ID original.
+
+O [guia PHP publicado](https://php.durable-workflow.com/build/messages/#apply-a-tracked-update) mostra o handler e a jornada do cliente. Os [controles com PHP 3.18.1 instalado / Server nativo 3.9.1](https://github.com/durable-workflow/sdk-php/pull/411#issuecomment-6855609359) verificam leituras de pendente até concluído com null sem uma segunda admissão, além do [tratamento do tamanho de conclusão](./server-config-reference.md#workflow-task-completion-size). Essa evidência não estabelece aceitação completa de chaves no #216 compartilhado nem suporte nativo a limpeza por timeout.
+
## Atualizar para o SDK PHP 3.12 a 3.14 {#upgrade-to-3-12-through-3-14}
PHP `^8.1`, os pisos da ponte Laravel, o protocolo de workers `1.20` e o plano de controle `2` não mudam em relação à 3.11. Verifique estas mudanças de comportamento antes de implantar:
diff --git a/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md b/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
index eb6d92a02d4..e4637b70fd2 100644
--- a/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
+++ b/i18n/pt-BR/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
@@ -50,7 +50,6 @@ O Server nativo recusa estas configurações, a menos que mantenham o valor indi
| O Server nativo não tem limites de estado durável por namespace | `DW_NAMESPACE_DURABLE_HARD_LIMITS`: não definida ou `{}`
`DW_NAMESPACE_DURABLE_LIMITS`: não definida ou `{}`
`DW_NAMESPACE_DURABLE_OVERRIDES`: não definida ou `{}` |
| O Server nativo não tem limites de admissão de requisições por namespace | `DW_NAMESPACE_ADMISSION_OVERRIDES`: não definida ou `{}`
`DW_NAMESPACE_HARD_MAX_CONCURRENT_REQUESTS`: não definida ou vazia
`DW_NAMESPACE_HARD_MAX_REQUESTS_PER_MINUTE`: não definida ou vazia
`DW_NAMESPACE_MAX_CONCURRENT_REQUESTS`: não definida ou vazia
`DW_NAMESPACE_MAX_REQUESTS_PER_MINUTE`: não definida ou vazia |
| O Server nativo não tem política de fronteira de serviço | `DW_SERVICE_BOUNDARY_CROSS_NAMESPACE_DEFAULT`: não definida ou `allow`
`DW_SERVICE_BOUNDARY_HARD_MAX_IN_FLIGHT`: não definida ou vazia
`DW_SERVICE_BOUNDARY_HARD_RATE_LIMIT_PER_MINUTE`: não definida ou vazia
`DW_SERVICE_BOUNDARY_MAX_IN_FLIGHT`: não definida ou vazia
`DW_SERVICE_BOUNDARY_NAMESPACE_MAX_IN_FLIGHT`: não definida ou vazia
`DW_SERVICE_BOUNDARY_NAMESPACE_OVERRIDES`: não definida ou `{}`
`DW_SERVICE_BOUNDARY_NAMESPACE_RATE_LIMIT_PER_MINUTE`: não definida ou vazia
`DW_SERVICE_BOUNDARY_RATE_LIMIT_PER_MINUTE`: não definida ou vazia |
-| O Server nativo não tem arquivo de admissão de armazenamento | `DW_STORAGE_ADMISSION_FILE`: não definida ou vazia
`DW_STORAGE_ADMISSION_SOURCE`: não definida ou vazia |
| O Server nativo não tem limites de admissão de tarefas | `DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: não definida, vazia ou que não seja um número positivo
`DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: não definida, vazia ou que não seja um número positivo
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE`: não definida, vazia ou que não seja um número positivo
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: não definida, vazia ou que não seja um número positivo
`DW_TASK_QUEUE_ADMISSION_OVERRIDES`: não definida ou `{}`
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: não definida, vazia ou que não seja um número positivo
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: não definida, vazia ou que não seja um número positivo
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE`: não definida, vazia ou que não seja um número positivo
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: não definida, vazia ou que não seja um número positivo |
| O Server nativo implementa uma única versão do protocolo dos workers | `DW_WORKER_PROTOCOL_VERSION`: não definida ou `1.20` |
| O Server nativo nunca confia em cabeçalhos de atribuição encaminhados | `DW_TRUST_FORWARDED_ATTRIBUTION_HEADERS`: não definida ou `false` |
@@ -61,7 +60,9 @@ O Server nativo recusa estas configurações, a menos que mantenham o valor indi
| O Server nativo armazena payloads externos apenas no seu disco local | `DW_EXTERNAL_PAYLOAD_S3_BUCKET`: não definida ou vazia |
| O Server nativo aceita apenas sua própria autenticação por token | `DW_AUTH_BACKWARD_COMPATIBLE`: não definida ou `true`
`DW_AUTH_PROVIDER`: não definida ou vazia
`DW_PRINCIPAL_TOKENS`: não definida ou vazia |
-O Server nativo aceita, mas ignora: `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+O Server nativo aceita, mas ignora: `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+
+O runtime nativo 3.9.1 suporta admissão de armazenamento opcional a partir de uma observação local publicada pelo operador. Defina `DW_STORAGE_ADMISSION_FILE` com o caminho absoluto e `DW_STORAGE_ADMISSION_SOURCE` com a identidade de origem esperada; `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS` tem padrão 15 (intervalo 1–300). Sem caminho nem origem definidos, fica desativada. Observações ausentes, inválidas ou vencidas recusam trabalho novo com `503 storage_admission_unavailable`; `draining` ou `fenced` recusam com `503 storage_pressure`. Readiness também retorna 503 enquanto a saúde do banco pode continuar em 200. Os [controles publicados do consumidor de arquivo 3.9.1](https://github.com/durable-workflow/server/issues/951#issuecomment-6853859351) verificam esses casos e a recuperação após substituição atômica do arquivo. Não qualificam medição física de quota nem mapeamento de Cloud em produção. Isso controla admissão; não é uma barreira de gravação ou reserva de bytes. O reforço do UID proprietário e uploads de conclusão durante draining continuam separados desse escopo publicado.
O Server nativo não tem limites de lease ou de despacho de filas de tarefas no servidor, grupos de orçamento, admissão de requisições por namespace, cotas de estado durável por namespace nem limites de polling mantido em espera, e ainda não há equivalente nativo para eles. Cada processo do Server nativo abre no máximo quatro conexões de banco de dados. As tarefas de consulta têm um limite fixo de 16 tarefas pendentes ou com lease por namespace; acima dele, novas consultas são recusadas com HTTP `429` e `query_task_queue_full`, como no PHP. Esse limite não é configurável. Para limitar a concorrência de tarefas no Server nativo, dimensione os slots de cada worker do SDK e o número de workers. [Admissão de filas de tarefas](/docs/polyglot/task-queue-admission) descreve os controles do PHP 2.x.
@@ -348,7 +349,9 @@ Uma conclusão maior é recusada com `413 payload_too_large` e `limit_kind: work
Python SDK 2.17 e Rust SDK 4.15 incluem tratamento para a recusa tipada. No Server 3.8.0, um controle Python publicado recebeu `httpx.ReadError` antes do HTTP 413 e deixou o workflow pendente. O runtime nativo 3.9.1 corrige a resposta descartando dados de forma limitada: no máximo 64 MiB da carga restante por até dois segundos, antes de devolver a recusa original e fechar a conexão. Uploads que ultrapassem qualquer limite ainda podem ter erros de transporte.
-O Python SDK 2.17.1 publicado com o Server nativo 3.9.1 qualificado (linux/amd64, SQLite) agora passa nos [controles com Worker realmente instalado](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512): fan-out de 300 × 10 KB dentro do limite, um único 413 tipado e uma única falha estrutural sem atividades parciais para uma conclusão grande demais, e depois uma tarefa bem-sucedida no mesmo Worker. Isso qualifica esse par exato Python/Server. PHP exige sua própria aceitação instalada; Rust 4.16 está qualificado abaixo. O #228 compartilhado continua aberto. A aceitação de chaves de requisição do #216 compartilhado é separada.
+O Python SDK 2.17.1 publicado com o Server nativo 3.9.1 qualificado (linux/amd64, SQLite) agora passa nos [controles com Worker realmente instalado](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512): fan-out de 300 × 10 KB dentro do limite, um único 413 tipado e uma única falha estrutural sem atividades parciais para uma conclusão grande demais, e depois uma tarefa bem-sucedida no mesmo Worker. Isso qualifica esse par exato Python/Server.
+
+Os [controles do PHP SDK 3.18.1 publicado / Server nativo 3.9.1](https://github.com/durable-workflow/.github/issues/228#issuecomment-6855610551) (PHP 8.3.36, linux/amd64, SQLite) também passam em 300 × 10 KB sem armazenamento externo, um único 413 tipado e uma falha estrutural sem atividades parciais para uma conclusão de 60 × 450 KB, seguidos de trabalho novo no mesmo Worker. Isso qualifica esse par exato PHP/Server; Rust 4.16 está qualificado abaixo. O fechamento entre produtos no #228 compartilhado e a aceitação de chaves no #216 compartilhado continuam separados.
Para manter uma conclusão dentro do limite:
diff --git a/i18n/pt-BR/source-hashes.json b/i18n/pt-BR/source-hashes.json
index be578197d37..70453603f07 100644
--- a/i18n/pt-BR/source-hashes.json
+++ b/i18n/pt-BR/source-hashes.json
@@ -80,7 +80,7 @@
"polyglot/invocable-carrier.md": "00bcf878b7bac1be90718b73f0a626a99cf0e111414ac0854c6491d159798c01",
"polyglot/invocable-php-handler.md": "3b678eb1d69fe32dfcfdc05d36b33e49e01b79d7216bd784f6a61a6f1c3c3a13",
"polyglot/namespace-auth-workers.md": "fee5e52a18637814f60aeb419f7ebc99ce4927089dfb748073697a8218bd47bb",
- "polyglot/php.md": "309e83622754b9d9abc65807280f2dab175a009054a001456ef1316776f11101",
+ "polyglot/php.md": "744b184b50b5de82f2d287beac0aa491c21b41b6287c2aed63ed7eb123f2e02a",
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
@@ -89,7 +89,7 @@
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "2cc511074e6d0ce8ababa0ccd6acbdaa7df3bf5d8c67ae5ef2fa07d75a05d2e7",
"polyglot/server-api-reference.md": "8bac825f11f7aa3f2a335cf3d1dcdc951219f11d6702e9fe3502d3803fd1e2a5",
- "polyglot/server-config-reference.md": "86cdcdac61326d12675b645bca90b2b18b107ee3d9ab8d839aef2eca823c40f0",
+ "polyglot/server-config-reference.md": "e7dc68015e9c1e43b102aa657c0dd2bc12487ef344cb10bdb2379c297114431f",
"polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2",
"polyglot/server.md": "55d5962ff5da8e29fbe0d568635c4d88ce539e39fdddce292df04b95b3561546",
"polyglot/service-operations.md": "a2ee46ac8d2e4f18aed4e3cb47a4f0b36f51ccc67f1e841efb99f0297391cf27",
diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/php.md b/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/php.md
index cd4ff0016f8..bb111ff0d95 100644
--- a/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/php.md
+++ b/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/php.md
@@ -289,6 +289,14 @@ service mode, включно з drain і rollback.
Ширше порівняння меж runtime наведено в
[режимах розгортання](/docs/polyglot/deployment-modes/).
+## Прочитати прийняте оновлення пізніше {#read-an-update-outcome}
+
+Вибраний PHP SDK 3.18.1 дозволяє читати збережене оновлення за сталим ID без повторного прийняття. `Client::updateOutcome($workflowId, $updateId)` типово використовує `waitFor: 'completed'`: незавершена робота породжує `UpdateStillPending`; завершений результат цілком може бути `null`. `updateOutcomeReceipt()` типово використовує `waitFor: 'accepted'` і повертає квитанцію Server, щоб перевіряти `update_status` та `wait_timed_out` окремо від завершеного результату.
+
+Ці GET-читання потребують можливості `update_outcome_reads` (нативний Server 3.6.0 і новіші). Без неї SDK породжує `LogicException` і не надсилає оновлення повторно. Виняток очікування початкового `updateWorkflow()` зберігає ID запиту викликача. Незавершене GET-читання зберігає `updateId`, але початковий ключ запиту може бути недоступним: тоді `$pending->requestId` дорівнює `''`, тобто невідомий. Продовжуйте читати за цим ID оновлення; ніколи не надсилайте порожній, виведений або внутрішній хешований ключ як початковий ID запиту.
+
+[Опублікований посібник PHP](https://php.durable-workflow.com/build/messages/#apply-a-tracked-update) показує обробник і шлях клієнта. [Перевірки встановленого PHP 3.18.1 / нативного Server 3.9.1](https://github.com/durable-workflow/sdk-php/pull/411#issuecomment-6855609359) підтверджують читання від очікування до завершеного null без другого прийняття оновлення та [обробку розміру завершення](./server-config-reference.md#workflow-task-completion-size). Ці докази не встановлюють повну перевірку ключів у спільному #216 або нативну підтримку очищення після тайм-ауту.
+
## Оновлення до PHP SDK 3.12–3.14 {#upgrade-to-3-12-through-3-14}
PHP `^8.1`, мінімальні вимоги мосту Laravel, протокол workers `1.20` і площина керування `2` не змінилися порівняно з 3.11. Перед розгортанням перевірте ці зміни поведінки:
diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md b/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
index e9c2b450c97..9f1af3f8b65 100644
--- a/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
+++ b/i18n/uk/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
@@ -71,7 +71,6 @@ Server. Як і `env:audit` у PHP, нативний аудит попередж
| Нативний Server не має лімітів durable-стану namespace | `DW_NAMESPACE_DURABLE_HARD_LIMITS`: не задано або `{}`
`DW_NAMESPACE_DURABLE_LIMITS`: не задано або `{}`
`DW_NAMESPACE_DURABLE_OVERRIDES`: не задано або `{}` |
| Нативний Server не має лімітів admission запитів namespace | `DW_NAMESPACE_ADMISSION_OVERRIDES`: не задано або `{}`
`DW_NAMESPACE_HARD_MAX_CONCURRENT_REQUESTS`: не задано або порожнє
`DW_NAMESPACE_HARD_MAX_REQUESTS_PER_MINUTE`: не задано або порожнє
`DW_NAMESPACE_MAX_CONCURRENT_REQUESTS`: не задано або порожнє
`DW_NAMESPACE_MAX_REQUESTS_PER_MINUTE`: не задано або порожнє |
| Нативний Server не має політики меж сервісів | `DW_SERVICE_BOUNDARY_CROSS_NAMESPACE_DEFAULT`: не задано або `allow`
`DW_SERVICE_BOUNDARY_HARD_MAX_IN_FLIGHT`: не задано або порожнє
`DW_SERVICE_BOUNDARY_HARD_RATE_LIMIT_PER_MINUTE`: не задано або порожнє
`DW_SERVICE_BOUNDARY_MAX_IN_FLIGHT`: не задано або порожнє
`DW_SERVICE_BOUNDARY_NAMESPACE_MAX_IN_FLIGHT`: не задано або порожнє
`DW_SERVICE_BOUNDARY_NAMESPACE_OVERRIDES`: не задано або `{}`
`DW_SERVICE_BOUNDARY_NAMESPACE_RATE_LIMIT_PER_MINUTE`: не задано або порожнє
`DW_SERVICE_BOUNDARY_RATE_LIMIT_PER_MINUTE`: не задано або порожнє |
-| Нативний Server не має файлу admission сховища | `DW_STORAGE_ADMISSION_FILE`: не задано або порожнє
`DW_STORAGE_ADMISSION_SOURCE`: не задано або порожнє |
| Нативний Server не має лімітів admission tasks | `DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: не задано, порожнє або не додатне число
`DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: не задано, порожнє або не додатне число
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE`: не задано, порожнє або не додатне число
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: не задано, порожнє або не додатне число
`DW_TASK_QUEUE_ADMISSION_OVERRIDES`: не задано або `{}`
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: не задано, порожнє або не додатне число
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: не задано, порожнє або не додатне число
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE`: не задано, порожнє або не додатне число
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: не задано, порожнє або не додатне число |
| Нативний Server реалізує одну версію worker-протоколу | `DW_WORKER_PROTOCOL_VERSION`: не задано або `1.20` |
| Нативний Server ніколи не довіряє пересланим заголовкам атрибуції | `DW_TRUST_FORWARDED_ATTRIBUTION_HEADERS`: не задано або `false` |
@@ -82,7 +81,9 @@ Server. Як і `env:audit` у PHP, нативний аудит попередж
| Нативний Server зберігає external payloads лише на своєму локальному диску | `DW_EXTERNAL_PAYLOAD_S3_BUCKET`: не задано або порожнє |
| Нативний Server підтримує лише власну автентифікацію за токеном | `DW_AUTH_BACKWARD_COMPATIBLE`: не задано або `true`
`DW_AUTH_PROVIDER`: не задано або порожнє
`DW_PRINCIPAL_TOKENS`: не задано або порожнє |
-Нативний Server приймає, але ігнорує: `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+Нативний Server приймає, але ігнорує: `DW_ADMIN_SIGNATURE_KEY`, `DW_AUTH_METHOD_HEADER`, `DW_AUTH_STATUS_HEADER`, `DW_BOOTSTRAP_DELAY_SECONDS`, `DW_BOOTSTRAP_RETRIES`, `DW_CALLER_LABEL_HEADER`, `DW_CALLER_TYPE_HEADER`, `DW_COMPRESSION_ENABLED`, `DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`, `DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`, `DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`, `DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`, `DW_EXTERNAL_PAYLOAD_S3_REGION`, `DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`, `DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`, `DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`, `DW_MAX_HISTORY_EVENTS`, `DW_MAX_TASKS_PER_POLL`, `DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`, `DW_OBSERVABILITY_CONTEXT_ENABLED`, `DW_OPERATOR_SIGNATURE_KEY`, `DW_PACKAGE_PROVENANCE_PATH`, `DW_POLLING_CACHE_PATH`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT`, `DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_SIGNATURE_KEY`, `DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`, `DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`, `DW_V2_CACHE_VALIDATION_MODE`, `DW_V2_GUARDRAILS_BOOT`, `DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`, `DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`, `DW_V2_MATCHING_ROLE_QUEUE_WAKE`, `DW_V2_TASK_DISPATCH_MODE`, `DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`, `DW_V2_TENANCY_ENVIRONMENT`, `DW_V2_TENANCY_ORGANIZATION`, `DW_V2_TENANCY_PROJECT`, `DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`, `DW_V2_VALIDATE_CACHE_BACKEND`, `DW_WAKE_SIGNAL_TTL_SECONDS`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT`, `DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`, `DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`, `DW_WORKER_POLL_INTERVAL_MS`, `DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`, `DW_WORKER_SIGNATURE_KEY`.
+
+Нативний 3.9.1 підтримує опційне керування прийняттям роботи за сховищем через локальне спостереження, опубліковане оператором. Укажіть абсолютний шлях у `DW_STORAGE_ADMISSION_FILE` і очікувану ідентичність джерела в `DW_STORAGE_ADMISSION_SOURCE`; `DW_STORAGE_ADMISSION_MAX_AGE_SECONDS` типово дорівнює 15 (діапазон 1–300). Якщо шлях і джерело не задані, функцію вимкнено. Відсутні, неправильні чи застарілі спостереження відхиляють нову роботу з `503 storage_admission_unavailable`; `draining` або `fenced` відхиляють її з `503 storage_pressure`. Readiness також повертає 503, тоді як стан бази може залишатися 200. [Опубліковані перевірки читача файлу 3.9.1](https://github.com/durable-workflow/server/issues/951#issuecomment-6853859351) підтверджують ці випадки та відновлення після атомарної заміни файлу. Вони не кваліфікують фізичне вимірювання квоти чи виробниче відображення Cloud. Це керування прийняттям, а не огорожа запису чи резервування байтів. Посилення перевірки UID власника та завантаження завершень під час draining залишаються поза цим опублікованим обсягом.
Нативний Server не має серверних обмежень leases чи dispatch для task queues,
budget-груп, admission запитів namespace, квот сталого стану namespace чи
@@ -448,7 +449,9 @@ runtime також діють. Рядок ID workflow стосується ок
Python SDK 2.17 і Rust SDK 4.15 обробляють типізовану відмову. На Server 3.8.0 опублікований контроль Python отримав `httpx.ReadError` до HTTP 413 і залишив workflow в очікуванні. Нативний runtime 3.9.1 виправляє відповідь обмеженим відкиданням решти запиту: щонайбільше 64 MiB за щонайбільше дві секунди перед початковою відмовою та закриттям з’єднання. Завантаження поза будь-якою з цих меж і далі можуть мати транспортні помилки.
-Опублікований Python SDK 2.17.1 із кваліфікованим нативним Server 3.9.1 (linux/amd64, SQLite) тепер проходить [контролі реально встановленого Worker](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512): fan-out 300 × 10 KB у межах бюджету, одна типізована 413 і один структурний збій без часткових активностей для завеликого завершення, а потім успішне завдання на тому самому Worker. Це кваліфікує саме цю пару Python/Server. PHP потребує власної перевірки встановленого пакета; Rust 4.16 кваліфіковано нижче. Спільне #228 залишається відкритим. Перевірка ключів запитів у спільному #216 є окремою.
+Опублікований Python SDK 2.17.1 із кваліфікованим нативним Server 3.9.1 (linux/amd64, SQLite) тепер проходить [контролі реально встановленого Worker](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512): fan-out 300 × 10 KB у межах бюджету, одна типізована 413 і один структурний збій без часткових активностей для завеликого завершення, а потім успішне завдання на тому самому Worker. Це кваліфікує саме цю пару Python/Server.
+
+[Перевірки опублікованого PHP SDK 3.18.1 / нативного Server 3.9.1](https://github.com/durable-workflow/.github/issues/228#issuecomment-6855610551) (PHP 8.3.36, linux/amd64, SQLite) також проходять 300 × 10 KB без зовнішнього сховища, одну типізовану 413 і один структурний збій без часткових активностей для завершення 60 × 450 KB, а потім нову роботу на тому самому Worker. Це кваліфікує саме цю пару PHP/Server; Rust 4.16 кваліфіковано нижче. Міжпродуктове закриття спільного #228 та перевірка ключів у спільному #216 залишаються окремими.
Щоб завершення вкладалося в ліміт:
diff --git a/i18n/uk/source-hashes.json b/i18n/uk/source-hashes.json
index be578197d37..70453603f07 100644
--- a/i18n/uk/source-hashes.json
+++ b/i18n/uk/source-hashes.json
@@ -80,7 +80,7 @@
"polyglot/invocable-carrier.md": "00bcf878b7bac1be90718b73f0a626a99cf0e111414ac0854c6491d159798c01",
"polyglot/invocable-php-handler.md": "3b678eb1d69fe32dfcfdc05d36b33e49e01b79d7216bd784f6a61a6f1c3c3a13",
"polyglot/namespace-auth-workers.md": "fee5e52a18637814f60aeb419f7ebc99ce4927089dfb748073697a8218bd47bb",
- "polyglot/php.md": "309e83622754b9d9abc65807280f2dab175a009054a001456ef1316776f11101",
+ "polyglot/php.md": "744b184b50b5de82f2d287beac0aa491c21b41b6287c2aed63ed7eb123f2e02a",
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
@@ -89,7 +89,7 @@
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "2cc511074e6d0ce8ababa0ccd6acbdaa7df3bf5d8c67ae5ef2fa07d75a05d2e7",
"polyglot/server-api-reference.md": "8bac825f11f7aa3f2a335cf3d1dcdc951219f11d6702e9fe3502d3803fd1e2a5",
- "polyglot/server-config-reference.md": "86cdcdac61326d12675b645bca90b2b18b107ee3d9ab8d839aef2eca823c40f0",
+ "polyglot/server-config-reference.md": "e7dc68015e9c1e43b102aa657c0dd2bc12487ef344cb10bdb2379c297114431f",
"polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2",
"polyglot/server.md": "55d5962ff5da8e29fbe0d568635c4d88ce539e39fdddce292df04b95b3561546",
"polyglot/service-operations.md": "a2ee46ac8d2e4f18aed4e3cb47a4f0b36f51ccc67f1e841efb99f0297391cf27",
diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/php.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/php.md
index ce6cf46ae72..6c0f918ccae 100644
--- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/php.md
+++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/php.md
@@ -184,6 +184,14 @@ Worker 会自动声明 `workflow_entry_arguments_validation`。在配套 Server
这些桥接不同于[嵌入式 Laravel 工作流](/docs/installation/);后者通过 `durable-workflow/workflow` 使 Laravel 应用自身管理持久状态并通过 Laravel 队列执行。参见 [Laravel 采用与运行时迁移](/docs/laravel-adoption/),了解同一个典型 Laravel 用例如何使用 v1、v2 嵌入式及已提供的服务模式桥接,包括排空和回滚。更全面的运行时边界比较见[部署模式](/docs/polyglot/deployment-modes/)。
+## 稍后读取已接受的更新 {#read-an-update-outcome}
+
+所选 PHP SDK 3.18.1 可通过稳定 ID 读取保留的更新,无需再次受理。`Client::updateOutcome($workflowId, $updateId)` 默认使用 `waitFor: 'completed'`:仍在等待时抛出 `UpdateStillPending`;已完成的结果可以合法地为 `null`。`updateOutcomeReceipt()` 默认使用 `waitFor: 'accepted'`,返回 Server 回执,以便将 `update_status`、`wait_timed_out` 与已完成结果分开检查。
+
+这些 GET 读取要求 `update_outcome_reads` capability(原生 Server 3.6.0 及以上)。不支持时 SDK 抛出 `LogicException`,不会重新提交更新。首次 `updateWorkflow()` 的等待异常保留调用方请求 ID。待完成的 GET 读取保留 `updateId`,但原始请求键可能不可用:此时 `$pending->requestId` 为 `''`,表示未知。请继续使用该更新 ID 读取;切勿将空键、推测键或内部哈希键当作原始请求 ID 提交。
+
+[已发布的 PHP 指南](https://php.durable-workflow.com/build/messages/#apply-a-tracked-update)展示处理器和客户端流程。[已安装 PHP 3.18.1 / 原生 Server 3.9.1 的验证](https://github.com/durable-workflow/sdk-php/pull/411#issuecomment-6855609359)确认从待完成到完成 null 的读取没有第二次更新受理,并验证了[完成请求大小处理](./server-config-reference.md#workflow-task-completion-size)。这些证据不代表共享 #216 的完整请求键验收或原生超时清理支持。
+
## 升级到 PHP SDK 3.12 至 3.14 {#upgrade-to-3-12-through-3-14}
PHP `^8.1`、Laravel 桥接的下限、worker 协议 `1.20` 和控制平面 `2` 与 3.11 相同。部署前请检查以下行为变化:
diff --git a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
index 7f18f63a04a..4a18066098d 100644
--- a/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
+++ b/i18n/zh-Hans/docusaurus-plugin-content-docs/current/polyglot/server-config-reference.md
@@ -50,7 +50,6 @@ PHP 2.x Server 还使用常规 Laravel 运行时设置,例如 `DB_*`、`REDIS_
| 原生 Server 没有命名空间持久化状态限制 | `DW_NAMESPACE_DURABLE_HARD_LIMITS`: 未设置或 `{}`
`DW_NAMESPACE_DURABLE_LIMITS`: 未设置或 `{}`
`DW_NAMESPACE_DURABLE_OVERRIDES`: 未设置或 `{}` |
| 原生 Server 没有命名空间请求准入限制 | `DW_NAMESPACE_ADMISSION_OVERRIDES`: 未设置或 `{}`
`DW_NAMESPACE_HARD_MAX_CONCURRENT_REQUESTS`: 未设置或为空
`DW_NAMESPACE_HARD_MAX_REQUESTS_PER_MINUTE`: 未设置或为空
`DW_NAMESPACE_MAX_CONCURRENT_REQUESTS`: 未设置或为空
`DW_NAMESPACE_MAX_REQUESTS_PER_MINUTE`: 未设置或为空 |
| 原生 Server 没有服务边界策略 | `DW_SERVICE_BOUNDARY_CROSS_NAMESPACE_DEFAULT`: 未设置或 `allow`
`DW_SERVICE_BOUNDARY_HARD_MAX_IN_FLIGHT`: 未设置或为空
`DW_SERVICE_BOUNDARY_HARD_RATE_LIMIT_PER_MINUTE`: 未设置或为空
`DW_SERVICE_BOUNDARY_MAX_IN_FLIGHT`: 未设置或为空
`DW_SERVICE_BOUNDARY_NAMESPACE_MAX_IN_FLIGHT`: 未设置或为空
`DW_SERVICE_BOUNDARY_NAMESPACE_OVERRIDES`: 未设置或 `{}`
`DW_SERVICE_BOUNDARY_NAMESPACE_RATE_LIMIT_PER_MINUTE`: 未设置或为空
`DW_SERVICE_BOUNDARY_RATE_LIMIT_PER_MINUTE`: 未设置或为空 |
-| 原生 Server 没有存储准入文件 | `DW_STORAGE_ADMISSION_FILE`: 未设置或为空
`DW_STORAGE_ADMISSION_SOURCE`: 未设置或为空 |
| 原生 Server 没有任务准入限制 | `DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: 未设置、为空或不是正数
`DW_ACTIVITY_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: 未设置、为空或不是正数
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE`: 未设置、为空或不是正数
`DW_ACTIVITY_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: 未设置、为空或不是正数
`DW_TASK_QUEUE_ADMISSION_OVERRIDES`: 未设置或 `{}`
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_NAMESPACE`: 未设置、为空或不是正数
`DW_WORKFLOW_TASK_MAX_ACTIVE_LEASES_PER_QUEUE`: 未设置、为空或不是正数
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE`: 未设置、为空或不是正数
`DW_WORKFLOW_TASK_MAX_DISPATCHES_PER_MINUTE_PER_NAMESPACE`: 未设置、为空或不是正数 |
| 原生 Server 只实现一个 Worker 协议版本 | `DW_WORKER_PROTOCOL_VERSION`: 未设置或 `1.20` |
| 原生 Server 从不信任转发的归属请求头 | `DW_TRUST_FORWARDED_ATTRIBUTION_HEADERS`: 未设置或 `false` |
@@ -61,7 +60,9 @@ PHP 2.x Server 还使用常规 Laravel 运行时设置,例如 `DB_*`、`REDIS_
| 原生 Server 只将外部载荷存储在本地磁盘上 | `DW_EXTERNAL_PAYLOAD_S3_BUCKET`: 未设置或为空 |
| 原生 Server 只支持自身的令牌认证 | `DW_AUTH_BACKWARD_COMPATIBLE`: 未设置或 `true`
`DW_AUTH_PROVIDER`: 未设置或为空
`DW_PRINCIPAL_TOKENS`: 未设置或为空 |
-原生 Server 接受但忽略:`DW_ADMIN_SIGNATURE_KEY`、`DW_AUTH_METHOD_HEADER`、`DW_AUTH_STATUS_HEADER`、`DW_BOOTSTRAP_DELAY_SECONDS`、`DW_BOOTSTRAP_RETRIES`、`DW_CALLER_LABEL_HEADER`、`DW_CALLER_TYPE_HEADER`、`DW_COMPRESSION_ENABLED`、`DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`、`DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`、`DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`、`DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`、`DW_EXTERNAL_PAYLOAD_S3_REGION`、`DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`、`DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`、`DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`、`DW_MAX_HISTORY_EVENTS`、`DW_MAX_TASKS_PER_POLL`、`DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`、`DW_OBSERVABILITY_CONTEXT_ENABLED`、`DW_OPERATOR_SIGNATURE_KEY`、`DW_PACKAGE_PROVENANCE_PATH`、`DW_POLLING_CACHE_PATH`、`DW_QUERY_TASK_POLL_MAX_CONCURRENT`、`DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`、`DW_SIGNATURE_KEY`、`DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`、`DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`、`DW_STORAGE_ADMISSION_MAX_AGE_SECONDS`、`DW_V2_CACHE_VALIDATION_MODE`、`DW_V2_GUARDRAILS_BOOT`、`DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`、`DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`、`DW_V2_MATCHING_ROLE_QUEUE_WAKE`、`DW_V2_TASK_DISPATCH_MODE`、`DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`、`DW_V2_TENANCY_ENVIRONMENT`、`DW_V2_TENANCY_ORGANIZATION`、`DW_V2_TENANCY_PROJECT`、`DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`、`DW_V2_VALIDATE_CACHE_BACKEND`、`DW_WAKE_SIGNAL_TTL_SECONDS`、`DW_WORKER_LONG_POLL_MAX_CONCURRENT`、`DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`、`DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`、`DW_WORKER_POLL_INTERVAL_MS`、`DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`、`DW_WORKER_SIGNATURE_KEY`。
+原生 Server 接受但忽略:`DW_ADMIN_SIGNATURE_KEY`、`DW_AUTH_METHOD_HEADER`、`DW_AUTH_STATUS_HEADER`、`DW_BOOTSTRAP_DELAY_SECONDS`、`DW_BOOTSTRAP_RETRIES`、`DW_CALLER_LABEL_HEADER`、`DW_CALLER_TYPE_HEADER`、`DW_COMPRESSION_ENABLED`、`DW_DUE_TIMER_RECOVERY_SCAN_LIMIT`、`DW_EXPIRED_WORKFLOW_TASK_RECOVERY_TTL_SECONDS`、`DW_EXTERNAL_PAYLOAD_S3_ACCESS_KEY_ID`、`DW_EXTERNAL_PAYLOAD_S3_ENDPOINT`、`DW_EXTERNAL_PAYLOAD_S3_REGION`、`DW_EXTERNAL_PAYLOAD_S3_SECRET_ACCESS_KEY`、`DW_EXTERNAL_PAYLOAD_S3_SESSION_TOKEN`、`DW_EXTERNAL_PAYLOAD_S3_USE_PATH_STYLE_ENDPOINT`、`DW_MAX_HISTORY_EVENTS`、`DW_MAX_TASKS_PER_POLL`、`DW_OBSERVABILITY_BAGGAGE_ALLOWLIST`、`DW_OBSERVABILITY_CONTEXT_ENABLED`、`DW_OPERATOR_SIGNATURE_KEY`、`DW_PACKAGE_PROVENANCE_PATH`、`DW_POLLING_CACHE_PATH`、`DW_QUERY_TASK_POLL_MAX_CONCURRENT`、`DW_QUERY_TASK_POLL_MAX_CONCURRENT_PER_NAMESPACE`、`DW_SIGNATURE_KEY`、`DW_SQLITE_CLAIM_LOCK_TTL_SECONDS`、`DW_SQLITE_CLAIM_LOCK_WAIT_SECONDS`、`DW_V2_CACHE_VALIDATION_MODE`、`DW_V2_GUARDRAILS_BOOT`、`DW_V2_LIMIT_SEARCH_ATTRIBUTE_SIZE_BYTES`、`DW_V2_LIMIT_WARNING_THRESHOLD_PERCENT`、`DW_V2_MATCHING_ROLE_QUEUE_WAKE`、`DW_V2_TASK_DISPATCH_MODE`、`DW_V2_TASK_REPAIR_LOOP_THROTTLE_SECONDS`、`DW_V2_TENANCY_ENVIRONMENT`、`DW_V2_TENANCY_ORGANIZATION`、`DW_V2_TENANCY_PROJECT`、`DW_V2_UPDATE_WAIT_POLL_INTERVAL_MS`、`DW_V2_VALIDATE_CACHE_BACKEND`、`DW_WAKE_SIGNAL_TTL_SECONDS`、`DW_WORKER_LONG_POLL_MAX_CONCURRENT`、`DW_WORKER_LONG_POLL_MAX_CONCURRENT_PER_NAMESPACE`、`DW_WORKER_LONG_POLL_RESERVED_HTTP_WORKERS`、`DW_WORKER_POLL_INTERVAL_MS`、`DW_WORKER_POLL_SIGNAL_CHECK_INTERVAL_MS`、`DW_WORKER_SIGNATURE_KEY`。
+
+原生 3.9.1 支持通过操作方发布的本地观测启用存储准入控制。将 `DW_STORAGE_ADMISSION_FILE` 设为绝对路径,将 `DW_STORAGE_ADMISSION_SOURCE` 设为预期来源标识;`DW_STORAGE_ADMISSION_MAX_AGE_SECONDS` 默认为 15(允许范围 1–300)。路径和来源均未设置时禁用。缺失、无效或过期观测会以 `503 storage_admission_unavailable` 拒绝新工作;`draining` 或 `fenced` 观测以 `503 storage_pressure` 拒绝。Readiness 同样返回 503,而数据库健康检查可能仍为 200。[已发布的 3.9.1 文件消费验证](https://github.com/durable-workflow/server/issues/951#issuecomment-6853859351)确认这些情况以及原子替换文件后的恢复;不验证物理配额测量或生产 Cloud 映射。这是准入控制,不是写入屏障或字节预留。所有者 UID 加固和 draining 期间的完成上传仍属于此已发布范围之外的工作。
原生 Server 没有服务器端任务队列租约上限或派发上限、预算组、命名空间请求准入、命名空间持久状态配额或保持中轮询上限,目前也没有对应的原生替代方案。每个原生 Server 进程最多打开四个数据库连接。查询任务有固定上限:每个命名空间最多16个待处理或已租用的任务,超出后新查询会与 PHP 一样以 HTTP `429` 和 `query_task_queue_full` 被拒绝;该上限不可配置。要在原生 Server 上限制任务并发,请调整每个 SDK Worker 的执行槽数量和 Worker 数量。PHP 2.x 的控制项见[任务队列准入](/docs/polyglot/task-queue-admission)。
@@ -334,7 +335,9 @@ Rust SDK 4.16 完成规划器遵守公布的正整数上限,即使它低于普
Python SDK 2.17 和 Rust SDK 4.15 包含类型化拒绝处理。Server 3.8.0 的已发布 Python 验证在收到 HTTP 413 前遇到 `httpx.ReadError`,使 workflow 保持待定。原生 3.9.1 通过有界丢弃请求余下数据修复此响应路径:最多 64 MiB、最多两秒,然后返回原始拒绝并关闭连接。超出任一边界的上传仍可能遇到传输错误。
-已发布的 Python SDK 2.17.1 与经过验证的原生 Server 3.9.1(linux/amd64、SQLite)现已通过[实际安装 Worker 的验证](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512):预算内 300 × 10 KB fan-out;过大的完成请求只产生一次类型化 413 和一次结构性失败,部分 activity 为零;随后同一 Worker 成功执行后续任务。此结果只验证这个确切的 Python/Server 组合。PHP 仍需独立的安装后验证;Rust 4.16 的验证如下。共享 #228 仍未关闭。共享 #216 的请求键验证是独立的。
+已发布的 Python SDK 2.17.1 与经过验证的原生 Server 3.9.1(linux/amd64、SQLite)现已通过[实际安装 Worker 的验证](https://github.com/durable-workflow/.github/issues/228#issuecomment-6853834512):预算内 300 × 10 KB fan-out;过大的完成请求只产生一次类型化 413 和一次结构性失败,部分 activity 为零;随后同一 Worker 成功执行后续任务。此结果只验证这个确切的 Python/Server 组合。
+
+[已发布 PHP SDK 3.18.1 / 原生 Server 3.9.1 的验证](https://github.com/durable-workflow/.github/issues/228#issuecomment-6855610551)(PHP 8.3.36、linux/amd64、SQLite)也通过了无外部存储的 300 × 10 KB、60 × 450 KB 完成请求仅产生一次类型化 413 和一次结构性失败且部分 activity 为零、随后同一 Worker 完成新工作的验证。此结果只验证这个确切的 PHP/Server 组合;Rust 4.16 的验证如下。共享 #228 的跨产品关闭和共享 #216 的请求键验收仍需分别处理。
要让完成请求保持在上限之内:
diff --git a/i18n/zh-Hans/source-hashes.json b/i18n/zh-Hans/source-hashes.json
index be578197d37..70453603f07 100644
--- a/i18n/zh-Hans/source-hashes.json
+++ b/i18n/zh-Hans/source-hashes.json
@@ -80,7 +80,7 @@
"polyglot/invocable-carrier.md": "00bcf878b7bac1be90718b73f0a626a99cf0e111414ac0854c6491d159798c01",
"polyglot/invocable-php-handler.md": "3b678eb1d69fe32dfcfdc05d36b33e49e01b79d7216bd784f6a61a6f1c3c3a13",
"polyglot/namespace-auth-workers.md": "fee5e52a18637814f60aeb419f7ebc99ce4927089dfb748073697a8218bd47bb",
- "polyglot/php.md": "309e83622754b9d9abc65807280f2dab175a009054a001456ef1316776f11101",
+ "polyglot/php.md": "744b184b50b5de82f2d287beac0aa491c21b41b6287c2aed63ed7eb123f2e02a",
"polyglot/polling-patterns.md": "30875099a23731c6c471b481a771378acc6ff57eed2fda4405a509057534c989",
"polyglot/portable-worker-affinity.md": "40973c6a31a76845b4f95e9a505e68ad76abd5174bbdccf37993cdebc8904959",
"polyglot/prerelease-history-migration.md": "a57f05f492228a8a67791f9152648a1e5f80856325b78777cf63b6ef49b7413c",
@@ -89,7 +89,7 @@
"polyglot/rust-cloud-quickstart.md": "2303434fc9302a81a8381ad4836423ef9952eb3201a4574c432254e3cb68c5f3",
"polyglot/rust.md": "2cc511074e6d0ce8ababa0ccd6acbdaa7df3bf5d8c67ae5ef2fa07d75a05d2e7",
"polyglot/server-api-reference.md": "8bac825f11f7aa3f2a335cf3d1dcdc951219f11d6702e9fe3502d3803fd1e2a5",
- "polyglot/server-config-reference.md": "86cdcdac61326d12675b645bca90b2b18b107ee3d9ab8d839aef2eca823c40f0",
+ "polyglot/server-config-reference.md": "e7dc68015e9c1e43b102aa657c0dd2bc12487ef344cb10bdb2379c297114431f",
"polyglot/server-role-topology.md": "3d048f0c6b5f179399622508f51e67fff8aa5a6d5b2492533fc720eeec2c27f2",
"polyglot/server.md": "55d5962ff5da8e29fbe0d568635c4d88ce539e39fdddce292df04b95b3561546",
"polyglot/service-operations.md": "a2ee46ac8d2e4f18aed4e3cb47a4f0b36f51ccc67f1e841efb99f0297391cf27",