Repository navigation
Route authored Nexus calls to an explicit target namespace #111
Description
Reproduced user-visible failure
A published Python workflow in tenant-b cannot address a Nexus service catalog in shared through WorkflowContext.call_nexus_service(). Its worker sends the caller's namespace as X-Namespace, so the Server searches tenant-b and returns HTTP 404 endpoint_not_found. There is no target-namespace option on the published workflow command or client Nexus method.
Actual published run 38126009987, runner 3348f91949eef9426c1539f7d36df618d356dda7, starts authored Python workflows and a PHP SDK service worker. The shared caller reaches the registered operation with HTTP 200 and receives a real call ID. The tenant-b caller sends X-Namespace: tenant-b, gets the wrong-catalog 404, and remains pending while its task retries. Both use the same installed code, service registration and authorized disposable credential. No SDK or transport is simulated.
Frozen tuple: Server 2.5.19 at sha256:1b8621cb43340f979f4dc144aa51c32d0747aaad73f2b600130e0ee973aea352, Workflow 2.5.9, PHP SDK 2.2.7, Python SDK 2.5.4, CLI 2.2.3 and Waterline 2.9.1. The official artifact independently verifies at 3344233 bytes and SHA-256 4e4a07c10ff4e5d9994b401cdabe99024f3c27b1421d4ea79583f9a6781d4480.
This is one concrete finding from .github #122 and Server #394. Terminal service result handling is a separate qualification gap. The successful HTTP control establishes addressing and admission, not full Nexus completion.
Acceptance
- Expose target-namespace addressing on the ordinary client and durable workflow API, retaining the original caller namespace and run identity.
- Keep worker polling, registration, heartbeats and completion in the caller's namespace during concurrent service requests. Do not mutate the shared client namespace to route a call.
- Include the target in deterministic call identity and replay validation. Changing a recorded target must fail clearly. Preserve replay of existing same-namespace histories.
- Preserve credential roles and namespace authorization. External payload transport must use the intended target scope too.
- Add focused request and replay regressions. Re-run the actual published caller-worker fixture against the registered PHP service, with a cross-namespace admission row tied to the original caller and target. Retain explicit missing-endpoint and forbidden-namespace diagnostics.
- Publish the qualified fix and complete affected consumer follow-through. Keep full terminal, failure, cancellation and recovery claims gated on their corresponding runtime evidence.
Activity
rmcdaniel commentedon Oct 11, 2026
Published Python SDK 2.6.0rc1 has now executed actual caller workflows against PHP SDK workers in both
sharedandtenant-b. Both send Avro input to the shared catalog, preserve original caller/run identity, and receive the expected greeting from the linked PHP service.Exact tuple, requests and linked histories. The full workflow still returns
Startedwithout the service result because the durable call never reaches its linked terminal outcome. That backend work remains in durable-workflow/workflow#753. This issue stays open for the remaining acceptance cases, including recovery and oversized transport where applicable. Stable remains 2.5.4.rmcdaniel commentedon Oct 11, 2026
Delivered in Python SDK 2.5.5, exact source
095a00d0c0e08592767c11b3c4da132aafabf1cf, through #120.Source qualification passes supported Python versions, lint, types, the official codec/replay corpus, built-package checks and 33 real HTTP integration cases on the ordinary worker protocol. Publication verifies distribution metadata, the exact install and the default
pip install durable-workflowselecting 2.5.5. The final protected run passes without changing the checker or tag.An additional registry-only execution on October 11 uses installed Python 2.5.5 and PHP 2.2.8 against published Server 2.5.22, immutable image
sha256:5e0d2dc34f6199f4b01b77874e046c173d9697499f647cc0e9ca543ea89bee7c, bundled Workflow 2.5.11. It runs the image's normal Apache entrypoint with isolated SQLite and namespace-owned local payload storage. No SDK, runtime source or transport is substituted.All 12 cases pass: client and authored workflow calls,
sharedandtenant-bcallers targetingshared, each with empty arguments, nested Unicode/null/boolean/numeric values, and external arguments. Every PHP service run actually completes with the original arguments. All six authored callers complete. The call records preserve the caller namespace and original run while polling and completion continue in that namespace. Each oversized request carries the original Avro reference, size 19,140 bytes and SHA-256c0119c8aa6852335223ffc0f90dfdb86e22ba367012ef7a507bb4470c0cb6080, uploaded through the target namespace. The caller client retains its original namespace.Actual installed-client diagnostics also pass: a missing endpoint returns HTTP404
endpoint_not_found; a disallowed caller namespace returns HTTP403caller_namespace_not_allowedand starts no linked work.Wheel SHA-256:
a167d021b25b90580539d7d99b6cf6d2e7f66be1014bbe5f42f116609ccd22f5. Source distribution SHA-256:436d44f7f7e3b93801a75f84209b1c975b853b39d03a964010ed6a7355bd443d.The focused source replay cases also retain the original call identity and reject a changed recorded target. This stable backport excludes the pending leased-authoring change. Complete Nexus cancellation, deadline and recovery qualification stays tracked in #116 and the owning runtime work.