# UI Run Summary Helpers

## Purpose

`runtime/ui/ini-panel/run-summary.js` contains small host-boundary helpers for
summarizing an INI panel G-code run.
`runtime/ui/ini-panel/run-workflow.js` contains the reusable UI workflow for
selecting the session/default G-code program, loading it from OPFS, staging it
into the interpreter WASM filesystem, invoking the LinuxCNC interpreter, and
returning run field/log state. These helpers are intentionally pure so browser
UI panels, SDK-facing wrappers, and Node smoke tests can share the same summary
shape without reading DOM text or parsing log output.

The helpers do not implement CNC behavior. G-code execution, canonical events,
tool handling, parameters, kinematics, and planner behavior remain owned by the
vendored LinuxCNC runtime.

## `createRunSummary(program, runtime, snapshot)`

`program` describes the host-selected program path mapping:

```js
{
  source: "default" | "snapshot",
  opfsPath: "linuxcnc/gcode/ui-session.ngc",
  wasmPath: "/work/ui-session.ngc"
}
```

`runtime` describes already-observed runtime boundary results:

```js
{
  runStatus: "ok",
  snapshotLabel: "ui-machine-session/ui-machine-session.json",
  iniWasmPath: "/work/session-machine.ini",
  canonicalEventCount: 2,
  motionSnapshotCount: 2
}
```

`snapshot` is the optional machine session snapshot loaded by the UI. The helper
reads only snapshot metadata such as `workflow` and `snapshotLabel`.
When `runtime.snapshotLabel` is present, it is used as the returned
`snapshotLabel`; otherwise the helper falls back to `snapshot.metadata.snapshotLabel`
and then `null`.

The returned summary has this shape:

```js
{
  runStatus: "ok",
  programSource: "snapshot",
  snapshotLabel: "ui-machine-session/ui-machine-session.json",
  workflow: "save-session-snapshot",
  programOpfsPath: "linuxcnc/gcode/ui-session.ngc",
  programWasmPath: "/work/ui-session.ngc",
  iniWasmPath: "/work/session-machine.ini",
  canonicalEventCount: 2,
  motionSnapshotCount: 2
}
```

## `summarizeRunResult(resultText, snapshots)`

`resultText` is the raw text returned by the LinuxCNC interpreter WASM call.
`snapshots` is the UI's already-parsed motion snapshot list.

The helper returns:

```js
{
  canonicalEventCount: 2,
  motionSnapshotCount: 2
}
```

`canonicalEventCount` only counts result lines beginning with `canon_event=`.
`motionSnapshotCount` is only `snapshots.length`.

## `runGcodeSessionWorkflow(input)`

The workflow requires a loaded machine session and injected host/runtime
functions:

```js
{
  interp,
  loadedSession,
  snapshot,
  loadGcodeProgram,
  gcodeFilenameFromProgramPath,
  summarizeRun
}
```

It returns the selected program mapping, raw interpreter result text, run
summary, UI field state, log lines, and optional UI motion snapshots produced
by the injected `summarizeRun` callback:

```js
{
  program: {
    source: "snapshot",
    opfsPath: "linuxcnc/gcode/ui-session.ngc",
    wasmPath: "/work/ui-session.ngc",
    text: "G0 X1\n"
  },
  resultText: "canon_event=...",
  summary: { runStatus: "ok", programSource: "snapshot" },
  fields: { runStatus: "ok", sessionGcode: "linuxcnc/gcode/ui-session.ngc" },
  motionSnapshots: [{ line: 1 }],
  logLines: ["Program: linuxcnc/gcode/ui-session.ngc -> /work/ui-session.ngc"]
}
```

`selectSessionGcodeProgram(input)` is the pure program-selection helper used by
the workflow. Invalid snapshot G-code paths fall back to the UI default program.

## Boundary Rules

- Do not parse G-code text in these helpers.
- Do not infer tool, parameter, kinematics, planner, or modal semantics.
- Do not derive new canonical events in JavaScript.
- Keep canonical-event and motion parsing in the existing UI display layer or
  inject it as already-observed UI state; the workflow must not own CNC
  semantics.
- Do not make UI helper output a promotion signal for runtime families blocked
  by host dependencies.
- Keep new fields limited to host/runtime boundary facts already produced by
  the LinuxCNC-owned runtime or UI staging layer.

## Validation

Run the focused Node smoke after changing these helpers:

```bash
wasm-port/tests/ui/node/verify_ini_panel_run_summary.sh
wasm-port/tests/ui/node/verify_ini_panel_run_workflow.sh
```

The aggregate UI Node smoke is:

```bash
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
```

`wasm-port/tests/host/verify_host_smokes.sh` includes the UI Node smoke so these
helpers are also covered by the regular host/WASM/browser gate.
