# Project release handoff

This is the short project-level handoff for the current LinuxCNC WASM/browser
port scope. It points a new maintainer to the supported workflow surfaces, the
required release gates, and the boundaries that must remain blocked until real
LinuxCNC-owned runtime proof exists.

## Start here

Use these documents as the current handoff set:

- `README.md` for the workspace layout and release validation commands.
- `docs/panel-entry.md` for browser/UI entry points and shell handoff helpers.
- `runtime/sdk/README.md` for stable SDK imports from `runtime/sdk/src/index.js`.
- `docs/opfs-session-persistence.md` for OPFS/session persistence scope.
- `docs/real-browser-simulation-priority.md` for the standing first priority:
  build the real browser CNC simulation page before lower-value metadata work.
- `docs/sim-configs-coverage-handoff.md` for sim-config inventory status.
- `docs/host-runtime-boundary-handoff.md` for blocked runtime families.
- `docs/source-reuse-map.md` and `docs/drift-report.md` for LinuxCNC source
  reuse and non-drift rules.
- `../PROJECT_COMPLETION_TRACKER.md` for project-level acceptance tracking.

Old turn logs `text1.txt` through `text14.txt` are historical context. Current
continuation records are in `../text15.txt`.

## Supported current workflows

## First Priority Constraint

Subsequent work must prioritize a real browser CNC simulation page. The page
should converge on visible machine/session loading, G-code program state,
LinuxCNC-backed interpreter execution, machine readiness/status panels, and a
toolpath/preview area backed by LinuxCNC-produced output or validated runtime
events. The authoritative constraint is
`docs/real-browser-simulation-priority.md`.
Its executable docs gate is
`verify_real_browser_simulation_priority_docs.sh`, which is included in the
host smoke and project release gate and ends with
`real_browser_simulation_priority_docs_node_smoke=ok`.
The first implementation entry point is `runtime/ui/simulation/index.html`,
validated by `verify_real_simulation_browser.sh`, which ends with
`browser_real_simulation_page_smoke=ok`.

This priority does not permit JavaScript-owned CNC semantics. G-code, tool,
parameter, kinematics, remap, planner, and canonical motion behavior must remain
owned by vendored LinuxCNC source and existing LinuxCNC-backed WASM boundaries.

- INI panel launch, edit/run page, read-only control page, workflow overview,
  and external shell handoff are exposed from `runtime/ui/ini-panel/`.
- External shells should use the read-only helpers documented in
  `docs/panel-entry.md`, including workflow overview embedding mount DOM
  contract/readiness/renderer/wrapper helpers.
- SDK callers should import stable helpers from `runtime/sdk/src/index.js`,
  including `createIniPanelShellApiSurfaceInventory()` for API discovery and
  `createIniPanelShellSessionReadinessWorkflowReport()` when they need
  machine-readable session readiness phase and missing reasons. The workflow
  overview exposes the API surface inventory as a read-only summary row.
- Project-level virtual HAL is exposed from the same SDK entrypoint for
  simulation pages, INI-panel shells, Node/browser smokes, and external
  dashboards. Use `createVirtualHalState()`, `applyVirtualHalAction()`,
  `createLinuxCncVirtualHalRuntime()`, and
  `createVirtualHalWasmBridgeSnapshot()` for shared browser virtual HAL state
  and standalone interpreter bridge values. Use
  `createVirtualHalPinInventory()`, `createVirtualHalBridgeReadiness()`,
  `createVirtualHalBridgeActionPlan()`, and
  `createVirtualHalProjectReport()` when a caller needs a machine-readable
  project report, pin inventory, or readiness/action-plan surface. The bridge
  readiness checks caller-provided evidence for
  `VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS`, while
  `VIRTUAL_HAL_PROJECT_PIN_GROUPS` provides stable inventory grouping.
  `VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES`,
  `executeVirtualHalCommand()`, `stepVirtualHalMotion()`, and
  `createVirtualHalSimulationRuntimeReport()` provide the simulation-grade
  replacement for host `halcmd`, HAL pin/signal/param storage, and the basic
  motion feedback loop used by browser/Node simulation. For simulation, this
  removes the host `halcmd`/`halrun`/motion-controller requirement.
  `applyVirtualHalToInterpSdk()` is the common adapter for interpreter SDK
  instances that expose `applyVirtualHalState()` or
  `applyVirtualHalSnapshot()`. This is a simulation runtime and virtual
  realtime HAL runtime replacement for browser workflows, not a Linux kernel
  hard-realtime ABI; kernel realtime scheduling, external device drivers, native
  HAL module ABI behavior, HALUI process behavior, Tcl/Python process
  integration, and external device semantics remain explicit boundaries.
- CI dashboards and external SDK callers can use
  `createProjectReleaseGateManifest()` to discover required gate commands and
  expected smoke outputs, `createProjectReleaseGateResultMatrix()` to map
  observed outputs onto passed/unknown gate rows,
  `createProjectReleaseGateActionPlan()` to derive pending gate commands, the
  next command, display rows, and a shell script from that matrix,
  `createProjectReleaseGateExecutionManifest()` to package each gate command,
  expected output, observed-output evidence, and passed/unknown status,
  `createProjectReleaseGateExecutionSummaryViewModel()` to expose dashboard
  status text, evidence counts, next missing gate, and normalized per-gate rows,
  and
  `createProjectReleaseReadinessReport()` for a machine-readable release
  readiness report covering the same manifest, execution manifest, result
  matrix, action plan, sim-config inventory baseline, and blocked runtime
  families.
  `createProjectReleaseReadinessSummaryViewModel()` turns that report into
  stable status text and rows for dashboards. The report helper is evidence
  driven and only reports `ready: true` when the caller supplies release gate
  evidence such as `project_release_gate=ok`. The project release gate writes
  the same report to `build/project-release-readiness.json` and validates it
  with `verify_project_release_readiness_artifact.sh`.
  External tools can load that artifact with
  `parseProjectReleaseReadinessArtifactJson()` and validate it with
  `createProjectReleaseReadinessArtifactValidation()`. Artifact validation
  requires the embedded gate manifest, execution manifest, result matrix, and
  action plan to be ready, so stale release JSON cannot pass the executable
  artifact gate.
  `createProjectReleaseReadinessArtifactValidationSummaryViewModel()` turns the
  validation into stable dashboard rows without reinterpreting artifact fields.
  `createProjectReleaseReadinessArtifactValidationActionPlan()` turns a blocked
  artifact validation into the project release gate and artifact validation
  commands to run next, plus the missing evidence rows.
  `createProjectReleaseReadinessArtifactJsonWorkflow()` is the one-call
  non-throwing JSON text workflow for dashboards that need parse, validation,
  summary, and action-plan output from the readiness artifact.
  `loadProjectReleaseReadinessArtifactUrlWorkflow()` provides the same
  SDK-side workflow from an artifact URL and caller-provided fetch
  implementation, including fetch status and next-command output.
  `createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel()` turns
  that SDK URL workflow into stable dashboard rows and status text.
  `createProjectReleaseReadinessArtifactUrlWorkflowActionPlan()` turns blocked
  URL workflows into ordered input, fetch, and command actions for CI tooling.
  `createProjectBatchAcceptanceCapabilityMatrix()` classifies per-batch evidence
  into accepted API/workflow/gate/browser capabilities and rejected entries.
  `createProjectBatchAcceptanceWorkflow()` records the per-batch acceptance rule
  that each batch must ship at least one callable API, verifiable workflow,
  executable gate, or browser capability. Its summary view-model and action-plan
  helpers provide dashboard rows and the next batch-acceptance gate command.
  `createProjectBatchAcceptanceChecklist()` combines those results into
  pass/blocked checklist rows for external release dashboards.
  `createProjectBatchAcceptanceReport()` packages the matrix, workflow,
  summary, action plan, and checklist into one stable CI/dashboard object.
  `createProjectBatchAcceptanceReportValidation()` and
  `createProjectBatchAcceptanceReportJsonWorkflow()` validate that object from
  parsed data or JSON text without throwing.
  `createProjectBatchAcceptanceReportValidationSummaryViewModel()` and
  `createProjectBatchAcceptanceReportValidationActionPlan()` expose dashboard
  rows and the next artifact gate command for blocked report validation.
  `loadProjectBatchAcceptanceReportUrlWorkflow()` fetches hosted batch
  acceptance report JSON through a caller-provided `fetch` implementation, then
  runs the same validation workflow without throwing.
  `createProjectBatchAcceptanceReportUrlWorkflowSummaryViewModel()` and
  `createProjectBatchAcceptanceReportUrlWorkflowActionPlan()` expose dashboard
  rows and ordered input/fetch/gate actions for that URL workflow.
  The executable batch acceptance gate writes
  `build/project-batch-acceptance.json` with
  `write_project_batch_acceptance_artifact.mjs` and validates it through
  `verify_project_batch_acceptance_artifact.sh`, ending with
  `project_batch_acceptance_artifact_node_smoke=ok`.
  Workflow overview shells can use
  `getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel()`
  and
  `getWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel()`
  to display the embedded release gate execution summary without parsing
  artifact internals. They can render or mount those per-gate rows through
  `getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState()`,
  `getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract()`,
  `getWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness()`,
  `renderWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState()`, and
  `mountWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState()`, and
  `getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan()` to show
  the URL workflow next action or command without executing gates. Direct JSON
  validation callers can use
  `getWorkflowOverviewReleaseReadinessArtifactValidationActionPlan()` for the
  artifact-validation next-command plan. They can render or mount that action
  plan through
  `getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState()`,
  `getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract()`,
  `getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness()`,
  `renderWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState()`, and
  `mountWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState()`.
  Browser shells can also pass the JSON to
  `linuxCncIniPanelWorkflowOverviewApi.validateWorkflowOverviewReleaseReadinessArtifactJson()`
  through the workflow overview iframe and receive stable validation rows. They
  can call `runWorkflowOverviewReleaseReadinessArtifactJsonWorkflow()` when they
  need parse, validation, summary, action-plan, and gate execution summary
  output in one workflow result, and
  `getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel()`
  when they need stable dashboard rows for that JSON workflow. The JSON
  workflow action plan is available through
  `getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan()`. They
  can render or mount the JSON workflow state into caller-owned DOM through
  `getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract()`,
  `getWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness()`,
  `renderWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState()`, and
  `mountWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState()`. They
  can also call
  `linuxCncIniPanelWorkflowOverviewApi.loadWorkflowOverviewReleaseReadinessArtifactUrl()`
  to fetch the artifact URL, validate it, and optionally mount the resulting
  read-only render state. That URL workflow includes a validation summary
  view-model and can be summarized with
  `getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel()`.
  The same workflow can expose the ordered next-action plan through
  `getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan()`. Shells
  can render or mount the URL workflow state through
  `getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState()`,
  `getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract()`,
  `getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness()`,
  `renderWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState()`, and
  `mountWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState()`.
  Direct artifact JSON validation can expose its own next-command plan through
  `getWorkflowOverviewReleaseReadinessArtifactValidationActionPlan()`.
  When the outer shell needs DOM output, the workflow
  overview iframe also exposes
  display, render-state, DOM readiness, renderer, and mount helpers for the
  same release readiness artifact validation.
- OPFS/session callers can use `createMachineSessionPersistenceSummary()` or
  `linuxCncIniPanelApi.getMachineSessionPersistenceSummary()` to inspect
  machine files, session snapshot, session readiness, session load, readonly
  status, and shell handoff readiness as stable rows. Shell handoff workflow
  summaries can include that report as the `persistence-summary` row beside the
  API surface inventory row, and launch/workflow-overview APIs expose the same
  helper for external shells. The summary also has display and render-state
  helpers for caller-owned DOM.
- OPFS/session persistence also has a dedicated browser workflow gate,
  `verify_opfs_session_workflow_browser.sh`, covering save machine files, save
  G-code, save session snapshot, session readiness, load into WASM, and
  persistence summary output.
- OPFS/session persistence is host-side storage glue. Parameter and tool-table
  behavior still comes from the LinuxCNC-backed interpreter SDK calls.
- Sim-config inventory promotion remains evidence-driven and must keep
  `unexpected_fail=0`.

## Required release gates

Run the single project release gate before claiming the current scope is
release-ready:

```bash
wasm-port/tests/host/verify_project_release_gate.sh
```

It executes the same minimum release validation commands:

```bash
git diff --check
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tools/verify_no_standalone_cnc_semantics.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_opfs_session_workflow_browser.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_release_artifact_url_workflow_browser.sh
wasm-port/tests/sdk/node/verify_project_batch_acceptance_workflow.sh
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
wasm-port/tests/sdk/node/verify_project_release_artifact_url_workflow.sh
wasm-port/tests/host/verify_host_smokes.sh
```

The host aggregate gate includes SDK, OPFS, docs, UI Node, WASM Node, and
browser smoke coverage. The project release gate then writes and verifies a
machine-readable release readiness artifact:

```text
project_release_readiness_artifact=...
project_release_readiness_artifact_node_smoke=ok
```

The readiness artifact exposes the promotion candidate TSV as a
release-visible summary without treating it as a runtime unlock:

```text
promotion-candidate-artifact=wasm-port/build/wasm/sim-configs-inventory/promotion-candidates.tsv
promotion-candidate-artifact-rows=28
promotion-candidate-layers=evidence-ready=8 inventory-ready=2
promotion-candidate-total=28
evidence-ready-candidate-rows=8
evidence-ready-candidate-preview=qtdragon-multi-joint-on-abort
evidence-ready-candidate-preview-gcode=linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc
evidence-ready-candidate-promotion-allowed=0
evidence-ready-candidate-baseline-changing=no
evidence-expansion-candidates=13
evidence-expansion-artifact-rows=13
evidence-expansion-artifact=wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv
promotion-candidate-allowed=0
```

A passing aggregate ends with:

```text
host_wasm_opfs_browser_smokes=ok
project_release_gate=ok
```

## Expected baseline outputs

The current sim-config inventory release baseline is:

```text
sim_configs_wasm_node_inventory_executed=82
sim_configs_wasm_node_inventory_passed=82
sim_configs_wasm_node_inventory_skipped=77
sim_configs_wasm_node_inventory_unexpected_fail=0
```

The expected docs and SDK smoke outputs include:

```text
project_release_handoff_docs_node_smoke=ok
opfs_session_docs_node_smoke=ok
sim_configs_coverage_docs_node_smoke=ok
host_runtime_boundary_docs_node_smoke=ok
sdk_surface_node_smoke=ok
project_batch_acceptance_workflow_node_smoke=ok
project_release_artifact_url_workflow_node_smoke=ok
```

The expected browser INI panel smoke outputs include:

```text
browser_ini_opfs_smoke=ok
browser_ini_control_page_smoke=ok
browser_ini_launch_smoke=ok
browser_ini_workflow_overview_smoke=ok
browser_ini_shell_integration_workflow_smoke=ok
browser_opfs_session_workflow_smoke=ok
browser_release_artifact_url_workflow_smoke=ok
```

## Blocked runtime families

These runtime families remain blocked:

- `L4-USER-M-PROCESS`
- `L4-TOOL-DB`
- `L4-PYTHON-REMAP`

Do not promote them from skipped/blocked state without LinuxCNC-owned native
runtime proof followed by Node/WASM and browser/host validation. The opt-in
runtime probes are documented in `docs/host-runtime-boundary-handoff.md`; they
must not be run on hosts that do not provide the required LinuxCNC runtime.

## Acceptance checklist

- `git diff --check` passes.
- Vendor sync and standalone CNC semantic guards pass.
- Interpreter WASM Node smoke passes.
- Sim-config inventory has `unexpected_fail=0`.
- UI Node smoke passes.
- Browser INI panel smoke passes.
- Release artifact URL browser workflow smoke passes.
- Host aggregate smoke passes.
- `verify_project_release_gate.sh` passes.
- SDK exports match `runtime/sdk/README.md`.
- `docs/panel-entry.md` documents the external shell workflow surface.
- OPFS/session, sim-config coverage, host/runtime boundary, source reuse, and
  drift docs all point to the current validation gates.
- Blocked runtime families remain documented and are not falsely promoted.

## Next maintainer rule

Add new CNC behavior only by reusing vendored LinuxCNC source or a documented
runtime-edge adapter. JavaScript may stage files, mount UI state, manage OPFS,
load WASM modules, and call C ABI functions; it must not implement G-code,
tool, parameter, planner, kinematics, remap, or canonical motion semantics.
