Filed from LawnStarter adoption ticket PE-80043 (api.lawnstarter.com), graded run at CLI 0.9.40, fork v8 @ 5e9d95c11837aeabbbb5d90cb45544f49dc58ca4.
Summary
graphify explain truncates its connection list at 20 entries. On a Laravel event class with degree 31, the 20-entry window is filled mostly by test-file imports edges, so only 3 of the 7 real listeners are identifiable from the output. The remaining listener files appear in the "Grouped by file" rollup, but the rollup gives only a connection count per file — it does not say which of those connections is the handle() reference that makes the file a listener. A consumer cannot answer "what listens to this event?" from the output.
docs already note "explain truncates on high-degree nodes … use affected for full fan-in". This issue is that the truncation is not signalled as lossy for the question being asked: the output looks complete because the rollup lists every file, and there is no hint that the per-edge relation labels were dropped.
Reproduction
Corpus: api.lawnstarter.com @ 382fe1a2c1 (private LawnStarter repo, PHP/Laravel, 6,224 files).
graphify update .
graphify explain "BackgroundCheckStatusChanged"
Expected
The 7 listeners registered for the event, each identifiable as a listener.
Ground truth by grep — app/Providers/EventServiceProvider.php:134-142 registers exactly these, and each declares handle(BackgroundCheckStatusChanged $event):
app/Listeners/BackgroundCheck/PropagateBackgroundCheckStatusOnChange.php:21
app/Listeners/BackgroundCheck/DetectBackgroundCheckSubmitted.php:14
app/Listeners/BackgroundCheck/DetectBackgroundCheckPassed.php:14
app/Listeners/BackgroundCheck/DetectBackgroundCheckFailed.php:14
app/Listeners/BackgroundCheck/DetectBackgroundCheckActionNeeded.php:14
app/Listeners/BackgroundCheck/DetectBackgroundCheckExpired.php:14
app/Listeners/BackgroundCheckEvent/LogBackgroundCheckStatusChangedEvent.php:21
Actual
Node: BackgroundCheckStatusChanged
Degree: 31
Connections (31):
...
<-- .handle() [references] app/Listeners/BackgroundCheck/DetectBackgroundCheckActionNeeded.php:L14
<-- .handle() [references] app/Listeners/BackgroundCheck/DetectBackgroundCheckSubmitted.php:L14
<-- .handle() [references] app/Listeners/BackgroundCheckEvent/LogBackgroundCheckStatusChangedEvent.php:L21
<-- DetectBackgroundCheckActionNeeded.php [imports] ...
<-- DetectBackgroundCheckExpired.php [imports] ...
... and 11 more
Grouped by file:
<-- app/Listeners/BackgroundCheck/DetectBackgroundCheckFailed.php: 2 connections
<-- app/Listeners/BackgroundCheck/DetectBackgroundCheckPassed.php: 2 connections
...
3 of 7 listeners carry an explicit .handle() [references] label. The other 4 are inside "... and 11 more".
Nine of the twenty shown connections are test-file imports, which crowd out the signal-bearing edges.
The full set is in the graph and the workaround works:
$ graphify affected "BackgroundCheckStatusChanged" --relation references --depth 1
- .handle() [references] app/Listeners/BackgroundCheck/DetectBackgroundCheckActionNeeded.php:L14
- .handle() [references] app/Listeners/BackgroundCheck/DetectBackgroundCheckExpired.php:L14
- .handle() [references] app/Listeners/BackgroundCheck/DetectBackgroundCheckFailed.php:L14
- .handle() [references] app/Listeners/BackgroundCheck/DetectBackgroundCheckPassed.php:L14
- .handle() [references] app/Listeners/BackgroundCheck/DetectBackgroundCheckSubmitted.php:L14
- .handle() [references] app/Listeners/BackgroundCheck/PropagateBackgroundCheckStatusOnChange.php:L21
- .handle() [references] app/Listeners/BackgroundCheckEvent/LogBackgroundCheckStatusChangedEvent.php:L21
7/7, exact lines, no wrong nodes.
Suggestions
- When truncating, prefer edges by relation informativeness rather than by traversal order —
references/calls before bulk imports.
- Make the truncation notice actionable, e.g.
... and 11 more (relation labels omitted — run 'graphify affected "X" --relation references' for the full set).
- Add a
--limit N / --all flag to explain so a caller can opt out of the 20-cap.
Related
Separately, this repo has no listens_to relation at all — EventServiceProvider::$listen produces zero edges (checked: the provider's 24 outbound edges are all imports, none to the BackgroundCheck listeners). The listeners are discoverable only by accident, because they happen to type-hint the event. Happy to split that into its own issue if useful.
Filed from LawnStarter adoption ticket PE-80043 (api.lawnstarter.com), graded run at CLI
0.9.40, forkv8@5e9d95c11837aeabbbb5d90cb45544f49dc58ca4.Summary
graphify explaintruncates its connection list at 20 entries. On a Laravel event class with degree 31, the 20-entry window is filled mostly by test-fileimportsedges, so only 3 of the 7 real listeners are identifiable from the output. The remaining listener files appear in the "Grouped by file" rollup, but the rollup gives only a connection count per file — it does not say which of those connections is thehandle()reference that makes the file a listener. A consumer cannot answer "what listens to this event?" from the output.docsalready note "explain truncates on high-degree nodes … use affected for full fan-in". This issue is that the truncation is not signalled as lossy for the question being asked: the output looks complete because the rollup lists every file, and there is no hint that the per-edge relation labels were dropped.Reproduction
Corpus:
api.lawnstarter.com@382fe1a2c1(private LawnStarter repo, PHP/Laravel, 6,224 files).Expected
The 7 listeners registered for the event, each identifiable as a listener.
Ground truth by grep —
app/Providers/EventServiceProvider.php:134-142registers exactly these, and each declareshandle(BackgroundCheckStatusChanged $event):Actual
3 of 7 listeners carry an explicit
.handle() [references]label. The other 4 are inside "... and 11 more".Nine of the twenty shown connections are test-file
imports, which crowd out the signal-bearing edges.The full set is in the graph and the workaround works:
7/7, exact lines, no wrong nodes.
Suggestions
references/callsbefore bulkimports.... and 11 more (relation labels omitted — run 'graphify affected "X" --relation references' for the full set).--limit N/--allflag toexplainso a caller can opt out of the 20-cap.Related
Separately, this repo has no
listens_torelation at all —EventServiceProvider::$listenproduces zero edges (checked: the provider's 24 outbound edges are allimports, none to theBackgroundChecklisteners). The listeners are discoverable only by accident, because they happen to type-hint the event. Happy to split that into its own issue if useful.