diff options
Diffstat (limited to 'skills/graph-viewer-codex-notes.md')
| -rw-r--r-- | skills/graph-viewer-codex-notes.md | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/skills/graph-viewer-codex-notes.md b/skills/graph-viewer-codex-notes.md new file mode 100644 index 00000000..0d67ea35 --- /dev/null +++ b/skills/graph-viewer-codex-notes.md @@ -0,0 +1,163 @@ +# Shared graph viewer: restart notes + +Updated 2026-10-29. Read graph/README.md for the current design and protocol. +These are AI-facing continuity notes, not a new task list or authority to change +compiler semantics. Cliff declared the viewer task complete on 2026-09-26. +Peephole animations, inlining display, TypeCheck diagnostics, and arrow-key +playback are committed. Unfinished compiler work is tracked in +docs/roadmap.md. + +## Playback and diagnostics + +Left/Right arrow keys perform Previous/Next actions, including animation stages, +outside editable content and without modifiers. Preserve slider navigation and +focus during source cursor updates so repeated playback keys keep working. + +Run TypeCheck after optimization and end playback on a visible diagnostic. +Historical chapter numbers below predate the split recorded in chapter-split.md. + +- Chapters 10-17: SimpleGraphObserver calls STOP.typeCheck() after Iter; the + previously package-private method is now public. Chapters 18-25 call + CodeGen.driver(CodeGen.Phase.TypeCheck), running the real ideal phases in + that chapter. Earlier chapters remain unchanged. +- GraphObserver.error(node,msg) is an optional callback. Existing compiler type + checking reports the node it diagnoses, rather than the viewer repeating the + check or trying to infer the node from text. Chapter 25 retains its originating + error selection. Compiler behavior without an observer still throws normally. +- GraphEvent has ERROR and optional msg. Node ID 0 handles a diagnostic without + a node, such as an unresolved struct name. GraphCapture emits a final snapshot + before detach and catches an already-reported exception in its viewer run, + avoiding a duplicate global error response. Success emits TypeCheck PHASE. +- The browser treats ERROR as a stable terminal frame. Next/Last/frame jumps + reveal folded ancestors locally, center the bad node at readable scale, and + show a red outline plus the message on the event line and in node details. + Persistent fold choices and earlier history remain available. A new compile + clears the diagnostic. Node-free errors show the message without centering. +- Restart make view for Java changes; refreshing is enough for JS-only changes. + +## Analysis-flow diagrams + +Normal viewer edges do not show `addDepForwards` analysis dependencies. For a +type-flow explanation, distinguish those reads from ordinary node inputs and +from lifetime-only edges. Label a hand-built diagram as a schematic, not a live +IR capture. Type flow runs def-to-use, opposite the usual input-pointer arrows. + +For example, chapter28b's GlobalEscapeNode has no ordinary inputs: it reads +calls/summaries through dependencies, and StopCU reads its result. Root Start +slot 2 keeps the helper alive without consuming its type. The disposable +`chapter28b/build/global-escape-flow.svg` illustrates this distinction; its DOT +source is a standalone schematic, not restored compiler DOT support. +`graph/render_docs.py` renders saved viewer JSON when a real snapshot is needed. + +## Durable design and owner preferences + +- Printer/viewer consolidation: all chapters' Node classes now extend + `com.seaofnodes.print.BaseNode<Node>`. GraphAdapter reads identity, raw indexed + edges, dependencies, labels, deadness and type text from that common contract. + It constructs node/edge records centrally. Chapter adapters retain semantic + kind/role rules, scope binding names, projection indices, call jumps and folding + state. The graph IDEA module depends on print; both Make source sets are already + compiled together. Browser protocol and grouping algorithms are unchanged. + +- Shared Java capture/model and browser code live in graph/. Each chapter keeps + a small SimpleGraphAdapter and SimpleGraphObserver, plus compiler callbacks. + No Maven requirement. DOT compiler/viewer support is gone; existing docs GV/SVG + assets and documentation regeneration rules remain. Keep the backport docs. +- Node inputs describe USE -> DEF: containing node is the use, edge idx is its + input slot, def is the target ID. 0 means no node. Output lists are reverse + caches, not semantic edge descriptors. Phi control comes from input 0's Region. +- Renderer uses kind through color/shape, not a printed KIND row. IDs follow names + in small font; projections use #id/index. Multi and projections share a box. +- Parser-held temporaries are low with Parser links. Active Scope is low; pending + scopes sit near their control, and Scope edges leave the top. Parser retention + and nested peep temporaries must not be confused. +- Functions/loops/SESE diamonds can fold. Folded edge bundles are thick, with + control color winning over memory, then data. Floating-node ownership can be + nominated by all inputs or all outputs in one region; exclude only when both + sides nominate DIFFERENT regions. RPO is off the layout task list. +- CallEnd cross-function links use clickable shortcut nodes. Loop/Phi backedges + route around the right of the loop region. Edge clicks hop use/def under the + stationary mouse with eased pan; preserve this behavior during display edits. +- Prefer concrete types and short names, avoid boxed high-count IDs and redundant + requireNonNull. Do not add permanent tests for each volatile UI experiment. +- Do not open visible test tabs or use the user's live WebSocket port 12345. + NoScript once blocked 127.0.0.1; a connecting tab is not always a compiler bug. + +## Peephole animation invariants + +Stable -> gather -> rewrite -> release (stable). Gather/rewrite are intermediate +views; slider/frame jumps/first/last skip them. Backward clicks reverse the stages. +Type-only and genuinely unchanged results take one click without gathering. + +- Pair enclosing BEFORE with matching RETURN/APPLY, using peep/up IDs. Nested + captures are available in the stream but not stable stops. A recursively built + constant must not appear before its enclosing rewrite. Raw nested frame jumps + map to the enclosing BEFORE. Capture numbers remain unchanged and can skip. +- Neighborhood: all changed nodes, original root, replacement (even an unchanged + existing GVN result), plus their one-hop defs from both snapshots. Exclude Start + anchors for constants. Do NOT use scheduling dependency lists as membership. +- Keep Multi/projection boxes intact. A gathered Phi brings its Region; gathering + the Region must NOT recursively bring all sibling Phis. +- Gathered pre/post geometry shares positions and reserves room for new nodes. + Exactly-one-hop outside neighbors stay more visible than the distant graph. + Folds temporarily open for the edit, but persistent fold choices survive release. +- Java capture temps IDs distinguish nested peep-created nodes from Parser-held + expression values. An unattached new replacement must not acquire a premature + Parser arrow. +- Chapters 18-25 mark Call/CallEnd/Fun/Return mid-inlining with folding:true. + The browser adds a small FOLDING tag and pink fill; this is unrelated to UI folds. + Read flags without calling transiently unsafe/mutating accessors (e.g. cend()). + +RETURN can precede caller attachment. GraphPeep.attached and viewer.resultEnd +conservatively extend to the next BEFORE/PHASE only if its changes are exactly +root->replacement rewires and deletion of the root/unused input nodes. No new +nodes or unrelated changes may slip in. The next BEFORE serves as both the +previous result and the next starting point. Preserve the original peep event +using editEvent; don't label it as the next peep. Streaming waits for that next +capture. Identical results without an attachment stay one-click, not empty zooms. + +Reproducer (chapter18): + +```simple +val _add1 = { int x -> return x+1; }; +val _mul2 = { int y -> return y*2; }; +return _mul2(1+_add1(2))+3; +``` + +Frame 111 BEFORE Phi_$mem#12 and 112 RETURN#67 had identical nodes; the caller's +ret.setDef happened in frame113. Playback now animates 111->113, showing Return#14 +memory input changing 12->67 and Phi12 disappearing. Likewise 113->115 for Phi13 +and 115->117 for Region11. No compiler peephole fix was needed. + +## Local verification tools (disposable, ignored) + +Windows workspace: C:/Users/cliffc/Desktop/Simple. Python is py -3.13. Playwright +is installed under build/graph-tools; headless Chromium channel='msedge' works. +Use an ephemeral HTTP port and intercepted browser WebSocket, or an isolated Java +capture server on an ephemeral port. Scratch helpers may disappear after cleanup. + +- build/build-graph-chapters.py: Make builds all chapters through Cygwin bash. +- build/check-viewer-errors.py: captures and checks latest TypeCheck feature; + build/error-chapterXX.json and build/viewer-error.png are outputs. +- build/check-peep-attach.py and check-peep-nav.py: attachment, streaming, reverse + navigation; build/peep111.json is the 174-frame capture above before TypeCheck. +- build/check-peep-gvn.py, check-peep-phis.py, check-peep-order.py: GVN endpoints, + sibling-Phi exclusion, nested replacement ordering. Some older scratch scripts + assumed adjacent capture frames and are stale after atomic peep playback. +- build/check-folding-state.py: inlining FOLDING labels; folding-frames.json is a + 349-frame chapter28b capture predating the added final TypeCheck frame. +- build/check-graph-finish.py defines capture(ch) before its chapter05 invocation; + helpers reuse that prefix. build/FinishFrames.java (build/graph-finish classes) + calls GraphCapture.run on an ephemeral socket without launching a browser. +- graph/test_browser.py and graph/test_transport.py are existing smoke tools. + +## Deferred work, not authorization to start + +Cliff considers incomplete/exit-loop grouping adequate as is. Bounded history +storage waits until an actual usage issue warrants it; full graph snapshots +currently remain cached. Stable whole-graph placement awaits viewing a larger +program to establish what is needed. Compilation-unit containers remain deferred. +These are future considerations, not unfinished requirements of the completed task. +Dead-field cleanup/interprocedural reverse +liveness is explicitly deferred; do not revive the rejected whole-graph store +sweep. Private-field syntax decisions belong in the parser, not optimization. |
