Complete sim config boundary coverage

This commit is contained in:
2026-06-11 06:12:06 +08:00
parent 5bd8f12872
commit 1ab5571ae1
76 changed files with 18975 additions and 146 deletions

View File

@@ -32,6 +32,8 @@ hash_build_validation_inputs() {
-o -name '*.run.stdout.log' \
-o -name '*.run.stderr.log' \
-o -name 'source-probes.tsv' \
-o -name 'native-source-proof-summary.tsv' \
-o -name 'native-runtime-probe-summary.tsv' \
-o -name 'native-probes.ok' \
-o -name 'linuxcnc_interp_minimal_harness' \
\) \
@@ -122,13 +124,195 @@ check_exitcode() {
fi
}
check_native_source_proof_summary_row() {
local boundary_class="$1"
local proof_key="$2"
local summary_file="$BUILD_DIR/native-source-proof-summary.tsv"
local row
row="$(awk -F'\t' -v boundary_class="$boundary_class" -v proof_key="$proof_key" '
NR > 1 && $1 == boundary_class && $2 == proof_key { print; count++ }
END {
if (count != 1) {
exit 1
}
}
' "$summary_file")" || {
echo "missing native source proof summary row: $boundary_class $proof_key" >&2
exit 1
}
local proof_value
local execution_enabled
local promotion_allowed
local stdout_log
IFS=$'\t' read -r _ _ proof_value execution_enabled promotion_allowed stdout_log <<< "$row"
if [[ "$proof_value" != "1" ]]; then
echo "$boundary_class native source proof is not complete: $proof_value" >&2
exit 1
fi
if [[ "$execution_enabled" != "0" || "$promotion_allowed" != "0" ]]; then
echo "$boundary_class unexpectedly enables execution or promotion" >&2
exit 1
fi
if [[ ! -f "$BUILD_DIR/$stdout_log" ]]; then
echo "$boundary_class summary references missing stdout log: $stdout_log" >&2
exit 1
fi
}
check_native_source_proof_summary() {
local summary_file="$BUILD_DIR/native-source-proof-summary.tsv"
if [[ ! -f "$summary_file" ]]; then
echo "missing native source proof summary: $summary_file" >&2
exit 1
fi
local expected_header
expected_header=$'boundary_class\tproof_key\tproof_value\texecution_enabled\tpromotion_allowed\tstdout_log'
if [[ "$(sed -n '1p' "$summary_file")" != "$expected_header" ]]; then
echo "native source proof summary header drift: $summary_file" >&2
exit 1
fi
local row_count
row_count="$(awk 'END { print NR - 1 }' "$summary_file")"
if [[ "$row_count" != "3" ]]; then
echo "native source proof summary must contain exactly 3 proof rows, got $row_count" >&2
exit 1
fi
check_native_source_proof_summary_row \
L4-USER-M-PROCESS \
millturn_user_m_native_source_state_proof
check_native_source_proof_summary_row \
L4-TOOL-DB \
tool_db_native_source_protocol_proof
check_native_source_proof_summary_row \
L4-PYTHON-REMAP \
python_remap_native_source_inventory_proof
}
check_native_runtime_probe_summary_row() {
local boundary_class="$1"
local boundary_kind="$2"
local target="$3"
local runtime_probe="$4"
local summary_file="$BUILD_DIR/native-runtime-probe-summary.tsv"
local row
row="$(awk -F'\t' \
-v boundary_class="$boundary_class" \
-v boundary_kind="$boundary_kind" \
-v target="$target" \
-v runtime_probe="$runtime_probe" '
NR > 1 && $1 == boundary_class && $2 == boundary_kind && $3 == target && $4 == runtime_probe {
print
count++
}
END {
if (count != 1) {
exit 1
}
}
' "$summary_file")" || {
echo "missing native runtime probe summary row: $boundary_class $boundary_kind $target" >&2
exit 1
}
local runtime_ready
local source_proof_ready
local probe_status
local execution_enabled
local promotion_allowed
local missing_requirements
local stdout_log
IFS=$'\t' read -r _ _ _ _ runtime_ready source_proof_ready probe_status execution_enabled promotion_allowed missing_requirements stdout_log <<< "$row"
if [[ "$source_proof_ready" != "1" ]]; then
echo "$target runtime probe lacks source proof readiness: $source_proof_ready" >&2
exit 1
fi
if [[ "$execution_enabled" != "0" || "$promotion_allowed" != "0" ]]; then
echo "$target runtime probe unexpectedly enables execution or promotion" >&2
exit 1
fi
if [[ ! "$probe_status" =~ ^(skipped_missing_host_runtime|ready_disabled_by_default|not_implemented_full_process_guard|runtime_state_probe_passed|runtime_protocol_probe_passed|runtime_lifecycle_probe_passed)$ ]]; then
echo "$target runtime probe has invalid status: $probe_status" >&2
exit 1
fi
if [[ "$runtime_ready" == "0" && "$probe_status" != "skipped_missing_host_runtime" ]]; then
echo "$target runtime probe is not ready but did not skip: $probe_status" >&2
exit 1
fi
if [[ "$runtime_ready" == "1" && "$missing_requirements" != "-" ]]; then
echo "$target runtime probe is ready but lists missing requirements: $missing_requirements" >&2
exit 1
fi
if [[ ! -f "$BUILD_DIR/$stdout_log" ]]; then
echo "$target runtime summary references missing stdout log: $stdout_log" >&2
exit 1
fi
}
check_native_runtime_probe_summary() {
local summary_file="$BUILD_DIR/native-runtime-probe-summary.tsv"
if [[ ! -f "$summary_file" ]]; then
echo "missing native runtime probe summary: $summary_file" >&2
exit 1
fi
local expected_header
expected_header=$'boundary_class\tboundary_kind\ttarget\truntime_probe\truntime_ready\tsource_proof_ready\tprobe_status\texecution_enabled\tpromotion_allowed\tmissing_requirements\tstdout_log'
if [[ "$(sed -n '1p' "$summary_file")" != "$expected_header" ]]; then
echo "native runtime probe summary header drift: $summary_file" >&2
exit 1
fi
local row_count
row_count="$(awk 'END { print NR - 1 }' "$summary_file")"
if [[ "$row_count" != "3" ]]; then
echo "native runtime probe summary must contain exactly 3 probe rows, got $row_count" >&2
exit 1
fi
check_native_runtime_probe_summary_row \
L4-USER-M-PROCESS \
external_user_m_process \
axis/vismach/millturn/example.ngc \
linuxcnc_millturn_user_m_runtime_probe
check_native_runtime_probe_summary_row \
L4-TOOL-DB \
tool_database_process \
axis/db_demo/base.ngc \
linuxcnc_tool_db_runtime_probe
check_native_runtime_probe_summary_row \
L4-PYTHON-REMAP \
python_runtime \
axis/remap/stop-lookahead/nc_files \
linuxcnc_python_remap_runtime_probe
}
check_source_probe_coverage
check_native_source_proof_summary
check_native_runtime_probe_summary
check_exitcode linuxcnc_interp_state_probe
check_exitcode linuxcnc_emc_status_probe
check_exitcode linuxcnc_emc_status_probe.run
check_exitcode linuxcnc_inifile_source_probe
check_exitcode linuxcnc_5axis_remap_asset_probe
check_exitcode linuxcnc_5axis_remap_asset_probe.run
check_exitcode linuxcnc_millturn_user_m_boundary_probe
check_exitcode linuxcnc_millturn_user_m_boundary_probe.run
check_exitcode linuxcnc_millturn_user_m_runtime_probe.run
check_exitcode linuxcnc_tool_db_boundary_probe
check_exitcode linuxcnc_tool_db_boundary_probe.run
check_exitcode linuxcnc_python_remap_boundary_probe
check_exitcode linuxcnc_python_remap_boundary_probe.run
check_exitcode linuxcnc_python_remap_runtime_probe.run
check_exitcode linuxcnc_tp_api_probe
check_exitcode linuxcnc_tp_api_probe.run
check_exitcode linuxcnc_kinematics_probe
@@ -381,6 +565,157 @@ grep -Fq "xyzac_trt_switch_mcodes_from_linuxcnc=1" "$FIVEAXIS_REMAP_ASSET_STDOUT
grep -Fq "xyzbc_trt_switch_mcodes_from_linuxcnc=1" "$FIVEAXIS_REMAP_ASSET_STDOUT"
grep -Fq "fiveaxis_remap_assets_from_linuxcnc=1" "$FIVEAXIS_REMAP_ASSET_STDOUT"
MILLTURN_USER_M_BOUNDARY_STDOUT="$BUILD_DIR/linuxcnc_millturn_user_m_boundary_probe.run.stdout.log"
grep -Fq "millturn_ini_open=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "millturn_RS274NGC.USER_M_PATH_ok=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "millturn_RS274NGC.SUBROUTINE_PATH_ok=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "millturn_DISPLAY.PYVCP_ok=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "millturn_HAL.HALUI_ok=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M128_state_mode=mill" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M128_guard_pin=kinstype.is-0" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M128_script_tcl_hal_runtime=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M128_remap_calls_user_m_process=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M428_switchkins_output_pin=motion.analog-out-03" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M428_switchkins_target=0" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M428_work_offset_pocket=P7" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M428_work_offset_words=X-290 Y0 Z-160 A0" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M428_active_g5x=G59.1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M428_calls_M128=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M428_source_transition_from_linuxcnc=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M128_X_AXIS_X.MIN_LIMIT_ok=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M128_X_AXIS_X.MAX_LIMIT_ok=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M128_Z_AXIS_Z.MAX_LIMIT_ok=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M128_source_state_targets_from_linuxcnc=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M129_state_mode=turn" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M129_guard_pin=kinstype.is-1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M129_script_tcl_hal_runtime=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M129_remap_calls_user_m_process=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M429_switchkins_output_pin=motion.analog-out-03" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M429_switchkins_target=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M429_work_offset_pocket=P8" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M429_work_offset_words=X-160 Y0 Z-290 A0" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M429_active_g5x=G59.2" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M429_calls_M129=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M429_source_transition_from_linuxcnc=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M129_X_AXIS_X.MIN_LIMIT_TURN_ok=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M129_Z_AXIS_Z.MAX_LIMIT_TURN_ok=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "M129_source_state_targets_from_linuxcnc=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "millturn_user_m_native_source_state_proof=1" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "millturn_user_m_execution_enabled=0" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
grep -Fq "millturn_user_m_promotion_allowed=0" "$MILLTURN_USER_M_BOUNDARY_STDOUT"
MILLTURN_USER_M_RUNTIME_STDOUT="$BUILD_DIR/linuxcnc_millturn_user_m_runtime_probe.run.stdout.log"
grep -Fq "millturn_user_m_runtime_requirements=" "$MILLTURN_USER_M_RUNTIME_STDOUT"
grep -Fq "millturn_user_m_source_proof_ready=1" "$MILLTURN_USER_M_RUNTIME_STDOUT"
grep -Fq "millturn_user_m_execution_enabled=0" "$MILLTURN_USER_M_RUNTIME_STDOUT"
grep -Fq "millturn_user_m_promotion_allowed=0" "$MILLTURN_USER_M_RUNTIME_STDOUT"
if grep -Fq "millturn_user_m_runtime_ready=1" "$MILLTURN_USER_M_RUNTIME_STDOUT"; then
grep -Eq "millturn_user_m_runtime_probe_status=(ready_disabled_by_default|runtime_state_probe_passed)" \
"$MILLTURN_USER_M_RUNTIME_STDOUT"
if grep -Fq "millturn_user_m_runtime_probe_status=runtime_state_probe_passed" "$MILLTURN_USER_M_RUNTIME_STDOUT"; then
grep -Fq "millturn_user_m_M128_runtime_state_ok=1" "$MILLTURN_USER_M_RUNTIME_STDOUT"
grep -Fq "millturn_user_m_M129_runtime_state_ok=1" "$MILLTURN_USER_M_RUNTIME_STDOUT"
fi
else
grep -Fq "millturn_user_m_runtime_ready=0" "$MILLTURN_USER_M_RUNTIME_STDOUT"
grep -Fq "millturn_user_m_runtime_probe_status=skipped_missing_host_runtime" \
"$MILLTURN_USER_M_RUNTIME_STDOUT"
fi
TOOL_DB_BOUNDARY_STDOUT="$BUILD_DIR/linuxcnc_tool_db_boundary_probe.run.stdout.log"
grep -Fq "db_nonran_ini_open=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "db_nonran_EMCIO.RANDOM_TOOLCHANGER_ok=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "db_nonran_EMCIO.DB_PROGRAM_ok=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "db_nonran_tool_table_ignored_with_db_program=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_task_db_mode_init=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_task_ignores_tool_table_with_db_program=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_task_load_unload_notify=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_child_process_boundary=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_program_executable_check=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_v2_1_handshake=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_getall_g_until_fini=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_notify_l_u_p_protocol=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_program_tooldb_module=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_program_nonran_callbacks=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_program_nonran_state_targets=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_program_reload_rules=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_native_source_protocol_proof=1" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_execution_enabled=0" "$TOOL_DB_BOUNDARY_STDOUT"
grep -Fq "tool_db_promotion_allowed=0" "$TOOL_DB_BOUNDARY_STDOUT"
TOOL_DB_RUNTIME_STDOUT="$BUILD_DIR/linuxcnc_tool_db_runtime_probe.run.stdout.log"
grep -Fq "tool_db_runtime_requirements=" "$TOOL_DB_RUNTIME_STDOUT"
grep -Fq "tool_db_source_proof_ready=1" "$TOOL_DB_RUNTIME_STDOUT"
grep -Fq "tool_db_execution_enabled=0" "$TOOL_DB_RUNTIME_STDOUT"
grep -Fq "tool_db_promotion_allowed=0" "$TOOL_DB_RUNTIME_STDOUT"
if grep -Fq "tool_db_runtime_ready=1" "$TOOL_DB_RUNTIME_STDOUT"; then
grep -Eq "tool_db_runtime_probe_status=(ready_disabled_by_default|runtime_protocol_probe_passed)" \
"$TOOL_DB_RUNTIME_STDOUT"
if grep -Fq "tool_db_runtime_probe_status=runtime_protocol_probe_passed" "$TOOL_DB_RUNTIME_STDOUT"; then
grep -Fq "tool_db_runtime_protocol_probe_ok=1" "$TOOL_DB_RUNTIME_STDOUT"
grep -Fq "tool_db_get_all_fini=1" "$TOOL_DB_RUNTIME_STDOUT"
grep -Fq "tool_db_put_tool_update_state_ok=1" "$TOOL_DB_RUNTIME_STDOUT"
grep -Fq "tool_db_load_spindle_state_ok=1" "$TOOL_DB_RUNTIME_STDOUT"
grep -Fq "tool_db_unload_spindle_state_ok=1" "$TOOL_DB_RUNTIME_STDOUT"
grep -Fq "tool_db_persistence_state_ok=1" "$TOOL_DB_RUNTIME_STDOUT"
fi
else
grep -Fq "tool_db_runtime_ready=0" "$TOOL_DB_RUNTIME_STDOUT"
grep -Fq "tool_db_runtime_probe_status=skipped_missing_host_runtime" \
"$TOOL_DB_RUNTIME_STDOUT"
fi
PYTHON_REMAP_BOUNDARY_STDOUT="$BUILD_DIR/linuxcnc_python_remap_boundary_probe.run.stdout.log"
grep -Fq "python_runtime_pycall_dispatch=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_runtime_remap_phases=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_runtime_generator_finish=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_runtime_callable_lookup=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_runtime_execute_runtime=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_plugin_initializes_python=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_plugin_toplevel_exec_file=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_plugin_ini_python_path=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_plugin_callable_invoke=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_plugin_reload_on_change=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_family_axis_laser_inventory=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_family_twp_nutating_inventory=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_family_axis_remap_cycle_inventory=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_family_gmoccapy_stdglue_inventory=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_remap_native_source_inventory_proof=1" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_remap_execution_enabled=0" "$PYTHON_REMAP_BOUNDARY_STDOUT"
grep -Fq "python_remap_promotion_allowed=0" "$PYTHON_REMAP_BOUNDARY_STDOUT"
PYTHON_REMAP_RUNTIME_STDOUT="$BUILD_DIR/linuxcnc_python_remap_runtime_probe.run.stdout.log"
grep -Fq "python_remap_runtime_fixture_family=axis/remap/stop-lookahead/nc_files" \
"$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_runtime_fixture_id=stop_lookahead_python_runtime_lifecycle" \
"$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_runtime_fixture_scope=no_python_callables_no_ngc_only_subpaths" \
"$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_runtime_requirements=" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_runtime_modules=axis/remap/stop-lookahead/python/remap.py,axis/remap/stop-lookahead/python/toplevel.py" \
"$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_source_proof_ready=1" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_execution_enabled=0" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_promotion_allowed=0" "$PYTHON_REMAP_RUNTIME_STDOUT"
if grep -Fq "python_remap_runtime_ready=1" "$PYTHON_REMAP_RUNTIME_STDOUT"; then
grep -Eq "python_remap_runtime_probe_status=(ready_disabled_by_default|runtime_lifecycle_probe_passed)" \
"$PYTHON_REMAP_RUNTIME_STDOUT"
if grep -Fq "python_remap_runtime_probe_status=runtime_lifecycle_probe_passed" "$PYTHON_REMAP_RUNTIME_STDOUT"; then
grep -Fq "python_remap_runtime_lifecycle_probe_ok=1" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_lifecycle_interpreter_sentinel_ok=1" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_lifecycle_toplevel_imported=1" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_lifecycle_remap_imported=1" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_lifecycle_callable_lookup_ok=1" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_lifecycle_generator_returned=1" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_lifecycle_generator_first_yield=2" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_lifecycle_generator_finish_ok=1" "$PYTHON_REMAP_RUNTIME_STDOUT"
fi
else
grep -Fq "python_remap_runtime_ready=0" "$PYTHON_REMAP_RUNTIME_STDOUT"
grep -Fq "python_remap_runtime_probe_status=skipped_missing_host_runtime" \
"$PYTHON_REMAP_RUNTIME_STDOUT"
fi
REMAP_PARSE_STDOUT="$BUILD_DIR/linuxcnc_remap_parse_harness.run.stdout.log"
check_remap_descriptor() {