Skip to content

Commit 47110a2

Browse files
committed
Rebuild graph as semantic presentation map
1 parent 2c6f4d9 commit 47110a2

11 files changed

Lines changed: 2816 additions & 564 deletions
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Graph Semantic Map Implementation Plan
2+
3+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4+
5+
**Goal:** Replace the current graph framing with a true semantic map stage that uses stable x/y semantics, Nobel reference beacons, and stage-only pan/zoom.
6+
7+
**Architecture:** Keep `GraphPage` and the existing drawer/detail UI, but move graph positioning into a semantic projection layer. Render the dense node/edge layer on canvas, while using an SVG overlay for axes, domain bands, Nobel beacons, and stage framing. Derive node positions from public-domain anchors and execution-maturity bands instead of raw force-layout coordinates.
8+
9+
**Tech Stack:** React, TypeScript, canvas 2D, SVG overlay, existing theme tokens, existing public-domain mapping
10+
11+
---
12+
13+
### Task 1: Add Semantic Layout Utilities
14+
15+
**Files:**
16+
- Create: `src/utils/graphSemanticLayout.ts`
17+
- Create: `scripts/graph-semantic-layout-check.ts`
18+
19+
- [ ] Define public x-axis anchors for the 9 public domains and four y-axis maturity bands in `src/utils/graphSemanticLayout.ts`.
20+
- [ ] Add deterministic jitter helpers seeded by node id so the semantic map feels organic but remains stable across reloads.
21+
- [ ] Export a `projectSemanticNode(node)` function that returns semantic `x`, `y`, public-domain label, and maturity band.
22+
- [ ] Write `scripts/graph-semantic-layout-check.ts` first with assertions that:
23+
- `pretraining` projects into `Information Science`
24+
- `physics` projects into the `Physics` x-band
25+
- `status: "hypothesis"` projects into the top maturity band
26+
- execution-bearing nodes project into lower bands
27+
- [ ] Run a TypeScript compile check on the script and confirm it fails before the helper exists or before exports line up.
28+
- [ ] Implement the helper minimally until the check script compiles and passes.
29+
30+
### Task 2: Add Nobel Reference Data
31+
32+
**Files:**
33+
- Create: `src/utils/nobelReferences.ts`
34+
- Reference: `../ScivBook/frontend/src/data/nobelPrizes.json`
35+
36+
- [ ] Copy the Nobel records needed for the semantic map into a local `nobelReferences.ts` dataset so SeevoMap does not depend on the ScivBook project at runtime.
37+
- [ ] Normalize each Nobel entry into:
38+
- `id`
39+
- `year`
40+
- `field`
41+
- `contribution`
42+
- `publicDomain`
43+
- `xBand`
44+
- `yBand`
45+
- [ ] Keep the first implementation lightweight: beacons may be static reference marks and do not need full detail panels.
46+
47+
### Task 3: Refactor GraphVisualization Into a Semantic Stage
48+
49+
**Files:**
50+
- Modify: `src/components/GraphVisualization.tsx`
51+
52+
- [ ] Replace the current "entire full-screen canvas is pannable" interaction with a bounded semantic stage.
53+
- [ ] Restrict pan/zoom to pointer interactions that start inside the semantic stage.
54+
- [ ] Render the stage boundary and axis frame in SVG so it remains crisp and synchronized with camera movement.
55+
- [ ] Replace the current semantic overlay with:
56+
- x-axis macro/micro guide
57+
- y-axis execution-maturity guide
58+
- 9 public-domain labels along the x-axis
59+
- 4 maturity labels along the y-axis
60+
- [ ] Use `projectSemanticNode()` for node positions instead of raw `node.x/node.y` when drawing the semantic map.
61+
- [ ] Continue to use the existing hover and click behavior, but translate hit testing to semantic positions.
62+
- [ ] Reduce edge density or edge prominence so the result reads as a map, not a wire cloud.
63+
64+
### Task 4: Nobel Beacon Overlay
65+
66+
**Files:**
67+
- Modify: `src/components/GraphVisualization.tsx`
68+
- Reference: `src/utils/nobelReferences.ts`
69+
70+
- [ ] Render Nobel beacons above the stage background and below the selected-node UI.
71+
- [ ] Give beacons lighter visual weight than SeevoMap nodes so they guide reading without overpowering the map.
72+
- [ ] Reuse the ScivBook-style reference idea:
73+
- beacons are semantic anchors
74+
- they are not part of graph filtering
75+
- they help users orient by field and maturity
76+
- [ ] Spread Nobel beacons across the full semantic field using the scale-map coordinates as the primary signal, instead of collapsing them into tight domain-local stacks.
77+
- [ ] Add a lightweight legend and hover introduction so users understand that the beacons are Nobel reference landmarks rather than regular graph nodes.
78+
79+
### Task 5: Verification
80+
81+
**Files:**
82+
- Modify: none
83+
84+
- [ ] Run `npm run build`.
85+
- [ ] Restart `npm run dev:local`.
86+
- [ ] Verify locally on `/#/graph`:
87+
- only the stage area is draggable
88+
- the graph fills the stage more tightly
89+
- the x-axis shows both macro/micro direction and 9 public domains
90+
- the y-axis shows the 4 execution-maturity bands
91+
- Nobel beacons render as reference markers
92+
- drawer filtering, hover, and selected-node detail still work
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as assert from "node:assert/strict";
2+
import {
3+
getPublicDomainAnchor,
4+
getSemanticMaturityBand,
5+
projectSemanticNode,
6+
} from "../src/utils/graphSemanticLayout";
7+
import type { MapNode } from "../src/utils/types";
8+
9+
const hypothesisNode: MapNode = {
10+
id: "hypothesis-node",
11+
label: "Try a new mechanism",
12+
x: 0,
13+
y: 0,
14+
domain: "physics",
15+
metric_name: "novelty_score",
16+
metric_value: 8.7,
17+
status: "hypothesis",
18+
};
19+
20+
const executionNode: MapNode = {
21+
id: "execution-node",
22+
label: "Run the eval and keep the winning patch",
23+
x: 0,
24+
y: 0,
25+
domain: "pretraining",
26+
metric_name: "val_bpb",
27+
metric_value: 1.12,
28+
success: true,
29+
status: "approved",
30+
};
31+
32+
assert.equal(getPublicDomainAnchor("pretraining").label, "Information Science");
33+
assert.equal(getPublicDomainAnchor("physics").label, "Physics");
34+
assert.equal(getSemanticMaturityBand(hypothesisNode).key, "hypothesis_led");
35+
assert.equal(getSemanticMaturityBand(executionNode).key, "execution_ready");
36+
37+
const projectedPhysics = projectSemanticNode(hypothesisNode);
38+
const projectedInfo = projectSemanticNode(executionNode);
39+
40+
assert.ok(projectedPhysics.x > 0 && projectedPhysics.x < 1);
41+
assert.ok(projectedPhysics.y > 0 && projectedPhysics.y < 1);
42+
assert.ok(projectedInfo.x < projectedPhysics.x, "Information Science should sit left of Physics");
43+
assert.ok(projectedInfo.y > projectedPhysics.y, "Execution-ready nodes should sit lower than hypothesis-led nodes");
44+
45+
console.log("graph semantic layout checks passed");

0 commit comments

Comments
 (0)