Skip to main content

Gaussian resource-contention fields for multi-agent coordination

Project description

causal-field

Replace hard mutex locks with Gaussian interference fields.

causal-field implements probabilistic resource coordination for multi-agent systems. Instead of hard locks that block, agents project Gaussian "splats" into a shared latent space — overlapping splats signal contention before conflict occurs. Inspired by 3D Gaussian Splatting.

pip install causal-field

PyPI version Downloads Python 3.10+ License: MIT CI


The idea

Traditional locks are binary: locked or free. Under contention, agents queue up and throughput collapses.

causal-field treats resource occupancy as a continuous probability landscape. Each agent projects a Gaussian splat at the resource's semantic coordinate. Before acquiring, an agent reads the total interference at that coordinate:

  • Interference below threshold → acquired (proceed normally)
  • Interference above threshold → soft-blocked (defer, retry later, or fallback)

Agents sense each other's intent — not just their current state.


Quickstart

from causal_field import CausalField, render_ascii

field = CausalField(dim=64)

# Two agents want the same resource
field.soft_acquire("agent-A", "file_write:/data/output.csv")
result = field.soft_acquire("agent-B", "file_write:/data/output.csv")

print(result)
# {"acquired": False, "interference": 0.91, "resource": "file_write:/data/output.csv", ...}

# Visualize in the terminal
print(render_ascii(field))

ASCII heatmap (zero dependencies)

+------------------------------------------------------------+
|                                                            |
|                    ░░░░                                    |
|                  ░░▒▒▒▒░░                                  |
|                ░░▒▒▓▓▓▒▒░░                                 |
|               ░▒▒▓▓██████▓▒░                               |
|               ░▒▒▓▓██████▓▒░                               |
|                ░░▒▒▓▓▓▒▒░░                                 |
|                  ░░▒▒▒▒░░                                  |
+------------------------------------------------------------+
  [agent-A] file_write:/data/output.csv  ████████░░ 0.80
  [agent-B] file_write:/data/output.csv  ████████░░ 0.80

High-intensity zones (heavy contention) appear as ; low as or space.


Benchmark

from causal_field import benchmark
print(benchmark(n_agents=10, n_rounds=1000)["note"])
# "Soft-lock is 1.4x faster than threading.Lock (10 agents, 1000 rounds, dim=64)"

Soft-lock wins when:

  • Many agents but sparse contention (most acquire without blocking)
  • Read-heavy workloads (threshold=0.95 — almost never blocked)
  • You need routing not serialization (soft-blocked agents can fallback, not deadlock)

threading.Lock wins when:

  • You need strict mutual exclusion (critical sections with real shared memory)
  • Two or fewer agents (no benefit from contention awareness)

Benchmark (concurrent, real threads)

from causal_field import contention_benchmark
result = contention_benchmark(n_agents=8, n_rounds=200, n_resources=2)
print(result["verdict"])
# "Soft-lock: 14,200 ops/s (p50=0.04ms, p99=0.18ms, 12% collision rate)
#  Mutex: 11,800 ops/s (p50=0.05ms, p99=0.31ms)
#  Soft-lock is 1.2x faster under 8-agent contention on 2 resources."

contention_benchmark() uses real threading.Thread objects competing concurrently — not a sequential simulation. Collision rate reflects actual contention under the test load. Soft-lock wins when contention is sparse; threading.Lock wins for strict serialization.


Per-resource-type thresholds

from causal_field import SOFT_LOCK_THRESHOLDS
print(SOFT_LOCK_THRESHOLDS)
# {
#   "file_read":  0.95,   # permissive — reads rarely conflict
#   "file_write": 0.82,   # aggressive — writes need protection
#   "gpu":        0.78,   # most aggressive — GPU is singular
#   "db_write":   0.80,
#   "default":    0.90,
# }

Resources are classified by prefix — file_write:*, gpu:*, db_write:*. Threshold selection is automatic.


Semantic coordinates

Resources are embedded into the field using nomic-embed-text (via local Ollama). Semantically similar resources land near each other — "write_file reports.csv" and "save reports.csv" will detect mutual contention. Falls back to deterministic SHA-256 hashing when Ollama is unavailable.

# Optional: install Ollama for semantic embeddings
pip install causal-field[embed]

Adaptive sigma

After each acquire/release, adjust the splat's spread based on outcome:

# Collision detected (splat was too wide, blocked others unnecessarily)
field.adjust_sigma("agent-A", "file_write:/data/out.csv", "collision")
# → sigma shrinks by 15%

# False positive (blocked but no real conflict existed)
field.adjust_sigma("agent-A", "file_write:/data/out.csv", "false_positive")
# → sigma grows by 15%

SplatOptimizer

Runs gradient descent during idle cycles to drift inactive splats apart, reducing future contention before it starts:

from causal_field import CausalField, SplatOptimizer

opt = SplatOptimizer(field, lr=0.05, max_steps=200)
result = opt.run()
print(result)
# {"steps": 47, "initial_loss": 2.3, "final_loss": 0.1, "converged": True, "frozen_splats": 2}

Active splats (mid-task, active=True) are never moved — only idle splats are optimized.


matplotlib visualizer (optional)

from causal_field import CausalField, visualize

field = CausalField(dim=8)
for i in range(4):
    field.soft_acquire(f"agent-{i}", f"gpu:slot_{i % 2}")

visualize(field, title="GPU Slot Contention")
pip install causal-field[viz]

Multi-session use

from pathlib import Path
from causal_field import CausalField

# Save field state between runs
path = Path(".causal-field-state.json")
field = CausalField(dim=64)
field.soft_acquire("agent-A", "file_write:/data/x.csv")
field.save(path)

# Restore in next process
field2 = CausalField.load(path)

Known Limitations

Limitation Impact Mitigation
Advisory only — not atomic Two agents can race through the same low-interference window Always back with threading.Lock for true mutual exclusion
Hash-based coordinates (Ollama down) Semantically similar resources may not collide Run pip install causal-field[embed] and keep Ollama up
In-memory only (single process) No cross-process coordination Use field.save() / CausalField.load() between processes; not suitable for distributed systems
Gaussian spread can block unrelated resources High sigma can create false positives across coordinate space Call adjust_sigma(agent, resource, "false_positive") to shrink splat width
Not a real-time system intensity_at() is a point-in-time snapshot For high-throughput systems, pair with a hard mutex for serialization-critical sections

Comparison: CausalField vs. alternatives

Feature causal-field threading.Lock asyncio.Lock multiprocessing.Lock
Probabilistic (no hard block) Yes No No No
Intent sensing before conflict Yes No No No
Works across threads Yes Yes No No
Works across processes Via save/load No No Yes
Distributed systems No No No Limited
Deadlock-free Yes No No No
Throughput advantage 1.4x (sparse contention) Baseline Baseline Higher overhead

When to use threading.Lock instead: Any time you need strict mutual exclusion (e.g., shared memory writes, counter increments). CausalField is not a replacement — it's a routing layer that sits in front of your hard lock.


Part of the LexiPro Sovereign OS

causal-field is extracted from LexiPro — a local-first agentic OS running 15 MCP servers, 228 tools, and 20 agent personas. In the full OS, CausalField powers the tool allocation layer: before any agent acquires a destructive tool, the field measures interference and auto-defers if another agent already holds a write-type resource at the same coordinate.

The hard mutex (acquire_mutex MCP tool) remains the sole serialization gate for actual file writes — CausalField is advisory, operating one layer earlier for routing decisions.


License

MIT — see LICENSE.

Built by Broken Arrow Entertainment LLC · Sovereign Intelligence Systems Group


OS Integration — MSCL CAP Layer

causal-field wires into the Minimal Stable Control Loop (MSCL) as the first contention check before any write-type tool executes. This is the integration pattern used in the LexiPro Sovereign OS:

# mscl.py — _check_contention() CAP layer (v22.8)
from causal_field import get_global_field, _resource_to_mu, _get_threshold

_WRITE_KWS = ("write", "edit", "save", "delete", "create", "append",
              "db_write", "insert", "update", "drop")

def check_write_contention(resource_mu: str, directorate: str) -> dict:
    if any(kw in resource_mu.lower() for kw in _WRITE_KWS):
        cf           = get_global_field()
        mu           = _resource_to_mu(resource_mu, cf.dim)
        interference = cf.intensity_at(mu)        # read-only — no splat projection
        threshold    = _get_threshold(resource_mu)

        if interference > threshold:
            return {
                "decision": "DENY",
                "reason": (
                    f"CAUSAL_FIELD_BLOCKED: {resource_mu} "
                    f"interference={interference:.3f} (>{threshold}). "
                    f"Acquire hard mutex first."
                ),
            }
    return {"decision": "ALLOW"}

Key design: the auth check reads the field via intensity_at(mu) — it does NOT call soft_acquire(). This avoids phantom splats during auth checks. Actual splat projection only happens when the agent explicitly calls soft_acquire() at execution time.

Full authority stack:

CausalField intensity_at()          ← instant snapshot, write-type resources
  → NeuralBus WRITE_CONTENTION      ← 60-second pheromone sliding window
      → MetaGovernor seniority      ← deferred-enough agents get priority boost
          → hard mutex acquire      ← sole serialization gate for actual writes

Adaptive sigma closes the loop: after each write, call field.adjust_sigma(agent_id, resource, outcome) so the field self-calibrates. Collisions shrink sigma (splat was too wide); false positives grow it.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

causal_field-1.0.1.tar.gz (21.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

causal_field-1.0.1-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

Details for the file causal_field-1.0.1.tar.gz.

File metadata

  • Download URL: causal_field-1.0.1.tar.gz
  • Upload date:
  • Size: 21.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for causal_field-1.0.1.tar.gz
Algorithm Hash digest
SHA256 7bb328218e4b184c17c5f6d640f2ebfa6a01d307f60b5b6809cd6b2335534821
MD5 c7abd91c4d600a549a33ab26fbc1848f
BLAKE2b-256 43513602f4c546e1f7464632e11b56e7d147790195ebd680702da3f7f4383eff

See more details on using hashes here.

File details

Details for the file causal_field-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: causal_field-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 16.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for causal_field-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 614999019eaa45f242fcc8be769483e46a32a948dd107f9f0bcb4e12fb1c1b40
MD5 c1b0b42f7c0a2e2ddba61b996a2fbe3d
BLAKE2b-256 548a1b4c3aaf84322492b0190768afdc0beb53709f6f74e6f3a4efae3d93c4d4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page