@mc-and-his-agents/loom-installer 0.1.43 → 0.1.44

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mc-and-his-agents/loom-installer",
3
- "version": "0.1.43",
3
+ "version": "0.1.44",
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": "8c3ba44e07d467f15fee186221344f2bef12ed42",
5
+ "source_commit": "62fc9353f0821c3354965e01eb8fb77576247888",
6
6
  "source_ref": "main",
7
- "built_at": "2026-04-27T22:10:31+08:00",
7
+ "built_at": "2026-04-27T23:17:55+08:00",
8
8
  "runtime": {
9
9
  "python_minimum": "3.10",
10
10
  "python_recommended": "3.11+"
@@ -628,8 +628,8 @@
628
628
  },
629
629
  {
630
630
  "path": "plugin/loom/skills/shared/scripts/governance_surface.py",
631
- "bytes": 57136,
632
- "sha256": "02e6f66afcfad5b117ea9a801c7153466f24c6d5721da1546f286aa046c548f1"
631
+ "bytes": 58392,
632
+ "sha256": "543e10c205be62f5be78704fe9bf27e808fc07ffe035382e3d4dd78ffa8c80cc"
633
633
  },
634
634
  {
635
635
  "path": "plugin/loom/skills/shared/scripts/loom_check.py",
@@ -1218,8 +1218,8 @@
1218
1218
  },
1219
1219
  {
1220
1220
  "path": "skills/loom-adopt/.loom-runtime/shared/scripts/governance_surface.py",
1221
- "bytes": 57136,
1222
- "sha256": "02e6f66afcfad5b117ea9a801c7153466f24c6d5721da1546f286aa046c548f1"
1221
+ "bytes": 58392,
1222
+ "sha256": "543e10c205be62f5be78704fe9bf27e808fc07ffe035382e3d4dd78ffa8c80cc"
1223
1223
  },
1224
1224
  {
1225
1225
  "path": "skills/loom-adopt/.loom-runtime/shared/scripts/loom_check.py",
@@ -1838,8 +1838,8 @@
1838
1838
  },
1839
1839
  {
1840
1840
  "path": "skills/loom-handoff/.loom-runtime/shared/scripts/governance_surface.py",
1841
- "bytes": 57136,
1842
- "sha256": "02e6f66afcfad5b117ea9a801c7153466f24c6d5721da1546f286aa046c548f1"
1841
+ "bytes": 58392,
1842
+ "sha256": "543e10c205be62f5be78704fe9bf27e808fc07ffe035382e3d4dd78ffa8c80cc"
1843
1843
  },
1844
1844
  {
1845
1845
  "path": "skills/loom-handoff/.loom-runtime/shared/scripts/loom_check.py",
@@ -2458,8 +2458,8 @@
2458
2458
  },
2459
2459
  {
2460
2460
  "path": "skills/loom-init/.loom-runtime/shared/scripts/governance_surface.py",
2461
- "bytes": 57136,
2462
- "sha256": "02e6f66afcfad5b117ea9a801c7153466f24c6d5721da1546f286aa046c548f1"
2461
+ "bytes": 58392,
2462
+ "sha256": "543e10c205be62f5be78704fe9bf27e808fc07ffe035382e3d4dd78ffa8c80cc"
2463
2463
  },
2464
2464
  {
2465
2465
  "path": "skills/loom-init/.loom-runtime/shared/scripts/loom_check.py",
@@ -3083,8 +3083,8 @@
3083
3083
  },
3084
3084
  {
3085
3085
  "path": "skills/loom-merge-ready/.loom-runtime/shared/scripts/governance_surface.py",
3086
- "bytes": 57136,
3087
- "sha256": "02e6f66afcfad5b117ea9a801c7153466f24c6d5721da1546f286aa046c548f1"
3086
+ "bytes": 58392,
3087
+ "sha256": "543e10c205be62f5be78704fe9bf27e808fc07ffe035382e3d4dd78ffa8c80cc"
3088
3088
  },
3089
3089
  {
3090
3090
  "path": "skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_check.py",
@@ -3703,8 +3703,8 @@
3703
3703
  },
3704
3704
  {
3705
3705
  "path": "skills/loom-pre-review/.loom-runtime/shared/scripts/governance_surface.py",
3706
- "bytes": 57136,
3707
- "sha256": "02e6f66afcfad5b117ea9a801c7153466f24c6d5721da1546f286aa046c548f1"
3706
+ "bytes": 58392,
3707
+ "sha256": "543e10c205be62f5be78704fe9bf27e808fc07ffe035382e3d4dd78ffa8c80cc"
3708
3708
  },
3709
3709
  {
3710
3710
  "path": "skills/loom-pre-review/.loom-runtime/shared/scripts/loom_check.py",
@@ -4323,8 +4323,8 @@
4323
4323
  },
4324
4324
  {
4325
4325
  "path": "skills/loom-resume/.loom-runtime/shared/scripts/governance_surface.py",
4326
- "bytes": 57136,
4327
- "sha256": "02e6f66afcfad5b117ea9a801c7153466f24c6d5721da1546f286aa046c548f1"
4326
+ "bytes": 58392,
4327
+ "sha256": "543e10c205be62f5be78704fe9bf27e808fc07ffe035382e3d4dd78ffa8c80cc"
4328
4328
  },
4329
4329
  {
4330
4330
  "path": "skills/loom-resume/.loom-runtime/shared/scripts/loom_check.py",
@@ -4943,8 +4943,8 @@
4943
4943
  },
4944
4944
  {
4945
4945
  "path": "skills/loom-retire/.loom-runtime/shared/scripts/governance_surface.py",
4946
- "bytes": 57136,
4947
- "sha256": "02e6f66afcfad5b117ea9a801c7153466f24c6d5721da1546f286aa046c548f1"
4946
+ "bytes": 58392,
4947
+ "sha256": "543e10c205be62f5be78704fe9bf27e808fc07ffe035382e3d4dd78ffa8c80cc"
4948
4948
  },
4949
4949
  {
4950
4950
  "path": "skills/loom-retire/.loom-runtime/shared/scripts/loom_check.py",
@@ -5563,8 +5563,8 @@
5563
5563
  },
5564
5564
  {
5565
5565
  "path": "skills/loom-review/.loom-runtime/shared/scripts/governance_surface.py",
5566
- "bytes": 57136,
5567
- "sha256": "02e6f66afcfad5b117ea9a801c7153466f24c6d5721da1546f286aa046c548f1"
5566
+ "bytes": 58392,
5567
+ "sha256": "543e10c205be62f5be78704fe9bf27e808fc07ffe035382e3d4dd78ffa8c80cc"
5568
5568
  },
5569
5569
  {
5570
5570
  "path": "skills/loom-review/.loom-runtime/shared/scripts/loom_check.py",
@@ -6183,8 +6183,8 @@
6183
6183
  },
6184
6184
  {
6185
6185
  "path": "skills/loom-spec-review/.loom-runtime/shared/scripts/governance_surface.py",
6186
- "bytes": 57136,
6187
- "sha256": "02e6f66afcfad5b117ea9a801c7153466f24c6d5721da1546f286aa046c548f1"
6186
+ "bytes": 58392,
6187
+ "sha256": "543e10c205be62f5be78704fe9bf27e808fc07ffe035382e3d4dd78ffa8c80cc"
6188
6188
  },
6189
6189
  {
6190
6190
  "path": "skills/loom-spec-review/.loom-runtime/shared/scripts/loom_check.py",
@@ -1004,6 +1004,35 @@ def active_entry_points(root: Path) -> dict[str, str]:
1004
1004
  return active
1005
1005
 
1006
1006
 
1007
+ def bootstrap_host_binding_branch(root: Path) -> str:
1008
+ init_result = root / ".loom/bootstrap/init-result.json"
1009
+ try:
1010
+ payload = json.loads(init_result.read_text(encoding="utf-8"))
1011
+ except (OSError, json.JSONDecodeError):
1012
+ return ""
1013
+ if not isinstance(payload, dict):
1014
+ return ""
1015
+ governance_surface = payload.get("governance_surface")
1016
+ if not isinstance(governance_surface, dict):
1017
+ return ""
1018
+ control_plane = governance_surface.get("governance_control_plane")
1019
+ if not isinstance(control_plane, dict):
1020
+ return ""
1021
+ host_binding = control_plane.get("host_binding")
1022
+ if not isinstance(host_binding, dict):
1023
+ return ""
1024
+ required_objects = host_binding.get("required_objects")
1025
+ if not isinstance(required_objects, dict):
1026
+ return ""
1027
+ branch = required_objects.get("branch")
1028
+ if not isinstance(branch, dict):
1029
+ return ""
1030
+ locator = branch.get("locator")
1031
+ if isinstance(locator, str) and locator.strip() and locator != "unknown":
1032
+ return locator.strip()
1033
+ return ""
1034
+
1035
+
1007
1036
  def detect_carrier_summary(root: Path, *, repository_mode: str, planning_mode: bool) -> dict[str, dict[str, str]]:
1008
1037
  active = active_entry_points(root)
1009
1038
  active_item_id = active.get("current_item_id") or "INIT-0001"
@@ -1140,6 +1169,11 @@ def detect_host_binding_surface(
1140
1169
  ) -> dict[str, Any]:
1141
1170
  branch_result = run_process(["git", "branch", "--show-current"], root)
1142
1171
  branch = branch_result.stdout.strip() if branch_result.returncode == 0 else ""
1172
+ branch_authority = "git"
1173
+ if not branch:
1174
+ branch = bootstrap_host_binding_branch(root)
1175
+ if branch:
1176
+ branch_authority = "bootstrap host binding"
1143
1177
  worktree_result = run_process(["git", "rev-parse", "--show-toplevel"], root)
1144
1178
  worktree = worktree_result.stdout.strip() if worktree_result.returncode == 0 else ""
1145
1179
  default_branch = github_control_plane.get("default_branch")
@@ -1152,7 +1186,7 @@ def detect_host_binding_surface(
1152
1186
  "branch": {
1153
1187
  "status": "present" if branch else "missing",
1154
1188
  "locator": branch or "unknown",
1155
- "authority": "git",
1189
+ "authority": branch_authority,
1156
1190
  },
1157
1191
  "worktree": {
1158
1192
  "status": "present" if worktree else "missing",
@@ -1004,6 +1004,35 @@ def active_entry_points(root: Path) -> dict[str, str]:
1004
1004
  return active
1005
1005
 
1006
1006
 
1007
+ def bootstrap_host_binding_branch(root: Path) -> str:
1008
+ init_result = root / ".loom/bootstrap/init-result.json"
1009
+ try:
1010
+ payload = json.loads(init_result.read_text(encoding="utf-8"))
1011
+ except (OSError, json.JSONDecodeError):
1012
+ return ""
1013
+ if not isinstance(payload, dict):
1014
+ return ""
1015
+ governance_surface = payload.get("governance_surface")
1016
+ if not isinstance(governance_surface, dict):
1017
+ return ""
1018
+ control_plane = governance_surface.get("governance_control_plane")
1019
+ if not isinstance(control_plane, dict):
1020
+ return ""
1021
+ host_binding = control_plane.get("host_binding")
1022
+ if not isinstance(host_binding, dict):
1023
+ return ""
1024
+ required_objects = host_binding.get("required_objects")
1025
+ if not isinstance(required_objects, dict):
1026
+ return ""
1027
+ branch = required_objects.get("branch")
1028
+ if not isinstance(branch, dict):
1029
+ return ""
1030
+ locator = branch.get("locator")
1031
+ if isinstance(locator, str) and locator.strip() and locator != "unknown":
1032
+ return locator.strip()
1033
+ return ""
1034
+
1035
+
1007
1036
  def detect_carrier_summary(root: Path, *, repository_mode: str, planning_mode: bool) -> dict[str, dict[str, str]]:
1008
1037
  active = active_entry_points(root)
1009
1038
  active_item_id = active.get("current_item_id") or "INIT-0001"
@@ -1140,6 +1169,11 @@ def detect_host_binding_surface(
1140
1169
  ) -> dict[str, Any]:
1141
1170
  branch_result = run_process(["git", "branch", "--show-current"], root)
1142
1171
  branch = branch_result.stdout.strip() if branch_result.returncode == 0 else ""
1172
+ branch_authority = "git"
1173
+ if not branch:
1174
+ branch = bootstrap_host_binding_branch(root)
1175
+ if branch:
1176
+ branch_authority = "bootstrap host binding"
1143
1177
  worktree_result = run_process(["git", "rev-parse", "--show-toplevel"], root)
1144
1178
  worktree = worktree_result.stdout.strip() if worktree_result.returncode == 0 else ""
1145
1179
  default_branch = github_control_plane.get("default_branch")
@@ -1152,7 +1186,7 @@ def detect_host_binding_surface(
1152
1186
  "branch": {
1153
1187
  "status": "present" if branch else "missing",
1154
1188
  "locator": branch or "unknown",
1155
- "authority": "git",
1189
+ "authority": branch_authority,
1156
1190
  },
1157
1191
  "worktree": {
1158
1192
  "status": "present" if worktree else "missing",
@@ -1004,6 +1004,35 @@ def active_entry_points(root: Path) -> dict[str, str]:
1004
1004
  return active
1005
1005
 
1006
1006
 
1007
+ def bootstrap_host_binding_branch(root: Path) -> str:
1008
+ init_result = root / ".loom/bootstrap/init-result.json"
1009
+ try:
1010
+ payload = json.loads(init_result.read_text(encoding="utf-8"))
1011
+ except (OSError, json.JSONDecodeError):
1012
+ return ""
1013
+ if not isinstance(payload, dict):
1014
+ return ""
1015
+ governance_surface = payload.get("governance_surface")
1016
+ if not isinstance(governance_surface, dict):
1017
+ return ""
1018
+ control_plane = governance_surface.get("governance_control_plane")
1019
+ if not isinstance(control_plane, dict):
1020
+ return ""
1021
+ host_binding = control_plane.get("host_binding")
1022
+ if not isinstance(host_binding, dict):
1023
+ return ""
1024
+ required_objects = host_binding.get("required_objects")
1025
+ if not isinstance(required_objects, dict):
1026
+ return ""
1027
+ branch = required_objects.get("branch")
1028
+ if not isinstance(branch, dict):
1029
+ return ""
1030
+ locator = branch.get("locator")
1031
+ if isinstance(locator, str) and locator.strip() and locator != "unknown":
1032
+ return locator.strip()
1033
+ return ""
1034
+
1035
+
1007
1036
  def detect_carrier_summary(root: Path, *, repository_mode: str, planning_mode: bool) -> dict[str, dict[str, str]]:
1008
1037
  active = active_entry_points(root)
1009
1038
  active_item_id = active.get("current_item_id") or "INIT-0001"
@@ -1140,6 +1169,11 @@ def detect_host_binding_surface(
1140
1169
  ) -> dict[str, Any]:
1141
1170
  branch_result = run_process(["git", "branch", "--show-current"], root)
1142
1171
  branch = branch_result.stdout.strip() if branch_result.returncode == 0 else ""
1172
+ branch_authority = "git"
1173
+ if not branch:
1174
+ branch = bootstrap_host_binding_branch(root)
1175
+ if branch:
1176
+ branch_authority = "bootstrap host binding"
1143
1177
  worktree_result = run_process(["git", "rev-parse", "--show-toplevel"], root)
1144
1178
  worktree = worktree_result.stdout.strip() if worktree_result.returncode == 0 else ""
1145
1179
  default_branch = github_control_plane.get("default_branch")
@@ -1152,7 +1186,7 @@ def detect_host_binding_surface(
1152
1186
  "branch": {
1153
1187
  "status": "present" if branch else "missing",
1154
1188
  "locator": branch or "unknown",
1155
- "authority": "git",
1189
+ "authority": branch_authority,
1156
1190
  },
1157
1191
  "worktree": {
1158
1192
  "status": "present" if worktree else "missing",
@@ -1004,6 +1004,35 @@ def active_entry_points(root: Path) -> dict[str, str]:
1004
1004
  return active
1005
1005
 
1006
1006
 
1007
+ def bootstrap_host_binding_branch(root: Path) -> str:
1008
+ init_result = root / ".loom/bootstrap/init-result.json"
1009
+ try:
1010
+ payload = json.loads(init_result.read_text(encoding="utf-8"))
1011
+ except (OSError, json.JSONDecodeError):
1012
+ return ""
1013
+ if not isinstance(payload, dict):
1014
+ return ""
1015
+ governance_surface = payload.get("governance_surface")
1016
+ if not isinstance(governance_surface, dict):
1017
+ return ""
1018
+ control_plane = governance_surface.get("governance_control_plane")
1019
+ if not isinstance(control_plane, dict):
1020
+ return ""
1021
+ host_binding = control_plane.get("host_binding")
1022
+ if not isinstance(host_binding, dict):
1023
+ return ""
1024
+ required_objects = host_binding.get("required_objects")
1025
+ if not isinstance(required_objects, dict):
1026
+ return ""
1027
+ branch = required_objects.get("branch")
1028
+ if not isinstance(branch, dict):
1029
+ return ""
1030
+ locator = branch.get("locator")
1031
+ if isinstance(locator, str) and locator.strip() and locator != "unknown":
1032
+ return locator.strip()
1033
+ return ""
1034
+
1035
+
1007
1036
  def detect_carrier_summary(root: Path, *, repository_mode: str, planning_mode: bool) -> dict[str, dict[str, str]]:
1008
1037
  active = active_entry_points(root)
1009
1038
  active_item_id = active.get("current_item_id") or "INIT-0001"
@@ -1140,6 +1169,11 @@ def detect_host_binding_surface(
1140
1169
  ) -> dict[str, Any]:
1141
1170
  branch_result = run_process(["git", "branch", "--show-current"], root)
1142
1171
  branch = branch_result.stdout.strip() if branch_result.returncode == 0 else ""
1172
+ branch_authority = "git"
1173
+ if not branch:
1174
+ branch = bootstrap_host_binding_branch(root)
1175
+ if branch:
1176
+ branch_authority = "bootstrap host binding"
1143
1177
  worktree_result = run_process(["git", "rev-parse", "--show-toplevel"], root)
1144
1178
  worktree = worktree_result.stdout.strip() if worktree_result.returncode == 0 else ""
1145
1179
  default_branch = github_control_plane.get("default_branch")
@@ -1152,7 +1186,7 @@ def detect_host_binding_surface(
1152
1186
  "branch": {
1153
1187
  "status": "present" if branch else "missing",
1154
1188
  "locator": branch or "unknown",
1155
- "authority": "git",
1189
+ "authority": branch_authority,
1156
1190
  },
1157
1191
  "worktree": {
1158
1192
  "status": "present" if worktree else "missing",
@@ -1004,6 +1004,35 @@ def active_entry_points(root: Path) -> dict[str, str]:
1004
1004
  return active
1005
1005
 
1006
1006
 
1007
+ def bootstrap_host_binding_branch(root: Path) -> str:
1008
+ init_result = root / ".loom/bootstrap/init-result.json"
1009
+ try:
1010
+ payload = json.loads(init_result.read_text(encoding="utf-8"))
1011
+ except (OSError, json.JSONDecodeError):
1012
+ return ""
1013
+ if not isinstance(payload, dict):
1014
+ return ""
1015
+ governance_surface = payload.get("governance_surface")
1016
+ if not isinstance(governance_surface, dict):
1017
+ return ""
1018
+ control_plane = governance_surface.get("governance_control_plane")
1019
+ if not isinstance(control_plane, dict):
1020
+ return ""
1021
+ host_binding = control_plane.get("host_binding")
1022
+ if not isinstance(host_binding, dict):
1023
+ return ""
1024
+ required_objects = host_binding.get("required_objects")
1025
+ if not isinstance(required_objects, dict):
1026
+ return ""
1027
+ branch = required_objects.get("branch")
1028
+ if not isinstance(branch, dict):
1029
+ return ""
1030
+ locator = branch.get("locator")
1031
+ if isinstance(locator, str) and locator.strip() and locator != "unknown":
1032
+ return locator.strip()
1033
+ return ""
1034
+
1035
+
1007
1036
  def detect_carrier_summary(root: Path, *, repository_mode: str, planning_mode: bool) -> dict[str, dict[str, str]]:
1008
1037
  active = active_entry_points(root)
1009
1038
  active_item_id = active.get("current_item_id") or "INIT-0001"
@@ -1140,6 +1169,11 @@ def detect_host_binding_surface(
1140
1169
  ) -> dict[str, Any]:
1141
1170
  branch_result = run_process(["git", "branch", "--show-current"], root)
1142
1171
  branch = branch_result.stdout.strip() if branch_result.returncode == 0 else ""
1172
+ branch_authority = "git"
1173
+ if not branch:
1174
+ branch = bootstrap_host_binding_branch(root)
1175
+ if branch:
1176
+ branch_authority = "bootstrap host binding"
1143
1177
  worktree_result = run_process(["git", "rev-parse", "--show-toplevel"], root)
1144
1178
  worktree = worktree_result.stdout.strip() if worktree_result.returncode == 0 else ""
1145
1179
  default_branch = github_control_plane.get("default_branch")
@@ -1152,7 +1186,7 @@ def detect_host_binding_surface(
1152
1186
  "branch": {
1153
1187
  "status": "present" if branch else "missing",
1154
1188
  "locator": branch or "unknown",
1155
- "authority": "git",
1189
+ "authority": branch_authority,
1156
1190
  },
1157
1191
  "worktree": {
1158
1192
  "status": "present" if worktree else "missing",
@@ -1004,6 +1004,35 @@ def active_entry_points(root: Path) -> dict[str, str]:
1004
1004
  return active
1005
1005
 
1006
1006
 
1007
+ def bootstrap_host_binding_branch(root: Path) -> str:
1008
+ init_result = root / ".loom/bootstrap/init-result.json"
1009
+ try:
1010
+ payload = json.loads(init_result.read_text(encoding="utf-8"))
1011
+ except (OSError, json.JSONDecodeError):
1012
+ return ""
1013
+ if not isinstance(payload, dict):
1014
+ return ""
1015
+ governance_surface = payload.get("governance_surface")
1016
+ if not isinstance(governance_surface, dict):
1017
+ return ""
1018
+ control_plane = governance_surface.get("governance_control_plane")
1019
+ if not isinstance(control_plane, dict):
1020
+ return ""
1021
+ host_binding = control_plane.get("host_binding")
1022
+ if not isinstance(host_binding, dict):
1023
+ return ""
1024
+ required_objects = host_binding.get("required_objects")
1025
+ if not isinstance(required_objects, dict):
1026
+ return ""
1027
+ branch = required_objects.get("branch")
1028
+ if not isinstance(branch, dict):
1029
+ return ""
1030
+ locator = branch.get("locator")
1031
+ if isinstance(locator, str) and locator.strip() and locator != "unknown":
1032
+ return locator.strip()
1033
+ return ""
1034
+
1035
+
1007
1036
  def detect_carrier_summary(root: Path, *, repository_mode: str, planning_mode: bool) -> dict[str, dict[str, str]]:
1008
1037
  active = active_entry_points(root)
1009
1038
  active_item_id = active.get("current_item_id") or "INIT-0001"
@@ -1140,6 +1169,11 @@ def detect_host_binding_surface(
1140
1169
  ) -> dict[str, Any]:
1141
1170
  branch_result = run_process(["git", "branch", "--show-current"], root)
1142
1171
  branch = branch_result.stdout.strip() if branch_result.returncode == 0 else ""
1172
+ branch_authority = "git"
1173
+ if not branch:
1174
+ branch = bootstrap_host_binding_branch(root)
1175
+ if branch:
1176
+ branch_authority = "bootstrap host binding"
1143
1177
  worktree_result = run_process(["git", "rev-parse", "--show-toplevel"], root)
1144
1178
  worktree = worktree_result.stdout.strip() if worktree_result.returncode == 0 else ""
1145
1179
  default_branch = github_control_plane.get("default_branch")
@@ -1152,7 +1186,7 @@ def detect_host_binding_surface(
1152
1186
  "branch": {
1153
1187
  "status": "present" if branch else "missing",
1154
1188
  "locator": branch or "unknown",
1155
- "authority": "git",
1189
+ "authority": branch_authority,
1156
1190
  },
1157
1191
  "worktree": {
1158
1192
  "status": "present" if worktree else "missing",
@@ -1004,6 +1004,35 @@ def active_entry_points(root: Path) -> dict[str, str]:
1004
1004
  return active
1005
1005
 
1006
1006
 
1007
+ def bootstrap_host_binding_branch(root: Path) -> str:
1008
+ init_result = root / ".loom/bootstrap/init-result.json"
1009
+ try:
1010
+ payload = json.loads(init_result.read_text(encoding="utf-8"))
1011
+ except (OSError, json.JSONDecodeError):
1012
+ return ""
1013
+ if not isinstance(payload, dict):
1014
+ return ""
1015
+ governance_surface = payload.get("governance_surface")
1016
+ if not isinstance(governance_surface, dict):
1017
+ return ""
1018
+ control_plane = governance_surface.get("governance_control_plane")
1019
+ if not isinstance(control_plane, dict):
1020
+ return ""
1021
+ host_binding = control_plane.get("host_binding")
1022
+ if not isinstance(host_binding, dict):
1023
+ return ""
1024
+ required_objects = host_binding.get("required_objects")
1025
+ if not isinstance(required_objects, dict):
1026
+ return ""
1027
+ branch = required_objects.get("branch")
1028
+ if not isinstance(branch, dict):
1029
+ return ""
1030
+ locator = branch.get("locator")
1031
+ if isinstance(locator, str) and locator.strip() and locator != "unknown":
1032
+ return locator.strip()
1033
+ return ""
1034
+
1035
+
1007
1036
  def detect_carrier_summary(root: Path, *, repository_mode: str, planning_mode: bool) -> dict[str, dict[str, str]]:
1008
1037
  active = active_entry_points(root)
1009
1038
  active_item_id = active.get("current_item_id") or "INIT-0001"
@@ -1140,6 +1169,11 @@ def detect_host_binding_surface(
1140
1169
  ) -> dict[str, Any]:
1141
1170
  branch_result = run_process(["git", "branch", "--show-current"], root)
1142
1171
  branch = branch_result.stdout.strip() if branch_result.returncode == 0 else ""
1172
+ branch_authority = "git"
1173
+ if not branch:
1174
+ branch = bootstrap_host_binding_branch(root)
1175
+ if branch:
1176
+ branch_authority = "bootstrap host binding"
1143
1177
  worktree_result = run_process(["git", "rev-parse", "--show-toplevel"], root)
1144
1178
  worktree = worktree_result.stdout.strip() if worktree_result.returncode == 0 else ""
1145
1179
  default_branch = github_control_plane.get("default_branch")
@@ -1152,7 +1186,7 @@ def detect_host_binding_surface(
1152
1186
  "branch": {
1153
1187
  "status": "present" if branch else "missing",
1154
1188
  "locator": branch or "unknown",
1155
- "authority": "git",
1189
+ "authority": branch_authority,
1156
1190
  },
1157
1191
  "worktree": {
1158
1192
  "status": "present" if worktree else "missing",
@@ -1004,6 +1004,35 @@ def active_entry_points(root: Path) -> dict[str, str]:
1004
1004
  return active
1005
1005
 
1006
1006
 
1007
+ def bootstrap_host_binding_branch(root: Path) -> str:
1008
+ init_result = root / ".loom/bootstrap/init-result.json"
1009
+ try:
1010
+ payload = json.loads(init_result.read_text(encoding="utf-8"))
1011
+ except (OSError, json.JSONDecodeError):
1012
+ return ""
1013
+ if not isinstance(payload, dict):
1014
+ return ""
1015
+ governance_surface = payload.get("governance_surface")
1016
+ if not isinstance(governance_surface, dict):
1017
+ return ""
1018
+ control_plane = governance_surface.get("governance_control_plane")
1019
+ if not isinstance(control_plane, dict):
1020
+ return ""
1021
+ host_binding = control_plane.get("host_binding")
1022
+ if not isinstance(host_binding, dict):
1023
+ return ""
1024
+ required_objects = host_binding.get("required_objects")
1025
+ if not isinstance(required_objects, dict):
1026
+ return ""
1027
+ branch = required_objects.get("branch")
1028
+ if not isinstance(branch, dict):
1029
+ return ""
1030
+ locator = branch.get("locator")
1031
+ if isinstance(locator, str) and locator.strip() and locator != "unknown":
1032
+ return locator.strip()
1033
+ return ""
1034
+
1035
+
1007
1036
  def detect_carrier_summary(root: Path, *, repository_mode: str, planning_mode: bool) -> dict[str, dict[str, str]]:
1008
1037
  active = active_entry_points(root)
1009
1038
  active_item_id = active.get("current_item_id") or "INIT-0001"
@@ -1140,6 +1169,11 @@ def detect_host_binding_surface(
1140
1169
  ) -> dict[str, Any]:
1141
1170
  branch_result = run_process(["git", "branch", "--show-current"], root)
1142
1171
  branch = branch_result.stdout.strip() if branch_result.returncode == 0 else ""
1172
+ branch_authority = "git"
1173
+ if not branch:
1174
+ branch = bootstrap_host_binding_branch(root)
1175
+ if branch:
1176
+ branch_authority = "bootstrap host binding"
1143
1177
  worktree_result = run_process(["git", "rev-parse", "--show-toplevel"], root)
1144
1178
  worktree = worktree_result.stdout.strip() if worktree_result.returncode == 0 else ""
1145
1179
  default_branch = github_control_plane.get("default_branch")
@@ -1152,7 +1186,7 @@ def detect_host_binding_surface(
1152
1186
  "branch": {
1153
1187
  "status": "present" if branch else "missing",
1154
1188
  "locator": branch or "unknown",
1155
- "authority": "git",
1189
+ "authority": branch_authority,
1156
1190
  },
1157
1191
  "worktree": {
1158
1192
  "status": "present" if worktree else "missing",
@@ -1004,6 +1004,35 @@ def active_entry_points(root: Path) -> dict[str, str]:
1004
1004
  return active
1005
1005
 
1006
1006
 
1007
+ def bootstrap_host_binding_branch(root: Path) -> str:
1008
+ init_result = root / ".loom/bootstrap/init-result.json"
1009
+ try:
1010
+ payload = json.loads(init_result.read_text(encoding="utf-8"))
1011
+ except (OSError, json.JSONDecodeError):
1012
+ return ""
1013
+ if not isinstance(payload, dict):
1014
+ return ""
1015
+ governance_surface = payload.get("governance_surface")
1016
+ if not isinstance(governance_surface, dict):
1017
+ return ""
1018
+ control_plane = governance_surface.get("governance_control_plane")
1019
+ if not isinstance(control_plane, dict):
1020
+ return ""
1021
+ host_binding = control_plane.get("host_binding")
1022
+ if not isinstance(host_binding, dict):
1023
+ return ""
1024
+ required_objects = host_binding.get("required_objects")
1025
+ if not isinstance(required_objects, dict):
1026
+ return ""
1027
+ branch = required_objects.get("branch")
1028
+ if not isinstance(branch, dict):
1029
+ return ""
1030
+ locator = branch.get("locator")
1031
+ if isinstance(locator, str) and locator.strip() and locator != "unknown":
1032
+ return locator.strip()
1033
+ return ""
1034
+
1035
+
1007
1036
  def detect_carrier_summary(root: Path, *, repository_mode: str, planning_mode: bool) -> dict[str, dict[str, str]]:
1008
1037
  active = active_entry_points(root)
1009
1038
  active_item_id = active.get("current_item_id") or "INIT-0001"
@@ -1140,6 +1169,11 @@ def detect_host_binding_surface(
1140
1169
  ) -> dict[str, Any]:
1141
1170
  branch_result = run_process(["git", "branch", "--show-current"], root)
1142
1171
  branch = branch_result.stdout.strip() if branch_result.returncode == 0 else ""
1172
+ branch_authority = "git"
1173
+ if not branch:
1174
+ branch = bootstrap_host_binding_branch(root)
1175
+ if branch:
1176
+ branch_authority = "bootstrap host binding"
1143
1177
  worktree_result = run_process(["git", "rev-parse", "--show-toplevel"], root)
1144
1178
  worktree = worktree_result.stdout.strip() if worktree_result.returncode == 0 else ""
1145
1179
  default_branch = github_control_plane.get("default_branch")
@@ -1152,7 +1186,7 @@ def detect_host_binding_surface(
1152
1186
  "branch": {
1153
1187
  "status": "present" if branch else "missing",
1154
1188
  "locator": branch or "unknown",
1155
- "authority": "git",
1189
+ "authority": branch_authority,
1156
1190
  },
1157
1191
  "worktree": {
1158
1192
  "status": "present" if worktree else "missing",
@@ -1004,6 +1004,35 @@ def active_entry_points(root: Path) -> dict[str, str]:
1004
1004
  return active
1005
1005
 
1006
1006
 
1007
+ def bootstrap_host_binding_branch(root: Path) -> str:
1008
+ init_result = root / ".loom/bootstrap/init-result.json"
1009
+ try:
1010
+ payload = json.loads(init_result.read_text(encoding="utf-8"))
1011
+ except (OSError, json.JSONDecodeError):
1012
+ return ""
1013
+ if not isinstance(payload, dict):
1014
+ return ""
1015
+ governance_surface = payload.get("governance_surface")
1016
+ if not isinstance(governance_surface, dict):
1017
+ return ""
1018
+ control_plane = governance_surface.get("governance_control_plane")
1019
+ if not isinstance(control_plane, dict):
1020
+ return ""
1021
+ host_binding = control_plane.get("host_binding")
1022
+ if not isinstance(host_binding, dict):
1023
+ return ""
1024
+ required_objects = host_binding.get("required_objects")
1025
+ if not isinstance(required_objects, dict):
1026
+ return ""
1027
+ branch = required_objects.get("branch")
1028
+ if not isinstance(branch, dict):
1029
+ return ""
1030
+ locator = branch.get("locator")
1031
+ if isinstance(locator, str) and locator.strip() and locator != "unknown":
1032
+ return locator.strip()
1033
+ return ""
1034
+
1035
+
1007
1036
  def detect_carrier_summary(root: Path, *, repository_mode: str, planning_mode: bool) -> dict[str, dict[str, str]]:
1008
1037
  active = active_entry_points(root)
1009
1038
  active_item_id = active.get("current_item_id") or "INIT-0001"
@@ -1140,6 +1169,11 @@ def detect_host_binding_surface(
1140
1169
  ) -> dict[str, Any]:
1141
1170
  branch_result = run_process(["git", "branch", "--show-current"], root)
1142
1171
  branch = branch_result.stdout.strip() if branch_result.returncode == 0 else ""
1172
+ branch_authority = "git"
1173
+ if not branch:
1174
+ branch = bootstrap_host_binding_branch(root)
1175
+ if branch:
1176
+ branch_authority = "bootstrap host binding"
1143
1177
  worktree_result = run_process(["git", "rev-parse", "--show-toplevel"], root)
1144
1178
  worktree = worktree_result.stdout.strip() if worktree_result.returncode == 0 else ""
1145
1179
  default_branch = github_control_plane.get("default_branch")
@@ -1152,7 +1186,7 @@ def detect_host_binding_surface(
1152
1186
  "branch": {
1153
1187
  "status": "present" if branch else "missing",
1154
1188
  "locator": branch or "unknown",
1155
- "authority": "git",
1189
+ "authority": branch_authority,
1156
1190
  },
1157
1191
  "worktree": {
1158
1192
  "status": "present" if worktree else "missing",