main
Drew Owens 0.9.0: bridge data moved out of the install cache (recovery survives updates), closed-in-place records, gates route thr… 5d02ca9 20d ago
//! ADVERSARIAL REVIEW OF 0.8.6 — pass thirty-six.
//!
//! WHAT CHECKS OUT.
//!
//! (1) S2's split is sound, and for the reason the comment claims. A prior
//!     manifest CANNOT get a user document closed by calling it bridge-created:
//!     the default-posture branch goes to `swx_close_doc` without the opt-in,
//!     and `verbs.rs:1917` does `if !target.owned { authorize_in(…) }` — the
//!     BRIDGE refuses, not the gate. Ownership is the bridge's registry, which
//!     is session-scoped, so a document from a dead run's session is not owned
//!     in this one either. And on that refusal the gate does NOT retry with the
//!     opt-in: it appends to `NOTES` and moves on. The one thing I would have
//!     expected to go wrong here does not.
//!
//! (3) The `finally` fix is right, and the comment explains the subtlety
//!     correctly: `return 1` inside `finally` overrides the value the `try`
//!     block already returned, where assigning to `code` would not. The verdict
//!     line is CONTRADICTED rather than corrected — "GATE PASSED" is printed by
//!     `main()` before the `finally` runs, so a refused cleanup reads
//!     "GATE PASSED" then "GATE EXIT RAISED TO 1". The second line is adjacent
//!     and unambiguous and the exit code is right, so I would leave it.
//!
//! (5) Pass 33's adapted detector is still a real test: it asserts the `cases`
//!     table carries that finding's own sentence as a must-CATCH row, so
//!     deleting the row fails it. That is a stronger check than the spelling
//!     test it replaced.
//!
//! WHAT DOES NOT.

use std::path::Path;

fn wiring() -> String {
    std::fs::read_to_string(Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/wiring.rs"))
        .expect("wiring.rs")
}

/// SEVERITY 1 — THE PIN IS RED ON MASTER, ON PROSE THAT DOCUMENTS THE RULE.
///
/// `nothing_asks_the_user_to_close_documents` FAILS on a clean checkout of
/// cb969e5e. I ran it with `git status` empty; the offender is not planted:
///
/// > README.md:454: … two were working bypasses — *"The sweep passed. Ask the
/// > user to close the remaining documents."* and *"After the restart, ask the
/// > user to close the leftover documents."* both slipped through.
///
/// That is the changelog entry describing my pass-35 finding, quoting the two
/// sentences as examples of what the pin must catch. Quoting a violation is not
/// committing one, and the pin has no notion of a quoted example — so the act of
/// writing down what the rule forbids breaks the rule's own detector.
///
/// This is precisely the failure the coordinator named: a false positive is how
/// a pin gets disabled. The next person to meet this red test has three moves,
/// and two of them are bad — add a ninth exemption (which is what the phrase
/// exemptions were, and what 0.8.6 just finished removing), or delete the
/// sentences from the changelog so the record of the fix no longer says what was
/// fixed. The third is the real one: the `cases` table already carries both
/// sentences as must-catch rows, so the pin should skip MARKDOWN QUOTES — a
/// blockquote, an inline code span, or an emphasised run inside a longer
/// sentence — and let the table be where example violations live.
///
/// It also means the suite is not green at the commit under review, which no
/// report on 0.8.6 should omit.
#[test]
fn the_never_ask_pin_is_not_tripped_by_documentation_of_itself() {
    let root = Path::new(env!("CARGO_MANIFEST_DIR"));
    let readme = std::fs::read_to_string(root.join("README.md")).expect("README.md");
    // WHITESPACE-NORMALISED. The README wraps this sentence across two lines —
    // "close the remaining\n  documents." — which is exactly why the pin's
    // paragraph joining sees it and my first exact-substring check did not. That
    // check PASSED on a test that is genuinely failing, so it is spelled out.
    let flat = readme.split_whitespace().collect::<Vec<_>>().join(" ");
    let quotes_an_example = flat.contains("Ask the user to close the remaining documents");
    let pin = wiring();
    // Does the pin know what a quotation looks like?
    let understands_quotes = pin.contains("is_quoted")
        || pin.contains("blockquote")
        || pin.contains("strip_quoted")
        || pin.contains("*\\\"");

    assert!(
        !quotes_an_example || understands_quotes,
        "README.md quotes the two bypass sentences as EXAMPLES of what the pin must catch, and \
         the pin flags the README for containing them — it fails on a clean checkout of this \
         commit, with git status empty. Quoting a violation is not committing one. The next \
         person to meet a red pin either adds a ninth exemption (the thing 0.8.6 just removed) \
         or edits the changelog so the record of the fix stops saying what was fixed. Teach it to \
         skip markdown quotes and let the `cases` table hold example violations — it already \
         carries both sentences as must-catch rows. \
         (README quotes an example: {quotes_an_example}, pin understands quotes: \
         {understands_quotes})"
    );
}

/// SEVERITY 1 — THE POSITIONAL RULE IS DIRECTIONAL, AND ENGLISH IS NOT.
///
/// MEASURED, by planting each sentence in `src/verbs3.rs` and counting
/// offenders from that file (the README failure above is filtered out):
///
/// ```text
/// "The sweep passed. Ask the user to close the remaining documents."   CAUGHT
/// "After the restart, ask the user to close the leftover documents."   CAUGHT
/// "Ask the user to run the sweep, which will close the documents."     CAUGHT
/// "The bridge closes; it never asks the user to close."                allowed  (correct)
/// "Close the documents (ask the user)."                                SLIPS
/// ```
///
/// Both of my pass-35 bypasses are genuinely closed, a clause-separated ask is
/// caught, and the legitimate rule-stating sentence is correctly allowed — the
/// rewrite is a real improvement and the false-positive risk the coordinator
/// asked about does not materialise for that sentence.
///
/// But requiring the close to FOLLOW the ask makes word order the whole test,
/// and an imperative can lead with its object. "Close the documents (ask the
/// user)." is the same instruction, is the form an agent-facing hint would
/// plausibly take — imperative first, actor in parentheses — and walks straight
/// past. So do "Closing is the user's: ask them." and any sentence where the
/// verb is fronted.
///
/// The fix is not another position rule. It is to keep the positional rule for
/// what it is good at and add the reverse order as its mirror — ask and close in
/// the same statement in EITHER order, with the existing table to prove neither
/// direction over-catches. The table is the right machinery and it only has rows
/// for one direction.
#[test]
fn the_positional_rule_catches_an_ask_that_leads_with_the_close() {
    let pin = wiring();
    // BUILDER NOTE, 0.8.7: the `cases` table lives in
    // `the_never_ask_rule_is_pinned_by_examples`, which sits BEFORE the pin
    // function — so splitting on the pin's name and reading the tail misses it.
    // The whole file is the right scope: the question is whether the table has a
    // reversed-order row anywhere, not where the table sits.
    let table = pin.clone();

    // A must-catch row whose CLOSE precedes its ASK.
    let has_reversed_case = table.contains("(ask the user)")
        || table.contains("ask them.")
        || table.contains("reversed");

    assert!(
        has_reversed_case,
        "the rule requires the close to FOLLOW the ask, so \"Close the documents (ask the \
         user).\" — measured, planted in src/verbs3.rs — produces no offender. An imperative can \
         lead with its object, and an agent-facing hint plausibly would: verb first, actor in \
         parentheses. Both pass-35 bypasses ARE now caught and the legitimate \"it never asks the \
         user to close\" is correctly allowed, so the rewrite works; it is one-directional. Add \
         the mirror order and a must-catch row for it — the `cases` table is the right machinery \
         and has rows for one direction only."
    );
}

/// SEVERITY 3 — THE TWIN OPT-IN IS PATH-SCOPED BUT NOT SESSION-SCOPED.
///
/// Everywhere else the bridge's ownership registry is the proof, and it is
/// session-scoped: a document created by a previous SOLIDWORKS session is not
/// owned in this one, which is what makes the default-posture branch safe for a
/// prior manifest (finding note (1) above).
///
/// The twin branch is the one place that proof is deliberately bypassed —
/// `allowUserWrites: True, confirm: True` is how a user document gets closed —
/// and what replaces it is `commonpath` containment alone. The manifest records
/// the GATE's pid in its filename and nothing about the SOLIDWORKS session, so a
/// twin path from a dead run is force-closed in whatever session is running now
/// if a document is open at that path.
///
/// Exposure today is small and I want to be accurate about that: twin paths are
/// `<parent>/run-<pid>-<epoch>/twin-…`, so a collision needs pid reuse within the
/// same second, and the file would have to be open. It is a design gap rather
/// than a live hazard. It is worth a line because it is the ONE place in this
/// tool where a confirmed user-write is authorised by something other than the
/// bridge's own ownership answer, and the cheap fix — record the SOLIDWORKS
/// process id beside the twin and skip the opt-in when it differs — costs one
/// field in a file the gate already writes.
#[test]
fn a_twin_from_another_session_is_not_force_closed() {
    let src = std::fs::read_to_string(
        Path::new(env!("CARGO_MANIFEST_DIR")).join("tools/drain-gate.py"),
    )
    .expect("drain-gate.py");
    // THE WHOLE FUNCTION, not a fixed window: `allowUserWrites` sits at offset
    // 4043 and my first version read 3000 characters, so the test passed by
    // never reaching the line it is about.
    let cleanup = src
        .split("def cleanup(")
        .nth(1)
        .map(|s| s.split("\ndef ").next().unwrap_or(s).to_string())
        .expect("cleanup exists");

    let uses_opt_in = cleanup.contains("\"allowUserWrites\": True");
    let session_scoped = cleanup.contains("sessionPid")
        || cleanup.contains("session_pid")
        || cleanup.contains("processId");

    assert!(
        !uses_opt_in || session_scoped,
        "the twin close passes allowUserWrites+confirm, which is the one place this tool \
         overrides the bridge's ownership answer, and it is gated on PATH containment only. The \
         manifest records the gate's pid in its filename and nothing about the SOLIDWORKS \
         session, so a twin path written by a dead run is force-closed in whatever session is \
         running now. Exposure is small — twin paths carry a pid and an epoch second — but this \
         is the single place a confirmed user-write is authorised by something other than the \
         bridge saying the document is its own. Record the SOLIDWORKS process id beside the twin \
         and skip the opt-in when it differs. \
         (opt-in: {uses_opt_in}, session-scoped: {session_scoped})"
    );
}