nexus: #114 decides where Nexus lives and not what a `nexus:` step promises — typed signature, identity propagation, cancellation, idempotency, timeouts and the local posture need deciding through one complete cross-team use case before the node kind exists
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Observed behavior
At 7530b29, docs/ARCHITECTURE.md's primitive table ends with Nexus as the one row with no surface, and its "Nexus" section sketches consuming and exposing directions. #114 decides placement: durable invocation is grammar (a Node kind on both drivers' terms), administration is temporal.nexus_* plugin tasks, and the local driver "likely refuses nexus steps with a message naming why". The only Nexus reference in code is the RegisterNexusService stub the versioning test's registry needs.
The tree already has four composition concepts whose ownership, history, cancellation and upgrade contracts differ, and a nexus: step would be a fifth:
| Concept | Spelling today | History | Cancellation | Upgrade |
|---|---|---|---|---|
| Lexical reuse | call: |
the caller's own | the caller's | the caller's pin |
| Separate child execution | none (ARCHITECTURE.md names it as what call: is not) |
its own | propagated by the parent | its own pin |
| Long-lived entity | entity_key, signals, signal_with_start |
its own, per key | its own | its own pin |
| Cross-team durable operation | none (Nexus) | caller records the operation; handler owns the work | Nexus cancellation across the boundary | independent |
What #114 does not decide, and what has to be decided before a node kind is added to workflow.proto (invariant 1 makes that the point of no cheap return):
- Typed signature. How an operation's input and output types are declared on the caller's side, against what the handler's Flowstate workflow declares (
inputs:/outputs:), and whether theplugins:-style minimum-version or a digest pins the handler's contract at submit. - Identity. Whether the caller's
WorkloadIdentitycrosses the boundary, as what (a Nexus header, an assertion from the issuer the federation machinery already mints), and what the handler'ssignals:-style policy sees as the principal.docs/MCP_AUTHORIZATION.md's refusal ofact/may_actdelegation is the fail-closed precedent. - Cancellation and compensation. Whether cancelling the caller cancels the operation, whether the handler's
undo:runs, and in what order relative to the caller's own compensation. - Idempotency. Whether a retried Nexus start is deduplicated by the handler and on what key; #1677's call identity is the natural request id.
- Timeouts. Schedule-to-close for the operation, and whether a handler's long
wait_for_signalis the caller's problem. - Local posture. #114 suggests refusal on the local driver; the alternative is a declared test double (a
flow teststub for the operation's contract) that is explicit about which transport and deployment failures it cannot reproduce. Refusal is honest and makes every Nexus workflow untestable locally; a typed stub keeps invariant 3 if the stub is the operation's contract, not its behavior.
Desired outcome
A design record that decides each of the six above, driven by one complete use case rather than the primitive: a tenant-provisioning operation that one team exposes from a Flowstate workflow and another team's Flowstate workflow invokes, cancels, and queries, across two namespaces of one dev cluster. The record shows the caller's Flowfile, the handler's Flowfile, the endpoint registration (as temporal.nexus_endpoint_create per #114), and the flow test file for the caller.
The record keeps the four concepts in the table distinct in spelling. Reusing call: for a Nexus operation would shorten the language and hide four different cancellation and upgrade contracts behind one word; the record should say why a separate spelling is the smaller cost, or show the composition rule that makes one spelling safe.
Acceptance criteria
- The record answers the six questions with the constraint that decides each, citing the existing mechanism it reuses (federation assertions for identity,
undo:ordering for compensation, #1677 for idempotency). - The use case's two Flowfiles validate today's grammar except for the one new node kind, so the diff the record implies is the node kind and the driver support, not a language change.
- A conformance case is specified for both drivers before implementation: the durable driver runs the operation across two namespaces; the local driver either refuses with the decided message or runs the decided stub, and the record says which.
Constraints and dependencies
- Sequenced after the guarantees the operation will lean on: per-action authorization (#1733) so a caller namespace's principal can be refused an operation, and call identity (#1677) so a retried start is recognizable.
- Nexus is available self-hosted and in Temporal Cloud, which keeps invariant 10; the record should name the minimum Temporal server version.
- Adjacent: #114, #1677, #1733, #106 (modules), #107 (self-provisioning),
docs/ARCHITECTURE.md"Nexus".
Open questions
- Whether exposing precedes consuming or the reverse; the use case needs both, and one has to be the stub while the other is built.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with docs/ARCHITECTURE.md, the RegisterNexusService stub, workflow.proto, and the referenced issues #114, #1677, and #1733. Produce the design record around the tenant-provisioning use case, covering the six open decisions, both Flowfiles, endpoint registration, flow test coverage, driver conformance, and the minimum Temporal server version.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend, distributed-systems, documentation
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100