fix(graph): 3.1.0 builds no graph — reach the event stream through get_stream() [3.1.1] - #133
fix(graph): 3.1.0 builds no graph — reach the event stream through get_stream() [3.1.1]#133cdeust wants to merge 2 commits into
Conversation
3.1.0 removed the module-level emit/close/reset forwarders from
graph_event_stream — correctly, because one of them silently dropped
`event_meta` once emit grew it — on the stated grounds that they "had never had
a caller in this repository's history". They had four. graph_build_run called
reset, emit and close on the module; graph_build_merge calls emit on whatever it
is handed, and was handed the module.
So run_build died on its first statement:
AttributeError: module 'cortex_viz.server.graph_event_stream'
has no attribute 'reset' graph_build_run.py:155
before a single source loaded. /api/graph/progress reported
`phase: "starting", pct: 0.0` forever and every DB-backed view stayed empty.
Trace was unaffected — it does not go through this builder.
The `finally` block had the same defect and was worse: `_ev.close()` on the
module sat inside `except Exception: pass`, so it failed silently. Subscribers
never received `done` and never disconnected. The crash was masking it.
Fix follows the singleton's own contract — "callers reach it through
get_stream() and use the GraphEventStream API directly", with activity_stream as
the worked example — rather than restoring the forwarders, which would re-open
the weaker door 3.1.0 closed on purpose. make_merge's `events` parameter is
annotated GraphEventStream so the next caller that passes the module fails at
type-check instead of halfway through a build.
Verified end to end, not just by unit test: the standalone server on the fixed
tree advances past `starting` — baseline_ready, 85 hooks, 49 discussion_agents,
36752 memories, then `layout bake (DrL)` — with zero `background build error`
in the log.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Patch release carrying the graph-build fix. 3.1.0 builds no graph at all, so every install of it should move. Version bumped across identity.py (the source of truth), pyproject, server.json, the Claude/Codex/Gemini manifests and the README badges; CHANGELOG entry states the upgrade urgency and what was wrong. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Denied — and the reasoning is worth recording rather than losing with the branch. The analysis of the failure in this PR is accurate: the forwarders were deleted on a false premise ("had never had a caller" — there were four), the graph build dies on its first statement, and the What is wrong is the remedy. Adapting the four callers to the deletion presents a removal as a solution, when what the description actually enumerates is the work that should have been done. The code had a problem — a forwarder that had drifted out of sync with the The removed code must be plugged back and made functional, callers untouched:
Branch |
3.1.0 never builds a graph. Every DB-backed view (Graph, Brain, Knowledge, Board, Wiki) stays
empty;
/api/graph/progresssits atphase: "starting", pct: 0.0forever. Trace is unaffected.Nothing was lost or corrupted — the build died before reading anything.
Root cause
3.1.0 removed the module-level
emit/close/resetforwarders fromgraph_event_stream, on thestated grounds that they "had never had a caller in this repository's history". That premise was
false — they had four:
graph_build_run.py:155_events.reset()graph_build_run.py:234_events.emit(...)graph_build_run.pyfinally_ev.close()graph_build_merge.py:136events.emit(...)(handed the module)So
run_buildraisedAttributeError: module 'cortex_viz.server.graph_event_stream' has no attribute 'reset'on its first statement.The
finallyblock was worse:_ev.close()sat insideexcept Exception: pass, so it failedsilently — subscribers never received
doneand never disconnected. The crash was masking asecond defect.
The fix, and what it deliberately does not do
It does not restore the forwarders. Removing them was right: one of them dropped
event_metaonce
emitgrew it, and the singleton's own comment says callers should "reach it throughget_stream()and use theGraphEventStreamAPI directly", withactivity_streamas the workedexample. The two stragglers now do that.
make_merge'seventsparameter is annotatedGraphEventStream, so the next caller that passes the module fails at type-check rather thanhalfway through a build.
Verification
End to end on the fixed tree, not just unit tests — the standalone server advances past
starting:baseline_ready, 85 hooks, 49 discussion_agents, 36752 memories, thenlayout bake (DrL), withzero
background build errorin the log. On 3.1.0 the same probe never leftpct: 0.0.New
tests/test_graph_build_event_stream_contract.py— 3 of its 4 tests fail on 3.1.0 and passhere. The existing merge tests could not have caught this: they all inject a fake stream, so the
defect lived in how the production caller obtains the stream, not in what it does with it. The
fourth test pins the removal, so re-adding a forwarder re-opens the
event_meta-dropping path.Downstream
cdeust/Cortex's marketplace pins this plugin byref: v3.1.0+sha, socortex-pluginskeepsserving the broken build until that pin moves. Sequence: merge here → tag
v3.1.1→ repoint theCortex marketplace entry to the new tag and sha.
🤖 Generated with Claude Code