Skip to main content

Determinism Model

IntentusNet enforces determinism at specific boundaries while allowing nondeterminism where appropriate. This document maps out exactly where each applies.

Determinism Boundaries​

Fully Deterministic Operations​

These operations produce identical results given identical inputs:

1. Agent Ordering​

# DETERMINISTIC: Same agents + same intent = same order
def compute_order(agents: List[AgentDefinition]) -> List[AgentDefinition]:
return sorted(agents, key=lambda a: (
0 if a.nodeId is None else 1,
a.nodePriority,
a.name
))

Guarantee: The ordering algorithm has no randomness, no timestamp dependencies, and no external state.

2. Fallback Sequence​

# DETERMINISTIC: Fallback order matches agent ordering
for agent in ordered_agents:
response = agent.handle(envelope)
if response.status == "success":
break

Guarantee: Agents are tried in the same order every time.

3. Policy Evaluation​

# DETERMINISTIC: Same rules + same envelope = same decision
for rule in policy_rules:
if rule.matches(envelope):
return rule.action

Guarantee: Policy rules are evaluated in definition order with no external dependencies.

4. Envelope Hashing​

# DETERMINISTIC: Same envelope = same hash
def compute_hash(envelope: dict) -> str:
canonical = json.dumps(envelope, sort_keys=True, separators=(',', ':'))
return f"sha256:{hashlib.sha256(canonical.encode()).hexdigest()}"

Guarantee: Canonical JSON serialization ensures stable hashing.

5. Sequence Numbers​

# DETERMINISTIC: Events numbered sequentially
class DeterministicClock:
def __init__(self):
self._seq = 0

def next(self) -> int:
self._seq += 1
return self._seq

Guarantee: No wall-clock dependencies, pure sequence.

Controlled Nondeterminism​

These operations are nondeterministic but their outputs are captured for replay:

1. Timestamps​

# NONDETERMINISTIC at creation, DETERMINISTIC on replay
timestamp = datetime.utcnow().isoformat()
record.header.createdUtcIso = timestamp
# Replay uses recorded timestamp

Handling: Timestamps are recorded; replay returns recorded values.

2. Execution IDs​

# NONDETERMINISTIC at creation
execution_id = f"exec-{secrets.token_hex(8)}"
# But stable for the lifetime of the record

Handling: Generated once, then immutable in the record.

3. Trace IDs​

# NONDETERMINISTIC if not provided
if not envelope.metadata.traceId:
envelope.metadata.traceId = generate_trace_id()

Handling: Generated if missing, but recorded; replay preserves the value.

External Nondeterminism​

These are outside IntentusNet's control:

1. Agent Behavior​

class MyAgent(BaseAgent):
def handle_intent(self, env: IntentEnvelope) -> AgentResponse:
# This may call an LLM, access databases, etc.
# IntentusNet doesn't control this
result = self.llm.generate(env.payload["prompt"])
return AgentResponse.success({"result": result}, agent=self.name)

Handling: IntentusNet records the response, enabling deterministic replay.

2. Model Outputs​

# LLM outputs are nondeterministic
response = openai.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
# May differ between calls, even with temperature=0

Handling: The output is recorded; replay returns the recorded output.

3. Network Latency​

# Timing varies
start = time.time()
response = agent.handle(envelope)
latency = time.time() - start # Varies each run

Handling: Latency is recorded for observability but doesn't affect determinism.

4. External Services​

# External service state is unknown
response = requests.get("https://api.example.com/data")
# May return different data each time

Handling: The response is captured in the agent's output.

Determinism Verification​

You can verify determinism properties:

def test_routing_determinism():
"""Verify routing is deterministic."""
runtime = IntentusRuntime()
register_test_agents(runtime)

envelope = create_test_envelope()

# Run 100 times
selections = []
for _ in range(100):
# Disable recording to avoid side effects
response = runtime.router.route_intent(envelope)
selections.append(response.metadata["selected_agent"])

# All should be identical
assert len(set(selections)) == 1

def test_hash_determinism():
"""Verify hashing is deterministic."""
envelope = create_test_envelope()

hashes = [compute_envelope_hash(envelope.to_dict()) for _ in range(100)]

assert len(set(hashes)) == 1

Replay Determinism​

Replay is deterministic because it doesn't re-execute:

Breaking Determinism​

Avoid these patterns that break determinism:

Don't: Random Agent Selection​

# BAD: Non-deterministic
import random
selected = random.choice(matching_agents)

Don't: Time-Based Selection​

# BAD: Non-deterministic
if datetime.now().hour < 12:
selected = morning_agent
else:
selected = afternoon_agent

Don't: External State in Routing​

# BAD: Non-deterministic
load = get_agent_load(agent)
if load < 0.5:
selected = agent

Preserving Determinism​

These patterns preserve determinism:

Do: Configuration-Based Priority​

# GOOD: Deterministic
AgentDefinition(name="primary", nodePriority=10)
AgentDefinition(name="fallback", nodePriority=100)

Do: Explicit Targeting​

# GOOD: Deterministic
RoutingOptions(targetAgent="specific-agent")

Do: Version-Based Selection​

# GOOD: Deterministic
Capability(intent=IntentRef(name="Process", version="2.0"))

Summary Table​

OperationDeterministic?Recorded?Replayable?
Agent orderingYesN/AN/A
Fallback sequenceYesYesYes
Policy evaluationYesYesYes
Envelope hashYesYesYes
Sequence numbersYesYesYes
TimestampsNoYesYes
Execution IDNoYesYes
Agent behaviorNoYesYes
Model outputNoYesYes
Network latencyNoYesN/A

Next Steps​