@mc-and-his-agents/loom-installer 0.1.51 → 0.1.52
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.
- package/package.json +1 -1
- package/payload/manifest.json +22 -22
- package/payload/plugin/loom/skills/shared/scripts/loom_check.py +35 -3
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/loom_check.py +35 -3
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/loom_check.py +35 -3
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/loom_check.py +35 -3
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_check.py +35 -3
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_check.py +35 -3
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/loom_check.py +35 -3
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/loom_check.py +35 -3
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/loom_check.py +35 -3
- package/payload/skills/loom-spec-review/.loom-runtime/shared/scripts/loom_check.py +35 -3
package/package.json
CHANGED
package/payload/manifest.json
CHANGED
|
@@ -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": "
|
|
5
|
+
"source_commit": "b63bb9c0ffc94f9c3f9d16d1aa8293e58e56609a",
|
|
6
6
|
"source_ref": "main",
|
|
7
|
-
"built_at": "2026-04-
|
|
7
|
+
"built_at": "2026-04-28T15:13:56+08:00",
|
|
8
8
|
"runtime": {
|
|
9
9
|
"python_minimum": "3.10",
|
|
10
10
|
"python_recommended": "3.11+"
|
|
@@ -633,8 +633,8 @@
|
|
|
633
633
|
},
|
|
634
634
|
{
|
|
635
635
|
"path": "plugin/loom/skills/shared/scripts/loom_check.py",
|
|
636
|
-
"bytes":
|
|
637
|
-
"sha256": "
|
|
636
|
+
"bytes": 372465,
|
|
637
|
+
"sha256": "c9dc22036e5b4ce50f3b434136d6398334a3845b9b705aa8746fc0049186bdff"
|
|
638
638
|
},
|
|
639
639
|
{
|
|
640
640
|
"path": "plugin/loom/skills/shared/scripts/loom_flow.py",
|
|
@@ -1223,8 +1223,8 @@
|
|
|
1223
1223
|
},
|
|
1224
1224
|
{
|
|
1225
1225
|
"path": "skills/loom-adopt/.loom-runtime/shared/scripts/loom_check.py",
|
|
1226
|
-
"bytes":
|
|
1227
|
-
"sha256": "
|
|
1226
|
+
"bytes": 372465,
|
|
1227
|
+
"sha256": "c9dc22036e5b4ce50f3b434136d6398334a3845b9b705aa8746fc0049186bdff"
|
|
1228
1228
|
},
|
|
1229
1229
|
{
|
|
1230
1230
|
"path": "skills/loom-adopt/.loom-runtime/shared/scripts/loom_flow.py",
|
|
@@ -1843,8 +1843,8 @@
|
|
|
1843
1843
|
},
|
|
1844
1844
|
{
|
|
1845
1845
|
"path": "skills/loom-handoff/.loom-runtime/shared/scripts/loom_check.py",
|
|
1846
|
-
"bytes":
|
|
1847
|
-
"sha256": "
|
|
1846
|
+
"bytes": 372465,
|
|
1847
|
+
"sha256": "c9dc22036e5b4ce50f3b434136d6398334a3845b9b705aa8746fc0049186bdff"
|
|
1848
1848
|
},
|
|
1849
1849
|
{
|
|
1850
1850
|
"path": "skills/loom-handoff/.loom-runtime/shared/scripts/loom_flow.py",
|
|
@@ -2463,8 +2463,8 @@
|
|
|
2463
2463
|
},
|
|
2464
2464
|
{
|
|
2465
2465
|
"path": "skills/loom-init/.loom-runtime/shared/scripts/loom_check.py",
|
|
2466
|
-
"bytes":
|
|
2467
|
-
"sha256": "
|
|
2466
|
+
"bytes": 372465,
|
|
2467
|
+
"sha256": "c9dc22036e5b4ce50f3b434136d6398334a3845b9b705aa8746fc0049186bdff"
|
|
2468
2468
|
},
|
|
2469
2469
|
{
|
|
2470
2470
|
"path": "skills/loom-init/.loom-runtime/shared/scripts/loom_flow.py",
|
|
@@ -3088,8 +3088,8 @@
|
|
|
3088
3088
|
},
|
|
3089
3089
|
{
|
|
3090
3090
|
"path": "skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_check.py",
|
|
3091
|
-
"bytes":
|
|
3092
|
-
"sha256": "
|
|
3091
|
+
"bytes": 372465,
|
|
3092
|
+
"sha256": "c9dc22036e5b4ce50f3b434136d6398334a3845b9b705aa8746fc0049186bdff"
|
|
3093
3093
|
},
|
|
3094
3094
|
{
|
|
3095
3095
|
"path": "skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_flow.py",
|
|
@@ -3708,8 +3708,8 @@
|
|
|
3708
3708
|
},
|
|
3709
3709
|
{
|
|
3710
3710
|
"path": "skills/loom-pre-review/.loom-runtime/shared/scripts/loom_check.py",
|
|
3711
|
-
"bytes":
|
|
3712
|
-
"sha256": "
|
|
3711
|
+
"bytes": 372465,
|
|
3712
|
+
"sha256": "c9dc22036e5b4ce50f3b434136d6398334a3845b9b705aa8746fc0049186bdff"
|
|
3713
3713
|
},
|
|
3714
3714
|
{
|
|
3715
3715
|
"path": "skills/loom-pre-review/.loom-runtime/shared/scripts/loom_flow.py",
|
|
@@ -4328,8 +4328,8 @@
|
|
|
4328
4328
|
},
|
|
4329
4329
|
{
|
|
4330
4330
|
"path": "skills/loom-resume/.loom-runtime/shared/scripts/loom_check.py",
|
|
4331
|
-
"bytes":
|
|
4332
|
-
"sha256": "
|
|
4331
|
+
"bytes": 372465,
|
|
4332
|
+
"sha256": "c9dc22036e5b4ce50f3b434136d6398334a3845b9b705aa8746fc0049186bdff"
|
|
4333
4333
|
},
|
|
4334
4334
|
{
|
|
4335
4335
|
"path": "skills/loom-resume/.loom-runtime/shared/scripts/loom_flow.py",
|
|
@@ -4948,8 +4948,8 @@
|
|
|
4948
4948
|
},
|
|
4949
4949
|
{
|
|
4950
4950
|
"path": "skills/loom-retire/.loom-runtime/shared/scripts/loom_check.py",
|
|
4951
|
-
"bytes":
|
|
4952
|
-
"sha256": "
|
|
4951
|
+
"bytes": 372465,
|
|
4952
|
+
"sha256": "c9dc22036e5b4ce50f3b434136d6398334a3845b9b705aa8746fc0049186bdff"
|
|
4953
4953
|
},
|
|
4954
4954
|
{
|
|
4955
4955
|
"path": "skills/loom-retire/.loom-runtime/shared/scripts/loom_flow.py",
|
|
@@ -5568,8 +5568,8 @@
|
|
|
5568
5568
|
},
|
|
5569
5569
|
{
|
|
5570
5570
|
"path": "skills/loom-review/.loom-runtime/shared/scripts/loom_check.py",
|
|
5571
|
-
"bytes":
|
|
5572
|
-
"sha256": "
|
|
5571
|
+
"bytes": 372465,
|
|
5572
|
+
"sha256": "c9dc22036e5b4ce50f3b434136d6398334a3845b9b705aa8746fc0049186bdff"
|
|
5573
5573
|
},
|
|
5574
5574
|
{
|
|
5575
5575
|
"path": "skills/loom-review/.loom-runtime/shared/scripts/loom_flow.py",
|
|
@@ -6188,8 +6188,8 @@
|
|
|
6188
6188
|
},
|
|
6189
6189
|
{
|
|
6190
6190
|
"path": "skills/loom-spec-review/.loom-runtime/shared/scripts/loom_check.py",
|
|
6191
|
-
"bytes":
|
|
6192
|
-
"sha256": "
|
|
6191
|
+
"bytes": 372465,
|
|
6192
|
+
"sha256": "c9dc22036e5b4ce50f3b434136d6398334a3845b9b705aa8746fc0049186bdff"
|
|
6193
6193
|
},
|
|
6194
6194
|
{
|
|
6195
6195
|
"path": "skills/loom-spec-review/.loom-runtime/shared/scripts/loom_flow.py",
|
|
@@ -2421,10 +2421,15 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2421
2421
|
".loom/bootstrap/init-result.json",
|
|
2422
2422
|
".loom/bin/loom_init.py",
|
|
2423
2423
|
".loom/bin/loom_flow.py",
|
|
2424
|
+
".loom/companion/README.md",
|
|
2425
|
+
".loom/companion/manifest.json",
|
|
2426
|
+
".loom/companion/repo-interface.json",
|
|
2427
|
+
".loom/companion/interop.json",
|
|
2424
2428
|
".loom/work-items/INIT-0001.md",
|
|
2425
2429
|
".loom/progress/INIT-0001.md",
|
|
2426
2430
|
".loom/reviews/INIT-0001.json",
|
|
2427
2431
|
".loom/status/current.md",
|
|
2432
|
+
"docs/evidence/validations/validation-loom-self-governance-adoption.md",
|
|
2428
2433
|
)
|
|
2429
2434
|
failures.extend(check_required_paths(root, "root-self-adoption", required_paths))
|
|
2430
2435
|
|
|
@@ -2459,6 +2464,12 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2459
2464
|
"carrier-refresh",
|
|
2460
2465
|
{"result": "pass", "schema_version": "loom-carrier-refresh/v1"},
|
|
2461
2466
|
),
|
|
2467
|
+
(
|
|
2468
|
+
"root shadow parity",
|
|
2469
|
+
["python3", ".loom/bin/loom_flow.py", "shadow-parity", "--target", "."],
|
|
2470
|
+
"shadow-parity",
|
|
2471
|
+
{"result": "pass"},
|
|
2472
|
+
),
|
|
2462
2473
|
)
|
|
2463
2474
|
for label, args, kind, expected in commands:
|
|
2464
2475
|
payload, error = load_command_json(root, args)
|
|
@@ -2483,8 +2494,8 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2483
2494
|
)
|
|
2484
2495
|
if kind == "governance-status":
|
|
2485
2496
|
maturity = payload.get("maturity")
|
|
2486
|
-
if not isinstance(maturity, dict) or maturity.get("current")
|
|
2487
|
-
failures.append(Failure("root-self-adoption", "`root governance status` must report
|
|
2497
|
+
if not isinstance(maturity, dict) or maturity.get("current") != "strong":
|
|
2498
|
+
failures.append(Failure("root-self-adoption", "`root governance status` must report strong maturity after self-management binding"))
|
|
2488
2499
|
if kind == "runtime-parity":
|
|
2489
2500
|
checks = payload.get("checks")
|
|
2490
2501
|
names = {check.get("name") for check in checks if isinstance(check, dict)} if isinstance(checks, list) else set()
|
|
@@ -2504,6 +2515,23 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2504
2515
|
head_binding = review.get("head_binding")
|
|
2505
2516
|
if isinstance(head_binding, dict) and head_binding.get("status") == "stale":
|
|
2506
2517
|
failures.append(Failure("root-self-adoption", "`root carrier refresh --dry-run` must detect stale review head binding"))
|
|
2518
|
+
if kind == "shadow-parity":
|
|
2519
|
+
reports = payload.get("reports")
|
|
2520
|
+
report_surfaces = {
|
|
2521
|
+
report.get("surface")
|
|
2522
|
+
for report in reports
|
|
2523
|
+
if isinstance(report, dict)
|
|
2524
|
+
} if isinstance(reports, list) else set()
|
|
2525
|
+
if report_surfaces != {"admission", "review", "merge_ready", "closeout"}:
|
|
2526
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must cover admission, review, merge_ready, and closeout"))
|
|
2527
|
+
surface = payload.get("governance_surface")
|
|
2528
|
+
if isinstance(surface, dict):
|
|
2529
|
+
repo_interface = surface.get("repo_interface")
|
|
2530
|
+
repo_interop = surface.get("repo_interop")
|
|
2531
|
+
if not isinstance(repo_interface, dict) or repo_interface.get("availability") != "present":
|
|
2532
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo companion interface"))
|
|
2533
|
+
if not isinstance(repo_interop, dict) or repo_interop.get("availability") != "present":
|
|
2534
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo interop contract"))
|
|
2507
2535
|
return failures
|
|
2508
2536
|
|
|
2509
2537
|
|
|
@@ -5097,7 +5125,11 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
|
|
|
5097
5125
|
except subprocess.TimeoutExpired:
|
|
5098
5126
|
gh_auth_probe = None
|
|
5099
5127
|
gh_auth_ready = gh_auth_probe is not None and gh_auth_probe.returncode == 0
|
|
5100
|
-
|
|
5128
|
+
# GitHub Actions' ephemeral token is enough for self-governance host binding
|
|
5129
|
+
# reads, but it is not a stable authority for historical live issue/PR/project
|
|
5130
|
+
# samples. Keep those samples as local authenticated coverage instead of
|
|
5131
|
+
# making CI depend on mutable host permissions.
|
|
5132
|
+
if gh_auth_ready and os.environ.get("GITHUB_ACTIONS") != "true":
|
|
5101
5133
|
with tempfile.TemporaryDirectory(prefix="loom-check-installed-post-merge-") as tmp:
|
|
5102
5134
|
tmp_root = Path(tmp)
|
|
5103
5135
|
install_root = tmp_root / "installed" / "skills"
|
|
@@ -2421,10 +2421,15 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2421
2421
|
".loom/bootstrap/init-result.json",
|
|
2422
2422
|
".loom/bin/loom_init.py",
|
|
2423
2423
|
".loom/bin/loom_flow.py",
|
|
2424
|
+
".loom/companion/README.md",
|
|
2425
|
+
".loom/companion/manifest.json",
|
|
2426
|
+
".loom/companion/repo-interface.json",
|
|
2427
|
+
".loom/companion/interop.json",
|
|
2424
2428
|
".loom/work-items/INIT-0001.md",
|
|
2425
2429
|
".loom/progress/INIT-0001.md",
|
|
2426
2430
|
".loom/reviews/INIT-0001.json",
|
|
2427
2431
|
".loom/status/current.md",
|
|
2432
|
+
"docs/evidence/validations/validation-loom-self-governance-adoption.md",
|
|
2428
2433
|
)
|
|
2429
2434
|
failures.extend(check_required_paths(root, "root-self-adoption", required_paths))
|
|
2430
2435
|
|
|
@@ -2459,6 +2464,12 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2459
2464
|
"carrier-refresh",
|
|
2460
2465
|
{"result": "pass", "schema_version": "loom-carrier-refresh/v1"},
|
|
2461
2466
|
),
|
|
2467
|
+
(
|
|
2468
|
+
"root shadow parity",
|
|
2469
|
+
["python3", ".loom/bin/loom_flow.py", "shadow-parity", "--target", "."],
|
|
2470
|
+
"shadow-parity",
|
|
2471
|
+
{"result": "pass"},
|
|
2472
|
+
),
|
|
2462
2473
|
)
|
|
2463
2474
|
for label, args, kind, expected in commands:
|
|
2464
2475
|
payload, error = load_command_json(root, args)
|
|
@@ -2483,8 +2494,8 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2483
2494
|
)
|
|
2484
2495
|
if kind == "governance-status":
|
|
2485
2496
|
maturity = payload.get("maturity")
|
|
2486
|
-
if not isinstance(maturity, dict) or maturity.get("current")
|
|
2487
|
-
failures.append(Failure("root-self-adoption", "`root governance status` must report
|
|
2497
|
+
if not isinstance(maturity, dict) or maturity.get("current") != "strong":
|
|
2498
|
+
failures.append(Failure("root-self-adoption", "`root governance status` must report strong maturity after self-management binding"))
|
|
2488
2499
|
if kind == "runtime-parity":
|
|
2489
2500
|
checks = payload.get("checks")
|
|
2490
2501
|
names = {check.get("name") for check in checks if isinstance(check, dict)} if isinstance(checks, list) else set()
|
|
@@ -2504,6 +2515,23 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2504
2515
|
head_binding = review.get("head_binding")
|
|
2505
2516
|
if isinstance(head_binding, dict) and head_binding.get("status") == "stale":
|
|
2506
2517
|
failures.append(Failure("root-self-adoption", "`root carrier refresh --dry-run` must detect stale review head binding"))
|
|
2518
|
+
if kind == "shadow-parity":
|
|
2519
|
+
reports = payload.get("reports")
|
|
2520
|
+
report_surfaces = {
|
|
2521
|
+
report.get("surface")
|
|
2522
|
+
for report in reports
|
|
2523
|
+
if isinstance(report, dict)
|
|
2524
|
+
} if isinstance(reports, list) else set()
|
|
2525
|
+
if report_surfaces != {"admission", "review", "merge_ready", "closeout"}:
|
|
2526
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must cover admission, review, merge_ready, and closeout"))
|
|
2527
|
+
surface = payload.get("governance_surface")
|
|
2528
|
+
if isinstance(surface, dict):
|
|
2529
|
+
repo_interface = surface.get("repo_interface")
|
|
2530
|
+
repo_interop = surface.get("repo_interop")
|
|
2531
|
+
if not isinstance(repo_interface, dict) or repo_interface.get("availability") != "present":
|
|
2532
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo companion interface"))
|
|
2533
|
+
if not isinstance(repo_interop, dict) or repo_interop.get("availability") != "present":
|
|
2534
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo interop contract"))
|
|
2507
2535
|
return failures
|
|
2508
2536
|
|
|
2509
2537
|
|
|
@@ -5097,7 +5125,11 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
|
|
|
5097
5125
|
except subprocess.TimeoutExpired:
|
|
5098
5126
|
gh_auth_probe = None
|
|
5099
5127
|
gh_auth_ready = gh_auth_probe is not None and gh_auth_probe.returncode == 0
|
|
5100
|
-
|
|
5128
|
+
# GitHub Actions' ephemeral token is enough for self-governance host binding
|
|
5129
|
+
# reads, but it is not a stable authority for historical live issue/PR/project
|
|
5130
|
+
# samples. Keep those samples as local authenticated coverage instead of
|
|
5131
|
+
# making CI depend on mutable host permissions.
|
|
5132
|
+
if gh_auth_ready and os.environ.get("GITHUB_ACTIONS") != "true":
|
|
5101
5133
|
with tempfile.TemporaryDirectory(prefix="loom-check-installed-post-merge-") as tmp:
|
|
5102
5134
|
tmp_root = Path(tmp)
|
|
5103
5135
|
install_root = tmp_root / "installed" / "skills"
|
|
@@ -2421,10 +2421,15 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2421
2421
|
".loom/bootstrap/init-result.json",
|
|
2422
2422
|
".loom/bin/loom_init.py",
|
|
2423
2423
|
".loom/bin/loom_flow.py",
|
|
2424
|
+
".loom/companion/README.md",
|
|
2425
|
+
".loom/companion/manifest.json",
|
|
2426
|
+
".loom/companion/repo-interface.json",
|
|
2427
|
+
".loom/companion/interop.json",
|
|
2424
2428
|
".loom/work-items/INIT-0001.md",
|
|
2425
2429
|
".loom/progress/INIT-0001.md",
|
|
2426
2430
|
".loom/reviews/INIT-0001.json",
|
|
2427
2431
|
".loom/status/current.md",
|
|
2432
|
+
"docs/evidence/validations/validation-loom-self-governance-adoption.md",
|
|
2428
2433
|
)
|
|
2429
2434
|
failures.extend(check_required_paths(root, "root-self-adoption", required_paths))
|
|
2430
2435
|
|
|
@@ -2459,6 +2464,12 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2459
2464
|
"carrier-refresh",
|
|
2460
2465
|
{"result": "pass", "schema_version": "loom-carrier-refresh/v1"},
|
|
2461
2466
|
),
|
|
2467
|
+
(
|
|
2468
|
+
"root shadow parity",
|
|
2469
|
+
["python3", ".loom/bin/loom_flow.py", "shadow-parity", "--target", "."],
|
|
2470
|
+
"shadow-parity",
|
|
2471
|
+
{"result": "pass"},
|
|
2472
|
+
),
|
|
2462
2473
|
)
|
|
2463
2474
|
for label, args, kind, expected in commands:
|
|
2464
2475
|
payload, error = load_command_json(root, args)
|
|
@@ -2483,8 +2494,8 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2483
2494
|
)
|
|
2484
2495
|
if kind == "governance-status":
|
|
2485
2496
|
maturity = payload.get("maturity")
|
|
2486
|
-
if not isinstance(maturity, dict) or maturity.get("current")
|
|
2487
|
-
failures.append(Failure("root-self-adoption", "`root governance status` must report
|
|
2497
|
+
if not isinstance(maturity, dict) or maturity.get("current") != "strong":
|
|
2498
|
+
failures.append(Failure("root-self-adoption", "`root governance status` must report strong maturity after self-management binding"))
|
|
2488
2499
|
if kind == "runtime-parity":
|
|
2489
2500
|
checks = payload.get("checks")
|
|
2490
2501
|
names = {check.get("name") for check in checks if isinstance(check, dict)} if isinstance(checks, list) else set()
|
|
@@ -2504,6 +2515,23 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2504
2515
|
head_binding = review.get("head_binding")
|
|
2505
2516
|
if isinstance(head_binding, dict) and head_binding.get("status") == "stale":
|
|
2506
2517
|
failures.append(Failure("root-self-adoption", "`root carrier refresh --dry-run` must detect stale review head binding"))
|
|
2518
|
+
if kind == "shadow-parity":
|
|
2519
|
+
reports = payload.get("reports")
|
|
2520
|
+
report_surfaces = {
|
|
2521
|
+
report.get("surface")
|
|
2522
|
+
for report in reports
|
|
2523
|
+
if isinstance(report, dict)
|
|
2524
|
+
} if isinstance(reports, list) else set()
|
|
2525
|
+
if report_surfaces != {"admission", "review", "merge_ready", "closeout"}:
|
|
2526
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must cover admission, review, merge_ready, and closeout"))
|
|
2527
|
+
surface = payload.get("governance_surface")
|
|
2528
|
+
if isinstance(surface, dict):
|
|
2529
|
+
repo_interface = surface.get("repo_interface")
|
|
2530
|
+
repo_interop = surface.get("repo_interop")
|
|
2531
|
+
if not isinstance(repo_interface, dict) or repo_interface.get("availability") != "present":
|
|
2532
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo companion interface"))
|
|
2533
|
+
if not isinstance(repo_interop, dict) or repo_interop.get("availability") != "present":
|
|
2534
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo interop contract"))
|
|
2507
2535
|
return failures
|
|
2508
2536
|
|
|
2509
2537
|
|
|
@@ -5097,7 +5125,11 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
|
|
|
5097
5125
|
except subprocess.TimeoutExpired:
|
|
5098
5126
|
gh_auth_probe = None
|
|
5099
5127
|
gh_auth_ready = gh_auth_probe is not None and gh_auth_probe.returncode == 0
|
|
5100
|
-
|
|
5128
|
+
# GitHub Actions' ephemeral token is enough for self-governance host binding
|
|
5129
|
+
# reads, but it is not a stable authority for historical live issue/PR/project
|
|
5130
|
+
# samples. Keep those samples as local authenticated coverage instead of
|
|
5131
|
+
# making CI depend on mutable host permissions.
|
|
5132
|
+
if gh_auth_ready and os.environ.get("GITHUB_ACTIONS") != "true":
|
|
5101
5133
|
with tempfile.TemporaryDirectory(prefix="loom-check-installed-post-merge-") as tmp:
|
|
5102
5134
|
tmp_root = Path(tmp)
|
|
5103
5135
|
install_root = tmp_root / "installed" / "skills"
|
|
@@ -2421,10 +2421,15 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2421
2421
|
".loom/bootstrap/init-result.json",
|
|
2422
2422
|
".loom/bin/loom_init.py",
|
|
2423
2423
|
".loom/bin/loom_flow.py",
|
|
2424
|
+
".loom/companion/README.md",
|
|
2425
|
+
".loom/companion/manifest.json",
|
|
2426
|
+
".loom/companion/repo-interface.json",
|
|
2427
|
+
".loom/companion/interop.json",
|
|
2424
2428
|
".loom/work-items/INIT-0001.md",
|
|
2425
2429
|
".loom/progress/INIT-0001.md",
|
|
2426
2430
|
".loom/reviews/INIT-0001.json",
|
|
2427
2431
|
".loom/status/current.md",
|
|
2432
|
+
"docs/evidence/validations/validation-loom-self-governance-adoption.md",
|
|
2428
2433
|
)
|
|
2429
2434
|
failures.extend(check_required_paths(root, "root-self-adoption", required_paths))
|
|
2430
2435
|
|
|
@@ -2459,6 +2464,12 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2459
2464
|
"carrier-refresh",
|
|
2460
2465
|
{"result": "pass", "schema_version": "loom-carrier-refresh/v1"},
|
|
2461
2466
|
),
|
|
2467
|
+
(
|
|
2468
|
+
"root shadow parity",
|
|
2469
|
+
["python3", ".loom/bin/loom_flow.py", "shadow-parity", "--target", "."],
|
|
2470
|
+
"shadow-parity",
|
|
2471
|
+
{"result": "pass"},
|
|
2472
|
+
),
|
|
2462
2473
|
)
|
|
2463
2474
|
for label, args, kind, expected in commands:
|
|
2464
2475
|
payload, error = load_command_json(root, args)
|
|
@@ -2483,8 +2494,8 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2483
2494
|
)
|
|
2484
2495
|
if kind == "governance-status":
|
|
2485
2496
|
maturity = payload.get("maturity")
|
|
2486
|
-
if not isinstance(maturity, dict) or maturity.get("current")
|
|
2487
|
-
failures.append(Failure("root-self-adoption", "`root governance status` must report
|
|
2497
|
+
if not isinstance(maturity, dict) or maturity.get("current") != "strong":
|
|
2498
|
+
failures.append(Failure("root-self-adoption", "`root governance status` must report strong maturity after self-management binding"))
|
|
2488
2499
|
if kind == "runtime-parity":
|
|
2489
2500
|
checks = payload.get("checks")
|
|
2490
2501
|
names = {check.get("name") for check in checks if isinstance(check, dict)} if isinstance(checks, list) else set()
|
|
@@ -2504,6 +2515,23 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2504
2515
|
head_binding = review.get("head_binding")
|
|
2505
2516
|
if isinstance(head_binding, dict) and head_binding.get("status") == "stale":
|
|
2506
2517
|
failures.append(Failure("root-self-adoption", "`root carrier refresh --dry-run` must detect stale review head binding"))
|
|
2518
|
+
if kind == "shadow-parity":
|
|
2519
|
+
reports = payload.get("reports")
|
|
2520
|
+
report_surfaces = {
|
|
2521
|
+
report.get("surface")
|
|
2522
|
+
for report in reports
|
|
2523
|
+
if isinstance(report, dict)
|
|
2524
|
+
} if isinstance(reports, list) else set()
|
|
2525
|
+
if report_surfaces != {"admission", "review", "merge_ready", "closeout"}:
|
|
2526
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must cover admission, review, merge_ready, and closeout"))
|
|
2527
|
+
surface = payload.get("governance_surface")
|
|
2528
|
+
if isinstance(surface, dict):
|
|
2529
|
+
repo_interface = surface.get("repo_interface")
|
|
2530
|
+
repo_interop = surface.get("repo_interop")
|
|
2531
|
+
if not isinstance(repo_interface, dict) or repo_interface.get("availability") != "present":
|
|
2532
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo companion interface"))
|
|
2533
|
+
if not isinstance(repo_interop, dict) or repo_interop.get("availability") != "present":
|
|
2534
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo interop contract"))
|
|
2507
2535
|
return failures
|
|
2508
2536
|
|
|
2509
2537
|
|
|
@@ -5097,7 +5125,11 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
|
|
|
5097
5125
|
except subprocess.TimeoutExpired:
|
|
5098
5126
|
gh_auth_probe = None
|
|
5099
5127
|
gh_auth_ready = gh_auth_probe is not None and gh_auth_probe.returncode == 0
|
|
5100
|
-
|
|
5128
|
+
# GitHub Actions' ephemeral token is enough for self-governance host binding
|
|
5129
|
+
# reads, but it is not a stable authority for historical live issue/PR/project
|
|
5130
|
+
# samples. Keep those samples as local authenticated coverage instead of
|
|
5131
|
+
# making CI depend on mutable host permissions.
|
|
5132
|
+
if gh_auth_ready and os.environ.get("GITHUB_ACTIONS") != "true":
|
|
5101
5133
|
with tempfile.TemporaryDirectory(prefix="loom-check-installed-post-merge-") as tmp:
|
|
5102
5134
|
tmp_root = Path(tmp)
|
|
5103
5135
|
install_root = tmp_root / "installed" / "skills"
|
|
@@ -2421,10 +2421,15 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2421
2421
|
".loom/bootstrap/init-result.json",
|
|
2422
2422
|
".loom/bin/loom_init.py",
|
|
2423
2423
|
".loom/bin/loom_flow.py",
|
|
2424
|
+
".loom/companion/README.md",
|
|
2425
|
+
".loom/companion/manifest.json",
|
|
2426
|
+
".loom/companion/repo-interface.json",
|
|
2427
|
+
".loom/companion/interop.json",
|
|
2424
2428
|
".loom/work-items/INIT-0001.md",
|
|
2425
2429
|
".loom/progress/INIT-0001.md",
|
|
2426
2430
|
".loom/reviews/INIT-0001.json",
|
|
2427
2431
|
".loom/status/current.md",
|
|
2432
|
+
"docs/evidence/validations/validation-loom-self-governance-adoption.md",
|
|
2428
2433
|
)
|
|
2429
2434
|
failures.extend(check_required_paths(root, "root-self-adoption", required_paths))
|
|
2430
2435
|
|
|
@@ -2459,6 +2464,12 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2459
2464
|
"carrier-refresh",
|
|
2460
2465
|
{"result": "pass", "schema_version": "loom-carrier-refresh/v1"},
|
|
2461
2466
|
),
|
|
2467
|
+
(
|
|
2468
|
+
"root shadow parity",
|
|
2469
|
+
["python3", ".loom/bin/loom_flow.py", "shadow-parity", "--target", "."],
|
|
2470
|
+
"shadow-parity",
|
|
2471
|
+
{"result": "pass"},
|
|
2472
|
+
),
|
|
2462
2473
|
)
|
|
2463
2474
|
for label, args, kind, expected in commands:
|
|
2464
2475
|
payload, error = load_command_json(root, args)
|
|
@@ -2483,8 +2494,8 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2483
2494
|
)
|
|
2484
2495
|
if kind == "governance-status":
|
|
2485
2496
|
maturity = payload.get("maturity")
|
|
2486
|
-
if not isinstance(maturity, dict) or maturity.get("current")
|
|
2487
|
-
failures.append(Failure("root-self-adoption", "`root governance status` must report
|
|
2497
|
+
if not isinstance(maturity, dict) or maturity.get("current") != "strong":
|
|
2498
|
+
failures.append(Failure("root-self-adoption", "`root governance status` must report strong maturity after self-management binding"))
|
|
2488
2499
|
if kind == "runtime-parity":
|
|
2489
2500
|
checks = payload.get("checks")
|
|
2490
2501
|
names = {check.get("name") for check in checks if isinstance(check, dict)} if isinstance(checks, list) else set()
|
|
@@ -2504,6 +2515,23 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2504
2515
|
head_binding = review.get("head_binding")
|
|
2505
2516
|
if isinstance(head_binding, dict) and head_binding.get("status") == "stale":
|
|
2506
2517
|
failures.append(Failure("root-self-adoption", "`root carrier refresh --dry-run` must detect stale review head binding"))
|
|
2518
|
+
if kind == "shadow-parity":
|
|
2519
|
+
reports = payload.get("reports")
|
|
2520
|
+
report_surfaces = {
|
|
2521
|
+
report.get("surface")
|
|
2522
|
+
for report in reports
|
|
2523
|
+
if isinstance(report, dict)
|
|
2524
|
+
} if isinstance(reports, list) else set()
|
|
2525
|
+
if report_surfaces != {"admission", "review", "merge_ready", "closeout"}:
|
|
2526
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must cover admission, review, merge_ready, and closeout"))
|
|
2527
|
+
surface = payload.get("governance_surface")
|
|
2528
|
+
if isinstance(surface, dict):
|
|
2529
|
+
repo_interface = surface.get("repo_interface")
|
|
2530
|
+
repo_interop = surface.get("repo_interop")
|
|
2531
|
+
if not isinstance(repo_interface, dict) or repo_interface.get("availability") != "present":
|
|
2532
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo companion interface"))
|
|
2533
|
+
if not isinstance(repo_interop, dict) or repo_interop.get("availability") != "present":
|
|
2534
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo interop contract"))
|
|
2507
2535
|
return failures
|
|
2508
2536
|
|
|
2509
2537
|
|
|
@@ -5097,7 +5125,11 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
|
|
|
5097
5125
|
except subprocess.TimeoutExpired:
|
|
5098
5126
|
gh_auth_probe = None
|
|
5099
5127
|
gh_auth_ready = gh_auth_probe is not None and gh_auth_probe.returncode == 0
|
|
5100
|
-
|
|
5128
|
+
# GitHub Actions' ephemeral token is enough for self-governance host binding
|
|
5129
|
+
# reads, but it is not a stable authority for historical live issue/PR/project
|
|
5130
|
+
# samples. Keep those samples as local authenticated coverage instead of
|
|
5131
|
+
# making CI depend on mutable host permissions.
|
|
5132
|
+
if gh_auth_ready and os.environ.get("GITHUB_ACTIONS") != "true":
|
|
5101
5133
|
with tempfile.TemporaryDirectory(prefix="loom-check-installed-post-merge-") as tmp:
|
|
5102
5134
|
tmp_root = Path(tmp)
|
|
5103
5135
|
install_root = tmp_root / "installed" / "skills"
|
|
@@ -2421,10 +2421,15 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2421
2421
|
".loom/bootstrap/init-result.json",
|
|
2422
2422
|
".loom/bin/loom_init.py",
|
|
2423
2423
|
".loom/bin/loom_flow.py",
|
|
2424
|
+
".loom/companion/README.md",
|
|
2425
|
+
".loom/companion/manifest.json",
|
|
2426
|
+
".loom/companion/repo-interface.json",
|
|
2427
|
+
".loom/companion/interop.json",
|
|
2424
2428
|
".loom/work-items/INIT-0001.md",
|
|
2425
2429
|
".loom/progress/INIT-0001.md",
|
|
2426
2430
|
".loom/reviews/INIT-0001.json",
|
|
2427
2431
|
".loom/status/current.md",
|
|
2432
|
+
"docs/evidence/validations/validation-loom-self-governance-adoption.md",
|
|
2428
2433
|
)
|
|
2429
2434
|
failures.extend(check_required_paths(root, "root-self-adoption", required_paths))
|
|
2430
2435
|
|
|
@@ -2459,6 +2464,12 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2459
2464
|
"carrier-refresh",
|
|
2460
2465
|
{"result": "pass", "schema_version": "loom-carrier-refresh/v1"},
|
|
2461
2466
|
),
|
|
2467
|
+
(
|
|
2468
|
+
"root shadow parity",
|
|
2469
|
+
["python3", ".loom/bin/loom_flow.py", "shadow-parity", "--target", "."],
|
|
2470
|
+
"shadow-parity",
|
|
2471
|
+
{"result": "pass"},
|
|
2472
|
+
),
|
|
2462
2473
|
)
|
|
2463
2474
|
for label, args, kind, expected in commands:
|
|
2464
2475
|
payload, error = load_command_json(root, args)
|
|
@@ -2483,8 +2494,8 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2483
2494
|
)
|
|
2484
2495
|
if kind == "governance-status":
|
|
2485
2496
|
maturity = payload.get("maturity")
|
|
2486
|
-
if not isinstance(maturity, dict) or maturity.get("current")
|
|
2487
|
-
failures.append(Failure("root-self-adoption", "`root governance status` must report
|
|
2497
|
+
if not isinstance(maturity, dict) or maturity.get("current") != "strong":
|
|
2498
|
+
failures.append(Failure("root-self-adoption", "`root governance status` must report strong maturity after self-management binding"))
|
|
2488
2499
|
if kind == "runtime-parity":
|
|
2489
2500
|
checks = payload.get("checks")
|
|
2490
2501
|
names = {check.get("name") for check in checks if isinstance(check, dict)} if isinstance(checks, list) else set()
|
|
@@ -2504,6 +2515,23 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2504
2515
|
head_binding = review.get("head_binding")
|
|
2505
2516
|
if isinstance(head_binding, dict) and head_binding.get("status") == "stale":
|
|
2506
2517
|
failures.append(Failure("root-self-adoption", "`root carrier refresh --dry-run` must detect stale review head binding"))
|
|
2518
|
+
if kind == "shadow-parity":
|
|
2519
|
+
reports = payload.get("reports")
|
|
2520
|
+
report_surfaces = {
|
|
2521
|
+
report.get("surface")
|
|
2522
|
+
for report in reports
|
|
2523
|
+
if isinstance(report, dict)
|
|
2524
|
+
} if isinstance(reports, list) else set()
|
|
2525
|
+
if report_surfaces != {"admission", "review", "merge_ready", "closeout"}:
|
|
2526
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must cover admission, review, merge_ready, and closeout"))
|
|
2527
|
+
surface = payload.get("governance_surface")
|
|
2528
|
+
if isinstance(surface, dict):
|
|
2529
|
+
repo_interface = surface.get("repo_interface")
|
|
2530
|
+
repo_interop = surface.get("repo_interop")
|
|
2531
|
+
if not isinstance(repo_interface, dict) or repo_interface.get("availability") != "present":
|
|
2532
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo companion interface"))
|
|
2533
|
+
if not isinstance(repo_interop, dict) or repo_interop.get("availability") != "present":
|
|
2534
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo interop contract"))
|
|
2507
2535
|
return failures
|
|
2508
2536
|
|
|
2509
2537
|
|
|
@@ -5097,7 +5125,11 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
|
|
|
5097
5125
|
except subprocess.TimeoutExpired:
|
|
5098
5126
|
gh_auth_probe = None
|
|
5099
5127
|
gh_auth_ready = gh_auth_probe is not None and gh_auth_probe.returncode == 0
|
|
5100
|
-
|
|
5128
|
+
# GitHub Actions' ephemeral token is enough for self-governance host binding
|
|
5129
|
+
# reads, but it is not a stable authority for historical live issue/PR/project
|
|
5130
|
+
# samples. Keep those samples as local authenticated coverage instead of
|
|
5131
|
+
# making CI depend on mutable host permissions.
|
|
5132
|
+
if gh_auth_ready and os.environ.get("GITHUB_ACTIONS") != "true":
|
|
5101
5133
|
with tempfile.TemporaryDirectory(prefix="loom-check-installed-post-merge-") as tmp:
|
|
5102
5134
|
tmp_root = Path(tmp)
|
|
5103
5135
|
install_root = tmp_root / "installed" / "skills"
|
|
@@ -2421,10 +2421,15 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2421
2421
|
".loom/bootstrap/init-result.json",
|
|
2422
2422
|
".loom/bin/loom_init.py",
|
|
2423
2423
|
".loom/bin/loom_flow.py",
|
|
2424
|
+
".loom/companion/README.md",
|
|
2425
|
+
".loom/companion/manifest.json",
|
|
2426
|
+
".loom/companion/repo-interface.json",
|
|
2427
|
+
".loom/companion/interop.json",
|
|
2424
2428
|
".loom/work-items/INIT-0001.md",
|
|
2425
2429
|
".loom/progress/INIT-0001.md",
|
|
2426
2430
|
".loom/reviews/INIT-0001.json",
|
|
2427
2431
|
".loom/status/current.md",
|
|
2432
|
+
"docs/evidence/validations/validation-loom-self-governance-adoption.md",
|
|
2428
2433
|
)
|
|
2429
2434
|
failures.extend(check_required_paths(root, "root-self-adoption", required_paths))
|
|
2430
2435
|
|
|
@@ -2459,6 +2464,12 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2459
2464
|
"carrier-refresh",
|
|
2460
2465
|
{"result": "pass", "schema_version": "loom-carrier-refresh/v1"},
|
|
2461
2466
|
),
|
|
2467
|
+
(
|
|
2468
|
+
"root shadow parity",
|
|
2469
|
+
["python3", ".loom/bin/loom_flow.py", "shadow-parity", "--target", "."],
|
|
2470
|
+
"shadow-parity",
|
|
2471
|
+
{"result": "pass"},
|
|
2472
|
+
),
|
|
2462
2473
|
)
|
|
2463
2474
|
for label, args, kind, expected in commands:
|
|
2464
2475
|
payload, error = load_command_json(root, args)
|
|
@@ -2483,8 +2494,8 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2483
2494
|
)
|
|
2484
2495
|
if kind == "governance-status":
|
|
2485
2496
|
maturity = payload.get("maturity")
|
|
2486
|
-
if not isinstance(maturity, dict) or maturity.get("current")
|
|
2487
|
-
failures.append(Failure("root-self-adoption", "`root governance status` must report
|
|
2497
|
+
if not isinstance(maturity, dict) or maturity.get("current") != "strong":
|
|
2498
|
+
failures.append(Failure("root-self-adoption", "`root governance status` must report strong maturity after self-management binding"))
|
|
2488
2499
|
if kind == "runtime-parity":
|
|
2489
2500
|
checks = payload.get("checks")
|
|
2490
2501
|
names = {check.get("name") for check in checks if isinstance(check, dict)} if isinstance(checks, list) else set()
|
|
@@ -2504,6 +2515,23 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2504
2515
|
head_binding = review.get("head_binding")
|
|
2505
2516
|
if isinstance(head_binding, dict) and head_binding.get("status") == "stale":
|
|
2506
2517
|
failures.append(Failure("root-self-adoption", "`root carrier refresh --dry-run` must detect stale review head binding"))
|
|
2518
|
+
if kind == "shadow-parity":
|
|
2519
|
+
reports = payload.get("reports")
|
|
2520
|
+
report_surfaces = {
|
|
2521
|
+
report.get("surface")
|
|
2522
|
+
for report in reports
|
|
2523
|
+
if isinstance(report, dict)
|
|
2524
|
+
} if isinstance(reports, list) else set()
|
|
2525
|
+
if report_surfaces != {"admission", "review", "merge_ready", "closeout"}:
|
|
2526
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must cover admission, review, merge_ready, and closeout"))
|
|
2527
|
+
surface = payload.get("governance_surface")
|
|
2528
|
+
if isinstance(surface, dict):
|
|
2529
|
+
repo_interface = surface.get("repo_interface")
|
|
2530
|
+
repo_interop = surface.get("repo_interop")
|
|
2531
|
+
if not isinstance(repo_interface, dict) or repo_interface.get("availability") != "present":
|
|
2532
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo companion interface"))
|
|
2533
|
+
if not isinstance(repo_interop, dict) or repo_interop.get("availability") != "present":
|
|
2534
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo interop contract"))
|
|
2507
2535
|
return failures
|
|
2508
2536
|
|
|
2509
2537
|
|
|
@@ -5097,7 +5125,11 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
|
|
|
5097
5125
|
except subprocess.TimeoutExpired:
|
|
5098
5126
|
gh_auth_probe = None
|
|
5099
5127
|
gh_auth_ready = gh_auth_probe is not None and gh_auth_probe.returncode == 0
|
|
5100
|
-
|
|
5128
|
+
# GitHub Actions' ephemeral token is enough for self-governance host binding
|
|
5129
|
+
# reads, but it is not a stable authority for historical live issue/PR/project
|
|
5130
|
+
# samples. Keep those samples as local authenticated coverage instead of
|
|
5131
|
+
# making CI depend on mutable host permissions.
|
|
5132
|
+
if gh_auth_ready and os.environ.get("GITHUB_ACTIONS") != "true":
|
|
5101
5133
|
with tempfile.TemporaryDirectory(prefix="loom-check-installed-post-merge-") as tmp:
|
|
5102
5134
|
tmp_root = Path(tmp)
|
|
5103
5135
|
install_root = tmp_root / "installed" / "skills"
|
|
@@ -2421,10 +2421,15 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2421
2421
|
".loom/bootstrap/init-result.json",
|
|
2422
2422
|
".loom/bin/loom_init.py",
|
|
2423
2423
|
".loom/bin/loom_flow.py",
|
|
2424
|
+
".loom/companion/README.md",
|
|
2425
|
+
".loom/companion/manifest.json",
|
|
2426
|
+
".loom/companion/repo-interface.json",
|
|
2427
|
+
".loom/companion/interop.json",
|
|
2424
2428
|
".loom/work-items/INIT-0001.md",
|
|
2425
2429
|
".loom/progress/INIT-0001.md",
|
|
2426
2430
|
".loom/reviews/INIT-0001.json",
|
|
2427
2431
|
".loom/status/current.md",
|
|
2432
|
+
"docs/evidence/validations/validation-loom-self-governance-adoption.md",
|
|
2428
2433
|
)
|
|
2429
2434
|
failures.extend(check_required_paths(root, "root-self-adoption", required_paths))
|
|
2430
2435
|
|
|
@@ -2459,6 +2464,12 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2459
2464
|
"carrier-refresh",
|
|
2460
2465
|
{"result": "pass", "schema_version": "loom-carrier-refresh/v1"},
|
|
2461
2466
|
),
|
|
2467
|
+
(
|
|
2468
|
+
"root shadow parity",
|
|
2469
|
+
["python3", ".loom/bin/loom_flow.py", "shadow-parity", "--target", "."],
|
|
2470
|
+
"shadow-parity",
|
|
2471
|
+
{"result": "pass"},
|
|
2472
|
+
),
|
|
2462
2473
|
)
|
|
2463
2474
|
for label, args, kind, expected in commands:
|
|
2464
2475
|
payload, error = load_command_json(root, args)
|
|
@@ -2483,8 +2494,8 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2483
2494
|
)
|
|
2484
2495
|
if kind == "governance-status":
|
|
2485
2496
|
maturity = payload.get("maturity")
|
|
2486
|
-
if not isinstance(maturity, dict) or maturity.get("current")
|
|
2487
|
-
failures.append(Failure("root-self-adoption", "`root governance status` must report
|
|
2497
|
+
if not isinstance(maturity, dict) or maturity.get("current") != "strong":
|
|
2498
|
+
failures.append(Failure("root-self-adoption", "`root governance status` must report strong maturity after self-management binding"))
|
|
2488
2499
|
if kind == "runtime-parity":
|
|
2489
2500
|
checks = payload.get("checks")
|
|
2490
2501
|
names = {check.get("name") for check in checks if isinstance(check, dict)} if isinstance(checks, list) else set()
|
|
@@ -2504,6 +2515,23 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2504
2515
|
head_binding = review.get("head_binding")
|
|
2505
2516
|
if isinstance(head_binding, dict) and head_binding.get("status") == "stale":
|
|
2506
2517
|
failures.append(Failure("root-self-adoption", "`root carrier refresh --dry-run` must detect stale review head binding"))
|
|
2518
|
+
if kind == "shadow-parity":
|
|
2519
|
+
reports = payload.get("reports")
|
|
2520
|
+
report_surfaces = {
|
|
2521
|
+
report.get("surface")
|
|
2522
|
+
for report in reports
|
|
2523
|
+
if isinstance(report, dict)
|
|
2524
|
+
} if isinstance(reports, list) else set()
|
|
2525
|
+
if report_surfaces != {"admission", "review", "merge_ready", "closeout"}:
|
|
2526
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must cover admission, review, merge_ready, and closeout"))
|
|
2527
|
+
surface = payload.get("governance_surface")
|
|
2528
|
+
if isinstance(surface, dict):
|
|
2529
|
+
repo_interface = surface.get("repo_interface")
|
|
2530
|
+
repo_interop = surface.get("repo_interop")
|
|
2531
|
+
if not isinstance(repo_interface, dict) or repo_interface.get("availability") != "present":
|
|
2532
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo companion interface"))
|
|
2533
|
+
if not isinstance(repo_interop, dict) or repo_interop.get("availability") != "present":
|
|
2534
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo interop contract"))
|
|
2507
2535
|
return failures
|
|
2508
2536
|
|
|
2509
2537
|
|
|
@@ -5097,7 +5125,11 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
|
|
|
5097
5125
|
except subprocess.TimeoutExpired:
|
|
5098
5126
|
gh_auth_probe = None
|
|
5099
5127
|
gh_auth_ready = gh_auth_probe is not None and gh_auth_probe.returncode == 0
|
|
5100
|
-
|
|
5128
|
+
# GitHub Actions' ephemeral token is enough for self-governance host binding
|
|
5129
|
+
# reads, but it is not a stable authority for historical live issue/PR/project
|
|
5130
|
+
# samples. Keep those samples as local authenticated coverage instead of
|
|
5131
|
+
# making CI depend on mutable host permissions.
|
|
5132
|
+
if gh_auth_ready and os.environ.get("GITHUB_ACTIONS") != "true":
|
|
5101
5133
|
with tempfile.TemporaryDirectory(prefix="loom-check-installed-post-merge-") as tmp:
|
|
5102
5134
|
tmp_root = Path(tmp)
|
|
5103
5135
|
install_root = tmp_root / "installed" / "skills"
|
|
@@ -2421,10 +2421,15 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2421
2421
|
".loom/bootstrap/init-result.json",
|
|
2422
2422
|
".loom/bin/loom_init.py",
|
|
2423
2423
|
".loom/bin/loom_flow.py",
|
|
2424
|
+
".loom/companion/README.md",
|
|
2425
|
+
".loom/companion/manifest.json",
|
|
2426
|
+
".loom/companion/repo-interface.json",
|
|
2427
|
+
".loom/companion/interop.json",
|
|
2424
2428
|
".loom/work-items/INIT-0001.md",
|
|
2425
2429
|
".loom/progress/INIT-0001.md",
|
|
2426
2430
|
".loom/reviews/INIT-0001.json",
|
|
2427
2431
|
".loom/status/current.md",
|
|
2432
|
+
"docs/evidence/validations/validation-loom-self-governance-adoption.md",
|
|
2428
2433
|
)
|
|
2429
2434
|
failures.extend(check_required_paths(root, "root-self-adoption", required_paths))
|
|
2430
2435
|
|
|
@@ -2459,6 +2464,12 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2459
2464
|
"carrier-refresh",
|
|
2460
2465
|
{"result": "pass", "schema_version": "loom-carrier-refresh/v1"},
|
|
2461
2466
|
),
|
|
2467
|
+
(
|
|
2468
|
+
"root shadow parity",
|
|
2469
|
+
["python3", ".loom/bin/loom_flow.py", "shadow-parity", "--target", "."],
|
|
2470
|
+
"shadow-parity",
|
|
2471
|
+
{"result": "pass"},
|
|
2472
|
+
),
|
|
2462
2473
|
)
|
|
2463
2474
|
for label, args, kind, expected in commands:
|
|
2464
2475
|
payload, error = load_command_json(root, args)
|
|
@@ -2483,8 +2494,8 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2483
2494
|
)
|
|
2484
2495
|
if kind == "governance-status":
|
|
2485
2496
|
maturity = payload.get("maturity")
|
|
2486
|
-
if not isinstance(maturity, dict) or maturity.get("current")
|
|
2487
|
-
failures.append(Failure("root-self-adoption", "`root governance status` must report
|
|
2497
|
+
if not isinstance(maturity, dict) or maturity.get("current") != "strong":
|
|
2498
|
+
failures.append(Failure("root-self-adoption", "`root governance status` must report strong maturity after self-management binding"))
|
|
2488
2499
|
if kind == "runtime-parity":
|
|
2489
2500
|
checks = payload.get("checks")
|
|
2490
2501
|
names = {check.get("name") for check in checks if isinstance(check, dict)} if isinstance(checks, list) else set()
|
|
@@ -2504,6 +2515,23 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2504
2515
|
head_binding = review.get("head_binding")
|
|
2505
2516
|
if isinstance(head_binding, dict) and head_binding.get("status") == "stale":
|
|
2506
2517
|
failures.append(Failure("root-self-adoption", "`root carrier refresh --dry-run` must detect stale review head binding"))
|
|
2518
|
+
if kind == "shadow-parity":
|
|
2519
|
+
reports = payload.get("reports")
|
|
2520
|
+
report_surfaces = {
|
|
2521
|
+
report.get("surface")
|
|
2522
|
+
for report in reports
|
|
2523
|
+
if isinstance(report, dict)
|
|
2524
|
+
} if isinstance(reports, list) else set()
|
|
2525
|
+
if report_surfaces != {"admission", "review", "merge_ready", "closeout"}:
|
|
2526
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must cover admission, review, merge_ready, and closeout"))
|
|
2527
|
+
surface = payload.get("governance_surface")
|
|
2528
|
+
if isinstance(surface, dict):
|
|
2529
|
+
repo_interface = surface.get("repo_interface")
|
|
2530
|
+
repo_interop = surface.get("repo_interop")
|
|
2531
|
+
if not isinstance(repo_interface, dict) or repo_interface.get("availability") != "present":
|
|
2532
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo companion interface"))
|
|
2533
|
+
if not isinstance(repo_interop, dict) or repo_interop.get("availability") != "present":
|
|
2534
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo interop contract"))
|
|
2507
2535
|
return failures
|
|
2508
2536
|
|
|
2509
2537
|
|
|
@@ -5097,7 +5125,11 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
|
|
|
5097
5125
|
except subprocess.TimeoutExpired:
|
|
5098
5126
|
gh_auth_probe = None
|
|
5099
5127
|
gh_auth_ready = gh_auth_probe is not None and gh_auth_probe.returncode == 0
|
|
5100
|
-
|
|
5128
|
+
# GitHub Actions' ephemeral token is enough for self-governance host binding
|
|
5129
|
+
# reads, but it is not a stable authority for historical live issue/PR/project
|
|
5130
|
+
# samples. Keep those samples as local authenticated coverage instead of
|
|
5131
|
+
# making CI depend on mutable host permissions.
|
|
5132
|
+
if gh_auth_ready and os.environ.get("GITHUB_ACTIONS") != "true":
|
|
5101
5133
|
with tempfile.TemporaryDirectory(prefix="loom-check-installed-post-merge-") as tmp:
|
|
5102
5134
|
tmp_root = Path(tmp)
|
|
5103
5135
|
install_root = tmp_root / "installed" / "skills"
|
|
@@ -2421,10 +2421,15 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2421
2421
|
".loom/bootstrap/init-result.json",
|
|
2422
2422
|
".loom/bin/loom_init.py",
|
|
2423
2423
|
".loom/bin/loom_flow.py",
|
|
2424
|
+
".loom/companion/README.md",
|
|
2425
|
+
".loom/companion/manifest.json",
|
|
2426
|
+
".loom/companion/repo-interface.json",
|
|
2427
|
+
".loom/companion/interop.json",
|
|
2424
2428
|
".loom/work-items/INIT-0001.md",
|
|
2425
2429
|
".loom/progress/INIT-0001.md",
|
|
2426
2430
|
".loom/reviews/INIT-0001.json",
|
|
2427
2431
|
".loom/status/current.md",
|
|
2432
|
+
"docs/evidence/validations/validation-loom-self-governance-adoption.md",
|
|
2428
2433
|
)
|
|
2429
2434
|
failures.extend(check_required_paths(root, "root-self-adoption", required_paths))
|
|
2430
2435
|
|
|
@@ -2459,6 +2464,12 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2459
2464
|
"carrier-refresh",
|
|
2460
2465
|
{"result": "pass", "schema_version": "loom-carrier-refresh/v1"},
|
|
2461
2466
|
),
|
|
2467
|
+
(
|
|
2468
|
+
"root shadow parity",
|
|
2469
|
+
["python3", ".loom/bin/loom_flow.py", "shadow-parity", "--target", "."],
|
|
2470
|
+
"shadow-parity",
|
|
2471
|
+
{"result": "pass"},
|
|
2472
|
+
),
|
|
2462
2473
|
)
|
|
2463
2474
|
for label, args, kind, expected in commands:
|
|
2464
2475
|
payload, error = load_command_json(root, args)
|
|
@@ -2483,8 +2494,8 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2483
2494
|
)
|
|
2484
2495
|
if kind == "governance-status":
|
|
2485
2496
|
maturity = payload.get("maturity")
|
|
2486
|
-
if not isinstance(maturity, dict) or maturity.get("current")
|
|
2487
|
-
failures.append(Failure("root-self-adoption", "`root governance status` must report
|
|
2497
|
+
if not isinstance(maturity, dict) or maturity.get("current") != "strong":
|
|
2498
|
+
failures.append(Failure("root-self-adoption", "`root governance status` must report strong maturity after self-management binding"))
|
|
2488
2499
|
if kind == "runtime-parity":
|
|
2489
2500
|
checks = payload.get("checks")
|
|
2490
2501
|
names = {check.get("name") for check in checks if isinstance(check, dict)} if isinstance(checks, list) else set()
|
|
@@ -2504,6 +2515,23 @@ def check_root_self_adoption_carrier(root: Path) -> list[Failure]:
|
|
|
2504
2515
|
head_binding = review.get("head_binding")
|
|
2505
2516
|
if isinstance(head_binding, dict) and head_binding.get("status") == "stale":
|
|
2506
2517
|
failures.append(Failure("root-self-adoption", "`root carrier refresh --dry-run` must detect stale review head binding"))
|
|
2518
|
+
if kind == "shadow-parity":
|
|
2519
|
+
reports = payload.get("reports")
|
|
2520
|
+
report_surfaces = {
|
|
2521
|
+
report.get("surface")
|
|
2522
|
+
for report in reports
|
|
2523
|
+
if isinstance(report, dict)
|
|
2524
|
+
} if isinstance(reports, list) else set()
|
|
2525
|
+
if report_surfaces != {"admission", "review", "merge_ready", "closeout"}:
|
|
2526
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must cover admission, review, merge_ready, and closeout"))
|
|
2527
|
+
surface = payload.get("governance_surface")
|
|
2528
|
+
if isinstance(surface, dict):
|
|
2529
|
+
repo_interface = surface.get("repo_interface")
|
|
2530
|
+
repo_interop = surface.get("repo_interop")
|
|
2531
|
+
if not isinstance(repo_interface, dict) or repo_interface.get("availability") != "present":
|
|
2532
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo companion interface"))
|
|
2533
|
+
if not isinstance(repo_interop, dict) or repo_interop.get("availability") != "present":
|
|
2534
|
+
failures.append(Failure("root-self-adoption", "`root shadow parity` must consume the root repo interop contract"))
|
|
2507
2535
|
return failures
|
|
2508
2536
|
|
|
2509
2537
|
|
|
@@ -5097,7 +5125,11 @@ def check_daily_execution_cli(root: Path) -> list[Failure]:
|
|
|
5097
5125
|
except subprocess.TimeoutExpired:
|
|
5098
5126
|
gh_auth_probe = None
|
|
5099
5127
|
gh_auth_ready = gh_auth_probe is not None and gh_auth_probe.returncode == 0
|
|
5100
|
-
|
|
5128
|
+
# GitHub Actions' ephemeral token is enough for self-governance host binding
|
|
5129
|
+
# reads, but it is not a stable authority for historical live issue/PR/project
|
|
5130
|
+
# samples. Keep those samples as local authenticated coverage instead of
|
|
5131
|
+
# making CI depend on mutable host permissions.
|
|
5132
|
+
if gh_auth_ready and os.environ.get("GITHUB_ACTIONS") != "true":
|
|
5101
5133
|
with tempfile.TemporaryDirectory(prefix="loom-check-installed-post-merge-") as tmp:
|
|
5102
5134
|
tmp_root = Path(tmp)
|
|
5103
5135
|
install_root = tmp_root / "installed" / "skills"
|