mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-24 22:39:31 +08:00
- Line precision: parse git diff --unified=0 into per-file changed line ranges
(defaultWorkingSetFor), so two agents in the SAME file but DIFFERENT functions
no longer false-collide. Overlap channel now uses the overlap coefficient
(|A∩B|/min(|A|,|B|)) — high when one edit sits inside the other's region, low
for disjoint ranges; whole-file edit = 1. Docstring + design doc updated.
- Trigger firing: buildProximityTriggers() turns advisories into the concrete
messages — transmit-intent to both on a Traffic Advisory, steer-away to the
yielding agent + a hold notice on a Resolution Advisory. buildProximitySnapshot
now returns triggers; dispatchProximityTriggers(triggers, {sendMessage}) delivers
them through an injectable sink (the ECC messages table), best-effort.
- 12 new tests (line-range disjoint vs overlapping, parseDiffRanges, triggers,
dispatch). Full suite 2881/2881; lint green.
152 lines
6.7 KiB
Markdown
152 lines
6.7 KiB
Markdown
# 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 `f` ⇒ `r_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.
|