fix(agent99): harden Windows99 no-IME transport
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 2s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m29s
CD Pipeline / build-and-deploy (push) Successful in 29m59s
AI 技術雷達監控 / ai-technology-watch (push) Successful in 38s
CD Pipeline / post-deploy-checks (push) Successful in 4m20s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 18s

This commit is contained in:
Your Name
2026-07-17 13:47:59 +08:00
parent 30c2a1807c
commit 402d11fd82
9 changed files with 438 additions and 14 deletions

View File

@@ -16,7 +16,10 @@ if [[ -n "${WINDOWS99_MAX_AUTH_USERS:-}" ]]; then
fi
KNOWN_HOSTS_FILE="${WINDOWS99_KNOWN_HOSTS_FILE:-${HOME:-/home/wooo}/.ssh/known_hosts}"
LOCAL_VERIFY_SCRIPT="${WINDOWS99_LOCAL_VERIFY_SCRIPT:-${SCRIPT_DIR}/windows99-vmware-autostart.ps1}"
REMOTE_VERIFY_COMMAND="${WINDOWS99_REMOTE_VERIFY_COMMAND:-powershell -NoProfile -ExecutionPolicy Bypass -Command \"& ([scriptblock]::Create([Console]::In.ReadToEnd())) -Mode Verify\"}"
REMOTE_VERIFY_COMMAND_OVERRIDE="${WINDOWS99_REMOTE_VERIFY_COMMAND:-}"
REMOTE_VERIFY_COMMAND=""
REMOTE_VERIFY_MODE="encoded_command_bounded_job_base64_line"
REMOTE_TRANSPORT_READY=0
SSH_USERS=(Administrator ogt wooo ooo administrator)
SSH_USERS_EXPLICIT=0
@@ -39,6 +42,7 @@ fi
if ! is_positive_int "${REMOTE_VERIFY_TIMEOUT}"; then
REMOTE_VERIFY_TIMEOUT=45
fi
REMOTE_VERIFY_JOB_TIMEOUT=$((REMOTE_VERIFY_TIMEOUT > 20 ? REMOTE_VERIFY_TIMEOUT - 15 : 5))
if ! is_positive_int "${MAX_AUTH_USERS}"; then
MAX_AUTH_USERS="${#SSH_USERS[@]}"
fi
@@ -111,6 +115,71 @@ if ! is_positive_int "${MAX_AUTH_USERS}"; then
MAX_AUTH_USERS=2
fi
build_bounded_powershell_command() {
local probe_mode="$1"
local timeout_seconds="$2"
local template encoded
template="$(cat <<'POWERSHELL'
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
[Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
$OutputEncoding = [Console]::OutputEncoding
$sourceLine = [Console]::In.ReadLine()
$sourceText = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($sourceLine))
$job = $null
$exitCode = 0
try {
$job = Start-Job -ScriptBlock {
param($probeSource, $probeMode)
$ProgressPreference = 'SilentlyContinue'
[Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
$OutputEncoding = [Console]::OutputEncoding
& ([scriptblock]::Create($probeSource)) -Mode $probeMode
} -ArgumentList $sourceText, '__MODE__'
$completed = Wait-Job -Job $job -Timeout __TIMEOUT__
if ($null -eq $completed) {
[Console]::Error.WriteLine('AGENT99_REMOTE_PROBE_TIMEOUT=1')
$exitCode = 124
} else {
Receive-Job -Job $job -ErrorAction Continue
if ($job.State -ne 'Completed') { $exitCode = 1 }
}
} catch {
[Console]::Error.WriteLine('AGENT99_REMOTE_PROBE_FAILED=1')
$exitCode = 1
} finally {
if ($null -ne $job) {
if ($job.State -eq 'Running') { Stop-Job -Job $job -ErrorAction SilentlyContinue }
Remove-Job -Job $job -Force -ErrorAction SilentlyContinue
}
}
exit $exitCode
POWERSHELL
)"
template="${template//__MODE__/${probe_mode}}"
template="${template//__TIMEOUT__/${timeout_seconds}}"
encoded="$(printf '%s' "${template}" | iconv -f UTF-8 -t UTF-16LE | base64 | tr -d '\r\n')" || return 1
[[ -n "${encoded}" ]] || return 1
printf '%s' "powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${encoded}"
}
encode_probe_source_line() {
base64 <"$1" | tr -d '\r\n'
printf '\n'
}
if [[ "${REMOTE_VERIFY_COMMAND_OVERRIDE}" == *"ReadToEnd"* ]]; then
REMOTE_VERIFY_MODE="unsafe_legacy_override_rejected"
elif [[ -n "${REMOTE_VERIFY_COMMAND_OVERRIDE}" ]]; then
REMOTE_VERIFY_COMMAND="${REMOTE_VERIFY_COMMAND_OVERRIDE}"
REMOTE_VERIFY_MODE="explicit_command_override"
REMOTE_TRANSPORT_READY=1
elif command -v iconv >/dev/null 2>&1 && command -v base64 >/dev/null 2>&1; then
if REMOTE_VERIFY_COMMAND="$(build_bounded_powershell_command Verify "${REMOTE_VERIFY_JOB_TIMEOUT}")"; then
REMOTE_TRANSPORT_READY=1
fi
fi
if [[ "${MODE}" != "check" && "${MODE}" != "collect" ]]; then
printf '%s\n' "error=invalid_mode:${MODE}" >&2
exit 64
@@ -293,6 +362,12 @@ elif [[ "${SSH_BATCHMODE_AUTH_READY}" != "1" ]]; then
if [[ "${MODE}" == "collect" ]]; then
PROCESS_EXIT_STATUS=75
fi
elif [[ "${REMOTE_TRANSPORT_READY}" != "1" ]]; then
VERIFY_COLLECTION_STATUS="blocked_local_transport_encoder_missing"
SAFE_NEXT_STEP="install_or_restore_local_iconv_and_base64_then_rerun_no_secret_no_remote_write"
if [[ "${MODE}" == "collect" ]]; then
PROCESS_EXIT_STATUS=75
fi
elif [[ "${MODE}" == "check" ]]; then
VERIFY_COLLECTION_STATUS="ready_ssh_batchmode_auth_probe_only"
SAFE_NEXT_STEP="rerun_collector_with_collect_then_commit_no_secret_verify_artifact_and_scorecard_rerun"
@@ -304,7 +379,7 @@ elif [[ "${LOCAL_VERIFY_SCRIPT_PRESENT}" != "1" ]]; then
else
DRY_RUN="false"
REMOTE_VERIFY_ATTEMPTED=1
if REMOTE_VERIFY_OUTPUT="$(run_ssh_timed "${SSH_AUTHENTICATED_USER}" "${REMOTE_VERIFY_TIMEOUT}" "${REMOTE_VERIFY_COMMAND}" <"${LOCAL_VERIFY_SCRIPT}" 2>&1)"; then
if REMOTE_VERIFY_OUTPUT="$(encode_probe_source_line "${LOCAL_VERIFY_SCRIPT}" | run_ssh_timed "${SSH_AUTHENTICATED_USER}" "${REMOTE_VERIFY_TIMEOUT}" "${REMOTE_VERIFY_COMMAND}" 2>&1)"; then
REMOTE_VERIFY_OUTPUT="${REMOTE_VERIFY_OUTPUT//$'\r'/}"
REMOTE_VERIFY_EXIT_STATUS=0
if grep -q '^AWOOOI_WINDOWS99_VMWARE_AUTOSTART=1$' <<<"${REMOTE_VERIFY_OUTPUT}" && grep -q '^MODE=Verify$' <<<"${REMOTE_VERIFY_OUTPUT}"; then
@@ -331,6 +406,7 @@ printf '%s\n' "via_host=${VIA_HOST:-none}"
printf '%s\n' "connect_timeout_seconds=${CONNECT_TIMEOUT}"
printf '%s\n' "ssh_timeout_seconds=${SSH_TIMEOUT}"
printf '%s\n' "remote_verify_timeout_seconds=${REMOTE_VERIFY_TIMEOUT}"
printf '%s\n' "remote_verify_job_timeout_seconds=${REMOTE_VERIFY_JOB_TIMEOUT}"
printf '%s\n' "port_timeout_wrapper=${PORT_TIMEOUT_WRAPPER}"
printf '%s\n' "ssh_auth_probe_user_limit=${MAX_AUTH_USERS}"
printf '%s\n' "ssh_timeout_wrapper=${SSH_TIMEOUT_WRAPPER}"
@@ -345,7 +421,8 @@ printf '%s\n' "ssh_batchmode_auth_ready=${SSH_BATCHMODE_AUTH_READY}"
printf '%s\n' "ssh_authenticated_user=${SSH_AUTHENTICATED_USER}"
printf '%s\n' "ssh_auth_probe_exit_status=${SSH_AUTH_PROBE_EXIT_STATUS}"
printf '%s\n' "ssh_auth_probe_stdout_present=${SSH_AUTH_PROBE_STDOUT_PRESENT}"
printf '%s\n' "remote_verify_mode=in_memory_stdin_scriptblock"
printf '%s\n' "remote_verify_mode=${REMOTE_VERIFY_MODE}"
printf '%s\n' "remote_transport_ready=${REMOTE_TRANSPORT_READY}"
printf '%s\n' "local_verify_script_present=${LOCAL_VERIFY_SCRIPT_PRESENT}"
printf '%s\n' "remote_verify_attempted=${REMOTE_VERIFY_ATTEMPTED}"
printf '%s\n' "remote_verify_exit_status=${REMOTE_VERIFY_EXIT_STATUS}"

View File

@@ -17,7 +17,10 @@ if [[ -n "${WINDOWS99_MAX_AUTH_USERS:-}" ]]; then
fi
KNOWN_HOSTS_FILE="${WINDOWS99_KNOWN_HOSTS_FILE:-/tmp/awoooi-windows99-known_hosts}"
LOCAL_LOCATOR_SCRIPT="${WINDOWS99_LOCAL_LOCATOR_SCRIPT:-${SCRIPT_DIR}/windows99-vmx-source-locator.ps1}"
REMOTE_LOCATOR_COMMAND="${WINDOWS99_REMOTE_LOCATOR_COMMAND:-powershell -NoProfile -ExecutionPolicy Bypass -Command \"& ([scriptblock]::Create([Console]::In.ReadToEnd())) -Mode Check\"}"
REMOTE_LOCATOR_COMMAND_OVERRIDE="${WINDOWS99_REMOTE_LOCATOR_COMMAND:-}"
REMOTE_LOCATOR_COMMAND=""
REMOTE_LOCATOR_MODE="encoded_command_bounded_job_base64_line"
REMOTE_TRANSPORT_READY=0
SSH_USERS=(ogt wooo ooo administrator Administrator)
SSH_USERS_EXPLICIT=0
@@ -93,6 +96,7 @@ fi
if ! is_positive_int "${REMOTE_LOCATOR_TIMEOUT}"; then
REMOTE_LOCATOR_TIMEOUT=60
fi
REMOTE_LOCATOR_JOB_TIMEOUT=$((REMOTE_LOCATOR_TIMEOUT > 20 ? REMOTE_LOCATOR_TIMEOUT - 15 : 5))
if ! is_positive_int "${MAX_AUTH_USERS}"; then
MAX_AUTH_USERS="${#SSH_USERS[@]}"
fi
@@ -103,6 +107,71 @@ if ! is_positive_int "${MAX_AUTH_USERS}"; then
MAX_AUTH_USERS=2
fi
build_bounded_powershell_command() {
local probe_mode="$1"
local timeout_seconds="$2"
local template encoded
template="$(cat <<'POWERSHELL'
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
[Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
$OutputEncoding = [Console]::OutputEncoding
$sourceLine = [Console]::In.ReadLine()
$sourceText = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($sourceLine))
$job = $null
$exitCode = 0
try {
$job = Start-Job -ScriptBlock {
param($probeSource, $probeMode)
$ProgressPreference = 'SilentlyContinue'
[Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
$OutputEncoding = [Console]::OutputEncoding
& ([scriptblock]::Create($probeSource)) -Mode $probeMode
} -ArgumentList $sourceText, '__MODE__'
$completed = Wait-Job -Job $job -Timeout __TIMEOUT__
if ($null -eq $completed) {
[Console]::Error.WriteLine('AGENT99_REMOTE_PROBE_TIMEOUT=1')
$exitCode = 124
} else {
Receive-Job -Job $job -ErrorAction Continue
if ($job.State -ne 'Completed') { $exitCode = 1 }
}
} catch {
[Console]::Error.WriteLine('AGENT99_REMOTE_PROBE_FAILED=1')
$exitCode = 1
} finally {
if ($null -ne $job) {
if ($job.State -eq 'Running') { Stop-Job -Job $job -ErrorAction SilentlyContinue }
Remove-Job -Job $job -Force -ErrorAction SilentlyContinue
}
}
exit $exitCode
POWERSHELL
)"
template="${template//__MODE__/${probe_mode}}"
template="${template//__TIMEOUT__/${timeout_seconds}}"
encoded="$(printf '%s' "${template}" | iconv -f UTF-8 -t UTF-16LE | base64 | tr -d '\r\n')" || return 1
[[ -n "${encoded}" ]] || return 1
printf '%s' "powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${encoded}"
}
encode_probe_source_line() {
base64 <"$1" | tr -d '\r\n'
printf '\n'
}
if [[ "${REMOTE_LOCATOR_COMMAND_OVERRIDE}" == *"ReadToEnd"* ]]; then
REMOTE_LOCATOR_MODE="unsafe_legacy_override_rejected"
elif [[ -n "${REMOTE_LOCATOR_COMMAND_OVERRIDE}" ]]; then
REMOTE_LOCATOR_COMMAND="${REMOTE_LOCATOR_COMMAND_OVERRIDE}"
REMOTE_LOCATOR_MODE="explicit_command_override"
REMOTE_TRANSPORT_READY=1
elif command -v iconv >/dev/null 2>&1 && command -v base64 >/dev/null 2>&1; then
if REMOTE_LOCATOR_COMMAND="$(build_bounded_powershell_command Check "${REMOTE_LOCATOR_JOB_TIMEOUT}")"; then
REMOTE_TRANSPORT_READY=1
fi
fi
if [[ "${MODE}" != "check" && "${MODE}" != "collect" ]]; then
printf '%s\n' "error=invalid_mode:${MODE}" >&2
exit 64
@@ -287,6 +356,12 @@ elif [[ "${SSH_BATCHMODE_AUTH_READY}" != "1" ]]; then
if [[ "${MODE}" == "collect" ]]; then
PROCESS_EXIT_STATUS=75
fi
elif [[ "${REMOTE_TRANSPORT_READY}" != "1" ]]; then
LOCATOR_COLLECTION_STATUS="blocked_local_transport_encoder_missing"
SAFE_NEXT_STEP="install_or_restore_local_iconv_and_base64_then_rerun_no_secret_no_remote_write"
if [[ "${MODE}" == "collect" ]]; then
PROCESS_EXIT_STATUS=75
fi
elif [[ "${MODE}" == "check" ]]; then
LOCATOR_COLLECTION_STATUS="ready_ssh_batchmode_auth_probe_only"
SAFE_NEXT_STEP="rerun_locator_with_collect_then_commit_no_secret_locator_artifact_and_scorecard_rerun"
@@ -298,7 +373,7 @@ elif [[ "${LOCAL_LOCATOR_SCRIPT_PRESENT}" != "1" ]]; then
else
DRY_RUN="false"
REMOTE_LOCATOR_ATTEMPTED=1
if REMOTE_LOCATOR_OUTPUT="$(run_ssh_timed "${SSH_AUTHENTICATED_USER}" "${REMOTE_LOCATOR_TIMEOUT}" "${REMOTE_LOCATOR_COMMAND}" <"${LOCAL_LOCATOR_SCRIPT}" 2>&1)"; then
if REMOTE_LOCATOR_OUTPUT="$(encode_probe_source_line "${LOCAL_LOCATOR_SCRIPT}" | run_ssh_timed "${SSH_AUTHENTICATED_USER}" "${REMOTE_LOCATOR_TIMEOUT}" "${REMOTE_LOCATOR_COMMAND}" 2>&1)"; then
REMOTE_LOCATOR_OUTPUT="${REMOTE_LOCATOR_OUTPUT//$'\r'/}"
REMOTE_LOCATOR_EXIT_STATUS=0
if grep -q '^AWOOOI_WINDOWS99_VMX_SOURCE_LOCATOR=1$' <<<"${REMOTE_LOCATOR_OUTPUT}" && grep -q '^MODE=Check$' <<<"${REMOTE_LOCATOR_OUTPUT}"; then
@@ -326,6 +401,7 @@ printf '%s\n' "target_vm_alias=111"
printf '%s\n' "connect_timeout_seconds=${CONNECT_TIMEOUT}"
printf '%s\n' "ssh_timeout_seconds=${SSH_TIMEOUT}"
printf '%s\n' "remote_locator_timeout_seconds=${REMOTE_LOCATOR_TIMEOUT}"
printf '%s\n' "remote_locator_job_timeout_seconds=${REMOTE_LOCATOR_JOB_TIMEOUT}"
printf '%s\n' "port_timeout_wrapper=${PORT_TIMEOUT_WRAPPER}"
printf '%s\n' "ssh_auth_probe_user_limit=${MAX_AUTH_USERS}"
printf '%s\n' "ssh_timeout_wrapper=${SSH_TIMEOUT_WRAPPER}"
@@ -339,7 +415,8 @@ printf '%s\n' "ssh_batchmode_auth_ready=${SSH_BATCHMODE_AUTH_READY}"
printf '%s\n' "ssh_authenticated_user=${SSH_AUTHENTICATED_USER}"
printf '%s\n' "ssh_auth_probe_exit_status=${SSH_AUTH_PROBE_EXIT_STATUS}"
printf '%s\n' "ssh_auth_probe_stdout_present=${SSH_AUTH_PROBE_STDOUT_PRESENT}"
printf '%s\n' "remote_locator_mode=in_memory_stdin_scriptblock"
printf '%s\n' "remote_locator_mode=${REMOTE_LOCATOR_MODE}"
printf '%s\n' "remote_transport_ready=${REMOTE_TRANSPORT_READY}"
printf '%s\n' "local_locator_script_present=${LOCAL_LOCATOR_SCRIPT_PRESENT}"
printf '%s\n' "remote_locator_attempted=${REMOTE_LOCATOR_ATTEMPTED}"
printf '%s\n' "remote_locator_exit_status=${REMOTE_LOCATOR_EXIT_STATUS}"

View File

@@ -54,12 +54,25 @@ def test_collector_contract_forbids_secret_and_runtime_actions() -> None:
assert "StrictHostKeyChecking=accept-new" in text
assert "StrictHostKeyChecking=no" not in text
assert 'REMOTE_VERIFY_TIMEOUT="${WINDOWS99_REMOTE_VERIFY_TIMEOUT:-45}"' in text
assert "REMOTE_VERIFY_TIMEOUT - 15" in text
assert "unsafe_legacy_override_rejected" in text
assert "SSH_USERS=(Administrator ogt wooo ooo administrator)" in text
assert "GSSAPIAuthentication=no" in text
assert "--via-host" in text
assert "via_host=" in text
assert "in_memory_stdin_scriptblock" in text
assert "[Console]::In.ReadToEnd()" in text
assert "encoded_command_bounded_job_base64_line" in text
assert "[Console]::In.ReadLine()" in text
assert "FromBase64String" in text
assert "[Console]::In.ReadToEnd()" not in text
assert "$ProgressPreference = 'SilentlyContinue'" in text
assert "[Text.UTF8Encoding]::new($false)" in text
assert "Start-Job" in text
assert "Wait-Job" in text
assert "Stop-Job" in text
assert "Remove-Job" in text
assert "-NonInteractive" in text
assert "-EncodedCommand" in text
assert 'Command \"& ([scriptblock]::Create([Console]::In.ReadToEnd()))' not in text
assert ".\\\\windows99-vmware-autostart.ps1 -Mode Verify" not in text
for forbidden in [
"sshpass",
@@ -161,6 +174,45 @@ def test_check_mode_probes_all_explicit_users_without_secret_prompt(tmp_path: Pa
assert values["password_prompt_allowed"] == "false"
def test_collect_mode_rejects_legacy_readtoend_override(
tmp_path: Path, monkeypatch
) -> None:
fake_bin = tmp_path / "bin"
fake_bin.mkdir()
_write_executable(
fake_bin / "nc",
"""
#!/usr/bin/env bash
exit 0
""",
)
_write_executable(
fake_bin / "ssh",
"""
#!/usr/bin/env bash
args="$*"
if [[ "$args" == *"powershell"* ]]; then
exit 44
fi
printf '%s\n' 'AWOOOI_WINDOWS99_SSH_READY'
exit 0
""",
)
monkeypatch.setenv(
"WINDOWS99_REMOTE_VERIFY_COMMAND",
"powershell -Command [Console]::In.ReadToEnd()",
)
result = _run_collector(fake_bin, "--collect", "--max-auth-users", "1")
assert result.returncode == 75
values = _key_values(result.stdout)
assert values["remote_verify_mode"] == "unsafe_legacy_override_rejected"
assert values["remote_transport_ready"] == "0"
assert values["remote_verify_attempted"] == "0"
assert values["verify_collection_status"] == "blocked_local_transport_encoder_missing"
def test_check_mode_can_cap_auth_probe_user_count_without_secret_prompt(
tmp_path: Path,
) -> None:
@@ -254,7 +306,9 @@ def test_check_mode_auth_ready_does_not_run_remote_verify(tmp_path: Path) -> Non
assert result.returncode == 0
values = _key_values(result.stdout)
assert values["ssh_batchmode_auth_ready"] == "1"
assert values["remote_verify_mode"] == "in_memory_stdin_scriptblock"
assert values["remote_verify_mode"] == "encoded_command_bounded_job_base64_line"
assert values["remote_transport_ready"] == "1"
assert values["remote_verify_job_timeout_seconds"] == "30"
assert values["local_verify_script_present"] == "1"
assert values["remote_verify_attempted"] == "0"
assert values["verify_collection_status"] == "ready_ssh_batchmode_auth_probe_only"
@@ -296,6 +350,7 @@ def test_collect_mode_runs_readonly_remote_verify_when_auth_ready(tmp_path: Path
assert values["dry_run"] == "false"
assert values["ssh_batchmode_auth_ready"] == "1"
assert values["remote_verify_attempted"] == "1"
assert values["remote_transport_ready"] == "1"
assert values["remote_verify_exit_status"] == "0"
assert values["verify_collection_status"] == "collected_windows99_vmware_verify_stdout"
assert "remote_verify_output_begin" in result.stdout

View File

@@ -52,8 +52,21 @@ def test_locator_contract_forbids_secret_runtime_actions_and_vmx_content_reads()
assert "NumberOfPasswordPrompts=0" in bash_text
assert "--via-host" in bash_text
assert "via_host=" in bash_text
assert "in_memory_stdin_scriptblock" in bash_text
assert "[Console]::In.ReadToEnd()" in bash_text
assert "REMOTE_LOCATOR_TIMEOUT - 15" in bash_text
assert "unsafe_legacy_override_rejected" in bash_text
assert "encoded_command_bounded_job_base64_line" in bash_text
assert "[Console]::In.ReadLine()" in bash_text
assert "FromBase64String" in bash_text
assert "[Console]::In.ReadToEnd()" not in bash_text
assert "$ProgressPreference = 'SilentlyContinue'" in bash_text
assert "[Text.UTF8Encoding]::new($false)" in bash_text
assert "Start-Job" in bash_text
assert "Wait-Job" in bash_text
assert "Stop-Job" in bash_text
assert "Remove-Job" in bash_text
assert "-NonInteractive" in bash_text
assert "-EncodedCommand" in bash_text
assert 'Command \"& ([scriptblock]::Create([Console]::In.ReadToEnd()))' not in bash_text
assert "Get-ChildItem" in ps_text
assert "Test-Path" in ps_text
for text in [bash_text, ps_text]:
@@ -110,6 +123,9 @@ def test_check_mode_reports_auth_probe_without_remote_locator(tmp_path: Path) ->
assert values["target_host_alias"] == "99"
assert values["target_vm_alias"] == "111"
assert values["ssh_batchmode_auth_ready"] == "1"
assert values["remote_locator_mode"] == "encoded_command_bounded_job_base64_line"
assert values["remote_transport_ready"] == "1"
assert values["remote_locator_job_timeout_seconds"] == "45"
assert values["remote_locator_attempted"] == "0"
assert values["locator_collection_status"] == "ready_ssh_batchmode_auth_probe_only"
assert values["secret_value_read"] == "false"