# 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 ``` 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=28 sim_configs_wasm_node_inventory_passed=28 sim_configs_wasm_node_inventory_skipped=131 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.