Skip to content

TiXL native operators — Path B, PCHI wire protocol direct, compiled against real Core.dll - #8

Merged
vdmo merged 1 commit into
mainfrom
feat/tixl-native-operators
Sep 30, 2026
Merged

vdmo merged 1 commit into
mainfrom
feat/tixl-native-operators

Conversation

@vdmo

@vdmo vdmo commented Sep 30, 2026

Copy link
Copy Markdown
Owner

Summary

Path B of the PCHI/TiXL integration (Path A: #6, the OSC bridge). TiXL has no separate plugin DLL system — per its own docs, "TiXL is the SDK": operators are C# source the running editor compiles and hot-reloads. These two files are real operators speaking PCHI's wire protocol directly — raw JSON-over-UDP out, WebSocket in — eliminating both the OSC round-trip and the external bridge process for TiXL specifically.

  • PCHISendControlParameter: sends a real control_parameter PCHIMessage straight to the Conductor's UDP port.
  • PCHIGovernanceReceive: owns its own ClientWebSocket (reconnecting), exposes GateState (same float-code encoding the OSC bridge uses, so both paths are interchangeable to an artist), ReceiptId, Tool, IsConnected as live graph values. Requires Fix: governance-event WebSocket broadcasts never reached anyone (two independent bugs) #5 on the Conductor.

Verification — stronger than the rest of this integration, and why

TiXL's Editor needs Windows (DirectX 11, WinForms) and can't run here — but Core.csproj, the library operators actually compile against, builds on Linux with -p:EnableWindowsTargeting=true (a standard cross-compile flag). I cloned tixl3d/tixl, installed the .NET 10 SDK locally, and genuinely compiled these two files against the real Core.dll: 0 warnings, 0 errors, confirmed again on a clean rebuild with the exact command documented in the README. That's the real compiler checking real API usage (Instance<T>, Slot<T>, InputSlot<T>, EvaluationContext, IStatusProvider), not written blind — a meaningfully stronger check than anything else in this integration has had.

Not verified: running inside a live TiXL editor. Turning this .cs file into an actual graph node needs the GUI (duplicate an existing operator to scaffold the .t3/.t3ui files the editor owns, then replace the generated body with this code) — stated plainly in the README as the one step this environment can't perform.

verify-build/Pchi.csproj is included so the compile check is reproducible by anyone reviewing this, not just asserted.

Test plan

  • dotnet build Operators/Pchi/Pchi.csproj -p:EnableWindowsTargeting=true -p:SolutionDir=... against a real tixl3d/tixl clone: 0 warnings, 0 errors
  • Repeated on a clean rebuild (removed bin/obj/.temp first) using the exact command in the README — same result
  • Not run inside the actual TiXL editor (Windows GUI) — see README

🤖 Generated with Claude Code

…rect, no OSC

Path B of the PCHI/TiXL integration (Path A: tools/tixl-pchi-bridge,
#6). TiXL has no separate plugin DLL system — per its own docs, "TiXL
*is* the SDK": operators are C# source the running editor compiles and
hot-reloads. These two files are real operators that speak PCHI's wire
protocol directly (raw JSON-over-UDP out, WebSocket in), eliminating
both the OSC round-trip and the external bridge process Path A needs,
for TiXL specifically.

- PCHISendControlParameter: TargetId/Parameter/Value/SendTrigger inputs,
  sends a real control_parameter PCHIMessage straight to the Conductor's
  UDP port. BuildWireJson() is the one place Rust's #[serde(rename)]
  wire names (type, payloadType) get applied — the exact field-name
  lesson from the Resolume/TiXL OSC bridges (#3), applied natively
  instead of relearned.
- PCHIGovernanceReceive: owns its own ClientWebSocket (reconnecting,
  background Task), exposes GateState (float code, same ALLOW/ESCALATE/
  DENY=1.0/0.5/0.0 encoding the OSC bridge uses so both paths are
  interchangeable to an artist), ReceiptId, Tool, IsConnected as live
  graph values. Requires #5 (the WS accept-loop fix) on the Conductor
  side.

## Verification — stronger than anything else in this integration, and why

TiXL's Editor needs Windows (DirectX 11, WinForms) and can't run here,
but Core.csproj — the library operators actually compile against —
builds on Linux with -p:EnableWindowsTargeting=true (a standard
cross-compile flag, not a workaround). Cloned tixl3d/tixl, installed
.NET 10 SDK (TixlNetFrameworkVersion = net10.0-windows) locally, and
compiled these two files against the real Core.dll: 0 warnings, 0
errors, on the first attempt and confirmed again on a clean rebuild
using the exact command documented in this commit's README. That's the
real compiler checking real API usage — Instance<T>, Slot<T>,
InputSlot<T>, EvaluationContext, IStatusProvider — not written blind.

Not verified: running inside a live TiXL editor. Turning this .cs file
into an actual graph node needs TiXL's GUI (duplicate an existing
operator to scaffold the accompanying .t3/.t3ui files TiXL's editor
owns, then replace the generated body with this code) — documented
plainly in the README as the one step this environment cannot perform
or verify.

verify-build/Pchi.csproj is included so the compile check is
reproducible by anyone, not just asserted.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
@vdmo
vdmo merged commit a3114d0 into main Sep 30, 2026
1 check passed
vdmo added a commit that referenced this pull request Sep 30, 2026
Third PCHI integration this session, alongside Resolume (#3) and TiXL
(#6, #8). cables.gl (https://github.com/cables-gl/cables, 562-star
open-source browser-based node/patch tool) runs in a browser sandbox,
which can't open the raw UDP socket the Conductor's control-update path
requires — so unlike TiXL's native operators, this needs a relay: HTTP
in (cables can always fetch()) -> raw JSON-over-UDP out to the
Conductor, and the Conductor's real governance-event WebSocket ->
relayed straight through to a WebSocket server cables can connect to
directly.

The governance-telemetry leg needed zero new protocol work: confirmed
from a real official example (cables-gl/websocket-example) that cables
already ships a working WebSocket-receive op against a plain `ws`
server — this relay's cables-facing WS server is deliberately that same
shape, not something invented for this integration.

Requires #5 (WS accept-loop fix) on the Conductor for governance
telemetry; control updates work regardless.

## A real mistake found and fixed along the way

Building this surfaced that the Heartbeat-exclusion fix (originally
meant to land in #5) had never actually made it into main — I'd pushed
it as a second commit onto that PR's branch and reported it as included,
but the merged PR only ever contained the first commit. Live-testing
this relay reproduced the exact duplicate-DENY bug the fix was supposed
to have eliminated. Re-landed as #9, cherry-picked cleanly, re-verified
live against this relay specifically (22s, 4+ heartbeat cycles, 1
receipt instead of 5) before writing this commit.

## Verification

Live, both directions, against a real Conductor:
- Outbound: a real POST (with an Origin header, and an explicit OPTIONS
  preflight check with Access-Control-Request-* headers — not just a
  bare curl a browser's CORS enforcement wouldn't accept) reaches the
  Conductor and is applied.
- Inbound: a real DENY is broadcast by the Conductor, relayed, and
  arrives at a real external WS client with the documented enriched
  shape (flattened gate_state/receipt_id/tool plus the full raw event).

Not tested against real cables.gl itself — the WebSocket-receive shape
is confirmed from a real official example; the HTTP-request op and
message parsing on the cables side are not independently confirmed the
way TiXL's operators were confirmed against real compiled source.
README states this plainly.

Co-authored-by: vdmo <[email protected]>
Co-authored-by: Claude Sonnet 5 <[email protected]>
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