Skip to content

Cross-batch edges are silently dropped when the node-type prefix differs #628

Description

@edunovaes

Summary

merge-batch-graphs.py drops cross-batch edges whose endpoint carries a different node-type prefix than the node that was actually emitted. The only signal is a line on stderr, so a run looks successful while the graph quietly comes out with fewer relationships than it should.

Why it happens

Each file-analyzer subagent chooses the ID prefix for the nodes it owns (file: / config: / document: / pipeline: / table: / schema: / endpoint:). When batch A emits an edge pointing at a file that batch B classified, A has to guess that prefix — batchImportData and neighborMap only resolve project-internal code imports, so doc→pipeline, doc→config and config→code references have no ground truth.

Step 6 then compares IDs by exact equality:

if src not in node_ids or tgt not in node_ids:
    unfixable.append(f"Edge {src}{tgt} ({etype}): dropped, missing ...")
    continue

Code files almost always end up as file:, so the loss lands entirely on the non-code node types — which is where documents, triggers, configures and depends_on live.

Reproduction

Two batches in .understand-anything/intermediate/:

// batch-1.json — owns the workflow doc, types it as a pipeline
{ "nodes": [ { "id": "pipeline:wf/a.md", "type": "pipeline", "name": "a",
               "filePath": "wf/a.md", "summary": "s", "tags": ["t"] } ],
  "edges": [] }

// batch-2.json — cites it, guesses "document:"
{ "nodes": [ { "id": "document:docs/d.md", "type": "document", "name": "d",
               "filePath": "docs/d.md", "summary": "s", "tags": ["t"] } ],
  "edges": [ { "source": "document:docs/d.md", "target": "document:wf/a.md",
               "type": "documents", "weight": 0.5 } ] }
$ python merge-batch-graphs.py <projectRoot>
Input: 2 nodes, 1 edges
Could not fix (1 issues — needs agent review):
  - Edge document:docs/d.md → document:wf/a.md (documents): dropped, missing target
Output: 2 nodes, 0 edges

The relationship is real and both endpoints exist. Only the prefix guess was wrong.

Impact

On a 205-file project (Next.js CRM, 46 SQL migrations, 17 workflow docs, docs tree), a single run had 25 edges about to be dropped this way. 21 of them were documents edges from the four root docs to the workflow files — the entire "which document describes which automation" map. Exactly one of the 26 reported drops was legitimate (a path referenced in a doc that no longer exists on disk).

Three more projects showed 2, 7 and 35 affected edges in the same run.

Note on the existing mechanism

The Could not fix (N issues — needs agent review) report implies the Phase 3 assemble-reviewer agent is meant to catch this. That agent is optional and LLM-priced, and this particular repair is fully deterministic — resolving the ID against the node set while ignoring the prefix, and only when the match is unambiguous.

A fix is proposed in #624 (with tests). Happy to adjust the approach if you'd prefer it handled elsewhere in the pipeline — e.g. having compute-batches.mjs publish an authoritative path → nodeType map so analyzers never have to guess.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions