@mc-and-his-agents/loom-installer 0.1.25 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/package.json +1 -1
  2. package/payload/manifest.json +82 -82
  3. package/payload/plugin/loom/skills/shared/scripts/governance_surface.py +53 -0
  4. package/payload/plugin/loom/skills/shared/scripts/loom_check.py +149 -1
  5. package/payload/plugin/loom/skills/shared/scripts/loom_flow.py +12 -2
  6. package/payload/plugin/loom/skills/shared/scripts/loom_init.py +2 -0
  7. package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/governance_surface.py +53 -0
  8. package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/loom_check.py +149 -1
  9. package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/loom_flow.py +12 -2
  10. package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/loom_init.py +2 -0
  11. package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/governance_surface.py +53 -0
  12. package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/loom_check.py +149 -1
  13. package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/loom_flow.py +12 -2
  14. package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/loom_init.py +2 -0
  15. package/payload/skills/loom-init/.loom-runtime/shared/scripts/governance_surface.py +53 -0
  16. package/payload/skills/loom-init/.loom-runtime/shared/scripts/loom_check.py +149 -1
  17. package/payload/skills/loom-init/.loom-runtime/shared/scripts/loom_flow.py +12 -2
  18. package/payload/skills/loom-init/.loom-runtime/shared/scripts/loom_init.py +2 -0
  19. package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/governance_surface.py +53 -0
  20. package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_check.py +149 -1
  21. package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_flow.py +12 -2
  22. package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_init.py +2 -0
  23. package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/governance_surface.py +53 -0
  24. package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_check.py +149 -1
  25. package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_flow.py +12 -2
  26. package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_init.py +2 -0
  27. package/payload/skills/loom-resume/.loom-runtime/shared/scripts/governance_surface.py +53 -0
  28. package/payload/skills/loom-resume/.loom-runtime/shared/scripts/loom_check.py +149 -1
  29. package/payload/skills/loom-resume/.loom-runtime/shared/scripts/loom_flow.py +12 -2
  30. package/payload/skills/loom-resume/.loom-runtime/shared/scripts/loom_init.py +2 -0
  31. package/payload/skills/loom-retire/.loom-runtime/shared/scripts/governance_surface.py +53 -0
  32. package/payload/skills/loom-retire/.loom-runtime/shared/scripts/loom_check.py +149 -1
  33. package/payload/skills/loom-retire/.loom-runtime/shared/scripts/loom_flow.py +12 -2
  34. package/payload/skills/loom-retire/.loom-runtime/shared/scripts/loom_init.py +2 -0
  35. package/payload/skills/loom-review/.loom-runtime/shared/scripts/governance_surface.py +53 -0
  36. package/payload/skills/loom-review/.loom-runtime/shared/scripts/loom_check.py +149 -1
  37. package/payload/skills/loom-review/.loom-runtime/shared/scripts/loom_flow.py +12 -2
  38. package/payload/skills/loom-review/.loom-runtime/shared/scripts/loom_init.py +2 -0
  39. package/payload/skills/loom-spec-review/.loom-runtime/shared/scripts/governance_surface.py +53 -0
  40. package/payload/skills/loom-spec-review/.loom-runtime/shared/scripts/loom_check.py +149 -1
  41. package/payload/skills/loom-spec-review/.loom-runtime/shared/scripts/loom_flow.py +12 -2
  42. package/payload/skills/loom-spec-review/.loom-runtime/shared/scripts/loom_init.py +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mc-and-his-agents/loom-installer",
3
- "version": "0.1.25",
3
+ "version": "0.1.27",
4
4
  "description": "Node installer for Loom plugin and single-skill installation surfaces.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,9 +2,9 @@
2
2
  "schema_version": "loom-installer-payload/v1",
3
3
  "loom_version": "0.4.0",
4
4
  "source_repository": "https://github.com/MC-and-his-Agents/Loom",
5
- "source_commit": "b3b72c7a74674319f0a7432487fc0e3cbf012b4f",
5
+ "source_commit": "72c484aa09e0c62361ba56aeeec319851468d5e8",
6
6
  "source_ref": "main",
7
- "built_at": "2026-04-26T23:56:30+08:00",
7
+ "built_at": "2026-04-27T00:39:19+08:00",
8
8
  "runtime": {
9
9
  "python_minimum": "3.10",
10
10
  "python_recommended": "3.11+"
@@ -623,23 +623,23 @@
623
623
  },
624
624
  {
625
625
  "path": "plugin/loom/skills/shared/scripts/governance_surface.py",
626
- "bytes": 53833,
627
- "sha256": "d12f21d009a5127a4b0aba70bc23e111a51a490017879ee59d51c22db65b5f0a"
626
+ "bytes": 56137,
627
+ "sha256": "2f873ee4ddd170af4a835da24bafa59f6e5561ee74360faf71e98e8480100a72"
628
628
  },
629
629
  {
630
630
  "path": "plugin/loom/skills/shared/scripts/loom_check.py",
631
- "bytes": 287428,
632
- "sha256": "48bf635cb9fb4f28b38309a81ecb67a48b489d72f83c4907d972230481848ddb"
631
+ "bytes": 296087,
632
+ "sha256": "1acd2461b1150b9d4c328571c849556e1b3b36dd9595254643aa046367b66009"
633
633
  },
634
634
  {
635
635
  "path": "plugin/loom/skills/shared/scripts/loom_flow.py",
636
- "bytes": 296151,
637
- "sha256": "f74afa96460de82ef279ec78a0468906ca1db26b867a4fc810025164ae8f7146"
636
+ "bytes": 296657,
637
+ "sha256": "7d4f476d8117a6b9d264a71f8300f229bf511dd9e1fb2b29636990c16c6d197d"
638
638
  },
639
639
  {
640
640
  "path": "plugin/loom/skills/shared/scripts/loom_init.py",
641
- "bytes": 85225,
642
- "sha256": "fc819d8172a1525c4fb86cbee680110c655101b6d6db7471a4d6c50d5c0bc1fc"
641
+ "bytes": 85311,
642
+ "sha256": "8fc0f350f55fa068b4b69854fb81f3b45fbace5bf384f900a63aeb9adfd87c1b"
643
643
  },
644
644
  {
645
645
  "path": "plugin/loom/skills/shared/scripts/loom_status.py",
@@ -1208,23 +1208,23 @@
1208
1208
  },
1209
1209
  {
1210
1210
  "path": "skills/loom-adopt/.loom-runtime/shared/scripts/governance_surface.py",
1211
- "bytes": 53833,
1212
- "sha256": "d12f21d009a5127a4b0aba70bc23e111a51a490017879ee59d51c22db65b5f0a"
1211
+ "bytes": 56137,
1212
+ "sha256": "2f873ee4ddd170af4a835da24bafa59f6e5561ee74360faf71e98e8480100a72"
1213
1213
  },
1214
1214
  {
1215
1215
  "path": "skills/loom-adopt/.loom-runtime/shared/scripts/loom_check.py",
1216
- "bytes": 287428,
1217
- "sha256": "48bf635cb9fb4f28b38309a81ecb67a48b489d72f83c4907d972230481848ddb"
1216
+ "bytes": 296087,
1217
+ "sha256": "1acd2461b1150b9d4c328571c849556e1b3b36dd9595254643aa046367b66009"
1218
1218
  },
1219
1219
  {
1220
1220
  "path": "skills/loom-adopt/.loom-runtime/shared/scripts/loom_flow.py",
1221
- "bytes": 296151,
1222
- "sha256": "f74afa96460de82ef279ec78a0468906ca1db26b867a4fc810025164ae8f7146"
1221
+ "bytes": 296657,
1222
+ "sha256": "7d4f476d8117a6b9d264a71f8300f229bf511dd9e1fb2b29636990c16c6d197d"
1223
1223
  },
1224
1224
  {
1225
1225
  "path": "skills/loom-adopt/.loom-runtime/shared/scripts/loom_init.py",
1226
- "bytes": 85225,
1227
- "sha256": "fc819d8172a1525c4fb86cbee680110c655101b6d6db7471a4d6c50d5c0bc1fc"
1226
+ "bytes": 85311,
1227
+ "sha256": "8fc0f350f55fa068b4b69854fb81f3b45fbace5bf384f900a63aeb9adfd87c1b"
1228
1228
  },
1229
1229
  {
1230
1230
  "path": "skills/loom-adopt/.loom-runtime/shared/scripts/loom_status.py",
@@ -1823,23 +1823,23 @@
1823
1823
  },
1824
1824
  {
1825
1825
  "path": "skills/loom-handoff/.loom-runtime/shared/scripts/governance_surface.py",
1826
- "bytes": 53833,
1827
- "sha256": "d12f21d009a5127a4b0aba70bc23e111a51a490017879ee59d51c22db65b5f0a"
1826
+ "bytes": 56137,
1827
+ "sha256": "2f873ee4ddd170af4a835da24bafa59f6e5561ee74360faf71e98e8480100a72"
1828
1828
  },
1829
1829
  {
1830
1830
  "path": "skills/loom-handoff/.loom-runtime/shared/scripts/loom_check.py",
1831
- "bytes": 287428,
1832
- "sha256": "48bf635cb9fb4f28b38309a81ecb67a48b489d72f83c4907d972230481848ddb"
1831
+ "bytes": 296087,
1832
+ "sha256": "1acd2461b1150b9d4c328571c849556e1b3b36dd9595254643aa046367b66009"
1833
1833
  },
1834
1834
  {
1835
1835
  "path": "skills/loom-handoff/.loom-runtime/shared/scripts/loom_flow.py",
1836
- "bytes": 296151,
1837
- "sha256": "f74afa96460de82ef279ec78a0468906ca1db26b867a4fc810025164ae8f7146"
1836
+ "bytes": 296657,
1837
+ "sha256": "7d4f476d8117a6b9d264a71f8300f229bf511dd9e1fb2b29636990c16c6d197d"
1838
1838
  },
1839
1839
  {
1840
1840
  "path": "skills/loom-handoff/.loom-runtime/shared/scripts/loom_init.py",
1841
- "bytes": 85225,
1842
- "sha256": "fc819d8172a1525c4fb86cbee680110c655101b6d6db7471a4d6c50d5c0bc1fc"
1841
+ "bytes": 85311,
1842
+ "sha256": "8fc0f350f55fa068b4b69854fb81f3b45fbace5bf384f900a63aeb9adfd87c1b"
1843
1843
  },
1844
1844
  {
1845
1845
  "path": "skills/loom-handoff/.loom-runtime/shared/scripts/loom_status.py",
@@ -2438,23 +2438,23 @@
2438
2438
  },
2439
2439
  {
2440
2440
  "path": "skills/loom-init/.loom-runtime/shared/scripts/governance_surface.py",
2441
- "bytes": 53833,
2442
- "sha256": "d12f21d009a5127a4b0aba70bc23e111a51a490017879ee59d51c22db65b5f0a"
2441
+ "bytes": 56137,
2442
+ "sha256": "2f873ee4ddd170af4a835da24bafa59f6e5561ee74360faf71e98e8480100a72"
2443
2443
  },
2444
2444
  {
2445
2445
  "path": "skills/loom-init/.loom-runtime/shared/scripts/loom_check.py",
2446
- "bytes": 287428,
2447
- "sha256": "48bf635cb9fb4f28b38309a81ecb67a48b489d72f83c4907d972230481848ddb"
2446
+ "bytes": 296087,
2447
+ "sha256": "1acd2461b1150b9d4c328571c849556e1b3b36dd9595254643aa046367b66009"
2448
2448
  },
2449
2449
  {
2450
2450
  "path": "skills/loom-init/.loom-runtime/shared/scripts/loom_flow.py",
2451
- "bytes": 296151,
2452
- "sha256": "f74afa96460de82ef279ec78a0468906ca1db26b867a4fc810025164ae8f7146"
2451
+ "bytes": 296657,
2452
+ "sha256": "7d4f476d8117a6b9d264a71f8300f229bf511dd9e1fb2b29636990c16c6d197d"
2453
2453
  },
2454
2454
  {
2455
2455
  "path": "skills/loom-init/.loom-runtime/shared/scripts/loom_init.py",
2456
- "bytes": 85225,
2457
- "sha256": "fc819d8172a1525c4fb86cbee680110c655101b6d6db7471a4d6c50d5c0bc1fc"
2456
+ "bytes": 85311,
2457
+ "sha256": "8fc0f350f55fa068b4b69854fb81f3b45fbace5bf384f900a63aeb9adfd87c1b"
2458
2458
  },
2459
2459
  {
2460
2460
  "path": "skills/loom-init/.loom-runtime/shared/scripts/loom_status.py",
@@ -3058,23 +3058,23 @@
3058
3058
  },
3059
3059
  {
3060
3060
  "path": "skills/loom-merge-ready/.loom-runtime/shared/scripts/governance_surface.py",
3061
- "bytes": 53833,
3062
- "sha256": "d12f21d009a5127a4b0aba70bc23e111a51a490017879ee59d51c22db65b5f0a"
3061
+ "bytes": 56137,
3062
+ "sha256": "2f873ee4ddd170af4a835da24bafa59f6e5561ee74360faf71e98e8480100a72"
3063
3063
  },
3064
3064
  {
3065
3065
  "path": "skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_check.py",
3066
- "bytes": 287428,
3067
- "sha256": "48bf635cb9fb4f28b38309a81ecb67a48b489d72f83c4907d972230481848ddb"
3066
+ "bytes": 296087,
3067
+ "sha256": "1acd2461b1150b9d4c328571c849556e1b3b36dd9595254643aa046367b66009"
3068
3068
  },
3069
3069
  {
3070
3070
  "path": "skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_flow.py",
3071
- "bytes": 296151,
3072
- "sha256": "f74afa96460de82ef279ec78a0468906ca1db26b867a4fc810025164ae8f7146"
3071
+ "bytes": 296657,
3072
+ "sha256": "7d4f476d8117a6b9d264a71f8300f229bf511dd9e1fb2b29636990c16c6d197d"
3073
3073
  },
3074
3074
  {
3075
3075
  "path": "skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_init.py",
3076
- "bytes": 85225,
3077
- "sha256": "fc819d8172a1525c4fb86cbee680110c655101b6d6db7471a4d6c50d5c0bc1fc"
3076
+ "bytes": 85311,
3077
+ "sha256": "8fc0f350f55fa068b4b69854fb81f3b45fbace5bf384f900a63aeb9adfd87c1b"
3078
3078
  },
3079
3079
  {
3080
3080
  "path": "skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_status.py",
@@ -3673,23 +3673,23 @@
3673
3673
  },
3674
3674
  {
3675
3675
  "path": "skills/loom-pre-review/.loom-runtime/shared/scripts/governance_surface.py",
3676
- "bytes": 53833,
3677
- "sha256": "d12f21d009a5127a4b0aba70bc23e111a51a490017879ee59d51c22db65b5f0a"
3676
+ "bytes": 56137,
3677
+ "sha256": "2f873ee4ddd170af4a835da24bafa59f6e5561ee74360faf71e98e8480100a72"
3678
3678
  },
3679
3679
  {
3680
3680
  "path": "skills/loom-pre-review/.loom-runtime/shared/scripts/loom_check.py",
3681
- "bytes": 287428,
3682
- "sha256": "48bf635cb9fb4f28b38309a81ecb67a48b489d72f83c4907d972230481848ddb"
3681
+ "bytes": 296087,
3682
+ "sha256": "1acd2461b1150b9d4c328571c849556e1b3b36dd9595254643aa046367b66009"
3683
3683
  },
3684
3684
  {
3685
3685
  "path": "skills/loom-pre-review/.loom-runtime/shared/scripts/loom_flow.py",
3686
- "bytes": 296151,
3687
- "sha256": "f74afa96460de82ef279ec78a0468906ca1db26b867a4fc810025164ae8f7146"
3686
+ "bytes": 296657,
3687
+ "sha256": "7d4f476d8117a6b9d264a71f8300f229bf511dd9e1fb2b29636990c16c6d197d"
3688
3688
  },
3689
3689
  {
3690
3690
  "path": "skills/loom-pre-review/.loom-runtime/shared/scripts/loom_init.py",
3691
- "bytes": 85225,
3692
- "sha256": "fc819d8172a1525c4fb86cbee680110c655101b6d6db7471a4d6c50d5c0bc1fc"
3691
+ "bytes": 85311,
3692
+ "sha256": "8fc0f350f55fa068b4b69854fb81f3b45fbace5bf384f900a63aeb9adfd87c1b"
3693
3693
  },
3694
3694
  {
3695
3695
  "path": "skills/loom-pre-review/.loom-runtime/shared/scripts/loom_status.py",
@@ -4288,23 +4288,23 @@
4288
4288
  },
4289
4289
  {
4290
4290
  "path": "skills/loom-resume/.loom-runtime/shared/scripts/governance_surface.py",
4291
- "bytes": 53833,
4292
- "sha256": "d12f21d009a5127a4b0aba70bc23e111a51a490017879ee59d51c22db65b5f0a"
4291
+ "bytes": 56137,
4292
+ "sha256": "2f873ee4ddd170af4a835da24bafa59f6e5561ee74360faf71e98e8480100a72"
4293
4293
  },
4294
4294
  {
4295
4295
  "path": "skills/loom-resume/.loom-runtime/shared/scripts/loom_check.py",
4296
- "bytes": 287428,
4297
- "sha256": "48bf635cb9fb4f28b38309a81ecb67a48b489d72f83c4907d972230481848ddb"
4296
+ "bytes": 296087,
4297
+ "sha256": "1acd2461b1150b9d4c328571c849556e1b3b36dd9595254643aa046367b66009"
4298
4298
  },
4299
4299
  {
4300
4300
  "path": "skills/loom-resume/.loom-runtime/shared/scripts/loom_flow.py",
4301
- "bytes": 296151,
4302
- "sha256": "f74afa96460de82ef279ec78a0468906ca1db26b867a4fc810025164ae8f7146"
4301
+ "bytes": 296657,
4302
+ "sha256": "7d4f476d8117a6b9d264a71f8300f229bf511dd9e1fb2b29636990c16c6d197d"
4303
4303
  },
4304
4304
  {
4305
4305
  "path": "skills/loom-resume/.loom-runtime/shared/scripts/loom_init.py",
4306
- "bytes": 85225,
4307
- "sha256": "fc819d8172a1525c4fb86cbee680110c655101b6d6db7471a4d6c50d5c0bc1fc"
4306
+ "bytes": 85311,
4307
+ "sha256": "8fc0f350f55fa068b4b69854fb81f3b45fbace5bf384f900a63aeb9adfd87c1b"
4308
4308
  },
4309
4309
  {
4310
4310
  "path": "skills/loom-resume/.loom-runtime/shared/scripts/loom_status.py",
@@ -4903,23 +4903,23 @@
4903
4903
  },
4904
4904
  {
4905
4905
  "path": "skills/loom-retire/.loom-runtime/shared/scripts/governance_surface.py",
4906
- "bytes": 53833,
4907
- "sha256": "d12f21d009a5127a4b0aba70bc23e111a51a490017879ee59d51c22db65b5f0a"
4906
+ "bytes": 56137,
4907
+ "sha256": "2f873ee4ddd170af4a835da24bafa59f6e5561ee74360faf71e98e8480100a72"
4908
4908
  },
4909
4909
  {
4910
4910
  "path": "skills/loom-retire/.loom-runtime/shared/scripts/loom_check.py",
4911
- "bytes": 287428,
4912
- "sha256": "48bf635cb9fb4f28b38309a81ecb67a48b489d72f83c4907d972230481848ddb"
4911
+ "bytes": 296087,
4912
+ "sha256": "1acd2461b1150b9d4c328571c849556e1b3b36dd9595254643aa046367b66009"
4913
4913
  },
4914
4914
  {
4915
4915
  "path": "skills/loom-retire/.loom-runtime/shared/scripts/loom_flow.py",
4916
- "bytes": 296151,
4917
- "sha256": "f74afa96460de82ef279ec78a0468906ca1db26b867a4fc810025164ae8f7146"
4916
+ "bytes": 296657,
4917
+ "sha256": "7d4f476d8117a6b9d264a71f8300f229bf511dd9e1fb2b29636990c16c6d197d"
4918
4918
  },
4919
4919
  {
4920
4920
  "path": "skills/loom-retire/.loom-runtime/shared/scripts/loom_init.py",
4921
- "bytes": 85225,
4922
- "sha256": "fc819d8172a1525c4fb86cbee680110c655101b6d6db7471a4d6c50d5c0bc1fc"
4921
+ "bytes": 85311,
4922
+ "sha256": "8fc0f350f55fa068b4b69854fb81f3b45fbace5bf384f900a63aeb9adfd87c1b"
4923
4923
  },
4924
4924
  {
4925
4925
  "path": "skills/loom-retire/.loom-runtime/shared/scripts/loom_status.py",
@@ -5518,23 +5518,23 @@
5518
5518
  },
5519
5519
  {
5520
5520
  "path": "skills/loom-review/.loom-runtime/shared/scripts/governance_surface.py",
5521
- "bytes": 53833,
5522
- "sha256": "d12f21d009a5127a4b0aba70bc23e111a51a490017879ee59d51c22db65b5f0a"
5521
+ "bytes": 56137,
5522
+ "sha256": "2f873ee4ddd170af4a835da24bafa59f6e5561ee74360faf71e98e8480100a72"
5523
5523
  },
5524
5524
  {
5525
5525
  "path": "skills/loom-review/.loom-runtime/shared/scripts/loom_check.py",
5526
- "bytes": 287428,
5527
- "sha256": "48bf635cb9fb4f28b38309a81ecb67a48b489d72f83c4907d972230481848ddb"
5526
+ "bytes": 296087,
5527
+ "sha256": "1acd2461b1150b9d4c328571c849556e1b3b36dd9595254643aa046367b66009"
5528
5528
  },
5529
5529
  {
5530
5530
  "path": "skills/loom-review/.loom-runtime/shared/scripts/loom_flow.py",
5531
- "bytes": 296151,
5532
- "sha256": "f74afa96460de82ef279ec78a0468906ca1db26b867a4fc810025164ae8f7146"
5531
+ "bytes": 296657,
5532
+ "sha256": "7d4f476d8117a6b9d264a71f8300f229bf511dd9e1fb2b29636990c16c6d197d"
5533
5533
  },
5534
5534
  {
5535
5535
  "path": "skills/loom-review/.loom-runtime/shared/scripts/loom_init.py",
5536
- "bytes": 85225,
5537
- "sha256": "fc819d8172a1525c4fb86cbee680110c655101b6d6db7471a4d6c50d5c0bc1fc"
5536
+ "bytes": 85311,
5537
+ "sha256": "8fc0f350f55fa068b4b69854fb81f3b45fbace5bf384f900a63aeb9adfd87c1b"
5538
5538
  },
5539
5539
  {
5540
5540
  "path": "skills/loom-review/.loom-runtime/shared/scripts/loom_status.py",
@@ -6133,23 +6133,23 @@
6133
6133
  },
6134
6134
  {
6135
6135
  "path": "skills/loom-spec-review/.loom-runtime/shared/scripts/governance_surface.py",
6136
- "bytes": 53833,
6137
- "sha256": "d12f21d009a5127a4b0aba70bc23e111a51a490017879ee59d51c22db65b5f0a"
6136
+ "bytes": 56137,
6137
+ "sha256": "2f873ee4ddd170af4a835da24bafa59f6e5561ee74360faf71e98e8480100a72"
6138
6138
  },
6139
6139
  {
6140
6140
  "path": "skills/loom-spec-review/.loom-runtime/shared/scripts/loom_check.py",
6141
- "bytes": 287428,
6142
- "sha256": "48bf635cb9fb4f28b38309a81ecb67a48b489d72f83c4907d972230481848ddb"
6141
+ "bytes": 296087,
6142
+ "sha256": "1acd2461b1150b9d4c328571c849556e1b3b36dd9595254643aa046367b66009"
6143
6143
  },
6144
6144
  {
6145
6145
  "path": "skills/loom-spec-review/.loom-runtime/shared/scripts/loom_flow.py",
6146
- "bytes": 296151,
6147
- "sha256": "f74afa96460de82ef279ec78a0468906ca1db26b867a4fc810025164ae8f7146"
6146
+ "bytes": 296657,
6147
+ "sha256": "7d4f476d8117a6b9d264a71f8300f229bf511dd9e1fb2b29636990c16c6d197d"
6148
6148
  },
6149
6149
  {
6150
6150
  "path": "skills/loom-spec-review/.loom-runtime/shared/scripts/loom_init.py",
6151
- "bytes": 85225,
6152
- "sha256": "fc819d8172a1525c4fb86cbee680110c655101b6d6db7471a4d6c50d5c0bc1fc"
6151
+ "bytes": 85311,
6152
+ "sha256": "8fc0f350f55fa068b4b69854fb81f3b45fbace5bf384f900a63aeb9adfd87c1b"
6153
6153
  },
6154
6154
  {
6155
6155
  "path": "skills/loom-spec-review/.loom-runtime/shared/scripts/loom_status.py",
@@ -252,6 +252,58 @@ MATURITY_REQUIRED_FIELDS = {
252
252
  },
253
253
  ],
254
254
  }
255
+ ADOPTION_GATE_ROLLOUT_MODES = {
256
+ "advisory": {
257
+ "summary": "Default mode for newly adopted repositories; Loom reports gate signals without becoming the blocking authority.",
258
+ "blocking": False,
259
+ },
260
+ "blocking": {
261
+ "summary": "Explicit opt-in mode for strong governance repositories after adversarial adoption checks pass.",
262
+ "blocking": True,
263
+ },
264
+ "rollback": {
265
+ "summary": "Emergency switch back to advisory consumption when runtime, evidence, or host bindings drift.",
266
+ "blocking": False,
267
+ },
268
+ }
269
+
270
+
271
+ def adoption_gate_rollout_status(*, maturity_current: str) -> dict[str, Any]:
272
+ blocking_preconditions = [
273
+ {
274
+ "id": "strong_maturity",
275
+ "status": "pass" if maturity_current == "strong" else "missing",
276
+ "layer": "github-profile",
277
+ "recommended_action": "upgrade the repository to strong maturity before enabling blocking gates",
278
+ },
279
+ {
280
+ "id": "adversarial_adoption_checks",
281
+ "status": "missing",
282
+ "layer": "core",
283
+ "recommended_action": "run the Loom-owned Syvert-style adversarial adoption fixture and record the validation evidence",
284
+ },
285
+ {
286
+ "id": "rollback_switch",
287
+ "status": "pass",
288
+ "layer": "core",
289
+ "recommended_action": "keep rollback available by switching gate mode back to advisory and rerunning governance-profile status",
290
+ },
291
+ ]
292
+ blocking_allowed = all(entry["status"] == "pass" for entry in blocking_preconditions)
293
+ return {
294
+ "schema_version": "loom-adoption-gate-rollout/v1",
295
+ "default_mode": "advisory",
296
+ "current_mode": "advisory",
297
+ "recommended_mode": "blocking" if blocking_allowed else "advisory",
298
+ "allowed_modes": ADOPTION_GATE_ROLLOUT_MODES,
299
+ "blocking_allowed": blocking_allowed,
300
+ "blocking_preconditions": blocking_preconditions,
301
+ "rollback": {
302
+ "mode": "rollback",
303
+ "switch_to": "advisory",
304
+ "recommended_action": "disable blocking consumption, preserve evidence, repair drift, then rerun adversarial adoption checks before re-enabling blocking",
305
+ },
306
+ }
255
307
 
256
308
 
257
309
  def run_process(args: list[str], cwd: Path) -> subprocess.CompletedProcess[str]:
@@ -1209,6 +1261,7 @@ def maturity_status(
1209
1261
  "required_fields": MATURITY_REQUIRED_FIELDS,
1210
1262
  "missing_by_level": missing_by_level,
1211
1263
  "missing_details_by_level": missing_details_by_level,
1264
+ "gate_rollout": adoption_gate_rollout_status(maturity_current=current),
1212
1265
  }
1213
1266
 
1214
1267
 
@@ -18,7 +18,7 @@ from pathlib import Path
18
18
 
19
19
  from fact_chain_support import inspect_fact_chain
20
20
  from governance_surface import build_governance_surface
21
- from loom_flow import repo_specific_requirements_payload
21
+ from loom_flow import repo_specific_requirements_payload, review_head_binding
22
22
  from runtime_paths import repo_local_root
23
23
 
24
24
  TOP_LEVEL_DIRS = (
@@ -97,6 +97,7 @@ CORE_DOCS = (
97
97
  "docs/evidence/validations/validation-adoption-maturity-upgrade-automation.md",
98
98
  "docs/evidence/validations/validation-adoption-maturity-required-fields.md",
99
99
  "docs/evidence/validations/validation-skills-consume-maturity-upgrade-path.md",
100
+ "docs/evidence/validations/validation-adoption-gate-rollout.md",
100
101
  "docs/evidence/validations/validation-github-profile-binding-orchestration.md",
101
102
  "docs/evidence/validations/validation-github-profile-drift-reconciliation.md",
102
103
  "docs/evidence/validations/validation-github-profile-graphql-budget-guard.md",
@@ -857,6 +858,71 @@ def require_governance_control_plane(
857
858
  missing_details = maturity.get("missing_details_by_level")
858
859
  if not isinstance(missing_details, dict) or set(missing_details) != {"light", "standard", "strong"}:
859
860
  failures.append(Failure(category, f"{context}.maturity missing_details_by_level must define light, standard, and strong"))
861
+ require_adoption_gate_rollout_payload(
862
+ failures,
863
+ category=category,
864
+ context=f"{context}.maturity.gate_rollout",
865
+ payload=maturity.get("gate_rollout"),
866
+ )
867
+
868
+
869
+ def require_adoption_gate_rollout_payload(
870
+ failures: list[Failure],
871
+ *,
872
+ category: str,
873
+ context: str,
874
+ payload: object,
875
+ ) -> None:
876
+ if not isinstance(payload, dict):
877
+ failures.append(Failure(category, f"{context} must be an object"))
878
+ return
879
+ if payload.get("schema_version") != "loom-adoption-gate-rollout/v1":
880
+ failures.append(Failure(category, f"{context} schema_version must be `loom-adoption-gate-rollout/v1`"))
881
+ if payload.get("default_mode") != "advisory":
882
+ failures.append(Failure(category, f"{context} default_mode must remain advisory"))
883
+ if payload.get("current_mode") not in {"advisory", "blocking", "rollback"}:
884
+ failures.append(Failure(category, f"{context} current_mode must stay within advisory/blocking/rollback"))
885
+ if payload.get("recommended_mode") not in {"advisory", "blocking", "rollback"}:
886
+ failures.append(Failure(category, f"{context} recommended_mode must stay within advisory/blocking/rollback"))
887
+ if not isinstance(payload.get("blocking_allowed"), bool):
888
+ failures.append(Failure(category, f"{context} blocking_allowed must be boolean"))
889
+ modes = payload.get("allowed_modes")
890
+ if not isinstance(modes, dict) or set(modes) != {"advisory", "blocking", "rollback"}:
891
+ failures.append(Failure(category, f"{context} allowed_modes must define advisory, blocking, and rollback"))
892
+ else:
893
+ for mode, entry in modes.items():
894
+ if not isinstance(entry, dict):
895
+ failures.append(Failure(category, f"{context}.allowed_modes.{mode} must be an object"))
896
+ continue
897
+ if not isinstance(entry.get("summary"), str) or not entry.get("summary"):
898
+ failures.append(Failure(category, f"{context}.allowed_modes.{mode} must include summary"))
899
+ if not isinstance(entry.get("blocking"), bool):
900
+ failures.append(Failure(category, f"{context}.allowed_modes.{mode} must include boolean blocking"))
901
+ preconditions = payload.get("blocking_preconditions")
902
+ if not isinstance(preconditions, list) or not preconditions:
903
+ failures.append(Failure(category, f"{context} blocking_preconditions must be non-empty"))
904
+ else:
905
+ ids = {entry.get("id") for entry in preconditions if isinstance(entry, dict)}
906
+ if not {"strong_maturity", "adversarial_adoption_checks", "rollback_switch"}.issubset(ids):
907
+ failures.append(Failure(category, f"{context} blocking_preconditions must include strong maturity, adversarial checks, and rollback switch"))
908
+ for entry in preconditions:
909
+ if not isinstance(entry, dict):
910
+ failures.append(Failure(category, f"{context} blocking_preconditions entries must be objects"))
911
+ continue
912
+ if entry.get("status") not in {"pass", "missing", "block"}:
913
+ failures.append(Failure(category, f"{context} blocking precondition status must be stable"))
914
+ if entry.get("layer") not in {"core", "github-profile", "repo-owned-residue"}:
915
+ failures.append(Failure(category, f"{context} blocking precondition layer must be stable"))
916
+ if not isinstance(entry.get("recommended_action"), str) or not entry.get("recommended_action"):
917
+ failures.append(Failure(category, f"{context} blocking preconditions must include recommended_action"))
918
+ rollback = payload.get("rollback")
919
+ if not isinstance(rollback, dict):
920
+ failures.append(Failure(category, f"{context} rollback must be an object"))
921
+ else:
922
+ if rollback.get("mode") != "rollback" or rollback.get("switch_to") != "advisory":
923
+ failures.append(Failure(category, f"{context} rollback must switch back to advisory"))
924
+ if not isinstance(rollback.get("recommended_action"), str) or not rollback.get("recommended_action"):
925
+ failures.append(Failure(category, f"{context} rollback must include recommended_action"))
860
926
 
861
927
 
862
928
  def require_locator_entry(
@@ -1385,6 +1451,12 @@ def require_governance_upgrade_payload(
1385
1451
  failures.append(Failure(category, f"{context} target_maturity must be standard/strong"))
1386
1452
  if not isinstance(payload.get("dry_run"), bool):
1387
1453
  failures.append(Failure(category, f"{context} dry_run must be boolean"))
1454
+ require_adoption_gate_rollout_payload(
1455
+ failures,
1456
+ category=category,
1457
+ context=f"{context}.gate_rollout",
1458
+ payload=payload.get("gate_rollout"),
1459
+ )
1388
1460
  actions = payload.get("actions")
1389
1461
  if not isinstance(actions, list) or not actions:
1390
1462
  failures.append(Failure(category, f"{context} must include non-empty actions"))
@@ -1428,6 +1500,12 @@ def require_maturity_upgrade_path(
1428
1500
  validation_entries = payload.get("validation_entries")
1429
1501
  if not isinstance(validation_entries, list) or not validation_entries:
1430
1502
  failures.append(Failure(category, f"{context} validation_entries must be non-empty"))
1503
+ require_adoption_gate_rollout_payload(
1504
+ failures,
1505
+ category=category,
1506
+ context=f"{context}.gate_rollout",
1507
+ payload=payload.get("gate_rollout"),
1508
+ )
1431
1509
 
1432
1510
 
1433
1511
  def require_review_record_contract(
@@ -2211,6 +2289,15 @@ def check_demo_fact_chain(root: Path) -> list[Failure]:
2211
2289
  failures.append(Failure("demo-fact-chain", detail))
2212
2290
  if report and report.get("fact_chain", {}).get("entry_points", {}).get("status_surface") != ".loom/status/current.md":
2213
2291
  failures.append(Failure("demo-fact-chain", "demo fact chain must point status_surface to `.loom/status/current.md`"))
2292
+ head_result = run_command(root, ["git", "rev-parse", "HEAD"], timeout_seconds=30)
2293
+ if head_result.returncode == 0:
2294
+ head_binding, head_errors = review_head_binding(
2295
+ root,
2296
+ reviewed_head=head_result.stdout.strip(),
2297
+ allowed_paths=set(),
2298
+ )
2299
+ if head_errors or head_binding.get("status") != "fresh":
2300
+ failures.append(Failure("demo-fact-chain", "review head binding must report `fresh` for the current HEAD"))
2214
2301
  with tempfile.TemporaryDirectory(prefix="loom-check-metadata-spoof-") as tmp:
2215
2302
  spoof_target = Path(tmp) / "new-project"
2216
2303
  shutil.copytree(target, spoof_target)
@@ -4421,6 +4508,65 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
4421
4508
  elif checkpoint_merge_payload.get("result") != "pass":
4422
4509
  failures.append(Failure("daily-execution-cli", "`installed checkpoint merge` must pass for the positive chain"))
4423
4510
 
4511
+ payload, error = load_command_json(
4512
+ root,
4513
+ [
4514
+ "python3",
4515
+ str(install_root / "shared" / "scripts" / "loom_flow.py"),
4516
+ "recovery",
4517
+ "writeback",
4518
+ "--target",
4519
+ str(positive_target),
4520
+ "--item",
4521
+ "INIT-0001",
4522
+ "--current-checkpoint",
4523
+ "merge checkpoint",
4524
+ "--current-stop",
4525
+ "Only Loom carrier status changed after review.",
4526
+ "--next-step",
4527
+ "Confirm carrier-only review head binding remains consumable.",
4528
+ "--latest-validation-summary",
4529
+ positive_summary,
4530
+ ],
4531
+ )
4532
+ if error:
4533
+ failures.append(Failure("daily-execution-cli", f"`installed recovery writeback carrier-only` failed: {error}"))
4534
+ elif payload.get("result") != "pass":
4535
+ failures.append(Failure("daily-execution-cli", "`installed recovery writeback carrier-only` must pass"))
4536
+ git_add = run_command(root, ["git", "add", "-f", ".loom/progress/INIT-0001.md", ".loom/status/current.md"], cwd=positive_target)
4537
+ if git_add.returncode != 0:
4538
+ detail = git_add.stderr.strip() or git_add.stdout.strip() or "git add failed"
4539
+ failures.append(Failure("daily-execution-cli", f"`installed carrier-only commit` add failed: {detail}"))
4540
+ else:
4541
+ git_commit = run_command(
4542
+ root,
4543
+ ["git", "commit", "-m", "refresh carriers after review for #354"],
4544
+ cwd=positive_target,
4545
+ )
4546
+ if git_commit.returncode != 0:
4547
+ detail = git_commit.stderr.strip() or git_commit.stdout.strip() or "git commit failed"
4548
+ failures.append(Failure("daily-execution-cli", f"`installed carrier-only commit` failed: {detail}"))
4549
+
4550
+ payload, error = load_command_json(
4551
+ root,
4552
+ [
4553
+ "python3",
4554
+ str(install_root / "shared" / "scripts" / "loom_flow.py"),
4555
+ "checkpoint",
4556
+ "merge",
4557
+ "--target",
4558
+ str(positive_target),
4559
+ "--item",
4560
+ "INIT-0001",
4561
+ ],
4562
+ )
4563
+ if error:
4564
+ failures.append(Failure("daily-execution-cli", f"`installed checkpoint merge` carrier-only failed: {error}"))
4565
+ elif payload.get("result") != "pass":
4566
+ failures.append(Failure("daily-execution-cli", "`installed checkpoint merge` must pass for carrier-only review head drift"))
4567
+ elif "carrier-only" not in json.dumps(payload, ensure_ascii=False):
4568
+ failures.append(Failure("daily-execution-cli", "`installed checkpoint merge` must expose carrier-only review head binding"))
4569
+
4424
4570
  broken_install = tmp_root / "broken-install" / "skills"
4425
4571
  shutil.copytree(root / "skills", broken_install)
4426
4572
  (broken_install / "install-layout.json").unlink()
@@ -4601,6 +4747,8 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
4601
4747
  failures.append(Failure("daily-execution-cli", f"`installed checkpoint merge` drift negative failed: {error}"))
4602
4748
  elif payload.get("result") != "block":
4603
4749
  failures.append(Failure("daily-execution-cli", "`installed checkpoint merge` must block when HEAD drifts beyond Loom carriers"))
4750
+ elif "implementation-drift-only" not in json.dumps(payload, ensure_ascii=False):
4751
+ failures.append(Failure("daily-execution-cli", "`installed checkpoint merge` drift negative must expose implementation-drift-only review head binding"))
4604
4752
 
4605
4753
  gh_auth_probe = None
4606
4754
  if shutil.which("gh") is not None: