# References — status and plan

Every doc here must be verified against `glyphviz_core/` / `glyphviz_gl/`
source (or by running the repo's real loader/renderer) before being marked
done. Nothing is inherited from `gaiaviz-skill/` without re-verification.

| Doc | Status | Scope / primary sources |
|---|---|---|
| `node-csv-format.md` | **Done** (2026-07-14, extended 2026-08-11/13/15) | Full node CSV spec, incl. `topo_scale`, the now-optional scale floor, Point's pixel sizing, geometry on a Link, and the Pin glyph's origin convention. Verified against `csv_reader.py`, `node.py`, `geometry_data.py`, `topology.py`, `geometry.py`, `link_geometry.py`. |
| `topologies.md` | **Done** (2026-07-14, extended 2026-08-12/14/15/17/23) | Per-topology child-placement math and worked coordinate examples for all 18 types, incl. Plot/Surface overlay rules, Z-variant behavior, the `topo_scale` linear/angular axis table, the Pin glyph's tip-on-origin convention, direction-relative branching (the tree recipe under a Point parent), and — since 2026-08-17 — "Pointing a glyph: use placement, not rotation": the per-topology aim table (which topologies aim a child's +Z outward, which only spin it about the axis, and that Zsphere aims nothing), the geometry pointing-axis table, and the radial-spokes/clock-face recipe. Verified against `topology.py` offset functions + `viewport.py` overlays; all 17 worked examples machine-checked through `compute_world_positions`, and the branching angles/reaches re-derived through the real loader + `Scene.basis_matrices` (branch angle exact to 1e-6°, non-uniform-scale shear measured). Extended 2026-08-23 with "What B moves, and what it doesn't" — the Global Scale table (surface-riding children move, Cartesian children/roots/World Grid children do not, and `B × parent scale + translate_z` is not proportional), plus the `Scene()`-defaults-to-3.0 verification trap; all six table rows re-measured through `compute_world_transforms` at B = 1 and 3. |
| `links-and-edges.md` | **Done** (2026-08-15, extended 2026-08-23) | The Link (type 7) row as the app writes it, the three drawing modes (Line 27 / Prism 28 / any glyph stretched between the ends), `ratio` as thickness in both readings, endpoint and orientation rules, and edge recipes (directed graphs, weighted edges, bonds, labelled edges, tree limbs). Verified against `link_geometry.py`, `viewport.py`'s link pass, and `main_window.py`'s link creation; endpoints and cross-axis thickness checked numerically through `link_glyph_matrix`. **"Laying out a graph" added 2026-08-23**: the node side of a graph scene (flat root rows whose `translate_*` are world coordinates), the 1/d vs 1/d² repulsion law that a 2D force layout gets wrong in three dimensions, PivotMDS initialization, displacement capping, fitting to a radius at a percentile, and judging a layout by spacing against glyph diameter rather than by a separation score. Verified against `graph.py` / `graph_layout.py`; every named symbol checked to exist and every default (falloff 1.0, 64 pivots, 98th percentile) read off the real signatures. |
| `world-grid.md` | **Done** (2026-07-18, extended 2026-08-13) | Flat plate vs globe, extents windows, region recentering, the grid scale rule, textures, picking/G-key behavior, multi-grid recipes. Verified against `node.py`/`topology.py`/`scene.py`/`viewport.py`/`main_window.py`; 18 checks incl. 7 engine-verified placement examples via the app's real transform path (`compute_world_transforms`). |
| `tags-and-labels.md` | **Done** (2026-07-18, extended 2026-08-17) | Inline `text`/`link` vs `gv_tag.csv`, title encodings, URL/file/app-launch link rules, display behavior incl. the 500-per-frame draw cap (a perf valve, not a string limit), that label text is read literally (numeric labels keep their authored form since the 2026-08-17 `dtype=str` fix), and "How long can a label be?" — no format/loader limit (round-tripped exactly at 10M characters), the limit being the single-line unwrapped render at ~5.4 px/char, plus the silently-swallowed newline. Verified against `csv_reader.py`/`viewport.py`/`main_window.py`; 18 behavior checks through the real loader/saver, label length and layout cost measured through the real `QStaticText` path at the viewport's own 9pt font. |
| `channels-animation.md` | **Done** (2026-07-18) | `gv_ch-map.csv`/`gv_ch-tracks.csv` formats, complete bindable-attribute list, playback transport, audio-sync manifest, recipes. Drafted in the wild by a skill-equipped Desktop instance, then verified/corrected against `channel_loader.py`/`channel_engine.py`/`main_window.py`; behaviors machine-checked through the real ChannelEngine (12 checks incl. an attribute-list drift guard). |
| `color-palettes.md` | **Done** (2026-07-17) | 26 palette definitions (full 20-color table + gradient formulas), `color_index`/`palette_id` resolution semantics, cycling keys, ramp recipes. Verified against `color_palette.py`; sample resolutions machine-checked via `resolve_palette_color`. |
| `textures-and-media.md` | **Done** (2026-07-17, extended 2026-08-13) | `texture_id` → `media/` file mapping (1-based, images then videos), which geometries actually render a texture, animated GIF/video textures, video audio incl. Solo Audio to Selection. Verified against `texture_manager.py`/`video_manager.py`/`main_window.py`/`geometry.py`. |
| `code-patterns.md` + `code/` helpers | Planned | Reusable generator snippets (node factory, topology position helpers, color ramps) and a standalone `validate_csv.py` implementing SKILL.md's validation checklist. Must run with no GlyphViz install (skill is used self-contained on claude.ai). |
| `troubleshooting.md` | **Done** (2026-08-13, extended 2026-08-15/17/23) | Symptom-indexed catalog of the sixteen cases where the CSV is valid, nothing errors, and the scene is still wrong. Verified against `scene.py`/`geometry.py`/`viewport.py`/`csv_reader.py`/`node.py`/`main_window.py`; 33 checks, incl. re-deriving the `topo_scale` distances through the real engine, a live tag-file load proving a `None` title becomes `nan`, and a guard that every symptom-index link resolves. Covers: the optional 0.2 minimum-glyph-size clamp, UTF-8/control-char tag kill, rotation_mode asymmetry, palette inertness, mesh_id non-inheritance, World-node bulk-edit exclusion, `topo_scale` mismatch after a topology change (children flung out of view), Point's scale-independent pixel size, textures silently ignored on wireframe/Point/Mesh geometries, one-ended links that never draw, `ratio` meaning pixels on a line link and world units on a glyph link, the Pin glyph standing on its origin, and (2026-08-23) a scene whose proportions change with the Global Scale slider because a distance was expressed as parent `scale` in one place and `translate_z` in another. |
| `app-usage.md` | Deliberately out of scope | Keyboard/GUI usage lives in `glyphviz-docs/`, not the skill. The skill only tells users how to open generated files — plus, since 2026-08-15, a short pointer to the in-app builders (Glyph Composer, Hyperglyph Tree Designer, Hyperglyph Lab) as an alternative route for a *shape-only* hyperglyph. That pointer names them and what they're for, nothing about how to drive them. The one further exception, added 2026-08-23, is `SKILL.md`'s "Closing the loop": `tools/export_frame.py` is the headless renderer, so it belongs to the *verification* workflow rather than to app usage — the section exists because a skill that cannot see its own output was costing users a screenshot exchange per question. |
