A graph-based shared blackboard where agents coordinate indirectly by depositing typed pheromone traces (PHEROMONE, BELIEF, PREFERENCE, ANTIBODY, RESOLUTION) onto graph nodes, then sensing and following concentration gradients. Traces spread via Euler-stable Laplacian diffusion and decay exponentially, creating a self-organizing lossy attention field. It can help agents inspect a graph neighborhood; it does not replace reliable messages, assignment, delivery, or completion evidence. NOT for r...
Installs into .claude/skills of the current project.
Are you the author of Stigmergic Diffusion Medium?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/curiositech-stigmergic-diffusion-medium-port-daddy)
---
name: stigmergic-diffusion-medium
description: >
A graph-based shared blackboard where agents coordinate indirectly by depositing
typed pheromone traces (PHEROMONE, BELIEF, PREFERENCE, ANTIBODY, RESOLUTION) onto
graph nodes, then sensing and following concentration gradients. Traces spread via
Euler-stable Laplacian diffusion and decay exponentially, creating a self-organizing
lossy attention field. It can help agents inspect a graph neighborhood; it does not
replace reliable messages, assignment, delivery, or completion evidence. NOT for
reliable messaging, assignment, coverage, or completion certification.
license: Apache-2.0
allowed-tools: Read,Write,Edit,Glob,Grep
metadata:
version: 0.1.0
author: soma-jury_rig-graft
tags: [stigmergy, multi-agent, coordination, diffusion, graph, blackboard, active-inference, pheromone]
pairs-with: [active-inference-agent, belief-market-tateonnement, immune-selection-pressure]
provenance:
kind: imported
source: workgroup-ai / jury_rig skill library (rehomed 2026-07-04)
---
# Stigmergic Diffusion Medium
## When to Use
- You need agents to coordinate without direct messaging: no queues, no RPC, no shared
mutable state beyond the medium itself. Agents write traces; other agents sense them.
- Your problem maps naturally onto a graph (import dependency graph, task DAG, knowledge
graph, file system, network topology) and agents need to discover high-value nodes by
following concentration signals rather than being assigned work.
- You want emergent load balancing and exploration: resolution traces dampen overcrowded
nodes; urgency amplification surfaces deadline pressure; antibody traces suppress
already-solved sub-problems — all without a scheduler.
NOT for:
- Hard real-time coordination where sub-millisecond synchronization is required (diffusion
physics introduce lag proportional to graph diameter).
- Problems where agents must exchange structured messages with guaranteed delivery — the
medium is a lossy signal field, not a reliable message bus.
- Flat, unstructured data with no natural graph topology; forcing one creates spurious
gradient artifacts.
## Core Concepts
**Trace** (`Trace` dataclass): A single stigmergic deposit with fields `trace_type`,
`intensity`, `depositor`, `created_at`, optional `deadline`/`urgency_alpha`/`urgency_beta`
for temporal pressure, and optional `confidence_stake`/`proposition` for belief-market
extension. The fundamental write unit.
**TraceType** (enum): Five distinct "goods" in the wide-market framework —
`PHEROMONE` (work-in-progress / distress), `BELIEF` (probabilistic claims),
`PREFERENCE` (Active Inference priors, desired future states), `ANTIBODY`
(known-bad / already-solved patterns, triggers negative selection), `RESOLUTION`
(anti-inflammatory: suppresses agent activity at a node after a problem is closed).
**Scalar diffusion is an attention heuristic**: At each synchronous tick, one scalar
field is updated with `p' = (I - αhL)p`, where `L=D-A` is the *unweighted,
undirected* combinatorial Laplacian. It can rank neighborhoods for inspection;
it cannot assign an owner, route a request, prove coverage, prevent duplicate work,
or prove a resolution. Those require a separate authority and evidence protocol.
**Pheromone gradient** (`gradient(node_id)`): The discrete exterior derivative of the
pheromone 0-cochain restricted to the star of a vertex:
`{neighbor: p_neighbor - p_self}`. Positive values attract; agents climb the gradient
toward higher concentrations. This is the only mechanism agents need to follow crowd
wisdom without knowing who deposited what.
**Resolution damping**: `sense()` returns *effective* pheromone =
`raw_pheromone * max(0, 1 - resolution_damping * resolution_level)`. Depositing a
`RESOLUTION` trace at a node makes it appear less attractive to new agents — the
anti-inflammatory that prevents pile-on after a problem is solved.
## Implementation Pattern
```python
# 1. Construct the medium (all randomness seeded for determinism)
medium = Medium(
decay_rate=0.01, # γ: exponential decay per tick
diffusion_rate=0.005, # α: Laplacian diffusion coefficient
resolution_damping=0.5, # how strongly RESOLUTION traces suppress activity
rng_seed=42,
)
# 2. Build topology (or import from repo_parser.py for code-review domains)
medium.add_node("auth/login.py")
medium.add_node("utils/crypto.py")
medium.add_edge("auth/login.py", "utils/crypto.py")
# 3. Agent deposits a trace after visiting a node
medium.deposit(
node_id="auth/login.py",
agent_id="agent-0",
intensity=1.0,
trace_type=TraceType.PHEROMONE,
deadline=medium.time + 10, # optional temporal urgency
)
# 4. Agent senses neighborhood before choosing next move
signals = medium.sense("auth/login.py", radius=1)
# → {"auth/login.py": 0.9, "utils/crypto.py": 0.1} (resolution-damped)
grad = medium.gradient("auth/login.py")
# → {"utils/crypto.py": -0.8} # climb toward higher concentration
# 5. Advance physics each simulation step
diagnostics = medium.tick(dt=1.0)
# Returns: {time, total_pheromone, distress_nodes, max_pheromone}
# tick() handles: decay → diffusion (stability-clamped) → urgency boost → prune epsilon
# 6. After solving a node, deposit RESOLUTION to prevent pile-on
medium.deposit("auth/login.py", "agent-0", intensity=2.0,
trace_type=TraceType.RESOLUTION)
# 7. Antibody negative selection: skip if already solved
if not medium.check_antibody(pattern_signature=hash_of_problem):
do_work()
medium.deposit(node_id, agent_id, 1.0, TraceType.ANTIBODY,
pattern_signature=hash_of_problem)
# 8. Observability
medium.hotspots(n=5) # top-5 nodes by pheromone
medium.snapshot() # full state dict for visualization
medium.global_uncertainty_map() # {node: uncertainty_proxy} for Active Inference seeding
medium.preference_field() # {node: total PREFERENCE intensity} for implicit coordination
medium.freeze_baseline() # capture normal operating state
medium.deviation_from_baseline(node_id) # novelty signal above baseline
```
**Physics tick order** (from `Medium.tick()`):
1. Exponential decay: `p *= exp(-γ dt)`
2. Resolution decay (faster): `r *= exp(-2γ dt)`
3. Laplacian diffusion with clamped `dt_eff`
4. Urgency amplification for traces with `deadline` set
5. Prune values below `1e-8`
**Numerical contract.** For the stated update, spectral stability is
`αh λ_max(L) ≤ 2`; since `λ_max(L) ≤ 2d_max`, `h ≤ 1/(αd_max)` is a sufficient
condition when `d_max>0`. The same bound makes the update a non-negative convex
combination at each node. `0.9/(αd_max)` is merely a safety factor for that exact
operator, not proof for weighted, directed, normalized, asynchronous, saturated, or
concurrently-mutated graphs. Treat `d_max=0` as a no-diffusion case. Decay and deposits
change total mass; only pure synchronous undirected diffusion conserves it. Record
whether a deposit occurs before or after a tick, and never infer delivery from a value.
## Worked operational trace
Use a dependency graph `auth -> crypto -> audit`, with a disconnected `billing` audit
obligation. An investigator deposits `1.0` at `auth`; another deposits `0.5` at
`crypto`. The next tick can make `crypto` look worth inspecting. A tested repair writes
an authoritative receipt outside the field; only then may a `RESOLUTION` trace reduce
attention. The disconnected billing obligation receives no influence, and two workers
can still inspect crypto. This is the intended limitation: field values suggest where to
look, while an owner/evidence ledger decides whether work happened.
## Failure diagnosis
- A raw `gradient()` bypasses resolution damping in the imported implementation. Either
navigate from the same damped values returned by `sense()` or state explicitly that
resolution is ignored; do not call it pile-on prevention.
- `ANTIBODY` is a signature lookup, not a negative concentration. A matching signature
can suppress a duplicate candidate only if its scope and freshness are appropriate.
- Do not reuse the unweighted bound for weighted/directed edges. Define the operator and
establish its own positivity/stability bound first.
## Key References
- Hansen & Ghrist (2021). "Opinion Dynamics on Discourse Sheaves." *SIAM Journal on
Applied Mathematics.* Proves convergence of sheaf Laplacian dynamics; the scalar
pheromone diffusion here is the constant-sheaf special case.
- Do not treat recent sheaf-diffusion preprints as validation of this scalar medium.
Its explicit tick order, graph model, and concurrency semantics require direct local
specification and testing.
- Friston (2010). "The free-energy principle: a unified brain theory?" *Nature Reviews
Neuroscience* 11, 127–138. Foundation for Active Inference agents that consume the
medium's `global_uncertainty_map()` and `preference_field()` outputs.
- Howkins (2026). `soma/medium.py` — SOMA Week 1 reference implementation. All function
signatures, parameter defaults, and physics are canonical from this file.
`/Users/erichowens/coding/soma/soma/medium.py`