Report review and pull-request counts, light the graph nodes, move the heatmap up - #77
Conversation
…e heatmap up Rebuilt onto main after #71 and #72 landed, which replaced the assembler with a manifest-driven one, added a test suite and a CI check, and took the fleet to ten members. Two pieces of the original branch were superseded and are dropped: main already derives the graph's accessible title from the fleet count, and already gives NaturalProductMech its Browse button. A fifth stat tile carries merged pull requests summed across the ten Mech repositories, and every card gains a line of small print under its headline number with that Mech's reviewed records and merged PRs. Whether a Mech tracks review is read from its LinkML schema, not from the values its records happen to carry. Seven declare a status slot whose enum permits REVIEWED, so a zero there is a real zero. MediaIngredientMech and CultureMech have a mapping_status, but its enum runs UNMAPPED to AMBIGUOUS and never reaches REVIEWED, so it grades mapping rather than review; CommunityMech has no such slot. Those three print only their PR count, because "nobody has reviewed one" and "this Mech does not track review" are different claims. mech_stats.py takes fleet membership from the manifest snapshot, the same source assemble_page.py validates the cards against, so a Mech admitted to the fleet cannot end up with a card and no stat line. roots.ORDER is a narrower thing, the members the vocabulary scans have measured, and stays at nine. TaxonMech's record glob lives in mech_stats.py until the census reaches it. assemble() now refuses to build if the stats miss a member, and two tests cover that and the untracked-review case. The Shared vocabulary heatmap moves above the graph, from the template into the fragment, since the graph is what it explains. Its heading is raw HTML carrying the id kramdown would have generated, because markdown is not processed inside the fragment. Graph nodes are lit as spheres: one highlight gradient and one limb gradient, both in objectBoundingBox units so a single pair serves all ten, neither carrying a hue, both multiplying over whichever Mech colour is underneath. The weighting is a theme token because it has to change -- light-theme Mech colours are far darker, carrying their contrast against white, and a limb tuned for the dark theme turned them to mud. The overlays take no pointer events, so hovering still hits the node. The hub keeps its flat fill and reads as the centre. The stat strip steps 5 to 3 to 2 columns on explicit breakpoints; auto-fit picks four between roughly 700px and 1010px and strands the fifth tile alone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BXHrBTSU8fU4Zg7HfaMKs9
Review of this branch measured what the highlight costs in colour separation. It lightens the middle of every node toward white, which pulls the ten Mech colours together: at the peak as submitted, the closest dark-theme pair fell from 0.106 to 0.054 in linear-RGB distance, and the worst pair overall held only 57% of its flat separation. The pair it hurt most was the one already too close to tell apart, CellStructureMech and TaxonMech (#78). Dropped from .52 to .34 on dark and .60 to .42 on light. The dark theme keeps 77% of flat separation and still reads as a lit sphere, because the limb shadow does most of the modelling there by design. The light theme leans on the highlight instead, so it keeps more of it. Checked in both themes. Closes #79 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BXHrBTSU8fU4Zg7HfaMKs9
|
Adversarial review done, read-only, against What I checked beyond reading the diff:
Addressed here: #79, a real defect in this branch. The highlight washes every node toward white, which pulls the ten Mech colours together. At the peak as submitted the worst dark-theme pair held only 57% of its flat separation. Lowered from .52 to .34 on dark and .60 to .42 on light, which restores 77% while still reading as a lit sphere, since the limb shadow does most of the modelling on dark by design. Left filed: #78, and it is the more serious of the two. CellStructureMech and TaxonMech are byte-identical on the light theme, both Also noted while reading: NaturalProductMech moved into the blue family in the same earlier change, which now puts three of ten in blue. |
Replaces #63, which GitHub closed automatically when its base branch was deleted on merging #60. Rebuilt onto main after #71 and #72 landed, which replaced the assembler with a manifest-driven one, added a test suite and a CI check, and took the fleet to ten members.
Two pieces of the original branch were superseded by that work and are dropped: main already derives the graph's accessible title from the fleet count, and already gives NaturalProductMech its Browse button.
Merged pull requests, on the strip and on every card. A fifth tile carries 2,778 merged PRs across the ten Mech repositories, and each card gains small print under its headline number.
Where "reviewed" comes from. Each Mech's LinkML schema, not the values its records happen to carry. Seven declare a status slot whose enum permits REVIEWED, so a zero there is a real zero. MediaIngredientMech and CultureMech have a
mapping_status, but its enum runs UNMAPPED to AMBIGUOUS and never reaches REVIEWED, so it grades mapping rather than review; CommunityMech has no such slot. Those three print only their PR count, because "nobody has reviewed one" and "this Mech does not track review" are different claims.Fits the manifest contract main introduced.
mech_stats.pytakes membership from the manifest snapshot, the same sourceassemble_page.pyvalidates the cards against, so a Mech admitted to the fleet cannot end up with a card and no stat line.roots.ORDERstays at nine, because it is a narrower thing: the members the vocabulary scans have measured. TaxonMech's record glob lives inmech_stats.pyuntil the census reaches it.assemble()refuses to build if the stats miss a member, and two new tests cover that and the untracked-review case.The heatmap moves above the graph, from the template into the fragment, since the graph is what it explains. Its heading is raw HTML carrying the id kramdown would have generated, because markdown is not processed inside the fragment.
Graph nodes are lit as spheres. One highlight gradient and one limb gradient, both in
objectBoundingBoxunits so a single pair serves all ten, neither carrying a hue, both multiplying over whichever Mech colour is underneath. The weighting is a theme token because it has to change: light-theme Mech colours are far darker, since they carry their contrast against white, and a limb tuned for the dark theme turned them to mud. The overlay circles take no pointer events, so hovering still hits the node. The hub keeps its flat fill and reads as the centre rather than an eleventh planet.Layout. The stat strip steps 5 to 3 to 2 columns on explicit breakpoints.
auto-fitpicks four between roughly 700px and 1010px, which strands the fifth tile alone on a stretched row.Checks:
python -m unittest discover -s testspasses 13 tests, andpython scripts/fleet/assemble_page.py --checkreports the page current. Verified in Chrome against a local render at 1400px: five tiles on one row, ten shaded nodes, ten card stat lines, heatmap ahead of the graph with no horizontal overflow.🤖 Generated with Claude Code
https://claude.ai/code/session_01BXHrBTSU8fU4Zg7HfaMKs9