diff --git a/CHANGELOG.md b/CHANGELOG.md
index 62163e4..5e5227b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,9 @@ and this project aims to follow [Semantic Versioning](https://semver.org/spec/v2
### Changed
- `HlcGuidFactory` constructor now enforces a 14-bit node ID constraint and throws `ArgumentOutOfRangeException` for values above `HlcGuidFactory.MaxNodeId` (16383). Previously, higher values were silently truncated in generated UUIDv7 values.
+### Documentation
+- Clarify `UuidV7Factory` collision and clock-skew guarantees, including the distinction between per-instance deterministic monotonicity and probabilistic cross-factory uniqueness.
+
## [1.3.1] - 2026-04-02
### Build
diff --git a/README.md b/README.md
index 0d9acaf..2cee190 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@ It is built around `TimeProvider` so that *time becomes an injectable dependency
- `UuidV7Factory` produces RFC 9562 UUIDv7 values as `Guid`
- Works with real or simulated time
- Configurable counter overflow behavior
+ - Per-instance monotonicity under clock rollback; cross-factory uniqueness remains probabilistic unless coordinated externally
- **Hybrid Logical Clock (HLC)**
- HLC timestamps and utilities to preserve causality in distributed simulations
@@ -74,6 +75,8 @@ var factory = new UuidV7Factory(TimeProvider.System);
var id = factory.NewGuid();
```
+For production services, prefer one shared `UuidV7Factory` instance per process. Its monotonic `(timestamp, counter)` allocation is deterministic within that live factory, including when wall time moves backwards. Independent factories, restarts, and multi-node fleets do not share that logical frontier; global uniqueness remains probabilistic and should be backed by storage uniqueness constraints where collisions are unacceptable.
+
### Vector Clock usage
```csharp
diff --git a/docs/changelog.md b/docs/changelog.md
index 50ca4a8..4f80cb8 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -10,6 +10,22 @@ This page mirrors the repository root `CHANGELOG.md`.
## [Unreleased]
+### Changed
+- `HlcGuidFactory` constructor now enforces a 14-bit node ID constraint and throws `ArgumentOutOfRangeException` for values above `HlcGuidFactory.MaxNodeId` (16383). Previously, higher values were silently truncated in generated UUIDv7 values.
+
+### Documentation
+- Clarify `UuidV7Factory` collision and clock-skew guarantees, including the distinction between per-instance deterministic monotonicity and probabilistic cross-factory uniqueness.
+
+## [1.3.1] - 2026-04-02
+
+### Build
+- Add GitHub Actions CI workflow for pushes and pull requests to `main`.
+- Add tag-driven release workflow to publish NuGet packages and create GitHub Releases.
+- Remove `setup-dotnet` lock-file caching requirement from workflows (no `packages.lock.json` needed).
+
+### Infrastructure
+- Add a repository `commit-msg` hook under `.githooks/` to strip auto-injected `Co-authored-by` trailers for Copilot/dexcompiler identities.
+
## [1.3.0] - 2026-02-19
### Fixed
@@ -56,4 +72,3 @@ This page mirrors the repository root `CHANGELOG.md`.
### Build
- Centralized common build properties in `Directory.Build.props`.
-
diff --git a/docs/guide/uuidv7.md b/docs/guide/uuidv7.md
index c4f19e0..ab0a95a 100644
--- a/docs/guide/uuidv7.md
+++ b/docs/guide/uuidv7.md
@@ -41,13 +41,30 @@ Console.WriteLine(id2.IsVersion7()); // true/false
## Monotonicity Guarantees
-Within a single millisecond, uniqueness and ordering are maintained by a **12-bit monotonic counter** appended to the 48-bit timestamp:
+Within a single factory instance, ordering is maintained by a **12-bit monotonic counter** appended to the 48-bit timestamp:
- When physical time moves to a new millisecond, the counter is reset to a **random start value** (masked into the lower half of the counter space to leave room for increments).
- Each successive `NewGuid()` within the same millisecond increments the counter.
+- If the wall clock moves backwards, the factory continues from the last logical `(timestamp, counter)` frontier instead of rewinding to the lower physical time.
- If the counter overflows (4,096 values exhausted), behavior depends on `CounterOverflowBehavior` (spin-wait, increment timestamp, or throw).
-This guarantees strict monotonicity without locks.
+This guarantees strict per-instance monotonicity without locks. The guarantee is scoped to the live factory instance, not to every factory in a fleet.
+
+## Collision and Clock-Skew Semantics
+
+`UuidV7Factory` separates local deterministic allocation from distributed probabilistic uniqueness:
+
+| Scope | Guarantee |
+|---|---|
+| One live factory instance | Deterministic, lock-free allocation of unique and monotonically increasing `(timestamp, counter)` pairs. Backward wall-clock movement does not rewind the logical frontier. |
+| Multiple threads sharing one factory | Same per-instance guarantee; CAS retries may occur under contention, but successful allocations do not reuse a pair. |
+| Multiple factories in one process | No shared logical frontier. Full UUID collisions are still extremely unlikely with independent CSPRNG state, but uniqueness is probabilistic. |
+| Multiple processes or machines | No built-in global coordination or node discriminator in `UuidV7Factory`. Clock skew can increase timestamp overlap, while uniqueness depends on randomized counter starts and the 62-bit random tail. |
+| Process restart | The new factory starts from current wall time and a random counter start. It does not inherit the previous logical frontier. |
+
+For production services, prefer a single `UuidV7Factory` singleton per process or service instance. The built-in DI helpers register it this way.
+
+For high-assurance shared namespaces, use a storage uniqueness constraint as the final guardrail and retry on conflict. If you need node-aware ordering semantics, consider `HlcGuidFactory`; it embeds a node ID and HLC timestamp, but it should be chosen for causal/node-aware ordering rather than treated as a blanket substitute for storage-level uniqueness.
## Counter Overflow Behavior
diff --git a/src/Abstractions/IUuidV7Factory.cs b/src/Abstractions/IUuidV7Factory.cs
index e1c0f51..04a2173 100644
--- a/src/Abstractions/IUuidV7Factory.cs
+++ b/src/Abstractions/IUuidV7Factory.cs
@@ -3,10 +3,15 @@ namespace Clockworks.Abstractions;
///
/// Abstraction for UUIDv7 generation with time control.
///
+///
+/// Implementations may provide deterministic monotonic allocation guarantees for a single factory instance. They do
+/// not imply deterministic global uniqueness across independent factories, processes, or machines unless the
+/// implementation explicitly documents such coordination.
+///
public interface IUuidV7Factory
{
///
- /// Creates a new UUIDv7.
+ /// Creates a new UUIDv7 value.
///
Guid NewGuid();
@@ -17,8 +22,7 @@ public interface IUuidV7Factory
(Guid Guid, long TimestampMs) NewGuidWithTimestamp();
///
- /// Batch generation for high-throughput scenarios.
- /// More efficient than calling NewGuid() in a loop.
+ /// Batch generation for high-throughput scenarios. More efficient than calling in a loop.
///
void NewGuids(Span destination);
}
diff --git a/src/Extensions.cs b/src/Extensions.cs
index 9e4f5ab..1b3af62 100644
--- a/src/Extensions.cs
+++ b/src/Extensions.cs
@@ -15,7 +15,8 @@ public static class ServiceCollectionExtensions
{
///
/// Adds the lock-free GUID factory with system time.
- /// Use this for most production scenarios.
+ /// Use this for most production scenarios. Registers a singleton factory so per-instance monotonic state is
+ /// shared across callers in the process.
///
public IServiceCollection AddLockFreeGuidFactory(
CounterOverflowBehavior overflowBehavior = CounterOverflowBehavior.SpinWait)
@@ -31,7 +32,8 @@ public IServiceCollection AddLockFreeGuidFactory(
///
/// Adds the lock-free GUID factory with a custom TimeProvider.
- /// Use this for testing or simulation.
+ /// Use this for testing or simulation. Registers a singleton factory so per-instance monotonic state is shared
+ /// across callers in the process.
///
public IServiceCollection AddLockFreeGuidFactory(
TimeProvider timeProvider,
diff --git a/src/UuidV7Factory.cs b/src/UuidV7Factory.cs
index c296567..8b16070 100644
--- a/src/UuidV7Factory.cs
+++ b/src/UuidV7Factory.cs
@@ -12,10 +12,19 @@ namespace Clockworks;
///
/// Implements RFC 9562 UUID version 7 and returns values as with:
///
-/// - Monotonic counter for sub-millisecond ordering
+/// - Per-instance monotonic counter for sub-millisecond ordering
/// - Lock-free synchronization using CAS operations
/// - Configurable overflow behavior
/// - TimeProvider integration for testing/simulation
+/// - Cryptographically secure random tail bytes by default
+///
+///
+/// Guarantee boundary: one live factory instance deterministically allocates unique, monotonically increasing
+/// (timestamp, counter) pairs, including when the supplied moves backwards. Global
+/// uniqueness across independent factories, processes, restarts, or machines remains probabilistic and depends on
+/// independent random tail bytes unless the caller adds coordination, node partitioning, or a storage uniqueness
+/// constraint.
+///
///
///
/// UUIDv7 bit layout (RFC 9562):
@@ -68,7 +77,8 @@ public sealed class UuidV7Factory : IUuidV7Factory, IDisposable
/// Time source (use for production).
///
/// Random number generator to use for the random portion of the UUID. If , a new
- /// cryptographically-secure RNG is created and owned by this instance.
+ /// cryptographically-secure RNG is created and owned by this instance. Production deployments should use a
+ /// cryptographically strong RNG with independent state for each factory.
///
/// Behavior to apply when the per-millisecond counter overflows.
public UuidV7Factory(