@openrig/cli 0.5.3 → 0.5.5

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 (842) hide show
  1. package/daemon/assets/guidance/openrig-start.md +7 -0
  2. package/daemon/assets/onboarding/01-world-and-purpose.md +52 -0
  3. package/daemon/assets/onboarding/02-self-and-competent-action.md +57 -0
  4. package/daemon/assets/plugins/openrig-core/.claude-plugin/plugin.json +1 -1
  5. package/daemon/assets/plugins/openrig-core/.codex-plugin/plugin.json +1 -1
  6. package/daemon/assets/plugins/openrig-core/README.md +5 -2
  7. package/daemon/assets/plugins/openrig-core/hooks/claude.json +3 -12
  8. package/daemon/assets/plugins/openrig-core/hooks/codex.json +5 -12
  9. package/daemon/assets/plugins/openrig-core/hooks/scripts/refocus.cjs +196 -106
  10. package/daemon/assets/plugins/openrig-core/skills/mission-slice-sop/SKILL.md +18 -23
  11. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/CHANGELOG.md +92 -0
  12. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/REVISION-GUIDE.md +34 -0
  13. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/ROADMAP.md +23 -0
  14. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/ROLLOUT.md +234 -0
  15. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/SKILL.md +404 -0
  16. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/scripts/compose.py +653 -0
  17. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/scripts/scaffold.sh +34 -0
  18. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/scripts/trace-due.sh +32 -0
  19. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/scripts/trace-stamp.sh +5 -0
  20. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/scripts/trunk-diff.sh +18 -0
  21. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/templates/LEARNED.md +40 -0
  22. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/templates/NOTES.md +9 -0
  23. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/templates/PLAYBOOK.md +5 -0
  24. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/templates/SOP.md +24 -0
  25. package/daemon/assets/plugins/openrig-core/skills/openrig-operating-model/templates/SPEC.md +54 -0
  26. package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +5 -0
  27. package/daemon/assets/plugins/openrig-core/skills/refocusing/SKILL.md +31 -0
  28. package/daemon/assets/plugins/openrig-core/skills/refocusing/references/refocus.md +22 -0
  29. package/daemon/assets/plugins/openrig-core/skills/refocusing/scripts/trace-to-root.py +221 -0
  30. package/daemon/assets/plugins/openrig-core/skills/retiring-and-inheriting-a-seat/SKILL.md +3 -3
  31. package/daemon/assets/plugins/openrig-core/skills/software-for-agents/SKILL.md +4 -9
  32. package/daemon/context-packs/onboarding-width/manifest.yaml +11 -0
  33. package/daemon/context-packs/{world/install/reference-material.md → onboarding-width/public-reference-material.md} +4 -26
  34. package/daemon/context-packs/{world/install/what-you-can-do.md → onboarding-width/public-what-you-can-do.md} +13 -9
  35. package/daemon/context-packs/skills/core/agent-starters/manifest.yaml +1 -1
  36. package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/SKILL.md +1 -1
  37. package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/manifest.yaml +1 -1
  38. package/daemon/context-packs/skills/core/attention-queue/manifest.yaml +1 -1
  39. package/daemon/context-packs/skills/core/cross-host-rig-commands/manifest.yaml +1 -1
  40. package/daemon/context-packs/skills/core/human-in-the-loop/manifest.yaml +1 -1
  41. package/daemon/context-packs/skills/core/openrig-architect/manifest.yaml +1 -1
  42. package/daemon/context-packs/skills/core/openrig-cmux/manifest.yaml +1 -1
  43. package/daemon/context-packs/skills/core/openrig-herdr/manifest.yaml +1 -1
  44. package/daemon/context-packs/skills/core/openrig-upgrade/manifest.yaml +1 -1
  45. package/daemon/context-packs/skills/core/rig-bundles-and-shareable-artifacts/manifest.yaml +1 -1
  46. package/daemon/context-packs/skills/core/rig-lifecycle/manifest.yaml +1 -1
  47. package/daemon/context-packs/skills/core/session-source-fork/manifest.yaml +1 -1
  48. package/daemon/context-packs/skills/core/specification-system/manifest.yaml +1 -1
  49. package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/manifest.yaml +1 -1
  50. package/daemon/context-packs/skills/core/watchdog/manifest.yaml +1 -1
  51. package/daemon/context-packs/skills/pm/backlog-capture/manifest.yaml +1 -1
  52. package/daemon/context-packs/skills/pm/context-builder/manifest.yaml +1 -1
  53. package/daemon/context-packs/skills/pm/exec-summary/manifest.yaml +1 -1
  54. package/daemon/context-packs/skills/pm/office-hours/manifest.yaml +1 -1
  55. package/daemon/context-packs/skills/pm/plan-review/manifest.yaml +1 -1
  56. package/daemon/context-packs/skills/pm/requirements-writer/SKILL.md +21 -15
  57. package/daemon/context-packs/skills/pm/requirements-writer/manifest.yaml +3 -3
  58. package/daemon/context-packs/skills/pm/ui-mockup/manifest.yaml +1 -1
  59. package/daemon/context-packs/skills/pods/development-team/manifest.yaml +1 -1
  60. package/daemon/context-packs/skills/pods/orchestration-team/manifest.yaml +1 -1
  61. package/daemon/context-packs/skills/pods/oversight-team/manifest.yaml +1 -1
  62. package/daemon/context-packs/skills/pods/review-team/manifest.yaml +1 -1
  63. package/daemon/context-packs/skills/process/agent-browser/manifest.yaml +1 -1
  64. package/daemon/context-packs/skills/process/brainstorming/manifest.yaml +1 -1
  65. package/daemon/context-packs/skills/process/context-engineering/manifest.yaml +1 -1
  66. package/daemon/context-packs/skills/process/dogfood/manifest.yaml +1 -1
  67. package/daemon/context-packs/skills/process/executing-plans/manifest.yaml +1 -1
  68. package/daemon/context-packs/skills/process/frontend-design/manifest.yaml +1 -1
  69. package/daemon/context-packs/skills/process/systematic-debugging/manifest.yaml +1 -1
  70. package/daemon/context-packs/skills/process/test-driven-development/manifest.yaml +1 -1
  71. package/daemon/context-packs/skills/process/using-superpowers/manifest.yaml +1 -1
  72. package/daemon/context-packs/skills/process/verification-before-completion/manifest.yaml +1 -1
  73. package/daemon/context-packs/skills/process/writing-plans/manifest.yaml +1 -1
  74. package/daemon/context-packs/world-example/manifest.yaml +8 -0
  75. package/daemon/context-packs/world-example/your-world.md +37 -0
  76. package/daemon/dist/adapters/claude-code-adapter.d.ts +15 -0
  77. package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  78. package/daemon/dist/adapters/claude-code-adapter.js +57 -0
  79. package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  80. package/daemon/dist/adapters/tmux.d.ts +31 -0
  81. package/daemon/dist/adapters/tmux.d.ts.map +1 -1
  82. package/daemon/dist/adapters/tmux.js +31 -11
  83. package/daemon/dist/adapters/tmux.js.map +1 -1
  84. package/daemon/dist/build-info.js +3 -3
  85. package/daemon/dist/daemon-db-path.d.ts.map +1 -1
  86. package/daemon/dist/daemon-db-path.js +50 -2
  87. package/daemon/dist/daemon-db-path.js.map +1 -1
  88. package/daemon/dist/db/all-migrations.d.ts.map +1 -1
  89. package/daemon/dist/db/all-migrations.js +4 -0
  90. package/daemon/dist/db/all-migrations.js.map +1 -1
  91. package/daemon/dist/db/migrations/072_thread_seat_map.d.ts +3 -0
  92. package/daemon/dist/db/migrations/072_thread_seat_map.d.ts.map +1 -0
  93. package/daemon/dist/db/migrations/072_thread_seat_map.js +22 -0
  94. package/daemon/dist/db/migrations/072_thread_seat_map.js.map +1 -0
  95. package/daemon/dist/db/migrations/073_queue_transition_wakes.d.ts +3 -0
  96. package/daemon/dist/db/migrations/073_queue_transition_wakes.d.ts.map +1 -0
  97. package/daemon/dist/db/migrations/073_queue_transition_wakes.js +21 -0
  98. package/daemon/dist/db/migrations/073_queue_transition_wakes.js.map +1 -0
  99. package/daemon/dist/domain/activity-taxonomy.d.ts +112 -0
  100. package/daemon/dist/domain/activity-taxonomy.d.ts.map +1 -0
  101. package/daemon/dist/domain/activity-taxonomy.js +99 -0
  102. package/daemon/dist/domain/activity-taxonomy.js.map +1 -0
  103. package/daemon/dist/domain/bind-plan.d.ts +19 -0
  104. package/daemon/dist/domain/bind-plan.d.ts.map +1 -0
  105. package/daemon/dist/domain/bind-plan.js +25 -0
  106. package/daemon/dist/domain/bind-plan.js.map +1 -0
  107. package/daemon/dist/domain/event-bus.d.ts +6 -0
  108. package/daemon/dist/domain/event-bus.d.ts.map +1 -1
  109. package/daemon/dist/domain/event-bus.js +15 -5
  110. package/daemon/dist/domain/event-bus.js.map +1 -1
  111. package/daemon/dist/domain/gateway/gateway-process-main.d.ts.map +1 -1
  112. package/daemon/dist/domain/gateway/gateway-process-main.js +9 -0
  113. package/daemon/dist/domain/gateway/gateway-process-main.js.map +1 -1
  114. package/daemon/dist/domain/gateway/gateway-process.d.ts.map +1 -1
  115. package/daemon/dist/domain/gateway/gateway-process.js +9 -0
  116. package/daemon/dist/domain/gateway/gateway-process.js.map +1 -1
  117. package/daemon/dist/domain/gateway/gateway-subsystem.d.ts +80 -0
  118. package/daemon/dist/domain/gateway/gateway-subsystem.d.ts.map +1 -0
  119. package/daemon/dist/domain/gateway/gateway-subsystem.js +149 -0
  120. package/daemon/dist/domain/gateway/gateway-subsystem.js.map +1 -0
  121. package/daemon/dist/domain/gateway/human-registry.d.ts +109 -0
  122. package/daemon/dist/domain/gateway/human-registry.d.ts.map +1 -1
  123. package/daemon/dist/domain/gateway/human-registry.js +250 -0
  124. package/daemon/dist/domain/gateway/human-registry.js.map +1 -1
  125. package/{dist → daemon/dist/domain/gateway}/slack/config.d.ts +8 -5
  126. package/daemon/dist/domain/gateway/slack/config.d.ts.map +1 -0
  127. package/{dist → daemon/dist/domain/gateway}/slack/config.js +8 -6
  128. package/daemon/dist/domain/gateway/slack/config.js.map +1 -0
  129. package/{dist → daemon/dist/domain/gateway}/slack/inbound-admission.d.ts +1 -1
  130. package/daemon/dist/domain/gateway/slack/inbound-admission.d.ts.map +1 -0
  131. package/daemon/dist/domain/gateway/slack/inbound-admission.js.map +1 -0
  132. package/{dist → daemon/dist/domain/gateway}/slack/inbound.d.ts +14 -3
  133. package/daemon/dist/domain/gateway/slack/inbound.d.ts.map +1 -0
  134. package/{dist → daemon/dist/domain/gateway}/slack/inbound.js +6 -5
  135. package/daemon/dist/domain/gateway/slack/inbound.js.map +1 -0
  136. package/daemon/dist/domain/gateway/slack/message.d.ts +80 -0
  137. package/daemon/dist/domain/gateway/slack/message.d.ts.map +1 -0
  138. package/daemon/dist/domain/gateway/slack/message.js +164 -0
  139. package/daemon/dist/domain/gateway/slack/message.js.map +1 -0
  140. package/daemon/dist/domain/gateway/slack/outbound-driver.d.ts +54 -0
  141. package/daemon/dist/domain/gateway/slack/outbound-driver.d.ts.map +1 -0
  142. package/daemon/dist/domain/gateway/slack/outbound-driver.js +96 -0
  143. package/daemon/dist/domain/gateway/slack/outbound-driver.js.map +1 -0
  144. package/daemon/dist/domain/gateway/slack/queue-access.d.ts +53 -0
  145. package/daemon/dist/domain/gateway/slack/queue-access.d.ts.map +1 -0
  146. package/daemon/dist/domain/gateway/slack/queue-access.js +72 -0
  147. package/daemon/dist/domain/gateway/slack/queue-access.js.map +1 -0
  148. package/daemon/dist/domain/gateway/slack/secrets.d.ts.map +1 -0
  149. package/daemon/dist/domain/gateway/slack/secrets.js.map +1 -0
  150. package/daemon/dist/domain/gateway/slack/slack-api.d.ts +106 -0
  151. package/daemon/dist/domain/gateway/slack/slack-api.d.ts.map +1 -0
  152. package/daemon/dist/domain/gateway/slack/slack-api.js +198 -0
  153. package/daemon/dist/domain/gateway/slack/slack-api.js.map +1 -0
  154. package/daemon/dist/domain/gateway/slack/slack-delivery.d.ts +47 -0
  155. package/daemon/dist/domain/gateway/slack/slack-delivery.d.ts.map +1 -0
  156. package/daemon/dist/domain/gateway/slack/slack-delivery.js +147 -0
  157. package/daemon/dist/domain/gateway/slack/slack-delivery.js.map +1 -0
  158. package/daemon/dist/domain/gateway/slack/slack-subsystem.d.ts +21 -0
  159. package/daemon/dist/domain/gateway/slack/slack-subsystem.d.ts.map +1 -0
  160. package/daemon/dist/domain/gateway/slack/slack-subsystem.js +198 -0
  161. package/daemon/dist/domain/gateway/slack/slack-subsystem.js.map +1 -0
  162. package/daemon/dist/domain/gateway/slack/socket-inbound.d.ts +30 -0
  163. package/daemon/dist/domain/gateway/slack/socket-inbound.d.ts.map +1 -0
  164. package/daemon/dist/domain/gateway/slack/socket-inbound.js +99 -0
  165. package/daemon/dist/domain/gateway/slack/socket-inbound.js.map +1 -0
  166. package/daemon/dist/domain/gateway/slack/state-store.d.ts.map +1 -0
  167. package/daemon/dist/domain/gateway/slack/state-store.js.map +1 -0
  168. package/daemon/dist/domain/gateway/slack/thread-routing.d.ts +17 -0
  169. package/daemon/dist/domain/gateway/slack/thread-routing.d.ts.map +1 -0
  170. package/daemon/dist/domain/gateway/slack/thread-routing.js +35 -0
  171. package/daemon/dist/domain/gateway/slack/thread-routing.js.map +1 -0
  172. package/daemon/dist/domain/gateway/slack/thread-seat-map.d.ts +56 -0
  173. package/daemon/dist/domain/gateway/slack/thread-seat-map.d.ts.map +1 -0
  174. package/daemon/dist/domain/gateway/slack/thread-seat-map.js +103 -0
  175. package/daemon/dist/domain/gateway/slack/thread-seat-map.js.map +1 -0
  176. package/daemon/dist/domain/gateway/spawn-gateway.d.ts.map +1 -1
  177. package/daemon/dist/domain/gateway/spawn-gateway.js +9 -0
  178. package/daemon/dist/domain/gateway/spawn-gateway.js.map +1 -1
  179. package/daemon/dist/domain/gateway/transport.d.ts.map +1 -1
  180. package/daemon/dist/domain/gateway/transport.js +9 -0
  181. package/daemon/dist/domain/gateway/transport.js.map +1 -1
  182. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  183. package/daemon/dist/domain/node-inventory.js +20 -0
  184. package/daemon/dist/domain/node-inventory.js.map +1 -1
  185. package/daemon/dist/domain/parked-query.d.ts +81 -0
  186. package/daemon/dist/domain/parked-query.d.ts.map +1 -0
  187. package/daemon/dist/domain/parked-query.js +126 -0
  188. package/daemon/dist/domain/parked-query.js.map +1 -0
  189. package/daemon/dist/domain/plugin-discovery-service.d.ts +16 -0
  190. package/daemon/dist/domain/plugin-discovery-service.d.ts.map +1 -1
  191. package/daemon/dist/domain/plugin-discovery-service.js +175 -1
  192. package/daemon/dist/domain/plugin-discovery-service.js.map +1 -1
  193. package/daemon/dist/domain/plugin-vendor-service.d.ts +9 -5
  194. package/daemon/dist/domain/plugin-vendor-service.d.ts.map +1 -1
  195. package/daemon/dist/domain/plugin-vendor-service.js +101 -12
  196. package/daemon/dist/domain/plugin-vendor-service.js.map +1 -1
  197. package/daemon/dist/domain/queue-pickup.d.ts +38 -0
  198. package/daemon/dist/domain/queue-pickup.d.ts.map +1 -0
  199. package/daemon/dist/domain/queue-pickup.js +67 -0
  200. package/daemon/dist/domain/queue-pickup.js.map +1 -0
  201. package/daemon/dist/domain/queue-repository.d.ts +41 -11
  202. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  203. package/daemon/dist/domain/queue-repository.js +316 -36
  204. package/daemon/dist/domain/queue-repository.js.map +1 -1
  205. package/daemon/dist/domain/queue-stuck-sweep.d.ts +77 -0
  206. package/daemon/dist/domain/queue-stuck-sweep.d.ts.map +1 -0
  207. package/daemon/dist/domain/queue-stuck-sweep.js +348 -0
  208. package/daemon/dist/domain/queue-stuck-sweep.js.map +1 -0
  209. package/daemon/dist/domain/queue-wake-ladder.d.ts +96 -0
  210. package/daemon/dist/domain/queue-wake-ladder.d.ts.map +1 -0
  211. package/daemon/dist/domain/queue-wake-ladder.js +533 -0
  212. package/daemon/dist/domain/queue-wake-ladder.js.map +1 -0
  213. package/daemon/dist/domain/queue-wake-repository.d.ts +37 -0
  214. package/daemon/dist/domain/queue-wake-repository.d.ts.map +1 -0
  215. package/daemon/dist/domain/queue-wake-repository.js +80 -0
  216. package/daemon/dist/domain/queue-wake-repository.js.map +1 -0
  217. package/daemon/dist/domain/rebuild-priming-chain.d.ts +28 -0
  218. package/daemon/dist/domain/rebuild-priming-chain.d.ts.map +1 -0
  219. package/daemon/dist/domain/rebuild-priming-chain.js +71 -0
  220. package/daemon/dist/domain/rebuild-priming-chain.js.map +1 -0
  221. package/daemon/dist/domain/reconciler.d.ts.map +1 -1
  222. package/daemon/dist/domain/reconciler.js +6 -1
  223. package/daemon/dist/domain/reconciler.js.map +1 -1
  224. package/daemon/dist/domain/review/compose.d.ts +3 -1
  225. package/daemon/dist/domain/review/compose.d.ts.map +1 -1
  226. package/daemon/dist/domain/review/compose.js +14 -8
  227. package/daemon/dist/domain/review/compose.js.map +1 -1
  228. package/daemon/dist/domain/review/gather.d.ts.map +1 -1
  229. package/daemon/dist/domain/review/gather.js +3 -1
  230. package/daemon/dist/domain/review/gather.js.map +1 -1
  231. package/daemon/dist/domain/rig-repository.d.ts +4 -0
  232. package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
  233. package/daemon/dist/domain/rig-repository.js +9 -0
  234. package/daemon/dist/domain/rig-repository.js.map +1 -1
  235. package/daemon/dist/domain/rigspec-instantiator.d.ts +12 -0
  236. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  237. package/daemon/dist/domain/rigspec-instantiator.js +50 -0
  238. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  239. package/daemon/dist/domain/running-name-guard.d.ts +52 -0
  240. package/daemon/dist/domain/running-name-guard.d.ts.map +1 -0
  241. package/daemon/dist/domain/running-name-guard.js +34 -0
  242. package/daemon/dist/domain/running-name-guard.js.map +1 -0
  243. package/daemon/dist/domain/scope/plan-lock-artifacts.d.ts +6 -5
  244. package/daemon/dist/domain/scope/plan-lock-artifacts.d.ts.map +1 -1
  245. package/daemon/dist/domain/scope/plan-lock-artifacts.js +23 -20
  246. package/daemon/dist/domain/scope/plan-lock-artifacts.js.map +1 -1
  247. package/daemon/dist/domain/scope/scaffold-placeholder.d.ts +4 -5
  248. package/daemon/dist/domain/scope/scaffold-placeholder.d.ts.map +1 -1
  249. package/daemon/dist/domain/scope/scaffold-placeholder.js +6 -7
  250. package/daemon/dist/domain/scope/scaffold-placeholder.js.map +1 -1
  251. package/daemon/dist/domain/scope/scope-approve.d.ts +1 -1
  252. package/daemon/dist/domain/scope/scope-approve.d.ts.map +1 -1
  253. package/daemon/dist/domain/scope/scope-approve.js +5 -4
  254. package/daemon/dist/domain/scope/scope-approve.js.map +1 -1
  255. package/daemon/dist/domain/scope/scope-audit.d.ts +42 -3
  256. package/daemon/dist/domain/scope/scope-audit.d.ts.map +1 -1
  257. package/daemon/dist/domain/scope/scope-audit.js +78 -93
  258. package/daemon/dist/domain/scope/scope-audit.js.map +1 -1
  259. package/daemon/dist/domain/scope/scope-view-projection.d.ts.map +1 -1
  260. package/daemon/dist/domain/scope/scope-view-projection.js +7 -2
  261. package/daemon/dist/domain/scope/scope-view-projection.js.map +1 -1
  262. package/daemon/dist/domain/seat-activity-service.d.ts +91 -0
  263. package/daemon/dist/domain/seat-activity-service.d.ts.map +1 -1
  264. package/daemon/dist/domain/seat-activity-service.js +416 -1
  265. package/daemon/dist/domain/seat-activity-service.js.map +1 -1
  266. package/daemon/dist/domain/seat-handover-planner.d.ts +14 -0
  267. package/daemon/dist/domain/seat-handover-planner.d.ts.map +1 -1
  268. package/daemon/dist/domain/seat-handover-planner.js +14 -1
  269. package/daemon/dist/domain/seat-handover-planner.js.map +1 -1
  270. package/daemon/dist/domain/seat-handover-service.d.ts +54 -1
  271. package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
  272. package/daemon/dist/domain/seat-handover-service.js +162 -19
  273. package/daemon/dist/domain/seat-handover-service.js.map +1 -1
  274. package/daemon/dist/domain/seat-lifecycle-service.d.ts +97 -0
  275. package/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -0
  276. package/daemon/dist/domain/seat-lifecycle-service.js +312 -0
  277. package/daemon/dist/domain/seat-lifecycle-service.js.map +1 -0
  278. package/daemon/dist/domain/session-transport.d.ts +8 -5
  279. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  280. package/daemon/dist/domain/session-transport.js +40 -18
  281. package/daemon/dist/domain/session-transport.js.map +1 -1
  282. package/daemon/dist/domain/successor-session-launcher.d.ts +6 -1
  283. package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
  284. package/daemon/dist/domain/successor-session-launcher.js +3 -3
  285. package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
  286. package/daemon/dist/domain/types.d.ts +69 -0
  287. package/daemon/dist/domain/types.d.ts.map +1 -1
  288. package/daemon/dist/domain/types.js.map +1 -1
  289. package/daemon/dist/domain/user-settings/settings-store.d.ts +1 -1
  290. package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
  291. package/daemon/dist/domain/user-settings/settings-store.js +48 -0
  292. package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
  293. package/daemon/dist/domain/view-projector.d.ts +1 -1
  294. package/daemon/dist/domain/view-projector.d.ts.map +1 -1
  295. package/daemon/dist/domain/view-projector.js +41 -2
  296. package/daemon/dist/domain/view-projector.js.map +1 -1
  297. package/daemon/dist/domain/watchdog-policy-engine.d.ts +7 -0
  298. package/daemon/dist/domain/watchdog-policy-engine.d.ts.map +1 -1
  299. package/daemon/dist/domain/watchdog-policy-engine.js +3 -0
  300. package/daemon/dist/domain/watchdog-policy-engine.js.map +1 -1
  301. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts +4 -3
  302. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  303. package/daemon/dist/domain/workspace/default-workspace-scaffold.js +56 -196
  304. package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  305. package/daemon/dist/domain/workspace/getting-started-narrative.js +1 -1
  306. package/daemon/dist/domain/workspace/getting-started-narrative.js.map +1 -1
  307. package/daemon/dist/domain/workspace/workspace-doctor.d.ts +8 -11
  308. package/daemon/dist/domain/workspace/workspace-doctor.d.ts.map +1 -1
  309. package/daemon/dist/domain/workspace/workspace-doctor.js +23 -25
  310. package/daemon/dist/domain/workspace/workspace-doctor.js.map +1 -1
  311. package/daemon/dist/gateway-slack-surface.d.ts +4 -0
  312. package/daemon/dist/gateway-slack-surface.d.ts.map +1 -0
  313. package/daemon/dist/gateway-slack-surface.js +8 -0
  314. package/daemon/dist/gateway-slack-surface.js.map +1 -0
  315. package/daemon/dist/index.d.ts +29 -0
  316. package/daemon/dist/index.d.ts.map +1 -1
  317. package/daemon/dist/index.js +99 -4
  318. package/daemon/dist/index.js.map +1 -1
  319. package/daemon/dist/lib/pane-envelope.d.ts +1 -1
  320. package/daemon/dist/lib/pane-envelope.d.ts.map +1 -1
  321. package/daemon/dist/lib/pane-envelope.js +8 -14
  322. package/daemon/dist/lib/pane-envelope.js.map +1 -1
  323. package/daemon/dist/routes/activity.d.ts +13 -0
  324. package/daemon/dist/routes/activity.d.ts.map +1 -1
  325. package/daemon/dist/routes/activity.js +186 -0
  326. package/daemon/dist/routes/activity.js.map +1 -1
  327. package/daemon/dist/routes/config.js +2 -2
  328. package/daemon/dist/routes/config.js.map +1 -1
  329. package/daemon/dist/routes/gateway.d.ts +3 -0
  330. package/daemon/dist/routes/gateway.d.ts.map +1 -0
  331. package/daemon/dist/routes/gateway.js +46 -0
  332. package/daemon/dist/routes/gateway.js.map +1 -0
  333. package/daemon/dist/routes/health-summary.d.ts.map +1 -1
  334. package/daemon/dist/routes/health-summary.js +8 -0
  335. package/daemon/dist/routes/health-summary.js.map +1 -1
  336. package/daemon/dist/routes/queue.d.ts.map +1 -1
  337. package/daemon/dist/routes/queue.js +32 -25
  338. package/daemon/dist/routes/queue.js.map +1 -1
  339. package/daemon/dist/routes/rigspec.js +20 -6
  340. package/daemon/dist/routes/rigspec.js.map +1 -1
  341. package/daemon/dist/routes/scope-audit.d.ts.map +1 -1
  342. package/daemon/dist/routes/scope-audit.js +72 -13
  343. package/daemon/dist/routes/scope-audit.js.map +1 -1
  344. package/daemon/dist/routes/seat.d.ts.map +1 -1
  345. package/daemon/dist/routes/seat.js +73 -0
  346. package/daemon/dist/routes/seat.js.map +1 -1
  347. package/daemon/dist/routes/transport.d.ts.map +1 -1
  348. package/daemon/dist/routes/transport.js +40 -36
  349. package/daemon/dist/routes/transport.js.map +1 -1
  350. package/daemon/dist/routes/up.js +21 -2
  351. package/daemon/dist/routes/up.js.map +1 -1
  352. package/daemon/dist/server.d.ts +17 -0
  353. package/daemon/dist/server.d.ts.map +1 -1
  354. package/daemon/dist/server.js +25 -4
  355. package/daemon/dist/server.js.map +1 -1
  356. package/daemon/dist/startup.d.ts +4 -0
  357. package/daemon/dist/startup.d.ts.map +1 -1
  358. package/daemon/dist/startup.js +33 -0
  359. package/daemon/dist/startup.js.map +1 -1
  360. package/daemon/docs/reference/agent-state-taxonomy.md +106 -0
  361. package/daemon/docs/reference/project-workspace.md +22 -14
  362. package/daemon/docs/reference/refocus-channel.md +27 -14
  363. package/daemon/docs/reference/sdlc-conventions.md +24 -13
  364. package/daemon/specs/agents/shared/skills/core/agent-startup-and-context-ingestion/SKILL.md +1 -1
  365. package/daemon/specs/agents/shared/skills/pm/requirements-writer/SKILL.md +21 -15
  366. package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/guidance/role.md +1 -1
  367. package/dist/build-info.js +3 -3
  368. package/dist/cli-error.js +1 -1
  369. package/dist/cli-error.js.map +1 -1
  370. package/dist/commands/broadcast.js +6 -0
  371. package/dist/commands/broadcast.js.map +1 -1
  372. package/dist/commands/config-init-workspace.d.ts.map +1 -1
  373. package/dist/commands/config-init-workspace.js +32 -57
  374. package/dist/commands/config-init-workspace.js.map +1 -1
  375. package/dist/commands/config.d.ts.map +1 -1
  376. package/dist/commands/config.js +5 -0
  377. package/dist/commands/config.js.map +1 -1
  378. package/dist/commands/context.d.ts.map +1 -1
  379. package/dist/commands/context.js +13 -3
  380. package/dist/commands/context.js.map +1 -1
  381. package/dist/commands/daemon.d.ts.map +1 -1
  382. package/dist/commands/daemon.js +36 -5
  383. package/dist/commands/daemon.js.map +1 -1
  384. package/dist/commands/gateway.d.ts +19 -1
  385. package/dist/commands/gateway.d.ts.map +1 -1
  386. package/dist/commands/gateway.js +157 -33
  387. package/dist/commands/gateway.js.map +1 -1
  388. package/dist/commands/import.d.ts.map +1 -1
  389. package/dist/commands/import.js +10 -0
  390. package/dist/commands/import.js.map +1 -1
  391. package/dist/commands/parked.d.ts +3 -0
  392. package/dist/commands/parked.d.ts.map +1 -0
  393. package/dist/commands/parked.js +83 -0
  394. package/dist/commands/parked.js.map +1 -0
  395. package/dist/commands/proof.d.ts +2 -1
  396. package/dist/commands/proof.d.ts.map +1 -1
  397. package/dist/commands/proof.js +8 -8
  398. package/dist/commands/proof.js.map +1 -1
  399. package/dist/commands/ps.d.ts +10 -0
  400. package/dist/commands/ps.d.ts.map +1 -1
  401. package/dist/commands/ps.js +14 -3
  402. package/dist/commands/ps.js.map +1 -1
  403. package/dist/commands/queue.d.ts.map +1 -1
  404. package/dist/commands/queue.js +67 -16
  405. package/dist/commands/queue.js.map +1 -1
  406. package/dist/commands/scope.d.ts.map +1 -1
  407. package/dist/commands/scope.js +255 -136
  408. package/dist/commands/scope.js.map +1 -1
  409. package/dist/commands/seat.d.ts.map +1 -1
  410. package/dist/commands/seat.js +128 -10
  411. package/dist/commands/seat.js.map +1 -1
  412. package/dist/commands/send.d.ts +1 -1
  413. package/dist/commands/send.d.ts.map +1 -1
  414. package/dist/commands/send.js +237 -34
  415. package/dist/commands/send.js.map +1 -1
  416. package/dist/commands/slack.d.ts +14 -28
  417. package/dist/commands/slack.d.ts.map +1 -1
  418. package/dist/commands/slack.js +73 -187
  419. package/dist/commands/slack.js.map +1 -1
  420. package/dist/commands/start.d.ts +3 -0
  421. package/dist/commands/start.d.ts.map +1 -1
  422. package/dist/commands/start.js +12 -5
  423. package/dist/commands/start.js.map +1 -1
  424. package/dist/commands/up.d.ts.map +1 -1
  425. package/dist/commands/up.js +19 -4
  426. package/dist/commands/up.js.map +1 -1
  427. package/dist/commands/view.d.ts +4 -2
  428. package/dist/commands/view.d.ts.map +1 -1
  429. package/dist/commands/view.js +1 -1
  430. package/dist/commands/view.js.map +1 -1
  431. package/dist/commands/walk.d.ts +1 -1
  432. package/dist/commands/walk.d.ts.map +1 -1
  433. package/dist/commands/walk.js +20 -10
  434. package/dist/commands/walk.js.map +1 -1
  435. package/dist/commands/watchdog.d.ts.map +1 -1
  436. package/dist/commands/watchdog.js +2 -1
  437. package/dist/commands/watchdog.js.map +1 -1
  438. package/dist/commands/workspace.js +1 -1
  439. package/dist/config-store.d.ts +15 -1
  440. package/dist/config-store.d.ts.map +1 -1
  441. package/dist/config-store.js +60 -0
  442. package/dist/config-store.js.map +1 -1
  443. package/dist/cross-host-target.d.ts.map +1 -1
  444. package/dist/cross-host-target.js +5 -4
  445. package/dist/cross-host-target.js.map +1 -1
  446. package/dist/daemon-lifecycle.d.ts +45 -3
  447. package/dist/daemon-lifecycle.d.ts.map +1 -1
  448. package/dist/daemon-lifecycle.js +126 -0
  449. package/dist/daemon-lifecycle.js.map +1 -1
  450. package/dist/index.d.ts.map +1 -1
  451. package/dist/index.js +2 -0
  452. package/dist/index.js.map +1 -1
  453. package/dist/lib/scope/capability-delta.d.ts +9 -0
  454. package/dist/lib/scope/capability-delta.d.ts.map +1 -0
  455. package/dist/lib/scope/capability-delta.js +73 -0
  456. package/dist/lib/scope/capability-delta.js.map +1 -0
  457. package/dist/lib/scope/scaffold-placeholder.d.ts +4 -5
  458. package/dist/lib/scope/scaffold-placeholder.d.ts.map +1 -1
  459. package/dist/lib/scope/scaffold-placeholder.js +6 -7
  460. package/dist/lib/scope/scaffold-placeholder.js.map +1 -1
  461. package/dist/lib/scope/scope-audit.d.ts +42 -3
  462. package/dist/lib/scope/scope-audit.d.ts.map +1 -1
  463. package/dist/lib/scope/scope-audit.js +78 -93
  464. package/dist/lib/scope/scope-audit.js.map +1 -1
  465. package/dist/lib/scope/scope-fs.d.ts +18 -14
  466. package/dist/lib/scope/scope-fs.d.ts.map +1 -1
  467. package/dist/lib/scope/scope-fs.js +60 -29
  468. package/dist/lib/scope/scope-fs.js.map +1 -1
  469. package/dist/lib/scope/templates.d.ts +17 -17
  470. package/dist/lib/scope/templates.d.ts.map +1 -1
  471. package/dist/lib/scope/templates.js +35 -39
  472. package/dist/lib/scope/templates.js.map +1 -1
  473. package/dist/lib/scope-templates/backlog-deprecation.md +3 -1
  474. package/dist/lib/scope-templates/backlog-tech-debt.md +3 -1
  475. package/dist/lib/scope-templates/bug-fix.md +3 -1
  476. package/dist/lib/scope-templates/capability-delta.md +60 -0
  477. package/dist/lib/scope-templates/mission-placeholder.md +9 -40
  478. package/dist/lib/scope-templates/mission-progress.md +5 -6
  479. package/dist/lib/scope-templates/mission-release.md +9 -40
  480. package/dist/lib/scope-templates/notes.md +14 -0
  481. package/dist/lib/scope-templates/placeholder.md +3 -1
  482. package/dist/lib/scope-templates/proof.md +1 -1
  483. package/dist/lib/scope-templates/release-feature.md +3 -1
  484. package/dist/lib/scope-templates/research.md +3 -1
  485. package/dist/lib/scope-templates/slice-progress.md +4 -5
  486. package/node_modules/@openrig/daemon/dist/adapters/claude-code-adapter.d.ts +15 -0
  487. package/node_modules/@openrig/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  488. package/node_modules/@openrig/daemon/dist/adapters/claude-code-adapter.js +57 -0
  489. package/node_modules/@openrig/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  490. package/node_modules/@openrig/daemon/dist/adapters/tmux.d.ts +31 -0
  491. package/node_modules/@openrig/daemon/dist/adapters/tmux.d.ts.map +1 -1
  492. package/node_modules/@openrig/daemon/dist/adapters/tmux.js +31 -11
  493. package/node_modules/@openrig/daemon/dist/adapters/tmux.js.map +1 -1
  494. package/node_modules/@openrig/daemon/dist/build-info.js +3 -3
  495. package/node_modules/@openrig/daemon/dist/daemon-db-path.d.ts.map +1 -1
  496. package/node_modules/@openrig/daemon/dist/daemon-db-path.js +50 -2
  497. package/node_modules/@openrig/daemon/dist/daemon-db-path.js.map +1 -1
  498. package/node_modules/@openrig/daemon/dist/db/all-migrations.d.ts.map +1 -1
  499. package/node_modules/@openrig/daemon/dist/db/all-migrations.js +4 -0
  500. package/node_modules/@openrig/daemon/dist/db/all-migrations.js.map +1 -1
  501. package/node_modules/@openrig/daemon/dist/db/migrations/072_thread_seat_map.d.ts +3 -0
  502. package/node_modules/@openrig/daemon/dist/db/migrations/072_thread_seat_map.d.ts.map +1 -0
  503. package/node_modules/@openrig/daemon/dist/db/migrations/072_thread_seat_map.js +22 -0
  504. package/node_modules/@openrig/daemon/dist/db/migrations/072_thread_seat_map.js.map +1 -0
  505. package/node_modules/@openrig/daemon/dist/db/migrations/073_queue_transition_wakes.d.ts +3 -0
  506. package/node_modules/@openrig/daemon/dist/db/migrations/073_queue_transition_wakes.d.ts.map +1 -0
  507. package/node_modules/@openrig/daemon/dist/db/migrations/073_queue_transition_wakes.js +21 -0
  508. package/node_modules/@openrig/daemon/dist/db/migrations/073_queue_transition_wakes.js.map +1 -0
  509. package/node_modules/@openrig/daemon/dist/domain/activity-taxonomy.d.ts +112 -0
  510. package/node_modules/@openrig/daemon/dist/domain/activity-taxonomy.d.ts.map +1 -0
  511. package/node_modules/@openrig/daemon/dist/domain/activity-taxonomy.js +99 -0
  512. package/node_modules/@openrig/daemon/dist/domain/activity-taxonomy.js.map +1 -0
  513. package/node_modules/@openrig/daemon/dist/domain/bind-plan.d.ts +19 -0
  514. package/node_modules/@openrig/daemon/dist/domain/bind-plan.d.ts.map +1 -0
  515. package/node_modules/@openrig/daemon/dist/domain/bind-plan.js +25 -0
  516. package/node_modules/@openrig/daemon/dist/domain/bind-plan.js.map +1 -0
  517. package/node_modules/@openrig/daemon/dist/domain/event-bus.d.ts +6 -0
  518. package/node_modules/@openrig/daemon/dist/domain/event-bus.d.ts.map +1 -1
  519. package/node_modules/@openrig/daemon/dist/domain/event-bus.js +15 -5
  520. package/node_modules/@openrig/daemon/dist/domain/event-bus.js.map +1 -1
  521. package/node_modules/@openrig/daemon/dist/domain/gateway/gateway-process-main.d.ts.map +1 -1
  522. package/node_modules/@openrig/daemon/dist/domain/gateway/gateway-process-main.js +9 -0
  523. package/node_modules/@openrig/daemon/dist/domain/gateway/gateway-process-main.js.map +1 -1
  524. package/node_modules/@openrig/daemon/dist/domain/gateway/gateway-process.d.ts.map +1 -1
  525. package/node_modules/@openrig/daemon/dist/domain/gateway/gateway-process.js +9 -0
  526. package/node_modules/@openrig/daemon/dist/domain/gateway/gateway-process.js.map +1 -1
  527. package/node_modules/@openrig/daemon/dist/domain/gateway/gateway-subsystem.d.ts +80 -0
  528. package/node_modules/@openrig/daemon/dist/domain/gateway/gateway-subsystem.d.ts.map +1 -0
  529. package/node_modules/@openrig/daemon/dist/domain/gateway/gateway-subsystem.js +149 -0
  530. package/node_modules/@openrig/daemon/dist/domain/gateway/gateway-subsystem.js.map +1 -0
  531. package/node_modules/@openrig/daemon/dist/domain/gateway/human-registry.d.ts +109 -0
  532. package/node_modules/@openrig/daemon/dist/domain/gateway/human-registry.d.ts.map +1 -1
  533. package/node_modules/@openrig/daemon/dist/domain/gateway/human-registry.js +250 -0
  534. package/node_modules/@openrig/daemon/dist/domain/gateway/human-registry.js.map +1 -1
  535. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/config.d.ts +44 -0
  536. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/config.d.ts.map +1 -0
  537. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/config.js +62 -0
  538. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/config.js.map +1 -0
  539. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/inbound-admission.d.ts +8 -0
  540. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/inbound-admission.d.ts.map +1 -0
  541. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/inbound-admission.js +20 -0
  542. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/inbound-admission.js.map +1 -0
  543. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/inbound.d.ts +113 -0
  544. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/inbound.d.ts.map +1 -0
  545. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/inbound.js +146 -0
  546. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/inbound.js.map +1 -0
  547. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/message.d.ts +80 -0
  548. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/message.d.ts.map +1 -0
  549. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/message.js +164 -0
  550. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/message.js.map +1 -0
  551. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/outbound-driver.d.ts +54 -0
  552. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/outbound-driver.d.ts.map +1 -0
  553. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/outbound-driver.js +96 -0
  554. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/outbound-driver.js.map +1 -0
  555. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/queue-access.d.ts +53 -0
  556. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/queue-access.d.ts.map +1 -0
  557. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/queue-access.js +72 -0
  558. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/queue-access.js.map +1 -0
  559. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/secrets.d.ts +21 -0
  560. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/secrets.d.ts.map +1 -0
  561. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/secrets.js +73 -0
  562. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/secrets.js.map +1 -0
  563. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-api.d.ts +106 -0
  564. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-api.d.ts.map +1 -0
  565. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-api.js +198 -0
  566. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-api.js.map +1 -0
  567. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-delivery.d.ts +47 -0
  568. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-delivery.d.ts.map +1 -0
  569. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-delivery.js +147 -0
  570. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-delivery.js.map +1 -0
  571. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-subsystem.d.ts +21 -0
  572. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-subsystem.d.ts.map +1 -0
  573. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-subsystem.js +198 -0
  574. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/slack-subsystem.js.map +1 -0
  575. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/socket-inbound.d.ts +30 -0
  576. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/socket-inbound.d.ts.map +1 -0
  577. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/socket-inbound.js +99 -0
  578. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/socket-inbound.js.map +1 -0
  579. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/state-store.d.ts +62 -0
  580. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/state-store.d.ts.map +1 -0
  581. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/state-store.js +132 -0
  582. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/state-store.js.map +1 -0
  583. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/thread-routing.d.ts +17 -0
  584. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/thread-routing.d.ts.map +1 -0
  585. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/thread-routing.js +35 -0
  586. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/thread-routing.js.map +1 -0
  587. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/thread-seat-map.d.ts +56 -0
  588. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/thread-seat-map.d.ts.map +1 -0
  589. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/thread-seat-map.js +103 -0
  590. package/node_modules/@openrig/daemon/dist/domain/gateway/slack/thread-seat-map.js.map +1 -0
  591. package/node_modules/@openrig/daemon/dist/domain/gateway/spawn-gateway.d.ts.map +1 -1
  592. package/node_modules/@openrig/daemon/dist/domain/gateway/spawn-gateway.js +9 -0
  593. package/node_modules/@openrig/daemon/dist/domain/gateway/spawn-gateway.js.map +1 -1
  594. package/node_modules/@openrig/daemon/dist/domain/gateway/transport.d.ts.map +1 -1
  595. package/node_modules/@openrig/daemon/dist/domain/gateway/transport.js +9 -0
  596. package/node_modules/@openrig/daemon/dist/domain/gateway/transport.js.map +1 -1
  597. package/node_modules/@openrig/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  598. package/node_modules/@openrig/daemon/dist/domain/node-inventory.js +20 -0
  599. package/node_modules/@openrig/daemon/dist/domain/node-inventory.js.map +1 -1
  600. package/node_modules/@openrig/daemon/dist/domain/parked-query.d.ts +81 -0
  601. package/node_modules/@openrig/daemon/dist/domain/parked-query.d.ts.map +1 -0
  602. package/node_modules/@openrig/daemon/dist/domain/parked-query.js +126 -0
  603. package/node_modules/@openrig/daemon/dist/domain/parked-query.js.map +1 -0
  604. package/node_modules/@openrig/daemon/dist/domain/plugin-discovery-service.d.ts +16 -0
  605. package/node_modules/@openrig/daemon/dist/domain/plugin-discovery-service.d.ts.map +1 -1
  606. package/node_modules/@openrig/daemon/dist/domain/plugin-discovery-service.js +175 -1
  607. package/node_modules/@openrig/daemon/dist/domain/plugin-discovery-service.js.map +1 -1
  608. package/node_modules/@openrig/daemon/dist/domain/plugin-vendor-service.d.ts +9 -5
  609. package/node_modules/@openrig/daemon/dist/domain/plugin-vendor-service.d.ts.map +1 -1
  610. package/node_modules/@openrig/daemon/dist/domain/plugin-vendor-service.js +101 -12
  611. package/node_modules/@openrig/daemon/dist/domain/plugin-vendor-service.js.map +1 -1
  612. package/node_modules/@openrig/daemon/dist/domain/queue-pickup.d.ts +38 -0
  613. package/node_modules/@openrig/daemon/dist/domain/queue-pickup.d.ts.map +1 -0
  614. package/node_modules/@openrig/daemon/dist/domain/queue-pickup.js +67 -0
  615. package/node_modules/@openrig/daemon/dist/domain/queue-pickup.js.map +1 -0
  616. package/node_modules/@openrig/daemon/dist/domain/queue-repository.d.ts +41 -11
  617. package/node_modules/@openrig/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  618. package/node_modules/@openrig/daemon/dist/domain/queue-repository.js +316 -36
  619. package/node_modules/@openrig/daemon/dist/domain/queue-repository.js.map +1 -1
  620. package/node_modules/@openrig/daemon/dist/domain/queue-stuck-sweep.d.ts +77 -0
  621. package/node_modules/@openrig/daemon/dist/domain/queue-stuck-sweep.d.ts.map +1 -0
  622. package/node_modules/@openrig/daemon/dist/domain/queue-stuck-sweep.js +348 -0
  623. package/node_modules/@openrig/daemon/dist/domain/queue-stuck-sweep.js.map +1 -0
  624. package/node_modules/@openrig/daemon/dist/domain/queue-wake-ladder.d.ts +96 -0
  625. package/node_modules/@openrig/daemon/dist/domain/queue-wake-ladder.d.ts.map +1 -0
  626. package/node_modules/@openrig/daemon/dist/domain/queue-wake-ladder.js +533 -0
  627. package/node_modules/@openrig/daemon/dist/domain/queue-wake-ladder.js.map +1 -0
  628. package/node_modules/@openrig/daemon/dist/domain/queue-wake-repository.d.ts +37 -0
  629. package/node_modules/@openrig/daemon/dist/domain/queue-wake-repository.d.ts.map +1 -0
  630. package/node_modules/@openrig/daemon/dist/domain/queue-wake-repository.js +80 -0
  631. package/node_modules/@openrig/daemon/dist/domain/queue-wake-repository.js.map +1 -0
  632. package/node_modules/@openrig/daemon/dist/domain/rebuild-priming-chain.d.ts +28 -0
  633. package/node_modules/@openrig/daemon/dist/domain/rebuild-priming-chain.d.ts.map +1 -0
  634. package/node_modules/@openrig/daemon/dist/domain/rebuild-priming-chain.js +71 -0
  635. package/node_modules/@openrig/daemon/dist/domain/rebuild-priming-chain.js.map +1 -0
  636. package/node_modules/@openrig/daemon/dist/domain/reconciler.d.ts.map +1 -1
  637. package/node_modules/@openrig/daemon/dist/domain/reconciler.js +6 -1
  638. package/node_modules/@openrig/daemon/dist/domain/reconciler.js.map +1 -1
  639. package/node_modules/@openrig/daemon/dist/domain/review/compose.d.ts +3 -1
  640. package/node_modules/@openrig/daemon/dist/domain/review/compose.d.ts.map +1 -1
  641. package/node_modules/@openrig/daemon/dist/domain/review/compose.js +14 -8
  642. package/node_modules/@openrig/daemon/dist/domain/review/compose.js.map +1 -1
  643. package/node_modules/@openrig/daemon/dist/domain/review/gather.d.ts.map +1 -1
  644. package/node_modules/@openrig/daemon/dist/domain/review/gather.js +3 -1
  645. package/node_modules/@openrig/daemon/dist/domain/review/gather.js.map +1 -1
  646. package/node_modules/@openrig/daemon/dist/domain/rig-repository.d.ts +4 -0
  647. package/node_modules/@openrig/daemon/dist/domain/rig-repository.d.ts.map +1 -1
  648. package/node_modules/@openrig/daemon/dist/domain/rig-repository.js +9 -0
  649. package/node_modules/@openrig/daemon/dist/domain/rig-repository.js.map +1 -1
  650. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.d.ts +12 -0
  651. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  652. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.js +50 -0
  653. package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  654. package/node_modules/@openrig/daemon/dist/domain/running-name-guard.d.ts +52 -0
  655. package/node_modules/@openrig/daemon/dist/domain/running-name-guard.d.ts.map +1 -0
  656. package/node_modules/@openrig/daemon/dist/domain/running-name-guard.js +34 -0
  657. package/node_modules/@openrig/daemon/dist/domain/running-name-guard.js.map +1 -0
  658. package/node_modules/@openrig/daemon/dist/domain/scope/plan-lock-artifacts.d.ts +6 -5
  659. package/node_modules/@openrig/daemon/dist/domain/scope/plan-lock-artifacts.d.ts.map +1 -1
  660. package/node_modules/@openrig/daemon/dist/domain/scope/plan-lock-artifacts.js +23 -20
  661. package/node_modules/@openrig/daemon/dist/domain/scope/plan-lock-artifacts.js.map +1 -1
  662. package/node_modules/@openrig/daemon/dist/domain/scope/scaffold-placeholder.d.ts +4 -5
  663. package/node_modules/@openrig/daemon/dist/domain/scope/scaffold-placeholder.d.ts.map +1 -1
  664. package/node_modules/@openrig/daemon/dist/domain/scope/scaffold-placeholder.js +6 -7
  665. package/node_modules/@openrig/daemon/dist/domain/scope/scaffold-placeholder.js.map +1 -1
  666. package/node_modules/@openrig/daemon/dist/domain/scope/scope-approve.d.ts +1 -1
  667. package/node_modules/@openrig/daemon/dist/domain/scope/scope-approve.d.ts.map +1 -1
  668. package/node_modules/@openrig/daemon/dist/domain/scope/scope-approve.js +5 -4
  669. package/node_modules/@openrig/daemon/dist/domain/scope/scope-approve.js.map +1 -1
  670. package/node_modules/@openrig/daemon/dist/domain/scope/scope-audit.d.ts +42 -3
  671. package/node_modules/@openrig/daemon/dist/domain/scope/scope-audit.d.ts.map +1 -1
  672. package/node_modules/@openrig/daemon/dist/domain/scope/scope-audit.js +78 -93
  673. package/node_modules/@openrig/daemon/dist/domain/scope/scope-audit.js.map +1 -1
  674. package/node_modules/@openrig/daemon/dist/domain/scope/scope-view-projection.d.ts.map +1 -1
  675. package/node_modules/@openrig/daemon/dist/domain/scope/scope-view-projection.js +7 -2
  676. package/node_modules/@openrig/daemon/dist/domain/scope/scope-view-projection.js.map +1 -1
  677. package/node_modules/@openrig/daemon/dist/domain/seat-activity-service.d.ts +91 -0
  678. package/node_modules/@openrig/daemon/dist/domain/seat-activity-service.d.ts.map +1 -1
  679. package/node_modules/@openrig/daemon/dist/domain/seat-activity-service.js +416 -1
  680. package/node_modules/@openrig/daemon/dist/domain/seat-activity-service.js.map +1 -1
  681. package/node_modules/@openrig/daemon/dist/domain/seat-handover-planner.d.ts +14 -0
  682. package/node_modules/@openrig/daemon/dist/domain/seat-handover-planner.d.ts.map +1 -1
  683. package/node_modules/@openrig/daemon/dist/domain/seat-handover-planner.js +14 -1
  684. package/node_modules/@openrig/daemon/dist/domain/seat-handover-planner.js.map +1 -1
  685. package/node_modules/@openrig/daemon/dist/domain/seat-handover-service.d.ts +54 -1
  686. package/node_modules/@openrig/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
  687. package/node_modules/@openrig/daemon/dist/domain/seat-handover-service.js +162 -19
  688. package/node_modules/@openrig/daemon/dist/domain/seat-handover-service.js.map +1 -1
  689. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.d.ts +97 -0
  690. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -0
  691. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.js +312 -0
  692. package/node_modules/@openrig/daemon/dist/domain/seat-lifecycle-service.js.map +1 -0
  693. package/node_modules/@openrig/daemon/dist/domain/session-transport.d.ts +8 -5
  694. package/node_modules/@openrig/daemon/dist/domain/session-transport.d.ts.map +1 -1
  695. package/node_modules/@openrig/daemon/dist/domain/session-transport.js +40 -18
  696. package/node_modules/@openrig/daemon/dist/domain/session-transport.js.map +1 -1
  697. package/node_modules/@openrig/daemon/dist/domain/successor-session-launcher.d.ts +6 -1
  698. package/node_modules/@openrig/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
  699. package/node_modules/@openrig/daemon/dist/domain/successor-session-launcher.js +3 -3
  700. package/node_modules/@openrig/daemon/dist/domain/successor-session-launcher.js.map +1 -1
  701. package/node_modules/@openrig/daemon/dist/domain/types.d.ts +69 -0
  702. package/node_modules/@openrig/daemon/dist/domain/types.d.ts.map +1 -1
  703. package/node_modules/@openrig/daemon/dist/domain/types.js.map +1 -1
  704. package/node_modules/@openrig/daemon/dist/domain/user-settings/settings-store.d.ts +1 -1
  705. package/node_modules/@openrig/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
  706. package/node_modules/@openrig/daemon/dist/domain/user-settings/settings-store.js +48 -0
  707. package/node_modules/@openrig/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
  708. package/node_modules/@openrig/daemon/dist/domain/view-projector.d.ts +1 -1
  709. package/node_modules/@openrig/daemon/dist/domain/view-projector.d.ts.map +1 -1
  710. package/node_modules/@openrig/daemon/dist/domain/view-projector.js +41 -2
  711. package/node_modules/@openrig/daemon/dist/domain/view-projector.js.map +1 -1
  712. package/node_modules/@openrig/daemon/dist/domain/watchdog-policy-engine.d.ts +7 -0
  713. package/node_modules/@openrig/daemon/dist/domain/watchdog-policy-engine.d.ts.map +1 -1
  714. package/node_modules/@openrig/daemon/dist/domain/watchdog-policy-engine.js +3 -0
  715. package/node_modules/@openrig/daemon/dist/domain/watchdog-policy-engine.js.map +1 -1
  716. package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts +4 -3
  717. package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  718. package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.js +56 -196
  719. package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  720. package/node_modules/@openrig/daemon/dist/domain/workspace/getting-started-narrative.js +1 -1
  721. package/node_modules/@openrig/daemon/dist/domain/workspace/getting-started-narrative.js.map +1 -1
  722. package/node_modules/@openrig/daemon/dist/domain/workspace/workspace-doctor.d.ts +8 -11
  723. package/node_modules/@openrig/daemon/dist/domain/workspace/workspace-doctor.d.ts.map +1 -1
  724. package/node_modules/@openrig/daemon/dist/domain/workspace/workspace-doctor.js +23 -25
  725. package/node_modules/@openrig/daemon/dist/domain/workspace/workspace-doctor.js.map +1 -1
  726. package/node_modules/@openrig/daemon/dist/gateway-slack-surface.d.ts +4 -0
  727. package/node_modules/@openrig/daemon/dist/gateway-slack-surface.d.ts.map +1 -0
  728. package/node_modules/@openrig/daemon/dist/gateway-slack-surface.js +8 -0
  729. package/node_modules/@openrig/daemon/dist/gateway-slack-surface.js.map +1 -0
  730. package/node_modules/@openrig/daemon/dist/index.d.ts +29 -0
  731. package/node_modules/@openrig/daemon/dist/index.d.ts.map +1 -1
  732. package/node_modules/@openrig/daemon/dist/index.js +99 -4
  733. package/node_modules/@openrig/daemon/dist/index.js.map +1 -1
  734. package/node_modules/@openrig/daemon/dist/lib/pane-envelope.d.ts +1 -1
  735. package/node_modules/@openrig/daemon/dist/lib/pane-envelope.d.ts.map +1 -1
  736. package/node_modules/@openrig/daemon/dist/lib/pane-envelope.js +8 -14
  737. package/node_modules/@openrig/daemon/dist/lib/pane-envelope.js.map +1 -1
  738. package/node_modules/@openrig/daemon/dist/routes/activity.d.ts +13 -0
  739. package/node_modules/@openrig/daemon/dist/routes/activity.d.ts.map +1 -1
  740. package/node_modules/@openrig/daemon/dist/routes/activity.js +186 -0
  741. package/node_modules/@openrig/daemon/dist/routes/activity.js.map +1 -1
  742. package/node_modules/@openrig/daemon/dist/routes/config.js +2 -2
  743. package/node_modules/@openrig/daemon/dist/routes/config.js.map +1 -1
  744. package/node_modules/@openrig/daemon/dist/routes/gateway.d.ts +3 -0
  745. package/node_modules/@openrig/daemon/dist/routes/gateway.d.ts.map +1 -0
  746. package/node_modules/@openrig/daemon/dist/routes/gateway.js +46 -0
  747. package/node_modules/@openrig/daemon/dist/routes/gateway.js.map +1 -0
  748. package/node_modules/@openrig/daemon/dist/routes/health-summary.d.ts.map +1 -1
  749. package/node_modules/@openrig/daemon/dist/routes/health-summary.js +8 -0
  750. package/node_modules/@openrig/daemon/dist/routes/health-summary.js.map +1 -1
  751. package/node_modules/@openrig/daemon/dist/routes/queue.d.ts.map +1 -1
  752. package/node_modules/@openrig/daemon/dist/routes/queue.js +32 -25
  753. package/node_modules/@openrig/daemon/dist/routes/queue.js.map +1 -1
  754. package/node_modules/@openrig/daemon/dist/routes/rigspec.js +20 -6
  755. package/node_modules/@openrig/daemon/dist/routes/rigspec.js.map +1 -1
  756. package/node_modules/@openrig/daemon/dist/routes/scope-audit.d.ts.map +1 -1
  757. package/node_modules/@openrig/daemon/dist/routes/scope-audit.js +72 -13
  758. package/node_modules/@openrig/daemon/dist/routes/scope-audit.js.map +1 -1
  759. package/node_modules/@openrig/daemon/dist/routes/seat.d.ts.map +1 -1
  760. package/node_modules/@openrig/daemon/dist/routes/seat.js +73 -0
  761. package/node_modules/@openrig/daemon/dist/routes/seat.js.map +1 -1
  762. package/node_modules/@openrig/daemon/dist/routes/transport.d.ts.map +1 -1
  763. package/node_modules/@openrig/daemon/dist/routes/transport.js +40 -36
  764. package/node_modules/@openrig/daemon/dist/routes/transport.js.map +1 -1
  765. package/node_modules/@openrig/daemon/dist/routes/up.js +21 -2
  766. package/node_modules/@openrig/daemon/dist/routes/up.js.map +1 -1
  767. package/node_modules/@openrig/daemon/dist/server.d.ts +17 -0
  768. package/node_modules/@openrig/daemon/dist/server.d.ts.map +1 -1
  769. package/node_modules/@openrig/daemon/dist/server.js +25 -4
  770. package/node_modules/@openrig/daemon/dist/server.js.map +1 -1
  771. package/node_modules/@openrig/daemon/dist/startup.d.ts +4 -0
  772. package/node_modules/@openrig/daemon/dist/startup.d.ts.map +1 -1
  773. package/node_modules/@openrig/daemon/dist/startup.js +33 -0
  774. package/node_modules/@openrig/daemon/dist/startup.js.map +1 -1
  775. package/node_modules/@openrig/daemon/package.json +5 -1
  776. package/package.json +1 -1
  777. package/tui/dist/daemon-client.d.ts +5 -0
  778. package/tui/dist/daemon-client.d.ts.map +1 -1
  779. package/tui/dist/daemon-client.js +17 -0
  780. package/tui/dist/daemon-client.js.map +1 -1
  781. package/tui/dist/hydrate.d.ts.map +1 -1
  782. package/tui/dist/hydrate.js +12 -4
  783. package/tui/dist/hydrate.js.map +1 -1
  784. package/tui/dist/live-events.d.ts +21 -0
  785. package/tui/dist/live-events.d.ts.map +1 -0
  786. package/tui/dist/live-events.js +88 -0
  787. package/tui/dist/live-events.js.map +1 -0
  788. package/tui/dist/live.js +1 -1
  789. package/tui/dist/main.js +27 -8
  790. package/tui/dist/main.js.map +1 -1
  791. package/tui/dist/refresh.d.ts +10 -1
  792. package/tui/dist/refresh.d.ts.map +1 -1
  793. package/tui/dist/refresh.js +22 -2
  794. package/tui/dist/refresh.js.map +1 -1
  795. package/daemon/context-packs/world/install/01-world-from-primitives.md +0 -97
  796. package/daemon/context-packs/world/install/02-permission-self-sleep.md +0 -141
  797. package/daemon/context-packs/world/install/03-what-this-is-for.md +0 -86
  798. package/daemon/context-packs/world/install/04-ontology.md +0 -790
  799. package/daemon/context-packs/world/install/05-harness-power-use.md +0 -355
  800. package/daemon/context-packs/world/install/06-a-competent-turn.md +0 -225
  801. package/daemon/context-packs/world/install/manifest.yaml +0 -125
  802. package/dist/lib/scope-templates/mission-brief.md +0 -20
  803. package/dist/lib/scope-templates/mission-notes.md +0 -102
  804. package/dist/slack/config.d.ts.map +0 -1
  805. package/dist/slack/config.js.map +0 -1
  806. package/dist/slack/connector-server.d.ts +0 -31
  807. package/dist/slack/connector-server.d.ts.map +0 -1
  808. package/dist/slack/connector-server.js +0 -108
  809. package/dist/slack/connector-server.js.map +0 -1
  810. package/dist/slack/inbound-admission.d.ts.map +0 -1
  811. package/dist/slack/inbound-admission.js.map +0 -1
  812. package/dist/slack/inbound.d.ts.map +0 -1
  813. package/dist/slack/inbound.js.map +0 -1
  814. package/dist/slack/message.d.ts +0 -39
  815. package/dist/slack/message.d.ts.map +0 -1
  816. package/dist/slack/message.js +0 -88
  817. package/dist/slack/message.js.map +0 -1
  818. package/dist/slack/outbound.d.ts +0 -39
  819. package/dist/slack/outbound.d.ts.map +0 -1
  820. package/dist/slack/outbound.js +0 -63
  821. package/dist/slack/outbound.js.map +0 -1
  822. package/dist/slack/queue-bridge.d.ts +0 -61
  823. package/dist/slack/queue-bridge.d.ts.map +0 -1
  824. package/dist/slack/queue-bridge.js +0 -114
  825. package/dist/slack/queue-bridge.js.map +0 -1
  826. package/dist/slack/secrets.d.ts.map +0 -1
  827. package/dist/slack/secrets.js.map +0 -1
  828. package/dist/slack/slack-api.d.ts +0 -49
  829. package/dist/slack/slack-api.d.ts.map +0 -1
  830. package/dist/slack/slack-api.js +0 -110
  831. package/dist/slack/slack-api.js.map +0 -1
  832. package/dist/slack/slack-delivery.d.ts +0 -14
  833. package/dist/slack/slack-delivery.d.ts.map +0 -1
  834. package/dist/slack/slack-delivery.js +0 -28
  835. package/dist/slack/slack-delivery.js.map +0 -1
  836. package/dist/slack/state-store.d.ts.map +0 -1
  837. package/dist/slack/state-store.js.map +0 -1
  838. /package/{dist → daemon/dist/domain/gateway}/slack/inbound-admission.js +0 -0
  839. /package/{dist → daemon/dist/domain/gateway}/slack/secrets.d.ts +0 -0
  840. /package/{dist → daemon/dist/domain/gateway}/slack/secrets.js +0 -0
  841. /package/{dist → daemon/dist/domain/gateway}/slack/state-store.d.ts +0 -0
  842. /package/{dist → daemon/dist/domain/gateway}/slack/state-store.js +0 -0
@@ -0,0 +1,653 @@
1
+ #!/usr/bin/env python3
2
+ """compose.py — leaf-to-root chain composition and subtree renders.
3
+
4
+ SUPERSEDED FOR REFOCUS: the public core reorientation trace lives at
5
+ ../../refocusing/scripts/trace-to-root.py. This general composer remains the
6
+ compatibility surface for down/progress and historical up invocations.
7
+
8
+ up <start-dir> --name FILE [--name FILE ...] [--root DIR]
9
+ Walk from start-dir up to root (default: filesystem stops at a dir
10
+ containing .compose-root, or at --root). Emit the chain ROOT-FIRST
11
+ (defaults, then overrides) with provenance headers, and a MISSING-LINK
12
+ report for altitudes without the file — the scream is output, not error.
13
+
14
+ down <root-dir> --name FILE [--name FILE ...] [--exclude GLOB ...]
15
+ Gather every instance of the named files under root-dir.
16
+
17
+ progress <root-dir> --name FILE [--name FILE ...] [--exclude GLOB ...]
18
+ THE DERIVED PROGRESS VIEW (the PROGRESS.md prototype done right):
19
+ count markdown checkboxes in the named files (the mark level), roll
20
+ counts UP the tree, and print a walk-map-shaped tree with done/total
21
+ per level. Never stored in any file — the render is the only home.
22
+ Gather every instance of the named files under root-dir (the subtree
23
+ render; run at the topology root = THE TRUNK RENDER). Sorted by path.
24
+
25
+ Composed output is GENERATED, NEVER EDITED (fragments are the source of truth).
26
+ Seals/locks bind to a render's bytes, not to fragments. Stdlib only.
27
+ """
28
+ import argparse, os, sys, fnmatch, datetime, re, shutil, subprocess
29
+
30
+ # A SHELF holds instances of an altitude; it is not a position and carries no chain file.
31
+ # Both trees have them: missions/ slices/ (work) and rigs/ pods/ seats/ (topology). Without
32
+ # this list the trace reports every shelf as a gap and the audit tells you to scaffold one —
33
+ # which is litter that inflates the map to a clean-looking 5/5 while adding nothing. Extend
34
+ # with --shelf for a tree that names them differently.
35
+ SHELF_NAMES = {"missions", "slices", "seats", "pods", "rigs"}
36
+
37
+ _TPL_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "templates")
38
+ def _template_bytes(name):
39
+ try:
40
+ return open(os.path.join(_TPL_DIR, name), "rb").read()
41
+ except OSError:
42
+ return None
43
+
44
+ def read_state(path):
45
+ """Detection is DETERMINISTIC-FIRST, declared-second — never memory-reliant:
46
+ 1. byte-identical to the shipped template -> 'unseeded' (nobody had to remember anything)
47
+ 2. `status: UNSEEDED` marker on content that DIFFERS from the template -> 'conflicted':
48
+ render the content AND scream — real work is never hidden behind a stale field,
49
+ and the disagreement is its own reported state (third-state law).
50
+ 3. otherwise -> 'seeded'. Every residual failure mode shows too much plus a scream,
51
+ never hides work and never silently trusts a field."""
52
+ raw = open(path, "rb").read()
53
+ tpl = _template_bytes(os.path.basename(path))
54
+ body = raw.decode("utf-8", errors="replace")
55
+ head = "\n".join(body.splitlines()[:15])
56
+ marked = re.search(r"^status:\s*UNSEEDED", head, re.M)
57
+ if tpl is not None and raw == tpl:
58
+ m = re.search(r"^owners?:\s*(.+)$", head, re.M)
59
+ return "unseeded", (m.group(1).strip() if m else "owner unknown — untouched scaffold")
60
+ if marked:
61
+ return "conflicted", body
62
+ return "seeded", body
63
+
64
+ def hdr(title):
65
+ return f"\n\n<!-- ═══ {title} ═══ -->\n\n## ⟦{title}⟧\n"
66
+
67
+ def frontmatter(payload):
68
+ """Parse the frontmatter block ONCE. Returns (dict, note); note is set when there is
69
+ nothing to read, so a caller can report the gap rather than silently skip it."""
70
+ if not payload:
71
+ return None, "no content"
72
+ m = re.match(r"^---\n(.*?)\n---\n", payload, re.S)
73
+ if not m:
74
+ return None, "no frontmatter"
75
+ try:
76
+ import yaml
77
+ return (yaml.safe_load(m.group(1)) or {}), None
78
+ except Exception as e:
79
+ return None, f"frontmatter did not parse ({e.__class__.__name__})"
80
+
81
+ def field_of(payload, field):
82
+ """Extract ONE frontmatter field. Returns (value, note).
83
+ A chain walked by FIELD composes intent without dragging bodies: three sentences
84
+ unfurl, not three documents. A level whose file exists but lacks the field is a
85
+ real gap and is reported as such — never silently skipped."""
86
+ fm, note = frontmatter(payload)
87
+ if fm is None:
88
+ return None, note
89
+ if field not in fm:
90
+ return None, f"no `{field}:` field"
91
+ v = fm[field]
92
+ return (" ".join(str(v).split()) if v is not None else None), None
93
+
94
+ def _cut_at_boundary(s, n):
95
+ """Cut to AT MOST n chars, NEVER inside a token.
96
+
97
+ Measured 2026-08-14: a cold subject read `see PROOF.m…` and `see P…` in the walk's own
98
+ output. A path cut mid-token still READS as a path — the reader cannot tell `PROOF.m` from
99
+ a file that is actually called that, so a truncation artifact is silently promoted to a
100
+ fact about the tree. Filenames, paths and identifiers are exactly the tokens a reader is
101
+ most likely to act on, which makes them the worst place to lose characters.
102
+
103
+ So the cut lands on whitespace or it does not land: paragraph, then line, then word. A
104
+ single unbroken token longer than the budget is DROPPED WHOLE rather than shortened —
105
+ half an identifier is worse than no identifier."""
106
+ if len(s) <= n:
107
+ return s
108
+ head = s[:n]
109
+ if s[n:n + 1].isspace(): # n already sits on a boundary
110
+ return head.rstrip()
111
+ for sep, floor in (("\n\n", n // 2), ("\n", n // 2), (" ", 0)):
112
+ i = head.rfind(sep)
113
+ if i > floor:
114
+ return head[:i].rstrip()
115
+ return "" # one unbroken token — drop it, never cut into it
116
+
117
+
118
+ def _short(s, n=52):
119
+ s = " ".join(str(s).split())
120
+ if len(s) <= n:
121
+ return s
122
+ return _cut_at_boundary(s, n - 1).rstrip(" ,;:.-—") + "…"
123
+
124
+ _ARTIFACT_KEYS = ("outputs", "output", "artifacts", "artifact")
125
+
126
+
127
+ def dep_artifacts(dep_dir, names, dep_fm):
128
+ """WHAT THE DEPENDENCY HANDS YOU — the file, not the fact that it is done.
129
+
130
+ Frontmatter first if the node declares it (`outputs:`/`output:`/`artifacts:`/`artifact:`),
131
+ because a declaration outranks a guess. Otherwise the directory itself: everything beside
132
+ the node file, which for a built slice IS its output (MAP.md, PROOF.md, the script). No
133
+ prose parsing — a `## Output` section is written for humans and reading it would make the
134
+ trace confidently wrong exactly where it is trying to stop being that."""
135
+ for k in _ARTIFACT_KEYS:
136
+ v = (dep_fm or {}).get(k)
137
+ if v:
138
+ return [" ".join(str(x).split()) for x in (v if isinstance(v, list) else [v])], "declared"
139
+ try:
140
+ entries = sorted(os.listdir(dep_dir))
141
+ except OSError:
142
+ return [], "unreadable"
143
+ out = [e + ("/" if os.path.isdir(os.path.join(dep_dir, e)) else "")
144
+ for e in entries if not e.startswith(".") and e not in set(names)]
145
+ return out, "on disk"
146
+
147
+
148
+ def blocking_state(payload, lvl, names):
149
+ """THE LEAF'S NEXT-ACTION FACTS, composed BESIDE its intent. Returns a line or None.
150
+
151
+ Measured 2026-08-14: a cold seat walked `--field intent`, reconstructed the mission's
152
+ thesis from ~90 words, and finished green and ready to start work its own slice says is
153
+ blocked — because the walk opened the file holding `status: not-started`, extracted
154
+ exactly one key, and threw the rest away. It answers *what is this for* completely and
155
+ *what should I do now* not at all, and ships as though the first answered the second.
156
+
157
+ So the blocking facts ride along: `status`, and `depends:` — a sibling slice id (or a
158
+ list of them) RESOLVED ON DISK so the dependency's current state is reported rather than
159
+ remembered. Leaf only — the ancestors say what the work is for, and only the leaf says
160
+ whether to start it.
161
+
162
+ Measured 2026-08-14: a cold subject working slice 13 needed slice 11's OUTPUT. The walk
163
+ gave it 11's STATE and nothing else; the subject called the missing location "the single
164
+ largest unknown in my Phase 1 answer and it was the load-bearing input", and resolved it
165
+ with `ls` a phase later. A status answers *may I start*; it does not answer *where is the
166
+ thing I start from*. So each dependency now renders its ABSOLUTE PATH and its output
167
+ ARTIFACTS beside its state — and an id that resolves to nothing renders UNRESOLVED, said
168
+ out loud, because an unresolvable dependency dropped in silence is the same false
169
+ confidence in a smaller box."""
170
+ fm, _ = frontmatter(payload)
171
+ if not fm:
172
+ return None
173
+ parts = []
174
+ if fm.get("status") is not None:
175
+ parts.append(f"status: {_short(fm['status'], 88)}")
176
+ deps = fm.get("depends")
177
+ if deps:
178
+ shelf = os.path.dirname(lvl)
179
+ lines = ["depends:"]
180
+ for dep in (deps if isinstance(deps, list) else [deps]):
181
+ dep = " ".join(str(dep).split())
182
+ dep_dir = os.path.join(shelf, dep)
183
+ if not os.path.isdir(dep_dir):
184
+ lines.append(f" {dep} — ⚠ UNRESOLVED: no directory `{dep}` under {shelf}"
185
+ f" (nothing to point you at — check the id)")
186
+ continue
187
+ state, dfm = None, None
188
+ for n in names:
189
+ cand = os.path.join(dep_dir, n)
190
+ if os.path.isfile(cand):
191
+ st, body = read_state(cand)
192
+ dfm = frontmatter(body)[0] if st != "unseeded" else None
193
+ state = _short((dfm or {}).get("status") or st)
194
+ break
195
+ lines.append(f" {dep} ({state})" if state else
196
+ f" {dep} (⚠ no {'/'.join(names)} — state unknown)")
197
+ lines.append(f" path: {os.path.abspath(dep_dir)}")
198
+ arts, how = dep_artifacts(dep_dir, names, dfm)
199
+ if arts:
200
+ shown = arts[:8]
201
+ more = f" (+{len(arts) - 8} more)" if len(arts) > 8 else ""
202
+ lines.append(f" artifacts ({how}): " + " · ".join(shown) + more)
203
+ else:
204
+ lines.append(f" artifacts: ⚠ none found — the dependency has produced no"
205
+ f" output file yet")
206
+ parts.append("\n".join(lines)) # lines 2+ carry their own indent; the caller indents line 1
207
+ return "\n ".join(parts) or None
208
+
209
+
210
+ def operates_on(payload):
211
+ """The roots this WORK touches — which are NOT the root the trace ascended.
212
+
213
+ Measured 2026-08-14, 4 cold subjects out of 4: the walk orients to PURPOSE excellently
214
+ and misleads on LOCATION every time. Naming the walked root did not help, because the
215
+ failure is not "which tree am I looking at" — it is "which tree does this work act on."
216
+ A slice about the skill library renders inside a map rooted at the workspace, and the
217
+ reader plans into the tree it was shown. One subject planned to CREATE a second corpus,
218
+ duplicating the very thing whose duplication was that slice's subject.
219
+
220
+ The walk cannot infer this: a work node is not bound to a root. So the node DECLARES it
221
+ and the leaf renders it verbatim. Mechanical, like `depends:`, and absent when unstated
222
+ rather than guessed."""
223
+ fm, _ = frontmatter(payload)
224
+ if not fm:
225
+ return None
226
+ roots = fm.get("operates_on")
227
+ if not roots:
228
+ return None
229
+ return [" ".join(str(r).split()) for r in (roots if isinstance(roots, list) else [roots])]
230
+
231
+
232
+ # WHAT SURVIVES TRUNCATION. Both lists are read off the 15 real SPEC.md files of
233
+ # context-engineering-v2 — every pattern below matches a heading that actually exists there;
234
+ # no category is invented for symmetry. CONTRACT is the completion-and-scope family (`Done
235
+ # when`, `What done looks like`, `Scope fences`, `Output`, `Inputs`, `Depends on`, `What must
236
+ # be built`, `How we will know it works`, `PAYLOAD`). DISCUSSION is the rationale-and-history
237
+ # family (`Why …`, `The problem …`, `The evidence …`, `The finding …`, `RESULT …`, `Also
238
+ # found`, `Triage`, `What is already done`, `New evidence`, `Where this spec was wrong`) —
239
+ # valuable, and the first thing a reader can go get from the file itself.
240
+ # Anything unmatched sits in the MIDDLE on purpose: an unfamiliar heading is neither
241
+ # privileged nor sacrificed, so a new section shape degrades gracefully instead of silently
242
+ # becoming the first casualty.
243
+ _PRI_CONTRACT = re.compile(
244
+ r"(done when|what done looks like|scope fence|outputs?\b|inputs?\b|depends on|"
245
+ r"what must be built|how we will know|acceptance|payload|deliverable)", re.I)
246
+ _PRI_DISCUSSION = re.compile(
247
+ r"^(why\b|the problem|the evidence|the finding|result\b|also\b|related\b|triage\b|"
248
+ r"background\b|history\b|what is already done|new evidence|measured\b|answered\b|"
249
+ r"where this spec was wrong|notes for|the counter-argument|the asset|the mechanism|"
250
+ r"this mission is the acceptance criteria)", re.I)
251
+
252
+
253
+ def _priority(heading):
254
+ """0 = preamble (never dropped) · 1 = contract · 2 = unclassified · 3 = discussion."""
255
+ if heading is None:
256
+ return 0
257
+ if _PRI_CONTRACT.search(heading):
258
+ return 1
259
+ if _PRI_DISCUSSION.match(heading):
260
+ return 3
261
+ return 2
262
+
263
+
264
+ def _sections(body):
265
+ """Split a node body at LEVEL-2 headings into [(heading|None, chunk), ...].
266
+
267
+ Chunk 0 is the preamble — the `# Title` and its lede — and carries heading None. `###`
268
+ stays inside its parent section: in these specs it is a sub-step of the section above it,
269
+ and splitting there would let half a section survive its own heading."""
270
+ starts = [m.start() for m in re.finditer(r"^## +.*$", body, re.M)]
271
+ if not starts:
272
+ return [(None, body)]
273
+ out = [(None, body[:starts[0]])]
274
+ for i, s in enumerate(starts):
275
+ chunk = body[s:starts[i + 1] if i + 1 < len(starts) else len(body)]
276
+ out.append((chunk.splitlines()[0].lstrip("# ").strip(), chunk))
277
+ return out
278
+
279
+
280
+ def leaf_body(payload, cap):
281
+ """Ancestors compose by FIELD; the leaf composes by BODY.
282
+
283
+ Measured 2026-08-14 (slice 01 A/B): a cold agent given three intent sentences
284
+ reconstructed the mission's thesis correctly, then assumed the work tree it had been
285
+ shown was the tree its slice was about. The slice was about the TOPOLOGY tree. It built
286
+ a coherent four-step plan aimed at the wrong one — and the three altitudes it planned
287
+ over need three different verbs, which it had no way to know.
288
+
289
+ That is misdirection, not a gap. Ancestors compress beautifully because they are stable
290
+ and abstract. **The leaf is where the nouns live, and a field-only walk throws them
291
+ away** — every word that would have disambiguated it sat in the body that was not shown.
292
+
293
+ Truncation is BY PRIORITY, never by position. Measured 2026-08-14: positional cutting on
294
+ slice 13 dropped `Output`, `Done when` and `Scope fences` — the three sections that say
295
+ what to produce, when it is finished and what it may not touch — and kept four screens of
296
+ rationale, because the rationale happened to be written first. The subject rated its own
297
+ grasp of purpose 85% and its next action 70% and named that omission as the reason. A
298
+ render that keeps the argument and drops the contract has the priorities backwards."""
299
+ if not payload:
300
+ return None
301
+ m = re.match(r"^---\n.*?\n---\n", payload, re.S)
302
+ body = (payload[m.end():] if m else payload).strip()
303
+ if not body:
304
+ return None
305
+ if len(body) <= cap:
306
+ return body
307
+ secs = _sections(body)
308
+ if len(secs) == 1: # headingless prose — nothing to prioritise
309
+ kept = _cut_at_boundary(body, cap)
310
+ return (kept + "\n\n[… " + str(len(body) - len(kept)) + " more chars, no further "
311
+ "headings — prose tail]" + "\n(read the node file for these)")
312
+ # Drop LOWEST priority first and, within a tier, the LARGEST section first. Size beats
313
+ # position here and it was measured: slice 13's contract sections total more than any
314
+ # sane cap, and dropping the tier tail-first killed `Done when` (12 lines) and `Scope
315
+ # fences` (9) to save `Output` and `Inputs` (~2k chars each) — the two long prose
316
+ # sections eating the two short decisive ones. Largest-first keeps the most sections
317
+ # standing, and in these specs the short section is the one carrying the ruling. The
318
+ # preamble (title + lede, index 0) is never a candidate: it is what names the thing.
319
+ keep, size = set(range(len(secs))), len(body)
320
+ for i in sorted(range(1, len(secs)), key=lambda i: (-_priority(secs[i][0]), -len(secs[i][1]))):
321
+ if size <= cap:
322
+ break
323
+ keep.discard(i)
324
+ size -= len(secs[i][1])
325
+ kept = "".join(secs[i][1] for i in sorted(keep)).rstrip()
326
+ if len(kept) > cap: # preamble alone overflows; cut it safely, never mid-token
327
+ kept = _cut_at_boundary(kept, cap)
328
+ dropped = [secs[i][0] for i in range(1, len(secs)) if i not in keep]
329
+ # NAME what was cut. A byte count reads as trivia; two subjects in a row lost the
330
+ # acceptance criteria to it and neither could tell, because a truncated head can end on
331
+ # a clean rhetorical close and look like a finished document. Listing the dropped
332
+ # headings turns invisible truncation into a decision the reader can actually make —
333
+ # one subject lowered its own confidence honestly on the strength of this line alone.
334
+ tail = ("\n\nOMITTED FROM THIS RENDER — " + str(len(body) - len(kept)) + " chars, sections: "
335
+ + " · ".join(dropped) if dropped else
336
+ "\n\n[… " + str(len(body) - len(kept)) + " more chars, no further headings — prose tail]")
337
+ return kept + tail + "\n(read the node file for these)"
338
+
339
+
340
+ def resolve_roots():
341
+ """WHERE THE TWO TREES LIVE — resolved, never hardcoded, never guessed.
342
+
343
+ A skill ships inside a plugin and its scripts must run unmodified on a stranger's machine.
344
+ The WORK tree has been addressable for a while (`workspace.root`). The TOPOLOGY tree was not:
345
+ every consumer hardcoded `~/.openrig/shared-docs`, so half the walk was portable and half was
346
+ not. Precedence matches every other typed key: env > config > derived > fail-with-the-key.
347
+
348
+ The derived step is honest rather than clever: this script physically lives inside the
349
+ shared-docs tree, so it can find its own `rigs/` sibling by walking up from __file__. That
350
+ works for the library copy and its symlinked projections (resolved with realpath) and NOT for
351
+ a real plugin copy — which is correct. A plugin copy on
352
+ someone else's machine has no business inferring a path; it must be told, and it fails saying
353
+ exactly which key to set rather than picking a directory and being confidently wrong."""
354
+ out = {}
355
+ out["work_root"] = os.environ.get("OPENRIG_WORKSPACE_ROOT") or rig_config("workspace.root")
356
+
357
+ t = os.environ.get("OPENRIG_TOPOLOGY_ROOT") or rig_config("workspace.topology_root")
358
+ if not t:
359
+ # realpath, NOT abspath: the runtime tiers project this script as a SYMLINK
360
+ # (~/.claude/skills/... -> the library copy). abspath keeps the symlink's own path, so
361
+ # the ascent runs up a tree with no `rigs/` sibling and topology_root comes back
362
+ # UNRESOLVED — for every agent reaching the tool the documented way. Measured 2026-08-14:
363
+ # exit 3 via the projection, exit 0 via the realpath, same file.
364
+ here = os.path.realpath(__file__)
365
+ for _ in range(6): # scripts/ skill/ skills/ skill-canon/ -> shared-docs/
366
+ here = os.path.dirname(here)
367
+ cand = os.path.join(here, "rigs")
368
+ if os.path.isdir(cand):
369
+ t = cand
370
+ break
371
+ out["topology_root"] = t
372
+ return out
373
+
374
+
375
+ def rig_config(key):
376
+ if not shutil.which("rig"):
377
+ return None
378
+ try:
379
+ p = subprocess.run(["rig", "config", "get", key], capture_output=True, text=True, timeout=10)
380
+ v = (p.stdout or "").strip()
381
+ return v if p.returncode == 0 and v else None
382
+ except Exception:
383
+ return None
384
+
385
+
386
+ def compose_up(start, names, root, field=None, prefer=False, shelves=None, leaf_cap=2400):
387
+ shelves = SHELF_NAMES | set(shelves or ())
388
+ start = os.path.abspath(start); root = os.path.abspath(root) if root else None
389
+ levels = []
390
+ d = start
391
+ while True:
392
+ levels.append(d)
393
+ if root and os.path.samefile(d, root): break
394
+ if not root and os.path.exists(os.path.join(d, ".compose-root")): break
395
+ parent = os.path.dirname(d)
396
+ if parent == d: break
397
+ d = parent
398
+ levels.reverse() # root first: defaults, then overrides
399
+ out = [f"<!-- GENERATED by compose.py up · {datetime.datetime.now().isoformat(timespec='minutes')} -->",
400
+ f"<!-- start: {start} · altitudes: {sum(1 for d in levels if os.path.basename(d) not in shelves)} ({len(levels)} path segments) · chains: {', '.join(names)}" + (f" · FIELD: {field}" if field else "") + " -->",
401
+ "<!-- Composed view — never edit; edit the fragments. -->"]
402
+ GLYPH = {"seeded": "✓ seeded", "unseeded": "⟂ UNSEEDED", "conflicted": "⚠ stale marker",
403
+ "absent": "✗ absent", "shelf": "· shelf"}
404
+ missing, unseeded = [], []
405
+ # --prefer turns the --name list into ONE chain resolved per level by precedence
406
+ # (first match wins) instead of N independent chains. A tree mid-rename is the normal
407
+ # case, not an exception: SPEC.md is the current node filename and README.md the legacy
408
+ # one, and a trace that cannot span both reports a chain as broken when it is merely mixed.
409
+ # Test the START NODE against the TREES, not the root against the workspace. Being
410
+ # somewhere under workspace.root is not the property that matters: the measured hazard
411
+ # is a fixture tree at workspace/artifacts/<qitem>/fixture-workspace/missions/, which is
412
+ # inside workspace.root and is not a work tree. Only slices_root and topology_root name
413
+ # actual trees, so those are the discriminator.
414
+ _cfg = [c for c in (rig_config("workspace.slices_root"),
415
+ resolve_roots().get("topology_root")) if c]
416
+ _here = os.path.abspath(start)
417
+ _root_warning = None
418
+ if _cfg and not any(_here == os.path.abspath(c) or _here.startswith(os.path.abspath(c) + os.sep)
419
+ for c in _cfg):
420
+ _root_warning = (" ⚠ THIS IS NOT A CONFIGURED TREE. Trees on this instance: "
421
+ + " · ".join(_cfg) + "\n A walk renders just as cleanly from a stray or"
422
+ " fixture tree — verify before acting on it.")
423
+ groups = [list(names)] if prefer else [[n] for n in names]
424
+ for group in groups:
425
+ name = group[0]
426
+ out.append(f"\n\n# CHAIN: {' → '.join(group)} (root → leaf)"
427
+ + (" · precedence: first match wins per level" if len(group) > 1 else ""))
428
+ # pass 1 — collect the state of every level (this IS the trace; the map derives from it)
429
+ chain, hits = [], {}
430
+ for lvl in levels:
431
+ p = None
432
+ for n in group:
433
+ cand = os.path.join(lvl, n)
434
+ if os.path.isfile(cand):
435
+ p, hits[lvl] = cand, n
436
+ break
437
+ where = os.path.relpath(lvl, levels[0]) or '.'
438
+ # A SHELF is a path segment, not an altitude. The chain has three rungs — project,
439
+ # mission, slice — and rendering `missions/` and `slices/` as rungs implies five.
440
+ # Any file living at a shelf is ordinary folder documentation, NOT a chain link:
441
+ # ignore it rather than flagging it. `README.md` does double duty as a legacy node
442
+ # name and as a plain readme, and only the level it sits at can tell them apart.
443
+ is_shelf = os.path.basename(lvl) in shelves
444
+ if is_shelf:
445
+ state, payload, p = "shelf", None, None
446
+ hits.pop(lvl, None)
447
+ elif p:
448
+ state, payload = read_state(p)
449
+ else:
450
+ state, payload = "absent", None
451
+ # Resolve the field HERE so the map can tell the truth. A map keyed on file
452
+ # presence says ✓ for a level that composes nothing — the exact reading that
453
+ # lets a trace certify the drift it exists to catch.
454
+ fval, fnote = (field_of(payload, field) if (field and state == "seeded") else (None, None))
455
+ chain.append((lvl, where, state, payload, fval, fnote))
456
+ # TRACE — derived orientation tree (never stored in files; the render is the only home)
457
+ # The map shows ALTITUDES as rungs; shelves fold into the next rung's path so the tree
458
+ # depth equals the number of levels that actually carry intent.
459
+ rungs, pending = [], []
460
+ for idx, row in enumerate(chain):
461
+ if row[2] == "shelf" and idx != len(chain) - 1:
462
+ pending.append(os.path.basename(row[0]) or row[0])
463
+ continue
464
+ label = "/".join(pending + [os.path.basename(row[0]) or row[0]])
465
+ rungs.append((label, row)); pending = []
466
+ leads = [("" if i == 0 else " " * (i - 1) + "└─ ") + rungs[i][0] + "/" for i in range(len(rungs))]
467
+ width = max(len(l) for l in leads) + 2
468
+ # NAME THE REFERENT. Three cold subjects in a row assumed the tree they were
469
+ # SHOWN was the tree their slice was ABOUT, and planned into the wrong one. The map
470
+ # cannot know "work" vs "topology" semantically, but it knows what it walked — and
471
+ # root + chain filename is enough to tell them apart (workspace/SPEC.md vs rigs/LEARNED.md).
472
+ out.append(f"\nTRACE · root {levels[0]} · chain {' → '.join(group)}")
473
+ # VALIDATE THE ROOT. Measured 2026-08-14: this box has four directories named
474
+ # `missions`, one of them a TEST FIXTURE under artifacts/. Handed the fixture as
475
+ # --root, the trace renders an equally clean, equally confident chain — because
476
+ # `✓ seeded` means "a file was found here", never "you are in the right tree".
477
+ # Confidence that is independent of correctness is the failure this whole mission
478
+ # is against, so the trace now says when it cannot vouch for where it is standing.
479
+ if _root_warning:
480
+ out.append(_root_warning)
481
+ for i, (_label, (lvl, where, state, payload, fval, fnote)) in enumerate(rungs):
482
+ note = f" (owner: {payload})" if state == "unseeded" and payload else ""
483
+ here = " ← you are here" if i == len(rungs) - 1 else ""
484
+ glyph = f"⟂ no {field}" if (field and state == "seeded" and not fval) else GLYPH[state]
485
+ # In precedence mode, name WHICH file answered at each level — a mixed tree is
486
+ # readable state, not noise, and hiding it is how a rename looks like corruption.
487
+ via = f" [{hits[lvl]}]" if len(group) > 1 and lvl in hits and state != "shelf" else ""
488
+ out.append(f" {leads[i]:<{width}}{glyph}{via}{note}{here}")
489
+ # pass 2 — contents, states collapsed per the three-state rules
490
+ found = 0
491
+ for lvl, where, state, payload, fval, fnote in chain:
492
+ if state == "shelf":
493
+ continue # a path segment, not a position — contributes nothing, flags nothing
494
+ elif state == "unseeded":
495
+ out.append(f"\n⟂ {name} @ {where} — UNSEEDED (scaffold only, not rendered; seed it: {payload})")
496
+ unseeded.append(f"{name} @ {where} (owner: {payload})")
497
+ elif state == "conflicted":
498
+ found += 1
499
+ out.append(hdr(f"{name} @ {where} — ⚠ carries status: UNSEEDED but content differs from template"))
500
+ out.append(payload.rstrip())
501
+ unseeded.append(f"{name} @ {where} — MARKER/CONTENT DISAGREE: rendered anyway; owner should clear the stale status line")
502
+ elif state == "seeded":
503
+ found += 1
504
+ if field:
505
+ if fval:
506
+ out.append(f"\n{where}: {fval}")
507
+ else:
508
+ out.append(f"\n{where}: ⚠ {fnote}")
509
+ unseeded.append(f"{name} @ {where} — {fnote}")
510
+ # The leaf is the only level whose answer is an ACTION. Compose its
511
+ # blocking state here or the walk certifies the next step it never read.
512
+ if lvl == chain[-1][0]:
513
+ blocked = blocking_state(payload, lvl, group)
514
+ if blocked:
515
+ out.append(f" {blocked}")
516
+ roots = operates_on(payload)
517
+ if roots:
518
+ out.append(" operates on: " + " · ".join(roots))
519
+ # ...and the only altitude that SPECIFIES. See leaf_body().
520
+ lb = leaf_body(payload, leaf_cap) if leaf_cap else None
521
+ if lb:
522
+ out.append(f"\n─── {where} · node body ───")
523
+ out.append(lb)
524
+ else:
525
+ out.append(hdr(f"{name} @ {where}"))
526
+ out.append(payload.rstrip())
527
+ else:
528
+ missing.append(f"{name} @ {where}")
529
+ if not found:
530
+ out.append(f"\n⚠ NO seeded instances of {name} on this walk.")
531
+ if unseeded or missing:
532
+ out.append("\n\n# ⚠ CHAIN AUDIT (the walk screams once, here — never by breaking, never by template litter)")
533
+ if unseeded:
534
+ out.append("UNSEEDED (file exists, template only — the owner writes the first true version):")
535
+ out += [f"- {m}" for m in unseeded]
536
+ if missing:
537
+ out.append("ABSENT (no file at a POSITION — scaffold it, or report to the level owner if absence looks wrong):")
538
+ out += [f"- {m}" for m in missing]
539
+ return "\n".join(out)
540
+
541
+ def compose_down(root, names, excludes):
542
+ root = os.path.abspath(root)
543
+ hits = []
544
+ for dirpath, dirs, files in os.walk(root):
545
+ dirs[:] = [x for x in dirs if not x.startswith(".") and x != "node_modules"
546
+ and not any(fnmatch.fnmatch(os.path.join(dirpath, x), g) for g in excludes)]
547
+ for name in names:
548
+ if name in files:
549
+ hits.append(os.path.join(dirpath, name))
550
+ hits.sort()
551
+ out = [f"<!-- GENERATED by compose.py down · {datetime.datetime.now().isoformat(timespec='minutes')} -->",
552
+ f"<!-- root: {root} · files: {len(hits)} · chains: {', '.join(names)} -->",
553
+ "<!-- Subtree render (trunk render at a tree root). Never edit. -->"]
554
+ unseeded = []
555
+ for p in hits:
556
+ state, payload = read_state(p)
557
+ rel = os.path.relpath(p, root)
558
+ if state == "unseeded":
559
+ unseeded.append(f"{rel} (owner: {payload})")
560
+ elif state == "conflicted":
561
+ out.append(hdr(f"{rel} — ⚠ stale UNSEEDED marker on real content"))
562
+ out.append(payload.rstrip())
563
+ unseeded.append(f"{rel} — MARKER/CONTENT DISAGREE: rendered anyway; clear the stale status line")
564
+ else:
565
+ out.append(hdr(rel))
566
+ out.append(payload.rstrip())
567
+ if unseeded:
568
+ out.append("\n\n# ⚠ UNSEEDED under this root (scaffold only — collapsed, not rendered)")
569
+ out += [f"- {u}" for u in unseeded]
570
+ if not hits:
571
+ out.append("\n⚠ no chain files under this root — unfurl first?")
572
+ return "\n".join(out)
573
+
574
+ def compose_progress(root, names, excludes):
575
+ import collections
576
+ root = os.path.abspath(root)
577
+ direct = collections.defaultdict(lambda: [0, 0]) # dir -> [done, total] from its own files
578
+ for dirpath, dirs, files in os.walk(root):
579
+ dirs[:] = [x for x in dirs if not x.startswith(".") and x != "node_modules"
580
+ and not any(fnmatch.fnmatch(os.path.join(dirpath, x), g) for g in excludes)]
581
+ for name in names:
582
+ if name in files:
583
+ txt = open(os.path.join(dirpath, name), encoding="utf-8", errors="replace").read()
584
+ done = len(re.findall(r"^\s*[-*] \[[xX]\]", txt, re.M))
585
+ open_ = len(re.findall(r"^\s*[-*] \[ \]", txt, re.M))
586
+ if done + open_:
587
+ direct[dirpath][0] += done
588
+ direct[dirpath][1] += done + open_
589
+ agg = collections.defaultdict(lambda: [0, 0]) # dir -> rolled-up [done, total]
590
+ for d, (dn, tt) in direct.items():
591
+ cur = d
592
+ while True:
593
+ agg[cur][0] += dn; agg[cur][1] += tt
594
+ if os.path.samefile(cur, root): break
595
+ cur = os.path.dirname(cur)
596
+ out = [f"<!-- GENERATED by compose.py progress · {datetime.datetime.now().isoformat(timespec='minutes')} -->",
597
+ "<!-- Derived from the mark level at render time. Never store this in a file. -->",
598
+ f"\nPROGRESS MAP ({', '.join(names)} — checkbox = the one mark level; everything above derives):"]
599
+ if not agg:
600
+ out.append(" (no checkboxes found in the named files under this root — nothing is marked here)")
601
+ return "\n".join(out)
602
+ keys = sorted(agg, key=lambda d: os.path.relpath(d, root))
603
+ leads = []
604
+ for d in keys:
605
+ rel = os.path.relpath(d, root)
606
+ depth = 0 if rel == "." else rel.count(os.sep) + 1
607
+ label = os.path.basename(root) if rel == "." else os.path.basename(d)
608
+ leads.append(("" if depth == 0 else " " * (depth - 1) + "└─ ") + label)
609
+ width = max(len(l) for l in leads) + 2
610
+ for i, d in enumerate(keys):
611
+ dn, tt = agg[d]
612
+ pct = 100 * dn // tt if tt else 0
613
+ glyph = "✓" if dn == tt else ("◐" if dn else "○")
614
+ own = " ·" if d in direct else " " # · = has marks of its own (vs pure roll-up)
615
+ out.append(f" {leads[i]:<{width}}{glyph} {dn}/{tt} ({pct}%){own}")
616
+ return "\n".join(out)
617
+
618
+ if __name__ == "__main__":
619
+ ap = argparse.ArgumentParser()
620
+ ap.add_argument("mode", choices=["up", "down", "progress", "roots"])
621
+ ap.add_argument("path", nargs="?")
622
+ ap.add_argument("--name", action="append")
623
+ ap.add_argument("--root", default=None)
624
+ ap.add_argument("--prefer", action="store_true",
625
+ help="treat --name as a PRECEDENCE list (first match wins per level) rather "
626
+ "than separate chains — for a tree mid-rename: --name SPEC.md --name README.md --prefer")
627
+ ap.add_argument("--exclude", action="append", default=[])
628
+ ap.add_argument("--field", default=None, help="compose ONE frontmatter field up the chain (e.g. --field intent) instead of whole bodies")
629
+ ap.add_argument("--leaf-cap", type=int, default=2400, metavar="N",
630
+ help="with --field: also render the LEAF's body, capped at N chars (0 = off). "
631
+ "Ancestors compress; the leaf is where the nouns are.")
632
+ ap.add_argument("--shelf", action="append", default=[],
633
+ help=f"extra directory name that HOLDS instances rather than being a position, so "
634
+ f"its absence of a chain file is correct (defaults: {', '.join(sorted(SHELF_NAMES))})")
635
+ a = ap.parse_args()
636
+ if a.mode == "roots":
637
+ r = resolve_roots()
638
+ for k in ("work_root", "topology_root"):
639
+ v = r.get(k)
640
+ if v:
641
+ print(f"{k}={v}")
642
+ else:
643
+ key = "workspace.root" if k == "work_root" else "workspace.topology_root"
644
+ print(f"# {k} UNRESOLVED — set it: rig config set {key} <path>", file=sys.stderr)
645
+ sys.exit(0 if all(r.values()) else 3)
646
+ if not a.name:
647
+ ap.error("--name is required for up/down/progress")
648
+ if a.mode == "up":
649
+ print(compose_up(a.path, a.name, a.root, a.field, prefer=a.prefer, shelves=a.shelf, leaf_cap=a.leaf_cap))
650
+ elif a.mode == "down":
651
+ print(compose_down(a.path, a.name, a.exclude))
652
+ else:
653
+ print(compose_progress(a.path, a.name, a.exclude))