wsb 0.253.6349

Workspace tools for every project under $PRJ: git across submodules, template stamping, GitHub, and the workbench
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
//! What the local render looks like, and what it must not be confused with.
//!
//! Every template in here is a VERBATIM copy of one this fleet ships, and
//! every "committed" render beside it is the file that is actually checked in
//! next to that template. The local renders are the same templates with the
//! other branch taken. Nothing is a simplified stand-in: the shapes that can
//! fool this check are the real ones, and a fixture invented to be easy to
//! match would prove nothing about them.

use super::*;

/// The local variable these fixtures' templates declare, as a workspace would
/// in its `.wsb/stamp.json`.
const VARIABLE: &str = "LOCAL_LIBS";

/// `fabricloom/floom-engine/Cargo.toml.wstemplate`, the two-dependency form.
const CARGO_TEMPLATE: &str = r#"[package]
name = "floom-engine"

[dependencies]
anyhow = "1.0"

[dependencies.capdag]
{%- if env.LOCAL_LIBS %}
# LOCAL_LIBS was set when this was rendered: the working copy in this
# workspace rather than a published tag. Re-render without it before
# committing or releasing — a path resolves on this machine only.
path = "{{ projects.capdag_rs.path_from_here }}"
{%- else %}
git = "https://github.com/machinefabric/capdag-rs"
tag = "v{{ projects.capdag_rs.latest_remote_version }}"
{%- endif %}
# Capture-capable host/cartridge: builds the device backends (avdevice).
features = ["capture"]

[dependencies.modelcartridge]
path = "{{ projects.modelcartridge.path_from_here }}"
"#;

const CARGO_COMMITTED: &str = r#"[package]
name = "floom-engine"

[dependencies]
anyhow = "1.0"

[dependencies.capdag]
git = "https://github.com/machinefabric/capdag-rs"
tag = "v1.710.0"
# Capture-capable host/cartridge: builds the device backends (avdevice).
features = ["capture"]

[dependencies.modelcartridge]
path = "../../cartridges/modelcartridge"
"#;

const CARGO_LOCAL: &str = r#"[package]
name = "floom-engine"

[dependencies]
anyhow = "1.0"

[dependencies.capdag]
# LOCAL_LIBS was set when this was rendered: the working copy in this
# workspace rather than a published tag. Re-render without it before
# committing or releasing — a path resolves on this machine only.
path = "../../capdag/capdag-rs"
# Capture-capable host/cartridge: builds the device backends (avdevice).
features = ["capture"]

[dependencies.modelcartridge]
path = "../../cartridges/modelcartridge"
"#;

/// `fabricloom/unifloom/package.json.wstemplate` — the whole conditional
/// inside one line, which is why a branch is not a line.
const NPM_TEMPLATE: &str = r#"{
  "name": "unifloom",
  "dependencies": {
    "capdag": {% if env.LOCAL_LIBS %}"file:{{ projects.capdag_js.path_from_here }}"{% else %}"^{{ projects.capdag_js.latest_remote_version }}"{% endif %},
    "monaco-editor": "^0.55.1"
  }
}
"#;

const NPM_COMMITTED: &str = r#"{
  "name": "unifloom",
  "dependencies": {
    "capdag": "^1.520.4",
    "monaco-editor": "^0.55.1"
  }
}
"#;

const NPM_LOCAL: &str = r#"{
  "name": "unifloom",
  "dependencies": {
    "capdag": "file:../../capdag/capdag-js",
    "monaco-editor": "^0.55.1"
  }
}
"#;

/// `…/hosts/go-relay/go.mod.wstemplate` — two conditionals, one of them
/// without an else, and a local branch that is not a path at all.
const GO_TEMPLATE: &str = r#"module github.com/machinefabric/capdag-interop-relay-host-go

go 1.21

require github.com/machinefabric/capdag-go v{% if env.LOCAL_LIBS %}0.0.0{% else %}{{ projects.capdag_go.latest_remote_version }}{% endif %}

require (
	github.com/google/uuid v1.6.0 // indirect
)
{%- if env.LOCAL_LIBS %}

// LOCAL_LIBS: the working copy in this workspace rather than a published
// tag. The require above carries the v0.0.0 placeholder a replaced module
// takes. Re-render without it before committing or releasing.
replace github.com/machinefabric/capdag-go => {{ projects.capdag_go.path_from_here }}
{%- endif %}
"#;

const GO_COMMITTED: &str = r#"module github.com/machinefabric/capdag-interop-relay-host-go

go 1.21

require github.com/machinefabric/capdag-go v1.386.0

require (
	github.com/google/uuid v1.6.0 // indirect
)
"#;

const GO_LOCAL: &str = r#"module github.com/machinefabric/capdag-interop-relay-host-go

go 1.21

require github.com/machinefabric/capdag-go v0.0.0

require (
	github.com/google/uuid v1.6.0 // indirect
)

// LOCAL_LIBS: the working copy in this workspace rather than a published
// tag. The require above carries the v0.0.0 placeholder a replaced module
// takes. Re-render without it before committing or releasing.
replace github.com/machinefabric/capdag-go => ../../../../../../capdag/capdag-go
"#;

/// `cartridges/mlxcartridge/Package.swift.wstemplate`.
const SWIFT_TEMPLATE: &str = r#"// swift-tools-version:5.9
import PackageDescription

let package = Package(
    name: "mlxcartridge",
    dependencies: [
        {%- if env.LOCAL_LIBS %}
        // LOCAL_LIBS: the working copy in this workspace rather than a
        // published tag. Re-render without it before committing or releasing.
        .package(path: "{{ projects.capdag_objc.path_from_here }}"),
        {%- else %}
        .package(url: "https://github.com/machinefabric/capdag-objc", exact: "{{ projects.capdag_objc.latest_remote_version }}"),
        {%- endif %}
        .package(path: "../shared-swift"),
    ]
)
"#;

const SWIFT_COMMITTED: &str = r#"// swift-tools-version:5.9
import PackageDescription

let package = Package(
    name: "mlxcartridge",
    dependencies: [
        .package(url: "https://github.com/machinefabric/capdag-objc", exact: "1.710.0"),
        .package(path: "../shared-swift"),
    ]
)
"#;

const SWIFT_LOCAL: &str = r#"// swift-tools-version:5.9
import PackageDescription

let package = Package(
    name: "mlxcartridge",
    dependencies: [
        // LOCAL_LIBS: the working copy in this workspace rather than a
        // published tag. Re-render without it before committing or releasing.
        .package(path: "../../capdag/capdag-objc"),
        .package(path: "../shared-swift"),
    ]
)
"#;

/// TEST11243: the local render is recognised in every shape this fleet uses.
///
/// Four ecosystems, and each one hides the local branch somewhere different:
/// Cargo puts it on its own lines, npm puts it inside one, Swift indents it
/// inside an array literal, and go.mod has two branches — one of which changes
/// a VERSION rather than adding a path, so a check that looked for paths would
/// miss half of what makes that manifest local.
#[test]
fn test11243_a_local_render_is_recognised_in_every_shape_the_fleet_uses() {
    for (name, template, local, committed) in [
        ("Cargo.toml", CARGO_TEMPLATE, CARGO_LOCAL, CARGO_COMMITTED),
        ("package.json", NPM_TEMPLATE, NPM_LOCAL, NPM_COMMITTED),
        ("go.mod", GO_TEMPLATE, GO_LOCAL, GO_COMMITTED),
        ("Package.swift", SWIFT_TEMPLATE, SWIFT_LOCAL, SWIFT_COMMITTED),
    ] {
        let hits = carried_by(template, local, VARIABLE);
        assert!(
            !hits.is_empty(),
            "{name}: the local render was not recognised — a release would ship it"
        );
        for Carried { line, text, block } in &hits {
            // The line it names has to be a line of the file, and the text has
            // to be that line: the refusal is read by a person who has to find
            // it.
            let actual = local
                .lines()
                .nth(line - 1)
                .unwrap_or_else(|| panic!("{name}: reported line {line}, which is past the end"));
            assert_eq!(actual.trim(), text, "{name}: line {line} is not what was reported");
            // And the branch it came from has to be the branch: every line of
            // it is a line of the local render and none is a line the ordinary
            // render also has, which is what makes reading the block for
            // references sound.
            for one in block {
                assert!(
                    local.lines().any(|l| l.trim() == one),
                    "{name}: the reported branch contains a line the file does not: {one}"
                );
            }
            // And it has to be a line the ordinary render does not have.
            // Naming a line both renders carry would point at the right file
            // and prove nothing about it.
            assert!(
                !committed.contains(text.as_str()),
                "{name}: line {line} appears in the ordinary render too, so it shows nothing: {text}"
            );
        }
    }
}

/// TEST11244: the committed render is not mistaken for the local one.
///
/// The half that decides whether this check can be left switched on. Every
/// fixture here is the file that is genuinely checked in beside its template,
/// and three of the four contain a path dependency that climbs out of the
/// package and is meant to: `floom-engine` depends on `cartridges/modelcartridge`
/// by path, permanently, and the Swift package on a sibling. A check that read
/// lines rather than branches refuses all of them, which is how this one was
/// nearly shipped refusing every release in the fleet.
#[test]
fn test11244_a_committed_render_is_not_mistaken_for_a_local_one() {
    for (name, template, committed) in [
        ("Cargo.toml", CARGO_TEMPLATE, CARGO_COMMITTED),
        ("package.json", NPM_TEMPLATE, NPM_COMMITTED),
        ("go.mod", GO_TEMPLATE, GO_COMMITTED),
        ("Package.swift", SWIFT_TEMPLATE, SWIFT_COMMITTED),
    ] {
        assert_eq!(
            carried_by(template, committed, VARIABLE),
            Vec::<Carried>::new(),
            "{name}: an ordinary committed manifest was refused as a local render"
        );
    }
    // Stated as its own assertion, because it is the specific confusion:
    // the committed Cargo render carries a `path =` line, and it is fine.
    assert!(
        CARGO_COMMITTED.contains("path = \"../../cartridges/modelcartridge\""),
        "the fixture no longer contains the committed path dependency it exists to protect"
    );
}

/// TEST11245: a manifest nothing generated is not judged.
///
/// The check reads templates. A hand-written manifest with a path dependency —
/// `wsb/daemon/Cargo.toml` says `wsb = { path = ".." }` — is a deliberate
/// arrangement inside one repository, and inventing a rule about it here would
/// refuse a release over a manifest this mechanism has no opinion about.
#[test]
fn test11245_a_manifest_no_template_generates_is_not_judged() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    std::fs::write(
        dir.path().join("Cargo.toml"),
        "[dependencies]\nwsb = { path = \"..\" }\ncapdag = { path = \"../../capdag/capdag-rs\" }\n",
    )
    .expect("the manifest writes");

    let found = scan(dir.path(), VARIABLE).expect("the scan runs");
    assert!(
        found.is_empty(),
        "a manifest with no template was judged: {found:?}"
    );
}

/// TEST11246: the scan finds the rendered file beside its template, and says
/// where.
///
/// The walk and the decision are separate, and this is the walk: a template
/// somewhere in a tree, its rendered form beside it, and a report that names
/// the file relative to what was scanned so the message means something from
/// wherever it is read.
#[test]
fn test11246_the_scan_names_the_file_it_found_and_the_line() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    let nested = dir.path().join("fabricloom").join("floom-engine");
    std::fs::create_dir_all(&nested).expect("the tree is created");
    std::fs::write(nested.join("Cargo.toml.wstemplate"), CARGO_TEMPLATE).expect("writes");
    std::fs::write(nested.join("Cargo.toml"), CARGO_LOCAL).expect("writes");

    let found = scan(dir.path(), VARIABLE).expect("the scan runs");
    assert_eq!(found.len(), 1, "expected exactly one finding, got {found:?}");
    assert_eq!(found[0].file, "fabricloom/floom-engine/Cargo.toml");
    assert_eq!(
        CARGO_LOCAL.lines().nth(found[0].line - 1).map(str::trim),
        Some(found[0].text.as_str())
    );

    // One finding says where; the refusal built from a set of them says what
    // to do about it. Both halves matter — a message with no file sends
    // somebody hunting, and one with no command leaves them to guess.
    let located = found[0].message();
    assert!(
        located.contains("fabricloom/floom-engine/Cargo.toml"),
        "a finding must name the file: {located}"
    );
    // And the line it shows is EVIDENCE: a line the ordinary render does not
    // have. Pointing at `[dependencies.capdag]`, which both renders carry,
    // would name the file correctly and prove nothing about it.
    assert!(
        !CARGO_COMMITTED.contains(&found[0].text),
        "the line shown appears in the ordinary render too, so it shows nothing: {located}"
    );
    let refusal = refusal(&found);
    assert!(
        refusal.contains("wsb local off"),
        "the refusal must name the command that undoes it: {refusal}"
    );
    assert!(
        refusal.contains(&located),
        "and carry the evidence: {refusal}"
    );

    // And with the committed render in place, the same tree passes. Without
    // this the test would be satisfied by a scan that reports everything.
    std::fs::write(nested.join("Cargo.toml"), CARGO_COMMITTED).expect("writes");
    assert!(
        scan(dir.path(), VARIABLE).expect("the scan runs").is_empty(),
        "the committed render was refused"
    );
}

/// TEST11247: a template whose rendered form is not there yet is not a
/// finding.
///
/// A fresh clone has templates and no renders. Refusing a release for a file
/// that does not exist would report a local dependency in a tree that has none.
#[test]
fn test11247_a_template_with_no_render_is_not_a_finding() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    std::fs::write(dir.path().join("Cargo.toml.wstemplate"), CARGO_TEMPLATE).expect("writes");
    assert!(
        scan(dir.path(), VARIABLE).expect("the scan runs").is_empty(),
        "a template with nothing rendered from it was reported"
    );
}

/// TEST11248: dependency trees are not walked.
///
/// `node_modules` holds thousands of third-party manifests, and one of them
/// carrying a `.wstemplate` — a published package that ships its own templates
/// — would put a stranger's file in this workspace's refusal. It is also the
/// difference between a scan that costs milliseconds and one that costs a
/// minute at every release.
#[test]
fn test11248_dependency_and_build_trees_are_not_walked() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    for skipped in ["node_modules", "target", ".git", "build"] {
        let nested = dir.path().join(skipped).join("someone-elses");
        std::fs::create_dir_all(&nested).expect("the tree is created");
        std::fs::write(nested.join("Cargo.toml.wstemplate"), CARGO_TEMPLATE).expect("writes");
        std::fs::write(nested.join("Cargo.toml"), CARGO_LOCAL).expect("writes");
    }
    assert!(
        scan(dir.path(), VARIABLE).expect("the scan runs").is_empty(),
        "a vendored tree was walked"
    );

    // The same file where it belongs IS found, so this is a statement about
    // where the scan looks and not about whether it looks at all.
    std::fs::write(dir.path().join("Cargo.toml.wstemplate"), CARGO_TEMPLATE).expect("writes");
    std::fs::write(dir.path().join("Cargo.toml"), CARGO_LOCAL).expect("writes");
    assert_eq!(
        scan(dir.path(), VARIABLE).expect("the scan runs").len(),
        1,
        "the file this scan is for was not found"
    );
}

/// TEST11262: a committed local render survives being restored from the
/// commit, which is why taking the render back is not enough on its own.
///
/// `wsb local off` restores what is COMMITTED, and that is the right rule —
/// it is what preserves a hand edit made since the last render. But it makes
/// the committed local render a FIXED POINT: `off` restores the local render,
/// `checkpoint` (which is `off`, commit, push, `on`) commits and pushes it
/// again, and every run afterwards does the same. Nothing in the loop can get
/// out of it.
///
/// Not hypothetical. Thirty-two generated manifests reached HEAD that way,
/// including a published mirror carrying `capdag = { path = "../.." }` — the
/// exact shape that once made a published capdag tag unresolvable for every
/// consumer. This test is the mechanism, in one file: restore from the commit,
/// and the tree is still local.
#[test]
fn test11262_a_committed_local_render_survives_a_restore_from_the_commit() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    let root = dir.path();
    let run = |args: &[&str]| {
        let status = crate::git_backend::git_command()
            .current_dir(root)
            .args(args)
            .stdout(std::process::Stdio::null())
            .stderr(std::process::Stdio::null())
            .status()
            .expect("git runs");
        assert!(status.success(), "git {args:?} failed");
    };
    run(&["init", "-q", "-b", "main"]);
    run(&["config", "user.email", "t@example.com"]);
    run(&["config", "user.name", "Test"]);

    std::fs::write(root.join("Cargo.toml.wstemplate"), CARGO_TEMPLATE).expect("writes");
    // The state the fleet was actually in: the LOCAL render, committed.
    std::fs::write(root.join("Cargo.toml"), CARGO_LOCAL).expect("writes");
    run(&["add", "-A"]);
    run(&["commit", "-q", "-m", "the local render, committed"]);

    // Someone renders the published form into the working tree…
    std::fs::write(root.join("Cargo.toml"), CARGO_COMMITTED).expect("writes");
    assert!(
        scan(root, VARIABLE).expect("the scan runs").is_empty(),
        "the published render must not be flagged"
    );

    // …and taking the render back — restoring what is committed — puts the
    // local one straight back. This is the whole trap.
    run(&["checkout", "--", "Cargo.toml"]);
    let found = scan(root, VARIABLE).expect("the scan runs");
    assert_eq!(
        found.len(),
        1,
        "restoring the commit must leave the tree local again, or this test protects nothing"
    );
    assert_eq!(found[0].file, "Cargo.toml");

    // The only way out is a render that does not consult the commit. That is
    // what `ensure_not_local` runs, and this is the shape of its result.
    std::fs::write(root.join("Cargo.toml"), CARGO_COMMITTED).expect("writes");
    assert!(
        scan(root, VARIABLE).expect("the scan runs").is_empty(),
        "a fresh render against published tags is what escapes it"
    );
}

/// TEST11263: the fleet's answer does not depend on which directory the
/// question was asked from.
///
/// This workspace is submodules all the way down, and every release door can
/// be run from inside one. Asked of a submodule, the scan answers for that
/// submodule alone — so a `checkpoint` typed in `wsb/`, a repository with no
/// `LOCAL_LIBS` templates in it at all, found nothing, reported a clean
/// tree, and committed and pushed the whole fleet's local render. That is not
/// a hypothetical: it is what happened, and it is why the root is resolved the
/// way the secret store resolves its own.
#[test]
fn test11263_the_fleets_answer_does_not_depend_on_where_it_was_asked() {
    let outer = tempfile::tempdir().expect("a scratch directory");
    let root = outer.path();
    let git = |dir: &std::path::Path, args: &[&str]| {
        let status = crate::git_backend::git_command()
            .current_dir(dir)
            .args(args)
            .stdout(std::process::Stdio::null())
            .stderr(std::process::Stdio::null())
            .status()
            .expect("git runs");
        assert!(status.success(), "git {args:?} failed in {}", dir.display());
    };
    git(root, &["init", "-q", "-b", "main"]);

    // A locally rendered manifest at the top…
    let engine = root.join("fabricloom").join("floom-engine");
    std::fs::create_dir_all(&engine).expect("the tree");
    std::fs::write(engine.join("Cargo.toml.wstemplate"), CARGO_TEMPLATE).expect("writes");
    std::fs::write(engine.join("Cargo.toml"), CARGO_LOCAL).expect("writes");

    // …and a nested repository that has no such template of its own. This is
    // `wsb/`: the place the command is most often typed.
    let inner = root.join("wsb");
    std::fs::create_dir_all(&inner).expect("the tree");
    git(&inner, &["init", "-q", "-b", "main"]);
    std::fs::write(inner.join("Cargo.toml"), "[package]\nname = \"wsb\"\n").expect("writes");

    // Asked of the nested repository, a plain scan honestly finds nothing —
    // there is nothing there.
    assert!(
        scan(&inner, VARIABLE).expect("the scan runs").is_empty(),
        "the nested repository has no templates, so a scan of it finds nothing"
    );

    // Asked FOR THE FLEET from inside it, the answer is the fleet's.
    let found = scan_workspace(&inner, VARIABLE).expect("the scan runs");
    assert_eq!(
        found.len(),
        1,
        "asked from a submodule, the fleet's answer was that submodule's: {found:?}"
    );
    assert_eq!(found[0].file, "fabricloom/floom-engine/Cargo.toml");

    // And from the top it is the same answer, which is the point.
    assert_eq!(scan_workspace(root, VARIABLE).expect("the scan runs"), found);
}

/// TEST11275: a survivor of the take-back says which of the two things it is.
///
/// A file still local after `wsb local off` is either a committed local
/// render — the fixed point, where the repository's HISTORY carries it and
/// only a committed fresh render escapes — or a file the take-back never
/// reached, whose history is perfectly clean. `checkpoint` used to announce
/// the first for every survivor without looking. Run from `wsb/`, where the
/// take-back covers its own update scope and not the nested submodules, it
/// declared thirty-three manifests' histories contaminated when every one of
/// them held a published tag at HEAD.
///
/// The two readings send you to opposite places — rewrite this history, or
/// touch nothing — so the answer is read from git, never assumed.
#[test]
fn test11275_a_survivor_names_why_it_survived() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    let root = dir.path();
    let run = |args: &[&str]| {
        let status = crate::git_backend::git_command()
            .current_dir(root)
            .args(args)
            .stdout(std::process::Stdio::null())
            .stderr(std::process::Stdio::null())
            .status()
            .expect("git runs");
        assert!(status.success(), "git {args:?} failed");
    };
    run(&["init", "-q", "-b", "main"]);
    run(&["config", "user.email", "t@example.com"]);
    run(&["config", "user.name", "Test"]);

    std::fs::write(root.join("clean.toml.wstemplate"), CARGO_TEMPLATE).expect("writes");
    std::fs::write(root.join("frozen.toml.wstemplate"), CARGO_TEMPLATE).expect("writes");
    // One committed as published, one committed as the local render. On disk
    // they are about to look identical — both local — which is exactly why
    // the working tree cannot answer this question.
    std::fs::write(root.join("clean.toml"), CARGO_COMMITTED).expect("writes");
    std::fs::write(root.join("frozen.toml"), CARGO_LOCAL).expect("writes");
    run(&["add", "-A"]);
    run(&["commit", "-q", "-m", "one clean, one frozen"]);

    // Now both carry the local render on disk: the take-back did not reach
    // this repository.
    std::fs::write(root.join("clean.toml"), CARGO_LOCAL).expect("writes");

    let found = scan(root, VARIABLE).expect("the scan runs");
    assert_eq!(found.len(), 2, "both files are local on disk");

    let of = |name: &str| {
        let one = found
            .iter()
            .find(|f| f.file == name)
            .unwrap_or_else(|| panic!("{name} is among the findings"));
        persistence(root, one, VARIABLE)
    };

    assert_eq!(
        of("clean.toml"),
        Persistence::NotRestored,
        "its committed form holds a published tag, so nothing about its history is wrong"
    );
    assert_eq!(
        of("frozen.toml"),
        Persistence::Committed,
        "its committed form IS the local render, so restoring the commit restores it"
    );
    // The distinction is the point: an answer that cannot tell them apart
    // would pass every assertion above with a single constant.
    assert_ne!(of("clean.toml"), of("frozen.toml"));
}

/// TEST11276: a generated file git does not track is neither answer.
///
/// "What does the history say" has no answer when there is no history of the
/// file, and the two real answers both make a claim about a commit. Folding it
/// into either one would either invent a contaminated history or promise a
/// clean one.
#[test]
fn test11276_an_untracked_render_makes_no_claim_about_history() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    let root = dir.path();
    let run = |args: &[&str]| {
        let status = crate::git_backend::git_command()
            .current_dir(root)
            .args(args)
            .stdout(std::process::Stdio::null())
            .stderr(std::process::Stdio::null())
            .status()
            .expect("git runs");
        assert!(status.success(), "git {args:?} failed");
    };
    run(&["init", "-q", "-b", "main"]);
    run(&["config", "user.email", "t@example.com"]);
    run(&["config", "user.name", "Test"]);
    std::fs::write(root.join("seed"), "seed").expect("writes");
    run(&["add", "-A"]);
    run(&["commit", "-q", "-m", "seed"]);

    // Rendered, local, and never committed.
    std::fs::write(root.join("Cargo.toml.wstemplate"), CARGO_TEMPLATE).expect("writes");
    std::fs::write(root.join("Cargo.toml"), CARGO_LOCAL).expect("writes");

    let found = scan(root, VARIABLE).expect("the scan runs");
    assert_eq!(found.len(), 1);
    assert_eq!(persistence(root, &found[0], VARIABLE), Persistence::Untracked);
}

/// `mfab-tests/capdag-interop/pyproject.toml.wstemplate`, as it stood when a
/// local render first reached a guest.
///
/// The one branch in the fleet that rendered an ABSOLUTE path. Kept as a
/// fixture after the tree stopped using it, because this check exists to
/// notice the shape coming back — and because it is the shape that grounded
/// every Windows run for a day, in pip's output, ten minutes into a guest.
const PYPROJECT_TEMPLATE: &str = r#"[project]
name = "capdag-interop-tests"
requires-python = ">=3.10"
dependencies = [
    "pytest>=7.0",
{%- if env.LOCAL_LIBS %}
    "capdag @ file://{{ projects.capdag_py.path }}",
{%- else %}
    "capdag>={{ projects.capdag_py.latest_remote_version }}",
{%- endif %}
    "tagged-urn>=1.27.122",
]
"#;

const PYPROJECT_LOCAL: &str = r#"[project]
name = "capdag-interop-tests"
requires-python = ">=3.10"
dependencies = [
    "pytest>=7.0",
    "capdag @ file:///home/bahram/ws/prj/machinefabric/main-worktree/capdag/capdag-py",
    "tagged-urn>=1.27.122",
]
"#;

/// Where each fixture sits in a workspace, at the depth its relative paths
/// were written for.
///
/// The depth is not decoration: `../../capdag/capdag-rs` means one thing from
/// `fabricloom/floom-engine` and another from the root, and a fixture placed
/// at the wrong depth would prove the opposite of what it was written to
/// prove.
const PLACED: &[(&str, &str, &str, &str)] = &[
    (
        "Cargo.toml",
        "fabricloom/floom-engine",
        CARGO_TEMPLATE,
        CARGO_LOCAL,
    ),
    (
        "package.json",
        "fabricloom/unifloom",
        NPM_TEMPLATE,
        NPM_LOCAL,
    ),
    (
        "go.mod",
        "mfab-tests/capdag-interop/src/capdag_interop/hosts/go-relay",
        GO_TEMPLATE,
        GO_LOCAL,
    ),
    (
        "Package.swift",
        "cartridges/mlxcartridge",
        SWIFT_TEMPLATE,
        SWIFT_LOCAL,
    ),
];

/// Write one fixture into a workspace at the place it belongs.
fn place(root: &std::path::Path, dir: &str, name: &str, template: &str, rendered: &str) {
    let at = root.join(dir);
    std::fs::create_dir_all(&at).expect("the tree is created");
    std::fs::write(at.join(format!("{name}.wstemplate")), template).expect("writes");
    std::fs::write(at.join(name), rendered).expect("writes");
}

/// TEST11466: a local render that stays inside the workspace travels with it.
///
/// The distinction this module turns on. Every one of these four is a local
/// render and a release door refuses all of them — but each names a directory
/// INSIDE the workspace, relative to the manifest that names it, so a copy of
/// the workspace contains it and `mg-test run` has nothing to refuse.
///
/// Asserted over the real fixtures rather than an invented one because of what
/// the real ones contain: a local branch opens with a comment, and `//` is a
/// comment marker in two of these four languages. Read as a path, `//` is the
/// filesystem ROOT — the most absolute path there is — which would report the
/// Go and Swift renders as escaping the workspace and ground exactly the runs
/// this test exists to keep running.
#[test]
fn test11466_a_local_render_inside_the_workspace_travels_with_it() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    for (name, at, template, rendered) in PLACED {
        place(dir.path(), at, name, template, rendered);
    }

    let found = scan(dir.path(), VARIABLE).expect("the scan runs");
    assert_eq!(
        found.len(),
        PLACED.len(),
        "every fixture is a local render and a release door refuses it: {found:?}"
    );
    let escaping = escaping(&found);
    assert!(
        escaping.is_empty(),
        "these renders are copied into the guest intact and must not be refused: {:?}",
        escaping
            .iter()
            .map(|one| (one.file.clone(), one.escapes.clone()))
            .collect::<Vec<_>>()
    );
}

/// TEST11467: an absolute reference does not travel, and the refusal names it.
///
/// The failure this whole distinction was drawn around. `capdag @
/// file:///home/bahram/…/capdag-py` is a local render like the others and
/// looks like one, but it names a directory on ONE workstation: the guest gets
/// the workspace, allocates, boots, builds wsb from source, and then dies in
/// pip on a path it has never heard of.
///
/// So the staging refusal has to name the reference and not merely the file —
/// the whole point is that this one manifest differs from the thirty beside it
/// that are fine.
#[test]
fn test11467_an_absolute_reference_does_not_travel() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    for (name, at, template, rendered) in PLACED {
        place(dir.path(), at, name, template, rendered);
    }
    place(
        dir.path(),
        "mfab-tests/capdag-interop",
        "pyproject.toml",
        PYPROJECT_TEMPLATE,
        PYPROJECT_LOCAL,
    );

    let found = scan(dir.path(), VARIABLE).expect("the scan runs");
    let escaping = escaping(&found);
    assert_eq!(
        escaping.len(),
        1,
        "exactly one of these references leaves the workspace: {:?}",
        escaping
            .iter()
            .map(|one| one.file.clone())
            .collect::<Vec<_>>()
    );
    assert_eq!(escaping[0].file, "mfab-tests/capdag-interop/pyproject.toml");
    assert_eq!(
        escaping[0].escapes,
        vec!["/home/bahram/ws/prj/machinefabric/main-worktree/capdag/capdag-py".to_string()],
        "the reference is recorded as the place it points at"
    );

    let refusal = staging_refusal(&escaping);
    assert!(
        refusal.contains("mfab-tests/capdag-interop/pyproject.toml"),
        "the refusal must name the file: {refusal}"
    );
    assert!(
        refusal.contains("/home/bahram/ws/prj/machinefabric/main-worktree/capdag/capdag-py"),
        "and the reference that cannot come with it: {refusal}"
    );
    // And it must not name the four that are fine. A refusal that listed every
    // local render sent somebody to undo the render they are working in, for
    // thirty manifests that would have arrived intact.
    for (name, at, _, _) in PLACED {
        assert!(
            !refusal.contains(&format!("{at}/{name}")),
            "{at}/{name} travels with the workspace and must not appear: {refusal}"
        );
    }
}

/// TEST11468: a relative reference that climbs out of the workspace does not
/// travel either.
///
/// Being relative is not the property that matters — being INSIDE is. A path
/// that walks up past the workspace root names a sibling of the workspace,
/// which is a fact about one desk, and the copy stops at the root.
#[test]
fn test11468_a_relative_reference_that_leaves_the_workspace_does_not_travel() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    let escaped = CARGO_LOCAL.replace(
        "path = \"../../capdag/capdag-rs\"",
        "path = \"../../../elsewhere/capdag-rs\"",
    );
    place(
        dir.path(),
        "fabricloom/floom-engine",
        "Cargo.toml",
        CARGO_TEMPLATE,
        &escaped,
    );

    let found = scan(dir.path(), VARIABLE).expect("the scan runs");
    let escaping = escaping(&found);
    assert_eq!(escaping.len(), 1, "the reference leaves the workspace");
    assert_eq!(
        escaping[0].escapes,
        vec!["../../../elsewhere/capdag-rs".to_string()]
    );

    // The committed path dependency two tables down still climbs out of its
    // PACKAGE and stays in the workspace, and must not be swept up with it.
    assert!(
        escaped.contains("path = \"../../cartridges/modelcartridge\""),
        "the fixture no longer carries the deliberate cross-repository path"
    );
    assert_eq!(
        escaping[0].escapes.len(),
        1,
        "only the reference that leaves the workspace is reported: {:?}",
        escaping[0].escapes
    );
}

/// TEST11469: a Windows path is absolute on the machine reading it too.
///
/// This scan runs on Linux and stages into Windows guests. `Path::is_absolute`
/// answers for the platform it is compiled for, so `C:\Users\…` read on Linux
/// is a relative path with a strange name — one that would be judged to sit
/// inside the workspace and be staged into a guest that cannot resolve it.
#[test]
fn test11469_a_windows_path_is_absolute_wherever_it_is_read() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    for (reference, why) in [
        ("C:/Users/bahram/capdag/capdag-rs", "a drive letter"),
        (r"C:\Users\bahram\capdag\capdag-rs", "a drive letter with backslashes"),
        (r"\\build\share\capdag-rs", "a UNC share"),
        ("~/ws/prj/machinefabric/main-worktree/capdag/capdag-rs", "a home directory"),
    ] {
        let at = dir.path().join(reference.len().to_string());
        let rendered = CARGO_LOCAL.replace("../../capdag/capdag-rs", reference);
        place(&at, "fabricloom/floom-engine", "Cargo.toml", CARGO_TEMPLATE, &rendered);
        let found = scan(&at, VARIABLE).expect("the scan runs");
        assert_eq!(
            escaping(&found).len(),
            1,
            "{why} names a place outside the workspace: {reference}"
        );
    }
}

/// TEST12440: a fleet's local render needs a build only when a local branch
/// reads the build root.
///
/// `local on` built lungo's distribution in every fleet, and in one with no
/// workspace declaration it could not, so `local on` failed there and took
/// its render back — for a distribution no manifest named.
#[test]
fn test12440_only_a_local_branch_that_reads_the_build_root_needs_a_build() {
    let dir = tempfile::tempdir().expect("a scratch directory");
    std::fs::write(dir.path().join("Cargo.toml.wstemplate"), CARGO_TEMPLATE).expect("writes");
    assert!(!local_render_reads_build_root(dir.path(), VARIABLE).unwrap(), "a path to a working copy reads no build root");

    let nested = dir.path().join("capdag").join("capdag-go");
    std::fs::create_dir_all(&nested).expect("the tree is created");
    std::fs::write(
        nested.join("go.mod.wstemplate"),
        "module example.com/x\n{% if env.LOCAL_LIBS %}\nreplace example.com/y => {{ build.root_from_here }}/lungo/distribution/go\n{% endif %}\n",
    )
    .expect("writes");
    assert!(local_render_reads_build_root(dir.path(), VARIABLE).unwrap());

    // The build root read outside a local branch is not this question's.
    let other = tempfile::tempdir().expect("a scratch directory");
    std::fs::write(other.path().join("x.toml.wstemplate"), "root = \"{{ build.root_from_here }}\"\n").expect("writes");
    assert!(!local_render_reads_build_root(other.path(), VARIABLE).unwrap());
}