main
Drew Owens 0.11.2 source 784acbf 5d ago
//! ADVERSARIAL REVIEW OF 0.4.3 — round four, and the last.
//!
//! The evidence law is nearly right. `watch_route` now asks whether OUR chain
//! existed before the log was written, and an unattributable route attributes
//! no log at all — which closes the case where the bridge had started nothing.
//!
//! What is left is that the test is NECESSARY and not SUFFICIENT. "Our chain
//! existed before this log was written" is true of every log written after our
//! chain started, including the user's. And the newest log wins the `find`, so
//! a launch the user begins while ours is stalling is preferentially the one we
//! read.
//!
//! Both tests here FAIL on 48a7e2c.

mod common;

use common::{Bridge, TempDir};
use serde_json::{json, Value};
use std::time::{Duration, Instant};
use swx_bridge::launchos::FakeOs;

fn s(v: &Value) -> String {
    serde_json::to_string_pretty(v).unwrap_or_default()
}

struct Sim {
    dir: TempDir,
    lnk: String,
}

impl Sim {
    fn new(tag: &str, routes: Value) -> Sim {
        let dir = TempDir::new(tag);
        std::fs::write(dir.join("routes.json"), routes.to_string()).unwrap();
        std::fs::write(
            dir.join("preexisting.json"),
            json!([{"pid": 6076, "image": "3DEXPERIENCELauncher.exe", "ageSeconds": 30000}])
                .to_string(),
        )
        .unwrap();
        let lnk = format!("{}/SOLIDWORKS Design.lnk", dir.path());
        std::fs::write(&lnk, "not really a shortcut").unwrap();
        Sim { dir, lnk }
    }

    /// The user starts SOLIDWORKS from their Start Menu, mid-flight.
    fn user_starts_solidworks(&self) {
        FakeOs::record_invoke(std::path::Path::new(&self.dir.path()), "userStartMenu", &self.lnk);
    }

    fn boot(&self, extra: &[(&str, &str)]) -> Bridge {
        let mut env: Vec<(&str, &str)> = vec![
            ("SWX_SOLIDWORKS_SHORTCUT", Box::leak(self.lnk.clone().into_boxed_str())),
            ("SWX_LAUNCH_FAKE_DIR", Box::leak(self.dir.path().into_boxed_str())),
            ("SWX_LAUNCH_RUN_BEGIN_SECS", "3"),
            ("SWX_LAUNCH_SLDWORKS_SECS", "6"),
            ("SWX_LAUNCH_ATTACH_SECS", "12"),
            ("SWX_LAUNCH_POLL_MS", "100"),
            ("SWX_LAUNCH_RETRY_SETTLE_MS", "400"),
            ("SWX_LAUNCH_ATTACH_POLL_MS", "150"),
            ("SWX_LAUNCH_BACKOFF_SECS", "0"),
        ];
        env.extend_from_slice(extra);
        Bridge::start_in(TempDir::new("adv4-scratch"), &env)
    }
}

fn wait_for_launch(b: &Bridge, secs: u64) -> Value {
    let deadline = Instant::now() + Duration::from_secs(secs);
    loop {
        let last = b.call("swx_status", json!({}));
        if last["launch"]["finished"] == true || Instant::now() > deadline {
            return last;
        }
        std::thread::sleep(Duration::from_millis(150));
    }
}

/// Our route DOES start a chain — so it is attributed, its root is confirmed,
/// and the round-three gate ("our chain must have existed") is satisfied. It
/// simply never reaches `Run Begin`. The user then starts SOLIDWORKS while we
/// are watching, and THEIR log is the newest one in the directory.
fn ours_stalls_theirs_works(tag: &str) -> (Sim, Bridge, Value) {
    let m = Sim::new(
        tag,
        json!({
            // Ours: a real chain, attributable, confirmed — and it stalls at
            // SecurityContext, exactly as measured on 2026-09-04.
            "shellExecute": {"chain": true},
            "powershell": {"chain": true},
            "explorer": {"chain": true},
            "cmdStart": {"chain": true},
            // Theirs: a Start-Menu launch that works.
            "userStartMenu": {"chain": true, "runBeginAfterMs": 0, "helperAfterMs": 50,
                              "sldworksAfterMs": 100, "attachAfterMs": 600}
        }),
    );
    let b = m.boot(&[]);
    b.call("swx_start", json!({"reason": "modelling a bracket", "waitSeconds": 0}));
    // Long enough for our own root to be confirmed (the first poll is at 100ms),
    // well inside the 3s Run Begin budget.
    std::thread::sleep(Duration::from_millis(600));
    m.user_starts_solidworks();
    let st = wait_for_launch(&b, 30);
    (m, b, st)
}

/// `watch_route`'s test is:
///
/// ```text
/// (Some(root), Some(written)) => root_confirmed && root.created_at <= written
/// ```
///
/// which asks "did our chain exist before this log was written". Every log
/// written after our chain started passes it — the user's included. And
/// `launcher_logs()` returns newest-first while the selection is a `find`, so
/// when a second launch is running the bridge preferentially reads THEIR log.
///
/// Our own route stalls at SecurityContext and its log never contains
/// `Run Begin`. The bridge reports that it saw one.
#[test]
fn a_newer_log_from_a_second_launch_is_not_our_run_begin() {
    let (_m, b, st) = ours_stalls_theirs_works("adv4-newerlog");
    assert!(
        st["launch"]["outcome"] == "attached",
        "precondition: the user's launch worked and the bridge attached: {}",
        s(&st["launch"])
    );
    assert!(
        st["launch"]["attributed"] == true && st["launch"]["rootConfirmed"] == true,
        "precondition: our own route was attributed and its root confirmed: {}",
        s(&st["launch"])
    );
    assert!(
        st["launch"]["runBeginSeen"] != json!(true),
        "our route's own launcher log stops at SecurityContext and never logs 'Run Begin' — the \
         bridge read it from a NEWER log written by a launch the user started while ours was \
         stalling. 'Our chain existed before this log was written' is necessary and not \
         sufficient: it is true of every log written after our chain started.\n{}\n\
         --- server log ---\n{}",
        s(&st["launch"]),
        b.log()
    );
}

/// ...and the consequence is the same one round three found: the
/// `run_begin_seen` guard on the route memory is satisfied by somebody else's
/// evidence, so a route that stalled at SecurityContext is written down as the
/// route that works on this machine and tried first for ever.
#[test]
fn a_route_that_stalled_is_never_remembered_as_the_one_that_works() {
    let (_m, b, st) = ours_stalls_theirs_works("adv4-preferred");
    assert!(
        st["launch"]["outcome"] == "attached",
        "precondition: attached: {}",
        s(&st["launch"])
    );
    assert!(
        st["launch"]["preferredRoute"].is_null(),
        "the bridge learned '{}' as the route that works — a route whose own launcher chain \
         stalled at SecurityContext and was cleaned up. Every future cold start on this machine \
         now begins with it.\n{}\n--- server log ---\n{}",
        st["launch"]["preferredRoute"].as_str().unwrap_or("?"),
        s(&st["launch"]),
        b.log()
    );
}

/// The gate's whole purpose is a PER-ROUTE table: which route reached
/// `Run Begin`, which produced a log, which left something behind. But the log
/// evidence lives only on the ATTEMPT — `launcherLog`, `runBeginSeen` and
/// `unattributedLog` are attempt-level fields, and `runBeginSeen` is reset per
/// route while `unattributedLog` and `rootConfirmed` are not.
///
/// `tools/launch-gate.py::route_table` therefore reads all three from the
/// attempt inside its per-route loop and prints the SAME value on every row —
/// the last route's log attributed to all of them, and "unattributed" against
/// routes that never saw one. A `RouteTry` has to carry its own evidence for
/// the gate's central measurement to mean anything.
#[test]
fn every_route_records_the_log_evidence_that_belongs_to_it() {
    let m = Sim::new(
        "adv4-perroute",
        json!({"shellExecute": {"chain": true}, "powershell": {"chain": true},
               "explorer": {"chain": true}, "cmdStart": {"chain": true}}),
    );
    let b = m.boot(&[("SWX_LAUNCH_RUN_BEGIN_SECS", "1")]);
    b.call("swx_start", json!({"reason": "starting SOLIDWORKS", "waitSeconds": 0}));
    let st = wait_for_launch(&b, 40);

    let tried = st["launch"]["routesTried"].as_array().cloned().unwrap_or_default();
    assert!(!tried.is_empty(), "precondition: at least one route was tried: {}", s(&st["launch"]));
    let first = &tried[0];
    assert!(
        first.get("launcherLog").is_some() && first.get("runBeginSeen").is_some(),
        "routesTried[0] carries no log evidence of its own — only route, stage, cleanup and a \
         note. The gate reads launcherLog/runBeginSeen/unattributedLog from the ATTEMPT for \
         every row, so its per-route table cannot distinguish the route that reached Run Begin \
         from the three that did not.\nroutesTried[0]: {}\n--- server log ---\n{}",
        s(first),
        b.log()
    );
}