feat(viewer): read the exported graph as a graph, and fix hierarchy edge cases - #334
Merged
Merged
Conversation
A level that holds one group is the whole repository drawn as a single node: it is the coarsening step that merged everything, a bucket that falls back from the directory label rules to a hub member, and an export that opens on it shows one blob. The builder now refuses it — the achieved level below stays the root — and coarsening keeps the smallest cut that still decomposes the level instead of the smallest cut overall. The location cut grew the same defect for wide repositories: TheAlgorithms/Python publishes 49 top-level directories against a root target of 24, so the exact cut could not expand at all and the root held 3 groups, one of them named after a hub member and holding 16,637 of the repository's 16,858 symbols. A single bucket that cannot expand now escapes once into the directories the repository publishes, inside a bounded multiple of its target, and records `escapedSingleBucket` with the achieved count. The same repository now opens on 49 named directories and reports `budgetSatisfied: false` instead of hiding the structure. The qualification report gains `levelsDecompose` and `locationEscapeQualified`, a fixture whose layout is wider than its budget, and a fixture the escape cuts; the CLI product test asserts that only the published partition may hold one group. 18 real repositories were compared before and after: 17 are byte-identical and TheAlgorithms/Python changes as described. COMPATIBILITY.md records that a level's composition is data no consumer may assume.
Reading a real `compass export html` page surfaced four things: - A workbench with one view rendered a one-item "Code graph" menu. It no longer renders the view list and folds its rail to the brand, the snapshot identity, and the disclosure, so the canvas takes the width. - A build without `labels.json` named every community `Community 0`, `Community 1`, … in the panel, on aggregated bubbles, and in the inspector. The embedded hierarchy holds one group per community at its finest level, so the viewer names them with those labels and never replaces a label the export published. flask now reads `tests`, `src/flask`, `src/flask/sansio`; zod — 2,753 communities and no labels file — reads `packages/zod/src/v4/locales`, `packages/zod/src/v4/core`, and the rest. - Selecting a node or opening a community left the community list in the column the inspector needed. The list is now dismissed while the reader inspects something and returns with the overview; Escape steps back out of a node selection. History comparisons keep the list as a disclosure so both sides of a diff stay reachable. - A selected community reported the bubble's own drawn degree, which is zero by construction. The inspector now shows the evidence the hierarchy holds: symbols, sub-groups, couplings to the groups beside it, cohesion, conductance, boundary kinds, and the durable group id. A group of a coarser level no longer offers to open the community whose *number* it happens to share — it offers the descent instead, because only the finest level pairs a group with a community. Covered by a new `communityFacts` suite, the inspector/workbench unit tests, a new `graph-ux` browser spec, and two export fixtures (a one-view clustered export and a three-level drill-down export). Verified against real exports of pallets/flask, colinhacks/zod, and TheAlgorithms/Python rendered in Chromium.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two changes that came out of building graphs for real repositories and reading the exported pages:
escapedSingleBucketwith an honestbudgetSatisfied.labels.json; selecting a node or opening a community dismisses the community list and hands the column to the inspector (Escape returns); a selected community reports its own evidence — symbols, sub-groups, couplings, cohesion, conductance, boundary kinds, durable group id — instead of a bubble's drawn degree.Motivation
Reading a real
pallets/flaskexport and acolinhacks/zodexport surfaced the feedback this change answers:Community 0 … Community 111, selecting a node left the community list occupying the inspector's space, and a selected community reporteddegree 0 / incoming 0 / outgoing 0because the bubble's couplings are not drawn in a narrowed canvas.src/flaskwould open community 0's symbols.Verification
Real-repository qualification (26 extractions across
flask,zod,axum,claude-code,kache,litestream,scrcpy,gson,ripgrep,serde,anyhow,graphify,mdBook,browser-use,fastapi,stable-diffusion-webui,v2rayN,spec-kit,TheAlgorithms/Python, and others): 17 hierarchies are byte-identical before and after;TheAlgorithms/Pythonchanges from 3 root groups to 49 named directory groups with every member preserved. Exports were rendered in Chromium for flask, zod, and TheAlgorithms/Python.One pre-existing failure is unrelated and reproduces on a clean checkout at the base commit:
compass-core --test code_graph_v1_publication_resilience→missing_dotnet_references_are_external_and_do_not_abort.Compatibility and documentation
community-hierarchy.jsonkeeps schemacompass.community-hierarchy/1and its identity strings; what changes is the level composition a build publishes.COMPATIBILITY.mdnow states that a level's composition is data no consumer may assume, and thatmergeEvidence.escapedSingleBucketis additive. Existing artifacts stay readable — an export still opens on a level an older artifact published.docs/reference/outputs.md, with theexport htmlhelp text anddocs/reference/commands.mdupdated for the opening rule.CHANGELOG.mdrecords both changes.Checklist
MIT OR Apache-2.0