Files
affaan-m--everything-claude…/docs/design/agent-proximity.md
T
wehub-resource-sync d48cda4081
CI / Test (ubuntu-latest, Node 18.x, bun) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, npm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, pnpm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, yarn) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 20.x, bun) (push) Failing after 17m13s
CI / Test (ubuntu-latest, Node 20.x, npm) (push) Failing after 18m42s
CI / Test (ubuntu-latest, Node 20.x, pnpm) (push) Failing after 15m0s
CI / Test (ubuntu-latest, Node 20.x, yarn) (push) Failing after 49m44s
CI / Test (ubuntu-latest, Node 22.x, bun) (push) Failing after 51m55s
CI / Test (ubuntu-latest, Node 22.x, pnpm) (push) Failing after 21m57s
CI / Test (ubuntu-latest, Node 22.x, npm) (push) Failing after 37m39s
CI / Test (ubuntu-latest, Node 22.x, yarn) (push) Failing after 34m7s
CI / Validate Components (push) Failing after 37m15s
CI / Python Tests (push) Failing after 10m1s
CI / Security Scan (push) Failing after 10m1s
CI / Lint (push) Failing after 17m12s
CI / Coverage (push) Failing after 20m19s
CI / Test (macos-latest, Node 18.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, yarn) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 11:55:55 +08:00

6.7 KiB
Raw Blame History

Agent-space distance metric & collision avoidance (Layer 4)

Status: v0 implemented in scripts/lib/agent-proximity/. This is the moat layer of ECC 2.0 — spatial deconfliction for multiple agents (and humans) working the same codebase, modeled on aircraft collision avoidance (TCAS).

The analogy

Two aircraft sharing airspace don't wait until they touch — TCAS continuously measures their separation and closure rate, issues a Traffic Advisory ("there is traffic near you") and then a coordinated Resolution Advisory ("you climb, the other descends"). We want the same for agents: a continuous notion of how close two agents are in code-space, so that as they approach we fire a trigger that makes them transmit what they're doing to each other and, if needed, makes one steer away — before they collide at the git/merge layer.

1. Agent state

At time t, agent a has a working set

W_a = { (f, R_f, w_f) }                                              (1)

where f is a touched file, R_f the set of edited line ranges in f, and w_f ∈ (0,1] a recency weight (older edits decay toward a floor). An agent may also declare an intent set I_a of files it is about to touch (look-ahead).

2. Collision is multi-channel (noisy-OR)

Two agents can collide through several independent channels. Each channel i yields a collision probability r_i ∈ [0,1]; we combine them as the probability of colliding through at least one channel:

R(a,b) = 1  Π_i ( 1  ω_i · r_i )                                   (2)

with channel weights ω_i ∈ [0,1]. The reported distance is the dual D(a,b) = 1 R(a,b).

Channel 1 — edit overlap r_overlap

For shared files S = files(W_a) ∩ files(W_b):

lineOverlap(f) = |R_f^a ∩ R_f^b| / min(|R_f^a|, |R_f^b|)   (overlap coefficient)
r_overlap = max_{f∈S} w_f^a·w_f^b · lineOverlap(f)                        (3)

The overlap coefficient (not Jaccard) is the right measure: it stays high when one agent's small edit sits inside the other's large region (Jaccard would dilute it by union size). A whole-file edit (no line info) ⇒ lineOverlap = 1. Same file, overlapping lines ⇒ imminent collision; same file, disjoint line ranges (different functions) ⇒ low r_overlap. Different files ⇒ no shared fr_overlap = 0.

Channel 2 — dependency coupling r_dep

Build a dependency graph G=(V,E), edge f→g iff f imports g. Even when two files sit in distant subtrees, if one agent edits a file the other imports, the edit breaks the importer. Coupling decays with (direction-agnostic) graph distance d_G:

coupling(f,g) = γ^{ d_G(f,g)  1 }     γ ∈ (0,1), 0 if unreachable   (4)
r_dep = max_{f∈W_a, g∈W_b}  w_f · w_g · coupling(f,g)                (5)

A direct import (d_G = 1) ⇒ coupling = 1. This is the "collision even when far away" term the metric must capture — a cross-file parameter/return dependency that fails at a distance.

Channel 3 — tree proximity r_tree (soft prior)

For two paths with lowest-common-ancestor depth L:

treeDistance(f,g) = ((depth_f  L) + (depth_g  L)) / (depth_f + depth_g)  (6)
r_tree = 1  min_{f∈W_a, g∈W_b} treeDistance(f,g)

(0 = same file, 1 = disjoint roots.) Tree proximity alone rarely causes a collision, so ω_tree is small — it nudges the metric, never dominates it.

Future channels (same shape)

Call-graph distance (two functions near in the call stack), symbol-level read/write hazard (a writes a symbol b reads), and test-coverage overlap all slot in as additional r_i with their own weights — the noisy-OR (2) absorbs them without changing the framework.

3. The TCAS protocol

Two thresholds carve a protected zone around R:

Risk band Advisory Action
R < τ_TA Clear nothing
τ_TA ≤ R < τ_RA Traffic Advisory both agents transmit intent to each other (the scout handshake — "here is what I'm doing / did")
R ≥ τ_RA Resolution Advisory the lower-priority agent steers away; the other holds course

The resolution is coordinated and deterministic (like one plane climbing while the other descends) so the two agents never pick the same maneuver. Right-of-way priority:

priority(a) = ( committed-work(a),  age(a) )      lexicographic

More committed work wins; ties break on earlier start; the final tiebreak is a stable agent id. The lower-priority agent receives the steer.

Closure rate. TCAS escalates on closing speed, not just separation. From two risk samples Δt apart, closureRate = (R_t R_{t−Δt}) / Δt; a positive closure rate near τ_TA can pre-emptively escalate before the protected zone is entered.

4. Vector-space view (the visualization)

Each file gets a coordinate via a space-filling embedding of its path (files sharing a long directory prefix share most of their coordinate), then pulled toward its dependency neighbours by one averaging step. An agent sits at the recency-weighted centroid of its files' coordinates. The result: ‖v_a v_b‖ tracks the collision risk R, so a 3D "where are the agents" view renders agents as moving points in a file-cloud — you literally watch them crawl toward each other, see the advisory line light up, and watch one steer away.

scanAirspace(agents, graph) returns, in one pass: the non-clear advisories (what the trigger layer acts on), the 3D positions and fileCoordinates (what the renderer draws), and pairwise links with risk (the edges to color).

5. How it wires into ECC

  • Inputs come from the session/work state: each running session's worktree diff gives its working set W_a; the dependency graph is built from the repo (buildDependencyGraph).
  • Triggers: the control-pane tick calls scanAirspace; a Traffic Advisory injects a "transmit intent" message between the two agents' sessions; a Resolution Advisory tells the lower-priority agent to steer (re-target to a different file/subtree) — the first concrete realization of just-in-time multi-agent (and multi-human) deconfliction.
  • Board: advisories surface on the kanban as proximity warnings, extending the agent/human JIT assignment layer already in the control pane.

Roadmap

  • v0 (done): tree + overlap + dependency channels, noisy-OR risk, TCAS advisories, priority/steer, 3D embedding, full test coverage.
  • v1: call-graph & symbol read/write channels; intent look-ahead; closure-rate escalation wired to live session diffs.
  • v2: cross-machine airspace over Tailscale (teammate agents enter the same space); the recorded "N agents, M humans, zero merge conflicts" demo.