main
Drew Owens 0.9.12 source 97dcc9e 19d ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405
//! DREW'S STANDING AUTHORIZATION, 2026-09-11:
//!
//!   "I despise every time you ask for help closing. You MUST find/build a way to
//!    safely close the docs/program."
//!
//! The authorization is to CLOSE. It is not an authorization to LOSE anything,
//! and the difference is the whole of this file. Every test here asserts the same
//! sequence from a different angle:
//!
//!   **nothing closes before it is on disk.**

//
// 0.9.10: the documents these sessions are seeded with were not opened by the
// bridge, so the user-presence guard counts them as the USER's (adversary pass
// 46: the baseline may contain only documents the bridge put there). Every
// sweep below passes `userPresentOverride` + `userAuthorized`, standing in for
// the user's explicit request — which is what these sweeps model.
mod common;

use common::{Bridge, TempDir};
use serde_json::{json, Value};

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

/// A session like the ones that have actually caused trouble: a document the
/// user saved and then edited, two pathless imports SHARING A TITLE (the state
/// that made every verb refuse with `ambiguous_target` live), an assembly, and a
/// component the assembly holds open.
/// A machine whose WINDOW CENSUS CAN BE READ. Without one the sweep correctly
/// preserves everything and closes nothing — a dialog nobody can see is the one
/// that matters — so every test about CLOSING has to supply a session the bridge
/// can look at.
fn a_visible_machine(tag: &str) -> TempDir {
    let d = TempDir::new(tag);
    std::fs::write(d.join("windows.json"), "[]").unwrap();
    d
}

fn a_difficult_session(scratch: &TempDir) {
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({
            "running": true, "untitled": 3, "active": "untitled:a",
            "docs": [
                // The user's own file, WITH unsaved changes. Their file on disk
                // must not be touched; their changes must still survive.
                {"docType": "part", "path": "C:\\Users\\drew\\work\\bracket.SLDPRT",
                 "title": "bracket.SLDPRT", "saved": true, "dirty": true},
                // Two imports, no path, SAME TITLE.
                {"docType": "part", "path": "untitled:a", "title": "First.step.SLDPRT",
                 "saved": false, "dirty": true},
                {"docType": "part", "path": "untitled:b", "title": "First.step.SLDPRT",
                 "saved": false, "dirty": true},
                // An assembly and a component it holds open.
                {"docType": "assembly", "path": "C:\\Users\\drew\\work\\gearbox.SLDASM",
                 "title": "gearbox.SLDASM", "saved": true, "dirty": false},
                {"docType": "part", "path": "C:\\Users\\drew\\work\\shaft.SLDPRT",
                 "title": "shaft.SLDPRT", "saved": true, "dirty": false,
                 "heldOpenByAssembly": true}
            ],
            "files": {}
        })
        .to_string(),
    )
    .unwrap();
}

#[test]
fn every_document_is_on_disk_before_anything_closes() {
    let scratch = TempDir::new("shutdown-safe");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-safe-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));

    let before = b.call("swx_docs", json!({}));
    check!(b, "precondition: a full session", before["count"].as_u64().unwrap_or(0) >= 4, s(&before));

    // DEFAULT POSTURE. No write opt-in, no per-document confirmation: the user
    // has already said this may happen. Only a reason.
    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "the user asked me to close SOLIDWORKS"}));
    check!(b, "the sweep succeeds in the default posture", r["success"] == true, s(&r));
    check!(b, "...and finishes", r["done"] == true, s(&r));

    // THE SAFETY PROPERTY: every document that was closed is on disk.
    let recovered = r["recovered"].as_array().cloned().unwrap_or_default();
    check!(b, "every document was accounted for", recovered.len() >= 4, s(&r));
    for doc in &recovered {
        let preserved = doc["preserved"].as_bool().unwrap_or(false);
        check!(b, "...each one preserved", preserved, s(doc));
        // A document that was dirty or pathless has a NEW file, and that file
        // really exists.
        if doc["wasDirty"] == true || doc["wasPathless"] == true {
            let rp = doc["recoveryPath"].as_str().unwrap_or("");
            check!(
                b,
                "...and a dirty or pathless document was written to recovery",
                !rp.is_empty() && std::path::Path::new(rp).exists(),
                s(doc)
            );
        }
    }

    // THE USER'S OWN FILE WAS NOT WRITTEN OVER: their dirty document went to
    // recovery under a different path.
    let theirs = recovered
        .iter()
        .find(|d| d["title"] == "bracket.SLDPRT")
        .cloned()
        .unwrap_or(json!({}));
    check!(
        b,
        "the user's dirty file was copied to recovery, NOT saved over",
        theirs["recoveryPath"].as_str().unwrap_or("") != "C:\\Users\\drew\\work\\bracket.SLDPRT"
            && theirs["recoveryPath"].as_str().unwrap_or("").contains("recovery"),
        s(&theirs)
    );

    // TWO DOCUMENTS SHARING A TITLE each got their own file.
    let paths: Vec<String> = recovered
        .iter()
        .filter(|d| d["title"] == "First.step.SLDPRT")
        .map(|d| d["recoveryPath"].as_str().unwrap_or("").to_string())
        .collect();
    check!(
        b,
        "same-titled pathless documents each get a UNIQUE recovery file",
        paths.len() == 2 && paths[0] != paths[1] && !paths[0].is_empty(),
        format!("{paths:?}")
    );

    // AND THE COUNT REACHES ZERO — including the component the assembly held.
    let after = b.call("swx_docs", json!({}));
    check!(b, "the session is empty", after["count"] == 0, s(&after));
}

/// A document that could NOT be written is not closed. This is the case the whole
/// design exists to get right: closing it would discard the only copy.
#[test]
fn a_document_that_cannot_be_saved_is_not_closed() {
    let scratch = TempDir::new("shutdown-nosave");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-nosave-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    std::fs::write(b.scratch.join("mock-saveas-fails"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep does NOT report itself done", r["done"] != true, s(&r));
    let remaining = r["remaining"].as_array().cloned().unwrap_or_default();
    check!(b, "...and names what it could not preserve", !remaining.is_empty(), s(&r));
    check!(
        b,
        "...saying why in terms of the harm",
        remaining[0]["why"].as_str().unwrap_or("").contains("NOT closed"),
        s(&remaining[0])
    );
    // The dirty documents are STILL OPEN: unsaved work is never discarded.
    let after = b.call("swx_docs", json!({}));
    check!(b, "the unsaved documents are still open", after["count"].as_u64().unwrap_or(0) > 0, s(&after));
}

/// A dialog stops the sweep and is never answered. A save prompt should be
/// impossible here — everything is clean before anything closes — so one
/// appearing means a premise is wrong.
#[test]
fn a_dialog_stops_the_sweep_and_is_never_answered() {
    let machine = TempDir::new("shutdown-dialog-machine");
    std::fs::write(
        machine.join("dialog-open.json"),
        json!({"hwnd": 9001, "className": "#32770", "title": "Save Modified Documents",
               "visible": true})
            .to_string(),
    )
    .unwrap();
    let scratch = TempDir::new("shutdown-dialog");
    a_difficult_session(&scratch);
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(
        b,
        "the sweep STOPS on a dialog",
        r["success"] == false && r["errorCode"] == "stopped_by_dialog",
        s(&r)
    );
    check!(
        b,
        "...names it",
        s(&r).contains("Save Modified Documents"),
        s(&r)
    );
    check!(
        b,
        "...and says it was not answered",
        r["_hint"].as_str().unwrap_or("").contains("never answers"),
        s(&r)
    );
    // NOTHING was closed.
    let after = b.call("swx_docs", json!({}));
    check!(b, "nothing was closed", after["count"].as_u64().unwrap_or(0) >= 4, s(&after));
}

/// The whole intention in one verb — and the quit happens only because the sweep
/// really emptied the session.
#[test]
fn swx_shutdown_preserves_everything_then_quits() {
    let machine = TempDir::new("shutdown-machine");
    std::fs::write(machine.join("quit-script.json"), r#"{"a":"exited"}"#).unwrap();
    let scratch = TempDir::new("shutdown-full");
    a_difficult_session(&scratch);
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[
            ("SWX_LAUNCH_FAKE_DIR", &machine.path()),
            ("SWX_QUIT_SETTLE_MS", "80"),
            ("SWX_QUIT_EXIT_WAIT_SECS", "3"),
        ],
    );
    b.call("swx_start", json!({}));

    // NO write opt-in and NO launch attribution: the user's authorization is what
    // makes this allowed, and this bridge did not launch the session.
    let r = b.call("swx_shutdown", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "the user asked me to close SOLIDWORKS"}));
    check!(b, "the shutdown succeeds", r["success"] == true, s(&r));
    check!(b, "...having preserved every document", r["recovered"].as_array().map(|a| a.len() >= 4).unwrap_or(false), s(&r));
    check!(b, "...emptied the session", r["done"] == true, s(&r));
    check!(b, "...and quit SOLIDWORKS", r["stopped"] == true, s(&r));

    // IDEMPOTENT: the last thing a caller does should be safe to repeat.
    let again = b.call("swx_shutdown", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "making sure"}));
    check!(
        b,
        "a second shutdown is a no-op, not a failure",
        again["success"] == true && again["alreadyStopped"] == true,
        s(&again)
    );
}

/// What was preserved can be found again — otherwise "nothing is lost" is a claim
/// nobody can act on.
#[test]
fn swx_recover_list_finds_what_was_preserved() {
    let scratch = TempDir::new("shutdown-recover");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-recover-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    let swept = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "precondition: the sweep ran", swept["done"] == true, s(&swept));

    let r = b.call("swx_recover_list", json!({}));
    let sweeps = r["sweeps"].as_array().cloned().unwrap_or_default();
    check!(b, "the sweep is listed", !sweeps.is_empty(), s(&r));
    let files = sweeps[0]["files"].as_array().cloned().unwrap_or_default();
    check!(b, "...with the files it preserved", files.len() >= 3, s(&sweeps[0]));
    check!(
        b,
        "...each really on disk",
        files.iter().all(|f| std::path::Path::new(f["path"].as_str().unwrap_or("")).exists()),
        s(&files[0])
    );
}

/// A DIALOG NOBODY CAN SEE. If the window census cannot be read, this bridge
/// cannot say whether a save prompt is on screen — and the two halves of the
/// sweep answer that differently. Saving loses nothing, so the saves go ahead;
/// closing while blind can lose everything, so nothing closes. The failure mode
/// this pins is the project's oldest: an unanswerable question read as
/// permission.
#[test]
fn an_unreadable_dialog_census_preserves_but_closes_nothing() {
    let scratch = TempDir::new("shutdown-blind");
    a_difficult_session(&scratch);
    // NO fake machine: there is no session this process can look at, so the
    // census is UNKNOWN — not empty.
    let b = Bridge::start_in(TempDir::borrowed(&scratch.0), &[]);
    b.call("swx_start", json!({}));

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(
        b,
        "a census nobody can read stops the closes",
        r["success"] == false && r["errorCode"] == "dialog_census_unknown",
        s(&r)
    );
    check!(b, "...says so in one word", r["stoppedBy"] == "dialogCensusUnknown", s(&r));
    check!(b, "...and does not claim a check it never made", r["dialogCensusReadable"] == false, s(&r));
    check!(b, "...nor that it finished", r["done"] != true, s(&r));

    // THE SAVES WENT AHEAD — and really wrote files.
    let recovered = r["recovered"].as_array().cloned().unwrap_or_default();
    let written: Vec<&Value> = recovered
        .iter()
        .filter(|d| d["preserved"] == true && d["recoveryPath"].is_string())
        .collect();
    check!(b, "the work was preserved anyway", written.len() >= 3, s(&r));
    for d in &written {
        let rp = d["recoveryPath"].as_str().unwrap_or("");
        let bytes = d["recoveryBytes"].as_u64().unwrap_or(0);
        check!(
            b,
            "...each recovery file exists, holds a real document's worth of bytes, \
             and carries the OLE compound-document signature",
            std::path::Path::new(rp).exists()
                && bytes >= 16 * 1024
                && d["recoverySignatureOk"] == true,
            s(d)
        );
    }

    // AND NOTHING WAS CLOSED.
    check!(b, "no document was closed", r["closed"].as_u64().unwrap_or(99) == 0, s(&r));
    let after = b.call("swx_docs", json!({}));
    check!(b, "the session is untouched", after["count"].as_u64().unwrap_or(0) >= 4, s(&after));
}

/// THE USER'S OWN FILE IS NEVER WRITTEN OVER, byte for byte.
///
/// `SaveAs3(path, ver, options=1)` with `swSaveAsOptions_Silent` ALONE — no
/// `Copy` bit — RE-POINTS the document at the new file. That is deliberate: the
/// document must become the recovery file, so the close that follows closes a
/// document whose only content is already on disk. The cost of re-pointing is
/// that the user's original is left exactly as it was, untouched, which is what
/// this test reads back one byte at a time. The journal supplies the other half:
/// the path closed was the RECOVERY path, so the re-point really happened before
/// the close.
#[test]
fn the_users_original_file_is_untouched_and_the_document_re_points() {
    let scratch = TempDir::new("shutdown-original");
    // A REAL FILE ON DISK holding known bytes, so "unchanged" is checkable.
    let theirs = scratch.join("bracket.SLDPRT");
    let original: Vec<u8> = (0u16..2048).map(|i| (i % 251) as u8).collect();
    std::fs::write(&theirs, &original).unwrap();
    let their_path = theirs.to_string_lossy().to_string();
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({
            "running": true, "untitled": 0, "active": their_path,
            "docs": [
                {"docType": "part", "path": their_path, "title": "bracket.SLDPRT",
                 "saved": true, "dirty": true}
            ],
            "files": {}
        })
        .to_string(),
    )
    .unwrap();
    let machine = a_visible_machine("shutdown-original-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep finished", r["success"] == true && r["done"] == true, s(&r));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    let theirs_rec = rec.iter().find(|d| d["title"] == "bracket.SLDPRT").cloned().unwrap_or(json!({}));
    let rp = theirs_rec["recoveryPath"].as_str().unwrap_or("").to_string();
    check!(b, "their document went to a DIFFERENT file", !rp.is_empty() && rp != their_path, s(&theirs_rec));

    // THE ORIGINAL BYTES, unchanged.
    let now = std::fs::read(&theirs).unwrap_or_default();
    check!(
        b,
        "the user's original file is byte-for-byte what it was",
        now == original,
        format!("{} bytes before, {} after", original.len(), now.len())
    );

    // THE RE-POINT: what was closed was the recovery file, not their original.
    let log = std::fs::read_to_string(scratch.join("mock-close-order.log")).unwrap_or_default();
    check!(
        b,
        "the CLOSE key was the recovery path — the document re-pointed",
        log.lines().any(|l| l == format!("closed\t{rp}")),
        log.clone()
    );
    check!(
        b,
        "...and their original path was never closed, because it was never the document any more",
        !log.lines().any(|l| l == format!("closed\t{their_path}")),
        log
    );
}

/// ORDERING, on the case that makes ordering matter: an assembly holding a DIRTY
/// component open. The component cannot close while its parent holds it, and its
/// unsaved changes exist only in memory — so the sweep must write it FIRST and
/// close the parent before the child. This asserts the order of events, not the
/// final state: a session can end with everything on disk and still have closed
/// something before it was written.
#[test]
fn no_component_closes_before_its_own_recovery_write() {
    let scratch = TempDir::new("shutdown-ordering");
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({
            "running": true, "untitled": 0, "active": "C:\\Users\\drew\\work\\rig.SLDASM",
            "docs": [
                // The parent, itself dirty.
                {"docType": "assembly", "path": "C:\\Users\\drew\\work\\rig.SLDASM",
                 "title": "rig.SLDASM", "saved": true, "dirty": true},
                // TWO DIRTY COMPONENTS the assembly holds open. Their changes are
                // in memory only; closing the parent takes them with it.
                {"docType": "part", "path": "C:\\Users\\drew\\work\\arm.SLDPRT",
                 "title": "arm.SLDPRT", "saved": true, "dirty": true,
                 "heldOpenByAssembly": true},
                {"docType": "part", "path": "", "title": "lever.SLDPRT",
                 "saved": false, "dirty": true, "heldOpenByAssembly": true}
            ],
            "files": {}
        })
        .to_string(),
    )
    .unwrap();
    let machine = a_visible_machine("shutdown-ordering-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep finished", r["success"] == true && r["done"] == true, s(&r));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    check!(b, "all three documents were preserved", rec.len() == 3, s(&r));
    for d in &rec {
        check!(
            b,
            "...each with a real document on disk, signature and all",
            d["recoveryBytes"].as_u64().unwrap_or(0) >= 16 * 1024
                && d["recoverySignatureOk"] == true,
            s(d)
        );
    }

    // THE JOURNAL. Every close must come after every write it depended on.
    let log = std::fs::read_to_string(scratch.join("mock-close-order.log")).unwrap_or_default();
    let lines: Vec<(&str, &str)> = log
        .lines()
        .filter_map(|l| l.split_once('\t'))
        .collect();
    let first_close = lines.iter().position(|(e, _)| *e == "closed");
    let last_write = lines.iter().rposition(|(e, _)| *e == "preserved");
    check!(
        b,
        "EVERY recovery write happened before the FIRST close",
        matches!((first_close, last_write), (Some(c), Some(w)) if w < c),
        log.clone()
    );

    // Each component's OWN write precedes its OWN close.
    for d in &rec {
        let rp = d["recoveryPath"].as_str().unwrap_or("").to_string();
        let wrote = lines.iter().position(|(e, p)| *e == "preserved" && *p == rp);
        let closed = lines.iter().position(|(e, p)| *e == "closed" && *p == rp);
        check!(
            b,
            "...and this document was written before it was closed",
            matches!((wrote, closed), (Some(w), Some(c)) if w < c),
            format!("{}\n{log}", s(d))
        );
    }

    // THE PARENT GOES FIRST: a child closed before its parent would have been
    // refused by SOLIDWORKS, which is the reason the order is what it is.
    let closes: Vec<&str> = lines.iter().filter(|(e, _)| *e == "closed").map(|(_, p)| *p).collect();
    let asm = closes.iter().position(|p| p.ends_with(".SLDASM"));
    check!(
        b,
        "the assembly closed before its components",
        asm == Some(0) && closes.len() == 3,
        format!("{closes:?}")
    );
    // AND NO CLOSE WAS EVER REFUSED. This is the assertion that makes the order
    // matter rather than the outcome: closing a child first still finishes, because
    // the sweep retries and the parent goes on the next pass — but SOLIDWORKS had
    // to say no first, and being told no is the thing we are avoiding.
    check!(
        b,
        "no close was attempted that SOLIDWORKS would refuse",
        !log.lines().any(|l| l.starts_with("refused\t")),
        log
    );
    let after = b.call("swx_docs", json!({}));
    check!(b, "the session is empty", after["count"] == 0, s(&after));
}

/// A RECOVERY FILE THAT HOLDS NOTHING IS NOT A SAVE. `Path::exists()` answers yes
/// to the zero-byte file a full disk leaves behind, and "the file is there" was
/// the whole premise for closing the document. So the write is verified by SIZE,
/// through the same constant on both backends, and a short file leaves the
/// document OPEN.
#[test]
fn a_zero_byte_recovery_file_does_not_authorise_a_close() {
    let scratch = TempDir::new("shutdown-partial");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-partial-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    // The disk fills: SaveAs3 "succeeds", the file appears, and it is empty.
    std::fs::write(b.scratch.join("mock-recovery-partial-write"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep does not report itself done", r["done"] != true, s(&r));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    let short: Vec<&Value> = rec.iter().filter(|d| d["preserved"] == false).collect();
    check!(b, "the documents it could not preserve are named", short.len() >= 3, s(&r));
    for d in &short {
        // THE FILE IS THERE. Existence would have said yes.
        let rp = d["recoveryPath"].as_str().unwrap_or("");
        check!(b, "...the empty file really exists", std::path::Path::new(rp).exists(), s(d));
        check!(b, "...and the size is reported, not just a verdict", d["recoveryBytes"] == 0, s(d));
        check!(
            b,
            "...saying why in terms of the harm",
            d["why"].as_str().unwrap_or("").contains("NOT closed"),
            s(d)
        );
    }
    // NOTHING that was only in memory was closed.
    let after = b.call("swx_docs", json!({}));
    check!(
        b,
        "every document whose only copy was in memory is still open",
        after["count"].as_u64().unwrap_or(0) >= 3,
        s(&after)
    );
}

/// A TRUNCATED FILE IS NOT A SAVE — and this is the case the 1 KB floor of 0.7.1
/// admitted. A partial write on a full disk does not usually stop at zero bytes;
/// it writes a genuine header and then stops, at 2 KB or 8 KB or 30 KB. Every one
/// of those passed the old floor, was recorded `preserved:true`, and the document
/// was closed against it.
#[test]
fn a_truncated_recovery_file_does_not_authorise_a_close() {
    let scratch = TempDir::new("shutdown-truncated");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-truncated-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    // A real header, and then the disk fills.
    std::fs::write(b.scratch.join("mock-recovery-truncated"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep does not report itself done", r["done"] != true, s(&r));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    let short: Vec<&Value> = rec.iter().filter(|d| d["preserved"] == false).collect();
    check!(b, "the truncated documents are named", short.len() >= 3, s(&r));
    for d in &short {
        // THE SIGNATURE IS RIGHT. Only the size is wrong — which is exactly why
        // the size check has to survive alongside the structural one.
        check!(b, "...the header was genuine", d["recoverySignatureOk"] == true, s(d));
        let bytes = d["recoveryBytes"].as_u64().unwrap_or(0);
        check!(b, "...the file was NOT empty", bytes > 0 && bytes < 16 * 1024, s(d));
        check!(
            b,
            "...and it says the file was short, in terms of the harm",
            d["why"].as_str().unwrap_or("").contains("NOT closed"),
            s(d)
        );
    }
    let after = b.call("swx_docs", json!({}));
    check!(
        b,
        "every document whose only copy was in memory is still open",
        after["count"].as_u64().unwrap_or(0) >= 3,
        s(&after)
    );
}

/// A FILE THAT IS NOT A SOLIDWORKS DOCUMENT DOES NOT AUTHORISE A CLOSE, whatever
/// its size. SOLIDWORKS documents are OLE compound files: eight bytes at offset 0
/// settle it structurally, where a byte count can only guess. The check FAILS
/// CLOSED, so a future container change would make this bridge refuse to close
/// rather than close against files it cannot vouch for.
#[test]
fn a_recovery_file_with_the_wrong_signature_does_not_authorise_a_close() {
    let scratch = TempDir::new("shutdown-header");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-header-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    // Full size, wrong container.
    std::fs::write(b.scratch.join("mock-recovery-bad-header"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep does not report itself done", r["done"] != true, s(&r));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    let bad: Vec<&Value> = rec.iter().filter(|d| d["preserved"] == false).collect();
    check!(b, "the unrecognised files are named", bad.len() >= 3, s(&r));
    for d in &bad {
        check!(b, "...the signature is reported, not just a verdict", d["recoverySignatureOk"] == false, s(d));
        // SIZE ALONE WOULD HAVE PASSED IT.
        check!(
            b,
            "...and the file was big enough that a byte floor would have said yes",
            d["recoveryBytes"].as_u64().unwrap_or(0) >= 16 * 1024,
            s(d)
        );
        check!(
            b,
            "...saying what it found and what it expected",
            d["why"].as_str().unwrap_or("").contains("D0 CF 11 E0"),
            s(d)
        );
    }
    let after = b.call("swx_docs", json!({}));
    check!(b, "nothing was closed against a file we cannot vouch for",
           after["count"].as_u64().unwrap_or(0) >= 3, s(&after));
}

/// A DIALOG RAISED BY A SAVE STOPS THE CLOSES.
///
/// This is the whole reason the census moved. A save is not a silent operation:
/// it can raise a missing-external-reference or rebuild prompt of its own. 0.7.1
/// censused once per BATCH, so a dialog raised by the first save was invisible
/// until every other document in the batch had already been closed — the sweep
/// carried on working behind a modal window it had itself produced.
#[test]
fn a_dialog_raised_by_a_save_stops_the_closes() {
    let scratch = TempDir::new("shutdown-midsweep");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-midsweep-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    let before = b.call("swx_docs", json!({}));
    let n = before["count"].as_u64().unwrap_or(0);
    check!(b, "precondition: a full session", n >= 4, s(&before));
    // The FIRST save puts a prompt on screen.
    std::fs::write(b.scratch.join("mock-dialog-after-save"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(
        b,
        "the sweep STOPS on a dialog a SAVE raised",
        r["success"] == false && r["errorCode"] == "stopped_by_dialog",
        s(&r)
    );
    check!(b, "...and names it", s(&r).contains("Save external references?"), s(&r));
    check!(b, "...and never answered it", r["_hint"].as_str().unwrap_or("").contains("never answers"), s(&r));

    // THE SWEEP STOPPED SAVING TOO, and this is the half only a per-SAVE census
    // can protect. Exactly one document was written — the one whose save raised
    // the prompt — and the bridge did not go on working behind a modal window it
    // had itself produced. A census that runs once per pass would have saved
    // every document in the pass before looking again.
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    check!(
        b,
        "it stopped at the document whose save raised the dialog",
        rec.len() == 1,
        s(&r)
    );

    // AND NOTHING WAS CLOSED.
    check!(b, "no document was closed", r["closed"].as_u64().unwrap_or(99) == 0, s(&r));
    let after = b.call("swx_docs", json!({}));
    check!(
        b,
        "the session still holds every document it held",
        after["count"].as_u64().unwrap_or(0) == n,
        s(&after)
    );
}

/// AND A DIALOG RAISED BY A CLOSE STOPS THE REST OF THEM. The census runs before
/// EVERY close, not once before the run of them: whatever a close puts on screen
/// is seen before the next one is attempted, and the documents that had not been
/// reached yet are left open with their work already safe on disk.
#[test]
fn a_dialog_raised_by_a_close_stops_the_remaining_closes() {
    let scratch = TempDir::new("shutdown-midclose");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-midclose-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    let before = b.call("swx_docs", json!({}));
    let n = before["count"].as_u64().unwrap_or(0);
    check!(b, "precondition: a full session", n >= 4, s(&before));
    std::fs::write(b.scratch.join("mock-dialog-during-close"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(
        b,
        "the sweep STOPS on a dialog a CLOSE raised",
        r["success"] == false && r["errorCode"] == "stopped_by_dialog",
        s(&r)
    );
    check!(b, "...and names it", s(&r).contains("Rebuild before closing?"), s(&r));

    // EVERYTHING WAS PRESERVED FIRST — the stop costs the user nothing.
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    check!(
        b,
        "every document was preserved before any of this",
        rec.len() >= 4 && rec.iter().all(|d| d["preserved"] == true),
        s(&r)
    );
    // AND THE SWEEP STOPPED PART-WAY, which is the point: it did not run the
    // whole list and look afterwards.
    let closed = r["closed"].as_u64().unwrap_or(0);
    check!(b, "it closed something, but not everything", closed >= 1 && closed < n, s(&r));
    let after = b.call("swx_docs", json!({}));
    check!(
        b,
        "the documents it had not reached are still open",
        after["count"].as_u64().unwrap_or(0) > 0,
        s(&after)
    );
}

/// REAL SOLIDWORKS FILES ARE ACCEPTED. This is the test the 0.7.2 spec needed and
/// did not have.
///
/// Pass 23 asked for the recovery file to be verified against the OLE
/// compound-document signature `D0 CF 11 E0 A1 B1 1A E1` — the answer every
/// reference gives for "what is a SLDPRT". Measured against 166 real
/// `.SLDPRT`/`.SLDASM`/`.SLDDRW` files from three hardware repositories on this
/// machine, **none** of them begins with it, and it does not appear anywhere in
/// the first 4 MB of any of them. All 166 carry `00 00 00 04` at offset 4
/// instead. Shipping the signature as specified would have rejected every
/// document on a modern install: failing closed, so nothing lost — and the sweep
/// would have preserved everything and closed nothing, for ever.
///
/// The headers below are the first bytes of real files, copied verbatim. A check
/// on a format this bridge does not own has to be pinned to samples of the real
/// thing, or the next well-sourced guess ships too.
#[test]
fn the_container_check_accepts_real_solidworks_documents() {
    use swx_bridge::comhost::host::recovery_file_verdict;
    use swx_bridge::disk::DocKind;
    // The KIND is what the backend established, which for these fixtures is the
    // kind the file name states. It is passed in, never read back off the name
    // inside the verdict — that circularity is what 0.7.5 removed.
    let kind_of = |name: &str| DocKind::from_extension(name);
    let dir = TempDir::new("containers");
    // (name, first 16 bytes as they appear on disk, what it is)
    let real: &[(&str, [u8; 16])] = &[
        ("drawing.SLDDRW",
         [0x63,0xf7,0xbf,0x10, 0x00,0x00,0x00,0x04, 0x10,0x75,0x2c,0xc4, 0x74,0xe9,0x14,0x00]),
        ("part.SLDPRT",
         [0x72,0x61,0xbe,0x5c, 0x00,0x00,0x00,0x04, 0x8a,0x8a,0x3f,0xf4, 0x8c,0x14,0x00,0x06]),
        ("part2.SLDPRT",
         [0xb8,0x79,0xb5,0xb6, 0x00,0x00,0x00,0x04, 0x8c,0x0b,0x87,0x9d, 0x6c,0xbd,0xba,0x63]),
        ("assembly.SLDASM",
         [0xbe,0x00,0x56,0x2f, 0x00,0x00,0x00,0x04, 0x10,0x45,0x18,0x78, 0x3f,0xe6,0xef,0x0a]),
        ("assembly2.SLDASM",
         [0x45,0x01,0x95,0xb3, 0x00,0x00,0x00,0x04, 0x89,0x56,0xde,0xec, 0x80,0x79,0xa5,0x4c]),
    ];
    for (name, head) in real {
        let p = dir.join(name);
        let mut body = head.to_vec();
        // EACH KIND AT A PLAUSIBLE SIZE FOR ITS KIND. The floors differ because
        // the real files do.
        body.resize(
            if name.ends_with("SLDASM") {
                128 * 1024
            } else if name.ends_with("SLDDRW") {
                512 * 1024
            } else {
                64 * 1024
            },
            b'x',
        );
        std::fs::write(&p, &body).unwrap();
        let v = recovery_file_verdict(&p.to_string_lossy(), kind_of(name), None);
        assert!(
            v.ok && v.signature_ok && v.container == Some("swdoc"),
            "a REAL SOLIDWORKS file was refused: {name} -> ok={} container={:?} why={:?}\n\
             Every document on a modern install looks like this. A check that rejects it \
             fails closed, which is safe — and leaves the bridge unable to close anything, \
             which is the whole feature.",
            v.ok, v.container, v.why
        );
    }

    // The LEGACY container is still a document: an older file from an archive.
    let old = dir.join("legacy.SLDPRT");
    let mut body = vec![0xD0u8, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];
    body.resize(64 * 1024, b'x');
    std::fs::write(&old, &body).unwrap();
    let v = recovery_file_verdict(&old.to_string_lossy(), Some(DocKind::Part), None);
    assert!(v.ok && v.container == Some("ole-compound"), "legacy compound file refused: {v:?}");

    // AND THE THINGS THAT ARE NOT DOCUMENTS ARE STILL REFUSED — the check has to
    // keep discriminating, not just say yes.
    let junk = dir.join("junk.SLDPRT");
    std::fs::write(&junk, vec![b'x'; 64 * 1024]).unwrap();
    let v = recovery_file_verdict(&junk.to_string_lossy(), Some(DocKind::Part), None);
    assert!(!v.ok && !v.signature_ok, "a file that is not a document was accepted: {v:?}");

    let short = dir.join("short.SLDPRT");
    let mut body = real[0].1.to_vec();
    body.resize(2048, b'x');
    std::fs::write(&short, &body).unwrap();
    let v = recovery_file_verdict(&short.to_string_lossy(), Some(DocKind::Part), None);
    assert!(
        !v.ok && v.signature_ok && v.bytes == 2048,
        "a truncated document was accepted: {v:?}"
    );

    let missing =
        recovery_file_verdict(&dir.join("nothing-here.SLDPRT").to_string_lossy(), Some(DocKind::Part), None);
    assert!(!missing.ok, "a file that does not exist was accepted: {missing:?}");

    // THE FLOOR IS PER KIND, and this is what one floor for all three would have
    // cost: 32 KB is a plausible part and a badly truncated assembly. The
    // smallest real assembly measured here is 95,492 bytes — three times the
    // smallest part — so an assembly that stops at 32 KB has lost most of itself
    // while still carrying the marker and clearing any part-sized floor.
    for (name, ok_expected) in [("thirty-two.SLDPRT", true), ("thirty-two.SLDASM", false)] {
        let p = dir.join(name);
        let mut body = real[1].1.to_vec();
        body.resize(32 * 1024, b'x');
        std::fs::write(&p, &body).unwrap();
        let v = recovery_file_verdict(&p.to_string_lossy(), kind_of(name), None);
        assert_eq!(
            v.ok, ok_expected,
            "a 32 KB {name} was judged ok={} — the floors must differ by kind, or an assembly \
             is closed against a third of itself: {v:?}",
            v.ok
        );
    }
}

/// An older document really can be closed: the legacy container is accepted end
/// to end, not just by the verdict function.
#[test]
fn a_legacy_compound_document_is_preserved_and_closed() {
    let scratch = TempDir::new("shutdown-legacy");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-legacy-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    std::fs::write(b.scratch.join("mock-recovery-legacy-container"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep finished", r["success"] == true && r["done"] == true, s(&r));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    check!(
        b,
        "every document was preserved and vouched for",
        rec.iter().all(|d| d["preserved"] == true),
        s(&r)
    );
    let after = b.call("swx_docs", json!({}));
    check!(b, "the session is empty", after["count"] == 0, s(&after));
}

/// A SWEEP THAT CANNOT FIT DOES NOT START.
///
/// This is the answer to the failure marker-and-floor cannot see: THE RIGHT FILE,
/// CUT SHORT. The container marker is at offset 4, so every prefix of a real
/// document carries it, and a truncation past 16 KB clears the size floor too —
/// a 20 KB prefix of a 500 KB assembly passes both checks and the document is
/// closed against it. Nothing in the file would show it. So the defence is the
/// decision to begin: a truncation this bridge could not detect afterwards is one
/// it declines to cause.
#[test]
fn a_sweep_that_cannot_fit_refuses_to_start() {
    let scratch = TempDir::new("shutdown-nospace");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-nospace-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[
            ("SWX_LAUNCH_FAKE_DIR", &machine.path()),
            // ROOM FOR ONE DOCUMENT, BUT NOT FOR THE SESSION. This is the case
            // only the gate before the sweep can catch: every individual save
            // would pass a per-save check and the sweep would get several
            // documents in before discovering it cannot finish — having already
            // written files it may not be able to complete.
            ("SWX_TEST_FREE_BYTES", "3000000"),
        ],
    );
    b.call("swx_start", json!({}));
    let before = b.call("swx_docs", json!({}));
    let n = before["count"].as_u64().unwrap_or(0);
    check!(b, "precondition: a full session", n >= 4, s(&before));

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(
        b,
        "the sweep refuses to begin",
        r["success"] == false && r["errorCode"] == "insufficient_headroom",
        s(&r)
    );
    check!(b, "...in one word a caller can branch on", r["stoppedBy"] == "insufficientHeadroom", s(&r));
    check!(b, "...and does not claim to have finished", r["done"] != true, s(&r));

    // THE NUMBERS ARE NAMED — free, needed, and the shortfall between them.
    check!(b, "it says how much room there was", r["headroomBytesBefore"] == 3_000_000, s(&r));
    check!(
        b,
        "...and that it refused BEFORE touching anything, not partway through",
        r["stoppedByHeadroom"]["when"] == "before anything was written",
        s(&r)
    );
    check!(
        b,
        "...the session as a whole is what did not fit",
        r["stoppedByHeadroom"]["neededBytes"].as_u64().unwrap_or(0) > 3_000_000,
        s(&r)
    );
    let est = r["estimatedWriteBytes"].as_u64().unwrap_or(0);
    check!(b, "...and what it was about to write", est > 1024, s(&r));
    check!(
        b,
        "...and the shortfall, without making the caller subtract",
        r["stoppedByHeadroom"]["shortfallBytes"].as_u64().unwrap_or(0) > 0,
        s(&r)
    );

    // NOTHING WAS WRITTEN AND NOTHING WAS CLOSED.
    check!(b, "nothing was preserved", r["recovered"].as_array().map(|a| a.is_empty()).unwrap_or(false), s(&r));
    check!(b, "nothing was closed", r["closed"].as_u64().unwrap_or(99) == 0, s(&r));
    let after = b.call("swx_docs", json!({}));
    check!(b, "the session is untouched", after["count"].as_u64().unwrap_or(0) == n, s(&after));
    // AND NO RECOVERY FILE WAS LEFT BEHIND to be mistaken for a rescue.
    let dir = scratch.join("recovery");
    let files: Vec<_> = std::fs::read_dir(&dir)
        .map(|rd| rd.flatten().map(|e| e.path()).collect())
        .unwrap_or_default();
    check!(b, "no half-written rescue was left on disk", files.is_empty(), format!("{files:?}"));
}

/// AND A DISK THAT FILLS MID-SWEEP STOPS IT. The check before the first save is
/// not enough: this sweep is itself one of the things filling the volume, so the
/// question is asked again before EVERY save — the one that would be truncated,
/// not the first of them.
#[test]
fn a_disk_that_fills_mid_sweep_stops_the_sweep() {
    let scratch = TempDir::new("shutdown-filling");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-filling-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[
            ("SWX_LAUNCH_FAKE_DIR", &machine.path()),
            // Room to start, room for the first save, and then the volume fills.
            ("SWX_TEST_FREE_BYTES", "50000000000,50000000000,2048"),
        ],
    );
    b.call("swx_start", json!({}));
    let before = b.call("swx_docs", json!({}));
    let n = before["count"].as_u64().unwrap_or(0);

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(
        b,
        "the sweep stops when the volume fills under it",
        r["success"] == false && r["errorCode"] == "insufficient_headroom",
        s(&r)
    );
    check!(b, "...and does not claim to have finished", r["done"] != true, s(&r));
    check!(
        b,
        "...saying WHEN it stopped, not just that it did",
        r["stoppedByHeadroom"]["when"].as_str().unwrap_or("").contains("after preserving"),
        s(&r)
    );

    // IT GOT SOMEWHERE FIRST, and what it wrote is real and still there.
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    check!(b, "it preserved what it could before stopping", rec.len() >= 1, s(&r));
    for d in &rec {
        if let Some(rp) = d["recoveryPath"].as_str() {
            check!(
                b,
                "...and that work is really on disk",
                std::path::Path::new(rp).exists() && d["recoverySignatureOk"] == true,
                s(d)
            );
        }
    }
    // BUT NOTHING WAS CLOSED: a sweep that cannot finish preserving must not
    // start closing.
    check!(b, "nothing was closed", r["closed"].as_u64().unwrap_or(99) == 0, s(&r));
    let after = b.call("swx_docs", json!({}));
    check!(b, "every document is still open", after["count"].as_u64().unwrap_or(0) == n, s(&after));
}

/// THE NUMBERS ARE ALWAYS REPORTED, including on the happy path. A sweep that
/// writes every open document to disk and never says how much room it had is
/// asking to be trusted about the one thing it cannot verify afterwards.
#[test]
fn a_successful_sweep_still_reports_the_room_it_had() {
    let scratch = TempDir::new("shutdown-headroom-ok");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-headroom-ok-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep finished", r["success"] == true && r["done"] == true, s(&r));
    check!(
        b,
        "it reports the free space it measured on a REAL volume",
        r["headroomBytesBefore"].as_u64().unwrap_or(0) > 0,
        s(&r)
    );
    check!(
        b,
        "...and what it estimated it would write",
        r["estimatedWriteBytes"].as_u64().unwrap_or(0) > 0,
        s(&r)
    );
    check!(
        b,
        "...and how that estimate was arrived at, since most of it is estimated",
        r["estimatedFrom"]["documents"].as_u64().unwrap_or(0) >= 4
            && r["estimatedFrom"]["estimated"].as_u64().unwrap_or(0) >= 1,
        s(&r)
    );
}

/// THE WIRE: the document's real TYPE decides the recovery file's name AND the
/// floor it is verified against.
///
/// This is the chain pass 26 broke open, asserted end to end rather than in
/// pieces. A dirty assembly must be written as `.SLDASM` and held to the
/// assembly floor. Break the type-to-extension map (`Assembly => "SLDPRT"`) and
/// this fails — which is what makes it a test of the WIRE and not of either end.
#[test]
fn an_assemblys_type_decides_both_its_recovery_name_and_its_floor() {
    let scratch = TempDir::new("shutdown-kindwire");
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({
            "running": true, "untitled": 1, "active": "untitled:a",
            "docs": [
                // A DIRTY, PATHLESS ASSEMBLY: nothing but its type says what it
                // is — no path, and a title SOLIDWORKS made up.
                {"docType": "assembly", "path": "untitled:a", "title": "Assem1",
                 "saved": false, "dirty": true}
            ],
            "files": {}
        })
        .to_string(),
    )
    .unwrap();
    let machine = a_visible_machine("shutdown-kindwire-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep finished", r["success"] == true && r["done"] == true, s(&r));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    let d = rec.first().cloned().unwrap_or(json!({}));
    check!(b, "the document was preserved", d["preserved"] == true, s(&r));
    // THE TYPE REACHED THE NAME.
    let rp = d["recoveryPath"].as_str().unwrap_or("").to_string();
    check!(b, "an assembly is written as an assembly", rp.ends_with(".SLDASM"), s(&d));
    // THE TYPE REACHED THE REPORT.
    check!(b, "and the kind it was judged as is published", d["docKind"] == "assembly", s(&d));
    // AND THE ASSEMBLY FLOOR WAS THE ONE APPLIED: the file clears 80 KB, which a
    // part-sized rescue of the same document would not have.
    check!(
        b,
        "an assembly's rescue is at least an assembly's worth of bytes",
        d["recoveryBytes"].as_u64().unwrap_or(0) >= 80 * 1024,
        s(&d)
    );
}

/// A DOCUMENT WHOSE TYPE COULD NOT BE READ IS CLASSIFIED FROM ITS OWN PATH.
///
/// `GetType` is a COM call on a document being closed under memory pressure —
/// the condition this sweep exists for. When it fails, the document's own file
/// path is the strongest evidence in the room: the user's file, named by
/// SOLIDWORKS, on disk. It is NOT the circularity 0.7.5 removed, and the
/// difference is provenance — the path describes the document; the recovery
/// file's name is chosen by this sweep FROM the kind, so reading a kind back out
/// of that can only repeat what was already assumed.
#[test]
fn an_unreadable_type_falls_back_to_the_documents_own_path() {
    let scratch = TempDir::new("shutdown-pathkind");
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({
            "running": true, "untitled": 0, "active": "C:\\Users\\drew\\work\\rig.SLDASM",
            "docs": [
                // A SAVED, DIRTY ASSEMBLY whose TITLE has no extension —
                // Explorer hides known types by default, so this is the common
                // case and not a contrived one. Its path says what it is.
                {"docType": "assembly", "path": "C:\\Users\\drew\\work\\rig.SLDASM",
                 "title": "rig", "saved": true, "dirty": true}
            ],
            "files": {}
        })
        .to_string(),
    )
    .unwrap();
    let machine = a_visible_machine("shutdown-pathkind-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    std::fs::write(b.scratch.join("mock-doctype-unreadable"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    let d = rec.first().cloned().unwrap_or(json!({}));
    check!(b, "the document was preserved", d["preserved"] == true, s(&r));
    check!(
        b,
        "an unreadable type falls back to the document's own path, not to a guess",
        d["docKind"] == "assembly",
        s(&d)
    );
    check!(
        b,
        "...so it is written as an assembly",
        d["recoveryPath"].as_str().unwrap_or("").ends_with(".SLDASM"),
        s(&d)
    );
    check!(
        b,
        "...and held to the assembly floor",
        d["recoveryBytes"].as_u64().unwrap_or(0) >= 80 * 1024,
        s(&d)
    );
}

/// AND WHEN NOTHING ANYWHERE SAYS WHAT IT IS, nothing is INVENTED — even though
/// something has to be written on the file.
///
/// Measured live 2026-09-17: `SaveAs3` to a neutral `.sldrecover` name answers
/// "format not supported" and writes nothing, so the honest name is not a name
/// this install will accept. The file is therefore named as a PART — and the
/// record says `namingFallback: "unknownKindNamedAsPart"`, the kind stays null,
/// and the verification still applies the strictest floor. The name is a label
/// SOLIDWORKS forced; the floor is the check.
#[test]
fn a_document_nothing_can_classify_is_named_as_a_part_but_never_called_one() {
    let scratch = TempDir::new("shutdown-unknownkind");
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({
            "running": true, "untitled": 1, "active": "untitled:a",
            "docs": [
                // No path, and a title with no extension: SOLIDWORKS' own
                // default name for an unsaved assembly.
                {"docType": "assembly", "path": "untitled:a", "title": "Assem1",
                 "saved": false, "dirty": true}
            ],
            "files": {}
        })
        .to_string(),
    )
    .unwrap();
    let machine = a_visible_machine("shutdown-unknownkind-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    std::fs::write(b.scratch.join("mock-doctype-unreadable"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    let d = rec.first().cloned().unwrap_or(json!({}));
    check!(b, "the kind is reported as unknown, not invented", d["docKind"].is_null(), s(&r));
    check!(
        b,
        "...the name is a part only because SOLIDWORKS accepts no other",
        d["recoveryPath"].as_str().unwrap_or("").ends_with(".SLDPRT"),
        s(&d)
    );
    check!(
        b,
        "...and the record says that name was a guess",
        d["namingFallback"] == "unknownKindNamedAsPart",
        s(&d)
    );
    check!(
        b,
        "...and it is held to the strictest floor, not the part floor its name implies",
        d["preserved"] != true || d["recoveryBytes"].as_u64().unwrap_or(0) >= 256 * 1024,
        s(&d)
    );
}

/// AND IF A FUTURE VERSION ACCEPTS THE NEUTRAL NAME, the honest name is used and
/// nothing is recorded as a guess. The path is kept alive and tested rather than
/// deleted, because the measurement that closed it is about THIS install and this
/// version.
#[test]
fn a_neutral_name_is_used_where_solidworks_accepts_one() {
    let scratch = TempDir::new("shutdown-neutralok");
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({
            "running": true, "untitled": 1, "active": "untitled:a",
            "docs": [
                {"docType": "assembly", "path": "untitled:a", "title": "Assem1",
                 "saved": false, "dirty": true}
            ],
            "files": {}
        })
        .to_string(),
    )
    .unwrap();
    let machine = a_visible_machine("shutdown-neutralok-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    std::fs::write(b.scratch.join("mock-doctype-unreadable"), "").unwrap();
    std::fs::write(b.scratch.join("mock-neutral-extension-accepted"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    let d = r["recovered"].as_array().and_then(|a| a.first()).cloned().unwrap_or(json!({}));
    check!(
        b,
        "the honest neutral name is used when it can be",
        d["recoveryPath"].as_str().unwrap_or("").ends_with(".sldrecover"),
        s(&d)
    );
    check!(b, "...and nothing is recorded as a guess", d["namingFallback"].is_null(), s(&d));
    check!(b, "...and the kind is still unknown", d["docKind"].is_null(), s(&d));
}

/// IF SOLIDWORKS WILL NOT WRITE THE NEUTRAL NAME, the document is re-saved as a
/// part and TOLD SO — and the verification does not soften.
///
/// `SaveAs3` dispatches its writer on the extension, and `.sldrecover` matches
/// none. Whether it fails or silently falls back is not something this bridge
/// knows, so it is not assumed: the save is attempted and the failure handled. A
/// guessed NAME is tolerable now in a way it was not before 0.7.5, because
/// nothing downstream reads the kind back out of it — the unknown-kind floor
/// still applies, and the record says `unknownKindNamedAsPart` so nobody reads
/// the `.SLDPRT` as a statement of fact.
#[test]
fn a_refused_neutral_name_falls_back_to_a_part_and_says_so() {
    let scratch = TempDir::new("shutdown-namefallback");
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({
            "running": true, "untitled": 1, "active": "untitled:a",
            "docs": [
                {"docType": "assembly", "path": "untitled:a", "title": "Assem1",
                 "saved": false, "dirty": true}
            ],
            "files": {}
        })
        .to_string(),
    )
    .unwrap();
    let machine = a_visible_machine("shutdown-namefallback-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    std::fs::write(b.scratch.join("mock-doctype-unreadable"), "").unwrap();
    std::fs::write(b.scratch.join("mock-saveas-rejects-unknown-extension"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    let d = rec.first().cloned().unwrap_or(json!({}));
    check!(b, "the document was still preserved", d["preserved"] == true, s(&r));
    check!(
        b,
        "the name fell back to a part",
        d["recoveryPath"].as_str().unwrap_or("").ends_with(".SLDPRT"),
        s(&d)
    );
    check!(
        b,
        "...and says the name is a fallback, not a finding",
        d["namingFallback"] == "unknownKindNamedAsPart",
        s(&d)
    );
    // THE VERIFICATION DID NOT SOFTEN. The kind is still unknown, so the file had
    // to clear the STRICTEST floor — not the 24 KB part floor its name implies.
    check!(b, "the kind is still reported as unknown", d["docKind"].is_null(), s(&d));
    check!(
        b,
        "...and it was held to the strictest floor despite the part name",
        d["recoveryBytes"].as_u64().unwrap_or(0) >= 256 * 1024,
        s(&d)
    );
}

/// EVERY RESCUE CARRIES ITS OWN INSTRUCTION, and the one for a file SOLIDWORKS
/// cannot open is not the one for a file it can.
///
/// A `.sldrecover` file is the rescue of a document that was never saved — the
/// user's only copy — and SOLIDWORKS dispatches on extension, so `swx_open` is
/// the single instruction that cannot work for it. The general hint saying so is
/// not enough: a caller reads the entry, not the preamble, and a list where every
/// file says the same thing tells nobody which one is the problem.
#[test]
fn recover_list_tells_each_file_how_to_be_reopened() {
    let scratch = TempDir::new("shutdown-howtoopen");
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({
            "running": true, "untitled": 1, "active": "untitled:a",
            "docs": [
                // One the bridge can classify, and one nothing can.
                {"docType": "part", "path": "C:\\Users\\drew\\work\\bracket.SLDPRT",
                 "title": "bracket.SLDPRT", "saved": true, "dirty": true},
                {"docType": "assembly", "path": "untitled:a", "title": "Assem1",
                 "saved": false, "dirty": true}
            ],
            "files": {}
        })
        .to_string(),
    )
    .unwrap();
    let machine = a_visible_machine("shutdown-howtoopen-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    std::fs::write(b.scratch.join("mock-doctype-unreadable"), "").unwrap();
    let swept = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "precondition: the sweep preserved both", swept["recovered"].as_array().map(|a| a.len()) == Some(2), s(&swept));

    let r = b.call("swx_recover_list", json!({}));
    let files: Vec<Value> = r["sweeps"]
        .as_array()
        .and_then(|a| a.first())
        .and_then(|s| s["files"].as_array())
        .cloned()
        .unwrap_or_default();
    check!(b, "both rescues are listed", files.len() == 2, s(&r));

    // SELECTED BY WHAT IS KNOWN ABOUT THE DOCUMENT, not by how the file is
    // spelled. Since SOLIDWORKS refuses a neutral extension, an unclassifiable
    // document is WRITTEN as `.SLDPRT` — so a test that picked by extension would
    // have quietly stopped testing anything.
    let unknown = files
        .iter()
        .find(|f| f["kindKnown"] == false)
        .cloned()
        .unwrap_or(json!({}));
    let known = files
        .iter()
        .find(|f| f["kindKnown"] == true)
        .cloned()
        .unwrap_or(json!({}));

    check!(b, "the unclassifiable rescue is marked as such", unknown["kindKnown"] == false, s(&unknown));
    check!(
        b,
        "...and its entry discloses that its NAME was a guess, which no file name can say",
        unknown["namingFallback"] == "unknownKindNamedAsPart",
        s(&unknown)
    );
    let how = unknown["howToOpen"].as_str().unwrap_or("").to_ascii_lowercase();
    check!(b, "...and its OWN entry says to rename it", how.contains("rename"), s(&unknown));
    check!(b, "...saying the extension was a guess, not an observation", how.contains("guess"), s(&unknown));
    check!(
        b,
        "...naming the extensions to try, in order",
        how.contains(".sldprt") && how.contains(".sldasm") && how.contains(".slddrw"),
        s(&unknown)
    );

    // AND THE ORDINARY ONE IS NOT DRESSED UP AS A PROBLEM: a list where every
    // entry warns is a list nobody reads.
    check!(b, "the ordinary rescue is marked openable", known["kindKnown"] == true, s(&known));
    let how_known = known["howToOpen"].as_str().unwrap_or("").to_ascii_lowercase();
    check!(b, "...and simply says to open it", how_known.contains("swx_open") && !how_known.contains("rename"), s(&known));
}

/// A LISTING MUST TELL A RESCUE FROM A HUSK.
///
/// Files land in a sweep directory whether or not the sweep vouched for them: a
/// refused save leaves a husk, a save that returns success can write something
/// that is not a document, and a full disk leaves a truncation. In every one of
/// those the DOCUMENT WAS LEFT OPEN — the work is still in SOLIDWORKS, not in the
/// folder. `swx_recover_list` is the verb the user reads on the worst day, and
/// presenting those leftovers as rescued work is the one lie that matters here.
///
/// The verdict is a pure function of the file, so it is simply re-run per file.
#[test]
fn recover_list_never_calls_an_unverified_file_a_rescue() {
    let scratch = TempDir::new("shutdown-husk");
    let b = Bridge::start_in(TempDir::borrowed(&scratch.0), &[]);
    let root = scratch.join("recovery").join("2026-09-12T00-00-00");
    std::fs::create_dir_all(&root).unwrap();

    // A GENUINE RESCUE: the marker, and a part's worth of bytes.
    let mut good = vec![0x9fu8, 0xe4, 0x18, 0x9f, 0x00, 0x00, 0x00, 0x04];
    good.resize(64 * 1024, b'x');
    std::fs::write(root.join("bracket.SLDPRT"), &good).unwrap();
    // A HUSK: plenty of bytes, no marker. This is why a document is still open.
    std::fs::write(root.join("Assem1.sldrecover"), vec![0x41u8; 900_000]).unwrap();
    // A TRUNCATION: the right marker, a third of a part.
    let mut short = good.clone();
    short.truncate(8 * 1024);
    std::fs::write(root.join("shaft.SLDPRT"), &short).unwrap();

    let r = b.call("swx_recover_list", json!({}));
    let files = r["sweeps"][0]["files"].as_array().cloned().unwrap_or_default();
    check!(b, "everything on disk is still listed", files.len() == 3, s(&r));

    let by = |n: &str| files.iter().find(|f| f["name"] == n).cloned().unwrap_or(json!({}));

    // A FOLDER WITH NO MANIFEST IS AN OLD ONE (or one whose record was lost), and
    // the honest answer about a file that merely LOOKS right is UNKNOWN: this verb
    // cannot see what the original document weighed, nor whether the extension was
    // a guess, and both are what the sweep's own verdict turned on. A weaker check
    // does not produce false negatives — it produces false POSITIVES, and
    // `verified:true` for a file the sweep refused is the error that costs the user.
    let good_f = by("bracket.SLDPRT");
    check!(b, "a re-checked file is not CLAIMED as verified", good_f["verified"].is_null(), s(&good_f));
    check!(b, "...and says where the answer came from", good_f["source"] == "reverified", s(&good_f));
    check!(
        b,
        "...and is offered as unconfirmed rather than as a rescue",
        good_f["howToOpen"].as_str().unwrap_or("").contains("UNCONFIRMED"),
        s(&good_f)
    );

    for name in ["Assem1.sldrecover", "shaft.SLDPRT"] {
        let f = by(name);
        check!(b, "a file the sweep refused is NOT verified", f["verified"] == false, s(&f));
        let how = f["howToOpen"].as_str().unwrap_or("");
        check!(b, "...and is not called a rescue", how.contains("NOT A RESCUE"), s(&f));
        // THE SWEEP'S OWN REASON, not a generic apology.
        check!(
            b,
            "...and carries the reason the sweep gave",
            f["verifiedReason"].as_str().unwrap_or("").len() > 20,
            s(&f)
        );
        // AND IT IS NEVER PRESENTED AS OPENABLE — not by swx_open, and not by
        // renaming, which for a husk would just produce an unopenable .SLDPRT.
        check!(
            b,
            "...and is never offered as something to open",
            !how.contains("swx_open") && !how.to_lowercase().contains("rename"),
            s(&f)
        );
        // WHERE THE WORK IS. Without a manifest this verb cannot state that the
        // sweep left the document open — only that if it is open, the work is
        // there — and it is worded accordingly. The manifest path says it flatly.
        check!(
            b,
            "...and points at SOLIDWORKS as the place the work still is",
            how.contains("still open in SOLIDWORKS"),
            s(&f)
        );
    }

    // THE HEADLINE MUST NOT SAY EVERYTHING HERE IS RESCUED WORK.
    let hint = r["_hint"].as_str().unwrap_or("");
    check!(
        b,
        "the hint warns about unverified files instead of claiming they are documents",
        hint.contains("verified:false") && hint.contains("NOT complete documents"),
        hint.to_string()
    );
}

/// THE SWEEP'S OWN RECORD IS WHAT THE LISTING REPORTS.
///
/// Everything the listing used to re-derive — what the original document weighed,
/// what kind `GetType` reported, whether the extension was a guess — was in hand
/// at save time and thrown away when the process ended. Re-deriving without them
/// is strictly weaker than the verdict it is reproducing, and a weaker check does
/// not produce false negatives; it produces FALSE POSITIVES. `verified:true` for a
/// file the sweep refused, read by the person whose sweep just failed, is the one
/// error here that costs something.
#[test]
fn the_listing_reports_the_sweeps_own_verdicts_from_its_manifest() {
    let scratch = TempDir::new("shutdown-manifest");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-manifest-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    let swept = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "the user asked me to close"}));
    check!(b, "precondition: the sweep ran", swept["done"] == true, s(&swept));

    let r = b.call("swx_recover_list", json!({}));
    let sweep = r["sweeps"].as_array().and_then(|a| a.first()).cloned().unwrap_or(json!({}));
    let dir = sweep["directory"].as_str().unwrap_or("").to_string();
    let files = sweep["files"].as_array().cloned().unwrap_or_default();
    check!(b, "the rescues are listed", !files.is_empty(), s(&r));

    // THE RECORD IS ON DISK, and it is not itself listed as a rescue.
    let manifest_path = std::path::Path::new(&dir).join("manifest.json");
    check!(b, "the sweep wrote its record beside the files", manifest_path.exists(), dir.clone());
    check!(
        b,
        "...and the record is not offered to the user as recovered work",
        !files.iter().any(|f| f["name"] == "manifest.json"),
        s(&sweep)
    );
    let m: Value = serde_json::from_str(&std::fs::read_to_string(&manifest_path).unwrap_or_default())
        .unwrap_or(json!({}));
    check!(
        b,
        "the record carries the sweep's reason and every file it decided about",
        m["reason"].as_str().unwrap_or("").contains("asked me to close")
            && m["files"].as_array().map(|a| !a.is_empty()).unwrap_or(false),
        s(&m)
    );
    // THE FACTS A FILE NAME CANNOT CARRY.
    let entry = m["files"].as_array().and_then(|a| a.first()).cloned().unwrap_or(json!({}));
    for field in ["originalBytes", "kind", "namingFallback", "signatureOk", "closed", "verdictReason"] {
        check!(b, "...including what no listing could re-derive", entry.get(field).is_some(), format!("{field}: {}", s(&entry)));
    }

    // AND THE LISTING ANSWERS FROM IT, saying so.
    for f in &files {
        check!(b, "every entry says where its verdict came from", f["source"] == "manifest", s(f));
        check!(b, "...and carries a real verdict, not an unknown", f["verified"] == true, s(f));
        check!(
            b,
            "...and says whether the document was actually closed",
            f["closed"] == true,
            s(f)
        );
    }
}

/// A SWEEP THAT IS STILL RUNNING HAS ALREADY WRITTEN DOWN WHAT IT DECIDED.
///
/// The record is rewritten after every save and every close, atomically, so a
/// bridge that dies mid-sweep leaves a manifest describing everything decided up
/// to that moment. That is the case that matters most: a sweep interrupted by a
/// crash is exactly the one whose files somebody reads later from a fresh bridge.
#[test]
fn an_interrupted_sweep_still_leaves_a_record_of_what_it_decided() {
    let scratch = TempDir::new("shutdown-partialmanifest");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-partialmanifest-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    // The volume fills after the first save: the sweep stops part-way, exactly as
    // an interruption would leave it.
    std::fs::write(b.scratch.join("mock-dialog-after-save"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "precondition: the sweep stopped part-way", r["done"] != true, s(&r));

    let listed = b.call("swx_recover_list", json!({}));
    let sweep = listed["sweeps"].as_array().and_then(|a| a.first()).cloned().unwrap_or(json!({}));
    let dir = sweep["directory"].as_str().unwrap_or("").to_string();
    check!(
        b,
        "a record exists for the part that ran",
        std::path::Path::new(&dir).join("manifest.json").exists(),
        s(&listed)
    );
    let files = sweep["files"].as_array().cloned().unwrap_or_default();
    check!(b, "and what was written is reported from it", files.iter().all(|f| f["source"] == "manifest"), s(&sweep));
    // NOTHING WAS CLOSED — the sweep stopped — and the record says so, which is
    // the difference between "your work is in this file" and "your work is still
    // in SOLIDWORKS".
    check!(
        b,
        "the record does not claim documents were closed when none were",
        files.iter().all(|f| f["closed"] == false),
        s(&sweep)
    );
    // No temporary file is left lying around pretending to be a rescue.
    check!(
        b,
        "the atomic write leaves no half-written record behind",
        !std::path::Path::new(&dir).join("manifest.json.tmp").exists(),
        dir
    );
}

/// TWO SWEEPS IN THE SAME SECOND DO NOT SHARE A FOLDER — OR A RECORD.
///
/// The sweep folder is named to the second. Two sweeps a fraction apart used to
/// land in the same one, and since the manifest arrived that means sharing the
/// record: the second sweep's `manifest.json` overwrites the first's, so the
/// first sweep's files sit there with nothing describing them — and if the second
/// preserved nothing, its cleanup deleted the first's manifest outright.
///
/// That is a reporting defect with a real victim (the record of why a document
/// was not preserved) and it was also the mechanism behind an intermittent
/// failure in the manifest test, about one run in twelve. It is fixed by giving
/// each sweep its own folder, not by retrying the test.
#[test]
fn two_sweeps_in_the_same_second_keep_separate_records() {
    let scratch = TempDir::new("shutdown-samesecond");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-samesecond-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));

    // FIRST SWEEP: preserves and closes everything.
    let first = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "first sweep"}));
    check!(b, "the first sweep ran", first["done"] == true, s(&first));
    let first_dir = first["recoveryDir"].as_str().unwrap_or("").to_string();
    let first_manifest = std::path::Path::new(&first_dir).join("manifest.json");
    check!(b, "it left a record", first_manifest.exists(), first_dir.clone());
    let first_text = std::fs::read_to_string(&first_manifest).unwrap_or_default();

    // SECOND SWEEP, IMMEDIATELY: the session is empty, so it preserves nothing —
    // the case whose cleanup used to delete somebody else's record.
    let second = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "second sweep"}));
    let second_dir = second["recoveryDir"].as_str().unwrap_or("").to_string();
    check!(
        b,
        "the second sweep got a folder of its own",
        second_dir != first_dir,
        format!("both sweeps used {first_dir}")
    );

    // THE FIRST SWEEP'S RECORD IS UNTOUCHED.
    check!(b, "the first record still exists", first_manifest.exists(), first_dir.clone());
    check!(
        b,
        "...and still says what the first sweep decided",
        std::fs::read_to_string(&first_manifest).unwrap_or_default() == first_text,
        first_dir.clone()
    );
    let m: Value = serde_json::from_str(&first_text).unwrap_or(json!({}));
    check!(b, "...naming its own reason, not the later sweep's", m["reason"] == "first sweep", s(&m));

    // AND THE LISTING STILL DESCRIBES EVERY FILE IT HOLDS.
    let listed = b.call("swx_recover_list", json!({}));
    let sweep = listed["sweeps"]
        .as_array()
        .and_then(|a| a.iter().find(|s| s["directory"] == json!(first_dir.clone())))
        .cloned()
        .unwrap_or(json!({}));
    let files = sweep["files"].as_array().cloned().unwrap_or_default();
    check!(b, "the first sweep's files are listed", !files.is_empty(), s(&listed));
    check!(
        b,
        "...every one of them from its own sweep's record",
        files.iter().all(|f| f["source"] == "manifest"),
        s(&sweep)
    );
}

/// THE RECORD IS WRITTEN ATOMICALLY, and nothing half-written is left behind.
///
/// A manifest is believed by the listing, so a truncated one is worse than none:
/// it would describe some files and silently omit others that are really there.
/// It is written to a temporary path and renamed.
#[test]
fn the_record_is_written_atomically() {
    // The write goes via a temp path — asserted against the source, because the
    // failure it prevents cannot be produced on demand from outside.
    let src = std::fs::read_to_string(
        std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src/verbs3.rs"),
    )
    .expect("verbs3.rs");
    let body = src
        .split("fn write_manifest(")
        .nth(1)
        .and_then(|r| r.split("\nfn ").next())
        .unwrap_or("");
    assert!(
        body.contains("manifest.json.tmp") && body.contains("rename"),
        "write_manifest must write a temporary file and RENAME it. A manifest is believed by \
         swx_recover_list, so a half-written one describes some rescues and silently omits \
         others. Body:\n{body}"
    );

    // And no temporary file survives a completed sweep.
    let scratch = TempDir::new("shutdown-atomic");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-atomic-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    let dir = r["recoveryDir"].as_str().unwrap_or("").to_string();
    check!(
        b,
        "no half-written record is left behind",
        !std::path::Path::new(&dir).join("manifest.json.tmp").exists(),
        dir.clone()
    );
    check!(b, "and the real one is there", std::path::Path::new(&dir).join("manifest.json").exists(), dir);
}

/// A DIALOG IS REPORTED BY WHAT IT SAYS, NOT JUST BY ITS TITLE.
///
/// Live, 2026-09-17: the sweep stopped correctly on
/// `{"kind":"license","title":"License Manager"}` — and that was everything the
/// caller got. Read by hand afterwards, the window said:
///
/// > Failed to check 1 license(s): 3DEXPERIENCE SOLIDWORKS Professional: Unable
/// > to connect to server. The session will end after the next 5 unsuccessful
/// > attempts.
///
/// with a single button: OK. A title cannot distinguish "your licence expired"
/// from "the licence server is unreachable and this session dies in five more
/// tries" — and the second is a countdown somebody needs to see. It appeared when
/// the 3DEXPERIENCE licence heartbeat failed, coinciding with the desktop
/// dropping off the relay, and both the sweep and the quit are blocked while it
/// is up.
///
/// READING IS NOT ANSWERING. Nothing here presses anything, and `neverAnswer`
/// stays true even for a dialog whose only button is OK: whether this bridge may
/// ever press one is a policy question for the user.
#[test]
fn a_blocking_dialog_reports_its_text_and_its_buttons() {
    let machine = TempDir::new("shutdown-licence-machine");
    std::fs::write(
        machine.join("dialog-open.json"),
        json!({
            "hwnd": 9400, "className": "#32770", "title": "License Manager", "visible": true,
            "text": ["Failed to check 1 license(s): 3DEXPERIENCE SOLIDWORKS Professional: \
                      Unable to connect to server. The session will end after the next 5 \
                      unsuccessful attempts."],
            "buttons": ["OK"]
        })
        .to_string(),
    )
    .unwrap();
    let scratch = TempDir::new("shutdown-licence");
    a_difficult_session(&scratch);
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep stops", r["errorCode"] == "stopped_by_dialog", s(&r));
    let d = r["stoppedByDialog"].clone();
    check!(b, "the dialog is classified", d["kind"] == "license", s(&d));
    check!(b, "...its contents were read", d["contentsReadable"] == true, s(&d));
    check!(
        b,
        "...and the caller is told WHAT it says, not just its title",
        d["text"][0].as_str().unwrap_or("").contains("Unable to connect to server")
            && d["text"][0].as_str().unwrap_or("").contains("next 5"),
        s(&d)
    );
    check!(b, "...and WHICH buttons exist", d["buttons"][0] == "OK", s(&d));
    check!(b, "...that the only choice is to acknowledge it", d["acknowledgeOnly"] == true, s(&d));
    // AND IT IS STILL NEVER ANSWERED.
    check!(b, "the bridge will not press it", d["neverAnswer"] == true, s(&d));
    let after = b.call("swx_docs", json!({}));
    check!(b, "nothing was closed behind it", after["count"].as_u64().unwrap_or(0) >= 4, s(&after));

    // A DIALOG THAT ASKS SOMETHING IS NOT ACKNOWLEDGE-ONLY. The distinction has
    // to discriminate, or it is just a field that always says yes — and this one
    // exists to feed a policy decision about what may ever be pressed.
    let machine2 = TempDir::new("shutdown-choice-machine");
    std::fs::write(
        machine2.join("dialog-open.json"),
        json!({
            "hwnd": 9402, "className": "#32770", "title": "Save Modified Documents",
            "visible": true,
            "text": ["Save changes to Part1?"],
            "buttons": ["Save all to This PC", "Don't Save", "Cancel"]
        })
        .to_string(),
    )
    .unwrap();
    let scratch2 = TempDir::new("shutdown-choice");
    a_difficult_session(&scratch2);
    let b2 = Bridge::start_in(
        TempDir::borrowed(&scratch2.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine2.path())],
    );
    b2.call("swx_start", json!({}));
    let r2 = b2.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    let d2 = r2["stoppedByDialog"].clone();
    check!(
        b2,
        "a dialog offering real choices is NOT acknowledge-only",
        d2["acknowledgeOnly"] == false,
        s(&d2)
    );
    check!(
        b2,
        "...and every choice it offers is named, since each does something different to the work",
        d2["buttons"].as_array().map(|a| a.len()) == Some(3),
        s(&d2)
    );
    check!(b2, "...and it is never answered either", d2["neverAnswer"] == true, s(&d2));
}

/// AN UNREADABLE DIALOG IS UNKNOWN, NOT SILENT. The stop still happens; the
/// contents are null and say so.
#[test]
fn a_dialog_whose_controls_cannot_be_read_says_so() {
    let machine = TempDir::new("shutdown-opaque-machine");
    std::fs::write(
        machine.join("dialog-open.json"),
        json!({"hwnd": 9401, "className": "#32770", "title": "License Manager", "visible": true})
            .to_string(),
    )
    .unwrap();
    std::fs::write(machine.join("dialog-contents-unreadable"), "").unwrap();
    let scratch = TempDir::new("shutdown-opaque");
    a_difficult_session(&scratch);
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    let d = r["stoppedByDialog"].clone();
    check!(b, "the sweep still stops", r["errorCode"] == "stopped_by_dialog", s(&r));
    check!(b, "the contents are UNKNOWN, not empty", d["contentsReadable"] == false, s(&d));
    check!(b, "...reported as null rather than as no text", d["text"].is_null(), s(&d));
    check!(b, "...and acknowledgeOnly is not guessed", d["acknowledgeOnly"].is_null(), s(&d));
    check!(b, "...and it is still never answered", d["neverAnswer"] == true, s(&d));
}

/// A DOCUMENT THE SWEEP REFUSED IS RECORDED AS REFUSED — in the manifest, which
/// is the only thing `swx_recover_list` trusts afterwards.
///
/// Every other sweep test preserves everything, so `preserved` is true for every
/// record and `write_manifest`'s `verified` field is true either way. Two
/// mutations survived on that: `verified` hard-coded to true, and
/// `host_failure_entry` dropping `hostError`. Both are the fixes from passes 29
/// and 30 — the manifest being the permanent record of WHY a document was not
/// preserved — and neither had a test that could tell.
///
/// So this sweep refuses one document (the write is truncated, so the bytes are
/// not a document) and asserts the refusal survives into the record and out
/// through the listing.
#[test]
fn a_refused_document_is_recorded_as_refused_in_the_manifest() {
    let scratch = TempDir::new("shutdown-refused-record");
    a_difficult_session(&scratch);
    let machine = a_visible_machine("shutdown-refused-record-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    // A TRUNCATED WRITE: a real header, then the disk stops. The sweep refuses
    // these and leaves the documents open.
    std::fs::write(b.scratch.join("mock-recovery-truncated"), "").unwrap();

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    check!(b, "the sweep did not finish", r["done"] != true, s(&r));
    let rec = r["recovered"].as_array().cloned().unwrap_or_default();
    let refused: Vec<&Value> = rec.iter().filter(|d| d["preserved"] == false).collect();
    check!(b, "at least one document was refused", !refused.is_empty(), s(&r));

    // ── THE MANIFEST CARRIES THE REFUSAL, not a blanket yes.
    let dir = r["recoveryDir"].as_str().unwrap_or("").to_string();
    let m: Value = serde_json::from_str(
        &std::fs::read_to_string(std::path::Path::new(&dir).join("manifest.json"))
            .unwrap_or_default(),
    )
    .unwrap_or(json!({}));
    let entries = m["files"].as_array().cloned().unwrap_or_default();
    check!(b, "the record exists and lists files", !entries.is_empty(), s(&m));
    let any_false = entries.iter().any(|e| e["verified"] == false);
    check!(
        b,
        "a refused document is recorded verified:false — the manifest is what swx_recover_list \
         trusts, so a blanket true would tell the user their only copy is intact",
        any_false,
        s(&m)
    );
    for e in entries.iter().filter(|e| e["verified"] == false) {
        check!(
            b,
            "...with the sweep's own reason for refusing it",
            e["verdictReason"].as_str().map(|r| r.len() > 20).unwrap_or(false),
            s(e)
        );
        check!(b, "...and it was not closed", e["closed"] == false, s(e));
    }

    // ── AND THE LISTING REPORTS IT AS NOT A RESCUE.
    let listed = b.call("swx_recover_list", json!({}));
    let files = listed["sweeps"]
        .as_array()
        .and_then(|a| a.iter().find(|s| s["directory"] == json!(dir.clone())))
        .and_then(|s| s["files"].as_array())
        .cloned()
        .unwrap_or_default();
    let unverified: Vec<&Value> = files.iter().filter(|f| f["verified"] == false).collect();
    check!(b, "the listing carries the refusal through", !unverified.is_empty(), s(&listed));
    // FROM THE MANIFEST, not from a re-check. The reverified path also produces
    // `verified:false` for bytes that are not a document — so without this, a
    // manifest that recorded nothing at all would still satisfy the assertion
    // above, and the guard being pinned here is `write_manifest`'s verdict.
    check!(
        b,
        "...and it came from the sweep's own record, not from re-reading the file",
        unverified.iter().all(|f| f["source"] == "manifest"),
        s(&listed)
    );
    check!(
        b,
        "...and never calls it a rescue",
        unverified.iter().all(|f| f["howToOpen"].as_str().unwrap_or("").contains("NOT A RESCUE")),
        s(&listed)
    );
}

/// A HOST FAILURE INSIDE THE SWEEP KEEPS ITS STRUCTURE — the other mutation that
/// survived. `host_failure_entry` exists because the sweep's records are written
/// into `manifest.json` and KEPT, so a prose-only verdict is the permanent record
/// of why a document was not preserved.
#[test]
fn a_host_failure_during_a_sweep_carries_its_structured_reason() {
    let scratch = TempDir::new("shutdown-hostfail-record");
    a_difficult_session(&scratch);
    // A FAILURE THAT CARRIES REAL COM DETAIL. `mock-com-timeout` produces an
    // error with NO data, and `Value::Null` satisfies `.is_some()` — so a test
    // built on it cannot tell "the host sent nothing" from "nothing constructs
    // the field", which is the mutation that survived.
    std::fs::write(scratch.join("mock-preserve-host-error-with-data"), "").unwrap();
    let machine = a_visible_machine("shutdown-hostfail-record-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );

    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    let failed = r["closeFailed"].as_array().cloned().unwrap_or_default();
    check!(b, "the host failed the sweep", !failed.is_empty(), s(&r));
    let e = failed.first().cloned().unwrap_or(json!({}));
    check!(
        b,
        "the entry says the host errored",
        e["why"].as_str().unwrap_or("").contains("com host errored"),
        s(&e)
    );
    // THE DATA ITSELF, not merely a field that exists. `Value::Null.is_some()` is
    // true, so asserting presence proved nothing.
    check!(
        b,
        "...carrying the COM failure the host actually reported",
        e["hostError"]["hresult"] == "0x80020005" && e["hostError"]["call"] == "SaveAs3",
        s(&e)
    );
    check!(
        b,
        "...and the host's own detail",
        e["detail"].as_str().unwrap_or("").contains("0x80020005"),
        s(&e)
    );

    // AND IT REACHES THE MANIFEST, which is the permanent record of why a
    // document was not preserved — a sweep that dies on the host leaves FEWER
    // files than documents, and this is the only thing that can explain that.
    let dir = r["recoveryDir"].as_str().unwrap_or("").to_string();
    let m: Value = serde_json::from_str(
        &std::fs::read_to_string(std::path::Path::new(&dir).join("manifest.json"))
            .unwrap_or_default(),
    )
    .unwrap_or(json!({}));
    let failures = m["failures"].as_array().cloned().unwrap_or_default();
    check!(b, "the record names the host failure", !failures.is_empty(), s(&m));
    check!(
        b,
        "...with its structured COM detail intact",
        failures.iter().any(|f| f["hostError"]["hresult"] == "0x80020005"),
        s(&m)
    );
}

/// A CLEAN, SAVED DOCUMENT IS CLOSED IN PLACE — AND THE RECORD SAYS SO.
///
/// Measured live 2026-09-30: Drew's saved `R_0603_1608Metric_1.step-1.sldprt`
/// was closed by the sweep with its original untouched (32,311 bytes, same
/// mtime). That is correct — its own file IS its preservation, so the sweep
/// writes no copy — but the record had no entry for it, so `swx_recover_list`
/// could not tell a user "your file was closed at its own path, untouched",
/// which is the most reassuring thing it has to say. "Untouched" is measured,
/// not assumed: the listing compares the file now with what the sweep recorded,
/// and says when something has written to it since, or when it is gone.
#[test]
fn a_clean_document_is_recorded_as_closed_in_place_and_listed_untouched() {
    let scratch = TempDir::new("shutdown-inplace");
    let work = TempDir::new("shutdown-inplace-work");
    let theirs = work.join("R_0603_1608Metric_1.step-1.SLDPRT");
    let mut body = vec![0x9f, 0xe4, 0x18, 0x9f, 0x00, 0x00, 0x00, 0x04];
    body.resize(32_311, b'x');
    std::fs::write(&theirs, &body).unwrap();
    let mtime_before = std::fs::metadata(&theirs).unwrap().modified().unwrap();
    let theirs_s = theirs.to_string_lossy().to_string();
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({
            "running": true, "untitled": 1, "active": "untitled:a",
            "docs": [
                {"docType": "part", "path": "untitled:a", "title": "Part2",
                 "saved": false, "dirty": true},
                {"docType": "part", "path": theirs_s,
                 "title": "R_0603_1608Metric_1.step-1.SLDPRT", "saved": true, "dirty": false}
            ],
            "files": {}
        })
        .to_string(),
    )
    .unwrap();
    let machine = a_visible_machine("shutdown-inplace-machine");
    let b = Bridge::start_in(
        TempDir::borrowed(&scratch.0),
        &[("SWX_LAUNCH_FAKE_DIR", &machine.path())],
    );
    b.call("swx_start", json!({}));
    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "the user asked me to close SOLIDWORKS"}));
    check!(b, "precondition: the sweep ran and emptied the session", r["done"] == true, s(&r));
    check!(
        b,
        "swx_close_all_safely: the user's own file is byte-identical, mtime unchanged",
        std::fs::read(&theirs).ok().as_deref() == Some(&body[..])
            && std::fs::metadata(&theirs).and_then(|m| m.modified()).ok() == Some(mtime_before),
        theirs_s.clone()
    );

    // THE RECORD.
    let dir = std::path::PathBuf::from(r["recoveryDir"].as_str().unwrap_or(""));
    let m: Value = serde_json::from_str(
        &std::fs::read_to_string(dir.join("manifest.json")).unwrap_or_default(),
    )
    .unwrap_or(json!({}));
    let entries = m["files"].as_array().cloned().unwrap_or_default();
    let entry = entries.iter().find(|e| e["originalPath"] == json!(theirs_s)).cloned().unwrap_or(json!({}));
    check!(
        b,
        "swx_close_all_safely: the manifest records the clean document as CLOSED IN PLACE, with no copy",
        entry["closedInPlace"] == true
            && entry["name"].is_null()
            && entry["recoveryPath"].is_null()
            && entry["recoveryBytes"].is_null(),
        s(&m)
    );
    check!(
        b,
        "swx_close_all_safely: ...with its original's size, and the close it was closed by",
        entry["originalBytes"] == 32_311 && entry["originalModifiedMs"].is_u64() && entry["closed"] == true,
        s(&entry)
    );
    check!(
        b,
        "swx_close_all_safely: ...and no claim to have verified bytes it never wrote",
        entry["verified"].is_null() && entry["preserved"] == true,
        s(&entry)
    );
    let copied = entries.iter().find(|e| e["title"] == "Part2").cloned().unwrap_or(json!({}));
    check!(
        b,
        "swx_close_all_safely: the unsaved document is a COPY, not closed in place",
        copied["closedInPlace"] == false && copied["recoveryPath"].is_string() && copied["verified"] == true,
        s(&copied)
    );

    // THE LISTING.
    let find = |l: &Value| -> Value {
        l["sweeps"]
            .as_array()
            .and_then(|a| a.first())
            .and_then(|sw| sw["closedInPlace"].as_array())
            .and_then(|a| a.iter().find(|e| e["originalPath"] == json!(theirs_s)).cloned())
            .unwrap_or(json!({}))
    };
    let l = b.call("swx_recover_list", json!({}));
    let ip = find(&l);
    check!(
        b,
        "swx_recover_list: lists the document as closed at its own path, untouched",
        ip["closed"] == true
            && ip["present"] == true
            && ip["untouched"] == true
            && ip["bytesNow"] == 32_311
            && ip["howToOpen"].as_str().unwrap_or("").contains("CLOSED IN PLACE, UNTOUCHED")
            && ip["howToOpen"].as_str().unwrap_or("").contains(&theirs_s),
        s(&l)
    );
    let files = l["sweeps"][0]["files"].as_array().cloned().unwrap_or_default();
    check!(
        b,
        "swx_recover_list: ...and never as a file in the recovery folder",
        !files.iter().any(|f| f["originalPath"] == json!(theirs_s)) && files.len() == 1,
        s(&l)
    );

    // SOMETHING WRITES IT AFTERWARDS — same length, later mtime.
    let mut rewritten = body.clone();
    rewritten[100] = b'y';
    std::fs::write(&theirs, &rewritten).unwrap();
    std::fs::File::options()
        .write(true)
        .open(&theirs)
        .unwrap()
        .set_modified(mtime_before + std::time::Duration::from_secs(60))
        .unwrap();
    let ip = find(&b.call("swx_recover_list", json!({})));
    check!(
        b,
        "swx_recover_list: a file written since the sweep is NOT called untouched, even at the same size",
        ip["untouched"] == false
            && ip["bytesNow"] == 32_311
            && ip["howToOpen"].as_str().unwrap_or("").contains("CHANGED SINCE"),
        s(&ip)
    );
    // ...and at a different size, it says what the sizes were.
    std::fs::write(&theirs, [&body[..], b"more"].concat()).unwrap();
    let ip = find(&b.call("swx_recover_list", json!({})));
    check!(
        b,
        "swx_recover_list: ...and says what changed",
        ip["untouched"] == false
            && ip["howToOpen"].as_str().unwrap_or("").contains("32311 byte(s) then, 32315 now"),
        s(&ip)
    );
    // AND THEN IT IS GONE.
    std::fs::remove_file(&theirs).unwrap();
    let ip = find(&b.call("swx_recover_list", json!({})));
    check!(
        b,
        "swx_recover_list: a file that is no longer at its path is reported gone, with no copy claimed",
        ip["present"] == false
            && ip["untouched"].is_null()
            && ip["recoveryPath"].is_null()
            && ip["howToOpen"].as_str().unwrap_or("").contains("NOT AT ITS PATH NOW"),
        s(&ip)
    );
}

/// A RECORD WRITTEN BEFORE 0.9.0 has no `closedInPlace` flag, and computed
/// `closed` from the recovery path — which a document closed in place does not
/// have — so it always said false. The listing still finds such a document, and
/// reports its close as UNKNOWN rather than repeating a false that was never
/// evidence. A REFUSED document, which also has no copy, is not one of them.
#[test]
fn a_pre_0_9_record_of_a_clean_document_is_listed_with_its_close_unknown() {
    let scratch = TempDir::new("shutdown-inplace-legacy");
    let work = TempDir::new("shutdown-inplace-legacy-work");
    let theirs = work.join("gearbox.SLDASM");
    std::fs::write(&theirs, vec![b'z'; 5000]).unwrap();
    let refused = work.join("refused.SLDPRT");
    std::fs::write(&refused, vec![b'z'; 4000]).unwrap();
    let dir = scratch.join("recovery").join("20260917-101500");
    std::fs::create_dir_all(&dir).unwrap();
    std::fs::write(
        dir.join("manifest.json"),
        s(&json!({
            "manifestVersion": 1, "sweep": "20260917-101500", "reason": "old sweep",
            "files": [
                {"name": "", "recoveryPath": Value::Null, "title": "gearbox.SLDASM",
                 "originalPath": theirs.to_string_lossy(), "kind": "assembly",
                 "namingFallback": Value::Null, "originalBytes": Value::Null,
                 "recoveryBytes": Value::Null, "signatureOk": Value::Null,
                 "verified": true, "verdictReason": Value::Null, "preserved": true,
                 "closed": false, "wasDirty": false, "wasPathless": false},
                {"name": "", "recoveryPath": Value::Null, "title": "refused.SLDPRT",
                 "originalPath": refused.to_string_lossy(), "kind": "part",
                 "namingFallback": Value::Null, "originalBytes": 4000,
                 "recoveryBytes": 0, "signatureOk": false,
                 "verified": false, "verdictReason": "could not be saved, so it was NOT closed",
                 "preserved": false, "closed": false, "wasDirty": true, "wasPathless": false}
            ]
        })),
    )
    .unwrap();
    let b = Bridge::start_in(TempDir::borrowed(&scratch.0), &[]);
    let l = b.call("swx_recover_list", json!({}));
    let ip = l["sweeps"][0]["closedInPlace"].as_array().cloned().unwrap_or_default();
    check!(
        b,
        "swx_recover_list: finds the clean document an old record describes, and only that one",
        ip.len() == 1 && ip[0]["originalPath"] == json!(theirs.to_string_lossy()),
        s(&l)
    );
    check!(
        b,
        "swx_recover_list: ...with its close UNKNOWN, not the false an old record wrote",
        ip[0]["closed"].is_null()
            && ip[0]["present"] == true
            && ip[0]["untouched"].is_null()
            && ip[0]["howToOpen"].as_str().unwrap_or("").contains("older than 0.9.0"),
        s(&ip[0])
    );
}

/// THE CRATE SESSION, MEASURED 2026-10-02 (pid 26924): 28 parts FIRST in
/// enumeration order, then the top-level assembly and four sub-assemblies. Every
/// part and sub-assembly is held open by the top level, so "still open after
/// CloseDoc" until it closes. 0.9.11's sweep walked the first `batch` documents
/// (parts), every close failed, and the no-progress stop ended it with 33 open.
/// 0.9.12 preserves the whole session first, closes in a GLOBAL order
/// (assemblies, the active one first, before parts), DEFERS what is held behind
/// an open assembly, and counts what went out with its parent as closed.
fn crate_session(tag: &str) -> (Bridge, TempDir, TempDir) {
    crate_session_held(tag, false, "ASM-CRATE.SLDASM")
}

fn crate_session_held(tag: &str, top_level_held: bool, active: &str) -> (Bridge, TempDir, TempDir) {
    let scratch = TempDir::new(tag);
    let root = "C:\\Users\\Public\\adom-crate\\";
    let mut docs: Vec<Value> = (1..=28)
        .map(|i| json!({"docType": "part", "path": format!("{root}PART-{i:02}.SLDPRT"),
                        "title": format!("PART-{i:02}.SLDPRT"), "saved": true, "dirty": false,
                        "heldOpenByAssembly": true}))
        .collect();
    docs.push(json!({"docType": "assembly", "path": format!("{root}ASM-CRATE.SLDASM"),
                     "title": "ASM-CRATE.SLDASM", "saved": true, "dirty": false,
                     "heldOpenByAssembly": top_level_held}));
    for i in 1..=4 {
        docs.push(json!({"docType": "assembly", "path": format!("{root}SUB-{i}.SLDASM"),
                         "title": format!("SUB-{i}.SLDASM"), "saved": true, "dirty": false,
                         "heldOpenByAssembly": true}));
    }
    std::fs::write(
        scratch.join("mock-solidworks-open-docs.json"),
        json!({"running": true, "untitled": 0, "active": format!("{root}{active}"),
               "docs": docs, "files": {}})
        .to_string(),
    )
    .unwrap();
    let machine = a_visible_machine(&format!("{tag}-m"));
    let b = Bridge::start_in(TempDir::borrowed(&scratch.0), &[("SWX_LAUNCH_FAKE_DIR", &machine.path())]);
    b.call("swx_start", json!({}));
    (b, scratch, machine)
}

#[test]
fn an_assembly_session_with_its_parts_listed_first_is_closed_completely() {
    for batch in [None, Some(1u64), Some(4)] {
        let (b, _s, _m) = crate_session(&format!("crate-sweep-{}", batch.map(|n| n.to_string()).unwrap_or("default".into())));
        let mut args = json!({"userPresentOverride": true, "userAuthorized": true, "reason": "Drew: close the crate"});
        if let Some(n) = batch {
            args["batch"] = json!(n);
        }
        let r = b.call("swx_close_all_safely", args);
        let docs = b.call("swx_docs", json!({}));
        check!(
            b,
            &format!("batch {batch:?}: the sweep ends at 0 documents, done, nothing failed"),
            r["done"] == true && docs["count"] == 0 && r["closeFailed"].as_array().map(|a| a.is_empty()).unwrap_or(false),
            s(&r)
        );
        check!(
            b,
            &format!("batch {batch:?}: the components went out with their parent, after their own records"),
            r["closedByParent"].as_array().map(|a| a.len() >= 28).unwrap_or(false)
                && r["recovered"].as_array().map(|a| a.len() == 33).unwrap_or(false),
            s(&r)
        );
    }
}

/// THE USER WAS LOOKING AT A SUB-ASSEMBLY: it is the active document, so it is
/// asked first — and it is held by the top level. That close is DEFERRED, not a
/// failure and not "no progress": the top level closes next, and the session
/// ends at 0, even one close per pass.
#[test]
fn a_held_sub_assembly_asked_first_is_deferred_not_failed() {
    let (b, _s, _m) = crate_session_held("crate-sub-active", false, "SUB-2.SLDASM");
    let r = b.call(
        "swx_close_all_safely",
        json!({"userPresentOverride": true, "userAuthorized": true, "reason": "close", "batch": 1}),
    );
    let docs = b.call("swx_docs", json!({}));
    check!(
        b,
        "the sub-assembly was deferred behind its parent, and the sweep ended at 0 documents",
        r["done"] == true && docs["count"] == 0 && r["closeFailed"].as_array().map(|a| a.is_empty()).unwrap_or(false),
        s(&r)
    );
}

/// A DEFERRED CLOSE IS NOT A FAILURE — but an assembly that genuinely cannot be
/// closed leaves its components deferred, and the sweep ends honestly: no
/// progress, done:false, every held document named.
#[test]
fn components_behind_an_assembly_that_will_not_close_are_reported_not_looped() {
    // The top level refuses to close as well: nothing can release anything.
    let (b, _scratch, _m) = crate_session_held("crate-stuck", true, "ASM-CRATE.SLDASM");
    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "close"}));
    check!(
        b,
        "nothing could close: done false, the stop is honest, and every document is named",
        r["done"] == false && r["closed"] == 0
            && r["closeFailed"].as_array().map(|a| a.len() == 33).unwrap_or(false),
        s(&r)
    );
}

/// swx_progress SHOWS A SWEEP WHILE IT RUNS (0.9.12): its stage and counts —
/// measured 2026-10-02 it answered `{}` while a sweep ran.
#[test]
fn a_running_sweep_is_visible_in_swx_progress() {
    let (b, scratch, _m) = crate_session("crate-progress");
    std::fs::write(scratch.join("mock-preserve-delay-ms"), "40").unwrap();
    let frames = std::thread::scope(|sc| {
        let sweeper = sc.spawn(|| {
            b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "close"}))
        });
        let mut seen = Vec::new();
        for _ in 0..60 {
            std::thread::sleep(std::time::Duration::from_millis(50));
            let p = b.call("swx_progress", json!({}));
            if let Some(f) = p["active"].as_array().and_then(|a| a.iter().find(|f| f["phase"] == "close_all_safely").cloned()) {
                seen.push(f);
            }
            if sweeper.is_finished() {
                break;
            }
        }
        let r = sweeper.join().unwrap();
        assert!(r["done"] == true, "precondition: the sweep finished: {}", s(&r));
        seen
    });
    check!(
        b,
        "swx_progress showed the sweep's stage and counts while it ran",
        frames.iter().any(|f| f["detail"]["stage"] == "preserve" && f["detail"]["preserved"].is_u64()),
        format!("{frames:?}")
    );
}

/// THE LICENSE MANAGER AS MEASURED 2026-10-02 — ownerless, and its body a
/// DirectUIHWND task dialog: the child-control walk reads NO text. 0.9.11 said
/// `text: []` with `contentsReadable: true` — "read, and it says nothing". It is
/// unreadable, says so, still stops the sweep, and is still never answered.
#[test]
fn a_task_dialog_whose_words_cannot_be_read_says_so() {
    let machine = TempDir::new("shutdown-taskdialog-machine");
    std::fs::write(
        machine.join("dialog-open.json"),
        json!({
            "hwnd": 9401, "className": "#32770", "title": "License Manager", "visible": true,
            "controls": [["DirectUIHWND", 0x5600_0000u64, "", true]]
        })
        .to_string(),
    )
    .unwrap();
    let scratch = TempDir::new("shutdown-taskdialog");
    a_difficult_session(&scratch);
    let b = Bridge::start_in(TempDir::borrowed(&scratch.0), &[("SWX_LAUNCH_FAKE_DIR", &machine.path())]);
    b.call("swx_start", json!({}));
    let r = b.call("swx_close_all_safely", json!({"userPresentOverride": true, "userAuthorized": true, "reason": "closing"}));
    let d = r["stoppedByDialog"].clone();
    check!(
        b,
        "the sweep stops on it; contentsReadable is false, the text is null, and the reply says why",
        r["errorCode"] == "stopped_by_dialog"
            && d["contentsReadable"] == false
            && d["text"].is_null()
            && d["contentsUnreadableWhy"].as_str().unwrap_or("").contains("DirectUIHWND")
            && d["neverAnswer"] == true,
        s(&d)
    );
}