Skip to content

Qt-removal R0: foundations - Python backend, single SPA, native pywebview shell, burn-down gate#99

Merged
dovvnloading merged 2 commits into
mainfrom
qt-removal/r0-foundations
Jul 22, 2026
Merged

Qt-removal R0: foundations - Python backend, single SPA, native pywebview shell, burn-down gate#99
dovvnloading merged 2 commits into
mainfrom
qt-removal/r0-foundations

Conversation

@dovvnloading

Copy link
Copy Markdown
Owner

Phase R0 of the Qt/PySide6 full-removal plan

Terminal goal (the only definition of done): zero PySide6 anywhere, package uninstalled, full parity — enforced by a permanent gate test. This PR lands the foundations; it adds only Qt-free code and touches no existing behavior.

What's in it

  • backend/ — FastAPI + session-scoped WebSocket event bus (versioned full-state snapshots + named intents, the direct successor of the QWebChannel IslandBridge wire contract), static SPA serving, /api/health. 14 tests.
  • web_ui/src/app — the single-SPA target that will consolidate the ~19 islands (GRAPHLINK_ISLAND=app builds to dist/app). New WS transport with auto-reconnect + re-subscribe (9 tests), token-driven shell.
  • api-contract codegentopics.ts generated from the existing island schema registry: topic → TS type + runtime validator, --check enforced.
  • graphlink_desktop.py — native desktop window via pywebview/WebView2. Not a browser, not Qt: boots the backend on a free localhost port and opens the app window.
  • Burn-down gatetests/test_no_qt_anywhere.py + qt_burndown.json, pinned at 168 Qt-importing files (90 source + 78 tests). Any increase fails CI; every removal must lower the pin in the same commit; at pin 0 the test additionally asserts PySide6 is uninstalled and undeclared. backend/, web_ui/, and the desktop entry are held to zero Qt from day one.

Acceptance (per plan R0)

  • python graphlink_desktop.py opened a native window with the SPA shell served by the Python backend ✅
  • Live WebSocket ping round-trip through the window: 4.1 ms
  • Gate test green in burn-down mode ✅
  • Full verification: 17 pytest + 544 vitest passing; codegen --check clean ✅

Burn-down: 168 of 168 remaining. (R0 builds the replacement rails; deletion begins as surfaces move over in R1+.)

dovvnloading and others added 2 commits July 22, 2026 11:15
…down gate

Per doc/QT_REMOVAL_PLAN.md phase R0 (terminal goal: ZERO PySide6/Qt):

- backend/: FastAPI app + session-scoped WebSocket event bus carrying the
  same versioned full-state-snapshot + named-intent wire semantics as the
  IslandBridge layer it succeeds; static serving of the SPA build;
  /api/health; 14 pytest cases (bus + WS endpoint).
- web_ui/src/app: the single-SPA target consolidating the islands
  (GRAPHLINK_ISLAND=app builds to dist/app). WS transport module with
  auto-reconnect/re-subscribe (9 tests), token-driven shell layout, live
  system panel.
- graphlink_island_codegen.py: emits web_ui/src/lib/api-contract/topics.ts,
  the SPA's topic->type/validator registry derived from the same schema
  registry (--check enforced).
- graphlink_desktop.py: NATIVE pywebview/WebView2 window (not a browser,
  zero Qt) that boots the backend and opens the SPA.
- tests/test_no_qt_anywhere.py + qt_burndown.json: THE permanent gate.
  Pin = 168 files importing Qt (90 source + 78 tests); any increase fails,
  any decrease must lower the pin in-commit; flips to zero-mode assertions
  (package uninstalled, undeclared) when the pin reaches 0. backend/,
  web_ui/, and graphlink_desktop.py are held to zero Qt from day one.

Acceptance drive PASSED: native window, SPA served by the Python backend,
live WS ping round-trip 4.1 ms. 17 pytest + 544 vitest green.
Burn-down: 168 of 168 remaining (R0 adds only Qt-free code by design).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… SPA target

- App.tsx: drop the vestigial transportRef (ref write during render -
  react-hooks/refs error); the memoized transport was already the only
  consumer.
- transport.test.ts: comma-expression assertion rewritten as a real
  assertion (no-unused-expressions error).
- test_gl_vars_dev_css.py: src/app is a documented carve-out from the
  dev-only token rule - the SPA has no Qt host injecting :root tokens, so
  the shipped file IS its token source until R2's backend-served theme.
  Islands remain fully guarded.

Local CI parity: npm run check exit 0; full offscreen pytest 1783 passed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dovvnloading
dovvnloading merged commit ec0438b into main Jul 22, 2026
2 checks passed
@dovvnloading
dovvnloading deleted the qt-removal/r0-foundations branch July 22, 2026 15:26
dovvnloading added a commit that referenced this pull request Jul 22, 2026
…e R1 superset

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dovvnloading added a commit that referenced this pull request Jul 22, 2026
…ng the R2 superset

# Conflicts:
#	backend/app.py
#	backend/canvas.py
#	backend/tests/test_app_ws.py
#	backend/tests/test_canvas.py
#	graphlink_app/graphlink_island_codegen.py
#	graphlink_app/graphlink_scene_payload.py
#	web_ui/src/app/App.tsx
#	web_ui/src/app/canvas/SceneCanvas.tsx
#	web_ui/src/app/canvas/sceneStore.test.ts
#	web_ui/src/app/canvas/sceneStore.ts
#	web_ui/src/app/styles.css
#	web_ui/src/lib/bridge-core/generated/scene-state.schema.json
#	web_ui/src/lib/bridge-core/generated/scene-state.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant