You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Document namespace request limits and every missing Server contract variable #335
Current state: documentation is complete and accepted, all eight locales delivered in 6370505761. PR398 mergebae91, exact checks/artifact39988187354/actualPages39990119970 and sixteen live-route checks pass. The separate malformed/non-object policy JSON product defect remains open in Server704; no released product fix is claimed. Closing this documentation issue preserves that explicit product follow-through.
Problem
The config reference names dw-contract.php as canonical, yet 32 of its 161 DW_* variables appear nowhere in the docs. Missing groups:
external payload namespace quotas and S3 transport settings;
service boundary limits;
storage admission.
Operators therefore can't find the Server's namespace request limits, the one-minute window, overrides and 429 behavior, or which routes count against them. Worker routes are exempt.
Acceptance criteria
Every DW_* variable in dw-contract.php appears in the config reference with its default, purpose and legacy alias.
The admission guide explains namespace request admission: counted routes, the minute window and burst behavior, the concurrency cap, overrides, hard caps, and the 429/503 reasons with retry_after_seconds.
A CI check fails when a contract variable is missing from the reference.
Additional scope from review (Slack miner case a8d890e6). The missing variables include the per-namespace durable-state limits (DW_NAMESPACE_DURABLE_LIMITS, hard limits and overrides). These cap open runs, open waits, timers, schedules and other rows, and refuse with 429 namespace_<resource>_exhausted. Every non-terminal run counts in its own namespace, so a parent waiting on a child or a service call holds an open run.
Users can't predict what a child workflow or service-operation handler consumes, or how to interpret those refusals. Please include in the reference:
Per-namespace overrides can raise or lower the defaults. Configured hard caps and the implementation ceilings still apply on top of any override.
Additional acceptance: the guide states that the limits are cluster-wide and shows a worked example of a default, an override and a hard cap interacting.
Product review and refreshed published-artifact inventory: this is a discoverability and documentation-contract gap for configuration already declared by the PHP Server. Documenting it does not replace qualification of the admission behavior or any product defect found while testing it.
The immutable published PHP Server2.11.0 image durableworkflow/server@sha256:b29157eb2cf844916debbbb3c01b3257672e0dece778a9c6fa539043a3038f02 contains 164 DW_* variables. Its extracted config/dw-contract.php is byte-identical to the published2.11.0 source, SHA256 4e6ab12b029d7da3d0c76d082f3b0901c3d234651721c74d296ebe24ba142f69.
A literal-name inventory finds 35 variables missing from the current config reference and from every current English guide: 13 external-payload variables, 8 namespace admission/durable-limit variables, 5 service-boundary variables, 3 storage-admission variables, 2 observability variables, 2 per-namespace worker/query wait limits, runtime credentials and the v1 flag. This refreshes the original161/32 report; it does not establish defaults, aliases or runtime acceptance merely by finding names.
The reference update must use a published contract, identify its PHP/runtime version scope, retain the actual installed-artifact boundary, and ship all eight locales together. Admission claims must state the shared-cache requirement: the published polling cache uses the configured cache, with a dedicated directory for the image's file-cache baseline. A process-local array cache does not establish cross-process or cluster-wide coordination. Multi-node scope still requires the documented shared Redis baseline.
Next implementation is the complete default/purpose/legacy-alias reference, a machine-contract coverage check and the worked admission examples, followed by actual published-runtime controls. No selected tuple, native Server support, Cloud policy or limit is changed by this inventory.
Published PHP2.11.0 configuration follow-through: ten cold-process limit-resolution controls pass using the installed classes from immutable image durableworkflow/server@sha256:b29157eb2cf844916debbbb3c01b3257672e0dece778a9c6fa539043a3038f02. Each fresh, isolated PHP process bootstrapped the shipped Laravel application with its actual environment, then called NamespaceRequestAdmission::limits("payments"). No Server code, vendor or configuration source was replaced.
Environment case
Resolved rate/minute, concurrency
All five namespace-request controls unset
null, null
Defaults100 and8
100,8
Defaults100/8, payments override200/12, hard caps150/10
150,10
Defaults100/8, payments override40/3
40,3
Only hard caps75/6
75,6
Configured20000000/2048
10000000,1024 implementation ceilings
Legacy aliases90/5 without canonical values
90,5
Canonical rate100 and legacy alias90
100,null
Default rate100, payments rate overrideJSON null
100,null — null override falls back to the default
Rate 0
InvalidArgumentException: null or a positive integer is required
The worked guide example can therefore show an override raising or lowering a default while the hard cap remains non-bypassable. A null override does not disable a configured default; zero is not an unlimited sentinel.
Actual HTTP follow-through also passes on the normal image entrypoint, server-bootstrap, synthetic SQLite and the image's file cache: with rate2/minute, the first two /api/workflows reads returned200 and the third returned429 namespace_request_rate_exhausted, limit:2, retryable:true, and retry_after_seconds:26, matching Retry-After:26. /api/cluster/info and /api/health still returned200 after exhaustion. A further counted read succeeded after the next real wall-clock minute began, less than60seconds after the first reads. The application clock was not changed. This confirms a fixed minute boundary rather than a rolling60-second interval for this control.
Further actual HTTP controls pass on fresh containers of the same immutable image:
Exhausting the namespace rate budget also refuses plural /api/workers management reads, while singular /api/worker/register still reaches its normal422 input validation. This tests route exemption with an intentionally incomplete request, not successful SDK registration. Admin /api/system/metrics remains200 after exhaustion.
Invalid configured rate0 and a configured but unreachable Redis cache each return503 namespace_request_admission_unavailable, retryable:true and matching one-second body/header retry hints.
With one concurrency slot occupied by the installed admission service in a separate process running as the HTTP application's www-data user, the actual HTTP request returns429 namespace_request_concurrency_exhausted, limit:1, and matching one-second retry hints. After that service releases its slot, the HTTP request returns200. This is an HTTP refusal/release control with a service-level slot holder, not two simultaneous business HTTP operations.
Durable max_worker_registrations:0 refuses the first valid metadata registration with429 namespace_worker_registrations_exhausted, retryable:true and60-second retry hint. With limit1, the first registration returns201, the second429; deleting the synthetic first registration through the admin API allows the second to register201. The normal metrics response reports database-authoritative usage1/limit1 with measurement_status:available. These are metadata-only external registrations, not running SDK handlers.
The original concurrency fixture failed its429 assertion because its root CLI holder created root-owned0755 polling-cache directories and0644 lock files. A fresh root-holder counterfactual reproduces the coordination503; a fresh holder using the application user creates matching writable files and passes the429/release control. No product source changed. This is a fixture identity/permissions correction; retain it as setup evidence, not a claim that a Server defect was fixed. Shared file-cache processes need compatible access to coordination files.
Scope remains installed PHP configuration, single-container HTTP/file-cache and synthetic SQLite registration quotas. Shared Redis success across API replicas, other durable resource lifecycle controls, production databases and native Server remain separate qualification. All fixture containers and synthetic databases/cache were retired after their bounded controls; borrowed images and the selected compatibility tuple remain unchanged.
Shared-cache follow-through: two actual API containers using one Redis7.4.11 store/key prefix and a shared ephemeral SQLite database enforce one namespace budget. With rate2/minute, requests across replicaA/B return200,200,429,429. With concurrency1, the installed admission service holds a slot onA, an HTTP read onB returns429 namespace_request_concurrency_exhausted, and after releaseB returns200. No clock manipulation or direct cache/counter writes were used. Redis image is redis@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499, local image identity sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058. All task containers, network and database volume were retired and verified absent. This qualifies HTTP request coordination, not production SQL/HA/native or every workflow lifecycle. The separate malformed-override defect is recorded in6369150521 and is not relabeled as a successful product control.
Product finding from the #335 negative controls: malformed DW_NAMESPACE_ADMISSION_OVERRIDES JSON is silently dropped by published PHP Server2.11.0. This is a product validation gap, not a documentation-only resolution.
Tested immutable image: durableworkflow/server@sha256:b29157eb2cf844916debbbb3c01b3257672e0dece778a9c6fa539043a3038f02, normal entrypoint and server-bootstrap, synthetic SQLite/file cache, actual authenticated control-plane HTTP, and DW_ENV_AUDIT_STRICT=1. Other namespace request rate/concurrency defaults and hard caps were unset.
Override value
Two successive /api/workflows reads in one real minute
{"default":{"max_requests_per_minute":1}}
200,429 namespace_request_rate_exhausted
{"default":{"max_requests_per_minute":1} (missing final brace)
200,200; startup strict audit did not reject it
An independent cold-process installed-class control resolves the valid payments override to rate1, but the malformed equivalent to max_requests_per_minute:null. The public configuration parser uses json_decode(...) ?: [], so malformed input becomes an empty override map before admission validation sees it. Existing global defaults and hard caps still apply; the observed unlimited result requires their being unset. This does not demonstrate bypassing a configured hard cap.
The product correction should reject invalid override configuration rather than silently discarding an intended tenant policy, with negative controls through normal bootstrap/HTTP. This finding is handed to the Server product owner; no Server source was edited here. The draft guide will describe the current2.11.0 limitation and narrow its503 claim to configuration that the actual validator rejects. A validation workaround does not complete the product fix.
Both normal HTTP test containers and all synthetic databases/cache were retired. Evidence is scoped to the exact published2.11.0 image, not a newer image or native Server. The previously recorded numeric-invalid503 and unavailable-cache503 controls remain valid and distinct.
All-eight-locale documentation acceptance is complete for PR398, merged normally at bae91b90dd31e82c16c863d2900d88bed54d8c7a.
Exact candidate 5cb43b744823bd4c4c0b38460194fb7f4fd8a600 passes documentation qualification39984923785 and all applicable checks. The reviewed Sonar report6369400863 has zero new/accepted issues and hotspots. The five contract checks cover missing rows, wrong aliases, empty defaults/purposes and moving-source provenance.
All sixteen live reference/admission routes return200 with the exact canonical and all nine alternate URLs. All 164 variable rows per locale match committed names, defaults, purposes and aliases: 1,312 exact rows. All 104 new admission paragraphs and 16 rendered examples match source. The known malformed-JSON limitation and its product-finding link are present in every locale.
Interactive checks pass all eight locales: two real Copy operations per admission guide, both TOC anchors and reference/admission navigation. English, Japanese and Simplified Chinese are inspected at390px in light/dark themes for both references, twelve views, without page overflow.
The reference is explicitly the qualified published PHP2.11.0 contract, not a selected-tuple update or a native/Cloud/production-SQL/HA qualification. Installed controls remain in 6367799774. The separate malformed override JSON defect6369150521 remains unfixed by documentation; product-owner tracking is still required. This issue stays open for that handoff, with the documentation slice delivered.
All eight documentation locales are published and verified in delivery6370505761. The separate malformed/non-object policy JSON defect is accepted and tracked in Server #704, including configuration/bootstrap validation independent of name-audit strictness. That product fix is not claimed released by this documentation.
Closing the completed Website documentation slice with explicit #704 follow-through. The current guides retain the published PHP2.11.0 limitation and the selected release tuple remains unchanged.
Activity
rmcdaniel commentedon Oct 20, 2026
Additional scope from review (Slack miner case a8d890e6). The missing variables include the per-namespace durable-state limits (
DW_NAMESPACE_DURABLE_LIMITS, hard limits and overrides). These cap open runs, open waits, timers, schedules and other rows, and refuse with429 namespace_<resource>_exhausted. Every non-terminal run counts in its own namespace, so a parent waiting on a child or a service call holds an open run.Users can't predict what a child workflow or service-operation handler consumes, or how to interpret those refusals. Please include in the reference:
dw_namespace_durable_state_usagemetric.rmcdaniel commentedon Oct 21, 2026
Scope addition: the admission guide should state whether the limits are cluster-wide or per replica, and how overrides relate to the hard caps.
ServerPollingCache) under per-namespace keys (NamespaceRequestAdmission). Multi-node deployments require shared Redis, so adding API replicas doesn't multiply a configured limit.Additional acceptance: the guide states that the limits are cluster-wide and shows a worked example of a default, an override and a hard cap interacting.
rmcdaniel commentedon Oct 23, 2026
Product review and refreshed published-artifact inventory: this is a discoverability and documentation-contract gap for configuration already declared by the PHP Server. Documenting it does not replace qualification of the admission behavior or any product defect found while testing it.
The immutable published PHP Server2.11.0 image
durableworkflow/server@sha256:b29157eb2cf844916debbbb3c01b3257672e0dece778a9c6fa539043a3038f02contains 164DW_*variables. Its extractedconfig/dw-contract.phpis byte-identical to the published2.11.0 source, SHA2564e6ab12b029d7da3d0c76d082f3b0901c3d234651721c74d296ebe24ba142f69.A literal-name inventory finds 35 variables missing from the current config reference and from every current English guide: 13 external-payload variables, 8 namespace admission/durable-limit variables, 5 service-boundary variables, 3 storage-admission variables, 2 observability variables, 2 per-namespace worker/query wait limits, runtime credentials and the v1 flag. This refreshes the original161/32 report; it does not establish defaults, aliases or runtime acceptance merely by finding names.
The reference update must use a published contract, identify its PHP/runtime version scope, retain the actual installed-artifact boundary, and ship all eight locales together. Admission claims must state the shared-cache requirement: the published polling cache uses the configured cache, with a dedicated directory for the image's file-cache baseline. A process-local array cache does not establish cross-process or cluster-wide coordination. Multi-node scope still requires the documented shared Redis baseline.
Next implementation is the complete default/purpose/legacy-alias reference, a machine-contract coverage check and the worked admission examples, followed by actual published-runtime controls. No selected tuple, native Server support, Cloud policy or limit is changed by this inventory.
rmcdaniel commentedon Oct 23, 2026
Published PHP2.11.0 configuration follow-through: ten cold-process limit-resolution controls pass using the installed classes from immutable image
durableworkflow/server@sha256:b29157eb2cf844916debbbb3c01b3257672e0dece778a9c6fa539043a3038f02. Each fresh, isolated PHP process bootstrapped the shipped Laravel application with its actual environment, then calledNamespaceRequestAdmission::limits("payments"). No Server code, vendor or configuration source was replaced.null,nullnullnullnull— null override falls back to the default0InvalidArgumentException: null or a positive integer is requiredThe worked guide example can therefore show an override raising or lowering a default while the hard cap remains non-bypassable. A null override does not disable a configured default; zero is not an unlimited sentinel.
Actual HTTP follow-through also passes on the normal image entrypoint,
server-bootstrap, synthetic SQLite and the image's file cache: with rate2/minute, the first two/api/workflowsreads returned200 and the third returned429namespace_request_rate_exhausted,limit:2,retryable:true, andretry_after_seconds:26, matchingRetry-After:26./api/cluster/infoand/api/healthstill returned200 after exhaustion. A further counted read succeeded after the next real wall-clock minute began, less than60seconds after the first reads. The application clock was not changed. This confirms a fixed minute boundary rather than a rolling60-second interval for this control.Further actual HTTP controls pass on fresh containers of the same immutable image:
/api/workersmanagement reads, while singular/api/worker/registerstill reaches its normal422 input validation. This tests route exemption with an intentionally incomplete request, not successful SDK registration. Admin/api/system/metricsremains200 after exhaustion.namespace_request_admission_unavailable,retryable:trueand matching one-second body/header retry hints.www-datauser, the actual HTTP request returns429namespace_request_concurrency_exhausted,limit:1, and matching one-second retry hints. After that service releases its slot, the HTTP request returns200. This is an HTTP refusal/release control with a service-level slot holder, not two simultaneous business HTTP operations.max_worker_registrations:0refuses the first valid metadata registration with429namespace_worker_registrations_exhausted,retryable:trueand60-second retry hint. With limit1, the first registration returns201, the second429; deleting the synthetic first registration through the admin API allows the second to register201. The normal metrics response reports database-authoritative usage1/limit1 withmeasurement_status:available. These are metadata-only external registrations, not running SDK handlers.The original concurrency fixture failed its429 assertion because its root CLI holder created root-owned0755 polling-cache directories and0644 lock files. A fresh root-holder counterfactual reproduces the coordination503; a fresh holder using the application user creates matching writable files and passes the429/release control. No product source changed. This is a fixture identity/permissions correction; retain it as setup evidence, not a claim that a Server defect was fixed. Shared file-cache processes need compatible access to coordination files.
Scope remains installed PHP configuration, single-container HTTP/file-cache and synthetic SQLite registration quotas. Shared Redis success across API replicas, other durable resource lifecycle controls, production databases and native Server remain separate qualification. All fixture containers and synthetic databases/cache were retired after their bounded controls; borrowed images and the selected compatibility tuple remain unchanged.
Shared-cache follow-through: two actual API containers using one Redis7.4.11 store/key prefix and a shared ephemeral SQLite database enforce one namespace budget. With rate2/minute, requests across replicaA/B return200,200,429,429. With concurrency1, the installed admission service holds a slot onA, an HTTP read onB returns429
namespace_request_concurrency_exhausted, and after releaseB returns200. No clock manipulation or direct cache/counter writes were used. Redis image isredis@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499, local image identitysha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058. All task containers, network and database volume were retired and verified absent. This qualifies HTTP request coordination, not production SQL/HA/native or every workflow lifecycle. The separate malformed-override defect is recorded in6369150521 and is not relabeled as a successful product control.rmcdaniel commentedon Oct 23, 2026
Product finding from the #335 negative controls: malformed
DW_NAMESPACE_ADMISSION_OVERRIDESJSON is silently dropped by published PHP Server2.11.0. This is a product validation gap, not a documentation-only resolution.Tested immutable image:
durableworkflow/server@sha256:b29157eb2cf844916debbbb3c01b3257672e0dece778a9c6fa539043a3038f02, normal entrypoint andserver-bootstrap, synthetic SQLite/file cache, actual authenticated control-plane HTTP, andDW_ENV_AUDIT_STRICT=1. Other namespace request rate/concurrency defaults and hard caps were unset./api/workflowsreads in one real minute{"default":{"max_requests_per_minute":1}}namespace_request_rate_exhausted{"default":{"max_requests_per_minute":1}(missing final brace)An independent cold-process installed-class control resolves the valid payments override to rate1, but the malformed equivalent to
max_requests_per_minute:null. The public configuration parser usesjson_decode(...) ?: [], so malformed input becomes an empty override map before admission validation sees it. Existing global defaults and hard caps still apply; the observed unlimited result requires their being unset. This does not demonstrate bypassing a configured hard cap.The product correction should reject invalid override configuration rather than silently discarding an intended tenant policy, with negative controls through normal bootstrap/HTTP. This finding is handed to the Server product owner; no Server source was edited here. The draft guide will describe the current2.11.0 limitation and narrow its503 claim to configuration that the actual validator rejects. A validation workaround does not complete the product fix.
Both normal HTTP test containers and all synthetic databases/cache were retired. Evidence is scoped to the exact published2.11.0 image, not a newer image or native Server. The previously recorded numeric-invalid503 and unavailable-cache503 controls remain valid and distinct.
rmcdaniel commentedon Oct 23, 2026
All-eight-locale documentation acceptance is complete for PR398, merged normally at
bae91b90dd31e82c16c863d2900d88bed54d8c7a.5cb43b744823bd4c4c0b38460194fb7f4fd8a600passes documentation qualification39984923785 and all applicable checks. The reviewed Sonar report6369400863 has zero new/accepted issues and hotspots. The five contract checks cover missing rows, wrong aliases, empty defaults/purposes and moving-source provenance.a37c1e2ca2bf33c8a28126fc7628d7b9afceca04.Live English entry points: configuration reference, namespace HTTP admission and durable-state quotas. The corresponding routes in all eight locales are verified.
The reference is explicitly the qualified published PHP2.11.0 contract, not a selected-tuple update or a native/Cloud/production-SQL/HA qualification. Installed controls remain in 6367799774. The separate malformed override JSON defect6369150521 remains unfixed by documentation; product-owner tracking is still required. This issue stays open for that handoff, with the documentation slice delivered.
rmcdaniel commentedon Oct 23, 2026
All eight documentation locales are published and verified in delivery6370505761. The separate malformed/non-object policy JSON defect is accepted and tracked in Server #704, including configuration/bootstrap validation independent of name-audit strictness. That product fix is not claimed released by this documentation.
Closing the completed Website documentation slice with explicit #704 follow-through. The current guides retain the published PHP2.11.0 limitation and the selected release tuple remains unchanged.