# 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 readiness, field, and 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, readiness state, 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" },
  readiness: { phase: "ready", canRun: true },
  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.

`createRunSessionReadinessState(input)` is the pure readiness helper used by the
workflow and panel state summary. It reports the selected program, loaded
session path, snapshot metadata, and whether the run button can execute.

## 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.
