What temporal coupling invariants prevent interference between concurrent sessions?

**Date of Record:** 2026 October 27 **Scope:** Applies when concurrent agentic sessions operate on shared state (databases, filesystems, message queues, or external services) whose operations interleave in time, and the interleaving can produce outcomes that neither session would have produced alone, requiring the system to preserve orderings that prevent interference. Does not apply to strictly isolated sessions or sessions whose operations are provably commutative.

Core Distinction

The separation between **individual session correctness** (each session's operations are locally correct) and **concurrent execution correctness** (the interleaved execution of multiple sessions produces acceptable outcomes). Relying on individual correctness creates the **Concurrency Interference**: each session behaves correctly within its own scope, but their interleaving causes outcomes that violate either session's expectations.

What Was Observed

In concurrent agent architectures, failing to preserve temporal coupling invariants produces three primary failure modes:

  1. **Read-Modify-Write Interleaving:** Session A reads value 5, Session B reads value 5, A writes 6, B writes 7. Final value is 7, but expected outcomes included 6 (A's contribution) and 7 (B's contribution). A's work is lost.
  2. **Time-of-Check-to-Time-of-Use:** Session A checks that a resource is available, Session B consumes it, Session A uses it assuming it was available. A's use is invalid but A's check was valid at check time.
  3. **Causal Reversal:** Session A's action causes B's action, B's action causes C's action, but C executes before A completes, and the causal chain is broken. Downstream observers see C→B→A ordering, which is causally impossible.

Recorded Elements

  1. **`operation-temporal-window-receipt`:** For each operation, the exact time window during which it is valid (its causal interval), so other sessions can avoid interfering operations within that window.
  2. **`concurrency-ordering-signature`:** For operations on shared state, the causal ordering (which operations must be visible before others), so interference-producing interleavings are detected.
  3. **`state-snapshot-version-receipt`:** For shared state, the version at which each session read it, so stale-read uses are detectable.
  4. **`interference-detection-signature`:** A post-execution check that compares the actual interleaved outcome to the acceptable outcomes for each participating session, flagging when neither session's expectation was met.

Condition of Validity

* **Applies when:** Sessions operate concurrently on shared state, their operations can interleave, and interleaving can produce outcomes neither session expected. * **Does not apply when:** Sessions are strictly isolated, or their operations are provably commutative (any interleaving produces the same outcome).

Decision Boundary

  1. **Do sessions operate on shared state concurrently?** If no, standard operations apply. If yes, proceed.
  2. **Is the `operation-temporal-window-receipt` maintained?** If yes, interference windows are visible. If no, sessions can unknowingly interfere.
  3. **Does `concurrency-ordering-signature` preserve the causal structure?** If yes, ordering is enforced. If no, interference is possible.
  4. **Conversely, when can operations proceed without ordering enforcement?** Only when the operations are verified commutative (any ordering produces the same outcome), or the operations are strictly isolated per session.

Operational Effect

  1. **Lost-Write Prevention:** Read-modify-write interleavings are detected.
  2. **TOCTOU Prevention:** Time-of-check-to-time-of-use gaps are enforced.
  3. **Causal Ordering:** Concurrent sessions preserve causal structure even under interleaving.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class InterferenceVerdict(Enum):
    NO_CONCURRENCY = auto()
    NON_INTERFERING = auto()
    INTERFERENCE_DETECTED = auto()
    CAUSAL_REVERSAL_DETECTED = auto()

@dataclass(frozen=True)
class Operation:
    operation_id: str
    session_id: str
    state_key: str
    operation_class: str  # "READ" | "WRITE" | "READ_MODIFY_WRITE"
    temporal_window_start: float
    temporal_window_end: float
    depends_on: tuple[str, ...]

@dataclass(frozen=True)
class ConcurrentState:
    operations: tuple[Operation, ...]

@dataclass(frozen=True)
class TemporalCouplingPolicy:
    require_ordering_for_rmw: bool

@dataclass(frozen=True)
class TemporalCouplingManifest:
    verdict: InterferenceVerdict
    directive: str
    manifest_digest: str

class TemporalCouplingGuard:
    @staticmethod
    def _hash(data: str) -> str:
        return hashlib.sha256(data.encode("utf-8")).hexdigest()

    @classmethod
    def evaluate_operations(
        cls, state: ConcurrentState, policy: TemporalCouplingPolicy
    ) -> TemporalCouplingManifest:
        
        # Gate 1: Single session
        sessions = {op.session_id for op in state.operations}
        if len(sessions) <= 1:
            digest = cls._hash(json.dumps({
                "sessions": str(len(sessions)),
                "ops": str(len(state.operations))
            }, sort_keys=True))
            return TemporalCouplingManifest(
                verdict=InterferenceVerdict.NO_CONCURRENCY,
                directive=f"PROCEED: Single session, no concurrency.",
                manifest_digest=digest
            )

        # Gate 2: Temporal overlap check per state key
        by_key: dict[str, list[Operation]] = {}
        for op in state.operations:
            by_key.setdefault(op.state_key, []).append(op)

        for key, ops in by_key.items():
            # Check for overlapping READ_MODIFY_WRITE
            rmw_ops = [o for o in ops if o.operation_class == "READ_MODIFY_WRITE"]
            for i in range(len(rmw_ops)):
                for j in range(i+1, len(rmw_ops)):
                    a, b = rmw_ops[i], rmw_ops[j]
                    if a.session_id == b.session_id:
                        continue
                    # Overlapping windows means RMW interference
                    if a.temporal_window_start < b.temporal_window_end and b.temporal_window_start < a.temporal_window_end:
                        if policy.require_ordering_for_rmw:
                            return TemporalCouplingManifest(
                                verdict=InterferenceVerdict.INTERFERENCE_DETECTED,
                                directive=f"HALT: RMW interference on {key} between {a.operation_id} and {b.operation_id}.",
                                manifest_digest=cls._hash(f"RMW_INTERFERENCE:{key}")
                            )

        # Gate 3: Causal reversal check
        op_map = {op.operation_id: op for op in state.operations}
        for op in state.operations:
            for dep_id in op.depends_on:
                dep = op_map.get(dep_id)
                if dep and op.temporal_window_start < dep.temporal_window_end and op.session_id != dep.session_id:
                    return TemporalCouplingManifest(
                        verdict=InterferenceVerdict.CAUSAL_REVERSAL_DETECTED,
                        directive=f"HALT: Operation {op.operation_id} depends on {dep_id} but starts before dep ends.",
                        manifest_digest=cls._hash(f"CAUSAL_REVERSAL:{op.operation_id}")
                    )

        # Gate 4: Non-interfering
        digest = cls._hash(json.dumps({
            "sessions": tuple(sorted(sessions)),
            "ops": tuple(sorted(op.operation_id for op in state.operations)),
            "state_keys": tuple(sorted(by_key.keys()))
        }, sort_keys=True))
        
        return TemporalCouplingManifest(
            verdict=InterferenceVerdict.NON_INTERFERING,
            directive=f"PROCEED: {len(sessions)} sessions, {len(state.operations)} ops, no interference.",
            manifest_digest=digest
        )