cursor-setup-system 0.0.61

Install, update, back up, restore and remove complete Cursor CLI configurations. Built by NDDev.
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
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
//! The commands an owner types.
//!
//! These are the reason the project exists: choose a complete harness state,
//! put it in place, change your mind, and get the previous one back. The wire
//! surface serves a consumer; this one serves a person.
//!
//! It is not a second implementation. Every mutation here builds the same plan
//! the wire surface builds and hands it to [`wire::perform`], so the lock, the
//! journal, the backup and the recovery story are identical. What differs is
//! only where the setup came from and who is reading the output.
//!
//! # The target is always explicit
//!
//! Every command takes `--target <absolute-directory>`. There is no default and
//! no fallback to a configuration home, because a mutation aimed at a guessed
//! path is a mutation aimed at someone else's state. The documented home is
//! printed by `--help` so it can be copied, not resolved.

use std::path::{Path, PathBuf};
use std::time::SystemTime;

use crate::provider_v3::plan::{PlanArtifact, PlanInputs};
use crate::provider_v3::{Error, Operation, Result, WireReason};
use crate::setup_core::backup::Pool;
use crate::setup_core::stamp::{ProviderState, StateReading};
use crate::setup_core::target::Target;

use crate::harness_runtime::adopt;
use crate::harness_runtime::catalog::{CATALOG_DIRECTORY, Catalog};
use crate::harness_runtime::expiry;
use crate::harness_runtime::facts::{self, Harness};
use crate::harness_runtime::wire::{self, Effect, Mutation};

/// How long a plan this surface makes stays applicable.
///
/// It is applied within the same process, so the window only has to cover that.
/// A long one would mean a plan could outlive the state it was made against.
const PLAN_WINDOW_SECONDS: u64 = 600;
/// Every verb this surface answers.
///
/// Named once so nothing has to remember it. `into_command` is the authority
/// and a test below proves this list is exactly what that match accepts, in
/// both directions -- a verb here the match refuses, or a verb the match takes
/// that is missing here, is red.
///
/// Read by [`crate::harness_runtime::catalog::misdirecting`], because a setup that tells an
/// agent to run a command this binary refuses is shipping an instruction that
/// fails. One of them did, for six releases.
pub const VERBS: &[&str] = &[
    "adopt",
    "backups",
    "diff",
    "hold",
    "install",
    "list",
    "reinstall",
    "release",
    "remove",
    "restore",
    "rollback",
    "select",
    "software",
    "status",
];

/// One parsed human command.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Command {
    /// Show the setups this build ships.
    List,
    /// Report what is in a target.
    Status {
        /// The directory to read.
        target: PathBuf,
    },
    /// Put a setup into a target.
    Install {
        /// The directory to write.
        target: PathBuf,
        /// The setup to apply.
        setup: String,
    },
    /// Keep one backup until it is released, so retention cannot reclaim it.
    Hold {
        /// The target whose pool holds it.
        target: PathBuf,
        /// The slot to keep. Named, never inferred.
        backup: Option<String>,
        /// Why it is held, so whoever meets a full pool knows the cost.
        reason: Option<String>,
    },
    /// Let retention have a held backup back.
    Release {
        /// The target whose pool holds it.
        target: PathBuf,
        /// The slot to let go.
        backup: Option<String>,
    },
    /// Report which versions of the product are installed, and which is exposed.
    Software {
        /// The program directory to read.
        prefix: PathBuf,
    },
    /// Point the exposed command back at a version already on disk.
    Rollback {
        /// The program directory to change.
        prefix: PathBuf,
        /// The version to expose. Named, never inferred.
        to: Option<String>,
    },
    /// Re-apply whatever setup is already recorded, repairing drift.
    Reinstall {
        /// The directory to repair.
        target: PathBuf,
    },
    /// Replace the applied setup with another.
    Select {
        /// The directory to write.
        target: PathBuf,
        /// The setup to switch to.
        setup: String,
    },
    /// List the backups a target holds.
    Backups {
        /// The directory to read.
        target: PathBuf,
    },
    /// Put a captured state back.
    Restore {
        /// The directory to write.
        target: PathBuf,
        /// The slot to read, or the most recent when absent.
        backup: Option<String>,
    },
    /// Take over a target the frozen estate's program still claims.
    Adopt {
        /// The directory to take over.
        target: PathBuf,
    },
    /// Withdraw everything this provider owns.
    Remove {
        /// The directory to clear.
        target: PathBuf,
    },
    /// Report what differs between the target and the setup recorded in it.
    Diff {
        /// The directory to compare.
        target: PathBuf,
    },
}

/// Whether a first argument names a human command.
#[must_use]
pub fn is_human_command(name: &str) -> bool {
    matches!(
        name,
        "list"
            | "install"
            | "reinstall"
            | "select"
            | "backups"
            | "restore"
            | "remove"
            | "adopt"
            | "diff"
            | "software"
            | "rollback"
            | "hold"
            | "release"
    )
}

/// Parse a human invocation.
///
/// # Errors
///
/// Refuses an unknown command, a missing `--target`, a missing setup name and
/// any unknown flag. Nothing is guessed.
pub fn parse<I, S>(arguments: I) -> Result<Command>
where
    I: IntoIterator<Item = S>,
    S: Into<String>,
{
    let tokens: Vec<String> = arguments.into_iter().map(Into::into).collect();
    let Some(name) = tokens.first().cloned() else {
        return Err(local("no command was given"));
    };
    let parsed = Arguments::scan(&name, tokens.get(1..).unwrap_or_default())?;
    parsed.into_command(&name)
}

/// The flags and positionals one invocation carried.
struct Arguments {
    target: Option<PathBuf>,
    backup: Option<String>,
    prefix: Option<PathBuf>,
    to: Option<String>,
    reason: Option<String>,
    positional: Vec<String>,
}

impl Arguments {
    /// Split an argument list into flags and positionals, refusing anything odd.
    fn scan(name: &str, rest: &[String]) -> Result<Self> {
        let mut parsed = Self {
            target: None,
            backup: None,
            prefix: None,
            to: None,
            reason: None,
            positional: Vec::new(),
        };
        let mut index = 0;
        while index < rest.len() {
            let Some(token) = rest.get(index) else { break };
            match token.as_str() {
                "--target" | "--backup" | "--prefix" | "--to" | "--reason" => {
                    let Some(value) = rest.get(index + 1) else {
                        return Err(local(format!("{token} has no value")));
                    };
                    if value.starts_with("--") {
                        return Err(local(format!("{token} has no value")));
                    }
                    match token.as_str() {
                        "--target" => {
                            if parsed.target.is_some() {
                                return Err(local("--target was given twice"));
                            }
                            parsed.target = Some(PathBuf::from(value));
                        }
                        "--prefix" => {
                            if parsed.prefix.is_some() {
                                return Err(local("--prefix was given twice"));
                            }
                            parsed.prefix = Some(PathBuf::from(value));
                        }
                        "--to" => {
                            if parsed.to.is_some() {
                                return Err(local("--to was given twice"));
                            }
                            parsed.to = Some(value.clone());
                        }
                        "--reason" => {
                            if parsed.reason.is_some() {
                                return Err(local("--reason was given twice"));
                            }
                            parsed.reason = Some(value.clone());
                        }
                        _ => {
                            if parsed.backup.is_some() {
                                return Err(local("--backup was given twice"));
                            }
                            parsed.backup = Some(value.clone());
                        }
                    }
                    index += 2;
                }
                other if other.starts_with("--") => {
                    return Err(local(format!("{other} is not an argument of {name}")));
                }
                other => {
                    parsed.positional.push(other.to_owned());
                    index += 1;
                }
            }
        }
        Ok(parsed)
    }

    fn target(&self, name: &str) -> Result<PathBuf> {
        self.target
            .clone()
            .ok_or_else(|| local(format!("{name} requires --target <absolute-directory>")))
    }

    fn prefix(&self, name: &str) -> Result<PathBuf> {
        self.prefix
            .clone()
            .ok_or_else(|| local(format!("{name} requires --prefix <absolute-directory>")))
    }

    fn setup(&self, name: &str) -> Result<String> {
        match self.positional.as_slice() {
            [only] => Ok(only.clone()),
            [] => Err(local(format!(
                "{name} requires a setup name; run `list` to see them"
            ))),
            _ => Err(local(format!("{name} takes one setup name"))),
        }
    }

    fn no_setup(&self, name: &str) -> Result<()> {
        if self.positional.is_empty() {
            Ok(())
        } else {
            Err(local(format!("{name} takes no setup name")))
        }
    }

    fn into_command(self, name: &str) -> Result<Command> {
        if self.backup.is_some() && !matches!(name, "restore" | "hold" | "release") {
            return Err(local(format!("--backup is not an argument of {name}")));
        }
        if self.prefix.is_some() && !matches!(name, "software" | "rollback") {
            return Err(local(format!("--prefix is not an argument of {name}")));
        }
        if self.to.is_some() && name != "rollback" {
            return Err(local(format!("--to is not an argument of {name}")));
        }
        if self.reason.is_some() && name != "hold" {
            return Err(local(format!("--reason is not an argument of {name}")));
        }
        match name {
            "list" => {
                self.no_setup(name)?;
                Ok(Command::List)
            }
            "hold" => {
                self.no_setup(name)?;
                Ok(Command::Hold {
                    target: self.target(name)?,
                    backup: self.backup,
                    reason: self.reason,
                })
            }
            "release" => {
                self.no_setup(name)?;
                Ok(Command::Release {
                    target: self.target(name)?,
                    backup: self.backup,
                })
            }
            "software" => {
                self.no_setup(name)?;
                Ok(Command::Software {
                    prefix: self.prefix(name)?,
                })
            }
            "rollback" => {
                self.no_setup(name)?;
                Ok(Command::Rollback {
                    prefix: self.prefix(name)?,
                    to: self.to,
                })
            }
            "status" => {
                self.no_setup(name)?;
                Ok(Command::Status {
                    target: self.target(name)?,
                })
            }
            "install" => Ok(Command::Install {
                target: self.target(name)?,
                setup: self.setup(name)?,
            }),
            "select" => Ok(Command::Select {
                target: self.target(name)?,
                setup: self.setup(name)?,
            }),
            "reinstall" => {
                self.no_setup(name)?;
                Ok(Command::Reinstall {
                    target: self.target(name)?,
                })
            }
            "backups" => {
                self.no_setup(name)?;
                Ok(Command::Backups {
                    target: self.target(name)?,
                })
            }
            "restore" => {
                self.no_setup(name)?;
                let target = self.target(name)?;
                Ok(Command::Restore {
                    target,
                    backup: self.backup,
                })
            }
            "remove" => {
                self.no_setup(name)?;
                Ok(Command::Remove {
                    target: self.target(name)?,
                })
            }
            "adopt" => {
                self.no_setup(name)?;
                Ok(Command::Adopt {
                    target: self.target(name)?,
                })
            }
            "diff" => {
                self.no_setup(name)?;
                Ok(Command::Diff {
                    target: self.target(name)?,
                })
            }
            other => Err(local(format!("{other:?} is not a command"))),
        }
    }
}

/// Run one human command, writing its report to stdout.
///
/// # Errors
///
/// Propagates the refusal. The caller renders it.
pub fn run(harness: &Harness, command: Command) -> Result<()> {
    match command {
        Command::List => list(harness),
        Command::Status { target } => status(harness, &target),
        Command::Backups { target } => backups(harness, &target),
        Command::Diff { target } => diff(harness, &target),
        Command::Install { target, setup } => {
            apply_setup(harness, &target, &setup, Operation::Install)
        }
        Command::Select { target, setup } => {
            apply_setup(harness, &target, &setup, Operation::Replace)
        }
        Command::Reinstall { target } => reinstall(harness, &target),
        Command::Restore { target, backup } => restore(harness, &target, backup),
        Command::Adopt { target } => adopt_target(harness, &target),
        Command::Remove { target } => remove(harness, &target),
        Command::Hold {
            target,
            backup,
            reason,
        } => hold(harness, &target, backup.as_deref(), reason.as_deref()),
        Command::Release { target, backup } => release(harness, &target, backup.as_deref()),
        Command::Software { prefix } => software(harness, &prefix),
        Command::Rollback { prefix, to } => rollback(harness, &prefix, to.as_deref()),
    }
}

/// Keep one backup until it is released.
///
/// The pool rolls: ten slots, oldest evicted. A long series of captures makes
/// more than that, so a baseline someone means to return to at the end is gone
/// by the time they get there. A hold is the smallest thing that stops it —
/// one marker eviction has to read.
fn hold(
    harness: &Harness,
    target: &Path,
    backup: Option<&str>,
    reason: Option<&str>,
) -> Result<()> {
    let (resolved, pool) = pool_of(harness, target)?;
    let reference = named_slot(&pool, backup, "hold")?;
    // A pool can be held by more than one run. Without a reason, whoever meets
    // a full pool knows which slots to release and not what releasing one
    // would cost.
    let reason = reason.unwrap_or("no reason recorded");
    if pool.hold(&reference, reason)? {
        println!(
            "{} is held ({reason}). Retention will not reclaim it until it is released.",
            reference.as_str()
        );
    } else {
        let why = pool
            .held_reason(&reference)?
            .unwrap_or_else(|| "no reason recorded".to_owned());
        println!("{} was already held ({why}).", reference.as_str());
    }
    println!(
        "  release it with:  release --backup {} --target {}",
        reference.as_str(),
        resolved.root().display()
    );
    Ok(())
}

/// Let retention have a held backup back.
fn release(harness: &Harness, target: &Path, backup: Option<&str>) -> Result<()> {
    let (_, pool) = pool_of(harness, target)?;
    let reference = named_slot(&pool, backup, "release")?;
    if pool.release(&reference)? {
        println!(
            "{} is released and will be reclaimed like any other slot.",
            reference.as_str()
        );
    } else {
        // Not a refusal: a run cleaning up after itself should not have to tell
        // "nothing to do" apart from "something is wrong".
        println!("{} was not held; nothing to release.", reference.as_str());
    }
    Ok(())
}

fn pool_of(harness: &Harness, target: &Path) -> Result<(Target, Pool)> {
    let resolved = Target::resolve(target, harness.control_directory)?;
    let pool = Pool::observe(&resolved.control_directory(), facts::BACKUP_SLOTS)?;
    Ok((resolved, pool))
}

/// The slot a caller named, or the list of the ones they could have named.
///
/// Never inferred. `restore` may default to the newest because that is the one
/// thing a caller wanting "undo" can mean; keeping a slot is a decision about a
/// specific capture, and guessing which would be guessing what a run is for.
fn named_slot(
    pool: &Pool,
    backup: Option<&str>,
    verb: &str,
) -> Result<crate::setup_core::backup::BackupRef> {
    let available = pool.list()?;
    let Some(text) = backup else {
        return Err(local(if available.is_empty() {
            format!("{verb} requires --backup <ref>, and this target has no backups")
        } else {
            format!(
                "{verb} requires --backup <ref>; this target holds {}",
                available
                    .iter()
                    .map(|record| record.backup_ref.as_str())
                    .collect::<Vec<_>>()
                    .join(", ")
            )
        }));
    };
    crate::setup_core::backup::BackupRef::parse(text)
        .map_err(|error| local(format!("{text:?} is not a backup reference: {error}")))
}

/// What the program directory holds, and which version answers to the command.
///
/// Install and update are not here, and their absence is the design rather than
/// an omission: both need bytes fetched over a network this program never
/// touches, so they are the three-phase exchange the wire already carries.
/// Rollback and this reading need no network at all, which is exactly why they
/// can be commands someone types.
fn software(harness: &Harness, prefix: &Path) -> Result<()> {
    let declared = declared_software(harness)?;
    // This platform's member, not the table's first row: the hint said `agent`
    // where Windows holds `agent.cmd`, so this surface answered "Nothing is
    // exposed" over a prefix with a working install -- found by our own
    // evidence the day the wire half of the same defect shipped as fixed.
    let present = crate::setup_core::software::Present::under_named(
        prefix,
        declared.command,
        declared.member_here(),
    );

    if present.versions.is_empty() {
        println!(
            "No version of {} is installed under {}.",
            declared.command,
            prefix.display()
        );
        return Ok(());
    }

    println!("{} under {}:", declared.command, prefix.display());
    println!();
    for version in &present.versions {
        let mark = if present.exposed.as_ref() == Some(version) {
            "* "
        } else {
            "  "
        };
        println!("  {mark}{version}");
    }
    println!();
    match &present.exposed {
        Some(version) => println!(
            "  {}/bin/{} runs {version}",
            prefix.display(),
            declared.command
        ),
        // Worth saying rather than leaving blank: the versions are on disk and
        // nothing answers to the command, which is a different situation from
        // having nothing installed.
        None => println!(
            "  Nothing is exposed: {}/bin/{} names no installed version.",
            prefix.display(),
            declared.command
        ),
    }
    if present.versions.len() > 1 {
        println!();
        println!(
            "  Change it with:  rollback --to <version> --prefix {}",
            prefix.display()
        );
    }
    Ok(())
}

/// Point the exposed command back at a version that is already on disk.
fn rollback(harness: &Harness, prefix: &Path, to: Option<&str>) -> Result<()> {
    let declared = declared_software(harness)?;
    // Same fact as `software` above: the member Windows actually gets.
    let present = crate::setup_core::software::Present::under_named(
        prefix,
        declared.command,
        declared.member_here(),
    );

    // Named, never inferred. There is no record of what was previous -- only
    // what is on disk -- and these version strings do not order reliably:
    // cursor's `2026.08.11-e8db854` sorts by string, not by release. Choosing
    // "the one before" would invent an ordering the vendor never promised.
    let Some(version) = to else {
        return Err(local(if present.versions.is_empty() {
            format!(
                "rollback requires --to <version>, and {} holds none",
                prefix.display()
            )
        } else {
            format!(
                "rollback requires --to <version>; {} holds {}",
                prefix.display(),
                present.versions.join(", ")
            )
        }));
    };

    if present.exposed.as_deref() == Some(version) {
        println!(
            "{} already runs {version}; nothing to do.",
            declared.command
        );
        return Ok(());
    }

    let rolled = crate::setup_core::software::rollback(&declared, prefix, version)?;
    println!(
        "{} now runs {}.",
        rolled.executable.display(),
        rolled.version
    );
    if let Some(previous) = present.exposed {
        println!("  it ran {previous} before this, and that tree is still here");
    }
    Ok(())
}

/// The software this build installs, or the reason it installs none.
///
/// Two different absences, and they are worth separating. A harness with no
/// `software` at all does not offer the lifecycle. A harness whose delivery is a
/// package manager does -- the product is installable, just not by fetching
/// bytes whose digest was fixed in advance -- and answering "nothing is
/// installed under this prefix" would suggest this build could put something
/// there. It cannot, and pi is the one that would have been told so.
fn declared_software(harness: &Harness) -> Result<crate::setup_core::software::Software> {
    let declared = harness.software.ok_or_else(|| {
        local(format!(
            "{} configures {} and does not install it",
            harness.provider_id, harness.product
        ))
    })?;
    if let crate::setup_core::software::Delivery::Manager { tool, reason } = declared.delivery {
        return Err(local(format!(
            "{} is delivered by {tool}: {reason}",
            declared.command
        )));
    }
    Ok(declared)
}

fn local(detail: impl Into<String>) -> Error {
    Error::refuse(WireReason::ProviderUnavailable, detail)
}

fn catalog(harness: &Harness) -> Result<Catalog> {
    Catalog::discover(harness).ok_or_else(|| {
        local(format!(
            "no setup catalog was found; point {}_SETUP_CATALOG at one, or run from a \
             tree that ships {CATALOG_DIRECTORY}/",
            harness.provider_id.to_uppercase().replace('-', "_")
        ))
    })
}

/// Break a description into lines a terminal can hold, at word boundaries.
///
/// `list` printed each description as one `println!`, which was fine while
/// every description was a sentence. The `full-auto` postures say what they
/// turn off *and* which axis they are, and the longest reached 330 characters
/// on one line -- unreadable in exactly the moment someone is choosing what to
/// install.
///
/// Fixed width rather than the terminal's: asking the terminal makes the
/// output depend on where it ran, and two runs of `list` that disagree are
/// worse than a line that is occasionally short. A word longer than the width
/// is emitted whole rather than cut, because a broken URL helps nobody.
fn wrapped(text: &str, width: usize) -> Vec<String> {
    let mut lines = Vec::new();
    let mut line = String::new();
    for word in text.split_whitespace() {
        if line.is_empty() {
            line.push_str(word);
        } else if line.chars().count() + 1 + word.chars().count() <= width {
            line.push(' ');
            line.push_str(word);
        } else {
            lines.push(std::mem::take(&mut line));
            line.push_str(word);
        }
    }
    if !line.is_empty() {
        lines.push(line);
    }
    lines
}

/// The width a description is wrapped to, indent excluded.
const DESCRIPTION_WIDTH: usize = 72;

fn list(harness: &Harness) -> Result<()> {
    let setups = catalog(harness)?.list()?;
    if setups.is_empty() {
        println!("{}: no setups in the catalog.", harness.provider_id);
        return Ok(());
    }
    println!("Setups for {} ({}):", harness.product, harness.vendor);
    println!();
    for setup in &setups {
        println!("  {}", setup.manifest.id);
        for line in wrapped(&setup.manifest.description, DESCRIPTION_WIDTH) {
            println!("      {line}");
        }
        println!(
            "      {} files, definition {}",
            setup.file_count,
            short(&setup.definition_digest)
        );
    }
    println!();
    println!("Install one with:  install <id> --target <absolute-directory>");
    Ok(())
}

fn status(harness: &Harness, target: &Path) -> Result<()> {
    let resolved = Target::resolve(target, harness.control_directory)?;
    let identity =
        resolved.identity_of_owned(harness.owned_projection(None), &harness.not_our_identity())?;
    println!("Target   {}", resolved.root().display());
    println!("Identity {}", short(&identity));

    match ProviderState::read(resolved.root(), harness.state_file)? {
        StateReading::Absent => {
            println!("Setup    none applied by {}", harness.provider_id);
        }
        StateReading::ForeignSchema { found_schema } => {
            println!("Setup    recorded in schema {found_schema}, which this build does not write");
            println!("         reported as found; nothing was migrated");
        }
        StateReading::Current(state) => {
            // One condition, one sentence. A target restored to a slot captured
            // before any setup existed holds exactly what an untouched target
            // holds, and used to read `(unnamed)` there while the same emptiness
            // one command earlier read `none applied`. Two sentences for one
            // state, and the reader has to know which path got them here to tell
            // that they mean the same thing.
            //
            // So both now open with `none`, and the clause after it says why
            // this one has a state file at all.
            match state.setup_stable_id.as_deref() {
                Some(id) => println!("Setup    {id}"),
                None => println!("Setup    none — the last operation named no setup"),
            }
            println!("Applied  operation {}", state.operation_id);
            if identity == state.target_identity_digest {
                println!("Drift    none");
            } else {
                println!("Drift    the target has changed since it was applied");
                println!("         run `diff` to see where, or `reinstall` to put it back");
            }
        }
    }

    // Observing, not opening: reporting how many backups exist must not create
    // the place they would live. Asking a question should not change its answer.
    let pool = Pool::observe(&resolved.control_directory(), facts::BACKUP_SLOTS)?;
    println!("Backups  {}", pool.list()?.len());
    Ok(())
}

fn backups(harness: &Harness, target: &Path) -> Result<()> {
    let resolved = Target::resolve(target, harness.control_directory)?;
    let records = Pool::observe(&resolved.control_directory(), facts::BACKUP_SLOTS)?.list()?;
    if records.is_empty() {
        println!("No backups. One is captured before every change.");
        return Ok(());
    }
    println!("Backups of {}, newest first:", resolved.root().display());
    println!();
    let pool = Pool::observe(&resolved.control_directory(), facts::BACKUP_SLOTS)?;
    for (position, record) in records.iter().enumerate() {
        let mut marker = String::new();
        if position == 0 {
            marker.push_str("  (restored by default)");
        }
        if let Some(why) = pool.held_reason(&record.backup_ref)? {
            use std::fmt::Write as _;
            let _ = write!(marker, "  (held: {why})");
        }
        println!("  {}{marker}", record.backup_ref.as_str());
        println!(
            "      before {}, setup {}",
            record.operation,
            record.setup_id.as_deref().unwrap_or("none")
        );
    }
    println!();
    println!("Restore a specific one with:  restore --backup <ref> --target <dir>");
    Ok(())
}

fn diff(harness: &Harness, target: &Path) -> Result<()> {
    let resolved = Target::resolve(target, harness.control_directory)?;
    let identity =
        resolved.identity_of_owned(harness.owned_projection(None), &harness.not_our_identity())?;
    let StateReading::Current(state) = ProviderState::read(resolved.root(), harness.state_file)?
    else {
        println!(
            "Nothing to compare: {} has applied no setup here.",
            harness.provider_id
        );
        return Ok(());
    };
    if identity == state.target_identity_digest {
        println!("The target matches the setup recorded in it.");
        return Ok(());
    }

    println!(
        "The target has changed since {} was applied.",
        state
            .setup_stable_id
            .as_deref()
            .unwrap_or("the recorded setup")
    );
    println!("  recorded {}", short(&state.target_identity_digest));
    println!("  observed {}", short(&identity));
    println!();
    println!("This provider owns:");
    for namespace in harness.native_namespaces {
        let path = resolved.root().join(namespace);
        let mark = if path.exists() { "present" } else { "absent " };
        println!("  {mark}  {namespace}");
    }
    println!();
    println!("`reinstall` puts the recorded setup back. Everything else is left alone.");
    Ok(())
}

fn apply_setup(
    harness: &Harness,
    target: &Path,
    setup_id: &str,
    operation: Operation,
) -> Result<()> {
    let setup = catalog(harness)?.get(setup_id)?;
    setup.check_within(harness)?;
    let report = mutate(
        harness,
        target,
        operation,
        Effect::Materialize { setup: &setup },
        wire::Applied {
            setup_id: Some(setup_id.to_owned()),
            setup_definition_digest: Some(setup.definition_digest.clone()),
            ..wire::Applied::default()
        },
    )?;
    println!("Applied setup {setup_id} to {}.", target.display());
    // **The same sentence `remove` says, because an install does the same
    // thing.** `replace_managed_from` removes each owned namespace whole before
    // copying into it, so an install takes whatever a person kept under one --
    // and until now only `remove` said so. The correction reached the result
    // line of one verb, the plan preview of both, and not this line, which is
    // the one somebody reads after an install has already happened.
    for line in wire::taken_before_writing(harness, HUMAN_SCOPE) {
        println!("  {line}");
    }
    println!(
        "  previous state captured as {}",
        report_field(&report, "backup_ref")
    );
    println!(
        "  target identity now {}",
        short(&report_field(&report, "target_identity_digest"))
    );
    Ok(())
}

fn reinstall(harness: &Harness, target: &Path) -> Result<()> {
    let resolved = Target::resolve(target, harness.control_directory)?;
    let StateReading::Current(state) = ProviderState::read(resolved.root(), harness.state_file)?
    else {
        return Err(local(
            "nothing is recorded here to reinstall; use `install <setup>` to choose one",
        ));
    };
    let Some(setup_id) = state.setup_stable_id else {
        return Err(local(
            "the recorded state names no setup, so there is nothing to re-apply",
        ));
    };
    apply_setup(harness, target, &setup_id, Operation::Replace)
}

fn restore(harness: &Harness, target: &Path, backup: Option<String>) -> Result<()> {
    let named = backup.clone();
    let report = mutate(
        harness,
        target,
        Operation::Restore,
        Effect::Restore { backup_ref: backup },
        wire::Applied::default(),
    )?;
    match named {
        Some(reference) => println!("Restored {reference} into {}.", target.display()),
        None => println!("Restored the most recent backup into {}.", target.display()),
    }
    println!(
        "  state before this restore captured as {}",
        report_field(&report, "backup_ref")
    );
    Ok(())
}

fn remove(harness: &Harness, target: &Path) -> Result<()> {
    // **A removal with no record of its own is not this provider's removal.**
    // `remove_managed` walks the declared namespaces and takes each whole, which
    // is exactly right for a target this build wrote: the setup owns those
    // entries and the state file says so. On a target it never wrote, the same
    // walk empties somebody else's home while the report says "removed
    // everything <provider> owns" -- and it owned nothing here. Measured
    // 2026-09-02 on a target holding only a person's own `config.toml`,
    // `AGENTS.md` and `prompts/`: all three went, recoverable from the slot the
    // capture took, under a sentence that did not describe what happened.
    //
    // The scoped branch of `remove_managed` already refuses for the same
    // reason, in the same words -- *this build does not know what it wrote* --
    // and this is that refusal on the surface a person types. The wire is not
    // changed: a consumer's removal is authorized by a plan it made against a
    // target it installed, and its own flow writes state first.
    // Three answers, and the middle one is why this is not a flat refusal: a
    // target with nothing of ours on it is *already removed*, and saying so
    // quietly keeps a repeat from becoming an error where nothing happened.
    // The consumer chose this shape on 2026-09-02 and takes the same three
    // over the wire.
    let resolved = Target::resolve(target, harness.control_directory)?;
    match wire::classify_removal(harness, &resolved, HUMAN_SCOPE)? {
        wire::Removal::Recorded => {}
        wire::Removal::NothingHere => {
            println!(
                "Nothing to remove: {} has applied no setup at {}, and none of \
                 what it declares is here.",
                harness.provider_id,
                resolved.root().display()
            );
            return Ok(());
        }
        wire::Removal::WouldTakeUnrecorded(present) => {
            return Err(wire::unrecorded_removal_refusal(
                harness, &resolved, &present,
            ));
        }
    }
    let report = mutate(
        harness,
        target,
        Operation::Remove,
        Effect::Remove,
        wire::Applied::default(),
    )?;
    println!(
        "Removed everything {} owns from {}.",
        harness.provider_id,
        target.display()
    );
    // **Say what "owns" means, because the sentence above is true and is heard
    // wrong.** A person reads "removed everything it owns" as "removed the
    // files it installed". `remove_managed` walks `native_namespaces` and calls
    // `remove_dir_all` on each, so a namespace goes whole -- including whatever
    // the person put there themselves.
    //
    // It matters most where a declaration keeps a transition window open. Cursor
    // owns `plugins` *and* `plugins/local`; the bytes this provider writes are
    // all under the second, and `remove` takes the first, which is where a
    // marketplace plugin lives. Nothing is lost -- the capture named below runs
    // before the removal, over exactly these namespaces, and `restore` returns
    // them byte-exact -- but "nothing is lost" is only true if the person knows
    // to restore, and they only know if they are told what went.
    // One sentence, from the one place that owns it. This used to be a second
    // copy saying "the capture below" while the plan preview said "above" --
    // two wordings of one fact, each true only where it happened to be printed.
    for line in wire::taken_before_writing(harness, HUMAN_SCOPE) {
        println!("  {line}");
    }
    println!(
        "  previous state captured as {}",
        report_field(&report, "backup_ref")
    );
    println!("  restore it with:  restore --target {}", target.display());
    Ok(())
}

/// Take over a target the frozen estate's program still claims.
///
/// Everything that could refuse happens before anything is captured or moved:
/// the stamp is read, its schema and its directory are checked, every file it
/// claims is accounted for against what is on disk, and any path it names that
/// this provider does not own is a refusal rather than a silent partial claim.
fn adopt_target(harness: &Harness, target: &Path) -> Result<()> {
    let resolved = Target::resolve(target, harness.control_directory)?;
    let Some((stamp, found)) = adopt::read(harness, &resolved)? else {
        return Err(local(if harness.predecessor_state_file.is_empty() {
            format!(
                "{} had no module in the frozen estate, so there is no stamp to adopt",
                harness.product
            )
        } else {
            format!(
                "{} holds no {}; there is nothing to adopt",
                resolved.root().display(),
                harness.predecessor_state_file
            )
        }));
    };

    let outside = found.outside(harness);
    if !outside.is_empty() {
        return Err(local(format!(
            "{} claims {}, which {} does not own; adopting it would record ownership of files no              later operation of this provider would write, restore or remove",
            stamp.display(),
            outside.join(", "),
            harness.provider_id
        )));
    }

    if let Some(elsewhere) = found.written_elsewhere(&resolved) {
        println!(
            "This stamp was written for {elsewhere}, and is being adopted at {}.",
            resolved.root().display()
        );
        println!("  every path it claims is checked against this target, not that one");
    }

    let accounted = found.account_for(&resolved)?;
    println!(
        "{} wrote {} for setup {:?}, build {}.",
        found.product_name, harness.predecessor_state_file, found.setup_id, found.build_version
    );
    for (relative, claim) in &accounted {
        println!("  {:-8} {relative}", claim.as_str());
    }
    let changed = accounted
        .iter()
        .filter(|(_, claim)| *claim != adopt::Claim::Intact)
        .count();
    if changed > 0 {
        println!(
            "  {changed} of {} are not what the stamp recorded; they are adopted as they are, and              the backup below holds them",
            accounted.len()
        );
    }

    let report = mutate(
        harness,
        target,
        Operation::Install,
        Effect::Adopt {
            stamp: stamp.clone(),
        },
        wire::Applied {
            setup_id: Some(found.setup_id.clone()),
            ..wire::Applied::default()
        },
    )?;

    println!();
    println!(
        "{} now owns {}.",
        harness.provider_id,
        resolved.root().display()
    );
    println!(
        "  previous state captured as {}",
        report_field(&report, "backup_ref")
    );
    println!(
        "  the old stamp is kept at {}/adopted/{}",
        harness.control_directory, harness.predecessor_state_file
    );
    Ok(())
}

/// Build a plan and apply it through the one write path.
fn mutate(
    harness: &Harness,
    target: &Path,
    operation: Operation,
    effect: Effect<'_>,
    applied: wire::Applied,
) -> Result<serde_json::Value> {
    let resolved = Target::resolve(target, harness.control_directory)?;
    let identity =
        resolved.identity_of_owned(harness.owned_projection(None), &harness.not_our_identity())?;
    let build_digest = harness.build_digest()?;
    let profile = harness.projection_profile()?;
    let operation_id = operation_id(harness, &identity);

    // A restore names the state it will produce; every other operation must not.
    //
    // The slot is resolved *here*, at plan time, and pinned into the effect. It
    // has to be: applying a restore captures the current state first, so a
    // reference resolved after that capture would name the capture itself and
    // the restore would be a no-op. "The most recent backup" means the most
    // recent one that existed when the restore was asked for.
    let (effect, restore_target_digest) = if operation == Operation::Restore {
        let control = resolved.ensure_control_directory()?;
        let pool = Pool::open(&control, facts::BACKUP_SLOTS)?;
        let Effect::Restore { backup_ref } = &effect else {
            return Err(local("a restore effect is required to plan a restore"));
        };
        let record = wire::chosen_backup(&pool, backup_ref.as_deref())?;
        let digest = crate::setup_core::digest::of_tree(&pool.payload_of(&record.backup_ref)?)?;
        let pinned = record.backup_ref.as_str().to_owned();
        (
            Effect::Restore {
                backup_ref: Some(pinned),
            },
            Some(digest),
        )
    } else {
        (effect, None)
    };

    let artifact = PlanArtifact::new(PlanInputs {
        // No scope: the human surface is a person at a terminal, and a
        // scope is something a consumer resolves. Omitted rather than
        // guessed at `global`, because a plan that named a scope nobody
        // chose would be a fact invented by this side.
        target_scope: None,
        provider_id: harness.provider_id,
        provider_version: harness.version,
        provider_build_digest: &build_digest,
        // No release verified a locally invoked binary; recording the build
        // digest here says what ran without claiming a release it did not have.
        provider_release_digest: &build_digest,
        operation_id: &operation_id,
        operation,
        canonical_target: &resolved.root().to_string_lossy(),
        expected_target_digest: &identity,
        projection_profile_digest: &profile.digest,
        bundle: None,
        backup_ref: match &effect {
            Effect::Restore { backup_ref } => backup_ref.clone(),
            _ => None,
        },
        restore_target_digest,
        permission_profile: None,
        expires_at: &expiry::deadline_in(PLAN_WINDOW_SECONDS, SystemTime::now()),
        // The human surface drives configuration, never the product's own
        // install: that arrives over the wire, with artifacts somebody else
        // downloaded between planning and applying.
        software_artifacts: Vec::new(),
        // The human surface removes whole and carries no bundle, so no path
        // has a second sentence.
        end_state: Vec::new(),
        effects: effect_lines(harness, &effect, applied.setup_id.as_deref()),
    })?;
    let plan_digest = artifact.digest()?;
    let provenance = serde_json::to_value(&artifact)
        .map_err(|source| local(format!("the plan artifact cannot be encoded: {source}")))?;

    wire::perform(
        harness,
        target,
        &Mutation {
            // The human surface names no scope, so a removal here is the
            // `global` one. A person typing `remove --target <dir>` is
            // pointing at a product's home; a shared root arrives only
            // through a consumer, which is where the scope comes from.
            target_scope: None,
            operation,
            operation_id,
            plan_digest,
            expected_target_digest: identity,
            effect,
            provenance,
            applied,
        },
    )
}

/// The scope every human command operates under.
///
/// A person typing `install --target <dir>` is pointing at a product's own
/// configuration home; a shared root arrives only through a consumer, which is
/// where a scope comes from. Named rather than written as a bare `None` at each
/// call site so that the next scope-aware reader is a compile error rather than
/// a silent global answer -- which is the defect `owned_projection(scope)` was
/// given a parameter to turn into one.
const HUMAN_SCOPE: Option<crate::provider_v3::TargetScope> = None;

fn effect_lines(harness: &Harness, effect: &Effect<'_>, setup_id: Option<&str>) -> Vec<String> {
    let capture = "capture the current target into a new backup slot".to_owned();
    match effect {
        Effect::Backup => vec![capture],
        Effect::Remove => {
            // A count, where the result line four hundred lines above names
            // them. `wire::taken_before_writing` carries the words both say.
            let mut lines = vec![capture];
            lines.extend(wire::taken_before_writing(harness, HUMAN_SCOPE));
            lines
        }
        Effect::Adopt { stamp } => vec![
            capture,
            format!(
                "record {} as the setup this target holds, without writing one file of it",
                setup_id.unwrap_or("the setup the old stamp names")
            ),
            format!(
                "move {} into {}/adopted, where the old program no longer sees it",
                stamp.display(),
                harness.control_directory
            ),
        ],
        Effect::Restore { backup_ref } => vec![
            capture,
            match backup_ref {
                Some(reference) => format!("restore the target from {reference}"),
                None => "restore the target from the most recent backup".to_owned(),
            },
        ],
        // The human surface never builds one of these: a bundle arrives over the
        // wire, and the plan for it is made there.
        Effect::MaterializeBundle { files } => vec![
            capture,
            format!("write the {} files the bundle declares", files.len()),
        ],
        // Nor this one: the surviving bytes are packed by the consumer.
        Effect::RemoveKeeping { files } => {
            let mut lines = vec![capture];
            lines.extend(wire::taken_before_writing(harness, HUMAN_SCOPE));
            lines.push(format!(
                "leave {} declared files behind at the bytes the bundle carries",
                files.len()
            ));
            lines
        }
        Effect::Materialize { setup } => {
            // "over the entries this provider owns" is true and is heard as
            // "writes the setup's files". `replace_managed_from` removes each
            // owned namespace whole first, so the removal is named before the
            // write it precedes.
            let mut lines = vec![capture];
            lines.extend(wire::taken_before_writing(harness, HUMAN_SCOPE));
            lines.push(format!(
                "write setup {} into them",
                setup_id.unwrap_or(setup.manifest.id.as_str())
            ));
            lines
        }
    }
}

/// A stable identifier for one operation.
///
/// Derived from the harness, the target identity and the clock rather than a
/// random source: the same command against the same target at the same second
/// produces the same id, which makes a repeated invocation recognisable in a
/// journal rather than looking like a second operation.
fn operation_id(harness: &Harness, identity: &str) -> String {
    let seconds = SystemTime::now()
        .duration_since(SystemTime::UNIX_EPOCH)
        .map_or(0, |elapsed| elapsed.as_secs());
    let seed = format!("{}:{identity}:{seconds}", harness.provider_id);
    let digest = crate::setup_core::digest::of_bytes(seed.as_bytes());
    format!(
        "operation_{}",
        digest
            .trim_start_matches("sha256:")
            .get(..24)
            .unwrap_or("unknown")
    )
}

fn report_field(report: &serde_json::Value, name: &str) -> String {
    report
        .get(name)
        .and_then(serde_json::Value::as_str)
        .unwrap_or("(none)")
        .to_owned()
}

fn short(digest: &str) -> String {
    digest.get(..19).unwrap_or(digest).to_owned()
}

#[cfg(test)]
mod tests {
    #![allow(clippy::unwrap_used, clippy::panic)]

    /// `rollback` names its version and never infers one.
    ///
    /// There is no record of what was previous -- only what is on disk -- and
    /// these version strings do not order reliably: cursor's
    /// `2026.08.11-e8db854` sorts by string, not by release. Choosing "the one
    /// before" would invent an ordering the vendor never promised, and pointing
    /// a command at the wrong build is the class of mistake this program
    /// refuses everywhere else.
    #[test]
    fn rollback_requires_the_version_it_is_going_to() {
        let parsed = parse(["rollback", "--prefix", "/tmp/prefix"]).unwrap();
        assert_eq!(
            parsed,
            Command::Rollback {
                prefix: std::path::PathBuf::from("/tmp/prefix"),
                to: None
            }
        );
        let with = parse(["rollback", "--to", "1.2.2", "--prefix", "/tmp/prefix"]).unwrap();
        assert_eq!(
            with,
            Command::Rollback {
                prefix: std::path::PathBuf::from("/tmp/prefix"),
                to: Some("1.2.2".to_owned())
            }
        );
    }

    /// The two new flags belong to the two new commands and nowhere else.
    #[test]
    fn prefix_and_to_are_refused_on_commands_that_do_not_take_them() {
        for tokens in [
            vec![
                "install", "baseline", "--target", "/tmp/t", "--prefix", "/tmp/p",
            ],
            vec!["restore", "--target", "/tmp/t", "--to", "1.2.2"],
            vec!["status", "--target", "/tmp/t", "--to", "1.2.2"],
        ] {
            let error = parse(tokens.clone()).unwrap_err();
            assert!(
                error.detail().contains("is not an argument of"),
                "{tokens:?} was accepted: {}",
                error.detail()
            );
        }
    }

    /// Two different absences, and the wrong one is misleading.
    ///
    /// Pi's `software` is `Some` and its delivery is npm, so before this was
    /// separated `software --prefix` answered *no version of pi is installed
    /// under /tmp/x* -- which reads as an invitation to install one. This build
    /// cannot, and says so in the same words `plan-operation` uses.
    #[test]
    fn a_product_delivered_by_a_package_manager_says_so_rather_than_looking_empty() {
        let mut managed = crate::harness_runtime::wire::tests_support::TEST;
        managed.software = Some(crate::setup_core::software::Software {
            version: "1.0.0",
            command: "managed",
            delivery: crate::setup_core::software::Delivery::Manager {
                tool: "npm",
                reason: "its closure is resolved at install time",
            },
            unsupported: &[],
            previous: None,
        });
        assert!(!managed.installs_a_program());

        let error = declared_software(&managed).unwrap_err();
        assert!(error.detail().contains("npm"), "{}", error.detail());
        assert!(
            !error.detail().contains("no version"),
            "it read as an empty prefix: {}",
            error.detail()
        );

        // And a build that installs nothing at all is a third answer again.
        let mut none = crate::harness_runtime::wire::tests_support::TEST;
        none.software = None;
        assert!(!none.installs_a_program());
        assert!(
            declared_software(&none)
                .unwrap_err()
                .detail()
                .contains("does not install it")
        );
    }

    /// Both new commands take a program directory, and neither guesses one.
    #[test]
    fn software_and_rollback_require_a_prefix() {
        for name in ["software", "rollback"] {
            let error = parse([name]).unwrap_err();
            assert!(error.detail().contains("--prefix"), "{}", error.detail());
        }
    }

    use crate::harness_runtime::wire::tests_support::TEST;

    use super::*;

    #[test]
    fn every_mutating_command_requires_an_explicit_target() {
        for name in [
            "status",
            "install",
            "reinstall",
            "select",
            "backups",
            "restore",
            "remove",
            "adopt",
            "diff",
        ] {
            let tokens = if matches!(name, "install" | "select") {
                vec![name.to_owned(), "some-setup".to_owned()]
            } else {
                vec![name.to_owned()]
            };
            let error = parse(tokens).unwrap_err();
            assert!(error.detail().contains("--target"), "{name}: {error}");
        }
    }

    #[test]
    fn list_needs_no_target_because_it_reads_no_target() {
        assert_eq!(parse(["list"]).unwrap(), Command::List);
    }

    #[test]
    fn install_and_select_require_exactly_one_setup_name() {
        assert!(
            parse(["install", "--target", "/tmp/x"])
                .unwrap_err()
                .detail()
                .contains("setup name")
        );
        assert!(
            parse(["install", "a", "b", "--target", "/tmp/x"])
                .unwrap_err()
                .detail()
                .contains("one setup name")
        );
        assert_eq!(
            parse(["install", "safe", "--target", "/tmp/x"]).unwrap(),
            Command::Install {
                target: PathBuf::from("/tmp/x"),
                setup: "safe".to_owned()
            }
        );
    }

    #[test]
    fn commands_that_take_no_setup_refuse_one() {
        for name in ["reinstall", "remove", "diff", "backups", "status"] {
            let error = parse([name, "stray", "--target", "/tmp/x"]).unwrap_err();
            assert!(error.detail().contains("no setup name"), "{name}: {error}");
        }
    }

    #[test]
    fn only_restore_accepts_a_backup_reference() {
        assert_eq!(
            parse([
                "restore",
                "--target",
                "/tmp/x",
                "--backup",
                "slot-000000000002"
            ])
            .unwrap(),
            Command::Restore {
                target: PathBuf::from("/tmp/x"),
                backup: Some("slot-000000000002".to_owned())
            }
        );
        assert!(
            parse([
                "remove",
                "--target",
                "/tmp/x",
                "--backup",
                "slot-000000000002"
            ])
            .unwrap_err()
            .detail()
            .contains("--backup")
        );
    }

    #[test]
    fn restore_without_a_reference_means_the_most_recent() {
        assert_eq!(
            parse(["restore", "--target", "/tmp/x"]).unwrap(),
            Command::Restore {
                target: PathBuf::from("/tmp/x"),
                backup: None
            }
        );
    }

    #[test]
    fn an_unknown_flag_or_command_is_refused_rather_than_ignored() {
        assert!(
            parse(["status", "--target", "/tmp/x", "--force"])
                .unwrap_err()
                .detail()
                .contains("--force")
        );
        assert!(
            parse(["frobnicate"])
                .unwrap_err()
                .detail()
                .contains("not a command")
        );
        assert!(
            parse(Vec::<String>::new())
                .unwrap_err()
                .detail()
                .contains("no command")
        );
    }

    #[test]
    fn a_repeated_flag_is_refused_rather_than_last_one_winning() {
        let error = parse(["status", "--target", "/a", "--target", "/b"]).unwrap_err();
        assert!(error.detail().contains("twice"));
    }

    #[test]
    fn the_human_command_names_are_exactly_what_is_dispatched() {
        for name in [
            "list",
            "install",
            "reinstall",
            "select",
            "backups",
            "restore",
            "remove",
            "adopt",
            "diff",
        ] {
            assert!(
                is_human_command(name),
                "{name} is dispatched but not recognised"
            );
        }
        // `status` is served by both surfaces and is routed by its flags, not here.
        assert!(!is_human_command("status"));
        assert!(!is_human_command("provider-info"));
        assert!(!is_human_command("plan-operation"));
    }

    // ---- end to end, over a real catalog and a real target ----

    use std::fs;

    use crate::harness_runtime::catalog::{SETUP_MANIFEST, SETUP_PAYLOAD, SETUP_SCHEMA, SetupManifest};

    fn scratch(name: &str) -> PathBuf {
        let base =
            std::env::temp_dir().join(format!("harness-human-{name}-{}", std::process::id()));
        let _ = fs::remove_dir_all(&base);
        fs::create_dir_all(base.join("target")).unwrap();
        fs::canonicalize(&base).unwrap()
    }

    fn write_setup(catalog: &Path, id: &str, files: &[(&str, &str)]) {
        let directory = catalog.join(id);
        fs::create_dir_all(directory.join(SETUP_PAYLOAD)).unwrap();
        fs::write(
            directory.join(SETUP_MANIFEST),
            serde_json::to_vec(&SetupManifest {
                schema_version: SETUP_SCHEMA,
                id: id.to_owned(),
                description: format!("the {id} setup"),
                sources: Vec::new(),
            })
            .unwrap(),
        )
        .unwrap();
        for (relative, content) in files {
            let path = directory.join(SETUP_PAYLOAD).join(relative);
            if let Some(parent) = path.parent() {
                fs::create_dir_all(parent).unwrap();
            }
            fs::write(path, content).unwrap();
        }
    }

    /// A world with a catalog, a target, and one file the provider does not own.
    fn world(name: &str) -> (PathBuf, PathBuf) {
        let base = scratch(name);
        let catalog = base.join("setups");
        fs::create_dir_all(&catalog).unwrap();
        write_setup(
            &catalog,
            "baseline",
            &[("AGENTS.md", "# baseline\n"), ("settings.json", "{}")],
        );
        write_setup(&catalog, "minimal", &[("AGENTS.md", "# minimal\n")]);
        let target = base.join("target");
        fs::write(target.join("unrelated.txt"), "mine").unwrap();
        (catalog, target)
    }

    fn harness() -> Harness {
        crate::harness_runtime::wire::tests_support::TEST
    }

    /// The two human previews say what an operation takes, not how many.
    ///
    /// `remove`'s *result* line has named the namespaces since `0.0.24`; the
    /// preview beside it still printed a count, and `install`'s preview said
    /// *"write setup X over the entries this provider owns"* -- true, and heard
    /// as "writes the setup's files", while `replace_managed_from` removes each
    /// owned namespace whole before copying into it.
    ///
    /// Observed red against the shipped wording: the old `Remove` line held a
    /// number and no name, and the old `Materialize` line held no removal at
    /// all.
    #[test]
    fn the_preview_names_what_goes_before_it_names_what_arrives() {
        let facts = harness();

        let removal = effect_lines(&facts, &Effect::Remove, None).join("\n");
        for namespace in facts.native_namespaces {
            assert!(removal.contains(namespace), "{removal}");
        }
        assert!(removal.contains("whole, not file by file"), "{removal}");

        let (catalog, _) = world("preview-names-what-goes");
        let setup = setup_at(&catalog, "baseline");
        let writing = effect_lines(
            &facts,
            &Effect::Materialize { setup: &setup },
            Some("baseline"),
        );
        let text = writing.join("\n");
        assert!(text.contains("whole, not file by file"), "{text}");
        // And in that order: what goes, then what arrives.
        let removed = text.find("whole, not file by file").unwrap();
        let written = text.find("write setup baseline").unwrap();
        assert!(removed < written, "the write is announced first: {text}");
    }

    fn setup_at(catalog: &Path, id: &str) -> crate::harness_runtime::catalog::Setup {
        Catalog::at(catalog).get(id).unwrap()
    }

    fn install(catalog: &Path, target: &Path, id: &str, operation: Operation) {
        let setup = setup_at(catalog, id);
        mutate(
            &harness(),
            target,
            operation,
            Effect::Materialize { setup: &setup },
            wire::Applied {
                setup_id: Some(id.to_owned()),
                setup_definition_digest: Some(setup.definition_digest.clone()),
                ..wire::Applied::default()
            },
        )
        .unwrap();
    }

    #[test]
    fn installing_a_setup_writes_it_and_leaves_everything_else_alone() {
        let (catalog, target) = world("install");
        install(&catalog, &target, "baseline", Operation::Install);

        assert_eq!(
            fs::read_to_string(target.join("AGENTS.md")).unwrap(),
            "# baseline\n"
        );
        assert!(target.join("settings.json").exists());
        assert_eq!(
            fs::read_to_string(target.join("unrelated.txt")).unwrap(),
            "mine"
        );
    }

    #[test]
    fn a_setup_installed_into_an_otherwise_empty_target_becomes_its_identity() {
        // The strongest statement this design can make: a target holding nothing
        // but one setup *is* that setup, byte for byte. If these ever diverge,
        // either the materializer changed something on the way in or the digest
        // is measuring something other than what was written.
        let base = scratch("identity-equals-definition");
        let catalog = base.join("setups");
        fs::create_dir_all(&catalog).unwrap();
        write_setup(
            &catalog,
            "exact",
            &[("AGENTS.md", "# exact\n"), ("skills/a.md", "one")],
        );
        let target = base.join("target");

        let setup = setup_at(&catalog, "exact");
        mutate(
            &harness(),
            &target,
            Operation::Install,
            Effect::Materialize { setup: &setup },
            wire::Applied {
                setup_id: Some("exact".to_owned()),
                ..wire::Applied::default()
            },
        )
        .unwrap();

        let resolved = Target::resolve(&target, harness().control_directory).unwrap();
        let identity = resolved
            .identity_of_owned(
                harness().owned_projection(None),
                &harness().not_our_identity(),
            )
            .unwrap();
        assert_eq!(identity, setup.definition_digest);
    }

    #[test]
    fn selecting_another_setup_reaches_its_complete_state_not_a_merge() {
        // baseline ships settings.json and minimal does not, so after selecting
        // minimal that file must be gone. A merge would leave it behind, and the
        // target would then be a state neither setup describes.
        let (catalog, target) = world("select");
        install(&catalog, &target, "baseline", Operation::Install);
        assert!(target.join("settings.json").exists());

        install(&catalog, &target, "minimal", Operation::Replace);
        assert_eq!(
            fs::read_to_string(target.join("AGENTS.md")).unwrap(),
            "# minimal\n"
        );
        assert!(
            !target.join("settings.json").exists(),
            "select left a file minimal does not own"
        );
        assert_eq!(
            fs::read_to_string(target.join("unrelated.txt")).unwrap(),
            "mine"
        );
    }

    #[test]
    fn every_change_captures_what_was_there_before_it() {
        let (catalog, target) = world("captures");
        install(&catalog, &target, "baseline", Operation::Install);
        install(&catalog, &target, "minimal", Operation::Replace);

        let control = target.join(harness().control_directory);
        let records = Pool::open(&control, facts::BACKUP_SLOTS)
            .unwrap()
            .list()
            .unwrap();
        assert_eq!(records.len(), 2);
        // Newest first: the second capture preceded the replace and knew which
        // setup was applied at the time.
        assert_eq!(records[0].operation, "replace");
        assert_eq!(records[0].setup_id.as_deref(), Some("baseline"));
        assert_eq!(
            records[1].setup_id, None,
            "the first capture predates any setup"
        );
    }

    #[test]
    fn restoring_a_named_backup_reaches_the_state_that_backup_holds() {
        let (catalog, target) = world("restore-named");
        install(&catalog, &target, "baseline", Operation::Install);
        install(&catalog, &target, "minimal", Operation::Replace);

        // The first slot predates every install, so restoring it empties what we own.
        mutate(
            &harness(),
            &target,
            Operation::Restore,
            Effect::Restore {
                backup_ref: Some("slot-000000000001".to_owned()),
            },
            wire::Applied::default(),
        )
        .unwrap();
        assert!(!target.join("AGENTS.md").exists());
        assert!(!target.join("settings.json").exists());
        assert_eq!(
            fs::read_to_string(target.join("unrelated.txt")).unwrap(),
            "mine"
        );
    }

    /// Read the provider state a mutation left behind.
    fn state(target: &Path) -> crate::setup_core::stamp::ProviderState {
        match ProviderState::read(target, harness().state_file).unwrap() {
            StateReading::Current(current) => *current,
            other => panic!("no current state: {other:?}"),
        }
    }

    #[test]
    fn a_restore_names_the_setup_the_slot_it_restored_wrote_down() {
        // A restore returns exact bytes, and until this guard it returned them
        // anonymously: the slot records which setup was in effect when it was
        // captured, and the restore threw that away. `status` then said
        // "(unnamed)" about a target that was byte-for-byte a known setup.
        let (catalog, target) = world("restore-names-its-setup");
        install(&catalog, &target, "baseline", Operation::Install);
        let installed = state(&target);
        install(&catalog, &target, "minimal", Operation::Replace);

        mutate(
            &harness(),
            &target,
            Operation::Restore,
            Effect::Restore { backup_ref: None },
            wire::Applied::default(),
        )
        .unwrap();

        let restored = state(&target);
        assert_eq!(
            restored.target_identity_digest, installed.target_identity_digest,
            "the bytes must come back exactly"
        );
        assert_eq!(
            restored.setup_stable_id.as_deref(),
            Some("baseline"),
            "and so must the name the slot recorded"
        );
        assert_eq!(
            restored.setup_definition_digest, installed.setup_definition_digest,
            "and the definition it was identified by"
        );
    }

    #[test]
    fn restoring_without_a_reference_reaches_the_most_recent_capture() {
        let (catalog, target) = world("restore-latest");
        install(&catalog, &target, "baseline", Operation::Install);
        install(&catalog, &target, "minimal", Operation::Replace);

        mutate(
            &harness(),
            &target,
            Operation::Restore,
            Effect::Restore { backup_ref: None },
            wire::Applied::default(),
        )
        .unwrap();
        // The newest capture preceded the replace, so baseline comes back.
        assert_eq!(
            fs::read_to_string(target.join("AGENTS.md")).unwrap(),
            "# baseline\n"
        );
        assert!(target.join("settings.json").exists());
    }

    #[test]
    fn reinstall_repairs_a_hand_edit_without_being_told_which_setup() {
        let (catalog, target) = world("reinstall");
        install(&catalog, &target, "minimal", Operation::Install);
        fs::write(target.join("AGENTS.md"), "# edited by hand\n").unwrap();

        let recorded = match ProviderState::read(&target, harness().state_file).unwrap() {
            StateReading::Current(state) => state.setup_stable_id,
            other => panic!("expected recorded state, got {other:?}"),
        };
        assert_eq!(recorded.as_deref(), Some("minimal"));

        install(&catalog, &target, &recorded.unwrap(), Operation::Replace);
        assert_eq!(
            fs::read_to_string(target.join("AGENTS.md")).unwrap(),
            "# minimal\n"
        );
    }

    #[test]
    fn removing_withdraws_what_is_owned_and_keeps_what_is_not() {
        let (catalog, target) = world("remove");
        install(&catalog, &target, "baseline", Operation::Install);

        mutate(
            &harness(),
            &target,
            Operation::Remove,
            Effect::Remove,
            wire::Applied::default(),
        )
        .unwrap();
        assert!(!target.join("AGENTS.md").exists());
        assert!(!target.join("settings.json").exists());
        assert_eq!(
            fs::read_to_string(target.join("unrelated.txt")).unwrap(),
            "mine"
        );
    }

    #[test]
    fn a_setup_writing_outside_the_declared_surface_never_reaches_the_target() {
        let (catalog, target) = world("outside");
        write_setup(
            &catalog,
            "sneaky",
            &[("AGENTS.md", "x"), ("elsewhere.txt", "y")],
        );
        let setup = setup_at(&catalog, "sneaky");

        let error = mutate(
            &harness(),
            &target,
            Operation::Install,
            Effect::Materialize { setup: &setup },
            wire::Applied {
                setup_id: Some("sneaky".to_owned()),
                ..wire::Applied::default()
            },
        )
        .unwrap_err();
        assert_eq!(error.reason(), Some(WireReason::UnsupportedNativeSurface));
        assert!(!target.join("elsewhere.txt").exists());
        assert!(
            !target.join("AGENTS.md").exists(),
            "a refused setup wrote part of itself"
        );
    }

    #[test]
    fn the_state_records_which_setup_is_applied_so_reinstall_has_something_to_read() {
        let (catalog, target) = world("state");
        install(&catalog, &target, "baseline", Operation::Install);
        match ProviderState::read(&target, harness().state_file).unwrap() {
            StateReading::Current(state) => {
                assert_eq!(state.setup_stable_id.as_deref(), Some("baseline"));
                assert!(state.backup_ref.is_some());
            }
            other => panic!("expected recorded state, got {other:?}"),
        }
    }

    #[test]
    fn an_operation_id_is_stable_for_the_same_target_and_second() {
        let harness = crate::harness_runtime::wire::tests_support::TEST;
        let one = operation_id(&harness, "sha256:abc");
        let two = operation_id(&harness, "sha256:abc");
        assert_eq!(one, two);
        assert_ne!(one, operation_id(&harness, "sha256:def"));
        assert!(one.starts_with("operation_"));
    }

    // ── adoption ─────────────────────────────────────────────────────────────

    /// A target holding what the frozen estate's stamp claims.
    fn estate_managed(name: &str, files: &[(&str, &str)], claimed: &[(&str, &str)]) -> PathBuf {
        let target = std::env::temp_dir().join(format!("adopt-{name}-{}", std::process::id()));
        let _ = fs::remove_dir_all(&target);
        fs::create_dir_all(&target).unwrap();
        for (relative, body) in files {
            let at = target.join(relative);
            if let Some(parent) = at.parent() {
                fs::create_dir_all(parent).unwrap();
            }
            fs::write(at, body).unwrap();
        }
        let managed: serde_json::Map<String, serde_json::Value> = claimed
            .iter()
            .map(|(relative, hex)| ((*relative).to_owned(), serde_json::json!(hex)))
            .collect();
        fs::write(
            target.join(TEST.predecessor_state_file),
            serde_json::to_vec_pretty(&serde_json::json!({
                "schema_version": 1,
                "product_name": "nddev-test-app",
                "build_version": "0.1.0",
                "setup_id": "full-auto",
                "canonical_target": target.to_string_lossy(),
                "managed_files": managed,
            }))
            .unwrap(),
        )
        .unwrap();
        target
    }

    fn hex_of(body: &str) -> String {
        crate::setup_core::digest::of_bytes(body.as_bytes())
            .trim_start_matches(crate::setup_core::digest::PREFIX)
            .to_owned()
    }

    #[test]
    fn adopt_takes_over_a_target_the_old_program_still_claims() {
        let body = "# from the estate\n";
        let target = estate_managed(
            "takeover",
            &[("AGENTS.md", body)],
            &[("AGENTS.md", &hex_of(body))],
        );

        run(
            &TEST,
            Command::Adopt {
                target: target.clone(),
            },
        )
        .unwrap();

        // The setup the old stamp named is now what this provider records.
        let resolved = Target::resolve(&target, TEST.control_directory).unwrap();
        let StateReading::Current(state) =
            ProviderState::read(resolved.root(), TEST.state_file).unwrap()
        else {
            panic!("adoption left no state");
        };
        assert_eq!(state.setup_stable_id.as_deref(), Some("full-auto"));

        // The old program looks for its stamp at the top level and no longer
        // finds it — but nothing was destroyed.
        assert!(!target.join(TEST.predecessor_state_file).exists());
        assert!(
            target
                .join(TEST.control_directory)
                .join("adopted")
                .join(TEST.predecessor_state_file)
                .is_file()
        );

        // The file the stamp claimed is untouched: adoption changes who owns
        // the target, not what is in it.
        assert_eq!(fs::read_to_string(target.join("AGENTS.md")).unwrap(), body);

        let _ = fs::remove_dir_all(&target);
    }

    #[test]
    fn adopt_captures_the_state_it_took_over() {
        let body = "# before\n";
        let target = estate_managed(
            "captured",
            &[("AGENTS.md", body)],
            &[("AGENTS.md", &hex_of(body))],
        );
        run(
            &TEST,
            Command::Adopt {
                target: target.clone(),
            },
        )
        .unwrap();

        let resolved = Target::resolve(&target, TEST.control_directory).unwrap();
        let slots = resolved.root().join(TEST.control_directory).join("backups");
        let taken = fs::read_dir(&slots).map_or(0, Iterator::count);
        assert_eq!(taken, 1, "adoption captured nothing to return to");

        let _ = fs::remove_dir_all(&target);
    }

    #[test]
    fn a_stamp_claiming_what_this_provider_does_not_own_is_refused() {
        // Recording ownership of a path no later operation would write,
        // restore or remove is a claim this build could not keep.
        let target = estate_managed(
            "outside",
            &[("AGENTS.md", "x"), ("somebody-elses.toml", "y")],
            &[
                ("AGENTS.md", &hex_of("x")),
                ("somebody-elses.toml", &hex_of("y")),
            ],
        );
        let error = run(
            &TEST,
            Command::Adopt {
                target: target.clone(),
            },
        )
        .unwrap_err();
        assert!(
            error.detail().contains("somebody-elses.toml"),
            "{}",
            error.detail()
        );
        // Nothing was taken over, and the stamp is where it was.
        assert!(target.join(TEST.predecessor_state_file).is_file());
        let _ = fs::remove_dir_all(&target);
    }

    #[test]
    fn adopt_on_a_target_with_no_stamp_says_there_is_nothing_to_adopt() {
        let target = std::env::temp_dir().join(format!("adopt-none-{}", std::process::id()));
        let _ = fs::remove_dir_all(&target);
        fs::create_dir_all(&target).unwrap();
        let error = run(
            &TEST,
            Command::Adopt {
                target: target.clone(),
            },
        )
        .unwrap_err();
        assert!(
            error.detail().contains("nothing to adopt"),
            "{}",
            error.detail()
        );
        let _ = fs::remove_dir_all(&target);
    }

    #[test]
    fn a_harness_with_no_predecessor_says_so_rather_than_looking_for_a_file() {
        let mut fresh = TEST;
        fresh.predecessor_state_file = "";
        let target = std::env::temp_dir().join(format!("adopt-fresh-{}", std::process::id()));
        let _ = fs::remove_dir_all(&target);
        fs::create_dir_all(&target).unwrap();
        let error = run(
            &fresh,
            Command::Adopt {
                target: target.clone(),
            },
        )
        .unwrap_err();
        assert!(
            error.detail().contains("no module in the frozen estate"),
            "{}",
            error.detail()
        );
        let _ = fs::remove_dir_all(&target);
    }

    #[test]
    fn a_file_that_drifted_since_the_stamp_is_accounted_for_not_assumed() {
        // The estate's own digest is the only record of what it wrote. A file
        // that no longer matches is adopted as it is, and the backup holds it —
        // but the difference is stated rather than passed over.
        let target = estate_managed(
            "drifted",
            &[("AGENTS.md", "what is there now")],
            &[("AGENTS.md", &hex_of("what the estate wrote"))],
        );
        let resolved = Target::resolve(&target, TEST.control_directory).unwrap();
        let (_, found) = adopt::read(&TEST, &resolved).unwrap().unwrap();
        let accounted = found.account_for(&resolved).unwrap();
        assert_eq!(
            accounted,
            vec![("AGENTS.md".to_owned(), adopt::Claim::Changed)]
        );

        // And adoption still succeeds: it is a takeover, not a verification.
        run(
            &TEST,
            Command::Adopt {
                target: target.clone(),
            },
        )
        .unwrap();
        assert_eq!(
            fs::read_to_string(target.join("AGENTS.md")).unwrap(),
            "what is there now"
        );
        let _ = fs::remove_dir_all(&target);
    }

    // ── a populated home, through the whole lifecycle ────────────────────────

    /// Fingerprint a tree using nothing this program owns.
    ///
    /// `crate::setup_core::digest::of_tree` is what the provider itself uses to decide
    /// a target is unchanged, so comparing against it would be asking the same
    /// function twice and believing the answer. This walks with `std::fs` and
    /// hashes with `sha2` directly. A restore that returned *almost* the right
    /// tree — a mode dropped, an empty directory lost, a byte reordered — is
    /// caught here and would not be caught by the other.
    ///
    /// The provider's own bookkeeping is skipped: the control directory and the
    /// state file are this build's, not the target's, and they are supposed to
    /// appear.
    fn independent_fingerprint(root: &Path, harness: &Harness) -> String {
        fn walk(at: &Path, base: &Path, skip: &[&str], into: &mut Vec<String>) {
            let mut entries: Vec<_> = fs::read_dir(at)
                .unwrap()
                .map(|entry| entry.unwrap().path())
                .collect();
            entries.sort();
            for path in entries {
                let relative = path
                    .strip_prefix(base)
                    .unwrap()
                    .to_string_lossy()
                    .replace('\\', "/");
                if skip.iter().any(|name| relative == *name) {
                    continue;
                }
                let found = fs::symlink_metadata(&path).unwrap();
                if found.is_dir() {
                    into.push(format!("d {relative}"));
                    walk(&path, base, skip, into);
                } else if found.is_symlink() {
                    let to = fs::read_link(&path).unwrap();
                    into.push(format!("l {relative} -> {}", to.to_string_lossy()));
                } else {
                    let bytes = fs::read(&path).unwrap();
                    let readonly = found.permissions().readonly();
                    into.push(format!(
                        "f {relative} {} {} ro={readonly}",
                        bytes.len(),
                        crate::setup_core::digest::of_bytes(&bytes)
                    ));
                }
            }
        }
        let skip = [harness.control_directory, harness.state_file];
        let mut lines = Vec::new();
        walk(root, root, &skip, &mut lines);
        crate::setup_core::digest::of_bytes(lines.join("\n").as_bytes())
    }

    /// A target with the awkward content a real configuration home grows.
    fn populated(name: &str) -> (PathBuf, PathBuf) {
        let base = scratch(name);
        let catalog = base.join("setups");
        fs::create_dir_all(&catalog).unwrap();
        write_setup(
            &catalog,
            "baseline",
            &[("AGENTS.md", "# baseline\n"), ("settings.json", "{}")],
        );
        let target = base.join("target");

        // Inside what this provider owns.
        let deep = target.join("skills/one/two/three/four/five/six");
        fs::create_dir_all(&deep).unwrap();
        fs::write(deep.join("leaf.md"), "a long way down\n").unwrap();
        fs::write(target.join("skills/пример.md"), "имя не в ASCII\n").unwrap();
        fs::write(target.join("skills/empty.md"), b"").unwrap();
        // CRLF on purpose: a restore that normalized line endings would be
        // returning a different file and reporting success.
        fs::write(target.join("skills/crlf.md"), b"one\r\ntwo\r\n").unwrap();
        fs::write(target.join("skills/big.md"), vec![b'x'; 300_000]).unwrap();
        fs::create_dir_all(target.join("skills/an-empty-directory")).unwrap();
        fs::write(target.join("AGENTS.md"), "# what was here first\n").unwrap();

        // Beside it, and none of this provider's business.
        fs::write(target.join("unrelated.txt"), "mine").unwrap();
        fs::write(target.join(".credentials.json"), "SECRET").unwrap();
        fs::create_dir_all(target.join("sessions/2026")).unwrap();
        fs::write(target.join("sessions/2026/log.jsonl"), "{}\n").unwrap();

        (catalog, target)
    }

    #[test]
    fn a_populated_target_comes_back_byte_for_byte_after_a_restore() {
        let (catalog, target) = populated("populated-restore");
        let harness = harness();
        let before = independent_fingerprint(&target, &harness);

        install(&catalog, &target, "baseline", Operation::Install);

        // What the setup declares is now what is there, and the deep tree that
        // was in the same namespace is gone with it — that is what owning a
        // namespace means.
        assert_eq!(
            fs::read_to_string(target.join("AGENTS.md")).unwrap(),
            "# baseline\n"
        );
        assert!(!target.join("skills/one").exists());

        // Nothing outside those namespaces moved.
        assert_eq!(
            fs::read_to_string(target.join("unrelated.txt")).unwrap(),
            "mine"
        );
        assert_eq!(
            fs::read_to_string(target.join(".credentials.json")).unwrap(),
            "SECRET"
        );
        assert!(target.join("sessions/2026/log.jsonl").is_file());

        run(
            &harness,
            Command::Restore {
                target: target.clone(),
                backup: None,
            },
        )
        .unwrap();

        assert_eq!(
            independent_fingerprint(&target, &harness),
            before,
            "the restored target is not the one that was captured"
        );

        let _ = fs::remove_dir_all(target.parent().unwrap());
    }

    #[test]
    fn a_backup_never_holds_what_it_could_not_put_back() {
        // The slot is what a restore replays. A credential swept into one would
        // be a secret this program copied without being asked, and a restore
        // would then write it back over whatever the product had since stored.
        let (catalog, target) = populated("populated-slot");
        install(&catalog, &target, "baseline", Operation::Install);

        let slots = target.join(harness().control_directory).join("backups");
        let mut swept = Vec::new();
        for slot in fs::read_dir(&slots).unwrap() {
            let slot = slot.unwrap().path();
            if slot.is_dir() {
                for found in walkdir(&slot) {
                    let name = found.to_string_lossy().into_owned();
                    if name.contains("credentials") || name.contains("sessions") {
                        swept.push(name);
                    }
                }
            }
        }
        assert!(swept.is_empty(), "a backup slot holds {swept:?}");

        let _ = fs::remove_dir_all(target.parent().unwrap());
    }

    /// Every path under a root, for a test that needs to look at all of them.
    fn walkdir(root: &Path) -> Vec<PathBuf> {
        let mut found = Vec::new();
        let mut pending = vec![root.to_path_buf()];
        while let Some(at) = pending.pop() {
            let Ok(entries) = fs::read_dir(&at) else {
                continue;
            };
            for entry in entries.flatten() {
                let path = entry.path();
                if path.is_dir() {
                    pending.push(path.clone());
                }
                found.push(path);
            }
        }
        found
    }

    #[test]
    fn remove_takes_a_populated_namespace_and_leaves_the_rest() {
        let (catalog, target) = populated("populated-remove");
        let harness = harness();
        install(&catalog, &target, "baseline", Operation::Install);

        run(
            &harness,
            Command::Remove {
                target: target.clone(),
            },
        )
        .unwrap();

        for owned in ["AGENTS.md", "settings.json", "skills"] {
            assert!(
                !target.join(owned).exists(),
                "{owned} survived a remove that claims to own it"
            );
        }
        assert_eq!(
            fs::read_to_string(target.join("unrelated.txt")).unwrap(),
            "mine"
        );
        assert!(target.join("sessions/2026/log.jsonl").is_file());

        let _ = fs::remove_dir_all(target.parent().unwrap());
    }

    #[test]
    #[cfg(unix)]
    fn a_read_only_file_in_an_owned_namespace_is_still_replaced() {
        // A product, or a person, can leave a file unwritable. The namespace is
        // still this provider's to replace, and failing there would leave a
        // half-applied target behind a permission bit.
        use std::os::unix::fs::PermissionsExt;
        let (catalog, target) = populated("populated-readonly");
        let stubborn = target.join("skills/пример.md");
        fs::set_permissions(&stubborn, fs::Permissions::from_mode(0o444)).unwrap();

        install(&catalog, &target, "baseline", Operation::Install);
        assert!(!stubborn.exists(), "a read-only file blocked the install");

        let _ = fs::remove_dir_all(target.parent().unwrap());
    }
    /// A description a terminal can hold, broken where words end.
    #[test]
    fn a_long_description_is_wrapped_at_word_boundaries() {
        let text = "Full auto: nothing is asked and nothing is sandboxed. This is a \
                    setup posture -- keys in this product's own configuration file.";
        let lines = wrapped(text, 40);
        assert!(lines.len() > 1, "{lines:?}");
        for line in &lines {
            assert!(line.chars().count() <= 40, "{line:?}");
            assert!(!line.starts_with(' ') && !line.ends_with(' '), "{line:?}");
        }
        assert_eq!(
            lines.join(" "),
            text.split_whitespace().collect::<Vec<_>>().join(" "),
            "wrapping must not lose or invent a word"
        );
    }

    /// A word longer than the width is emitted whole.
    ///
    /// Cutting it would produce a broken URL, and a description that cites a
    /// vendor page is exactly where a long word appears.
    #[test]
    fn a_word_longer_than_the_width_is_not_cut() {
        let long = "https://learn.chatgpt.com/docs/config-file/config-reference";
        // Both positions, because they take different branches: a long word
        // that *starts* a line is pushed into an empty buffer, and one that
        // follows a word is pushed after the buffer is flushed. An earlier
        // version of this test asserted only the second, and a mutation that
        // truncated the first left it green.
        for text in [
            format!("see {long} for this"),
            format!("{long} is the page"),
        ] {
            let lines = wrapped(&text, 20);
            assert!(
                lines.iter().any(|line| line == long),
                "{text:?} became {lines:?}"
            );
        }
    }

    /// Nothing in, nothing out -- rather than one empty line.
    #[test]
    fn an_empty_description_wraps_to_nothing() {
        assert!(wrapped("", 40).is_empty());
        assert!(wrapped("   ", 40).is_empty());
    }
    /// `VERBS` is exactly what `into_command` accepts, both ways.
    ///
    /// A list beside a match is two expressions of one fact, and this project
    /// has paid for that five times. Here the match is the authority and the
    /// list is checked against it, so a verb added to one and not the other is
    /// red rather than merely inconsistent.
    #[test]
    fn the_named_verbs_are_the_ones_the_parser_takes() {
        for verb in VERBS {
            let refused = Arguments::scan(verb, &[])
                .unwrap()
                .into_command(verb)
                .is_err_and(|error| error.detail().contains("is not a command"));
            assert!(!refused, "{verb} is named and the parser does not know it");
        }
        // The other direction: anything not named must be refused as unknown,
        // rather than quietly parsed.
        for absent in [
            "migrate",
            "switch",
            "plan",
            "update",
            "install-cli",
            "software-status",
        ] {
            let error = Arguments::scan(absent, &[])
                .unwrap()
                .into_command(absent)
                .unwrap_err();
            assert!(
                error.detail().contains("is not a command"),
                "{absent} is not named and the parser did not refuse it as unknown: {}",
                error.detail()
            );
        }
    }
}