Skip to content

Document namespace request limits and every missing Server contract variable #335

Closed

Description

@rmcdaniel

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:

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.

Activity

  1. added
    documentationImprovements or additions to documentation
    kind:defectA public product behavior is incorrect
    priority:P3Lower-priority product improvement
    on Oct 20, 2026
  2. rmcdaniel commented on Oct 20, 2026

    @rmcdaniel
    MemberAuthor

    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:

    • which namespace each resource counts in;
    • the refusal reasons and retry hints;
    • the dw_namespace_durable_state_usage metric.
  3. rmcdaniel commented on Oct 21, 2026

    @rmcdaniel
    MemberAuthor

    Scope addition: the admission guide should state whether the limits are cluster-wide or per replica, and how overrides relate to the hard caps.

    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.

  4. rmcdaniel commented on Oct 23, 2026

    @rmcdaniel
    MemberAuthor

    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.

  5. rmcdaniel commented on Oct 23, 2026

    @rmcdaniel
    MemberAuthor

    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.

  6. rmcdaniel commented on Oct 23, 2026

    @rmcdaniel
    MemberAuthor

    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.

  7. rmcdaniel commented on Oct 23, 2026

    @rmcdaniel
    MemberAuthor

    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.
    • The published artifact39988187354 and actual Pages deployment39990119970 pass. Published Pages commit: a37c1e2ca2bf33c8a28126fc7628d7b9afceca04.
    • 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.

    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.

  8. rmcdaniel commented on Oct 23, 2026

    @rmcdaniel
    MemberAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationkind:defectA public product behavior is incorrectpriority:P3Lower-priority product improvement

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions