Date.now() determinism when used as condition timeout

In the typescript SDK, the Date object is replaced by Temporal to support Workflow determinism requirements. The behavior I’m observing, though, seems a bit more nuanced than simply having the value “set on the first invocation of the Workflow Task” (as described in the Typescript SDK docs).

For example, take the updatable-timer.ts example. The target time used in that example should be deterministic (line 10), but the Date.now() used as the timeout for the condition (line 41) shouldn’t be deterministic (or the timeout would never be reached).

Are there clear rules for when Date.now() (and other deterministic functions) are non-deterministic?

I think you confuse determinism with returning the same value on each call.

Condition on line 41 calls Date.now() many times. On each call, it returns a new time. The determinism requirement states that when this code is replayed, then the same set of values is returned during replay.

Just to add some clarification,
The time is set on each workflow task where a single workflow run (or execution) will typically have more than one task.

Thanks for your quick response. You’re right, I was confusing determinism with returning the same value on each call. That said, I’m still not clear on the distinction between the Date.now() calls on line 10 vs line 41.

Are you saying that the calls to Date.now() that are being made by condition are distinct from replay of code that calls Date.now(). And Date.now() is only returning new values in the former case because the condition has been started, but not completed. Once the condition is completed (either due to the signal or timer, in the example), subsequent calls to that Date.now() would return the same value. Is that in the right ballpark?

Condition is evaluated many times. Every time it is evaluated a potentially new value of Date.now() is returned.

The replay will execute all the workflow code in exactly the same sequence as it did the first time. It includes calling the condition at exactly the same points as it was called during the first execution.

Once the condition is completed (either due to the signal or timer, in the example), subsequent calls to that Date.now() would return the same value. Is that in the right ballpark?

Not really. Once the condition is completed it is not evaluated anymore. So there are no subsequent calls to Date.now() from that line of code.