Skip to content

fix(graph): count edges by both endpoints and expose cross-layer bleed - #183

Merged
Cipher208 merged 1 commit into
masterfrom
fix/graph-edge-count-contract
Nov 2, 2026
Merged

Cipher208 merged 1 commit into
masterfrom
fix/graph-edge-count-contract

Conversation

@Cipher208

Copy link
Copy Markdown
Owner

Что

epi_edges не хранит слой, и три ридера выводили его тремя способами: count_edges по источнику, memory_graph_edges по обоим концам, get_neighbors по цели. Миграция слоёв 2026-11-02 создала кросс-слойные рёбра и превратила задокументированное расхождение в живое.

база / слой было count_edges стало total cross_layer
Hermes agent 45 291 19 786 32 990
Hermes user 370 795 363 310 32 990
Mimocode agent 1 781 1 157 879
CowAgent agent 2 380 2 099 496

Сходится: 19 786 + 25 505 (agent→user) = 45 291; входящих user→agent 7 485 — ровно «лишние» в user-счётчике.

Контракт

  • total / live / dead — только рёбра с обоими концами в слое, т.е. то, что реально перечисляет memory_graph_edges;
  • user_id теперь на обоих концах, как в тулзе (без этого count_edges("default") в Mimocode agent давал 1 781 против 646 читаемых);
  • cross_layer — рёбра с одним концом в слое, симметрично: одна и та же утечка видна с обеих сторон;
  • total == live + dead сохраняется, ребро с отсутствующим концом не входит никуда.

StatsResult.graph_edges_cross_layer + проброс в memory_stats и dashboard. Смысл существующих полей не менялся.

Попутно: абсолютный операторский путь вырезан из комментария (shared/archived_memories.py); в трекнутых файлах /home/murat — 0. Устаревшее «Today no such edge exists» в докстринге заменено измеренным контрактом.

Вне объёма

get_neighbors (target-only) не трогал — отдельная находка, меняет recall-расширение. Исторические кросс-слойные рёбра не перекладывал.

Проверка

  • 2821 passed (2818 + 3 новых), 4:27;
  • ruff check чисто, ruff format 750 файлов;
  • mypy 63 = baseline;
  • blind verifier: 15/15 PASS, дефектов нет; adversarial — удалённый источник, удалённая цель, два user_id в слое, self-loop, пустая БД.

Spec: .compose-локальный 2026-11-02-cross-layer-edge-count.md.

`epi_edges` has no layer column, so the three readers derived an edge's layer
three ways: `count_edges` by the source node, `memory_graph_edges` by both
endpoints, `get_neighbors` by the target. The 2026-11-02 layer migration created
cross-layer edges, turning a documented divergence into a live one: on Hermes the
agent counter reported 45 291 edges while the tool could list 19 786.

`count_edges` now counts total/live/dead only for edges with BOTH endpoints in
the layer, matching what the reader returns, and scopes `user_id` on both ends
like the reader does. The bleed is not hidden: `cross_layer` counts edges with
exactly one endpoint in the layer, symmetrically, so the same edge is visible
from both sides. `memory_stats` and the dashboard carry the new field.

Also drops an absolute operator home path from a comment and replaces the stale
"today no such edge exists" claim in the docstring with the measured contract.
@coderabbitai

coderabbitai Bot commented Nov 2, 2026

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions github-actions Bot added the fix label Nov 2, 2026
@Cipher208
Cipher208 merged commit 51cbac3 into master Nov 2, 2026
19 checks passed
@Cipher208
Cipher208 deleted the fix/graph-edge-count-contract branch November 2, 2026 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant