#2486 (thanks @adminwat): normalize dict-shaped hyperedge members to ids
(or drop with a warning) so a malformed hyperedge can't abort a completed
merge with a TypeError.
#2484 (thanks @sortakool; approach from @oleksii-tumanov's #1691):
merge-graphs relabels hyperedge member ids and ids with the repo prefix,
unions both inputs' hyperedges instead of clobbering, and writes both
persistence slots.
#2485 (thanks @sortakool): build_from_json reads hyperedges from the
top-level and nested slots; a full validation wipeout is reported loudly.
#2490 (thanks @PapiScholz): the skill Step-5 flow passes curated
community_labels to to_json, so graph.json ships community_name.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
merge-graphs prefixed each graph's node ids with `<repo>::` where repo was
`gp.parent.parent.name` — the graphify-out parent dir name. That tag is not
unique across inputs: `src/graphify-out` and `frontend/src/graphify-out` both
yield `src`, so a bare `app` node from a backend `src/app.js` and a frontend
`App.jsx` both became `src::app` and nx.compose silently merged them into one
node (one graph's label/source_file, both graphs' edges) — inventing false
cross-runtime `path` results with no warning.
New `distinct_repo_tags` guarantees a unique prefix per graph: colliding tags
are widened with their own parent dir (`frontend_src`), then an index suffix
backstops any residual duplicate. The handler prints a note when it disambiguates.
Verified end to end: the two `app` nodes now survive as `..._src::app` and
`frontend_src::app` instead of collapsing. Regression tests cover the merge case
and the tag uniquifier (pass-through, widening, and triple-collision fallback).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#1586: the skill's interpreter-detection allowlist rejected any shebath path
with a char outside [a-zA-Z0-9/_.-], so Homebrew's versioned python@3.13 path
was skipped and detection fell through to a bare python3 without graphify.
Allow @ in the skillgen source fragments (core/devin/aider/posix), regenerate
all skill artifacts, and register the change as a sanctioned monolith diff.
Injection chars (; $ ( etc.) are still rejected.
#1606: graphify merge-graphs crashed with an unhandled NetworkXError when
inputs disagreed on directed/multigraph. _to_simple only converted MultiGraph,
leaving a DiGraph to fail compose. Normalize every input to a plain undirected
Graph (the merged cross-repo view is undirected anyway).
Also confirmed on v8: `graphify kilo install` (#1605) works (reporter was on an
older version), and `pip3 install graphifyy` failing on macOS (#1585) is a
broken Homebrew Python 3.14 / pyexpat env, not a graphify issue — pip crashes
in its own vendored distlib before graphify is touched.
skillgen --check / --monolith-roundtrip / --schema-singleton all green; shell
smoke accepts python@3.13 and still rejects `; rm -rf /` and `$(evil)`. Full
suite 2789.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>