@opengsd/gsd-path 1.6.1 → 1.7.0

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 (275) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/DOCS.md +27 -1
  3. package/FULL.md +2 -1
  4. package/HOOKS.md +38 -4
  5. package/QUICK.md +1 -1
  6. package/README.md +20 -29
  7. package/RUNTIME.md +5 -3
  8. package/WORKFLOW.md +9 -2
  9. package/package.json +1 -1
  10. package/scripts/_common.py +76 -2
  11. package/scripts/archive_milestone.py +129 -7
  12. package/scripts/build_recovery.py +25 -2
  13. package/scripts/build_state.py +333 -8
  14. package/scripts/check_handoffs.py +437 -30
  15. package/scripts/check_task_briefs.py +135 -11
  16. package/scripts/discussion_validate.py +46 -10
  17. package/scripts/dispatch_driver.py +28 -3
  18. package/scripts/git_guard.py +44 -4
  19. package/scripts/guard_hook.py +456 -9
  20. package/scripts/install.py +34 -4
  21. package/scripts/integration.py +196 -39
  22. package/scripts/isolation.py +1015 -37
  23. package/scripts/lean_verification.py +33 -14
  24. package/scripts/loop_run.py +9 -4
  25. package/scripts/members.py +17 -3
  26. package/scripts/pipeline_diagnose.py +104 -1
  27. package/scripts/pipeline_state.py +10 -2
  28. package/scripts/runtime_store.py +88 -3
  29. package/scripts/state_checkpoint.py +15 -0
  30. package/scripts/status_runtime.py +73 -2
  31. package/scripts/workflow_run.py +10 -3
  32. package/scripts/worktree_paths.py +45 -0
  33. package/skills/gsd-path/BUILD.md +5 -1
  34. package/skills/gsd-path/DEFINE.md +2 -1
  35. package/skills/gsd-path/PLAN.md +10 -0
  36. package/skills/gsd-path/SHIP.md +43 -9
  37. package/skills/gsd-path/SKILL.md +16 -1
  38. package/skills/gsd-path/references/build-native.md +20 -3
  39. package/skills/gsd-path/references/coder.md +6 -3
  40. package/skills/gsd-path/references/reviewer-final.md +10 -0
  41. package/skills/gsd-path/references/reviewer-wave.md +61 -22
  42. package/skills/gsd-path/references/reviewer.md +8 -6
  43. package/skills/gsd-path/references/runtime-selection.md +36 -0
  44. package/skills/gsd-path/references/spec-probes.md +19 -1
  45. package/skills/gsd-path/scripts/_common.py +76 -2
  46. package/skills/gsd-path/scripts/archive_milestone.py +129 -7
  47. package/skills/gsd-path/scripts/build_recovery.py +25 -2
  48. package/skills/gsd-path/scripts/build_state.py +333 -8
  49. package/skills/gsd-path/scripts/check_handoffs.py +437 -30
  50. package/skills/gsd-path/scripts/check_task_briefs.py +135 -11
  51. package/skills/gsd-path/scripts/discussion_validate.py +46 -10
  52. package/skills/gsd-path/scripts/dispatch_driver.py +28 -3
  53. package/skills/gsd-path/scripts/git_guard.py +44 -4
  54. package/skills/gsd-path/scripts/integration.py +196 -39
  55. package/skills/gsd-path/scripts/isolation.py +1015 -37
  56. package/skills/gsd-path/scripts/lean_verification.py +33 -14
  57. package/skills/gsd-path/scripts/loop_run.py +9 -4
  58. package/skills/gsd-path/scripts/members.py +17 -3
  59. package/skills/gsd-path/scripts/pipeline_state.py +10 -2
  60. package/skills/gsd-path/scripts/state_checkpoint.py +15 -0
  61. package/skills/gsd-path/scripts/status_runtime.py +73 -2
  62. package/skills/gsd-path/scripts/workflow_run.py +10 -3
  63. package/skills/gsd-path/scripts/worktree_paths.py +45 -0
  64. package/skills/gsd-path/templates/intent.md +5 -3
  65. package/skills/gsd-path/templates/task.md +8 -1
  66. package/skills/gsd-path/templates/wave-review.md +24 -8
  67. package/skills/gsd-path-build/SKILL.md +5 -1
  68. package/skills/gsd-path-build/references/build-native.md +20 -3
  69. package/skills/gsd-path-build/references/coder.md +6 -3
  70. package/skills/gsd-path-build/references/reviewer-final.md +10 -0
  71. package/skills/gsd-path-build/references/reviewer-wave.md +61 -22
  72. package/skills/gsd-path-build/references/reviewer.md +8 -6
  73. package/skills/gsd-path-build/references/runtime-selection.md +36 -0
  74. package/skills/gsd-path-build/references/spec-probes.md +19 -1
  75. package/skills/gsd-path-build/scripts/_common.py +76 -2
  76. package/skills/gsd-path-build/scripts/archive_milestone.py +129 -7
  77. package/skills/gsd-path-build/scripts/build_recovery.py +25 -2
  78. package/skills/gsd-path-build/scripts/build_state.py +333 -8
  79. package/skills/gsd-path-build/scripts/check_handoffs.py +437 -30
  80. package/skills/gsd-path-build/scripts/check_task_briefs.py +135 -11
  81. package/skills/gsd-path-build/scripts/discussion_validate.py +46 -10
  82. package/skills/gsd-path-build/scripts/dispatch_driver.py +28 -3
  83. package/skills/gsd-path-build/scripts/integration.py +196 -39
  84. package/skills/gsd-path-build/scripts/isolation.py +1015 -37
  85. package/skills/gsd-path-build/scripts/loop_run.py +9 -4
  86. package/skills/gsd-path-build/scripts/members.py +17 -3
  87. package/skills/gsd-path-build/scripts/pipeline_state.py +10 -2
  88. package/skills/gsd-path-build/scripts/state_checkpoint.py +15 -0
  89. package/skills/gsd-path-build/scripts/workflow_run.py +10 -3
  90. package/skills/gsd-path-build/scripts/worktree_paths.py +45 -0
  91. package/skills/gsd-path-build/templates/task.md +8 -1
  92. package/skills/gsd-path-build/templates/wave-review.md +24 -8
  93. package/skills/gsd-path-decide/references/runtime-selection.md +36 -0
  94. package/skills/gsd-path-decide/scripts/_common.py +76 -2
  95. package/skills/gsd-path-decide/scripts/archive_milestone.py +129 -7
  96. package/skills/gsd-path-decide/scripts/build_recovery.py +25 -2
  97. package/skills/gsd-path-decide/scripts/check_handoffs.py +437 -30
  98. package/skills/gsd-path-decide/scripts/check_task_briefs.py +135 -11
  99. package/skills/gsd-path-decide/scripts/discussion_validate.py +46 -10
  100. package/skills/gsd-path-decide/scripts/integration.py +196 -39
  101. package/skills/gsd-path-decide/scripts/isolation.py +1015 -37
  102. package/skills/gsd-path-decide/scripts/loop_run.py +9 -4
  103. package/skills/gsd-path-decide/scripts/members.py +17 -3
  104. package/skills/gsd-path-decide/scripts/pipeline_state.py +10 -2
  105. package/skills/gsd-path-decide/scripts/state_checkpoint.py +15 -0
  106. package/skills/gsd-path-decide/scripts/worktree_paths.py +45 -0
  107. package/skills/gsd-path-define/SKILL.md +2 -1
  108. package/skills/gsd-path-define/references/runtime-selection.md +36 -0
  109. package/skills/gsd-path-define/references/spec-probes.md +19 -1
  110. package/skills/gsd-path-define/scripts/_common.py +76 -2
  111. package/skills/gsd-path-define/scripts/archive_milestone.py +129 -7
  112. package/skills/gsd-path-define/scripts/build_recovery.py +25 -2
  113. package/skills/gsd-path-define/scripts/check_handoffs.py +437 -30
  114. package/skills/gsd-path-define/scripts/check_task_briefs.py +135 -11
  115. package/skills/gsd-path-define/scripts/discussion_validate.py +46 -10
  116. package/skills/gsd-path-define/scripts/integration.py +196 -39
  117. package/skills/gsd-path-define/scripts/isolation.py +1015 -37
  118. package/skills/gsd-path-define/scripts/loop_run.py +9 -4
  119. package/skills/gsd-path-define/scripts/members.py +17 -3
  120. package/skills/gsd-path-define/scripts/pipeline_state.py +10 -2
  121. package/skills/gsd-path-define/scripts/state_checkpoint.py +15 -0
  122. package/skills/gsd-path-define/scripts/worktree_paths.py +45 -0
  123. package/skills/gsd-path-define/templates/intent.md +5 -3
  124. package/skills/gsd-path-discuss/references/runtime-selection.md +36 -0
  125. package/skills/gsd-path-discuss/scripts/_common.py +76 -2
  126. package/skills/gsd-path-discuss/scripts/loop_run.py +9 -4
  127. package/skills/gsd-path-discuss/scripts/worktree_paths.py +45 -0
  128. package/skills/gsd-path-docs-audit/references/runtime-selection.md +36 -0
  129. package/skills/gsd-path-docs-audit/scripts/_common.py +76 -2
  130. package/skills/gsd-path-docs-audit/scripts/archive_milestone.py +129 -7
  131. package/skills/gsd-path-docs-audit/scripts/build_recovery.py +25 -2
  132. package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +437 -30
  133. package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +135 -11
  134. package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +46 -10
  135. package/skills/gsd-path-docs-audit/scripts/integration.py +196 -39
  136. package/skills/gsd-path-docs-audit/scripts/isolation.py +1015 -37
  137. package/skills/gsd-path-docs-audit/scripts/loop_run.py +9 -4
  138. package/skills/gsd-path-docs-audit/scripts/members.py +17 -3
  139. package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +10 -2
  140. package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +15 -0
  141. package/skills/gsd-path-docs-audit/scripts/worktree_paths.py +45 -0
  142. package/skills/gsd-path-forensics/references/runtime-selection.md +36 -0
  143. package/skills/gsd-path-forensics/scripts/_common.py +76 -2
  144. package/skills/gsd-path-forensics/scripts/loop_run.py +9 -4
  145. package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +104 -1
  146. package/skills/gsd-path-forensics/scripts/worktree_paths.py +45 -0
  147. package/skills/gsd-path-inspect/references/runtime-selection.md +36 -0
  148. package/skills/gsd-path-inspect/scripts/_common.py +76 -2
  149. package/skills/gsd-path-inspect/scripts/archive_milestone.py +129 -7
  150. package/skills/gsd-path-inspect/scripts/build_recovery.py +25 -2
  151. package/skills/gsd-path-inspect/scripts/check_handoffs.py +437 -30
  152. package/skills/gsd-path-inspect/scripts/check_task_briefs.py +135 -11
  153. package/skills/gsd-path-inspect/scripts/discussion_validate.py +46 -10
  154. package/skills/gsd-path-inspect/scripts/integration.py +196 -39
  155. package/skills/gsd-path-inspect/scripts/isolation.py +1015 -37
  156. package/skills/gsd-path-inspect/scripts/loop_run.py +9 -4
  157. package/skills/gsd-path-inspect/scripts/members.py +17 -3
  158. package/skills/gsd-path-inspect/scripts/pipeline_state.py +10 -2
  159. package/skills/gsd-path-inspect/scripts/state_checkpoint.py +15 -0
  160. package/skills/gsd-path-inspect/scripts/workflow_run.py +10 -3
  161. package/skills/gsd-path-inspect/scripts/worktree_paths.py +45 -0
  162. package/skills/gsd-path-loop/references/runtime-selection.md +36 -0
  163. package/skills/gsd-path-loop/scripts/_common.py +76 -2
  164. package/skills/gsd-path-loop/scripts/loop_run.py +9 -4
  165. package/skills/gsd-path-loop/scripts/worktree_paths.py +45 -0
  166. package/skills/gsd-path-migrate/references/runtime-selection.md +36 -0
  167. package/skills/gsd-path-migrate/scripts/_common.py +76 -2
  168. package/skills/gsd-path-migrate/scripts/loop_run.py +9 -4
  169. package/skills/gsd-path-plan/SKILL.md +10 -0
  170. package/skills/gsd-path-plan/references/runtime-selection.md +36 -0
  171. package/skills/gsd-path-plan/references/spec-probes.md +19 -1
  172. package/skills/gsd-path-plan/scripts/_common.py +76 -2
  173. package/skills/gsd-path-plan/scripts/archive_milestone.py +129 -7
  174. package/skills/gsd-path-plan/scripts/build_recovery.py +25 -2
  175. package/skills/gsd-path-plan/scripts/check_handoffs.py +437 -30
  176. package/skills/gsd-path-plan/scripts/check_task_briefs.py +135 -11
  177. package/skills/gsd-path-plan/scripts/discussion_validate.py +46 -10
  178. package/skills/gsd-path-plan/scripts/integration.py +196 -39
  179. package/skills/gsd-path-plan/scripts/isolation.py +1015 -37
  180. package/skills/gsd-path-plan/scripts/loop_run.py +9 -4
  181. package/skills/gsd-path-plan/scripts/members.py +17 -3
  182. package/skills/gsd-path-plan/scripts/pipeline_state.py +10 -2
  183. package/skills/gsd-path-plan/scripts/state_checkpoint.py +15 -0
  184. package/skills/gsd-path-plan/scripts/workflow_run.py +10 -3
  185. package/skills/gsd-path-plan/scripts/worktree_paths.py +45 -0
  186. package/skills/gsd-path-plan/templates/task.md +8 -1
  187. package/skills/gsd-path-research/references/runtime-selection.md +36 -0
  188. package/skills/gsd-path-research/scripts/_common.py +76 -2
  189. package/skills/gsd-path-research/scripts/archive_milestone.py +129 -7
  190. package/skills/gsd-path-research/scripts/build_recovery.py +25 -2
  191. package/skills/gsd-path-research/scripts/check_handoffs.py +437 -30
  192. package/skills/gsd-path-research/scripts/check_task_briefs.py +135 -11
  193. package/skills/gsd-path-research/scripts/discussion_validate.py +46 -10
  194. package/skills/gsd-path-research/scripts/integration.py +196 -39
  195. package/skills/gsd-path-research/scripts/isolation.py +1015 -37
  196. package/skills/gsd-path-research/scripts/loop_run.py +9 -4
  197. package/skills/gsd-path-research/scripts/members.py +17 -3
  198. package/skills/gsd-path-research/scripts/pipeline_state.py +10 -2
  199. package/skills/gsd-path-research/scripts/state_checkpoint.py +15 -0
  200. package/skills/gsd-path-research/scripts/worktree_paths.py +45 -0
  201. package/skills/gsd-path-roadmap/references/runtime-selection.md +36 -0
  202. package/skills/gsd-path-roadmap/scripts/_common.py +76 -2
  203. package/skills/gsd-path-roadmap/scripts/archive_milestone.py +129 -7
  204. package/skills/gsd-path-roadmap/scripts/build_recovery.py +25 -2
  205. package/skills/gsd-path-roadmap/scripts/check_handoffs.py +437 -30
  206. package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +135 -11
  207. package/skills/gsd-path-roadmap/scripts/discussion_validate.py +46 -10
  208. package/skills/gsd-path-roadmap/scripts/integration.py +196 -39
  209. package/skills/gsd-path-roadmap/scripts/isolation.py +1015 -37
  210. package/skills/gsd-path-roadmap/scripts/loop_run.py +9 -4
  211. package/skills/gsd-path-roadmap/scripts/members.py +17 -3
  212. package/skills/gsd-path-roadmap/scripts/pipeline_state.py +10 -2
  213. package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +15 -0
  214. package/skills/gsd-path-roadmap/scripts/worktree_paths.py +45 -0
  215. package/skills/gsd-path-ship/SKILL.md +43 -9
  216. package/skills/gsd-path-ship/references/reviewer-final.md +10 -0
  217. package/skills/gsd-path-ship/references/reviewer-wave.md +61 -22
  218. package/skills/gsd-path-ship/references/reviewer.md +8 -6
  219. package/skills/gsd-path-ship/references/runtime-selection.md +36 -0
  220. package/skills/gsd-path-ship/references/spec-probes.md +19 -1
  221. package/skills/gsd-path-ship/scripts/_common.py +76 -2
  222. package/skills/gsd-path-ship/scripts/archive_milestone.py +129 -7
  223. package/skills/gsd-path-ship/scripts/build_recovery.py +25 -2
  224. package/skills/gsd-path-ship/scripts/build_state.py +333 -8
  225. package/skills/gsd-path-ship/scripts/check_handoffs.py +437 -30
  226. package/skills/gsd-path-ship/scripts/check_task_briefs.py +135 -11
  227. package/skills/gsd-path-ship/scripts/discussion_validate.py +46 -10
  228. package/skills/gsd-path-ship/scripts/integration.py +196 -39
  229. package/skills/gsd-path-ship/scripts/isolation.py +1015 -37
  230. package/skills/gsd-path-ship/scripts/lean_verification.py +33 -14
  231. package/skills/gsd-path-ship/scripts/loop_run.py +9 -4
  232. package/skills/gsd-path-ship/scripts/members.py +17 -3
  233. package/skills/gsd-path-ship/scripts/pipeline_state.py +10 -2
  234. package/skills/gsd-path-ship/scripts/state_checkpoint.py +15 -0
  235. package/skills/gsd-path-ship/scripts/workflow_run.py +10 -3
  236. package/skills/gsd-path-ship/scripts/worktree_paths.py +45 -0
  237. package/skills/gsd-path-ship/templates/wave-review.md +24 -8
  238. package/skills/gsd-path-undo/references/runtime-selection.md +36 -0
  239. package/skills/gsd-path-undo/scripts/_common.py +76 -2
  240. package/skills/gsd-path-undo/scripts/loop_run.py +9 -4
  241. package/skills/gsd-path-undo/scripts/worktree_paths.py +45 -0
  242. package/skills/path/BUILD.md +5 -1
  243. package/skills/path/DEFINE.md +2 -1
  244. package/skills/path/PLAN.md +10 -0
  245. package/skills/path/SHIP.md +43 -9
  246. package/skills/path/SKILL.md +16 -1
  247. package/skills/path/references/build-native.md +20 -3
  248. package/skills/path/references/coder.md +6 -3
  249. package/skills/path/references/reviewer-final.md +10 -0
  250. package/skills/path/references/reviewer-wave.md +61 -22
  251. package/skills/path/references/reviewer.md +8 -6
  252. package/skills/path/references/runtime-selection.md +36 -0
  253. package/skills/path/references/spec-probes.md +19 -1
  254. package/skills/path/scripts/_common.py +76 -2
  255. package/skills/path/scripts/archive_milestone.py +129 -7
  256. package/skills/path/scripts/build_recovery.py +25 -2
  257. package/skills/path/scripts/build_state.py +333 -8
  258. package/skills/path/scripts/check_handoffs.py +437 -30
  259. package/skills/path/scripts/check_task_briefs.py +135 -11
  260. package/skills/path/scripts/discussion_validate.py +46 -10
  261. package/skills/path/scripts/dispatch_driver.py +28 -3
  262. package/skills/path/scripts/git_guard.py +44 -4
  263. package/skills/path/scripts/integration.py +196 -39
  264. package/skills/path/scripts/isolation.py +1015 -37
  265. package/skills/path/scripts/lean_verification.py +33 -14
  266. package/skills/path/scripts/loop_run.py +9 -4
  267. package/skills/path/scripts/members.py +17 -3
  268. package/skills/path/scripts/pipeline_state.py +10 -2
  269. package/skills/path/scripts/state_checkpoint.py +15 -0
  270. package/skills/path/scripts/status_runtime.py +73 -2
  271. package/skills/path/scripts/workflow_run.py +10 -3
  272. package/skills/path/scripts/worktree_paths.py +45 -0
  273. package/skills/path/templates/intent.md +5 -3
  274. package/skills/path/templates/task.md +8 -1
  275. package/skills/path/templates/wave-review.md +24 -8
@@ -7,11 +7,13 @@ import sys
7
7
  # Runtime helpers must not modify their immutable installation.
8
8
  sys.dont_write_bytecode = True
9
9
 
10
+ import contextlib
10
11
  import hashlib
11
12
  import json
12
13
  import os
13
14
  import tempfile
14
15
  from pathlib import Path
16
+ from typing import Optional
15
17
 
16
18
  if __package__:
17
19
  from . import _common
@@ -22,7 +24,39 @@ else:
22
24
  from scripts import _common
23
25
 
24
26
 
27
+ # Run-scoped cache for read-only consumers (#469): recovery resolves a
28
+ # placement per task, and each resolution lists the whole worktree registry
29
+ # and re-reads the placement receipt. Within one read-only run none of that
30
+ # can change, so the listing and the derived workspace answer once. Flows
31
+ # that create, move, or retire worktrees never enter this scope.
32
+ _PLACEMENT_CACHE: Optional[dict] = None
33
+
34
+
35
+ @contextlib.contextmanager
36
+ def readonly_placement_cache():
37
+ global _PLACEMENT_CACHE
38
+ if _PLACEMENT_CACHE is not None: # already inside a read-only run
39
+ yield
40
+ return
41
+ _PLACEMENT_CACHE = {"porcelain": {}, "workspace": {}}
42
+ try:
43
+ yield
44
+ finally:
45
+ _PLACEMENT_CACHE = None
46
+
47
+
25
48
  def _worktree_list_porcelain(primary: Path) -> tuple[str, bool]:
49
+ if _PLACEMENT_CACHE is not None:
50
+ key = str(primary)
51
+ if key in _PLACEMENT_CACHE["porcelain"]:
52
+ return _PLACEMENT_CACHE["porcelain"][key] # type: ignore[index]
53
+ output = _worktree_list_porcelain_uncached(primary)
54
+ _PLACEMENT_CACHE["porcelain"][key] = output
55
+ return output
56
+ return _worktree_list_porcelain_uncached(primary)
57
+
58
+
59
+ def _worktree_list_porcelain_uncached(primary: Path) -> tuple[str, bool]:
26
60
  try:
27
61
  if __package__:
28
62
  from . import pipeline_git as pg
@@ -58,6 +92,17 @@ def _identity(path: Path) -> str:
58
92
 
59
93
 
60
94
  def _workspace(primary: Path, pin: bool) -> Path:
95
+ if _PLACEMENT_CACHE is not None and not pin:
96
+ key = str(primary)
97
+ if key in _PLACEMENT_CACHE["workspace"]:
98
+ return _PLACEMENT_CACHE["workspace"][key] # type: ignore[index]
99
+ workspace = _workspace_uncached(primary, False)
100
+ _PLACEMENT_CACHE["workspace"][key] = workspace
101
+ return workspace
102
+ return _workspace_uncached(primary, pin)
103
+
104
+
105
+ def _workspace_uncached(primary: Path, pin: bool) -> Path:
61
106
  common = Path(_git(primary, "rev-parse", "--git-common-dir"))
62
107
  common = (primary / common).resolve()
63
108
  identity = _identity(primary)
@@ -130,7 +130,11 @@ STATE.md-only "finalize" checkpoint for work already checkpointed. The helper
130
130
  refuses a `build:` checkpoint that deletes or renames a `.project/tasks/`
131
131
  brief unless the canonical `build: abandon milestone <slug>` checkpoint moves
132
132
  that same brief into `.project/archive/`; build adds fix tasks and repairs
133
- briefs, it never replans.
133
+ briefs, it never replans. It also refuses a `build:` checkpoint while the
134
+ committed STATE is `ship/active`: final-review outputs stay uncommitted until
135
+ the ship commit. The one exception is the patch re-entry checkpoint: the
136
+ worktree STATE is `build/active` and its Log ends with `patch plan reopened`,
137
+ `patch plan approved`, `build started`.
134
138
 
135
139
  ## Execute from runtime receipts
136
140
 
@@ -273,7 +273,8 @@ question. The rules change for every primary mode:
273
273
  for kept prohibitions, each with a recommended ruling first. A ruling
274
274
  observable where the user sees the work becomes or amends a success
275
275
  criterion; write every ruling into `## Edge coverage` and
276
- `## Prohibitions`. Program mode skips this step (each milestone runs it
276
+ `## Prohibitions`. Bound every absence criterion in the edge round
277
+ (search space, check, absent result). Program mode skips this step (each milestone runs it
277
278
  in milestone mode); milestone mode runs it inside its confirmation.
278
279
  7. Classify the proposed milestone lane before writing the approval draft.
279
280
  Milestone mode keeps `Lane: milestone` and skips this classification.
@@ -114,6 +114,11 @@ as stated in Lookahead mode.
114
114
  `worktree: null`, and `task_branch: null` values on every new task.
115
115
  In patch mode, tasks already `done` keep their landed metadata; only
116
116
  the appended patch tasks must start clean.
117
+ - A `status: withdrawn` task is an owner-ruled tombstone: its file and id
118
+ stay in place, it is never dispatched, and its Log must carry a
119
+ `Withdrawn — <date>: <owner ruling verbatim>` entry. Reject an uncited
120
+ tombstone, a dependent that is not `done` or withdrawn, and an SC it
121
+ still owns; re-own or remove that SC through a Define INTENT Correction.
117
122
  - Require every dependency id to exist, forbid later-wave dependencies,
118
123
  detect cycles, and forbid unordered file overlap between planned tasks
119
124
  in the same wave. Same-wave tasks may share files only when one
@@ -266,6 +271,11 @@ as stated in Lookahead mode.
266
271
  A landed brief is immutable history: the helper checks its `files` scope
267
272
  at the recorded historical base and does not check the paths that its
268
273
  prose and Verify name.
274
+ Approval also refuses unsupported `.project/` entries (anything outside
275
+ the fixed set of state files and milestone directories): remove or
276
+ relocate them first — a staged `git rm` already satisfies the gate and
277
+ the approval checkpoint commits the removal. Task `files` may not
278
+ declare anything under `.project/`.
269
279
  This applies to plan re-approval too; the dispatch CLI remains HEAD-only
270
280
  with no overrides.
271
281
 
@@ -69,7 +69,8 @@ so the position is unchanged. Then:
69
69
  task logs prove it is the immediately preceding `ship/blocked` finding
70
70
  set, the approved patch tasks copied every finding verbatim, and those tasks
71
71
  are now done; otherwise it blocks. Git history preserves the superseded
72
- finding, while final review itself still creates no pre-ship commit.
72
+ finding, while final review itself still creates no pre-ship commit
73
+ (`isolation.py checkpoint` refuses a `build:` checkpoint at `ship/active`).
73
74
  2. Derive a stable numbered list of cross-wave integration risks from
74
75
  interfaces and flows that span waves. List only genuine risks that could
75
76
  plausibly fail; never pad the list. Include PLAN.md's project Verify as
@@ -89,7 +90,14 @@ so the position is unchanged. Then:
89
90
  head and holds the exact output; there is no reusable ledger entry.
90
91
  Single-repo re-entry at the same command and commit reuses the execution,
91
92
  including a failed one, and finishes interrupted collection without running
92
- the command again.
93
+ the command again. The one exception is an owner-diagnosed host failure (for
94
+ example a host toolchain version the project does not pin): re-run
95
+ `workflow_run.py prepare-final` with `--rerun` to retire the recorded
96
+ execution, run the command again, and append a second ledger entry marked
97
+ `rerun` — the failed entry stays as history. Product failures never take
98
+ `--rerun`; they go through the patch plan. The sidecar inherits the
99
+ orchestrator environment, PATH included, by design: the Verify must run the
100
+ project's own toolchain, so a host/PATH mismatch is a host failure.
93
101
  Missing legacy output requires evidence reconciliation, not a blind rerun.
94
102
  Any non-zero result stops this step; preserve its stderr and diagnose through
95
103
  the bundled forensics contract. Do not launch reviewers while project Verify
@@ -145,7 +153,8 @@ so the position is unchanged. Then:
145
153
  verdict `met` with a non-`none` Check or Reference, and every criterion
146
154
  listed in PLAN.md's Surface contract requires a matching `Surface` field
147
155
  and a non-`none` Check. A non-zero exit is
148
- `ship/blocked`; never rerun project Verify to repair the evidence.
156
+ `ship/blocked`; never rerun project Verify to repair the evidence (a
157
+ host-caused command failure uses the `prepare-final --rerun` route above).
149
158
  6. Redispatch one complete corrected brief for a missing or invalid reviewer
150
159
  artifact under the same logical task name, following the runtime dispatch
151
160
  contract. Before dispatch, record the invalid destination's exact SHA-256.
@@ -274,7 +283,16 @@ The persisted `STATE.archive` field is the transaction identity.
274
283
  `awaiting-merge`, report the member PR
275
284
  link, stop, and rerun the same command after the user merges it; never
276
285
  merge a member PR yourself. When it returns `integrated`, keep its `body`
277
- for the ship commit below.
286
+ for the ship commit below. When it refuses with
287
+ `member reviewed HEAD reached <default> outside Path`, the member's work
288
+ was already published past its reviewed HEAD by an earlier user-approved
289
+ step: present the member, its reviewed HEAD, and the live default-branch
290
+ tip, and ask the user whether to adopt that landing. Only on an explicit
291
+ user approval rerun the same command with
292
+ `--adopt-landed-member <member>=<live tip SHA>`; the helper then publishes
293
+ the bound branch and an `adopted-landing` milestone tag at that tip and
294
+ makes no merge. A mismatched or stale SHA is refused, and a later rerun
295
+ validates the adoption without the flag.
278
296
  5. Only after preflight passes, record shipment through the journaled helper;
279
297
  for a program it atomically replaces both ROADMAP.md and STATE.md, setting
280
298
  the current entry to `Status: shipped` with the exact `Archive:` pointer:
@@ -329,7 +347,13 @@ The persisted `STATE.archive` field is the transaction identity.
329
347
  `build/rebase-adoption.json`) may advance the ref from the adopted head
330
348
  to its immediate, canonical `.project/`-only ship child under an exact-SHA
331
349
  lease after the helper proves the clean ship state, receipt, and archived
332
- tasks. Every other value blocks. If origin/main advances
350
+ tasks, and a strict ancestor of the ship commit — a build task may have
351
+ legitimately pushed the bound branch as a deploy pin (#464) — is adopted
352
+ only after the user approves, by rerunning with
353
+ `integrate --adopt-published-bound <live 40-hex SHA>`; the helper requires
354
+ the SHA to equal the live tip exactly and fast-forwards under the same
355
+ exact lease, and direct integration only. Every other value blocks. If
356
+ origin/main advances
333
357
  after the local merge but rejects the push, a retry may discard and
334
358
  rebuild only the unpublished canonical merge and tag under the helper's
335
359
  existing recovery checks.
@@ -416,10 +440,15 @@ Run this recovery setup from a separate checkout, outside the closed primary
416
440
  worktree's guard.
417
441
 
418
442
  1. Create separate disposable trust and validation checkouts from the same
419
- published origin and `STATE.branch`. This separation is required because an
420
- explicit runtime upgrade changes the trust checkout's declaration and launcher,
421
- while archive validation requires a clean checkout. Never use the primary
422
- worktree for either role.
443
+ published origin and its default branch (checking out `STATE.branch` when
444
+ it still exists; a rebase-merged pull request may have deleted it). This
445
+ separation is required because an explicit runtime upgrade changes the
446
+ trust checkout's declaration and launcher, while archive validation
447
+ requires a clean checkout. Never use the primary worktree for either role.
448
+ A rebase-merged milestone additionally needs the original ship commits to
449
+ resolve — use a checkout that fetched and retained them (the primary
450
+ always does; a clone that never fetched the bound branch does not), and a
451
+ checkout whose originals were collected cannot carry a full validation.
423
452
  2. From the trusted fixed GSD Path checkout, preview and then explicitly upgrade only the
424
453
  disposable trust checkout's managed trust anchor:
425
454
 
@@ -447,6 +476,11 @@ worktree's guard.
447
476
  python3 -B <verified-runtime>/archive_milestone.py validate-integrated --repo <validation-root> --slug <STATE.milestone>
448
477
  ```
449
478
 
479
+ When the validation checkout is on the default branch after the milestone
480
+ closed (the bound branch is gone), pass `--historical`; a rebase-merged
481
+ landing is then accepted only through the milestone tag's Ship/Landing
482
+ pair plus a re-proven rebase replay.
483
+
450
484
  4. A pass restores the normal shipped handoff without another commit or
451
485
  publication action. Remove only the disposable checkouts. A failure is a
452
486
  new validation finding: report it with the primary worktree's archived
@@ -227,7 +227,9 @@ A coordinator project can change other repositories (members) in the same
227
227
  milestone; `.project/MEMBERS.md` lists them. Change members only at a
228
228
  milestone boundary, never during build or ship. Resolve the bundled
229
229
  `scripts/members.py` to an absolute path and use it; never edit MEMBERS.md
230
- or a member marker by hand.
230
+ or a member marker by hand (the one exception is adding the optional
231
+ `Prepare:` row below through a reviewed change — `members.py` has no
232
+ subcommand for it yet).
231
233
 
232
234
  - To add an existing repository, it needs a GitHub.com `origin`, a clean
233
235
  worktree, and no active milestone of its own. Its default branch can have
@@ -240,6 +242,19 @@ or a member marker by hand.
240
242
  When `validate` or member close later reports
241
243
  `remote default must be <recorded>`, stop and report it; never edit the
242
244
  record.
245
+ - A member whose isolates need more than tracked files — uninitialized
246
+ submodules, gitignored build inputs — declares a `Prepare:` command in its
247
+ MEMBERS.md row (added by editing the committed file through a reviewed
248
+ change; `members.py` validates it like any field). The runtime runs it
249
+ inside every fresh member isolate, task or verify, before any Verify: it
250
+ must provision by copying from the member's primary checkout, never by
251
+ linking (retirement defuses links, and a link would let the isolate mutate
252
+ shared inputs). For submodules, the offline recipe is
253
+ `git config submodule.<name>.url <primary>/.git/modules/<name> && git -c protocol.file.allow=always submodule update --init <name>`
254
+ — it reads the primary's object store and touches no network. A failed
255
+ Prepare fails the isolation loudly with its output before a Verify runs.
256
+ Retained isolates keep their provisioning: a re-authorized rerun does not
257
+ Prepare again.
243
258
  - To create a new member repository, present the exact `owner/name`,
244
259
  visibility, and checkout path as the **Review** surface and get approval
245
260
  first, as for a new GitHub repository. Then run the same command with
@@ -207,7 +207,16 @@ dispatch contract and perform steps 1–5 by hand.
207
207
  its exact base prove the remaining branch before deletion. Create the retry
208
208
  from the new clean primary HEAD. A member task (`repo: <member>`) stays
209
209
  `pending` in the coordinator; its rejected attempt lives in the member
210
- sidecar. Copy the live copy's Log delta into the coordinator task file,
210
+ sidecar. When the failure was environmental — the isolate could not build
211
+ a Verify for reasons outside the product, and the coder fixed the
212
+ environment inside the retained sidecar — do not re-isolate: rerun
213
+ `python3 <absolute isolation.py> activate-member-task --repo <absolute
214
+ primary> --member <member> --task-id <id> --reauthorize` after checking
215
+ that the live copy's Log stayed append-only and the member base is
216
+ unchanged; it re-arms the authorization the failed finish cleared, and the
217
+ next `finish` runs the full Verify set once and lands (#461). A
218
+ product-failure rejection instead follows the full retry: copy the live
219
+ copy's Log delta into the coordinator task file,
211
220
  checkpoint it, then retire the sidecar with `python3 <absolute isolation.py>
212
221
  retire-member-task --repo <absolute primary> --member <member> --task-id
213
222
  <id> --task-file <task path> --force`. It refuses until the committed task
@@ -231,7 +240,11 @@ dispatch contract and perform steps 1–5 by hand.
231
240
  `python3 <absolute check_handoffs.py> plan --repo <absolute repo root>`
232
241
  before creating any worktree; a lint or coverage failure is a documented plan
233
242
  defect — repair it against INTENT.md and SYNTHESIS.md, then re-establish
234
- the base. Then isolate each ready task with
243
+ the base. The brief lint is read-only and idempotent; it reports progress
244
+ on stderr (one line every 20 tasks) and its stdout is exactly the result
245
+ JSON. A host timeout that cut it off with no failure output is not a
246
+ contract verdict — rerun it with a larger timeout and judge only the
247
+ completed run. Then isolate each ready task with
235
248
  `python3 <absolute workflow_run.py> prepare-task --repo <absolute primary>
236
249
  --expected-head <recorded base> --task-id <id> --round-size <N>` where N is the
237
250
  number of tasks in this dispatch round. For a coordinator task, serial
@@ -619,7 +632,11 @@ dispatch contract and perform steps 1–5 by hand.
619
632
  Log waiver — or, in program flow (ROADMAP.md exists), to abandon the
620
633
  milestone under the Milestone abandon procedure — listing the
621
634
  orchestrator's recommended option first marked `(recommended)` with a
622
- one-line reason drawn from the review evidence. Never choose silently.
635
+ one-line reason drawn from the review evidence. When the cap cycle is
636
+ later than 1 and a blocking group in its `groups` has `first_seen_cycle`
637
+ 1, recommend sending it
638
+ to define: fix cycles since cycle 1 have not closed that criterion, so it
639
+ is likely unbounded. Never choose silently.
623
640
  When the canonical verdict is `pass` and `wave-N.cycleC.panel.md` reports
624
641
  `Actionable` greater than 0, do not advance silently: present **Outcome**
625
642
  with the canonical pass plus the actionable count, **Review** linking the
@@ -35,7 +35,10 @@ reality:
35
35
  item in INTENT.md `## Success criteria`.
36
36
  - Confirm your Interface contract text appears verbatim in every sibling
37
37
  task file it exchanges with. Sibling task files under `.project/tasks/`
38
- are readable in your worktree — read-only; never edit them.
38
+ are readable in your worktree — read-only; never edit them. On a member
39
+ task the orchestrator pins them under
40
+ `.gsd-path-coordinator/.project/tasks/` beside your live task copy —
41
+ read them there.
39
42
  - Confirm every path the Verify command references exists or is declared.
40
43
 
41
44
  Route any mismatch before writing a line of product code: a clear defect — a
@@ -86,8 +89,8 @@ them.
86
89
 
87
90
  - You are not alone in the repository. Other agents may use sibling worktrees;
88
91
  do not inspect, revert, or overwrite their changes.
89
- - Never edit `base`, `worktree`, `task_branch`, `status`, or `agent`.
90
- The orchestrator owns them.
92
+ - Never edit `base`, `worktree`, `task_branch`, `status`, `agent`, or
93
+ `member_base` (member tasks). The orchestrator owns them.
91
94
  - Never stage, commit, amend, rebase, reset, or otherwise mutate Git.
92
95
  - Never add an unnamed dependency, weaken verification, or improve adjacent
93
96
  code.
@@ -1,6 +1,16 @@
1
1
  ## Final integration mode
2
2
 
3
3
  Use only final-review.md. Treat INTENT.md success criteria as the rubric.
4
+ To locate each task's authoritative accepted evidence instead of joining
5
+ task Logs, ledger rows, and gap artifacts by hand, run
6
+ `python3 <absolute build_state.py> evidence-manifest --repo
7
+ <absolute primary> --project-dir .project --head <reviewed HEAD>`:
8
+ it classifies every task as `ledger`, `log-only`, `rejected`,
9
+ `superseded`, or `missing` and names the receipt, and reports the member
10
+ project Verify as `gap-embedded` only from a passing `final-gap-1.md` at
11
+ the reviewed HEAD — a
12
+ `log-only` task is accepted through its retained isolated-Verify Log, and
13
+ an absent ledger row is explained, never treated as data loss.
4
14
  Each `### SCn —` heading must have every word of the criterion in INTENT.md
5
15
  `## Success criteria`: join indented continuation lines and sub-bullets
6
16
  with a single space. You can keep or remove the `- ` markers of the
@@ -8,19 +8,45 @@ tasks in this wave as the rubric. For each task:
8
8
  Never infer either SHA from task ids, branch position, or nearby history.
9
9
  2. Fail a missing, malformed, or invalid SHA. Inspect the commit with
10
10
  `git show --format=fuller --stat --patch <commit> --`.
11
- 3. In the supplied verify sidecar at `base`, apply only the complete
12
- binary patch from `commit^..commit` for the task's declared product files
13
- and inspect the diff. Use the orchestrator's recorded isolated Verify
14
- output in that task's Log as the Verify evidence. Do not re-run the
15
- task Verify command or PLAN.md's project Verify. Re-run a command only
16
- when the recorded output plus the isolated diff cannot check the
17
- criterion. Never use the primary worktree or branch tip as task
18
- evidence. Do not create or remove Git worktrees yourself.
19
- 4. Mark `pass` or `fail`. Before the evidence separator (` — `), copy the
20
- complete task acceptance or interface criterion (see Review file format
21
- below). Do not substitute an AC id or summary: finding grouping binds
22
- this text to the task. Give the observed result, `file:line`, and
11
+ 3. Select the inspection mode your brief supplies and record it — never
12
+ improvise a third:
13
+ - **Reconstructed product** (default): the brief supplies a verify
14
+ sidecar at `base`. In it, apply only the complete binary patch from
15
+ `commit^..commit` for the task's declared product files and inspect
16
+ the diff. Use the orchestrator's recorded isolated Verify output in
17
+ that task's Log as the Verify evidence.
18
+ - **Immutable patch**: the brief supplies one later combined checkout
19
+ with report-write authority only. Inspect the immutable objects
20
+ directly — `git show`/`git diff` on the recorded commits — and prove
21
+ the identity before judging: (a) the landing commit's parent
22
+ `commit^` equals the task file's recorded `base` (or the patch's
23
+ resulting blobs at `base` equal the landing commit's blobs for the
24
+ declared files), and (b) any file judged from the combined checkout
25
+ has its blob there equal to the landing commit's blob at that path.
26
+ Without both identities the review blocks: a mismatch means the
27
+ supplied checkout is not the reviewed product.
28
+ In both modes: do not re-run the task Verify command or PLAN.md's
29
+ project Verify; re-run a command only when the recorded output plus
30
+ the diff cannot check the criterion. Never use the primary worktree
31
+ or branch tip as task evidence. Do not create or remove Git worktrees
32
+ yourself.
33
+ 4. Mark `pass` or `fail`. Before the evidence separator (` — `), name the
34
+ criterion (see Review file format below): copy the complete task
35
+ acceptance or interface criterion verbatim, or — on a `pass` line only —
36
+ cite the criterion by its stable id in the task's numbered acceptance or
37
+ interface list (`T012/AC3`, `T012/IF2`) together with the evidence. A
38
+ `fail` line always copies the criterion verbatim: finding grouping binds
39
+ that text to the task. Give the observed result, `file:line`, and
23
40
  concrete fix direction for each failure.
41
+ 5. Account for every claim. Each acceptance criterion (`T012/AC3`) and
42
+ interface bullet (`T012/IF2`) of the task must appear in its
43
+ section as an evidence reference, a finding, or an explicitly
44
+ authorized disposition — a bare line naming the id with
45
+ `disposition: <authority and date> (<Cn>): <reason>`, where `Cn` is a
46
+ numbered INTENT.md correction. No citation, or a `Cn` that
47
+ `## Corrections` does not define, fails the gate. One observation may
48
+ support several claims when each is identified by its id. The wave gate
49
+ rejects a review that leaves a claim unaccounted for.
24
50
 
25
51
  A Log entry `orchestrator regression Verify of <task id> retired: superseded
26
52
  by <task id>` is not evidence: judge the superseding task's acceptance
@@ -30,8 +56,12 @@ criteria. The same applies to the entry `orchestrator regression Verify of
30
56
  Then check each INTENT.md success criterion owned by a task in this wave
31
57
  against that same isolated product. In each `### SCn —` heading, copy the
32
58
  complete criterion text from INTENT.md `## Success criteria` (see Review
33
- file format below). Mark `pass` or `fail` with evidence; a failed owned SC
34
- blocks the wave. Omit the Intent coverage section when no task in the wave owns
59
+ file format below). Write the headings in ascending SC id order (SC2 before
60
+ SC4), and separate the id from the text with an em dash (—). Mark `pass`
61
+ or `fail` with evidence; a failed owned SC blocks the wave. Under a `pass`
62
+ SC, record each subclaim a numbered INTENT.md correction excludes as
63
+ `- Excluded by <Cn>: <subclaim>`; the gate rejects an exclusion under a
64
+ failing SC or one that cites an undefined correction. Omit the Intent coverage section when no task in the wave owns
35
65
  an SC. When INTENT.md `## Edge coverage` or `## Prohibitions` has rows for
36
66
  an owned SC, judge it against those rulings too: cite each `held-out` edge
37
67
  id with its held-out test's recorded output and each `judgment` prohibition
@@ -40,8 +70,12 @@ fails the SC.
40
70
 
41
71
  Allow changed paths only in the task's `files` plus its assigned task file.
42
72
  Within the task file, allow orchestrator-owned `base`, `worktree`,
43
- `task_branch`, `status`, and `agent` fields plus append-only Log
44
- entries; block contract-body changes in the task commit. Warn on disabled tests
73
+ `task_branch`, `status`, and `agent` fields — and, on a member task,
74
+ `member_base` — plus append-only Log entries; block contract-body changes
75
+ in the task commit. `base` names the task's starting commit in the
76
+ coordinator repository; `member_base` names the starting commit in the
77
+ member repository from which the member task branch and isolate were
78
+ created. Warn on disabled tests
45
79
  or Verify commands that cannot fail unless either defeats a criterion. Set the
46
80
  wave verdict to `pass` only when every task passes and every owned INTENT
47
81
  success criterion for the wave passes.
@@ -65,10 +99,14 @@ criterion text does not match. Apply the rules before you write the file.
65
99
  `- ❌ ` for fail. Each task section and each `### SCn —` block needs one
66
100
  or more lines with the marker of its own verdict. A failed task needs a
67
101
  `- ❌ ` criterion line, also when other text describes the failure.
68
- - **Criterion text.** In a task evidence line and in a `### SCn —` heading,
69
- copy every word of the criterion. Join wrapped lines and sub-bullets with
70
- one space. You can keep or remove the `- ` markers of the sub-bullets.
71
- A changed, added, removed or moved word does not match.
102
+ - **Criterion text.** In a `### SCn —` heading and on every `- ❌ ` fail
103
+ line, copy every word of the criterion. Join wrapped lines and
104
+ sub-bullets with one space. You can keep or remove the `- ` markers of
105
+ the sub-bullets. A changed, added, removed or moved word does not
106
+ match. On a `- ✅ ` pass line, name the criterion either by copying it
107
+ verbatim or by citing its stable id in the task's numbered acceptance
108
+ or interface list (`T001/AC1`, `T001/IF2`) together with the evidence;
109
+ the wave gate does not compare pass-line criterion text.
72
110
  - **Angle brackets.** Text such as `<b>` or `<path>` outside backticks reads
73
111
  as an unfilled template placeholder and is rejected. Write literal markup
74
112
  and code in backticks inside a sentence, for example: the output has
@@ -116,8 +154,9 @@ runtime checks freshness and derives the final view from these records.
116
154
  ## Deep review lenses
117
155
 
118
156
  A `deep` wave spawns two independent reviewers in parallel, each with a fresh
119
- context and its own verify sidecar at the recorded review base. Every
120
- Wave mode rule above applies to both lenses.
157
+ context and its own isolated workspace at the recorded review base (a verify
158
+ sidecar in reconstructed mode, or the supplied combined checkout in immutable
159
+ mode). Every Wave mode rule above applies to both lenses.
121
160
 
122
161
  - **Contract** — logical task name
123
162
  `review_wave_<wave>_cycle_<cycle>_contract`; stages
@@ -5,16 +5,18 @@ Verify written GSD Path expectations and block failures. Never fix code.
5
5
  ## Brief contract
6
6
 
7
7
  - Require the mode, all inputs, exact canonical output path, applicable
8
- template, repository root, and orchestrator-created verify sidecar
9
- root by absolute path. Wave mode also requires the absolute INTENT.md
10
- path. The brief must also name the staged output path under
11
- that sidecar.
8
+ template, and repository root by absolute path. Wave mode also requires
9
+ the absolute INTENT.md path and names the inspection mode: a verify
10
+ sidecar root for reconstructed-product review, or one combined checkout
11
+ with report-write authority for immutable-patch review. The brief must
12
+ also name the staged output path under that workspace.
12
13
  - Read AGENTS.md and the template before reviewing.
13
- - Write only the exact assigned review output under the supplied verify sidecar
14
+ - Write only the exact assigned review output under the supplied workspace
14
15
  at its staged `.project/review/` path. The orchestrator validates and
15
16
  atomically transfers that file to the canonical primary `.project/review/`
16
17
  path after collection. Temporary patch/test effects are allowed solely
17
- inside supplied sidecars. Never edit a product path or any other
18
+ inside supplied sidecars; an immutable-mode combined checkout carries
19
+ report-write authority only. Never edit a product path or any other
18
20
  primary-worktree path. Stop on a missing input or template.
19
21
 
20
22
  ## Load the assigned mode
@@ -20,6 +20,42 @@ references to bundled copies of those helpers. Other skill helpers, templates,
20
20
  and role briefs remain in the installed skill bundle. Pass `-B` to Python helper
21
21
  invocations so execution does not create bytecode in the runtime store.
22
22
 
23
+ When the runtime enforcing an active task cannot finish it, one narrowly
24
+ authorized recovery exists:
25
+ `python3 -B <absolute isolation.py> runtime-hotfix --repo <absolute primary>
26
+ --task-id <id> --runtime <64-hex runtime digest printed by runtime_store.py publish>
27
+ --authorized-by <the owner ruling>` validates the replacement runtime,
28
+ re-runs that task's Verify in a fresh sidecar at the recorded base under the
29
+ replacement pin, and records the receipt twice: a Log line in the task file
30
+ naming the task, base, and both runtime digests, and an identical blob behind
31
+ the local ref `refs/gsd-path/runtime-hotfix/<task>-<base>`. Only a Log line
32
+ whose exact twin that ref holds later admits `.gsd-path/runtime.json` into that
33
+ task's landing, and only when the pin names exactly the receipt's runtime; any
34
+ other task, base, a Log line alone, or a bare mention authorizes nothing, and a
35
+ failing re-run refuses the hotfix. Limits: the command serves only a serial
36
+ task working in the primary and refuses parallel or member tasks; the ref is
37
+ local repository state, so a clone without it cannot land the pin and the
38
+ proof fails closed. The guard applies two rules to agent shell commands. It
39
+ denies any command where `runtime-hotfix` directly follows `isolation.py`, stdin
40
+ `-`, or an `isolation` module operand (`-m isolation`, `-Bm isolation`,
41
+ `-misolation`). It also denies every Git command with a word, including global
42
+ `-c` options and inline variable assignments, that contains `refs/gsd-path/` or
43
+ `runtime-hotfix`. This deliberately blocks read-only uses such as
44
+ `git log refs/gsd-path/<ref>` or `git log --grep runtime-hotfix`, and commit
45
+ messages or branch names that contain `runtime-hotfix`. Limits: it cannot see a copied or renamed
46
+ `isolation.py`, a refspec stored in a Git config file, a ref write made from
47
+ inside another program, a direct edit of files under `.git/`, or shell
48
+ expansion that splits both protected words, such as
49
+ `refs/gs{d,}-path/task-authorizations/<task>`.
50
+
51
+ Publishing a runtime to the shared store is project-free:
52
+ `python3 -B <absolute runtime_store.py> publish --source <absolute package root>`
53
+ verifies and publishes the content-addressed runtime, printing its version,
54
+ digest, and store path as JSON; `--provenance` records a note in that output
55
+ only. Publication alone neither authorizes execution nor changes a project's
56
+ trusted runtime — a project runs the bytes only when its own pin names that
57
+ digest.
58
+
23
59
  The selected runtime is authoritative for each helper in its `manifest.json`;
24
60
  this includes `review_findings.py` and `task_context.py`. A selected runtime
25
61
  that was published before a helper became a runtime file does not list that
@@ -96,6 +96,23 @@ Present the kept items with a recommended ruling and record each as a row:
96
96
  Work that affects no person directly records a single row instead, and no
97
97
  other: `| N1 | all | none | dismissed | <why no person is affected> |`.
98
98
 
99
+ ## Absence criteria
100
+
101
+ A criterion that claims absence ("X does not exist", "no X anywhere",
102
+ "never Y"), including one written from a prohibition, has no end until it
103
+ says where to look. Each review can look somewhere new, so the build loops
104
+ to the cycle cap. Every absence criterion states:
105
+
106
+ - the search space: the files, surfaces, or artifacts to check;
107
+ - the check: the command or observation that covers that space;
108
+ - the absent result: the output that counts as absent.
109
+
110
+ When one is missing, propose a bounded form in the same question round as
111
+ the edges, recommended form first, and amend the criterion after the user
112
+ rules. Do not choose the search space yourself: a narrower space is a scope
113
+ ruling. Under pre-approval, an unbounded absence criterion is a required
114
+ answer: stop and ask.
115
+
99
116
  ## INTENT.md tables
100
117
 
101
118
  ```markdown
@@ -131,7 +148,8 @@ rechecked; a near-miss heading fails the gate rather than switching it off.
131
148
  the owning task's Approach so the coder knows the line.
132
149
  - **Review.** A row pins the reading of its criterion. A reviewer does not
133
150
  pass a reading that contradicts a ruling in either table, and cites each
134
- held-out edge and judgment prohibition id with its evidence.
151
+ held-out edge and judgment prohibition id with its evidence. An absence
152
+ criterion is judged over its stated search space only.
135
153
  - **Final review.** A criterion that carries a held-out edge or a judgment
136
154
  prohibition is `met` only when its Check, Observed, or Reference cites
137
155
  every such id with the evidence: the held-out test's recorded passing