# LS1009: Domain Reads a Nondeterministic Value

## Intent

LS1009 is a compiler check that reports a read of the clock, randomness, or a new identifier in Domain, the project that holds business rules, because such reads answer differently on each call and tests cannot repeat them. This page states what the rule reports, where the warning sits, and how to pass the value in as an argument.

## Reference

### What the rule enforces

LS1009 enforces [Pass nondeterministic values into Domain](https://litespec.dev/2.0.0/backend/domain.md#pass-nondeterministic-values-into-domain) (`litespec/backend/domain#pass-nondeterministic-values-into-domain`). It runs in Domain only. Its category is `LiteSpec.Domain`. It reports a warning and is enabled by default, as the [Analyzers overview](https://litespec.dev/2.0.0/analyzers/README.md) describes.

### What the rule reports

The rule reports reads of `DateTime.Now`, `DateTime.UtcNow`, `DateTime.Today`, `DateTimeOffset.Now`, `DateTimeOffset.UtcNow`, `TimeProvider.System`, `Environment.TickCount`, `Environment.TickCount64`, `Random.Shared`, `Guid.NewGuid`, `Guid.CreateVersion7`, `Stopwatch.GetTimestamp`, `Stopwatch.StartNew`, any `RandomNumberGenerator` call, and `new Random()`. The diagnostic sits on the member name, on the invoked method name, or on the type in `new Random()`.

### Failing example

```csharp
public DateTime Stamp()
{
    return DateTime.UtcNow;
}
```

### Passing example

```csharp
public DateTime Stamp(DateTime utcNow)
{
    return utcNow;
}
```

### How to fix

Pass time, randomness, and new identifiers in as arguments from the caller, and create version 7 identifiers with `Guid.CreateVersion7` in the calling layer.

## Notes

### What the rule ignores

The rule does not report values passed in as arguments, deterministic members such as `DateTime.MinValue`, `Guid.Empty`, or `Guid.Parse`, instance calls on an injected clock such as `clock.GetUtcNow()`, or names inside `nameof`. It does not run outside Domain.
