@productbrain/cli 0.1.0-beta.109 → 0.1.0-beta.10908

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 (1511) hide show
  1. package/README.md +11 -2
  2. package/dist/__tests__/adapters.test.js +79 -53
  3. package/dist/__tests__/adapters.test.js.map +1 -1
  4. package/dist/__tests__/adminConfig.test.d.ts +18 -0
  5. package/dist/__tests__/adminConfig.test.d.ts.map +1 -0
  6. package/dist/__tests__/adminConfig.test.js +221 -0
  7. package/dist/__tests__/adminConfig.test.js.map +1 -0
  8. package/dist/__tests__/batch-transformations.test.js +2 -26
  9. package/dist/__tests__/batch-transformations.test.js.map +1 -1
  10. package/dist/__tests__/capture-receipt-coaching.test.d.ts +2 -0
  11. package/dist/__tests__/capture-receipt-coaching.test.d.ts.map +1 -0
  12. package/dist/__tests__/capture-receipt-coaching.test.js +109 -0
  13. package/dist/__tests__/capture-receipt-coaching.test.js.map +1 -0
  14. package/dist/__tests__/capture-receipt-role-hint.test.d.ts +2 -0
  15. package/dist/__tests__/capture-receipt-role-hint.test.d.ts.map +1 -0
  16. package/dist/__tests__/capture-receipt-role-hint.test.js +64 -0
  17. package/dist/__tests__/capture-receipt-role-hint.test.js.map +1 -0
  18. package/dist/__tests__/capture-receipt-spine-floor.test.d.ts +2 -0
  19. package/dist/__tests__/capture-receipt-spine-floor.test.d.ts.map +1 -0
  20. package/dist/__tests__/capture-receipt-spine-floor.test.js +45 -0
  21. package/dist/__tests__/capture-receipt-spine-floor.test.js.map +1 -0
  22. package/dist/__tests__/capture.test.js +941 -218
  23. package/dist/__tests__/capture.test.js.map +1 -1
  24. package/dist/__tests__/client-binding-guard.test.d.ts +2 -0
  25. package/dist/__tests__/client-binding-guard.test.d.ts.map +1 -0
  26. package/dist/__tests__/client-binding-guard.test.js +84 -0
  27. package/dist/__tests__/client-binding-guard.test.js.map +1 -0
  28. package/dist/__tests__/coaching-mirror-drift.test.d.ts +2 -0
  29. package/dist/__tests__/coaching-mirror-drift.test.d.ts.map +1 -0
  30. package/dist/__tests__/coaching-mirror-drift.test.js +50 -0
  31. package/dist/__tests__/coaching-mirror-drift.test.js.map +1 -0
  32. package/dist/__tests__/codex-prep-parity.test.d.ts +2 -0
  33. package/dist/__tests__/codex-prep-parity.test.d.ts.map +1 -0
  34. package/dist/__tests__/codex-prep-parity.test.js +84 -0
  35. package/dist/__tests__/codex-prep-parity.test.js.map +1 -0
  36. package/dist/__tests__/config-prod-fallthrough.test.d.ts +2 -0
  37. package/dist/__tests__/config-prod-fallthrough.test.d.ts.map +1 -0
  38. package/dist/__tests__/config-prod-fallthrough.test.js +93 -0
  39. package/dist/__tests__/config-prod-fallthrough.test.js.map +1 -0
  40. package/dist/__tests__/config.test.js +821 -32
  41. package/dist/__tests__/config.test.js.map +1 -1
  42. package/dist/__tests__/constellation.test.js +26 -14
  43. package/dist/__tests__/constellation.test.js.map +1 -1
  44. package/dist/__tests__/conversation.test.d.ts +2 -0
  45. package/dist/__tests__/conversation.test.d.ts.map +1 -0
  46. package/dist/__tests__/conversation.test.js +113 -0
  47. package/dist/__tests__/conversation.test.js.map +1 -0
  48. package/dist/__tests__/entry-formatter.test.d.ts +2 -0
  49. package/dist/__tests__/entry-formatter.test.d.ts.map +1 -0
  50. package/dist/__tests__/entry-formatter.test.js +182 -0
  51. package/dist/__tests__/entry-formatter.test.js.map +1 -0
  52. package/dist/__tests__/entry-preflight.test.d.ts +2 -0
  53. package/dist/__tests__/entry-preflight.test.d.ts.map +1 -0
  54. package/dist/__tests__/entry-preflight.test.js +58 -0
  55. package/dist/__tests__/entry-preflight.test.js.map +1 -0
  56. package/dist/__tests__/entryAccept-batch.test.d.ts +2 -0
  57. package/dist/__tests__/entryAccept-batch.test.d.ts.map +1 -0
  58. package/dist/__tests__/entryAccept-batch.test.js +305 -0
  59. package/dist/__tests__/entryAccept-batch.test.js.map +1 -0
  60. package/dist/__tests__/entryAccept.test.d.ts +2 -0
  61. package/dist/__tests__/entryAccept.test.d.ts.map +1 -0
  62. package/dist/__tests__/entryAccept.test.js +556 -0
  63. package/dist/__tests__/entryAccept.test.js.map +1 -0
  64. package/dist/__tests__/entryDiscardResolve.test.d.ts +2 -0
  65. package/dist/__tests__/entryDiscardResolve.test.d.ts.map +1 -0
  66. package/dist/__tests__/entryDiscardResolve.test.js +28 -0
  67. package/dist/__tests__/entryDiscardResolve.test.js.map +1 -0
  68. package/dist/__tests__/entryOwn.test.d.ts +2 -0
  69. package/dist/__tests__/entryOwn.test.d.ts.map +1 -0
  70. package/dist/__tests__/entryOwn.test.js +50 -0
  71. package/dist/__tests__/entryOwn.test.js.map +1 -0
  72. package/dist/__tests__/entryTick.test.d.ts +2 -0
  73. package/dist/__tests__/entryTick.test.d.ts.map +1 -0
  74. package/dist/__tests__/entryTick.test.js +40 -0
  75. package/dist/__tests__/entryTick.test.js.map +1 -0
  76. package/dist/__tests__/envelope-contract.test.js +2 -0
  77. package/dist/__tests__/envelope-contract.test.js.map +1 -1
  78. package/dist/__tests__/errors.test.js +41 -0
  79. package/dist/__tests__/errors.test.js.map +1 -1
  80. package/dist/__tests__/fields.test.js +14 -3
  81. package/dist/__tests__/fields.test.js.map +1 -1
  82. package/dist/__tests__/gateway-dry-run-timeout.test.d.ts +2 -0
  83. package/dist/__tests__/gateway-dry-run-timeout.test.d.ts.map +1 -0
  84. package/dist/__tests__/gateway-dry-run-timeout.test.js +70 -0
  85. package/dist/__tests__/gateway-dry-run-timeout.test.js.map +1 -0
  86. package/dist/__tests__/gateway-timeout-body-phase.test.d.ts +2 -0
  87. package/dist/__tests__/gateway-timeout-body-phase.test.d.ts.map +1 -0
  88. package/dist/__tests__/gateway-timeout-body-phase.test.js +116 -0
  89. package/dist/__tests__/gateway-timeout-body-phase.test.js.map +1 -0
  90. package/dist/__tests__/glossary.test.js +10 -27
  91. package/dist/__tests__/glossary.test.js.map +1 -1
  92. package/dist/__tests__/handshake-augment.test.d.ts +2 -0
  93. package/dist/__tests__/handshake-augment.test.d.ts.map +1 -0
  94. package/dist/__tests__/handshake-augment.test.js +407 -0
  95. package/dist/__tests__/handshake-augment.test.js.map +1 -0
  96. package/dist/__tests__/handshake-dormancy.test.d.ts +2 -0
  97. package/dist/__tests__/handshake-dormancy.test.d.ts.map +1 -0
  98. package/dist/__tests__/handshake-dormancy.test.js +24 -0
  99. package/dist/__tests__/handshake-dormancy.test.js.map +1 -0
  100. package/dist/__tests__/handshake-formatter.test.d.ts +2 -0
  101. package/dist/__tests__/handshake-formatter.test.d.ts.map +1 -0
  102. package/dist/__tests__/handshake-formatter.test.js +111 -0
  103. package/dist/__tests__/handshake-formatter.test.js.map +1 -0
  104. package/dist/__tests__/handshake-preview.test.js +308 -587
  105. package/dist/__tests__/handshake-preview.test.js.map +1 -1
  106. package/dist/__tests__/handshake-session-threading.test.d.ts +2 -0
  107. package/dist/__tests__/handshake-session-threading.test.d.ts.map +1 -0
  108. package/dist/__tests__/handshake-session-threading.test.js +185 -0
  109. package/dist/__tests__/handshake-session-threading.test.js.map +1 -0
  110. package/dist/__tests__/handshake.e2e.test.js +4 -35
  111. package/dist/__tests__/handshake.e2e.test.js.map +1 -1
  112. package/dist/__tests__/handshake.test.js +552 -317
  113. package/dist/__tests__/handshake.test.js.map +1 -1
  114. package/dist/__tests__/health-gap-kinds-drift.test.d.ts +2 -0
  115. package/dist/__tests__/health-gap-kinds-drift.test.d.ts.map +1 -0
  116. package/dist/__tests__/health-gap-kinds-drift.test.js +43 -0
  117. package/dist/__tests__/health-gap-kinds-drift.test.js.map +1 -0
  118. package/dist/__tests__/hook-intents.test.js +31 -43
  119. package/dist/__tests__/hook-intents.test.js.map +1 -1
  120. package/dist/__tests__/init.test.js +51 -14
  121. package/dist/__tests__/init.test.js.map +1 -1
  122. package/dist/__tests__/kernel-value-sets-drift.test.d.ts +2 -0
  123. package/dist/__tests__/kernel-value-sets-drift.test.d.ts.map +1 -0
  124. package/dist/__tests__/kernel-value-sets-drift.test.js +46 -0
  125. package/dist/__tests__/kernel-value-sets-drift.test.js.map +1 -0
  126. package/dist/__tests__/kernel-value-sets-generator.test.d.ts +2 -0
  127. package/dist/__tests__/kernel-value-sets-generator.test.d.ts.map +1 -0
  128. package/dist/__tests__/kernel-value-sets-generator.test.js +108 -0
  129. package/dist/__tests__/kernel-value-sets-generator.test.js.map +1 -0
  130. package/dist/__tests__/login.test.js +18 -1
  131. package/dist/__tests__/login.test.js.map +1 -1
  132. package/dist/__tests__/method-registry.integration.test.js +2 -3
  133. package/dist/__tests__/method-registry.integration.test.js.map +1 -1
  134. package/dist/__tests__/method-registry.test.d.ts +6 -8
  135. package/dist/__tests__/method-registry.test.d.ts.map +1 -1
  136. package/dist/__tests__/method-registry.test.js +22 -70
  137. package/dist/__tests__/method-registry.test.js.map +1 -1
  138. package/dist/__tests__/missingPin.test.d.ts +11 -0
  139. package/dist/__tests__/missingPin.test.d.ts.map +1 -0
  140. package/dist/__tests__/missingPin.test.js +232 -0
  141. package/dist/__tests__/missingPin.test.js.map +1 -0
  142. package/dist/__tests__/notice-marker.test.d.ts +2 -0
  143. package/dist/__tests__/notice-marker.test.d.ts.map +1 -0
  144. package/dist/__tests__/notice-marker.test.js +176 -0
  145. package/dist/__tests__/notice-marker.test.js.map +1 -0
  146. package/dist/__tests__/orient.test.js +416 -36
  147. package/dist/__tests__/orient.test.js.map +1 -1
  148. package/dist/__tests__/perimeter.test.js +23 -1
  149. package/dist/__tests__/perimeter.test.js.map +1 -1
  150. package/dist/__tests__/preview-key-refresh.test.d.ts +2 -0
  151. package/dist/__tests__/preview-key-refresh.test.d.ts.map +1 -0
  152. package/dist/__tests__/preview-key-refresh.test.js +186 -0
  153. package/dist/__tests__/preview-key-refresh.test.js.map +1 -0
  154. package/dist/__tests__/profiles.test.js +597 -3
  155. package/dist/__tests__/profiles.test.js.map +1 -1
  156. package/dist/__tests__/prompts.test.js +18 -1
  157. package/dist/__tests__/prompts.test.js.map +1 -1
  158. package/dist/__tests__/proof-run.test.d.ts +2 -0
  159. package/dist/__tests__/proof-run.test.d.ts.map +1 -0
  160. package/dist/__tests__/proof-run.test.js +255 -0
  161. package/dist/__tests__/proof-run.test.js.map +1 -0
  162. package/dist/__tests__/rate-limit-resilience.test.d.ts +8 -0
  163. package/dist/__tests__/rate-limit-resilience.test.d.ts.map +1 -0
  164. package/dist/__tests__/rate-limit-resilience.test.js +191 -0
  165. package/dist/__tests__/rate-limit-resilience.test.js.map +1 -0
  166. package/dist/__tests__/read-target-notice.test.d.ts +2 -0
  167. package/dist/__tests__/read-target-notice.test.d.ts.map +1 -0
  168. package/dist/__tests__/read-target-notice.test.js +125 -0
  169. package/dist/__tests__/read-target-notice.test.js.map +1 -0
  170. package/dist/__tests__/relate.test.js +246 -14
  171. package/dist/__tests__/relate.test.js.map +1 -1
  172. package/dist/__tests__/removed-commands.test.d.ts +2 -0
  173. package/dist/__tests__/removed-commands.test.d.ts.map +1 -0
  174. package/dist/__tests__/removed-commands.test.js +70 -0
  175. package/dist/__tests__/removed-commands.test.js.map +1 -0
  176. package/dist/__tests__/reply-commands-registered.test.d.ts +2 -0
  177. package/dist/__tests__/reply-commands-registered.test.d.ts.map +1 -0
  178. package/dist/__tests__/reply-commands-registered.test.js +81 -0
  179. package/dist/__tests__/reply-commands-registered.test.js.map +1 -0
  180. package/dist/__tests__/repo-detect.test.js +18 -38
  181. package/dist/__tests__/repo-detect.test.js.map +1 -1
  182. package/dist/__tests__/reportedProfile.test.d.ts +2 -0
  183. package/dist/__tests__/reportedProfile.test.d.ts.map +1 -0
  184. package/dist/__tests__/reportedProfile.test.js +328 -0
  185. package/dist/__tests__/reportedProfile.test.js.map +1 -0
  186. package/dist/__tests__/restore.test.d.ts +2 -0
  187. package/dist/__tests__/restore.test.d.ts.map +1 -0
  188. package/dist/__tests__/restore.test.js +85 -0
  189. package/dist/__tests__/restore.test.js.map +1 -0
  190. package/dist/__tests__/route-latency-budget.test.d.ts +2 -0
  191. package/dist/__tests__/route-latency-budget.test.d.ts.map +1 -0
  192. package/dist/__tests__/route-latency-budget.test.js +107 -0
  193. package/dist/__tests__/route-latency-budget.test.js.map +1 -0
  194. package/dist/__tests__/runner.test.js +59 -44
  195. package/dist/__tests__/runner.test.js.map +1 -1
  196. package/dist/__tests__/session-binding-refusal-tenant.test.d.ts +2 -0
  197. package/dist/__tests__/session-binding-refusal-tenant.test.d.ts.map +1 -0
  198. package/dist/__tests__/session-binding-refusal-tenant.test.js +112 -0
  199. package/dist/__tests__/session-binding-refusal-tenant.test.js.map +1 -0
  200. package/dist/__tests__/session-close-conversation.test.d.ts +2 -0
  201. package/dist/__tests__/session-close-conversation.test.d.ts.map +1 -0
  202. package/dist/__tests__/session-close-conversation.test.js +75 -0
  203. package/dist/__tests__/session-close-conversation.test.js.map +1 -0
  204. package/dist/__tests__/session-close-loop.test.d.ts +2 -0
  205. package/dist/__tests__/session-close-loop.test.d.ts.map +1 -0
  206. package/dist/__tests__/session-close-loop.test.js +227 -0
  207. package/dist/__tests__/session-close-loop.test.js.map +1 -0
  208. package/dist/__tests__/session-label.test.d.ts +2 -0
  209. package/dist/__tests__/session-label.test.d.ts.map +1 -0
  210. package/dist/__tests__/session-label.test.js +46 -0
  211. package/dist/__tests__/session-label.test.js.map +1 -0
  212. package/dist/__tests__/session-list-show.test.d.ts +2 -0
  213. package/dist/__tests__/session-list-show.test.d.ts.map +1 -0
  214. package/dist/__tests__/session-list-show.test.js +173 -0
  215. package/dist/__tests__/session-list-show.test.js.map +1 -0
  216. package/dist/__tests__/session-pinned-role.test.d.ts +2 -0
  217. package/dist/__tests__/session-pinned-role.test.d.ts.map +1 -0
  218. package/dist/__tests__/session-pinned-role.test.js +305 -0
  219. package/dist/__tests__/session-pinned-role.test.js.map +1 -0
  220. package/dist/__tests__/session-reset.test.d.ts +2 -0
  221. package/dist/__tests__/session-reset.test.d.ts.map +1 -0
  222. package/dist/__tests__/session-reset.test.js +138 -0
  223. package/dist/__tests__/session-reset.test.js.map +1 -0
  224. package/dist/__tests__/session-resume-backstop.test.d.ts +2 -0
  225. package/dist/__tests__/session-resume-backstop.test.d.ts.map +1 -0
  226. package/dist/__tests__/session-resume-backstop.test.js +139 -0
  227. package/dist/__tests__/session-resume-backstop.test.js.map +1 -0
  228. package/dist/__tests__/session-role-name-sanitize.test.d.ts +2 -0
  229. package/dist/__tests__/session-role-name-sanitize.test.d.ts.map +1 -0
  230. package/dist/__tests__/session-role-name-sanitize.test.js +122 -0
  231. package/dist/__tests__/session-role-name-sanitize.test.js.map +1 -0
  232. package/dist/__tests__/session-start-key-refresh.test.d.ts +2 -0
  233. package/dist/__tests__/session-start-key-refresh.test.d.ts.map +1 -0
  234. package/dist/__tests__/session-start-key-refresh.test.js +197 -0
  235. package/dist/__tests__/session-start-key-refresh.test.js.map +1 -0
  236. package/dist/__tests__/session-state-machine.test.js +235 -10
  237. package/dist/__tests__/session-state-machine.test.js.map +1 -1
  238. package/dist/__tests__/session-switch.test.d.ts +2 -0
  239. package/dist/__tests__/session-switch.test.d.ts.map +1 -0
  240. package/dist/__tests__/session-switch.test.js +343 -0
  241. package/dist/__tests__/session-switch.test.js.map +1 -0
  242. package/dist/__tests__/session-touch.test.js +48 -107
  243. package/dist/__tests__/session-touch.test.js.map +1 -1
  244. package/dist/__tests__/sessionBinding.test.d.ts +2 -0
  245. package/dist/__tests__/sessionBinding.test.d.ts.map +1 -0
  246. package/dist/__tests__/sessionBinding.test.js +118 -0
  247. package/dist/__tests__/sessionBinding.test.js.map +1 -0
  248. package/dist/__tests__/sessionByIdLookup.test.d.ts +2 -0
  249. package/dist/__tests__/sessionByIdLookup.test.d.ts.map +1 -0
  250. package/dist/__tests__/sessionByIdLookup.test.js +63 -0
  251. package/dist/__tests__/sessionByIdLookup.test.js.map +1 -0
  252. package/dist/__tests__/skill-vocabulary.test.d.ts +1 -1
  253. package/dist/__tests__/skill-vocabulary.test.js +7 -2
  254. package/dist/__tests__/skill-vocabulary.test.js.map +1 -1
  255. package/dist/__tests__/state.test.js +21 -1
  256. package/dist/__tests__/state.test.js.map +1 -1
  257. package/dist/__tests__/stillTrue.test.d.ts +2 -0
  258. package/dist/__tests__/stillTrue.test.d.ts.map +1 -0
  259. package/dist/__tests__/stillTrue.test.js +52 -0
  260. package/dist/__tests__/stillTrue.test.js.map +1 -0
  261. package/dist/__tests__/strip.test.js +57 -3
  262. package/dist/__tests__/strip.test.js.map +1 -1
  263. package/dist/__tests__/surfaces.test.js +3 -4
  264. package/dist/__tests__/surfaces.test.js.map +1 -1
  265. package/dist/__tests__/tenant-notice-write-path.test.d.ts +2 -0
  266. package/dist/__tests__/tenant-notice-write-path.test.d.ts.map +1 -0
  267. package/dist/__tests__/tenant-notice-write-path.test.js +183 -0
  268. package/dist/__tests__/tenant-notice-write-path.test.js.map +1 -0
  269. package/dist/__tests__/update-check.test.js +180 -1
  270. package/dist/__tests__/update-check.test.js.map +1 -1
  271. package/dist/__tests__/update.test.js +458 -8
  272. package/dist/__tests__/update.test.js.map +1 -1
  273. package/dist/__tests__/upgrade-runner.test.js +12 -0
  274. package/dist/__tests__/upgrade-runner.test.js.map +1 -1
  275. package/dist/__tests__/upgrade.test.d.ts +2 -0
  276. package/dist/__tests__/upgrade.test.d.ts.map +1 -0
  277. package/dist/__tests__/upgrade.test.js +56 -0
  278. package/dist/__tests__/upgrade.test.js.map +1 -0
  279. package/dist/__tests__/verify-formatter.test.d.ts +2 -0
  280. package/dist/__tests__/verify-formatter.test.d.ts.map +1 -0
  281. package/dist/__tests__/verify-formatter.test.js +85 -0
  282. package/dist/__tests__/verify-formatter.test.js.map +1 -0
  283. package/dist/__tests__/vocabulary-leak.test.d.ts +21 -13
  284. package/dist/__tests__/vocabulary-leak.test.d.ts.map +1 -1
  285. package/dist/__tests__/vocabulary-leak.test.js +72 -24
  286. package/dist/__tests__/vocabulary-leak.test.js.map +1 -1
  287. package/dist/__tests__/workspace.test.js +11 -72
  288. package/dist/__tests__/workspace.test.js.map +1 -1
  289. package/dist/__tests__/workspaceNotice.test.d.ts +2 -0
  290. package/dist/__tests__/workspaceNotice.test.d.ts.map +1 -0
  291. package/dist/__tests__/workspaceNotice.test.js +559 -0
  292. package/dist/__tests__/workspaceNotice.test.js.map +1 -0
  293. package/dist/commands/__tests__/quality.test.d.ts +2 -0
  294. package/dist/commands/__tests__/quality.test.d.ts.map +1 -0
  295. package/dist/commands/__tests__/quality.test.js +192 -0
  296. package/dist/commands/__tests__/quality.test.js.map +1 -0
  297. package/dist/commands/__tests__/rework.test.d.ts +2 -0
  298. package/dist/commands/__tests__/rework.test.d.ts.map +1 -0
  299. package/dist/commands/__tests__/rework.test.js +149 -0
  300. package/dist/commands/__tests__/rework.test.js.map +1 -0
  301. package/dist/commands/__tests__/tensionsList.test.d.ts +2 -0
  302. package/dist/commands/__tests__/tensionsList.test.d.ts.map +1 -0
  303. package/dist/commands/__tests__/tensionsList.test.js +63 -0
  304. package/dist/commands/__tests__/tensionsList.test.js.map +1 -0
  305. package/dist/commands/accept-policy.d.ts +10 -0
  306. package/dist/commands/accept-policy.d.ts.map +1 -0
  307. package/dist/commands/accept-policy.js +107 -0
  308. package/dist/commands/accept-policy.js.map +1 -0
  309. package/dist/commands/admin/cockpit.d.ts +2 -13
  310. package/dist/commands/admin/cockpit.d.ts.map +1 -1
  311. package/dist/commands/admin/cockpit.js +5 -5
  312. package/dist/commands/admin/cockpit.js.map +1 -1
  313. package/dist/commands/admin/index.d.ts +49 -0
  314. package/dist/commands/admin/index.d.ts.map +1 -1
  315. package/dist/commands/admin/index.js +148 -29
  316. package/dist/commands/admin/index.js.map +1 -1
  317. package/dist/commands/admin/index.test.d.ts +2 -0
  318. package/dist/commands/admin/index.test.d.ts.map +1 -0
  319. package/dist/commands/admin/index.test.js +94 -0
  320. package/dist/commands/admin/index.test.js.map +1 -0
  321. package/dist/commands/admin/inspect.d.ts.map +1 -1
  322. package/dist/commands/admin/inspect.js +2 -7
  323. package/dist/commands/admin/inspect.js.map +1 -1
  324. package/dist/commands/admin/probe.d.ts +75 -0
  325. package/dist/commands/admin/probe.d.ts.map +1 -0
  326. package/dist/commands/admin/probe.js +224 -0
  327. package/dist/commands/admin/probe.js.map +1 -0
  328. package/dist/commands/admin/probe.test.d.ts +2 -0
  329. package/dist/commands/admin/probe.test.d.ts.map +1 -0
  330. package/dist/commands/admin/probe.test.js +193 -0
  331. package/dist/commands/admin/probe.test.js.map +1 -0
  332. package/dist/commands/admin/run.d.ts +43 -0
  333. package/dist/commands/admin/run.d.ts.map +1 -0
  334. package/dist/commands/admin/run.js +78 -0
  335. package/dist/commands/admin/run.js.map +1 -0
  336. package/dist/commands/admin/run.test.d.ts +18 -0
  337. package/dist/commands/admin/run.test.d.ts.map +1 -0
  338. package/dist/commands/admin/run.test.js +168 -0
  339. package/dist/commands/admin/run.test.js.map +1 -0
  340. package/dist/commands/admin/seed.d.ts +6 -21
  341. package/dist/commands/admin/seed.d.ts.map +1 -1
  342. package/dist/commands/admin/seed.js +41 -310
  343. package/dist/commands/admin/seed.js.map +1 -1
  344. package/dist/commands/admin/seed.test.d.ts +3 -4
  345. package/dist/commands/admin/seed.test.d.ts.map +1 -1
  346. package/dist/commands/admin/seed.test.js +26 -76
  347. package/dist/commands/admin/seed.test.js.map +1 -1
  348. package/dist/commands/admin/seedRegistryEntries.generated.d.ts.map +1 -1
  349. package/dist/commands/admin/seedRegistryEntries.generated.js +3 -84
  350. package/dist/commands/admin/seedRegistryEntries.generated.js.map +1 -1
  351. package/dist/commands/admin/seedRegistryEntries.test.d.ts +5 -3
  352. package/dist/commands/admin/seedRegistryEntries.test.d.ts.map +1 -1
  353. package/dist/commands/admin/seedRegistryEntries.test.js +60 -26
  354. package/dist/commands/admin/seedRegistryEntries.test.js.map +1 -1
  355. package/dist/commands/admin/seedRowType.d.ts +22 -0
  356. package/dist/commands/admin/seedRowType.d.ts.map +1 -0
  357. package/dist/commands/admin/seedRowType.js +2 -0
  358. package/dist/commands/admin/seedRowType.js.map +1 -0
  359. package/dist/commands/admin/seedStatusColor.d.ts +9 -0
  360. package/dist/commands/admin/seedStatusColor.d.ts.map +1 -0
  361. package/dist/commands/admin/seedStatusColor.js +19 -0
  362. package/dist/commands/admin/seedStatusColor.js.map +1 -0
  363. package/dist/commands/admin/seedStatusColor.test.d.ts +2 -0
  364. package/dist/commands/admin/seedStatusColor.test.d.ts.map +1 -0
  365. package/dist/commands/admin/seedStatusColor.test.js +31 -0
  366. package/dist/commands/admin/seedStatusColor.test.js.map +1 -0
  367. package/dist/commands/brief.d.ts.map +1 -1
  368. package/dist/commands/brief.js +24 -2
  369. package/dist/commands/brief.js.map +1 -1
  370. package/dist/commands/capture.d.ts +17 -14
  371. package/dist/commands/capture.d.ts.map +1 -1
  372. package/dist/commands/capture.js +129 -288
  373. package/dist/commands/capture.js.map +1 -1
  374. package/dist/commands/chain-walk.d.ts.map +1 -1
  375. package/dist/commands/chain-walk.js.map +1 -1
  376. package/dist/commands/changes.d.ts.map +1 -1
  377. package/dist/commands/changes.js.map +1 -1
  378. package/dist/commands/codex-prep.d.ts +11 -1
  379. package/dist/commands/codex-prep.d.ts.map +1 -1
  380. package/dist/commands/codex-prep.js +14 -83
  381. package/dist/commands/codex-prep.js.map +1 -1
  382. package/dist/commands/collections.d.ts +1 -1
  383. package/dist/commands/collections.d.ts.map +1 -1
  384. package/dist/commands/collections.js +1 -1
  385. package/dist/commands/collections.js.map +1 -1
  386. package/dist/commands/conflicts.d.ts +35 -0
  387. package/dist/commands/conflicts.d.ts.map +1 -0
  388. package/dist/commands/conflicts.js +194 -0
  389. package/dist/commands/conflicts.js.map +1 -0
  390. package/dist/commands/conflicts.test.d.ts +2 -0
  391. package/dist/commands/conflicts.test.d.ts.map +1 -0
  392. package/dist/commands/conflicts.test.js +179 -0
  393. package/dist/commands/conflicts.test.js.map +1 -0
  394. package/dist/commands/connect-config.test.d.ts +2 -0
  395. package/dist/commands/connect-config.test.d.ts.map +1 -0
  396. package/dist/commands/connect-config.test.js +52 -0
  397. package/dist/commands/connect-config.test.js.map +1 -0
  398. package/dist/commands/connect-context.d.ts +55 -0
  399. package/dist/commands/connect-context.d.ts.map +1 -0
  400. package/dist/commands/connect-context.js +78 -0
  401. package/dist/commands/connect-context.js.map +1 -0
  402. package/dist/commands/connect-context.test.d.ts +2 -0
  403. package/dist/commands/connect-context.test.d.ts.map +1 -0
  404. package/dist/commands/connect-context.test.js +148 -0
  405. package/dist/commands/connect-context.test.js.map +1 -0
  406. package/dist/commands/connect-decline.test.d.ts +2 -0
  407. package/dist/commands/connect-decline.test.d.ts.map +1 -0
  408. package/dist/commands/connect-decline.test.js +70 -0
  409. package/dist/commands/connect-decline.test.js.map +1 -0
  410. package/dist/commands/connect-integration.test.js +24 -7
  411. package/dist/commands/connect-integration.test.js.map +1 -1
  412. package/dist/commands/connect-legacy-migration.test.d.ts +2 -0
  413. package/dist/commands/connect-legacy-migration.test.d.ts.map +1 -0
  414. package/dist/commands/connect-legacy-migration.test.js +109 -0
  415. package/dist/commands/connect-legacy-migration.test.js.map +1 -0
  416. package/dist/commands/connect-redeem-failure.test.d.ts +2 -0
  417. package/dist/commands/connect-redeem-failure.test.d.ts.map +1 -0
  418. package/dist/commands/connect-redeem-failure.test.js +134 -0
  419. package/dist/commands/connect-redeem-failure.test.js.map +1 -0
  420. package/dist/commands/connect-screens.d.ts +16 -6
  421. package/dist/commands/connect-screens.d.ts.map +1 -1
  422. package/dist/commands/connect-screens.js +81 -35
  423. package/dist/commands/connect-screens.js.map +1 -1
  424. package/dist/commands/connect-seal.test.d.ts +2 -0
  425. package/dist/commands/connect-seal.test.d.ts.map +1 -0
  426. package/dist/commands/connect-seal.test.js +55 -0
  427. package/dist/commands/connect-seal.test.js.map +1 -0
  428. package/dist/commands/connect.d.ts +19 -0
  429. package/dist/commands/connect.d.ts.map +1 -1
  430. package/dist/commands/connect.js +239 -71
  431. package/dist/commands/connect.js.map +1 -1
  432. package/dist/commands/connect.test.js +226 -23
  433. package/dist/commands/connect.test.js.map +1 -1
  434. package/dist/commands/constellation.d.ts.map +1 -1
  435. package/dist/commands/constellation.js.map +1 -1
  436. package/dist/commands/context.d.ts.map +1 -1
  437. package/dist/commands/context.js.map +1 -1
  438. package/dist/commands/cross-cut.d.ts.map +1 -1
  439. package/dist/commands/cross-cut.js.map +1 -1
  440. package/dist/commands/digest.d.ts +17 -0
  441. package/dist/commands/digest.d.ts.map +1 -0
  442. package/dist/commands/digest.js +58 -0
  443. package/dist/commands/digest.js.map +1 -0
  444. package/dist/commands/digest.test.d.ts +2 -0
  445. package/dist/commands/digest.test.d.ts.map +1 -0
  446. package/dist/commands/digest.test.js +36 -0
  447. package/dist/commands/digest.test.js.map +1 -0
  448. package/dist/commands/direction.d.ts +10 -0
  449. package/dist/commands/direction.d.ts.map +1 -0
  450. package/dist/commands/direction.js +79 -0
  451. package/dist/commands/direction.js.map +1 -0
  452. package/dist/commands/doctor.d.ts.map +1 -1
  453. package/dist/commands/doctor.js +107 -37
  454. package/dist/commands/doctor.js.map +1 -1
  455. package/dist/commands/doctor.test.js +221 -6
  456. package/dist/commands/doctor.test.js.map +1 -1
  457. package/dist/commands/entryAccept.d.ts +26 -0
  458. package/dist/commands/entryAccept.d.ts.map +1 -0
  459. package/dist/commands/entryAccept.js +308 -0
  460. package/dist/commands/entryAccept.js.map +1 -0
  461. package/dist/commands/entryDiscardResolve.d.ts +9 -0
  462. package/dist/commands/entryDiscardResolve.d.ts.map +1 -0
  463. package/dist/commands/entryDiscardResolve.js +27 -0
  464. package/dist/commands/entryDiscardResolve.js.map +1 -0
  465. package/dist/commands/entryOwn.d.ts +5 -0
  466. package/dist/commands/entryOwn.d.ts.map +1 -0
  467. package/dist/commands/entryOwn.js +17 -0
  468. package/dist/commands/entryOwn.js.map +1 -0
  469. package/dist/commands/entryPreflight.d.ts +8 -0
  470. package/dist/commands/entryPreflight.d.ts.map +1 -0
  471. package/dist/commands/entryPreflight.js +48 -0
  472. package/dist/commands/entryPreflight.js.map +1 -0
  473. package/dist/commands/entryTick.d.ts +8 -0
  474. package/dist/commands/entryTick.d.ts.map +1 -0
  475. package/dist/commands/entryTick.js +43 -0
  476. package/dist/commands/entryTick.js.map +1 -0
  477. package/dist/commands/feedback.d.ts +39 -0
  478. package/dist/commands/feedback.d.ts.map +1 -0
  479. package/dist/commands/feedback.js +176 -0
  480. package/dist/commands/feedback.js.map +1 -0
  481. package/dist/commands/feedback.test.d.ts +2 -0
  482. package/dist/commands/feedback.test.d.ts.map +1 -0
  483. package/dist/commands/feedback.test.js +117 -0
  484. package/dist/commands/feedback.test.js.map +1 -0
  485. package/dist/commands/fields.d.ts.map +1 -1
  486. package/dist/commands/fields.js +1 -1
  487. package/dist/commands/fields.js.map +1 -1
  488. package/dist/commands/files.d.ts +26 -0
  489. package/dist/commands/files.d.ts.map +1 -0
  490. package/dist/commands/files.js +160 -0
  491. package/dist/commands/files.js.map +1 -0
  492. package/dist/commands/files.test.d.ts +2 -0
  493. package/dist/commands/files.test.d.ts.map +1 -0
  494. package/dist/commands/files.test.js +278 -0
  495. package/dist/commands/files.test.js.map +1 -0
  496. package/dist/commands/handshake.d.ts +47 -136
  497. package/dist/commands/handshake.d.ts.map +1 -1
  498. package/dist/commands/handshake.js +576 -1343
  499. package/dist/commands/handshake.js.map +1 -1
  500. package/dist/commands/handshakeCursorSkillCleanup.d.ts +36 -0
  501. package/dist/commands/handshakeCursorSkillCleanup.d.ts.map +1 -0
  502. package/dist/commands/handshakeCursorSkillCleanup.js +110 -0
  503. package/dist/commands/handshakeCursorSkillCleanup.js.map +1 -0
  504. package/dist/commands/handshakeDriftClassification.d.ts +33 -0
  505. package/dist/commands/handshakeDriftClassification.d.ts.map +1 -0
  506. package/dist/commands/handshakeDriftClassification.js +62 -0
  507. package/dist/commands/handshakeDriftClassification.js.map +1 -0
  508. package/dist/commands/history.d.ts +30 -0
  509. package/dist/commands/history.d.ts.map +1 -0
  510. package/dist/commands/history.js +62 -0
  511. package/dist/commands/history.js.map +1 -0
  512. package/dist/commands/history.test.d.ts +2 -0
  513. package/dist/commands/history.test.d.ts.map +1 -0
  514. package/dist/commands/history.test.js +106 -0
  515. package/dist/commands/history.test.js.map +1 -0
  516. package/dist/commands/init.d.ts +1 -1
  517. package/dist/commands/init.d.ts.map +1 -1
  518. package/dist/commands/init.js +22 -13
  519. package/dist/commands/init.js.map +1 -1
  520. package/dist/commands/login.d.ts.map +1 -1
  521. package/dist/commands/login.js +15 -11
  522. package/dist/commands/login.js.map +1 -1
  523. package/dist/commands/organisation.d.ts +12 -0
  524. package/dist/commands/organisation.d.ts.map +1 -0
  525. package/dist/commands/organisation.js +147 -0
  526. package/dist/commands/organisation.js.map +1 -0
  527. package/dist/commands/organisation.test.d.ts +2 -0
  528. package/dist/commands/organisation.test.d.ts.map +1 -0
  529. package/dist/commands/organisation.test.js +116 -0
  530. package/dist/commands/organisation.test.js.map +1 -0
  531. package/dist/commands/organisationHierarchy.d.ts +15 -0
  532. package/dist/commands/organisationHierarchy.d.ts.map +1 -0
  533. package/dist/commands/organisationHierarchy.js +114 -0
  534. package/dist/commands/organisationHierarchy.js.map +1 -0
  535. package/dist/commands/organisationHierarchy.test.d.ts +2 -0
  536. package/dist/commands/organisationHierarchy.test.d.ts.map +1 -0
  537. package/dist/commands/organisationHierarchy.test.js +144 -0
  538. package/dist/commands/organisationHierarchy.test.js.map +1 -0
  539. package/dist/commands/organisationWrite.d.ts +20 -0
  540. package/dist/commands/organisationWrite.d.ts.map +1 -0
  541. package/dist/commands/organisationWrite.js +41 -0
  542. package/dist/commands/organisationWrite.js.map +1 -0
  543. package/dist/commands/orient.d.ts +64 -67
  544. package/dist/commands/orient.d.ts.map +1 -1
  545. package/dist/commands/orient.js +148 -25
  546. package/dist/commands/orient.js.map +1 -1
  547. package/dist/commands/outcome.d.ts +90 -0
  548. package/dist/commands/outcome.d.ts.map +1 -0
  549. package/dist/commands/outcome.js +201 -0
  550. package/dist/commands/outcome.js.map +1 -0
  551. package/dist/commands/outcome.test.d.ts +2 -0
  552. package/dist/commands/outcome.test.d.ts.map +1 -0
  553. package/dist/commands/outcome.test.js +320 -0
  554. package/dist/commands/outcome.test.js.map +1 -0
  555. package/dist/commands/people.d.ts +6 -0
  556. package/dist/commands/people.d.ts.map +1 -0
  557. package/dist/commands/people.js +23 -0
  558. package/dist/commands/people.js.map +1 -0
  559. package/dist/commands/people.test.d.ts +2 -0
  560. package/dist/commands/people.test.d.ts.map +1 -0
  561. package/dist/commands/people.test.js +61 -0
  562. package/dist/commands/people.test.js.map +1 -0
  563. package/dist/commands/profile.d.ts +24 -16
  564. package/dist/commands/profile.d.ts.map +1 -1
  565. package/dist/commands/profile.js +272 -98
  566. package/dist/commands/profile.js.map +1 -1
  567. package/dist/commands/proof-run.d.ts +51 -0
  568. package/dist/commands/proof-run.d.ts.map +1 -0
  569. package/dist/commands/proof-run.js +209 -0
  570. package/dist/commands/proof-run.js.map +1 -0
  571. package/dist/commands/quality.d.ts +21 -0
  572. package/dist/commands/quality.d.ts.map +1 -0
  573. package/dist/commands/quality.js +52 -0
  574. package/dist/commands/quality.js.map +1 -0
  575. package/dist/commands/questions.d.ts +23 -0
  576. package/dist/commands/questions.d.ts.map +1 -0
  577. package/dist/commands/questions.js +238 -0
  578. package/dist/commands/questions.js.map +1 -0
  579. package/dist/commands/questions.test.d.ts +2 -0
  580. package/dist/commands/questions.test.d.ts.map +1 -0
  581. package/dist/commands/questions.test.js +159 -0
  582. package/dist/commands/questions.test.js.map +1 -0
  583. package/dist/commands/relate.d.ts +1 -0
  584. package/dist/commands/relate.d.ts.map +1 -1
  585. package/dist/commands/relate.js +89 -15
  586. package/dist/commands/relate.js.map +1 -1
  587. package/dist/commands/restore.d.ts +2 -0
  588. package/dist/commands/restore.d.ts.map +1 -0
  589. package/dist/commands/restore.js +83 -0
  590. package/dist/commands/restore.js.map +1 -0
  591. package/dist/commands/rework.d.ts +24 -0
  592. package/dist/commands/rework.d.ts.map +1 -0
  593. package/dist/commands/rework.js +97 -0
  594. package/dist/commands/rework.js.map +1 -0
  595. package/dist/commands/role.d.ts +88 -0
  596. package/dist/commands/role.d.ts.map +1 -0
  597. package/dist/commands/role.js +235 -0
  598. package/dist/commands/role.js.map +1 -0
  599. package/dist/commands/role.test.d.ts +2 -0
  600. package/dist/commands/role.test.d.ts.map +1 -0
  601. package/dist/commands/role.test.js +348 -0
  602. package/dist/commands/role.test.js.map +1 -0
  603. package/dist/commands/scoreboard.d.ts +26 -0
  604. package/dist/commands/scoreboard.d.ts.map +1 -0
  605. package/dist/commands/scoreboard.js +40 -0
  606. package/dist/commands/scoreboard.js.map +1 -0
  607. package/dist/commands/search.d.ts +2 -1
  608. package/dist/commands/search.d.ts.map +1 -1
  609. package/dist/commands/search.js +5 -4
  610. package/dist/commands/search.js.map +1 -1
  611. package/dist/commands/session.d.ts +62 -7
  612. package/dist/commands/session.d.ts.map +1 -1
  613. package/dist/commands/session.js +421 -83
  614. package/dist/commands/session.js.map +1 -1
  615. package/dist/commands/status.d.ts +7 -0
  616. package/dist/commands/status.d.ts.map +1 -0
  617. package/dist/commands/status.js +101 -0
  618. package/dist/commands/status.js.map +1 -0
  619. package/dist/commands/status.test.d.ts +2 -0
  620. package/dist/commands/status.test.d.ts.map +1 -0
  621. package/dist/commands/status.test.js +75 -0
  622. package/dist/commands/status.test.js.map +1 -0
  623. package/dist/commands/stillTrue.d.ts +14 -0
  624. package/dist/commands/stillTrue.d.ts.map +1 -0
  625. package/dist/commands/stillTrue.js +48 -0
  626. package/dist/commands/stillTrue.js.map +1 -0
  627. package/dist/commands/tensionsList.d.ts +5 -0
  628. package/dist/commands/tensionsList.d.ts.map +1 -0
  629. package/dist/commands/tensionsList.js +27 -0
  630. package/dist/commands/tensionsList.js.map +1 -0
  631. package/dist/commands/update.d.ts +21 -0
  632. package/dist/commands/update.d.ts.map +1 -1
  633. package/dist/commands/update.js +157 -42
  634. package/dist/commands/update.js.map +1 -1
  635. package/dist/commands/upgrade.d.ts.map +1 -1
  636. package/dist/commands/upgrade.js +31 -10
  637. package/dist/commands/upgrade.js.map +1 -1
  638. package/dist/commands/usage.d.ts.map +1 -1
  639. package/dist/commands/usage.js +0 -18
  640. package/dist/commands/usage.js.map +1 -1
  641. package/dist/commands/verify.d.ts.map +1 -1
  642. package/dist/commands/verify.js +7 -1
  643. package/dist/commands/verify.js.map +1 -1
  644. package/dist/commands/welcome.d.ts.map +1 -1
  645. package/dist/commands/welcome.js +5 -2
  646. package/dist/commands/welcome.js.map +1 -1
  647. package/dist/commands/whoami.d.ts +20 -0
  648. package/dist/commands/whoami.d.ts.map +1 -0
  649. package/dist/commands/whoami.js +126 -0
  650. package/dist/commands/whoami.js.map +1 -0
  651. package/dist/commands/whoami.test.d.ts +2 -0
  652. package/dist/commands/whoami.test.d.ts.map +1 -0
  653. package/dist/commands/whoami.test.js +130 -0
  654. package/dist/commands/whoami.test.js.map +1 -0
  655. package/dist/commands/workspace.d.ts +7 -74
  656. package/dist/commands/workspace.d.ts.map +1 -1
  657. package/dist/commands/workspace.js +9 -70
  658. package/dist/commands/workspace.js.map +1 -1
  659. package/dist/formatters/__tests__/orient-plannedWorkCut.test.d.ts +2 -0
  660. package/dist/formatters/__tests__/orient-plannedWorkCut.test.d.ts.map +1 -0
  661. package/dist/formatters/__tests__/orient-plannedWorkCut.test.js +49 -0
  662. package/dist/formatters/__tests__/orient-plannedWorkCut.test.js.map +1 -0
  663. package/dist/formatters/__tests__/orient-provenance.test.d.ts +6 -0
  664. package/dist/formatters/__tests__/orient-provenance.test.d.ts.map +1 -0
  665. package/dist/formatters/__tests__/orient-provenance.test.js +319 -0
  666. package/dist/formatters/__tests__/orient-provenance.test.js.map +1 -0
  667. package/dist/formatters/__tests__/orient-ruleLists.test.d.ts +2 -0
  668. package/dist/formatters/__tests__/orient-ruleLists.test.d.ts.map +1 -0
  669. package/dist/formatters/__tests__/orient-ruleLists.test.js +93 -0
  670. package/dist/formatters/__tests__/orient-ruleLists.test.js.map +1 -0
  671. package/dist/formatters/__tests__/session-list-show.test.d.ts +2 -0
  672. package/dist/formatters/__tests__/session-list-show.test.d.ts.map +1 -0
  673. package/dist/formatters/__tests__/session-list-show.test.js +195 -0
  674. package/dist/formatters/__tests__/session-list-show.test.js.map +1 -0
  675. package/dist/formatters/__tests__/session.test.d.ts +2 -0
  676. package/dist/formatters/__tests__/session.test.d.ts.map +1 -0
  677. package/dist/formatters/__tests__/session.test.js +199 -0
  678. package/dist/formatters/__tests__/session.test.js.map +1 -0
  679. package/dist/formatters/__tests__/tensionsList.test.d.ts +2 -0
  680. package/dist/formatters/__tests__/tensionsList.test.d.ts.map +1 -0
  681. package/dist/formatters/__tests__/tensionsList.test.js +30 -0
  682. package/dist/formatters/__tests__/tensionsList.test.js.map +1 -0
  683. package/dist/formatters/brief.d.ts +6 -15
  684. package/dist/formatters/brief.d.ts.map +1 -1
  685. package/dist/formatters/brief.js +16 -14
  686. package/dist/formatters/brief.js.map +1 -1
  687. package/dist/formatters/brief.test.d.ts +2 -0
  688. package/dist/formatters/brief.test.d.ts.map +1 -0
  689. package/dist/formatters/brief.test.js +21 -0
  690. package/dist/formatters/brief.test.js.map +1 -0
  691. package/dist/formatters/capture.d.ts +17 -10
  692. package/dist/formatters/capture.d.ts.map +1 -1
  693. package/dist/formatters/capture.js +33 -10
  694. package/dist/formatters/capture.js.map +1 -1
  695. package/dist/formatters/coaching.d.ts +60 -0
  696. package/dist/formatters/coaching.d.ts.map +1 -0
  697. package/dist/formatters/coaching.js +51 -0
  698. package/dist/formatters/coaching.js.map +1 -0
  699. package/dist/formatters/collections.d.ts +0 -1
  700. package/dist/formatters/collections.d.ts.map +1 -1
  701. package/dist/formatters/collections.js +14 -5
  702. package/dist/formatters/collections.js.map +1 -1
  703. package/dist/formatters/conflicts.d.ts +71 -0
  704. package/dist/formatters/conflicts.d.ts.map +1 -0
  705. package/dist/formatters/conflicts.js +105 -0
  706. package/dist/formatters/conflicts.js.map +1 -0
  707. package/dist/formatters/conflicts.test.d.ts +2 -0
  708. package/dist/formatters/conflicts.test.d.ts.map +1 -0
  709. package/dist/formatters/conflicts.test.js +166 -0
  710. package/dist/formatters/conflicts.test.js.map +1 -0
  711. package/dist/formatters/context.d.ts +1 -1
  712. package/dist/formatters/context.d.ts.map +1 -1
  713. package/dist/formatters/context.js.map +1 -1
  714. package/dist/formatters/digest.d.ts +13 -0
  715. package/dist/formatters/digest.d.ts.map +1 -0
  716. package/dist/formatters/digest.js +98 -0
  717. package/dist/formatters/digest.js.map +1 -0
  718. package/dist/formatters/digest.test.d.ts +2 -0
  719. package/dist/formatters/digest.test.d.ts.map +1 -0
  720. package/dist/formatters/digest.test.js +166 -0
  721. package/dist/formatters/digest.test.js.map +1 -0
  722. package/dist/formatters/direction.d.ts +48 -0
  723. package/dist/formatters/direction.d.ts.map +1 -0
  724. package/dist/formatters/direction.js +75 -0
  725. package/dist/formatters/direction.js.map +1 -0
  726. package/dist/formatters/direction.test.d.ts +2 -0
  727. package/dist/formatters/direction.test.d.ts.map +1 -0
  728. package/dist/formatters/direction.test.js +70 -0
  729. package/dist/formatters/direction.test.js.map +1 -0
  730. package/dist/formatters/entry.d.ts +68 -1
  731. package/dist/formatters/entry.d.ts.map +1 -1
  732. package/dist/formatters/entry.js +104 -11
  733. package/dist/formatters/entry.js.map +1 -1
  734. package/dist/formatters/entryAccept.d.ts +79 -0
  735. package/dist/formatters/entryAccept.d.ts.map +1 -0
  736. package/dist/formatters/entryAccept.js +78 -0
  737. package/dist/formatters/entryAccept.js.map +1 -0
  738. package/dist/formatters/feedback.d.ts +61 -0
  739. package/dist/formatters/feedback.d.ts.map +1 -0
  740. package/dist/formatters/feedback.js +95 -0
  741. package/dist/formatters/feedback.js.map +1 -0
  742. package/dist/formatters/feedback.test.d.ts +2 -0
  743. package/dist/formatters/feedback.test.d.ts.map +1 -0
  744. package/dist/formatters/feedback.test.js +142 -0
  745. package/dist/formatters/feedback.test.js.map +1 -0
  746. package/dist/formatters/fields.d.ts +7 -1
  747. package/dist/formatters/fields.d.ts.map +1 -1
  748. package/dist/formatters/fields.js +9 -3
  749. package/dist/formatters/fields.js.map +1 -1
  750. package/dist/formatters/fields.test.d.ts +2 -0
  751. package/dist/formatters/fields.test.d.ts.map +1 -0
  752. package/dist/formatters/fields.test.js +42 -0
  753. package/dist/formatters/fields.test.js.map +1 -0
  754. package/dist/formatters/handshake.d.ts +31 -9
  755. package/dist/formatters/handshake.d.ts.map +1 -1
  756. package/dist/formatters/handshake.js +60 -38
  757. package/dist/formatters/handshake.js.map +1 -1
  758. package/dist/formatters/orient.coherencyCheckTag.test.d.ts +2 -0
  759. package/dist/formatters/orient.coherencyCheckTag.test.d.ts.map +1 -0
  760. package/dist/formatters/orient.coherencyCheckTag.test.js +22 -0
  761. package/dist/formatters/orient.coherencyCheckTag.test.js.map +1 -0
  762. package/dist/formatters/orient.d.ts +114 -111
  763. package/dist/formatters/orient.d.ts.map +1 -1
  764. package/dist/formatters/orient.js +182 -151
  765. package/dist/formatters/orient.js.map +1 -1
  766. package/dist/formatters/orient.rcrtMiss.test.d.ts +2 -0
  767. package/dist/formatters/orient.rcrtMiss.test.d.ts.map +1 -0
  768. package/dist/formatters/orient.rcrtMiss.test.js +77 -0
  769. package/dist/formatters/orient.rcrtMiss.test.js.map +1 -0
  770. package/dist/formatters/orient.rituals.test.d.ts +2 -0
  771. package/dist/formatters/orient.rituals.test.d.ts.map +1 -0
  772. package/dist/formatters/orient.rituals.test.js +72 -0
  773. package/dist/formatters/orient.rituals.test.js.map +1 -0
  774. package/dist/formatters/orientDegradation.d.ts +38 -0
  775. package/dist/formatters/orientDegradation.d.ts.map +1 -0
  776. package/dist/formatters/orientDegradation.js +50 -0
  777. package/dist/formatters/orientDegradation.js.map +1 -0
  778. package/dist/formatters/orientDegradation.test.d.ts +2 -0
  779. package/dist/formatters/orientDegradation.test.d.ts.map +1 -0
  780. package/dist/formatters/orientDegradation.test.js +28 -0
  781. package/dist/formatters/orientDegradation.test.js.map +1 -0
  782. package/dist/formatters/orientDirection.d.ts +25 -0
  783. package/dist/formatters/orientDirection.d.ts.map +1 -0
  784. package/dist/formatters/orientDirection.js +7 -0
  785. package/dist/formatters/orientDirection.js.map +1 -0
  786. package/dist/formatters/orientDirection.test.d.ts +2 -0
  787. package/dist/formatters/orientDirection.test.d.ts.map +1 -0
  788. package/dist/formatters/orientDirection.test.js +48 -0
  789. package/dist/formatters/orientDirection.test.js.map +1 -0
  790. package/dist/formatters/orientRetrievalMiss.d.ts +22 -0
  791. package/dist/formatters/orientRetrievalMiss.d.ts.map +1 -0
  792. package/dist/formatters/orientRetrievalMiss.js +17 -0
  793. package/dist/formatters/orientRetrievalMiss.js.map +1 -0
  794. package/dist/formatters/plannedWorkCounts.d.ts +19 -0
  795. package/dist/formatters/plannedWorkCounts.d.ts.map +1 -0
  796. package/dist/formatters/plannedWorkCounts.js +17 -0
  797. package/dist/formatters/plannedWorkCounts.js.map +1 -0
  798. package/dist/formatters/qualityChecks.d.ts +8 -0
  799. package/dist/formatters/qualityChecks.d.ts.map +1 -0
  800. package/dist/formatters/qualityChecks.js +50 -0
  801. package/dist/formatters/qualityChecks.js.map +1 -0
  802. package/dist/formatters/questions.d.ts +72 -0
  803. package/dist/formatters/questions.d.ts.map +1 -0
  804. package/dist/formatters/questions.js +116 -0
  805. package/dist/formatters/questions.js.map +1 -0
  806. package/dist/formatters/questions.test.d.ts +2 -0
  807. package/dist/formatters/questions.test.d.ts.map +1 -0
  808. package/dist/formatters/questions.test.js +144 -0
  809. package/dist/formatters/questions.test.js.map +1 -0
  810. package/dist/formatters/relate.d.ts +13 -2
  811. package/dist/formatters/relate.d.ts.map +1 -1
  812. package/dist/formatters/relate.js +15 -5
  813. package/dist/formatters/relate.js.map +1 -1
  814. package/dist/formatters/relate.test.d.ts +2 -0
  815. package/dist/formatters/relate.test.d.ts.map +1 -0
  816. package/dist/formatters/relate.test.js +91 -0
  817. package/dist/formatters/relate.test.js.map +1 -0
  818. package/dist/formatters/scoreboard.d.ts +11 -0
  819. package/dist/formatters/scoreboard.d.ts.map +1 -0
  820. package/dist/formatters/scoreboard.js +162 -0
  821. package/dist/formatters/scoreboard.js.map +1 -0
  822. package/dist/formatters/scoreboard.test.d.ts +2 -0
  823. package/dist/formatters/scoreboard.test.d.ts.map +1 -0
  824. package/dist/formatters/scoreboard.test.js +301 -0
  825. package/dist/formatters/scoreboard.test.js.map +1 -0
  826. package/dist/formatters/search.d.ts +24 -0
  827. package/dist/formatters/search.d.ts.map +1 -1
  828. package/dist/formatters/search.js +26 -11
  829. package/dist/formatters/search.js.map +1 -1
  830. package/dist/formatters/search.test.d.ts +2 -0
  831. package/dist/formatters/search.test.d.ts.map +1 -0
  832. package/dist/formatters/search.test.js +86 -0
  833. package/dist/formatters/search.test.js.map +1 -0
  834. package/dist/formatters/session-feedback.test.d.ts +2 -0
  835. package/dist/formatters/session-feedback.test.d.ts.map +1 -0
  836. package/dist/formatters/session-feedback.test.js +118 -0
  837. package/dist/formatters/session-feedback.test.js.map +1 -0
  838. package/dist/formatters/session.d.ts +117 -5
  839. package/dist/formatters/session.d.ts.map +1 -1
  840. package/dist/formatters/session.js +317 -21
  841. package/dist/formatters/session.js.map +1 -1
  842. package/dist/formatters/spineCheck.d.ts +14 -0
  843. package/dist/formatters/spineCheck.d.ts.map +1 -0
  844. package/dist/formatters/spineCheck.js +113 -0
  845. package/dist/formatters/spineCheck.js.map +1 -0
  846. package/dist/formatters/spineCheck.test.d.ts +2 -0
  847. package/dist/formatters/spineCheck.test.d.ts.map +1 -0
  848. package/dist/formatters/spineCheck.test.js +76 -0
  849. package/dist/formatters/spineCheck.test.js.map +1 -0
  850. package/dist/formatters/tensionsList.d.ts +17 -0
  851. package/dist/formatters/tensionsList.d.ts.map +1 -0
  852. package/dist/formatters/tensionsList.js +33 -0
  853. package/dist/formatters/tensionsList.js.map +1 -0
  854. package/dist/formatters/update.d.ts +22 -0
  855. package/dist/formatters/update.d.ts.map +1 -1
  856. package/dist/formatters/update.js +36 -7
  857. package/dist/formatters/update.js.map +1 -1
  858. package/dist/formatters/update.test.d.ts +2 -0
  859. package/dist/formatters/update.test.d.ts.map +1 -0
  860. package/dist/formatters/update.test.js +59 -0
  861. package/dist/formatters/update.test.js.map +1 -0
  862. package/dist/formatters/verify.d.ts +12 -4
  863. package/dist/formatters/verify.d.ts.map +1 -1
  864. package/dist/formatters/verify.js +20 -2
  865. package/dist/formatters/verify.js.map +1 -1
  866. package/dist/generated/healthGapKinds.generated.d.ts +12 -0
  867. package/dist/generated/healthGapKinds.generated.d.ts.map +1 -0
  868. package/dist/generated/healthGapKinds.generated.js +16 -0
  869. package/dist/generated/healthGapKinds.generated.js.map +1 -0
  870. package/dist/generated/organisationalAuthorityRefusalCodes.generated.d.ts +12 -0
  871. package/dist/generated/organisationalAuthorityRefusalCodes.generated.d.ts.map +1 -0
  872. package/dist/generated/organisationalAuthorityRefusalCodes.generated.js +11 -0
  873. package/dist/generated/organisationalAuthorityRefusalCodes.generated.js.map +1 -0
  874. package/dist/generated/relationTypes.generated.d.ts +12 -0
  875. package/dist/generated/relationTypes.generated.d.ts.map +1 -0
  876. package/dist/generated/relationTypes.generated.js +11 -0
  877. package/dist/generated/relationTypes.generated.js.map +1 -0
  878. package/dist/generated/routeLatencyBudget.generated.d.ts +55 -0
  879. package/dist/generated/routeLatencyBudget.generated.d.ts.map +1 -0
  880. package/dist/generated/routeLatencyBudget.generated.js +272 -0
  881. package/dist/generated/routeLatencyBudget.generated.js.map +1 -0
  882. package/dist/generated/sourceSurfaces.generated.d.ts +12 -0
  883. package/dist/generated/sourceSurfaces.generated.d.ts.map +1 -0
  884. package/dist/generated/sourceSurfaces.generated.js +11 -0
  885. package/dist/generated/sourceSurfaces.generated.js.map +1 -0
  886. package/dist/generators/adapters.d.ts +39 -6
  887. package/dist/generators/adapters.d.ts.map +1 -1
  888. package/dist/generators/adapters.js +88 -89
  889. package/dist/generators/adapters.js.map +1 -1
  890. package/dist/generators/adapters.test.js +14 -6
  891. package/dist/generators/adapters.test.js.map +1 -1
  892. package/dist/generators/briefing-projections.test.d.ts +2 -0
  893. package/dist/generators/briefing-projections.test.d.ts.map +1 -0
  894. package/dist/generators/briefing-projections.test.js +98 -0
  895. package/dist/generators/briefing-projections.test.js.map +1 -0
  896. package/dist/generators/context-md.d.ts +7 -2
  897. package/dist/generators/context-md.d.ts.map +1 -1
  898. package/dist/generators/context-md.js +14 -53
  899. package/dist/generators/context-md.js.map +1 -1
  900. package/dist/generators/everyone-rules-md.d.ts +9 -0
  901. package/dist/generators/everyone-rules-md.d.ts.map +1 -0
  902. package/dist/generators/everyone-rules-md.js +21 -0
  903. package/dist/generators/everyone-rules-md.js.map +1 -0
  904. package/dist/generators/noProjectionAssets.d.ts +15 -0
  905. package/dist/generators/noProjectionAssets.d.ts.map +1 -0
  906. package/dist/generators/noProjectionAssets.js +6 -0
  907. package/dist/generators/noProjectionAssets.js.map +1 -0
  908. package/dist/generators/portable-knowledge.d.ts +9 -26
  909. package/dist/generators/portable-knowledge.d.ts.map +1 -1
  910. package/dist/generators/portable-knowledge.js +11 -125
  911. package/dist/generators/portable-knowledge.js.map +1 -1
  912. package/dist/generators/portable-knowledge.test.js +82 -267
  913. package/dist/generators/portable-knowledge.test.js.map +1 -1
  914. package/dist/generators/region-projections.d.ts +17 -0
  915. package/dist/generators/region-projections.d.ts.map +1 -0
  916. package/dist/generators/region-projections.js +51 -0
  917. package/dist/generators/region-projections.js.map +1 -0
  918. package/dist/generators/region-projections.test.d.ts +2 -0
  919. package/dist/generators/region-projections.test.d.ts.map +1 -0
  920. package/dist/generators/region-projections.test.js +58 -0
  921. package/dist/generators/region-projections.test.js.map +1 -0
  922. package/dist/generators/region.d.ts +24 -0
  923. package/dist/generators/region.d.ts.map +1 -0
  924. package/dist/generators/region.js +87 -0
  925. package/dist/generators/region.js.map +1 -0
  926. package/dist/generators/region.test.d.ts +2 -0
  927. package/dist/generators/region.test.d.ts.map +1 -0
  928. package/dist/generators/region.test.js +125 -0
  929. package/dist/generators/region.test.js.map +1 -0
  930. package/dist/generators/retired-projections.d.ts +12 -0
  931. package/dist/generators/retired-projections.d.ts.map +1 -0
  932. package/dist/generators/retired-projections.js +75 -0
  933. package/dist/generators/retired-projections.js.map +1 -0
  934. package/dist/generators/retired-projections.test.d.ts +2 -0
  935. package/dist/generators/retired-projections.test.d.ts.map +1 -0
  936. package/dist/generators/retired-projections.test.js +64 -0
  937. package/dist/generators/retired-projections.test.js.map +1 -0
  938. package/dist/handleCliError.d.ts +13 -0
  939. package/dist/handleCliError.d.ts.map +1 -0
  940. package/dist/handleCliError.js +80 -0
  941. package/dist/handleCliError.js.map +1 -0
  942. package/dist/index.d.ts +0 -5
  943. package/dist/index.d.ts.map +1 -1
  944. package/dist/index.js +201 -515
  945. package/dist/index.js.map +1 -1
  946. package/dist/lib/__tests__/legalRelationTypes.test.d.ts +2 -0
  947. package/dist/lib/__tests__/legalRelationTypes.test.d.ts.map +1 -0
  948. package/dist/lib/__tests__/legalRelationTypes.test.js +61 -0
  949. package/dist/lib/__tests__/legalRelationTypes.test.js.map +1 -0
  950. package/dist/lib/__tests__/parseFields.test.d.ts +2 -0
  951. package/dist/lib/__tests__/parseFields.test.d.ts.map +1 -0
  952. package/dist/lib/__tests__/parseFields.test.js +40 -0
  953. package/dist/lib/__tests__/parseFields.test.js.map +1 -0
  954. package/dist/lib/adminConfig.d.ts +48 -0
  955. package/dist/lib/adminConfig.d.ts.map +1 -0
  956. package/dist/lib/adminConfig.js +130 -0
  957. package/dist/lib/adminConfig.js.map +1 -0
  958. package/dist/lib/canonicalRefs.d.ts +27 -8
  959. package/dist/lib/canonicalRefs.d.ts.map +1 -1
  960. package/dist/lib/canonicalRefs.js +25 -6
  961. package/dist/lib/canonicalRefs.js.map +1 -1
  962. package/dist/lib/captureLink.d.ts +31 -0
  963. package/dist/lib/captureLink.d.ts.map +1 -0
  964. package/dist/lib/captureLink.js +125 -0
  965. package/dist/lib/captureLink.js.map +1 -0
  966. package/dist/lib/checklist.d.ts +32 -0
  967. package/dist/lib/checklist.d.ts.map +1 -0
  968. package/dist/lib/checklist.js +79 -0
  969. package/dist/lib/checklist.js.map +1 -0
  970. package/dist/lib/client.d.ts +38 -24
  971. package/dist/lib/client.d.ts.map +1 -1
  972. package/dist/lib/client.js +208 -100
  973. package/dist/lib/client.js.map +1 -1
  974. package/dist/lib/commanderOptions.d.ts +8 -0
  975. package/dist/lib/commanderOptions.d.ts.map +1 -0
  976. package/dist/lib/commanderOptions.js +10 -0
  977. package/dist/lib/commanderOptions.js.map +1 -0
  978. package/dist/lib/compose-wrapup-view.d.ts +56 -0
  979. package/dist/lib/compose-wrapup-view.d.ts.map +1 -0
  980. package/dist/lib/compose-wrapup-view.js +39 -0
  981. package/dist/lib/compose-wrapup-view.js.map +1 -0
  982. package/dist/lib/config.d.ts +97 -68
  983. package/dist/lib/config.d.ts.map +1 -1
  984. package/dist/lib/config.js +213 -205
  985. package/dist/lib/config.js.map +1 -1
  986. package/dist/lib/configResult.d.ts +102 -0
  987. package/dist/lib/configResult.d.ts.map +1 -0
  988. package/dist/lib/configResult.js +179 -0
  989. package/dist/lib/configResult.js.map +1 -0
  990. package/dist/lib/connectProfileName.d.ts +36 -0
  991. package/dist/lib/connectProfileName.d.ts.map +1 -0
  992. package/dist/lib/connectProfileName.js +72 -0
  993. package/dist/lib/connectProfileName.js.map +1 -0
  994. package/dist/lib/connectProfileName.test.d.ts +2 -0
  995. package/dist/lib/connectProfileName.test.d.ts.map +1 -0
  996. package/dist/lib/connectProfileName.test.js +100 -0
  997. package/dist/lib/connectProfileName.test.js.map +1 -0
  998. package/dist/lib/constants.d.ts +6 -1
  999. package/dist/lib/constants.d.ts.map +1 -1
  1000. package/dist/lib/constants.js +9 -1
  1001. package/dist/lib/constants.js.map +1 -1
  1002. package/dist/lib/conversation.d.ts +36 -0
  1003. package/dist/lib/conversation.d.ts.map +1 -0
  1004. package/dist/lib/conversation.js +66 -0
  1005. package/dist/lib/conversation.js.map +1 -0
  1006. package/dist/lib/createEntryResult.d.ts +34 -0
  1007. package/dist/lib/createEntryResult.d.ts.map +1 -0
  1008. package/dist/lib/createEntryResult.js +12 -0
  1009. package/dist/lib/createEntryResult.js.map +1 -0
  1010. package/dist/lib/deployment.js +2 -2
  1011. package/dist/lib/deployment.js.map +1 -1
  1012. package/dist/lib/deployment.test.js +20 -1
  1013. package/dist/lib/deployment.test.js.map +1 -1
  1014. package/dist/lib/envKeySnapshot.d.ts +10 -0
  1015. package/dist/lib/envKeySnapshot.d.ts.map +1 -0
  1016. package/dist/lib/envKeySnapshot.js +30 -0
  1017. package/dist/lib/envKeySnapshot.js.map +1 -0
  1018. package/dist/lib/errors.d.ts +90 -0
  1019. package/dist/lib/errors.d.ts.map +1 -1
  1020. package/dist/lib/errors.js +83 -0
  1021. package/dist/lib/errors.js.map +1 -1
  1022. package/dist/lib/frontmatter.d.ts +55 -0
  1023. package/dist/lib/frontmatter.d.ts.map +1 -0
  1024. package/dist/lib/frontmatter.js +92 -0
  1025. package/dist/lib/frontmatter.js.map +1 -0
  1026. package/dist/lib/frontmatter.test.d.ts +15 -0
  1027. package/dist/lib/frontmatter.test.d.ts.map +1 -0
  1028. package/dist/lib/frontmatter.test.js +98 -0
  1029. package/dist/lib/frontmatter.test.js.map +1 -0
  1030. package/dist/lib/gatewayTimeout.d.ts +88 -0
  1031. package/dist/lib/gatewayTimeout.d.ts.map +1 -0
  1032. package/dist/lib/gatewayTimeout.js +118 -0
  1033. package/dist/lib/gatewayTimeout.js.map +1 -0
  1034. package/dist/lib/gitEnvLeakKeysParity.test.d.ts +2 -0
  1035. package/dist/lib/gitEnvLeakKeysParity.test.d.ts.map +1 -0
  1036. package/dist/lib/gitEnvLeakKeysParity.test.js +73 -0
  1037. package/dist/lib/gitEnvLeakKeysParity.test.js.map +1 -0
  1038. package/dist/lib/glossary.d.ts +3 -15
  1039. package/dist/lib/glossary.d.ts.map +1 -1
  1040. package/dist/lib/glossary.js +6 -47
  1041. package/dist/lib/glossary.js.map +1 -1
  1042. package/dist/lib/hook-intents.d.ts +9 -4
  1043. package/dist/lib/hook-intents.d.ts.map +1 -1
  1044. package/dist/lib/hook-intents.js +10 -11
  1045. package/dist/lib/hook-intents.js.map +1 -1
  1046. package/dist/lib/judgeWait.d.ts +50 -0
  1047. package/dist/lib/judgeWait.d.ts.map +1 -0
  1048. package/dist/lib/judgeWait.js +64 -0
  1049. package/dist/lib/judgeWait.js.map +1 -0
  1050. package/dist/lib/kernelEnvelope.d.ts +42 -0
  1051. package/dist/lib/kernelEnvelope.d.ts.map +1 -0
  1052. package/dist/lib/kernelEnvelope.js +67 -0
  1053. package/dist/lib/kernelEnvelope.js.map +1 -0
  1054. package/dist/lib/legalRelationTypes.d.ts +19 -0
  1055. package/dist/lib/legalRelationTypes.d.ts.map +1 -0
  1056. package/dist/lib/legalRelationTypes.js +64 -0
  1057. package/dist/lib/legalRelationTypes.js.map +1 -0
  1058. package/dist/lib/localBinding.d.ts +86 -0
  1059. package/dist/lib/localBinding.d.ts.map +1 -0
  1060. package/dist/lib/localBinding.js +173 -0
  1061. package/dist/lib/localBinding.js.map +1 -0
  1062. package/dist/lib/method-registry.d.ts +16 -11
  1063. package/dist/lib/method-registry.d.ts.map +1 -1
  1064. package/dist/lib/method-registry.js +13 -25
  1065. package/dist/lib/method-registry.js.map +1 -1
  1066. package/dist/lib/normalizeMaterializedFilename.d.ts +3 -3
  1067. package/dist/lib/normalizeMaterializedFilename.js +3 -3
  1068. package/dist/lib/notice-marker.d.ts +3 -0
  1069. package/dist/lib/notice-marker.d.ts.map +1 -0
  1070. package/dist/lib/notice-marker.js +223 -0
  1071. package/dist/lib/notice-marker.js.map +1 -0
  1072. package/dist/lib/outcomeObjectiveLines.d.ts +30 -0
  1073. package/dist/lib/outcomeObjectiveLines.d.ts.map +1 -0
  1074. package/dist/lib/outcomeObjectiveLines.js +29 -0
  1075. package/dist/lib/outcomeObjectiveLines.js.map +1 -0
  1076. package/dist/lib/ownerLine.d.ts +90 -0
  1077. package/dist/lib/ownerLine.d.ts.map +1 -0
  1078. package/dist/lib/ownerLine.js +77 -0
  1079. package/dist/lib/ownerLine.js.map +1 -0
  1080. package/dist/lib/parseFields.d.ts +19 -0
  1081. package/dist/lib/parseFields.d.ts.map +1 -0
  1082. package/dist/lib/parseFields.js +49 -0
  1083. package/dist/lib/parseFields.js.map +1 -0
  1084. package/dist/lib/pinnedRole.d.ts +28 -0
  1085. package/dist/lib/pinnedRole.d.ts.map +1 -0
  1086. package/dist/lib/pinnedRole.js +106 -0
  1087. package/dist/lib/pinnedRole.js.map +1 -0
  1088. package/dist/lib/platformGlossary.d.ts +22 -0
  1089. package/dist/lib/platformGlossary.d.ts.map +1 -0
  1090. package/dist/lib/platformGlossary.js +26 -0
  1091. package/dist/lib/platformGlossary.js.map +1 -0
  1092. package/dist/lib/previewBanner.d.ts +9 -0
  1093. package/dist/lib/previewBanner.d.ts.map +1 -0
  1094. package/dist/lib/previewBanner.js +36 -0
  1095. package/dist/lib/previewBanner.js.map +1 -0
  1096. package/dist/lib/productbrain-files.d.ts +108 -0
  1097. package/dist/lib/productbrain-files.d.ts.map +1 -0
  1098. package/dist/lib/productbrain-files.js +240 -0
  1099. package/dist/lib/productbrain-files.js.map +1 -0
  1100. package/dist/lib/productbrain-files.test.d.ts +2 -0
  1101. package/dist/lib/productbrain-files.test.d.ts.map +1 -0
  1102. package/dist/lib/productbrain-files.test.js +518 -0
  1103. package/dist/lib/productbrain-files.test.js.map +1 -0
  1104. package/dist/lib/profiles.d.ts +55 -5
  1105. package/dist/lib/profiles.d.ts.map +1 -1
  1106. package/dist/lib/profiles.js +81 -27
  1107. package/dist/lib/profiles.js.map +1 -1
  1108. package/dist/lib/projectConfig.d.ts +121 -0
  1109. package/dist/lib/projectConfig.d.ts.map +1 -0
  1110. package/dist/lib/projectConfig.js +226 -0
  1111. package/dist/lib/projectConfig.js.map +1 -0
  1112. package/dist/lib/prompts.d.ts +2 -0
  1113. package/dist/lib/prompts.d.ts.map +1 -1
  1114. package/dist/lib/prompts.js +2 -0
  1115. package/dist/lib/prompts.js.map +1 -1
  1116. package/dist/lib/proseBody.d.ts +14 -0
  1117. package/dist/lib/proseBody.d.ts.map +1 -0
  1118. package/dist/lib/proseBody.js +25 -0
  1119. package/dist/lib/proseBody.js.map +1 -0
  1120. package/dist/lib/rate-limit.d.ts +34 -0
  1121. package/dist/lib/rate-limit.d.ts.map +1 -0
  1122. package/dist/lib/rate-limit.js +89 -0
  1123. package/dist/lib/rate-limit.js.map +1 -0
  1124. package/dist/lib/readinessNotices.d.ts +12 -0
  1125. package/dist/lib/readinessNotices.d.ts.map +1 -0
  1126. package/dist/lib/readinessNotices.js +15 -0
  1127. package/dist/lib/readinessNotices.js.map +1 -0
  1128. package/dist/lib/repo-detect.d.ts +8 -2
  1129. package/dist/lib/repo-detect.d.ts.map +1 -1
  1130. package/dist/lib/repo-detect.js +11 -6
  1131. package/dist/lib/repo-detect.js.map +1 -1
  1132. package/dist/lib/reportedProfile.d.ts +18 -0
  1133. package/dist/lib/reportedProfile.d.ts.map +1 -0
  1134. package/dist/lib/reportedProfile.js +144 -0
  1135. package/dist/lib/reportedProfile.js.map +1 -0
  1136. package/dist/lib/ruleListRender.d.ts +255 -0
  1137. package/dist/lib/ruleListRender.d.ts.map +1 -0
  1138. package/dist/lib/ruleListRender.js +338 -0
  1139. package/dist/lib/ruleListRender.js.map +1 -0
  1140. package/dist/lib/runner.d.ts +9 -1
  1141. package/dist/lib/runner.d.ts.map +1 -1
  1142. package/dist/lib/runner.js +30 -4
  1143. package/dist/lib/runner.js.map +1 -1
  1144. package/dist/lib/seatSentence.d.ts +62 -0
  1145. package/dist/lib/seatSentence.d.ts.map +1 -0
  1146. package/dist/lib/seatSentence.js +82 -0
  1147. package/dist/lib/seatSentence.js.map +1 -0
  1148. package/dist/lib/session.d.ts +90 -6
  1149. package/dist/lib/session.d.ts.map +1 -1
  1150. package/dist/lib/session.js +261 -17
  1151. package/dist/lib/session.js.map +1 -1
  1152. package/dist/lib/sessionBinding.d.ts +61 -0
  1153. package/dist/lib/sessionBinding.d.ts.map +1 -0
  1154. package/dist/lib/sessionBinding.js +125 -0
  1155. package/dist/lib/sessionBinding.js.map +1 -0
  1156. package/dist/lib/sessionNotices.d.ts +54 -0
  1157. package/dist/lib/sessionNotices.d.ts.map +1 -0
  1158. package/dist/lib/sessionNotices.js +130 -0
  1159. package/dist/lib/sessionNotices.js.map +1 -0
  1160. package/dist/lib/sessionNotices.test.d.ts +2 -0
  1161. package/dist/lib/sessionNotices.test.d.ts.map +1 -0
  1162. package/dist/lib/sessionNotices.test.js +53 -0
  1163. package/dist/lib/sessionNotices.test.js.map +1 -0
  1164. package/dist/lib/spineVerdictRead.d.ts +70 -0
  1165. package/dist/lib/spineVerdictRead.d.ts.map +1 -0
  1166. package/dist/lib/spineVerdictRead.js +73 -0
  1167. package/dist/lib/spineVerdictRead.js.map +1 -0
  1168. package/dist/lib/spinner.js +2 -2
  1169. package/dist/lib/spinner.js.map +1 -1
  1170. package/dist/lib/startup-resolution-signals.d.ts +34 -0
  1171. package/dist/lib/startup-resolution-signals.d.ts.map +1 -0
  1172. package/dist/lib/startup-resolution-signals.js +116 -0
  1173. package/dist/lib/startup-resolution-signals.js.map +1 -0
  1174. package/dist/lib/startup-resolution-signals.test.d.ts +2 -0
  1175. package/dist/lib/startup-resolution-signals.test.d.ts.map +1 -0
  1176. package/dist/lib/startup-resolution-signals.test.js +113 -0
  1177. package/dist/lib/startup-resolution-signals.test.js.map +1 -0
  1178. package/dist/lib/startup-signals.d.ts +12 -0
  1179. package/dist/lib/startup-signals.d.ts.map +1 -0
  1180. package/dist/lib/startup-signals.js +179 -0
  1181. package/dist/lib/startup-signals.js.map +1 -0
  1182. package/dist/lib/startup-signals.test.d.ts +2 -0
  1183. package/dist/lib/startup-signals.test.d.ts.map +1 -0
  1184. package/dist/lib/startup-signals.test.js +165 -0
  1185. package/dist/lib/startup-signals.test.js.map +1 -0
  1186. package/dist/lib/state.d.ts +11 -2
  1187. package/dist/lib/state.d.ts.map +1 -1
  1188. package/dist/lib/state.js +11 -4
  1189. package/dist/lib/state.js.map +1 -1
  1190. package/dist/lib/statusCategories.d.ts +160 -0
  1191. package/dist/lib/statusCategories.d.ts.map +1 -0
  1192. package/dist/lib/statusCategories.js +284 -0
  1193. package/dist/lib/statusCategories.js.map +1 -0
  1194. package/dist/lib/strip.d.ts +17 -0
  1195. package/dist/lib/strip.d.ts.map +1 -1
  1196. package/dist/lib/strip.js +48 -1
  1197. package/dist/lib/strip.js.map +1 -1
  1198. package/dist/lib/style.d.ts +8 -2
  1199. package/dist/lib/style.d.ts.map +1 -1
  1200. package/dist/lib/style.js +24 -17
  1201. package/dist/lib/style.js.map +1 -1
  1202. package/dist/lib/tokenConstants.d.ts +2 -0
  1203. package/dist/lib/tokenConstants.d.ts.map +1 -1
  1204. package/dist/lib/tokenConstants.js +2 -0
  1205. package/dist/lib/tokenConstants.js.map +1 -1
  1206. package/dist/lib/update-check.d.ts +29 -13
  1207. package/dist/lib/update-check.d.ts.map +1 -1
  1208. package/dist/lib/update-check.js +132 -76
  1209. package/dist/lib/update-check.js.map +1 -1
  1210. package/dist/lib/upgrade-runner.d.ts +2 -1
  1211. package/dist/lib/upgrade-runner.d.ts.map +1 -1
  1212. package/dist/lib/upgrade-runner.js +8 -7
  1213. package/dist/lib/upgrade-runner.js.map +1 -1
  1214. package/dist/lib/workspaceNotice.d.ts +202 -0
  1215. package/dist/lib/workspaceNotice.d.ts.map +1 -0
  1216. package/dist/lib/workspaceNotice.js +345 -0
  1217. package/dist/lib/workspaceNotice.js.map +1 -0
  1218. package/dist/lib/writePerimeter.d.ts +72 -0
  1219. package/dist/lib/writePerimeter.d.ts.map +1 -0
  1220. package/dist/lib/writePerimeter.js +128 -0
  1221. package/dist/lib/writePerimeter.js.map +1 -0
  1222. package/dist/registerEntryCommands.d.ts +18 -0
  1223. package/dist/registerEntryCommands.d.ts.map +1 -0
  1224. package/dist/registerEntryCommands.js +122 -0
  1225. package/dist/registerEntryCommands.js.map +1 -0
  1226. package/dist/registerHistoryCommand.d.ts +8 -0
  1227. package/dist/registerHistoryCommand.d.ts.map +1 -0
  1228. package/dist/registerHistoryCommand.js +14 -0
  1229. package/dist/registerHistoryCommand.js.map +1 -0
  1230. package/dist/registerOutcomeCommands.d.ts +27 -0
  1231. package/dist/registerOutcomeCommands.d.ts.map +1 -0
  1232. package/dist/registerOutcomeCommands.js +27 -0
  1233. package/dist/registerOutcomeCommands.js.map +1 -0
  1234. package/dist/registerRoleCommands.d.ts +11 -0
  1235. package/dist/registerRoleCommands.d.ts.map +1 -0
  1236. package/dist/registerRoleCommands.js +42 -0
  1237. package/dist/registerRoleCommands.js.map +1 -0
  1238. package/dist/registerTensionsCommands.d.ts +10 -0
  1239. package/dist/registerTensionsCommands.d.ts.map +1 -0
  1240. package/dist/registerTensionsCommands.js +15 -0
  1241. package/dist/registerTensionsCommands.js.map +1 -0
  1242. package/dist/scoreboard/diagnose.d.ts +190 -0
  1243. package/dist/scoreboard/diagnose.d.ts.map +1 -0
  1244. package/dist/scoreboard/diagnose.js +282 -0
  1245. package/dist/scoreboard/diagnose.js.map +1 -0
  1246. package/dist/scoreboard/diagnose.test.d.ts +15 -0
  1247. package/dist/scoreboard/diagnose.test.d.ts.map +1 -0
  1248. package/dist/scoreboard/diagnose.test.js +288 -0
  1249. package/dist/scoreboard/diagnose.test.js.map +1 -0
  1250. package/dist/scoreboard/floors.d.ts +47 -0
  1251. package/dist/scoreboard/floors.d.ts.map +1 -0
  1252. package/dist/scoreboard/floors.js +33 -0
  1253. package/dist/scoreboard/floors.js.map +1 -0
  1254. package/dist/scoreboard/localDrift.d.ts +23 -0
  1255. package/dist/scoreboard/localDrift.d.ts.map +1 -0
  1256. package/dist/scoreboard/localDrift.js +111 -0
  1257. package/dist/scoreboard/localDrift.js.map +1 -0
  1258. package/dist/scoreboard/localDrift.test.d.ts +9 -0
  1259. package/dist/scoreboard/localDrift.test.d.ts.map +1 -0
  1260. package/dist/scoreboard/localDrift.test.js +82 -0
  1261. package/dist/scoreboard/localDrift.test.js.map +1 -0
  1262. package/dist/surfaces/__tests__/adapter.test.js +2 -6
  1263. package/dist/surfaces/__tests__/adapter.test.js.map +1 -1
  1264. package/dist/surfaces/__tests__/claude-skill-pointer-drift.test.d.ts +2 -0
  1265. package/dist/surfaces/__tests__/claude-skill-pointer-drift.test.d.ts.map +1 -0
  1266. package/dist/surfaces/__tests__/claude-skill-pointer-drift.test.js +179 -0
  1267. package/dist/surfaces/__tests__/claude-skill-pointer-drift.test.js.map +1 -0
  1268. package/dist/surfaces/adapters/claude.d.ts.map +1 -1
  1269. package/dist/surfaces/adapters/claude.js +30 -25
  1270. package/dist/surfaces/adapters/claude.js.map +1 -1
  1271. package/dist/surfaces/registry.js +1 -1
  1272. package/dist/surfaces/registry.js.map +1 -1
  1273. package/package.json +9 -7
  1274. package/dist/__tests__/audit.test.d.ts +0 -2
  1275. package/dist/__tests__/audit.test.d.ts.map +0 -1
  1276. package/dist/__tests__/audit.test.js +0 -394
  1277. package/dist/__tests__/audit.test.js.map +0 -1
  1278. package/dist/__tests__/authority-domains.test.d.ts +0 -2
  1279. package/dist/__tests__/authority-domains.test.d.ts.map +0 -1
  1280. package/dist/__tests__/authority-domains.test.js +0 -48
  1281. package/dist/__tests__/authority-domains.test.js.map +0 -1
  1282. package/dist/__tests__/ingest.test.d.ts +0 -2
  1283. package/dist/__tests__/ingest.test.d.ts.map +0 -1
  1284. package/dist/__tests__/ingest.test.js +0 -185
  1285. package/dist/__tests__/ingest.test.js.map +0 -1
  1286. package/dist/__tests__/onboarding-path-b.test.d.ts +0 -2
  1287. package/dist/__tests__/onboarding-path-b.test.d.ts.map +0 -1
  1288. package/dist/__tests__/onboarding-path-b.test.js +0 -46
  1289. package/dist/__tests__/onboarding-path-b.test.js.map +0 -1
  1290. package/dist/__tests__/onboarding.test.d.ts +0 -6
  1291. package/dist/__tests__/onboarding.test.d.ts.map +0 -1
  1292. package/dist/__tests__/onboarding.test.js +0 -347
  1293. package/dist/__tests__/onboarding.test.js.map +0 -1
  1294. package/dist/__tests__/promote.test.d.ts +0 -2
  1295. package/dist/__tests__/promote.test.d.ts.map +0 -1
  1296. package/dist/__tests__/promote.test.js +0 -230
  1297. package/dist/__tests__/promote.test.js.map +0 -1
  1298. package/dist/__tests__/proposals.test.d.ts +0 -2
  1299. package/dist/__tests__/proposals.test.d.ts.map +0 -1
  1300. package/dist/__tests__/proposals.test.js +0 -167
  1301. package/dist/__tests__/proposals.test.js.map +0 -1
  1302. package/dist/__tests__/setup-ingest.test.d.ts +0 -2
  1303. package/dist/__tests__/setup-ingest.test.d.ts.map +0 -1
  1304. package/dist/__tests__/setup-ingest.test.js +0 -71
  1305. package/dist/__tests__/setup-ingest.test.js.map +0 -1
  1306. package/dist/__tests__/setup-resolver.test.d.ts +0 -14
  1307. package/dist/__tests__/setup-resolver.test.d.ts.map +0 -1
  1308. package/dist/__tests__/setup-resolver.test.js +0 -228
  1309. package/dist/__tests__/setup-resolver.test.js.map +0 -1
  1310. package/dist/__tests__/setup.test.d.ts +0 -2
  1311. package/dist/__tests__/setup.test.d.ts.map +0 -1
  1312. package/dist/__tests__/setup.test.js +0 -141
  1313. package/dist/__tests__/setup.test.js.map +0 -1
  1314. package/dist/commands/__tests__/setup-state.test.d.ts +0 -2
  1315. package/dist/commands/__tests__/setup-state.test.d.ts.map +0 -1
  1316. package/dist/commands/__tests__/setup-state.test.js +0 -194
  1317. package/dist/commands/__tests__/setup-state.test.js.map +0 -1
  1318. package/dist/commands/accept.d.ts +0 -18
  1319. package/dist/commands/accept.d.ts.map +0 -1
  1320. package/dist/commands/accept.js +0 -76
  1321. package/dist/commands/accept.js.map +0 -1
  1322. package/dist/commands/audit.d.ts +0 -25
  1323. package/dist/commands/audit.d.ts.map +0 -1
  1324. package/dist/commands/audit.js +0 -188
  1325. package/dist/commands/audit.js.map +0 -1
  1326. package/dist/commands/authority-domains.d.ts +0 -146
  1327. package/dist/commands/authority-domains.d.ts.map +0 -1
  1328. package/dist/commands/authority-domains.js +0 -282
  1329. package/dist/commands/authority-domains.js.map +0 -1
  1330. package/dist/commands/brand-pack.d.ts +0 -2
  1331. package/dist/commands/brand-pack.d.ts.map +0 -1
  1332. package/dist/commands/brand-pack.js +0 -25
  1333. package/dist/commands/brand-pack.js.map +0 -1
  1334. package/dist/commands/ingest.d.ts +0 -14
  1335. package/dist/commands/ingest.d.ts.map +0 -1
  1336. package/dist/commands/ingest.js +0 -189
  1337. package/dist/commands/ingest.js.map +0 -1
  1338. package/dist/commands/method.d.ts +0 -99
  1339. package/dist/commands/method.d.ts.map +0 -1
  1340. package/dist/commands/method.js +0 -784
  1341. package/dist/commands/method.js.map +0 -1
  1342. package/dist/commands/migrate-setup.d.ts +0 -18
  1343. package/dist/commands/migrate-setup.d.ts.map +0 -1
  1344. package/dist/commands/migrate-setup.js +0 -198
  1345. package/dist/commands/migrate-setup.js.map +0 -1
  1346. package/dist/commands/promote.d.ts +0 -12
  1347. package/dist/commands/promote.d.ts.map +0 -1
  1348. package/dist/commands/promote.js +0 -113
  1349. package/dist/commands/promote.js.map +0 -1
  1350. package/dist/commands/proposals.d.ts +0 -9
  1351. package/dist/commands/proposals.d.ts.map +0 -1
  1352. package/dist/commands/proposals.js +0 -24
  1353. package/dist/commands/proposals.js.map +0 -1
  1354. package/dist/commands/reject.d.ts +0 -14
  1355. package/dist/commands/reject.d.ts.map +0 -1
  1356. package/dist/commands/reject.js +0 -43
  1357. package/dist/commands/reject.js.map +0 -1
  1358. package/dist/commands/setup-detect-surfaces.d.ts +0 -38
  1359. package/dist/commands/setup-detect-surfaces.d.ts.map +0 -1
  1360. package/dist/commands/setup-detect-surfaces.js +0 -67
  1361. package/dist/commands/setup-detect-surfaces.js.map +0 -1
  1362. package/dist/commands/setup-ingest.d.ts +0 -17
  1363. package/dist/commands/setup-ingest.d.ts.map +0 -1
  1364. package/dist/commands/setup-ingest.js +0 -226
  1365. package/dist/commands/setup-ingest.js.map +0 -1
  1366. package/dist/commands/setup-resolver.d.ts +0 -58
  1367. package/dist/commands/setup-resolver.d.ts.map +0 -1
  1368. package/dist/commands/setup-resolver.js +0 -150
  1369. package/dist/commands/setup-resolver.js.map +0 -1
  1370. package/dist/commands/setup-state.d.ts +0 -42
  1371. package/dist/commands/setup-state.d.ts.map +0 -1
  1372. package/dist/commands/setup-state.js +0 -93
  1373. package/dist/commands/setup-state.js.map +0 -1
  1374. package/dist/commands/setup.d.ts +0 -23
  1375. package/dist/commands/setup.d.ts.map +0 -1
  1376. package/dist/commands/setup.js +0 -69
  1377. package/dist/commands/setup.js.map +0 -1
  1378. package/dist/formatters/audit.d.ts +0 -46
  1379. package/dist/formatters/audit.d.ts.map +0 -1
  1380. package/dist/formatters/audit.js +0 -81
  1381. package/dist/formatters/audit.js.map +0 -1
  1382. package/dist/formatters/promote.d.ts +0 -30
  1383. package/dist/formatters/promote.d.ts.map +0 -1
  1384. package/dist/formatters/promote.js +0 -39
  1385. package/dist/formatters/promote.js.map +0 -1
  1386. package/dist/formatters/proposals.d.ts +0 -45
  1387. package/dist/formatters/proposals.d.ts.map +0 -1
  1388. package/dist/formatters/proposals.js +0 -62
  1389. package/dist/formatters/proposals.js.map +0 -1
  1390. package/dist/generators/__tests__/surface-profiles.test.d.ts +0 -2
  1391. package/dist/generators/__tests__/surface-profiles.test.d.ts.map +0 -1
  1392. package/dist/generators/__tests__/surface-profiles.test.js +0 -89
  1393. package/dist/generators/__tests__/surface-profiles.test.js.map +0 -1
  1394. package/dist/generators/archetypes.d.ts +0 -52
  1395. package/dist/generators/archetypes.d.ts.map +0 -1
  1396. package/dist/generators/archetypes.js +0 -153
  1397. package/dist/generators/archetypes.js.map +0 -1
  1398. package/dist/generators/archetypes.test.d.ts +0 -2
  1399. package/dist/generators/archetypes.test.d.ts.map +0 -1
  1400. package/dist/generators/archetypes.test.js +0 -237
  1401. package/dist/generators/archetypes.test.js.map +0 -1
  1402. package/dist/generators/chain-classifier.d.ts +0 -49
  1403. package/dist/generators/chain-classifier.d.ts.map +0 -1
  1404. package/dist/generators/chain-classifier.js +0 -180
  1405. package/dist/generators/chain-classifier.js.map +0 -1
  1406. package/dist/generators/chain-classifier.test.d.ts +0 -2
  1407. package/dist/generators/chain-classifier.test.d.ts.map +0 -1
  1408. package/dist/generators/chain-classifier.test.js +0 -257
  1409. package/dist/generators/chain-classifier.test.js.map +0 -1
  1410. package/dist/generators/chain-rules.d.ts +0 -42
  1411. package/dist/generators/chain-rules.d.ts.map +0 -1
  1412. package/dist/generators/chain-rules.js +0 -144
  1413. package/dist/generators/chain-rules.js.map +0 -1
  1414. package/dist/generators/chain-rules.test.d.ts +0 -2
  1415. package/dist/generators/chain-rules.test.d.ts.map +0 -1
  1416. package/dist/generators/chain-rules.test.js +0 -179
  1417. package/dist/generators/chain-rules.test.js.map +0 -1
  1418. package/dist/generators/handshake-diff.d.ts +0 -67
  1419. package/dist/generators/handshake-diff.d.ts.map +0 -1
  1420. package/dist/generators/handshake-diff.js +0 -183
  1421. package/dist/generators/handshake-diff.js.map +0 -1
  1422. package/dist/generators/handshake-diff.test.d.ts +0 -2
  1423. package/dist/generators/handshake-diff.test.d.ts.map +0 -1
  1424. package/dist/generators/handshake-diff.test.js +0 -264
  1425. package/dist/generators/handshake-diff.test.js.map +0 -1
  1426. package/dist/lib/activation.d.ts +0 -28
  1427. package/dist/lib/activation.d.ts.map +0 -1
  1428. package/dist/lib/activation.js +0 -57
  1429. package/dist/lib/activation.js.map +0 -1
  1430. package/dist/lib/activation.test.d.ts +0 -6
  1431. package/dist/lib/activation.test.d.ts.map +0 -1
  1432. package/dist/lib/activation.test.js +0 -121
  1433. package/dist/lib/activation.test.js.map +0 -1
  1434. package/dist/lib/collectionRegistry.d.ts +0 -38
  1435. package/dist/lib/collectionRegistry.d.ts.map +0 -1
  1436. package/dist/lib/collectionRegistry.js +0 -112
  1437. package/dist/lib/collectionRegistry.js.map +0 -1
  1438. package/dist/lib/conversation-engine.d.ts +0 -45
  1439. package/dist/lib/conversation-engine.d.ts.map +0 -1
  1440. package/dist/lib/conversation-engine.js +0 -112
  1441. package/dist/lib/conversation-engine.js.map +0 -1
  1442. package/dist/lib/conversation-phases.d.ts +0 -59
  1443. package/dist/lib/conversation-phases.d.ts.map +0 -1
  1444. package/dist/lib/conversation-phases.js +0 -11
  1445. package/dist/lib/conversation-phases.js.map +0 -1
  1446. package/dist/lib/conversation-signals.d.ts +0 -30
  1447. package/dist/lib/conversation-signals.d.ts.map +0 -1
  1448. package/dist/lib/conversation-signals.js +0 -64
  1449. package/dist/lib/conversation-signals.js.map +0 -1
  1450. package/dist/lib/inferSourceDate.d.ts +0 -12
  1451. package/dist/lib/inferSourceDate.d.ts.map +0 -1
  1452. package/dist/lib/inferSourceDate.js +0 -44
  1453. package/dist/lib/inferSourceDate.js.map +0 -1
  1454. package/dist/lib/onboarding-path-b.d.ts +0 -10
  1455. package/dist/lib/onboarding-path-b.d.ts.map +0 -1
  1456. package/dist/lib/onboarding-path-b.js +0 -214
  1457. package/dist/lib/onboarding-path-b.js.map +0 -1
  1458. package/dist/lib/onboarding-phases.d.ts +0 -9
  1459. package/dist/lib/onboarding-phases.d.ts.map +0 -1
  1460. package/dist/lib/onboarding-phases.js +0 -120
  1461. package/dist/lib/onboarding-phases.js.map +0 -1
  1462. package/dist/lib/onboarding-shared.d.ts +0 -81
  1463. package/dist/lib/onboarding-shared.d.ts.map +0 -1
  1464. package/dist/lib/onboarding-shared.js +0 -190
  1465. package/dist/lib/onboarding-shared.js.map +0 -1
  1466. package/dist/lib/onboarding-topics.d.ts +0 -27
  1467. package/dist/lib/onboarding-topics.d.ts.map +0 -1
  1468. package/dist/lib/onboarding-topics.js +0 -57
  1469. package/dist/lib/onboarding-topics.js.map +0 -1
  1470. package/dist/lib/onboarding.d.ts +0 -17
  1471. package/dist/lib/onboarding.d.ts.map +0 -1
  1472. package/dist/lib/onboarding.js +0 -350
  1473. package/dist/lib/onboarding.js.map +0 -1
  1474. package/dist/setup/__tests__/coach-traces.test.d.ts +0 -2
  1475. package/dist/setup/__tests__/coach-traces.test.d.ts.map +0 -1
  1476. package/dist/setup/__tests__/coach-traces.test.js +0 -189
  1477. package/dist/setup/__tests__/coach-traces.test.js.map +0 -1
  1478. package/dist/setup/__tests__/setup-commands.test.d.ts +0 -2
  1479. package/dist/setup/__tests__/setup-commands.test.d.ts.map +0 -1
  1480. package/dist/setup/__tests__/setup-commands.test.js +0 -177
  1481. package/dist/setup/__tests__/setup-commands.test.js.map +0 -1
  1482. package/dist/setup/__tests__/state-machine.test.d.ts +0 -2
  1483. package/dist/setup/__tests__/state-machine.test.d.ts.map +0 -1
  1484. package/dist/setup/__tests__/state-machine.test.js +0 -341
  1485. package/dist/setup/__tests__/state-machine.test.js.map +0 -1
  1486. package/dist/setup/detect-surfaces.d.ts +0 -21
  1487. package/dist/setup/detect-surfaces.d.ts.map +0 -1
  1488. package/dist/setup/detect-surfaces.js +0 -39
  1489. package/dist/setup/detect-surfaces.js.map +0 -1
  1490. package/dist/setup/manifest-writer.d.ts +0 -17
  1491. package/dist/setup/manifest-writer.d.ts.map +0 -1
  1492. package/dist/setup/manifest-writer.js +0 -153
  1493. package/dist/setup/manifest-writer.js.map +0 -1
  1494. package/dist/setup/perimeter.d.ts +0 -62
  1495. package/dist/setup/perimeter.d.ts.map +0 -1
  1496. package/dist/setup/perimeter.js +0 -113
  1497. package/dist/setup/perimeter.js.map +0 -1
  1498. package/dist/setup/state-machine.d.ts +0 -67
  1499. package/dist/setup/state-machine.d.ts.map +0 -1
  1500. package/dist/setup/state-machine.js +0 -124
  1501. package/dist/setup/state-machine.js.map +0 -1
  1502. package/dist/surfaces/__tests__/pb-setup-passthrough.test.d.ts +0 -2
  1503. package/dist/surfaces/__tests__/pb-setup-passthrough.test.d.ts.map +0 -1
  1504. package/dist/surfaces/__tests__/pb-setup-passthrough.test.js +0 -132
  1505. package/dist/surfaces/__tests__/pb-setup-passthrough.test.js.map +0 -1
  1506. package/templates/archetypes/boundary.md +0 -23
  1507. package/templates/archetypes/constraint.md +0 -23
  1508. package/templates/archetypes/convention.md +0 -23
  1509. package/templates/archetypes/policy.md +0 -23
  1510. package/templates/archetypes/quality-gate.md +0 -23
  1511. package/templates/archetypes/workflow.md +0 -23
@@ -2,186 +2,44 @@
2
2
  * pb handshake — generate context files for AI developer tools.
3
3
  * Context export wiring (read-only filesystem bridge; GLO-63, DEC-161) — not a product surface.
4
4
  */
5
- import { mkdirSync, writeFileSync, existsSync, readFileSync, readdirSync, copyFileSync, appendFileSync, unlinkSync, statSync } from 'fs';
6
- import { join, dirname, resolve, basename } from 'path';
5
+ import { mkdirSync, writeFileSync, existsSync, readFileSync, readdirSync, copyFileSync, realpathSync } from 'fs';
6
+ import { join, dirname, resolve, basename, relative, sep } from 'path';
7
7
  import { homedir } from 'os';
8
8
  import { fileURLToPath } from 'url';
9
- import { createHash } from 'crypto';
9
+ import { execSync } from 'child_process';
10
10
  import { getConfigOrGuide } from '../lib/config.js';
11
11
  import { select as promptSelect, confirm as promptConfirm } from '../lib/prompts.js';
12
- import { composeHooksFromIntents, getHookStatusForSurface } from '../lib/hook-intents.js';
13
- import { kernelCall, kernelCallWithSession } from '../lib/client.js';
12
+ import { HOOK_INTENT_CONFIGS, composeHooksFromIntents, getHookStatusForSurface } from '../lib/hook-intents.js';
13
+ import { kernelCall } from '../lib/client.js';
14
14
  import { readSession } from '../lib/session.js';
15
15
  import { detectRepo, extractWorkspaceProfile } from '../lib/repo-detect.js';
16
16
  import { generateContextMd } from '../generators/context-md.js';
17
17
  import { generateBriefingMd } from '../generators/briefing-md.js';
18
- import { MARKER, generateAgentsMd, generateClaudeMd, generateCursorMdc, generateCopilotMd } from '../generators/adapters.js';
19
- import { readCanonicalSkills, readCanonicalRules, readPersonalLayer, readPersonalSkillsLayer, generateCursorSkill, generateCursorRule, generateCodexSkill, generateCodexSkillIndex, generateClaudeRule, generateClaudeSkillRouter, shouldEmitToTarget, filterByLevel, validateCodexSkills, evaluateConditions, STAGE_TO_MAX_LEVEL, LEVEL_ORDER, } from '../generators/portable-knowledge.js';
20
- import { generateChainRules } from '../generators/chain-rules.js';
21
- import { saveHandshakeState, loadPreviousState, diffHandshakeState, formatDiff, buildCurrentState, } from '../generators/handshake-diff.js';
18
+ import { MARKER, generateAgentsMd, generateClaudeMd, generateCursorMdc, generateCopilotMd, generateCopilotInstructionFiles } from '../generators/adapters.js';
19
+ import { readCanonicalSkills, readCanonicalRules, readPersonalLayer, readPersonalSkillsLayer, generateCursorSkill, generateCursorRule, generateCodexSkill, generateCodexSkillIndex, shouldEmitToTarget, filterByLevel, validateCodexSkills, evaluateConditions, } from '../generators/portable-knowledge.js';
20
+ import { findNoProjectionAssets } from '../generators/noProjectionAssets.js'; // WP-660 S2 combine
22
21
  import { resolveSurfaceProfile } from '../generators/surface-profiles.js';
22
+ import { generateEveryoneRulesMd } from '../generators/everyone-rules-md.js';
23
+ import { removeStaleBriefingProjections, retireGeneratedProjections } from '../generators/retired-projections.js';
24
+ import { formatWorkspaceBriefingLines } from '../lib/ruleListRender.js';
23
25
  import { formatHandshakeReport } from '../formatters/handshake.js';
26
+ import { classifyAdapterFile, detectEol, spliceAppend, spliceReplace } from '../generators/region.js';
27
+ import { REGION_PROJECTIONS } from '../generators/region-projections.js';
24
28
  import { readManifest, readManifestStatus, filterByAdoptionState } from '../generators/manifest.js';
25
29
  import { generateBoundaryManifest, getBoundaryEnforcementMode } from '../generators/boundary-manifest.js';
26
30
  import { loadMethodRegistry } from '../lib/method-registry.js';
27
31
  import { CLIError, ErrorCode } from '../lib/errors.js';
28
- import { trackEvent } from '../lib/telemetry.js';
32
+ import { isJsonMode } from '../lib/runner.js';
33
+ import { stripConvexInternals } from '../lib/strip.js';
29
34
  import { replaceVocabTokens } from '../lib/canonicalRefs.js';
30
35
  // WP-436 S3: vocab projector — resolves {{vocab:...}} tokens before writing to disk.
31
36
  import { getOrFetchVocabCtx } from '../lib/workspaceVocabCache.js';
32
37
  import { normalizeMaterializedFilename } from '../lib/normalizeMaterializedFilename.js';
33
- import { assertSetupWritePath } from '../setup/perimeter.js';
34
- // WP-421 S3: SurfaceAdapter reverse-map for tampered prompts (DEC-952, doneWhen #34).
35
- import { canonicalPathForAnySurface, SURFACE_GOVERN_NO_SURFACES, SURFACE_REGISTRY, validateSurfacesForMode, } from '../surfaces/registry.js';
36
- import { getReverseMapFallbackMessage, reportReverseMapMissing } from '../surfaces/telemetry.js';
37
- const MAX_HANDSHAKE_WAIT_MS = 10_000; // 10 seconds
38
- const POLL_INTERVAL_MS = 500; // 500 ms per poll
39
- const MAX_POLLS = MAX_HANDSHAKE_WAIT_MS / POLL_INTERVAL_MS; // 20
40
- // ── WP-379 S4: Dormant marker ─────────────────────────────────────────────────
41
- /**
42
- * DORMANT_MARKER — appended to previously-projected asset files when the asset's
43
- * gate deactivates (e.g. workspace readiness exceeds the max threshold).
44
- *
45
- * Contract:
46
- * - The file is NOT deleted. It persists on disk so that history is preserved
47
- * and the agent surface remains inspectable.
48
- * - The marker is appended at the end of the file, idempotent — if it already
49
- * exists, no second append occurs.
50
- * - The marker does NOT trigger a drift TEN. Dormant files are intentionally
51
- * deactivated, not accidentally forked.
52
- * - The marker is never included in active file writes — only dormant writes.
53
- *
54
- * Used by: writeDormantMarker() (write) and hasDormantMarker() (idempotency check).
55
- * Exported for use in tests.
56
- *
57
- * Chain: WP-379 S4.
58
- */
59
- export const DORMANT_MARKER = '<!-- pb-status: dormant -->';
60
- /**
61
- * hasDormantMarker — check whether a file on disk already has the dormant marker.
62
- * Used for idempotency: if the marker is already present, skip the append.
63
- */
64
- function hasDormantMarker(content) {
65
- return content.includes(DORMANT_MARKER);
66
- }
67
- /**
68
- * writeDormantMarker — append the dormant marker to a previously-projected file.
69
- *
70
- * Idempotent: if DORMANT_MARKER is already present, no-op.
71
- * Only operates on files that have the auto-gen MARKER — we never touch
72
- * manually-authored files.
73
- *
74
- * @param filePath Absolute path to the file.
75
- * @returns 'written' | 'already-dormant' | 'skipped' (no auto-gen marker)
76
- */
77
- export function writeDormantMarkerToFile(filePath) {
78
- if (!existsSync(filePath))
79
- return 'skipped';
80
- const content = readFileSync(filePath, 'utf8');
81
- // Only mark files that were originally projected by pb handshake.
82
- // Files without the auto-gen MARKER are manually authored — leave them alone.
83
- if (!content.includes(MARKER))
84
- return 'skipped';
85
- if (hasDormantMarker(content))
86
- return 'already-dormant';
87
- // Append the marker on its own line. No trailing newline assumption —
88
- // appendFileSync adds to whatever is already there.
89
- appendFileSync(filePath, `\n${DORMANT_MARKER}\n`);
90
- return 'written';
91
- }
92
- /**
93
- * deriveDormantFilePaths — compute the set of on-disk file paths that would have
94
- * been projected for a given dormant asset (by name and assetKind).
95
- *
96
- * Assets are projected to one or more surfaces (cursor/claude/codex) depending
97
- * on shouldEmitToTarget. Since we don't re-run shouldEmitToTarget here, we
98
- * speculatively probe all known surface paths and let writeDormantMarkerToFile
99
- * decide whether each exists and has the auto-gen MARKER.
100
- *
101
- * @param asset The dormant asset from the server.
102
- * @param cwd Current working directory (project root).
103
- * @returns Array of absolute file paths to probe.
104
- */
105
- function deriveDormantFilePaths(asset, cwd) {
106
- // Defense-in-depth: even though `name` originates from platform-seeded DB
107
- // entries (not user input), validate it against a strict charset before
108
- // interpolating into a filesystem path. Reject anything that could traverse
109
- // out of the expected directories. WP-379 S4 review finding.
110
- if (!/^[A-Za-z0-9 ._-]+$/.test(asset.name)) {
111
- return [];
112
- }
113
- const paths = [];
114
- const { name, assetKind } = asset;
115
- if (assetKind === 'skill') {
116
- // Cursor skill
117
- paths.push(join(cwd, '.cursor', 'skills', name, 'SKILL.md'));
118
- // Codex skill
119
- paths.push(join(cwd, '.codex', 'skills', `${name}.md`));
120
- }
121
- else if (assetKind === 'rule' || assetKind === 'hook') {
122
- // Cursor rule
123
- paths.push(join(cwd, '.cursor', 'rules', `${name}.mdc`));
124
- // Claude rule
125
- paths.push(join(cwd, '.claude', 'rules', `${name}.md`));
126
- }
127
- return paths;
128
- }
129
- /**
130
- * Single-shot health probe — calls `workspace.health` and inspects
131
- * `starterSetupSeeded`. Does NOT poll internally; polling is the caller's
132
- * responsibility (connect-screens.tsx).
133
- *
134
- * Returns:
135
- * - `seeds-ready` — health query succeeded AND starterSetupSeeded is true
136
- * - `seeds-pending` — health query succeeded but starterSetupSeeded is false
137
- * - `probe-failed` — health query threw (network, auth, etc.)
138
- */
139
- export async function probeStarterSetupSeeded() {
140
- try {
141
- const health = await kernelCall('workspace.health', {});
142
- if (health.starterSetupSeeded) {
143
- return { status: 'seeds-ready' };
144
- }
145
- const starterGaps = (health.gaps ?? []).filter((g) => g.kind === 'starter-setup-missing' || g.kind === 'platform-domains-missing');
146
- return {
147
- status: 'seeds-pending',
148
- gaps: starterGaps.length > 0 ? starterGaps : [
149
- {
150
- kind: 'starter-setup-missing',
151
- severity: 'warn',
152
- message: 'Starter setup seeds are still running.',
153
- },
154
- ],
155
- };
156
- }
157
- catch (err) {
158
- return {
159
- status: 'probe-failed',
160
- error: err instanceof Error ? err.message : String(err),
161
- };
162
- }
163
- }
164
- /**
165
- * Poll `probeStarterSetupSeeded` up to MAX_POLLS times (10s at 500ms intervals).
166
- * Returns the final probe result — caller decides how to render the outcome.
167
- *
168
- * Exported so connect-screens.tsx can use it without re-implementing the loop.
169
- */
170
- export async function pollUntilSeedsReady() {
171
- for (let poll = 0; poll < MAX_POLLS; poll++) {
172
- const result = await probeStarterSetupSeeded();
173
- if (result.status === 'seeds-ready')
174
- return result;
175
- if (result.status === 'probe-failed')
176
- return result; // don't retry on auth/network errors
177
- // seeds-pending — wait before next poll
178
- if (poll < MAX_POLLS - 1) {
179
- await new Promise((res) => setTimeout(res, POLL_INTERVAL_MS));
180
- }
181
- }
182
- // Final probe after exhausting waits — return whatever state we have
183
- return probeStarterSetupSeeded();
184
- }
38
+ import { findLeftoverCursorSkills, LEFTOVER_FILES_MAX } from './handshakeCursorSkillCleanup.js';
39
+ import { classifyDriftBucket } from './handshakeDriftClassification.js';
40
+ import { sanitizeStartupResolutionSignals } from '../lib/startup-resolution-signals.js';
41
+ import { assertSetupWritePath } from '../lib/writePerimeter.js';
42
+ import { SURFACE_GOVERN_NO_SURFACES, SURFACE_REGISTRY, validateSurfacesForMode, } from '../surfaces/registry.js';
185
43
  const LEVELS = {
186
44
  guide: {
187
45
  label: 'Guide me',
@@ -210,8 +68,7 @@ const LEVELS = {
210
68
  };
211
69
  // Explicit ordering — determines menu numbering in promptLevel(). Do not reorder.
212
70
  const LEVEL_KEYS = ['guide', 'work', 'silent', 'full-trust'];
213
- // Hook failure contract (TEN-712): all hook commands MUST end with '2>/dev/null || true'
214
- // so Claude Code always starts even if pb is unavailable. Never remove this suffix.
71
+ // Hook failure contract (TEN-712): every hook command MUST end with '|| true' so Claude Code always starts even if pb is unavailable.
215
72
  const INIT_PERMISSION = 'Bash(pb:*)';
216
73
  function readSettings(filePath) {
217
74
  if (!existsSync(filePath))
@@ -239,7 +96,16 @@ function writeTeamSettings(cwd, dryRun) {
239
96
  }
240
97
  settings.permissions = permissions;
241
98
  const hooks = (settings.hooks ?? {});
242
- const hookAdditions = composeHooksFromIntents(['session-start', 'session-close', 'pre-compact'], hooks);
99
+ const hookAdditions = composeHooksFromIntents(['session-start', 'session-close'], hooks);
100
+ const close = HOOK_INTENT_CONFIGS['session-close'].command; // TASK-763 (DEC-2038): an older init closed on Stop, every turn
101
+ const stop = (hooks.Stop ?? []).map((g) => ({ ...g, hooks: g.hooks.filter((h) => h.command !== close) })).filter((g) => g.hooks.length > 0);
102
+ if (JSON.stringify(stop) !== JSON.stringify(hooks.Stop ?? [])) {
103
+ if (stop.length)
104
+ hooks.Stop = stop;
105
+ else
106
+ delete hooks.Stop;
107
+ added.push('Stop → pb session close removed (closed every turn)');
108
+ }
243
109
  for (const addition of hookAdditions) {
244
110
  hooks[addition.event] = [...(hooks[addition.event] ?? []), addition.entry];
245
111
  added.push(addition.label);
@@ -312,8 +178,7 @@ export async function runHandshakeInit(options = {}) {
312
178
  for (const item of teamAdded)
313
179
  console.log(` + ${item}`);
314
180
  }
315
- // Step 2: Personal config — wizard or --level flag
316
- // Cast is safe: LEVEL_KEYS.includes() validated above; invalid level already threw CLIError.
181
+ // Step 2: Personal config — wizard or --level flag. Cast is safe: LEVEL_KEYS.includes() validated above.
317
182
  const levelKey = options.level ? options.level : await promptLevel();
318
183
  const level = LEVELS[levelKey];
319
184
  const personalAdded = writePersonalSettings(levelKey, dryRun);
@@ -335,11 +200,7 @@ export async function runHandshakeInit(options = {}) {
335
200
  if (!dryRun)
336
201
  console.log('Reload /hooks in Claude Code (or restart) to activate.');
337
202
  console.log('Run `pb handshake --init --level <guide|work|silent|full-trust>` to change level.');
338
- // Step 2b: Report multi-surface hook opt-in status (WP-310 E3b)
339
- // Reads manifest.hooks.{cursor,copilot} and prints an informational note for
340
- // each opted-in surface. Silence = no manifest or no hooks flags set.
341
- // DEC-536: Claude-native default is already wired above; this block only fires
342
- // when the user has explicitly opted in via manifest.
203
+ // Step 2b: Report multi-surface hook opt-in status (WP-310 E3b) — manifest.hooks.{cursor,copilot}, silence = no manifest/flags (DEC-536).
343
204
  const pbDirForManifest = join(cwd, '.productbrain');
344
205
  const initManifest = readManifest(pbDirForManifest);
345
206
  const multiSurfaceOptIns = [];
@@ -408,22 +269,218 @@ export async function runHandshakeInit(options = {}) {
408
269
  }
409
270
  }
410
271
  }
411
- /**
412
- * Normalize volatile handshake-only timestamps before comparing generated files.
413
- * This keeps the visible timestamps in generated artifacts while avoiding
414
- * meaningless rewrites when semantic content is unchanged.
415
- */
272
+ const LOCAL_REF_REGEX = /\b(?:WP|TEN|DEC|BET|FEAT|INS|STD|PRI|ARCH)[-\s#]*\d+\b|\bPR\s*#?\s*\d+\b/gi;
273
+ const STARTUP_RESOLUTION_RESOLVER_VERSION = 'startup-resolution-v1';
274
+ // Global cap on collected refs (spec "Contract: StartupResolutionSignals" — arrays are capped).
275
+ const LOCAL_REF_GLOBAL_CAP = 25;
276
+ // Per-source cap so a broad source (context.md) can't starve briefing.md's task-specific refs (Codex@677).
277
+ const LOCAL_REF_PER_SOURCE_CAP = 18;
278
+ // Time-boxed so an unauthed/slow `gh` can't stall session-start (F4).
279
+ const PR_DIFF_TIMEOUT_MS = 4_000;
280
+ // Bounds worst-case `gh` subprocess invocations per handshake.
281
+ const PR_DIFF_MAX_REFS = 5;
282
+ function runGitText(cwd, command) {
283
+ try {
284
+ const value = execSync(command, {
285
+ cwd,
286
+ encoding: 'utf8',
287
+ stdio: ['ignore', 'pipe', 'ignore'],
288
+ }).trim();
289
+ return value.length > 0 ? value : undefined;
290
+ }
291
+ catch {
292
+ return undefined;
293
+ }
294
+ }
295
+ /** Dereference a "PR #N" ref to its changed paths via `gh pr diff <N> --name-only` (F4: server
296
+ * resolver has no git/gh access). Guarded/time-boxed; `run` is injectable for tests. */
297
+ export function dereferencePrRefToPaths(cwd, prNumber, run = runGitTextTimeboxed) {
298
+ if (!Number.isInteger(prNumber) || prNumber <= 0)
299
+ return [];
300
+ const raw = run(cwd, `gh pr diff ${prNumber} --name-only`, PR_DIFF_TIMEOUT_MS);
301
+ if (!raw)
302
+ return [];
303
+ return raw.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
304
+ }
305
+ /** Time-boxed variant of runGitText for the PR-diff dereference (F4). */
306
+ function runGitTextTimeboxed(cwd, command, timeoutMs) {
307
+ try {
308
+ const value = execSync(command, {
309
+ cwd,
310
+ encoding: 'utf8',
311
+ stdio: ['ignore', 'pipe', 'ignore'],
312
+ timeout: timeoutMs,
313
+ }).trim();
314
+ return value.length > 0 ? value : undefined;
315
+ }
316
+ catch {
317
+ return undefined;
318
+ }
319
+ }
320
+ function readOptionalLocalText(cwd, path) {
321
+ const fullPath = join(cwd, path);
322
+ if (!existsSync(fullPath))
323
+ return undefined;
324
+ try {
325
+ return readFileSync(fullPath, 'utf8');
326
+ }
327
+ catch {
328
+ return undefined;
329
+ }
330
+ }
331
+ function normalizeLocalRef(ref) {
332
+ const trimmed = ref.trim().replace(/\s+/g, ' ');
333
+ const pr = trimmed.match(/^PR\s*#?\s*(\d+)$/i);
334
+ if (pr)
335
+ return `PR #${pr[1]}`;
336
+ const entry = trimmed.match(/^([A-Z]+)[-\s#]*(\d+)$/i);
337
+ if (entry)
338
+ return `${entry[1].toUpperCase()}-${entry[2]}`;
339
+ return trimmed;
340
+ }
341
+ /** Collect normalized local refs across several text sources, deduped. Codex@677: a per-source
342
+ * cap alongside the global one, so a broad source (context.md) can't starve a later,
343
+ * task-specific source (briefing.md); already-collected refs dedupe without spending later quota. */
344
+ function collectLocalRefs(texts) {
345
+ const refs = [];
346
+ const seen = new Set();
347
+ for (const text of texts) {
348
+ if (!text)
349
+ continue;
350
+ let fromThisSource = 0;
351
+ for (const match of text.matchAll(LOCAL_REF_REGEX)) {
352
+ const ref = normalizeLocalRef(match[0]);
353
+ const key = ref.toLowerCase();
354
+ if (seen.has(key))
355
+ continue;
356
+ if (fromThisSource >= LOCAL_REF_PER_SOURCE_CAP)
357
+ break;
358
+ seen.add(key);
359
+ refs.push(ref);
360
+ fromThisSource++;
361
+ if (refs.length >= LOCAL_REF_GLOBAL_CAP)
362
+ return refs;
363
+ }
364
+ }
365
+ return refs;
366
+ }
367
+ function deriveHandshakeStartupTask(refs, changedPaths, callerTask) {
368
+ if (callerTask && callerTask.trim())
369
+ return callerTask.trim();
370
+ const parts = [];
371
+ if (refs.length > 0)
372
+ parts.push(refs.join(' '));
373
+ if (changedPaths.length > 0)
374
+ parts.push(`changed paths ${changedPaths.slice(0, 5).join(' ')}`);
375
+ return parts.length > 0 ? parts.join(' ') : undefined;
376
+ }
377
+ const DEFAULT_HANDSHAKE_SIGNAL_DEPS = {
378
+ runGit: runGitText,
379
+ prDiff: (cwd, prNumber) => dereferencePrRefToPaths(cwd, prNumber),
380
+ };
381
+ /** Extract the PR number from a normalized "PR #N" ref, else null. */
382
+ function prNumberFromRef(ref) {
383
+ const m = ref.match(/^PR\s*#?\s*(\d+)$/i);
384
+ if (!m)
385
+ return null;
386
+ const n = Number(m[1]);
387
+ return Number.isInteger(n) && n > 0 ? n : null;
388
+ }
389
+ export function deriveHandshakeStartupSignals(cwd, callerSignals = {}, deps = DEFAULT_HANDSHAKE_SIGNAL_DEPS) {
390
+ const { runGit, prDiff } = deps;
391
+ const branchName = runGit(cwd, 'git branch --show-current');
392
+ const commitSha = runGit(cwd, 'git rev-parse --short HEAD');
393
+ // Changed paths, unioned + deduped: (1) dirty worktree; (2) committed branch delta vs origin/main's
394
+ // merge-base (Codex@665, invisible once the tree is clean); (3) PR-ref dereference (F4), appended later.
395
+ const dirtyChangedPaths = runGit(cwd, 'git diff --name-only HEAD')?.split(/\r?\n/).filter(Boolean) ?? [];
396
+ const mergeBase = runGit(cwd, 'git merge-base HEAD origin/main');
397
+ const branchChangedPaths = mergeBase
398
+ ? (runGit(cwd, `git diff --name-only ${mergeBase} HEAD`)?.split(/\r?\n/).filter(Boolean) ?? [])
399
+ : [];
400
+ const worktreeName = basename(cwd);
401
+ const contextText = readOptionalLocalText(cwd, '.productbrain/context.md');
402
+ const briefingText = readOptionalLocalText(cwd, '.productbrain/briefing.md');
403
+ const callerRefs = Array.isArray(callerSignals.reviewedArtifactRefs) ? callerSignals.reviewedArtifactRefs.join('\n') : undefined;
404
+ // Codex@677: briefing.md (task-specific) reads BEFORE context.md (broad) so its refs collect first — with the per-source cap, context.md can't starve briefing.
405
+ const refs = collectLocalRefs([
406
+ callerSignals.taskText ?? undefined,
407
+ callerSignals.explicitScope ?? undefined,
408
+ callerRefs,
409
+ branchName,
410
+ worktreeName,
411
+ briefingText,
412
+ contextText,
413
+ ]);
414
+ // F4: dereference "PR #N" refs to diff paths, folded into changedPaths — the only place this can happen (server records dereferenced:false, no git access). Time-boxed; absent/unauthed gh no-ops.
415
+ const prDiffPaths = [];
416
+ if (callerSignals.changedPaths === undefined) {
417
+ let derefed = 0;
418
+ for (const ref of refs) {
419
+ const prNumber = prNumberFromRef(ref);
420
+ if (prNumber === null)
421
+ continue;
422
+ if (derefed >= PR_DIFF_MAX_REFS)
423
+ break;
424
+ derefed++;
425
+ try {
426
+ for (const p of prDiff(cwd, prNumber))
427
+ prDiffPaths.push(p);
428
+ }
429
+ catch {
430
+ // gh absent / unauthed / PR missing — skip gracefully, leave existing behavior.
431
+ }
432
+ }
433
+ }
434
+ // Caller-supplied changedPaths win (backward compat); otherwise union the
435
+ // three local sources, deduped, order-stable.
436
+ const unionedChangedPaths = callerSignals.changedPaths ??
437
+ Array.from(new Set([...dirtyChangedPaths, ...branchChangedPaths, ...prDiffPaths]));
438
+ const baseSignals = sanitizeStartupResolutionSignals({
439
+ ...callerSignals,
440
+ sourceSurface: callerSignals.sourceSurface ?? 'cli',
441
+ resolverVersion: callerSignals.resolverVersion ?? STARTUP_RESOLUTION_RESOLVER_VERSION,
442
+ branchName: callerSignals.branchName ?? branchName,
443
+ worktreeName: callerSignals.worktreeName ?? worktreeName,
444
+ changedPaths: unionedChangedPaths,
445
+ reviewedArtifactRefs: callerSignals.reviewedArtifactRefs ?? refs,
446
+ commitSha: callerSignals.commitSha ?? commitSha,
447
+ });
448
+ const taskText = deriveHandshakeStartupTask(baseSignals.reviewedArtifactRefs ?? [], baseSignals.changedPaths ?? [], baseSignals.taskText);
449
+ const sanitized = sanitizeStartupResolutionSignals({
450
+ ...baseSignals,
451
+ taskText,
452
+ });
453
+ const hasMeaningfulEvidence = Boolean(sanitized.taskText) ||
454
+ (sanitized.changedPaths?.length ?? 0) > 0 ||
455
+ (sanitized.reviewedArtifactRefs?.length ?? 0) > 0 ||
456
+ Boolean(sanitized.explicitScope);
457
+ if (hasMeaningfulEvidence)
458
+ return sanitized;
459
+ // Codex@704: even with no evidence, emit a minimal envelope carrying attribution — {} would
460
+ // drop the whole startup block, losing the loud domain-unresolved signal (spec "Loud Unresolved State", AC #4).
461
+ return sanitizeStartupResolutionSignals({
462
+ sourceSurface: sanitized.sourceSurface ?? 'cli',
463
+ resolverVersion: sanitized.resolverVersion ?? STARTUP_RESOLUTION_RESOLVER_VERSION,
464
+ branchName: sanitized.branchName,
465
+ worktreeName: sanitized.worktreeName,
466
+ commitSha: sanitized.commitSha,
467
+ changeId: sanitized.changeId,
468
+ });
469
+ }
470
+ /** Normalize volatile handshake-only timestamps before comparing generated files — keeps visible
471
+ * timestamps in artifacts while avoiding meaningless rewrites when content is unchanged. */
416
472
  export function normalizeHandshakeContentForComparison(content) {
417
473
  return content
418
474
  .replace(/<!-- auto-generated by pb handshake — [0-9]{4}-[0-9]{2}-[0-9]{2}T[^>]+ -->/g, '<!-- auto-generated by pb handshake — <TIMESTAMP> -->')
419
475
  .replace(/^_Generated: [0-9]{4}-[0-9]{2}-[0-9]{2}T.*_$/gm, '_Generated: <TIMESTAMP>_');
420
476
  }
421
477
  function shouldWriteAdapter(filePath, force) {
422
- if (force)
423
- return true;
478
+ // An absent file at an adapter path is a projection target → materialize it.
424
479
  if (!existsSync(filePath))
425
480
  return true;
426
481
  const content = readFileSync(filePath, 'utf8');
482
+ // No MARKER → user-owned/committed-static (CLAUDE.md, AGENTS.md, Copilot instructions) — never overwritten, not even under --force.
483
+ void force;
427
484
  return content.includes(MARKER);
428
485
  }
429
486
  function normalizeSurfaceName(surface) {
@@ -440,210 +497,9 @@ function surfacePerimeterRoots(surface) {
440
497
  return ['.claude', 'CLAUDE.md'];
441
498
  return [`.${surface}`];
442
499
  }
443
- function modeRank(mode) {
444
- return { off: 0, observe: 1, project: 2, govern: 3 }[mode];
445
- }
446
- function normalizeSetupAuthoringBody(body) {
447
- return body.replace(/\r\n/g, '\n').replace(/\r/g, '\n').trimEnd();
448
- }
449
- function setupAuthoringAssetHash(asset) {
450
- const canonical = {
451
- entryId: asset.entryId,
452
- name: asset.name,
453
- description: asset.description ?? '',
454
- assetKind: asset.assetKind,
455
- triggers: asset.triggers ?? [],
456
- semanticRefs: asset.semanticRefs ?? [],
457
- body: normalizeSetupAuthoringBody(asset.body),
458
- };
459
- return `sha256:${createHash('sha256').update(JSON.stringify(canonical), 'utf8').digest('hex')}`;
460
- }
461
- function parseSetupAuthoringFrontmatter(raw) {
462
- const fmMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
463
- if (!fmMatch) {
464
- const h1 = raw.match(/^# (.+)$/m);
465
- return { name: h1?.[1] ?? '', description: '', body: raw, triggers: [], semanticRefs: [] };
466
- }
467
- const fields = new Map();
468
- const arrayFields = new Map();
469
- const lines = fmMatch[1].split('\n');
470
- let currentArrayKey = null;
471
- let currentArrayValues = [];
472
- for (const line of lines) {
473
- const arrayItemMatch = line.match(/^\s+-\s+(.+)$/);
474
- const keyValueMatch = line.match(/^(\w+):\s*(.*)$/);
475
- if (arrayItemMatch && currentArrayKey) {
476
- currentArrayValues.push(arrayItemMatch[1].trim().replace(/^['"]|['"]$/g, ''));
477
- }
478
- else if (keyValueMatch) {
479
- if (currentArrayKey) {
480
- arrayFields.set(currentArrayKey, currentArrayValues);
481
- currentArrayKey = null;
482
- currentArrayValues = [];
483
- }
484
- const [, key, value] = keyValueMatch;
485
- if (value.trim() === '') {
486
- currentArrayKey = key;
487
- }
488
- else {
489
- fields.set(key, value.trim().replace(/^['"]|['"]$/g, ''));
490
- }
491
- }
492
- }
493
- if (currentArrayKey)
494
- arrayFields.set(currentArrayKey, currentArrayValues);
495
- const body = fmMatch[2];
496
- return {
497
- frontmatterId: fields.get('id'),
498
- name: fields.get('name') ?? body.match(/^# (.+)$/m)?.[1] ?? '',
499
- description: fields.get('description') ?? '',
500
- body,
501
- triggers: arrayFields.get('triggers') ?? [],
502
- semanticRefs: arrayFields.get('semanticRefs') ?? [],
503
- };
504
- }
505
- function deriveSetupAuthoringEntryId(filename, kind) {
506
- const base = basename(filename, '.md');
507
- const snakeCase = base.toUpperCase().replace(/[^A-Z0-9]+/g, '_');
508
- return `SETUP-${kind.toUpperCase()}-${snakeCase}`;
509
- }
510
- function scanSetupAuthoringFiles(productbrainDir) {
511
- const dirs = [
512
- { dir: 'skills', kind: 'skill' },
513
- { dir: 'rules', kind: 'rule' },
514
- { dir: 'hooks', kind: 'hook' },
515
- ];
516
- const items = [];
517
- for (const { dir, kind } of dirs) {
518
- const absDir = join(productbrainDir, dir);
519
- if (!existsSync(absDir))
520
- continue;
521
- for (const file of readdirSync(absDir).filter((f) => f.endsWith('.md'))) {
522
- const filePath = join(absDir, file);
523
- const parsed = parseSetupAuthoringFrontmatter(readFileSync(filePath, 'utf8'));
524
- const fallbackName = basename(file, '.md');
525
- items.push({
526
- filePath,
527
- derivedEntryId: deriveSetupAuthoringEntryId(file, kind),
528
- frontmatterId: parsed.frontmatterId,
529
- name: parsed.name || fallbackName,
530
- description: parsed.description,
531
- body: parsed.body,
532
- assetKind: kind,
533
- triggers: parsed.triggers,
534
- semanticRefs: parsed.semanticRefs,
535
- });
536
- }
537
- }
538
- return items.sort((a, b) => a.filePath.localeCompare(b.filePath));
539
- }
540
- function setupAuthoringDirForKind(kind) {
541
- if (kind === 'skill')
542
- return 'skills';
543
- if (kind === 'rule')
544
- return 'rules';
545
- if (kind === 'hook')
546
- return 'hooks';
547
- return null;
548
- }
549
- function setupAuthoringFilename(name, entryId) {
550
- const base = (name || entryId)
551
- .replace(/[\/\\:*?"<>|]/g, '-')
552
- .replace(/\s+/g, ' ')
553
- .trim();
554
- return `${base || entryId}.md`;
555
- }
556
- function setupAuthoringPath(cwd, asset) {
557
- const dir = setupAuthoringDirForKind(asset.assetKind);
558
- if (!dir)
559
- return null;
560
- return join(cwd, '.productbrain', dir, setupAuthoringFilename(asset.name, asset.entryId));
561
- }
562
- function renderSetupAuthoringFile(asset) {
563
- const lines = [
564
- '---',
565
- `id: ${asset.entryId}`,
566
- `name: ${JSON.stringify(asset.name)}`,
567
- `description: ${JSON.stringify(asset.description ?? '')}`,
568
- `assetKind: ${asset.assetKind}`,
569
- ];
570
- const pushArray = (key, values) => {
571
- if (!values || values.length === 0)
572
- return;
573
- lines.push(`${key}:`);
574
- for (const value of values)
575
- lines.push(` - ${JSON.stringify(value)}`);
576
- };
577
- pushArray('triggers', asset.triggers);
578
- pushArray('semanticRefs', asset.semanticRefs);
579
- lines.push('---', normalizeSetupAuthoringBody(asset.body), '');
580
- return lines.join('\n');
581
- }
582
- function loadAuthoringSyncState(productbrainDir) {
583
- const statePath = join(productbrainDir, '.authoring-sync.json');
584
- if (!existsSync(statePath))
585
- return { version: 1, assets: {} };
586
- try {
587
- const parsed = JSON.parse(readFileSync(statePath, 'utf8'));
588
- if (parsed.version !== 1 || !parsed.assets || typeof parsed.assets !== 'object') {
589
- return { version: 1, assets: {} };
590
- }
591
- return { version: 1, assets: parsed.assets };
592
- }
593
- catch {
594
- return { version: 1, assets: {} };
595
- }
596
- }
597
- function saveAuthoringSyncState(productbrainDir, state) {
598
- const statePath = join(productbrainDir, '.authoring-sync.json');
599
- assertSetupWritePath(statePath, { surfaces: [] });
600
- mkdirSync(productbrainDir, { recursive: true });
601
- writeFileSync(statePath, JSON.stringify(state, null, 2) + '\n');
602
- }
603
- const DRIFT_HASH_TRAILER_REGEX = /^<!--\s*pb-hash:\s*sha256:([0-9a-f]+)\s*-->\s*$/m;
604
- const DRIFT_HASH_TRAILER_STRIP = /^<!--\s*pb-hash:.*-->\s*$/gm;
605
- const DRIFT_TIMESTAMP_STRIP = /^<!--\s*pb-generated-at:.*-->\s*$/gm;
606
- /**
607
- * Classify a single projection-target file into one of the three drift buckets.
608
- *
609
- * Returns `null` when `filePath` does not exist (first-run / unprojected) — the
610
- * write loop treats that as "would-write" and the file is not part of any bucket.
611
- *
612
- * @param filePath Absolute path to the projection file on disk.
613
- * @returns { bucket, expectedHash, actualHash } when the file exists.
614
- * `expectedHash`/`actualHash` are populated only for the
615
- * tampered bucket so the headless refusal payload can include
616
- * them verbatim. For clean / user-owned, both are `''`.
617
- */
618
- export function classifyDriftBucket(filePath) {
619
- if (!existsSync(filePath))
620
- return null;
621
- const content = readFileSync(filePath, 'utf8');
622
- // No auto-gen MARKER → user-owned. Never touch.
623
- if (!content.includes(MARKER)) {
624
- return { bucket: 'user-owned', expectedHash: '', actualHash: '' };
625
- }
626
- // Marker present but no hash trailer → legacy / pre-S0c projection: treat as
627
- // clean (the hash trailer was added in WP-345 S0c). The forked-vs-clean
628
- // semantic falls back to existing shouldWriteAdapter behavior.
629
- const trailerMatch = content.match(DRIFT_HASH_TRAILER_REGEX);
630
- if (!trailerMatch) {
631
- return { bucket: 'pb-managed-clean', expectedHash: '', actualHash: '' };
632
- }
633
- const expectedHash = `sha256:${trailerMatch[1]}`;
634
- // Recompute the actual hash from the body (strip trailer + timestamp, LF, trim).
635
- const normalized = content
636
- .replace(DRIFT_HASH_TRAILER_STRIP, '')
637
- .replace(DRIFT_TIMESTAMP_STRIP, '')
638
- .replace(/\r\n/g, '\n')
639
- .replace(/\r/g, '\n')
640
- .trimEnd();
641
- const actualHash = `sha256:${createHash('sha256').update(normalized, 'utf8').digest('hex')}`;
642
- if (actualHash === expectedHash) {
643
- return { bucket: 'pb-managed-clean', expectedHash, actualHash };
644
- }
645
- return { bucket: 'pb-managed-tampered', expectedHash, actualHash };
646
- }
500
+ // ── WP-421 S3: Three-bucket drift classification (doneWhen #17) — now its own module (STD-2/DEC-1504
501
+ // shrink-only offset). Re-exported so existing imports `from '../commands/handshake.js'` keep working.
502
+ export { classifyDriftBucket };
647
503
  function deduplicateEntries(entries) {
648
504
  const seen = new Set();
649
505
  const result = [];
@@ -657,46 +513,35 @@ function deduplicateEntries(entries) {
657
513
  return result;
658
514
  }
659
515
  /**
660
- * resolveProjectionCollision — WP-379 S5b
661
- *
662
- * Marker-scoped orphan unlink: enumerates target dirs (.cursor/rules/,
663
- * .claude/rules/, .claude/skills/, .codex/skills/); for each file that has
664
- * the auto-gen MARKER whose lowercase-normalized filename does NOT match any
665
- * current active-asset materializedFilename, the file is unlinked.
666
- *
667
- * User-forked files (no MARKER) are never touched, regardless of name.
516
+ * findLeftoverProjections — WP-379 S5b
668
517
  *
669
- * Linux case-collision disambiguation:
670
- * 1. Exact match (lowercase name == any canonical name): survives.
671
- * 2. Case-variant with MARKER (marker file, no exact canonical match): unlinked.
672
- * 3. Ambiguous (zero exact, multiple case-variants with MARKER):
673
- * newest mtime wins; all others are unlinked; a collision TEN is
674
- * appended to the session capture queue (not fired inline).
518
+ * Lists marker-bearing files under .cursor/rules/, .claude/rules/, .claude/skills/, .codex/skills/
519
+ * (plus the nested .cursor/skills/<name>/SKILL.md layout) that look stale: orphan (no canonical
520
+ * asset), stale case/punctuation variant, or a leftover `.dormant` copy. User-owned (no MARKER)
521
+ * files and unselected `allowedTargets` are never reported.
675
522
  *
676
- * Returns a list of unlink results so the caller can log/report them.
523
+ * Round 12: stops once `LEFTOVER_FILES_MAX + 1` matches are found across the flat + merged
524
+ * nested-Cursor scan combined — bounds read/enumerate I/O, not just the reported list.
525
+ * `truncated` says more exist beyond the capped, returned `files`.
677
526
  *
678
- * @param cwd Project root (absolute path).
679
- * @param assetNames The current set of canonical asset names from the server
680
- * (e.g. ["Setup-ProductBrain", "chain-rules"]).
681
- * @param log Progress log function.
682
- * @param logErr Error log function.
527
+ * @param cursorSkillNames Cursor-specific, SKILL-kind-only canon (falls back to `assetNames`).
528
+ * @param exactRelativePaths Round 11: exact write-plan paths (forward-slash), exempted from both
529
+ * checks — covers asset-less generated files and a canonical raw name not already normalized.
683
530
  */
684
- export function resolveProjectionCollision(cwd, assetNames, log, logErr) {
685
- // Target directories by extension suffix.
531
+ export function findLeftoverProjections(cwd, assetNames, allowedTargets, cursorSkillNames, exactRelativePaths) {
686
532
  const TARGET_DIRS_BY_EXT = [
687
- { dir: join(cwd, '.cursor', 'rules'), ext: '.mdc' },
688
- { dir: join(cwd, '.claude', 'rules'), ext: '.md' },
689
- { dir: join(cwd, '.claude', 'skills'), ext: '.md' },
690
- { dir: join(cwd, '.codex', 'skills'), ext: '.md' },
533
+ { dir: join(cwd, '.cursor', 'rules'), ext: '.mdc', surface: 'cursor' },
534
+ { dir: join(cwd, '.claude', 'rules'), ext: '.md', surface: 'claude' },
535
+ { dir: join(cwd, '.claude', 'skills'), ext: '.md', surface: 'claude' },
536
+ { dir: join(cwd, '.codex', 'skills'), ext: '.md', surface: 'codex' },
691
537
  ];
692
- // Build a set of normalized canonical names (without extension) for fast lookup.
693
- // We normalize all asset names to detect case-variant collisions.
694
- // For each asset name we derive the normalized basename (the part before the ext).
695
- // canonicalNormalizedNames: Set<normalized-stem> (lowercase + slug).
696
538
  const canonicalNormalizedStems = new Set(assetNames.map((n) => normalizeMaterializedFilename(n)));
697
- const results = [];
698
- const collisionTens = [];
699
- for (const { dir, ext } of TARGET_DIRS_BY_EXT) {
539
+ const exactPaths = exactRelativePaths ?? new Set();
540
+ const leftovers = [];
541
+ let truncated = false;
542
+ scanLoop: for (const { dir, ext, surface } of TARGET_DIRS_BY_EXT) {
543
+ if (!allowedTargets.has(surface))
544
+ continue;
700
545
  if (!existsSync(dir))
701
546
  continue;
702
547
  let files;
@@ -706,14 +551,10 @@ export function resolveProjectionCollision(cwd, assetNames, log, logErr) {
706
551
  catch {
707
552
  continue; // unreadable dir — skip
708
553
  }
709
- // Group files by their normalized stem.
710
- // normalizedStem → [ { filename, fullPath } ]
711
- const groups = new Map();
712
554
  for (const filename of files) {
713
- if (!filename.endsWith(ext))
555
+ if (!filename.endsWith(ext) && !filename.endsWith(`${ext}.dormant`))
714
556
  continue;
715
557
  const fullPath = join(dir, filename);
716
- // Only operate on files that have the auto-gen MARKER.
717
558
  let content;
718
559
  try {
719
560
  content = readFileSync(fullPath, 'utf8');
@@ -722,115 +563,82 @@ export function resolveProjectionCollision(cwd, assetNames, log, logErr) {
722
563
  continue; // unreadable file — skip
723
564
  }
724
565
  if (!content.includes(MARKER))
725
- continue; // user-forked — never touch
726
- const stem = basename(filename, ext);
566
+ continue; // user-owned — never reported
567
+ const isDormant = filename.endsWith('.dormant');
568
+ // A live file the write plan targets by this exact path is canonical by construction.
569
+ if (!isDormant) {
570
+ const relativePath = relative(cwd, fullPath).split(sep).join('/');
571
+ if (exactPaths.has(relativePath))
572
+ continue;
573
+ }
574
+ const stem = basename(isDormant ? filename.slice(0, -'.dormant'.length) : filename, ext);
727
575
  const normalizedStem = normalizeMaterializedFilename(stem);
728
- const group = groups.get(normalizedStem) ?? [];
729
- group.push({ filename, fullPath });
730
- groups.set(normalizedStem, group);
731
- }
732
- // Evaluate each normalized stem group.
733
- for (const [normalizedStem, members] of groups) {
734
- const isKnownCanonical = canonicalNormalizedStems.has(normalizedStem);
735
- if (!isKnownCanonical) {
736
- // All members of this group are orphans (no canonical asset with this stem).
737
- // Unlink them all — they're stale projections of an asset no longer in the server.
738
- for (const { filename, fullPath } of members) {
739
- try {
740
- unlinkSync(fullPath);
741
- log(`Orphan unlinked: ${fullPath}`);
742
- results.push({ action: 'unlinked', filePath: fullPath, reason: 'orphan-no-canonical-match' });
743
- }
744
- catch (err) {
745
- logErr(`Warning: could not unlink orphan ${fullPath} — ${err instanceof Error ? err.message : String(err)}`);
746
- results.push({ action: 'kept', filePath: fullPath, reason: 'unlink-failed' });
747
- }
748
- }
749
- continue;
576
+ let entry = null;
577
+ if (!canonicalNormalizedStems.has(normalizedStem)) {
578
+ entry = { path: fullPath, reason: 'orphan — no canonical asset matches this name' };
750
579
  }
751
- // The stem IS known canonical. Check for case-collision.
752
- if (members.length === 1) {
753
- // Single file — no collision.
754
- results.push({ action: 'kept', filePath: members[0].fullPath, reason: 'canonical-exact' });
755
- continue;
580
+ else if (isDormant) {
581
+ entry = { path: fullPath, reason: 'leftover .dormant file from an older binary version' };
756
582
  }
757
- // Multiple files with the same normalized stem → case-collision.
758
- // Rule: exact match (filename stem === normalized stem, i.e. already lowercase) wins.
759
- const exactMatches = members.filter(({ filename }) => {
760
- const stem = basename(filename, ext);
761
- return stem === normalizedStem; // lowercase-equal means already normalized
762
- });
763
- if (exactMatches.length === 1) {
764
- // Rule 1: exactly one exact match → keep it, unlink all case-variants.
765
- const keeper = exactMatches[0];
766
- results.push({ action: 'kept', filePath: keeper.fullPath, reason: 'case-exact-match-wins' });
767
- for (const member of members) {
768
- if (member.fullPath === keeper.fullPath)
769
- continue;
770
- try {
771
- unlinkSync(member.fullPath);
772
- log(`Case-variant unlinked: ${member.fullPath} (kept: ${keeper.filename})`);
773
- results.push({ action: 'unlinked', filePath: member.fullPath, reason: 'case-variant-unlinked' });
774
- }
775
- catch (err) {
776
- logErr(`Warning: could not unlink case-variant ${member.fullPath} — ${err instanceof Error ? err.message : String(err)}`);
777
- results.push({ action: 'kept', filePath: member.fullPath, reason: 'unlink-failed' });
778
- }
779
- }
780
- continue;
583
+ else if (stem !== normalizedStem) {
584
+ entry = { path: fullPath, reason: `stale case/punctuation variant — canonical form is "${normalizedStem}${ext}"` };
781
585
  }
782
- // Rule 3: ambiguous — zero exact matches (or multiple exact matches, which
783
- // can't happen on a case-sensitive FS). Newest mtime wins.
784
- // Sort by mtime descending: highest mtime = newest = winner.
785
- const withStats = members.map(({ filename, fullPath }) => {
786
- try {
787
- const { mtimeMs } = statSync(fullPath);
788
- return { filename, fullPath, mtimeMs };
789
- }
790
- catch {
791
- return { filename, fullPath, mtimeMs: 0 };
792
- }
793
- });
794
- withStats.sort((a, b) => b.mtimeMs - a.mtimeMs);
795
- const winner = withStats[0];
796
- log(`Case-collision ambiguous for ${normalizedStem}${ext}: newest mtime wins (${winner.filename})`);
797
- results.push({ action: 'collision-ten', filePath: winner.fullPath, reason: 'ambiguous-newest-mtime-wins' });
798
- const tenMsg = `Handshake case-collision: ambiguous filename for stem "${normalizedStem}${ext}" ` +
799
- `(${members.map((m) => m.filename).join(', ')}). ` +
800
- `Kept newest: ${winner.filename}. Consider renaming to ${normalizedStem}${ext}.`;
801
- collisionTens.push(tenMsg);
802
- for (const member of withStats.slice(1)) {
803
- try {
804
- unlinkSync(member.fullPath);
805
- log(`Case-variant (ambiguous) unlinked: ${member.fullPath}`);
806
- results.push({ action: 'unlinked', filePath: member.fullPath, reason: 'ambiguous-case-variant-unlinked' });
807
- }
808
- catch (err) {
809
- logErr(`Warning: could not unlink ambiguous case-variant ${member.fullPath} — ${err instanceof Error ? err.message : String(err)}`);
810
- results.push({ action: 'kept', filePath: member.fullPath, reason: 'unlink-failed' });
811
- }
586
+ if (!entry)
587
+ continue;
588
+ leftovers.push(entry);
589
+ if (leftovers.length > LEFTOVER_FILES_MAX) {
590
+ truncated = true;
591
+ leftovers.pop();
592
+ break scanLoop;
812
593
  }
813
594
  }
814
595
  }
815
- return { results, collisionTens };
596
+ // Nested Cursor skills — extracted to its own module (STD-2/DEC-1504 shrink-only offset).
597
+ // Skipped once the flat scan already hit the cap; the remaining budget keeps the combined
598
+ // total across both scans stopping at LEFTOVER_FILES_MAX + 1.
599
+ if (!truncated && allowedTargets.has('cursor')) {
600
+ const nested = findLeftoverCursorSkills(cwd, cursorSkillNames ?? assetNames, LEFTOVER_FILES_MAX - leftovers.length);
601
+ leftovers.push(...nested.files);
602
+ truncated = nested.truncated;
603
+ }
604
+ return { files: leftovers, truncated };
605
+ }
606
+ /** Round 13 (Codex P1, security): strips a `user:token@` userinfo segment from an https remote
607
+ * so a credential never reaches JSON output. SSH remotes (`git@host:...`) are untouched — that
608
+ * `git@` is a fixed public username, not a secret. */
609
+ function redactGitRemote(remote) {
610
+ return remote ? remote.replace(/^(https?:\/\/)[^@/]+@/i, '$1') : remote;
611
+ }
612
+ /** Round 13 (Codex P1, security): `pb --json handshake` serialized the report directly — leaking
613
+ * an HTTPS git-remote credential and raw Convex `_id`/`_creationTime` on `matchedEntries` (never
614
+ * went through the shared runner's `stripConvexInternals`). One public shape, both JSON paths. */
615
+ function toPublicJsonReport(report) {
616
+ return stripConvexInternals({ ...report, repo: { ...report.repo, gitRemote: redactGitRemote(report.repo.gitRemote) } });
617
+ }
618
+ /** TASK-554 (RULE-659): getOrientView always serves the briefing's facts; a view without them is a broken contract. */
619
+ function servedBriefing(view) {
620
+ if (view.briefing)
621
+ return view.briefing;
622
+ throw new CLIError('The orient view carried no briefing; getOrientView always serves one.', { code: ErrorCode.INTERNAL, category: 'internal' });
816
623
  }
817
624
  export async function runHandshake(options = {}) {
818
- const config = await getConfigOrGuide(() => runHandshake(options));
625
+ const config = await getConfigOrGuide(async () => { await runHandshake(options); });
819
626
  if (!config)
820
- return;
627
+ return undefined;
821
628
  const cwd = process.cwd();
822
629
  const force = options.force ?? false;
823
630
  const dryRun = options.dryRun ?? false;
824
- // Preview mode: default when neither --apply nor --dry-run is passed.
825
- // --dry-run is kept as a backward-compat alias for preview (same behavior).
631
+ // Preview mode: default when neither --apply nor --dry-run is passed (--dry-run is a backward-compat alias).
826
632
  const preview = !options.apply && !dryRun;
827
633
  const applyMode = options.apply === true && !dryRun;
828
634
  const level = options.level;
635
+ // `quiet` gates the final report write (`--json` alone still prints). `suppressProgress`
636
+ // also silences stdout log() prose in JSON mode. logErr() stays on `quiet` alone (stderr).
829
637
  const quiet = options.quiet ?? false;
830
- const generate = options.generate ?? false;
638
+ const suppressProgress = quiet || isJsonMode();
831
639
  const timestamp = new Date().toISOString();
832
- // Helper: emit progress line only when not quiet (used when handshake is a sub-step)
833
- const log = (msg) => { if (!quiet)
640
+ // Helper: emit progress line only when not suppressed. logErr is gated on `quiet` alone.
641
+ const log = (msg) => { if (!suppressProgress)
834
642
  process.stdout.write(msg + '\n'); };
835
643
  const logErr = (msg) => { if (!quiet)
836
644
  process.stderr.write(msg + '\n'); };
@@ -849,6 +657,21 @@ export async function runHandshake(options = {}) {
849
657
  if (repo.detectedStack.length > 0) {
850
658
  log(`Stack: ${repo.detectedStack.join(', ')}`);
851
659
  }
660
+ const startupSignals = deriveHandshakeStartupSignals(cwd, options.startupSignals ?? {});
661
+ const orientArgs = { tier: 'standard' };
662
+ if (options.invocationPath)
663
+ orientArgs.invocationPath = options.invocationPath;
664
+ if (Object.keys(startupSignals).length > 0) {
665
+ orientArgs.startupSignals = startupSignals;
666
+ if (startupSignals.taskText)
667
+ orientArgs.task = startupSignals.taskText;
668
+ }
669
+ // Scopes the role rule lists this orient call returns to THIS session, not a sibling's.
670
+ const activeSession = readSession();
671
+ if (activeSession?.sessionId)
672
+ orientArgs.sessionId = activeSession.sessionId;
673
+ if (activeSession?.conversationId)
674
+ orientArgs.conversationId = activeSession.conversationId;
852
675
  // 2. Fetch orient view + workspace readiness in parallel (budget max +200ms added latency)
853
676
  log('Fetching workspace context...');
854
677
  let orientView = null;
@@ -856,7 +679,7 @@ export async function runHandshake(options = {}) {
856
679
  try {
857
680
  const workspaceReadinessPromise = kernelCall('chain.workspaceReadiness', {}).catch(() => null);
858
681
  const [orientResult, readinessRaw] = await Promise.all([
859
- kernelCall('chain.getOrientView', { tier: 'standard' }).catch((err) => {
682
+ kernelCall('chain.getOrientView', orientArgs).catch((err) => {
860
683
  logErr(`Warning: could not fetch workspace context — ${err instanceof Error ? err.message : err}`);
861
684
  logErr('Continuing with limited context (Chain search + portable knowledge only).');
862
685
  return null;
@@ -871,7 +694,7 @@ export async function runHandshake(options = {}) {
871
694
  logErr('Continuing with limited context (Chain search + portable knowledge only).');
872
695
  }
873
696
  if (workspaceProfile) {
874
- log(`Workspace profile: stage=${workspaceProfile.stage}, entries=${workspaceProfile.totalEntries}, governance=${workspaceProfile.governanceMode}`);
697
+ log(`Workspace profile: entries=${workspaceProfile.totalEntries}`);
875
698
  }
876
699
  // 3. Build search queries from repo context
877
700
  const searchQueries = [];
@@ -893,9 +716,7 @@ export async function runHandshake(options = {}) {
893
716
  const searchResults = await Promise.all(uniqueQueries.map((q) => kernelCall('chain.searchEntries', { query: q }).catch(() => [])));
894
717
  matchedEntries = deduplicateEntries(searchResults.flat());
895
718
  }
896
- // 5. Read canonical skills & rules — DB-first (WP-345 S0c, TEN-1459), FS fallback.
897
- // Primary: query setup.listAssetsForUser from DB (workspace SSOT).
898
- // Fallback: read from .productbrain/ filesystem (legacy — used when DB is empty or unavailable).
719
+ // 5. Read canonical skills & rules — DB-first (WP-345 S0c, TEN-1459): query setup.listAssetsForUser, FS fallback.
899
720
  const pbDir = join(cwd, '.productbrain');
900
721
  const manifestStatus = readManifestStatus(pbDir);
901
722
  const manifest = manifestStatus.manifest;
@@ -934,323 +755,17 @@ export async function runHandshake(options = {}) {
934
755
  const authorityCanWrite = manifestStatus.mode === 'project' || manifestStatus.mode === 'govern';
935
756
  const authorityPreviewOnly = applyMode && !authorityCanWrite;
936
757
  const writeMode = applyMode && authorityCanWrite;
937
- let dbSkills = [];
938
- let dbRules = [];
939
- let usedDbSource = false;
940
- let dbAssetRows = [];
941
- // WP-379 S4: dormant assets (gate-failed) — their on-disk files get the dormant marker.
942
- let dormantDbAssetRows = [];
943
- // WP-428 S2 (Finding #5): tracks entryIds whose body fetch from storage failed.
944
- // Hoisted here (same scope as dbAssetRows) so both the skills/rules projection loop
945
- // AND the authoring-file projection loop can skip failed assets.
946
- const bodyFetchFailedEntryIds = new Set();
947
- // WP-379 S5b: whether any setup_receipt exists for this workspace (first-run UX gate).
948
- // undefined when server is pre-S5b (treat as unknown → suppress drift TENs conservatively).
949
- let hasAnyReceipt = undefined;
950
- const dbProjectionHashes = new Map();
951
- const syncDriftTensToFire = [];
952
- const deferredAuthoringBaselineEntryIds = new Set();
953
- if (writeMode) {
954
- const authoringItems = scanSetupAuthoringFiles(pbDir);
955
- if (authoringItems.length > 0) {
956
- // WP-428 S2 (Critical #1): ingestSetupAssetsBatch is an internalMutation — it cannot
957
- // call ctx.storage.store(). We now call ingestSetupAssetWithBody (action) per-asset so
958
- // each asset gets bodyStorageId written. This loses intra-batch collision detection;
959
- // canonical-id collision check is now client-side before dispatch.
960
- //
961
- // Client-side collision detection (replaces server-side DEC-954 check in the batch mutation):
962
- const idToPaths = new Map();
963
- for (const item of authoringItems) {
964
- const canonicalId = item.frontmatterId?.trim() || item.derivedEntryId;
965
- const paths = idToPaths.get(canonicalId) ?? [];
966
- paths.push(item.filePath);
967
- idToPaths.set(canonicalId, paths);
968
- }
969
- const conflictingPaths = new Set();
970
- for (const [, paths] of idToPaths) {
971
- if (paths.length > 1) {
972
- for (const p of paths)
973
- conflictingPaths.add(p);
974
- }
975
- }
976
- if (conflictingPaths.size > 0) {
977
- logErr(`Setup authoring import partial: ${conflictingPaths.size} file(s) refused for duplicate setup id. ` +
978
- [...conflictingPaths].join(', '));
979
- }
980
- const itemsToIngest = authoringItems.filter((item) => !conflictingPaths.has(item.filePath));
981
- if (itemsToIngest.length > 0) {
982
- try {
983
- // Parallel uploads — concurrency limit 10 to avoid overwhelming the gateway.
984
- const CONCURRENCY = 10;
985
- const ingestResults = [];
986
- for (let i = 0; i < itemsToIngest.length; i += CONCURRENCY) {
987
- const batch = itemsToIngest.slice(i, i + CONCURRENCY);
988
- const settled = await Promise.allSettled(batch.map(async (item) => {
989
- const result = await kernelCall('setup.ingestSetupAssetWithBody', {
990
- entryId: item.derivedEntryId,
991
- frontmatterId: item.frontmatterId,
992
- name: item.name,
993
- description: item.description,
994
- body: item.body,
995
- assetKind: item.assetKind,
996
- triggers: item.triggers,
997
- semanticRefs: item.semanticRefs,
998
- });
999
- return { filePath: item.filePath, ...result };
1000
- }));
1001
- for (const r of settled) {
1002
- if (r.status === 'fulfilled') {
1003
- ingestResults.push(r.value);
1004
- if (r.value.conflict === 'repo-wins') {
1005
- syncDriftTensToFire.push(`Repo authoring file won setup sync conflict for ${r.value.entryId} at ${r.value.filePath}.`);
1006
- logErr(`Warning: repo authoring file won sync conflict for ${r.value.entryId}; DB edit was overwritten.`);
1007
- }
1008
- }
1009
- else {
1010
- trackEvent('setup.authoring_import.item_failed', { error: r.reason instanceof Error ? r.reason.message : String(r.reason) });
1011
- logErr(`Warning: setup authoring import failed for one asset — ${r.reason instanceof Error ? r.reason.message : String(r.reason)}`);
1012
- }
1013
- }
1014
- }
1015
- if (ingestResults.length > 0) {
1016
- log(`Setup authoring import: ${ingestResults.length} file(s) checked (with bodyStorageId).`);
1017
- }
1018
- }
1019
- catch (err) {
1020
- trackEvent('setup.authoring_import.failed', { error: err instanceof Error ? err.message : String(err) });
1021
- logErr(`Warning: setup authoring import failed — ${err instanceof Error ? err.message : String(err)}`);
1022
- }
1023
- }
1024
- }
1025
- }
1026
- try {
1027
- // WP-379 S4: listAssetsForUser now returns { activeAssets, dormantAssets }.
1028
- // Wire format changed from DbAsset[] to { activeAssets: DbAsset[], dormantAssets: DbAsset[] }.
1029
- // Fall back to empty arrays if the server returns the old flat-array shape (graceful degradation).
1030
- const rawResponse = await kernelCall('setup.listAssetsForUser', {}).catch(() => null);
1031
- let dbAssets = [];
1032
- if (rawResponse !== null) {
1033
- if (Array.isArray(rawResponse)) {
1034
- // Pre-S4 server — treat entire response as active assets with no dormant list.
1035
- dbAssets = rawResponse;
1036
- dormantDbAssetRows = [];
1037
- hasAnyReceipt = undefined; // unknown on legacy servers
1038
- }
1039
- else {
1040
- dbAssets = rawResponse.activeAssets ?? [];
1041
- dormantDbAssetRows = rawResponse.dormantAssets ?? [];
1042
- // WP-379 S5b: extract hasAnyReceipt when provided by the server.
1043
- // undefined means pre-S5b server — we treat as unknown (no receipts assumed).
1044
- hasAnyReceipt = rawResponse.hasAnyReceipt;
1045
- }
1046
- }
1047
- if (dbAssets.length > 0) {
1048
- dbAssetRows = dbAssets;
1049
- // WP-428 S2: body is no longer inline — fetch from storage per-asset when bodyStorageId is set.
1050
- // Projectable assets: non-disabled skill/rule/hook entries. Fetch bodies in parallel (bounded).
1051
- const projectableAssets = dbAssets.filter((a) => !a.disabledByOwner && (a.assetKind === 'skill' || a.assetKind === 'rule' || a.assetKind === 'hook'));
1052
- const assetsNeedingBodyFetch = projectableAssets.filter((a) => a.bodyStorageId);
1053
- const bodyFetchMap = new Map(); // entryId → body
1054
- // WP-428 S2 (Finding #5/#12): track fetch-failed assets so we can skip their projection.
1055
- // Failed entryIds are excluded from dbSkills/dbRules — no empty body written, no lastProjectedHash update.
1056
- // bodyFetchFailedEntryIds is declared at outer scope (also used by authoring-file projection loop).
1057
- if (assetsNeedingBodyFetch.length > 0) {
1058
- log(`Fetching ${assetsNeedingBodyFetch.length} asset body(s) from storage...`);
1059
- const bodyFetchResults = await Promise.allSettled(assetsNeedingBodyFetch.map(async (asset) => {
1060
- const result = await kernelCall('setup.fetchAssetBody', { bodyStorageId: asset.bodyStorageId });
1061
- return { entryId: asset.entryId, name: asset.name, body: result.body };
1062
- }));
1063
- for (let i = 0; i < bodyFetchResults.length; i++) {
1064
- const result = bodyFetchResults[i];
1065
- if (result.status === 'fulfilled') {
1066
- bodyFetchMap.set(result.value.entryId, result.value.body);
1067
- }
1068
- else {
1069
- // WP-428 S2 (Finding #12): include entryId and name in the warning (Finding #5: skip projection).
1070
- const asset = assetsNeedingBodyFetch[i];
1071
- logErr(`Warning: failed to fetch body for ${asset.entryId} (${asset.name}) — ${result.reason instanceof Error ? result.reason.message : String(result.reason)}`);
1072
- bodyFetchFailedEntryIds.add(asset.entryId);
1073
- }
1074
- }
1075
- if (bodyFetchFailedEntryIds.size > 0) {
1076
- logErr(`${bodyFetchFailedEntryIds.size} asset(s) skipped due to body fetch failure: ${[...bodyFetchFailedEntryIds].join(', ')}`);
1077
- }
1078
- }
1079
- // Map DB assets to CanonicalSkill/CanonicalRule shapes
1080
- for (const asset of dbAssets) {
1081
- if (asset.disabledByOwner)
1082
- continue;
1083
- // WP-428 S2 (Finding #5): skip projection for assets whose body fetch failed.
1084
- // Do NOT write empty body to disk and do NOT update lastProjectedHash.
1085
- if (bodyFetchFailedEntryIds.has(asset.entryId))
1086
- continue;
1087
- // WP-428 S2: resolve body — prefer storage-fetched body, fall back to inline body (pre-S2 servers).
1088
- // Fallback: pre-S2 servers (no bodyStorageId) return inline body. Once all servers are S2+, this can be deleted.
1089
- const resolvedBody = bodyFetchMap.get(asset.entryId) ?? asset.body ?? '';
1090
- if (asset.assetKind === 'skill') {
1091
- dbSkills.push({
1092
- name: asset.name,
1093
- description: asset.description,
1094
- triggers: asset.triggers ?? [],
1095
- body: resolvedBody,
1096
- sourcePath: `db:${asset.entryId}`,
1097
- });
1098
- }
1099
- else if (asset.assetKind === 'rule' || asset.assetKind === 'hook') {
1100
- dbRules.push({
1101
- name: asset.name,
1102
- description: asset.description,
1103
- autoApply: false,
1104
- body: resolvedBody,
1105
- sourcePath: `db:${asset.entryId}`,
1106
- });
1107
- }
1108
- }
1109
- usedDbSource = true;
1110
- log(`Setup assets: ${dbSkills.length} skills, ${dbRules.length} rules/hooks from DB (WP-345 DB-first path)`);
1111
- if (dormantDbAssetRows.length > 0) {
1112
- log(`Setup assets: ${dormantDbAssetRows.length} dormant (gate-filtered) asset(s) will be marked on disk`);
1113
- }
1114
- }
1115
- }
1116
- catch {
1117
- // DB source unavailable — silently fall through to FS path
1118
- }
1119
- const allSkills = usedDbSource ? dbSkills : readCanonicalSkills(pbDir);
1120
- const manualRules = usedDbSource ? dbRules : readCanonicalRules(pbDir);
1121
- if (!usedDbSource) {
1122
- log('Setup assets: reading from filesystem (DB source unavailable or empty)');
1123
- }
1124
- // 5a-pre. E4: Resolve semantic refs in DB assets (WP-345, DEC-A, DEC-C, DEC-K)
1125
- // For each asset with semanticRefs[], resolve them via the Convex resolver and
1126
- // replace {{ref:key}} placeholders in the body. Runs in apply mode only (not preview).
1127
- // NG11: PostHog events fire from CLI side only (never inside Convex mutations).
1128
- if (usedDbSource && writeMode) {
1129
- const projectableDbAssets = dbAssetRows.filter((a) => !a.disabledByOwner && (a.assetKind === 'skill' || a.assetKind === 'rule' || a.assetKind === 'hook'));
1130
- const assetsWithRefs = projectableDbAssets.filter((a) => a.semanticRefs && a.semanticRefs.length > 0);
1131
- if (assetsWithRefs.length > 0) {
1132
- log(`Resolving semantic refs for ${assetsWithRefs.length} asset(s)...`);
1133
- // Collect unique ref keys across all assets
1134
- const allRefKeys = [...new Set(assetsWithRefs.flatMap((a) => a.semanticRefs))];
1135
- // Resolve all refs in a single batch call. Shape: SetupRefResolution[]
1136
- // (DEC-767 / WP-354 Build-Order #6 — kind + status discriminator).
1137
- let resolvedRefs = [];
1138
- try {
1139
- resolvedRefs = await kernelCall('setup.resolveSemanticRefs', { semanticRefs: allRefKeys });
1140
- }
1141
- catch (err) {
1142
- trackEvent('setup.refs.resolve_failed', { error: err instanceof Error ? err.message : String(err) });
1143
- logErr(`Warning: could not resolve semantic refs — ${err instanceof Error ? err.message : String(err)}`);
1144
- }
1145
- // Build resolved map: canonicalKey → display name. Only required refs
1146
- // count as unresolved warnings; seed/unknown refs are not gates.
1147
- const resolvedMap = new Map();
1148
- let unresolvedCount = 0;
1149
- for (const result of resolvedRefs) {
1150
- if (result.status === 'resolved' && result.localEntryId) {
1151
- resolvedMap.set(result.ref, result.localEntryId);
1152
- trackEvent('skill.ref.resolved', { ref: result.ref, kind: result.kind });
1153
- }
1154
- else if (result.status === 'unsupported-future') {
1155
- // seed: refs are explicitly future scope per WP-354 Build-Order #6 — not a warning.
1156
- trackEvent('skill.ref.future', { ref: result.ref, kind: result.kind });
1157
- }
1158
- else if (result.required) {
1159
- unresolvedCount++;
1160
- trackEvent('skill.ref.unresolved', { ref: result.ref, kind: result.kind, status: result.status });
1161
- }
1162
- }
1163
- if (unresolvedCount > 0) {
1164
- logErr(`Warning: ${unresolvedCount} required semantic ref(s) could not be resolved.`);
1165
- }
1166
- // Projection must preserve ref tokens as portable machine-readable refs.
1167
- // resolvedMap is only used for validation/telemetry here; generated setup
1168
- // artifacts keep {{ref:domain:...}} / {{ref:entry:...}} intact.
1169
- }
1170
- // Compute projection hash for each projected DB asset (DEC-K).
1171
- // The stored hash is sha256 of the normalized resolved asset body; DB persistence
1172
- // is deferred until the write loop confirms a matching file was emitted.
1173
- // Strip existing hash trailer and timestamp lines, normalize to LF, then hash.
1174
- const HASH_TRAILER_REGEX = /^<!--\s*pb-hash:.*-->\s*$/gm;
1175
- const TIMESTAMP_REGEX = /^<!--\s*pb-generated-at:.*-->\s*$/gm;
1176
- for (const rawAsset of projectableDbAssets) {
1177
- const resolvedAsset = [...dbSkills, ...dbRules].find((a) => a.sourcePath === `db:${rawAsset.entryId}`);
1178
- if (!resolvedAsset)
1179
- continue;
1180
- try {
1181
- // Build the projected body (what will be written to disk)
1182
- const projectedBody = resolvedAsset.body;
1183
- // Normalize: strip existing hash/timestamp trailers, convert to LF
1184
- const normalized = projectedBody
1185
- .replace(HASH_TRAILER_REGEX, '')
1186
- .replace(TIMESTAMP_REGEX, '')
1187
- .replace(/\r\n/g, '\n')
1188
- .replace(/\r/g, '\n')
1189
- .trimEnd();
1190
- // Compute sha256 hash
1191
- const hash = createHash('sha256').update(normalized, 'utf8').digest('hex');
1192
- const hashTrailer = `<!-- pb-hash: sha256:${hash} -->`;
1193
- // Append hash trailer to the projected body
1194
- resolvedAsset.body = `${normalized}\n${hashTrailer}`;
1195
- dbProjectionHashes.set(rawAsset.entryId, {
1196
- hash: `sha256:${hash}`,
1197
- assetKind: rawAsset.assetKind,
1198
- });
1199
- // Drift detection: compare against last known hash
1200
- if (rawAsset.lastProjectedHash && rawAsset.lastProjectedHash !== `sha256:${hash}`) {
1201
- trackEvent('skill.drift.detected', {
1202
- entryId: rawAsset.entryId,
1203
- assetKind: rawAsset.assetKind,
1204
- });
1205
- log(`Drift detected for asset ${rawAsset.entryId} — projecting updated version.`);
1206
- }
1207
- trackEvent('skill.projection.succeeded', {
1208
- entryId: rawAsset.entryId,
1209
- assetKind: rawAsset.assetKind,
1210
- });
1211
- }
1212
- catch (err) {
1213
- trackEvent('skill.projection.failed', {
1214
- entryId: rawAsset.entryId,
1215
- assetKind: rawAsset.assetKind,
1216
- });
1217
- logErr(`Warning: projection failed for ${rawAsset.entryId} — ${err instanceof Error ? err.message : String(err)}`);
1218
- }
1219
- }
1220
- }
1221
- // 5a. Optionally fetch and merge Chain-derived rules (--generate flag)
1222
- let chainRulesStats = null;
1223
- let chainGaps = [];
758
+ // TASK-554 (TEN-4036): materialize governs the coding-tool surfaces (DEC-951). PB's own files
759
+ // under .productbrain/ (context.md, briefing.md, generated/) refresh on every --apply wherever
760
+ // that folder exists; mode `off` means it does not (DEC-955), and then nothing is created.
761
+ const pbOwnedWriteMode = applyMode && manifestStatus.mode !== 'off';
762
+ // Skills and rules are read from the filesystem only (WP-776 S3f, DEC-1771).
763
+ const allSkills = readCanonicalSkills(pbDir);
764
+ const manualRules = readCanonicalRules(pbDir);
765
+ // The --generate flag and its chain-rules generator are gone: the everyone/team/role rule lists
766
+ // (DEC-1774) are the rule-delivery path (context.md, chain.mdc, everyone-rules.md).
1224
767
  let allRules = manualRules;
1225
- if (generate) {
1226
- log('Generating Chain-derived rules...');
1227
- const chainResult = await generateChainRules(kernelCall, manualRules);
1228
- if (chainResult.sentinel) {
1229
- // MCP unavailable — inject sentinel rule and warn
1230
- allRules = [...manualRules, chainResult.sentinel];
1231
- logErr('Warning: Chain MCP unavailable — generated rules are disabled. Sentinel rule injected.');
1232
- }
1233
- else {
1234
- // Merge generated rules after manual rules (manual takes precedence on dedup)
1235
- allRules = [...manualRules, ...chainResult.rules];
1236
- chainRulesStats = chainResult.stats;
1237
- chainGaps = chainResult.gaps;
1238
- const { generatedRules, suppressedByManual, suppressedByZeroEntries } = chainResult.stats;
1239
- log(`Chain-derived rules: ${generatedRules} generated, ${suppressedByManual} suppressed by manual, ${suppressedByZeroEntries} gaps`);
1240
- if (chainGaps.length > 0) {
1241
- log(`Gaps (no matching governance entries): ${chainGaps.join(', ')}`);
1242
- }
1243
- // Diff: compare current state against previous run
1244
- const previousState = loadPreviousState(pbDir);
1245
- const currentState = buildCurrentState(chainResult.rules, chainResult.classified);
1246
- saveHandshakeState(pbDir, chainResult.rules, chainResult.classified);
1247
- const diff = diffHandshakeState(currentState, previousState);
1248
- const diffText = formatDiff(diff);
1249
- log(diffText);
1250
- }
1251
- }
1252
- // 5b. Read personal layer (WP-310 E2) — machine-local rules/skills from .productbrain/.local/
1253
- // Returns [] when the directory is absent. All returned entries have persist: 'local'.
768
+ // 5b. Read personal layer (WP-310 E2) — machine-local rules/skills from .productbrain/.local/, [] if absent, all persist: 'local'.
1254
769
  const personalRules = readPersonalLayer(pbDir);
1255
770
  if (personalRules.length > 0) {
1256
771
  // Name collision detection — warn when a personal rule overrides a team rule
@@ -1273,11 +788,12 @@ export async function runHandshake(options = {}) {
1273
788
  }
1274
789
  allSkills.push(...personalSkills);
1275
790
  }
1276
- // 5d. Load method registry (WP-310 E4) — only when manifest is present.
791
+ // 5d. Load method registry (WP-310 E4) — only when manifest is present. Unrelated to the
792
+ // setup-assets system (WP-329's own "methods" Chain collection, no setup.* coupling) — kept.
1277
793
  let registrySource;
1278
794
  let registryStale;
1279
795
  if (manifest) {
1280
- const registryResult = await loadMethodRegistry(manifest.method_source, kernelCall).catch(() => null);
796
+ const registryResult = await loadMethodRegistry().catch(() => null);
1281
797
  if (registryResult) {
1282
798
  registrySource = registryResult.source;
1283
799
  registryStale = registryResult.stale;
@@ -1288,24 +804,10 @@ export async function runHandshake(options = {}) {
1288
804
  // Compute adoption counts for report (only meaningful when manifest is present)
1289
805
  const adoptedRulesCount = manifest ? adoptionFilteredRules.length : undefined;
1290
806
  const rejectedRulesCount = manifest ? allRules.length - adoptionFilteredRules.length : undefined;
1291
- // Apply level filtering with stage-gating (after adoption filter, before target filtering in write loop)
1292
- // Stage caps the effective level: blank→beginner, seed→intermediate, grounded+→expert.
1293
- // If stage caps below the requested level, log it so the user knows why items were dropped.
1294
- const profileStage = workspaceProfile?.stage;
1295
- const levelFilteredSkills = filterByLevel(adoptionFilteredSkills, level, profileStage);
1296
- const levelFilteredRules = filterByLevel(adoptionFilteredRules, level, profileStage);
1297
- // Log when stage gating changes the effective level
1298
- if (profileStage) {
1299
- const stageCap = STAGE_TO_MAX_LEVEL[profileStage];
1300
- if (stageCap) {
1301
- const requestedIdx = level ? LEVEL_ORDER.indexOf(level) : LEVEL_ORDER.length - 1;
1302
- const capIdx = LEVEL_ORDER.indexOf(stageCap);
1303
- if (capIdx < requestedIdx) {
1304
- log(`Stage "${profileStage}" caps level from ${level || 'expert'} to ${stageCap}`);
1305
- }
1306
- }
1307
- }
1308
- // Apply when-condition filtering (stage-aware, workspace profile + repo context)
807
+ // Level filtering: requested level only (WP-762 C4e-2, DEC-1800 — no more stage cap).
808
+ const levelFilteredSkills = filterByLevel(adoptionFilteredSkills, level);
809
+ const levelFilteredRules = filterByLevel(adoptionFilteredRules, level);
810
+ // Apply when-condition filtering (workspace profile + repo context)
1309
811
  const canonicalSkills = levelFilteredSkills.filter((skill) => {
1310
812
  const result = evaluateConditions(skill.conditions ?? {}, workspaceProfile, repo);
1311
813
  if (dryRun && !result.included) {
@@ -1326,26 +828,23 @@ export async function runHandshake(options = {}) {
1326
828
  if (dryRun && canonicalRules.length > 0) {
1327
829
  log(` INCLUDED rules: ${canonicalRules.map((r) => r.name).join(', ')}`);
1328
830
  }
831
+ const noProjectionAssets = findNoProjectionAssets(canonicalSkills, canonicalRules);
1329
832
  if (canonicalSkills.length > 0 || canonicalRules.length > 0) {
1330
833
  const levelSuffix = level ? ` (level: ${level})` : '';
1331
- const stageSuffix = profileStage ? `, stage: ${profileStage}` : '';
1332
834
  const stackSuffix = repo.detectedStack.length > 0 ? `, stack: [${repo.detectedStack.join(', ')}]` : '';
1333
835
  const totalSkills = allSkills.length;
1334
836
  const totalRules = allRules.length;
1335
- log(`Portable knowledge: ${canonicalSkills.length}/${totalSkills} skills, ${canonicalRules.length}/${totalRules} rules${levelSuffix}${stageSuffix}${stackSuffix}`);
837
+ log(`Portable knowledge: ${canonicalSkills.length}/${totalSkills} skills, ${canonicalRules.length}/${totalRules} rules${levelSuffix}${stackSuffix}`);
1336
838
  }
1337
839
  // 6. Generate file contents
1338
- // Build workspace context for AGENTS.md enrichment (stage, focus, governance, entry count)
840
+ // Build workspace context for AGENTS.md enrichment (focus, entry count) — TASK-435 (C4c) deleted `stage` from it.
1339
841
  const agentsWorkspaceContext = workspaceProfile
1340
842
  ? {
1341
- stage: workspaceProfile.stage,
1342
843
  focus: orientView?.strategicContext?.currentWorkPackage ?? undefined,
1343
- governanceMode: workspaceProfile.governanceMode,
1344
844
  totalEntries: workspaceProfile.totalEntries,
1345
845
  }
1346
846
  : undefined;
1347
- // Collect codex-targeted skills for AGENTS.md skill directory.
1348
- // persist: 'local' entries are included; all projections are now local-only.
847
+ // Collect codex-targeted skills for AGENTS.md skill directory — persist: 'local' entries included (all projections are local-only now).
1349
848
  const agentsCodexSkills = canonicalSkills
1350
849
  .filter((s) => shouldEmitToTarget(s, 'codex'))
1351
850
  .map((s) => ({
@@ -1375,15 +874,27 @@ export async function runHandshake(options = {}) {
1375
874
  skills: copilotSkills.length > 0 ? copilotSkills : undefined,
1376
875
  rules: copilotRules.length > 0 ? copilotRules : undefined,
1377
876
  };
1378
- const contextContent = orientView ? generateContextMd(orientView, repo, timestamp, workspaceProfile?.stage) : null;
877
+ // TASK-554 (WP-777, DEC-1888): one workspace briefing (spine and the Everyone rule list, from
878
+ // the kernel builder) feeds context.md, everyone-rules.md and chain.mdc. `null` means the orient
879
+ // fetch failed: the two briefing files are not written (and a stale copy is removed in apply
880
+ // mode below), and chain.mdc says the briefing is unavailable.
881
+ const workspaceBriefingLines = orientView ? formatWorkspaceBriefingLines(servedBriefing(orientView), orientView.ruleLists) : null;
882
+ const contextContent = orientView && workspaceBriefingLines ? generateContextMd(orientView, workspaceBriefingLines, repo, timestamp) : null;
883
+ const everyoneRulesContent = workspaceBriefingLines ? generateEveryoneRulesMd(workspaceBriefingLines, timestamp) : null;
1379
884
  const briefingContent = generateBriefingMd(matchedEntries, repo, uniqueQueries, timestamp);
1380
885
  const agentsContent = generateAgentsMd(timestamp, {
1381
886
  workspaceContext: agentsWorkspaceContext,
1382
887
  skills: agentsCodexSkills.length > 0 ? agentsCodexSkills : undefined,
1383
888
  });
1384
889
  const claudeContent = generateClaudeMd(timestamp);
1385
- const cursorContent = generateCursorMdc(timestamp);
890
+ const cursorContent = generateCursorMdc(timestamp, workspaceBriefingLines);
1386
891
  const copilotContent = generateCopilotMd(timestamp, copilotOptions);
892
+ // DEC-1343: one committed .github/instructions/<slug>.instructions.md per copilot rule with applyTo; repo-wide rules stay above.
893
+ const copilotInstructionFiles = generateCopilotInstructionFiles(canonicalRules
894
+ .filter((r) => shouldEmitToTarget(r, 'copilot'))
895
+ // `.github/instructions/` is COMMITTED — never project a machine-local (persist: 'local') rule into it.
896
+ .filter((r) => r.persist !== 'local')
897
+ .map((r) => ({ name: r.name, body: r.body, applyTo: r.applyTo, sourcePath: r.sourcePath })), timestamp);
1387
898
  const boundaryEnforcementMode = getBoundaryEnforcementMode(manifest);
1388
899
  const boundaryManifestContent = boundaryEnforcementMode === 'advisory'
1389
900
  ? null
@@ -1392,124 +903,30 @@ export async function runHandshake(options = {}) {
1392
903
  const filesWritten = [];
1393
904
  const filesSkipped = [];
1394
905
  const previewPlan = [];
1395
- if (writeMode && usedDbSource) {
1396
- const authoringSyncState = loadAuthoringSyncState(pbDir);
1397
- let authoringSyncStateChanged = false;
1398
- const personalAssets = dbAssetRows.filter((asset) => asset.scope === 'personal' &&
1399
- !asset.disabledByOwner &&
1400
- (asset.assetKind === 'skill' || asset.assetKind === 'rule' || asset.assetKind === 'hook'));
1401
- for (const asset of personalAssets) {
1402
- // WP-428 S2 (Finding #5): skip projection for assets whose body fetch failed.
1403
- // Do NOT write the authoring file with empty body, do NOT update lastProjectedHash.
1404
- if (bodyFetchFailedEntryIds.has(asset.entryId))
1405
- continue;
1406
- const authoringPath = setupAuthoringPath(cwd, asset);
1407
- if (!authoringPath)
1408
- continue;
1409
- const relativeAuthoringPath = authoringPath.replace(cwd + '/', '');
1410
- const bodyHash = setupAuthoringAssetHash(asset);
1411
- const authoringExists = existsSync(authoringPath);
1412
- const tracked = authoringSyncState.assets[asset.entryId];
1413
- const trackedHere = tracked?.path === relativeAuthoringPath;
1414
- const trackedMatchesServer = Boolean(trackedHere && asset.lastProjectedHash && tracked?.hash === asset.lastProjectedHash);
1415
- if (!authoringExists && asset.lastProjectedHash && trackedHere && trackedMatchesServer) {
1416
- try {
1417
- const dormantResult = await kernelCall('setup.markPersonalSetupAssetDormantFromSync', { entryId: asset.entryId, expectedLastProjectedHash: tracked.hash });
1418
- if (dormantResult.action === 'conflict') {
1419
- syncDriftTensToFire.push(`Repo authoring deletion skipped for ${asset.entryId}; server baseline changed during sync, so writeback was deferred until the next DB read.`);
1420
- logErr(`Warning: authoring deletion for ${asset.entryId} was not applied because the DB baseline changed during sync.`);
1421
- deferredAuthoringBaselineEntryIds.add(asset.entryId);
1422
- continue;
1423
- }
1424
- else {
1425
- syncDriftTensToFire.push(`Repo authoring file was deleted for ${asset.entryId}; caller-owned personal setup asset marked dormant.`);
1426
- log(`Setup authoring deletion: ${asset.entryId} marked dormant.`);
1427
- delete authoringSyncState.assets[asset.entryId];
1428
- authoringSyncStateChanged = true;
1429
- continue;
1430
- }
1431
- }
1432
- catch (err) {
1433
- logErr(`Warning: could not mark ${asset.entryId} dormant after authoring deletion — ${err instanceof Error ? err.message : String(err)}`);
1434
- continue;
1435
- }
1436
- }
1437
- else if (!authoringExists && asset.lastProjectedHash && trackedHere) {
1438
- syncDriftTensToFire.push(`Repo authoring deletion skipped for ${asset.entryId}; local sync baseline is stale, so DB writeback wins.`);
1439
- logErr(`Warning: authoring deletion for ${asset.entryId} was not applied because the DB baseline changed.`);
1440
- }
1441
- const nextAuthoringContent = renderSetupAuthoringFile(asset);
1442
- if (authoringExists) {
1443
- const parsed = parseSetupAuthoringFrontmatter(readFileSync(authoringPath, 'utf8'));
1444
- const fileHash = setupAuthoringAssetHash({
1445
- entryId: parsed.frontmatterId?.trim() || asset.entryId,
1446
- name: parsed.name || asset.name,
1447
- description: parsed.description,
1448
- body: parsed.body,
1449
- assetKind: asset.assetKind,
1450
- triggers: parsed.triggers,
1451
- semanticRefs: parsed.semanticRefs,
1452
- });
1453
- if (fileHash === bodyHash) {
1454
- if (asset.lastProjectedHash !== bodyHash) {
1455
- await kernelCall('setup.updateLastProjectedHash', {
1456
- entryId: asset.entryId,
1457
- hash: bodyHash,
1458
- }).catch(() => null);
1459
- }
1460
- authoringSyncState.assets[asset.entryId] = { path: relativeAuthoringPath, hash: bodyHash };
1461
- authoringSyncStateChanged = true;
1462
- continue;
1463
- }
1464
- if (!asset.lastProjectedHash) {
1465
- syncDriftTensToFire.push(`Repo authoring file differs from DB for ${asset.entryId} at ${authoringPath} with no shared baseline; DB writeback skipped.`);
1466
- logErr(`Warning: setup authoring drift for ${asset.entryId}; DB writeback skipped because no shared baseline exists.`);
1467
- continue;
1468
- }
1469
- if (fileHash !== asset.lastProjectedHash &&
1470
- bodyHash !== asset.lastProjectedHash) {
1471
- syncDriftTensToFire.push(`Repo authoring file won setup sync conflict for ${asset.entryId} at ${authoringPath}.`);
1472
- logErr(`Warning: repo authoring file won sync conflict for ${asset.entryId}; DB writeback skipped.`);
1473
- continue;
1474
- }
1475
- if (fileHash !== asset.lastProjectedHash) {
1476
- syncDriftTensToFire.push(`Repo authoring file differs from DB baseline for ${asset.entryId} at ${authoringPath}; DB writeback skipped.`);
1477
- logErr(`Warning: setup authoring drift for ${asset.entryId}; DB writeback skipped.`);
1478
- continue;
1479
- }
1480
- }
1481
- try {
1482
- assertSetupWritePath(authoringPath, perimeterManifest);
1483
- mkdirSync(dirname(authoringPath), { recursive: true });
1484
- writeFileSync(authoringPath, nextAuthoringContent);
1485
- filesWritten.push(relativeAuthoringPath);
1486
- await kernelCall('setup.updateLastProjectedHash', {
1487
- entryId: asset.entryId,
1488
- hash: bodyHash,
1489
- }).catch(() => null);
1490
- authoringSyncState.assets[asset.entryId] = { path: relativeAuthoringPath, hash: bodyHash };
1491
- authoringSyncStateChanged = true;
1492
- }
1493
- catch (err) {
1494
- logErr(`Warning: could not write setup authoring file for ${asset.entryId} — ${err instanceof Error ? err.message : String(err)}`);
1495
- }
1496
- }
1497
- if (authoringSyncStateChanged) {
1498
- try {
1499
- saveAuthoringSyncState(pbDir, authoringSyncState);
1500
- }
1501
- catch (err) {
1502
- logErr(`Warning: could not persist setup authoring sync state — ${err instanceof Error ? err.message : String(err)}`);
1503
- }
1504
- }
1505
- }
1506
906
  const writes = [
1507
907
  ...(contextContent ? [{ path: join(cwd, '.productbrain', 'context.md'), relative: '.productbrain/context.md', content: contextContent, dirs: join(cwd, '.productbrain'), isAdapter: false }] : []),
908
+ ...(everyoneRulesContent
909
+ ? [{
910
+ path: join(cwd, '.productbrain', 'generated', 'everyone-rules.md'),
911
+ relative: '.productbrain/generated/everyone-rules.md',
912
+ content: everyoneRulesContent,
913
+ dirs: join(cwd, '.productbrain', 'generated'),
914
+ isAdapter: false,
915
+ }]
916
+ : []),
1508
917
  { path: join(cwd, '.productbrain', 'briefing.md'), relative: '.productbrain/briefing.md', content: briefingContent, isAdapter: false },
1509
- { path: join(cwd, 'AGENTS.md'), relative: 'AGENTS.md', content: agentsContent, isAdapter: true, target: 'codex' },
1510
- { path: join(cwd, 'CLAUDE.md'), relative: 'CLAUDE.md', content: claudeContent, isAdapter: true, target: 'claude' },
918
+ { path: join(cwd, 'AGENTS.md'), relative: 'AGENTS.md', content: agentsContent, isAdapter: true, target: 'codex', augmentTarget: true },
919
+ { path: join(cwd, 'CLAUDE.md'), relative: 'CLAUDE.md', content: claudeContent, isAdapter: true, target: 'claude', augmentTarget: true },
1511
920
  { path: join(cwd, '.cursor', 'rules', 'chain.mdc'), relative: '.cursor/rules/chain.mdc', content: cursorContent, dirs: join(cwd, '.cursor', 'rules'), isAdapter: true, target: 'cursor' },
1512
921
  { path: join(cwd, '.github', 'copilot-instructions.md'), relative: '.github/copilot-instructions.md', content: copilotContent, dirs: join(cwd, '.github'), isAdapter: true, target: 'copilot' },
922
+ ...copilotInstructionFiles.map((f) => ({
923
+ path: join(cwd, f.relativePath),
924
+ relative: f.relativePath,
925
+ content: f.content,
926
+ dirs: join(cwd, '.github', 'instructions'),
927
+ isAdapter: true,
928
+ target: 'copilot',
929
+ })),
1513
930
  ...(boundaryManifestContent ? [{
1514
931
  path: join(cwd, '.productbrain', 'generated', 'boundaries.json'),
1515
932
  relative: '.productbrain/generated/boundaries.json',
@@ -1575,54 +992,38 @@ export async function runHandshake(options = {}) {
1575
992
  dbAssetEntryId,
1576
993
  });
1577
994
  }
1578
- // Add Claude Code rule copies (filtered by target)
1579
- const claudeProfile = resolveSurfaceProfile('claude');
1580
- for (const rule of canonicalRules) {
1581
- if (!shouldEmitToTarget(rule, 'claude'))
1582
- continue;
1583
- const dbAssetEntryId = rule.sourcePath.startsWith('db:') ? rule.sourcePath.slice(3) : undefined;
1584
- writes.push({
1585
- path: join(cwd, '.claude', 'rules', `${rule.name}.md`),
1586
- relative: `.claude/rules/${rule.name}.md`,
1587
- content: generateClaudeRule(rule, claudeProfile),
1588
- dirs: join(cwd, '.claude', 'rules'),
1589
- isAdapter: true,
1590
- target: 'claude',
1591
- dbAssetEntryId,
1592
- });
1593
- }
1594
- // Add Claude Code skill router (filtered by target)
1595
- const claudeSkills = canonicalSkills.filter((s) => shouldEmitToTarget(s, 'claude'));
1596
- const skillRouterContent = generateClaudeSkillRouter(claudeSkills, claudeProfile);
1597
- if (skillRouterContent) {
1598
- writes.push({
1599
- path: join(cwd, '.claude', 'rules', 'skill-router.md'),
1600
- relative: '.claude/rules/skill-router.md',
1601
- content: skillRouterContent,
1602
- dirs: join(cwd, '.claude', 'rules'),
1603
- isAdapter: true,
1604
- target: 'claude',
1605
- });
1606
- }
1607
- // 7a. WP-379 S5b: Resolve projection collisions before writing.
1608
- // In apply mode, enumerate target dirs and unlink any auto-generated files
1609
- // whose normalized name no longer matches any active asset from the server.
1610
- // This prevents case-variant orphans from accumulating across handshakes.
1611
- // Runs only when we have a DB asset list (usedDbSource) — without a DB source,
1612
- // we can't determine which files are canonical vs. orphan.
1613
- const collisionTensToFire = [];
1614
- if (writeMode && usedDbSource) {
1615
- const activeAssetNames = dbAssetRows
1616
- .filter((a) => !a.disabledByOwner)
1617
- .map((a) => a.name);
1618
- const { collisionTens } = resolveProjectionCollision(cwd, activeAssetNames, log, logErr);
1619
- collisionTensToFire.push(...collisionTens);
995
+ // 7a. WP-379 S5b: find leftover projections (apply mode) — REPORT-ONLY (coordinator ruling, PR
996
+ // #912 round 10), see findLeftoverProjections's own header. WP-776 S3f: gated on writeMode
997
+ // alone now — the DB source (dbQuerySucceeded) is gone, so activeAssetNames comes from the
998
+ // filesystem-sourced allSkills/allRules (which already include the personal layer, merged in
999
+ // above) instead of dbAssetRows.
1000
+ let leftoverFiles = [];
1001
+ let leftoverFilesTruncated = false;
1002
+ // TASK-554 (RULE-659): a failed orient fetch is named in the report, and apply removes stale briefing copies.
1003
+ if (orientView === null) {
1004
+ for (const path of ['.productbrain/context.md', '.productbrain/generated/everyone-rules.md'])
1005
+ filesSkipped.push({ path, reason: 'briefing unavailable — the orient fetch failed' });
1006
+ const stale = pbOwnedWriteMode ? removeStaleBriefingProjections(cwd) : [];
1007
+ if (stale.length > 0)
1008
+ logErr(`Warning: the workspace briefing could not be fetched; removed the stale ${stale.join(', ')}.`);
1620
1009
  }
1621
- // ── WP-436 S3: Vocab projector — fetch workspace vocab context once per handshake ──
1622
- // Source-side (.productbrain/skills/*.md + rules/*.md) stays tokenized.
1623
- // The projector resolves {{vocab:...}} tokens before writing adapter output to disk
1624
- // (.cursor/rules/, .claude/rules/, CLAUDE.md, AGENTS.md, .github/copilot-instructions.md).
1625
- // Fail-open: if vocab fetch fails, skip resolution and write raw token (no breakage).
1010
+ if (writeMode) {
1011
+ retireGeneratedProjections(cwd, log);
1012
+ const activeAssetNames = [
1013
+ ...allSkills.map((s) => s.name),
1014
+ ...allRules.map((r) => r.name),
1015
+ ];
1016
+ // Nested .cursor/skills scan gets its OWN canon: canonicalSkills is SKILL-kind only and
1017
+ // shouldEmitToTarget(_, 'cursor') respects per-skill target routing.
1018
+ const cursorSkillNames = canonicalSkills.filter((s) => shouldEmitToTarget(s, 'cursor')).map((s) => s.name);
1019
+ // Round 11: exempt exact write-plan paths from the leftover scan (see findLeftoverProjections's own doc).
1020
+ const exactRelativePaths = new Set(writes.map((w) => w.relative));
1021
+ const scanResult = findLeftoverProjections(cwd, activeAssetNames, allowedTargets, cursorSkillNames, exactRelativePaths);
1022
+ leftoverFiles = scanResult.files;
1023
+ leftoverFilesTruncated = scanResult.truncated;
1024
+ }
1025
+ // ── WP-436 S3: Vocab projector — fetch workspace vocab context once per handshake. Source-side
1026
+ // stays tokenized; resolves {{vocab:...}} before writing. Fail-open: a failed fetch writes the raw token.
1626
1027
  const handshakeVocabCtx = await getOrFetchVocabCtx(config.apiKey, async () => {
1627
1028
  try {
1628
1029
  const vocab = await kernelCall('chain.getVocabulary', {});
@@ -1638,19 +1039,30 @@ export async function runHandshake(options = {}) {
1638
1039
  return null; // fail-open
1639
1040
  }
1640
1041
  });
1641
- const forkedPaths = [];
1642
- const projectedHashUpdates = new Map();
1042
+ const userOwnedSkipped = [];
1643
1043
  const cleanBucketPaths = [];
1644
1044
  const tamperedBucket = [];
1645
- const recordProjectedHash = (entryId) => {
1646
- if (!applyMode || !entryId)
1647
- return;
1648
- if (deferredAuthoringBaselineEntryIds.has(entryId))
1649
- return;
1650
- const projection = dbProjectionHashes.get(entryId);
1651
- if (projection)
1652
- projectedHashUpdates.set(entryId, projection.hash);
1653
- };
1045
+ // TEN-2155: region augmentation context + symlink dedupe — codexActive gates the AGENTS.md skills-index pointer.
1046
+ const regionCtx = { codexActive: allowedTargets.has('codex') };
1047
+ const malformedRegionPaths = [];
1048
+ // Same inode for two augment targets (e.g. CLAUDE.md symlinked to AGENTS.md): augment only first-seen.
1049
+ const seenAugmentRealpaths = new Set();
1050
+ const augmentTargetSkip = new Set();
1051
+ for (const w of writes) {
1052
+ if (!w.augmentTarget || !w.target || !allowedTargets.has(w.target) || !existsSync(w.path))
1053
+ continue;
1054
+ let real;
1055
+ try {
1056
+ real = realpathSync(w.path);
1057
+ }
1058
+ catch {
1059
+ real = w.path;
1060
+ }
1061
+ if (seenAugmentRealpaths.has(real))
1062
+ augmentTargetSkip.add(w.path);
1063
+ else
1064
+ seenAugmentRealpaths.add(real);
1065
+ }
1654
1066
  for (const w of writes) {
1655
1067
  // Surface filtering: skip adapter writes for targets not in the allowed set
1656
1068
  if (w.target && !allowedTargets.has(w.target)) {
@@ -1659,17 +1071,78 @@ export async function runHandshake(options = {}) {
1659
1071
  previewPlan.push({ path: w.relative, status: 'filtered' });
1660
1072
  continue;
1661
1073
  }
1074
+ // ── TEN-2155: augment user-owned CLAUDE.md / AGENTS.md with a marked PB region — runs ahead
1075
+ // of the legacy MARKER gates; absent/legacy-pb-managed fall through to the legacy path.
1076
+ if (w.augmentTarget) {
1077
+ const projection = REGION_PROJECTIONS[w.target];
1078
+ if (projection && existsSync(w.path)) {
1079
+ if (augmentTargetSkip.has(w.path)) {
1080
+ filesSkipped.push({ path: w.relative, reason: 'symlinked to another augment target — augmented once' });
1081
+ continue;
1082
+ }
1083
+ const disk = readFileSync(w.path, 'utf8');
1084
+ const cls = classifyAdapterFile(disk);
1085
+ if (cls === 'augmentable' || cls === 'region-present') {
1086
+ const eol = detectEol(disk);
1087
+ const region = replaceVocabTokens(projection.build(regionCtx, eol), handshakeVocabCtx);
1088
+ // Defense-in-depth: the composed region (post vocab-token resolution) must itself be a
1089
+ // single well-formed region. v1 content has no vocab tokens so this is a no-op, but it
1090
+ // guards the documented future override/vocab seam from injecting a stray sentinel/MARKER.
1091
+ if (classifyAdapterFile(region) !== 'region-present') {
1092
+ filesSkipped.push({ path: w.relative, reason: 'internal: composed PB region malformed — skipped to protect your file' });
1093
+ if (preview)
1094
+ previewPlan.push({ path: w.relative, status: 'needs-attention' });
1095
+ continue;
1096
+ }
1097
+ const candidate = cls === 'augmentable' ? spliceAppend(disk, region, eol) : spliceReplace(disk, region);
1098
+ if (candidate === disk) {
1099
+ filesSkipped.push({ path: w.relative, reason: 'unchanged' });
1100
+ if (preview)
1101
+ previewPlan.push({ path: w.relative, status: 'unchanged' });
1102
+ continue;
1103
+ }
1104
+ if (preview || dryRun) {
1105
+ filesWritten.push(w.relative + (dryRun ? ' (dry run)' : ''));
1106
+ if (preview)
1107
+ previewPlan.push({ path: w.relative, status: 'would-augment' });
1108
+ continue;
1109
+ }
1110
+ if (authorityPreviewOnly) {
1111
+ // apply + materialize observe/off: honor authority — do NOT write; mirror the legacy
1112
+ // preview-only skip so the report does not falsely list it as written.
1113
+ filesSkipped.push({ path: w.relative, reason: `preview-only (materialize: ${manifestStatus.mode})` });
1114
+ continue;
1115
+ }
1116
+ assertSetupWritePath(w.path, perimeterManifest);
1117
+ writeFileSync(w.path, candidate);
1118
+ filesWritten.push(w.relative);
1119
+ continue;
1120
+ }
1121
+ if (cls === 'malformed') {
1122
+ filesSkipped.push({ path: w.relative, reason: 'malformed PB region — left untouched; fix the pb:region sentinels' });
1123
+ if (preview)
1124
+ previewPlan.push({ path: w.relative, status: 'needs-attention' });
1125
+ malformedRegionPaths.push(w.relative);
1126
+ continue;
1127
+ }
1128
+ // cls 'pb-managed' falls through to legacy re-projection; 'opt-out' (pb:no-augment) falls through to the user-owned skip.
1129
+ }
1130
+ // absent file → fall through to legacy whole-file CREATE.
1131
+ }
1662
1132
  if (w.isAdapter && !shouldWriteAdapter(w.path, force)) {
1663
- filesSkipped.push({ path: w.relative, reason: 'exists without auto-generated marker (use --force to overwrite)' });
1133
+ // User-owned: a file at an adapter path without our auto-gen MARKER is the
1134
+ // user's own file. Leave it untouched — never overwrite, never treat as drift
1135
+ // or log a TEN (TEN-2150). Relayed to the connect screen via userOwnedSkipped.
1136
+ filesSkipped.push({ path: w.relative, reason: 'user-owned — left untouched (pb won\'t overwrite your file)' });
1664
1137
  if (preview) {
1665
- previewPlan.push({ path: w.relative, status: 'forked' });
1138
+ previewPlan.push({ path: w.relative, status: 'user-owned' });
1666
1139
  }
1667
1140
  else {
1668
- forkedPaths.push(w.relative);
1141
+ userOwnedSkipped.push(w.relative);
1669
1142
  }
1670
1143
  continue;
1671
1144
  }
1672
- if (authorityPreviewOnly) {
1145
+ if (w.isAdapter ? authorityPreviewOnly : applyMode && !pbOwnedWriteMode) {
1673
1146
  filesSkipped.push({
1674
1147
  path: w.relative,
1675
1148
  reason: `preview-only (materialize: ${manifestStatus.mode})`,
@@ -1700,12 +1173,8 @@ export async function runHandshake(options = {}) {
1700
1173
  }
1701
1174
  continue;
1702
1175
  }
1703
- // ── WP-421 S3: defer tampered adapter writes (doneWhen #17) ──────────────
1704
- // For adapter projections that already exist on disk, classify into
1705
- // pb-managed-clean / pb-managed-tampered. Tampered = MARKER present +
1706
- // hash trailer mismatches body. Defer (do NOT overwrite); post-loop
1707
- // resolution handles them. --force bypasses the tampered defer (legacy
1708
- // semantic: explicit user opt-in to overwrite).
1176
+ // ── WP-421 S3: defer tampered adapter writes (doneWhen #17) — classify pb-managed-clean vs
1177
+ // pb-managed-tampered, deferred not overwritten; post-loop resolves. --force bypasses the defer.
1709
1178
  if (w.isAdapter && !force) {
1710
1179
  const drift = classifyDriftBucket(w.path);
1711
1180
  if (drift && drift.bucket === 'pb-managed-tampered') {
@@ -1716,7 +1185,6 @@ export async function runHandshake(options = {}) {
1716
1185
  expectedHash: drift.expectedHash,
1717
1186
  actualHash: drift.actualHash,
1718
1187
  dirs: w.dirs,
1719
- dbAssetEntryId: w.dbAssetEntryId,
1720
1188
  });
1721
1189
  // Do NOT write — defer until prompt/refusal resolves the file.
1722
1190
  continue;
@@ -1728,10 +1196,8 @@ export async function runHandshake(options = {}) {
1728
1196
  assertSetupWritePath(w.path, perimeterManifest);
1729
1197
  if (w.dirs)
1730
1198
  mkdirSync(w.dirs, { recursive: true });
1731
- // WP-436 S3: resolve {{vocab:...}} tokens before writing projected adapter files.
1732
- // Source-side (.productbrain/skills/*.md, rules/*.md) stays tokenized.
1733
- // Only adapter projections (cursor/rules, claude/rules, CLAUDE.md, AGENTS.md, etc.) get resolved.
1734
- // Fail-open: if vocabCtx is undefined, replaceVocabTokens falls back to canonicalKey literals.
1199
+ // WP-436 S3: resolve {{vocab:...}} tokens before writing projected adapter files only
1200
+ // (source-side stays tokenized). Fail-open: undefined vocabCtx falls back to canonicalKey literals.
1735
1201
  const resolvedContent = w.isAdapter
1736
1202
  ? replaceVocabTokens(w.content, handshakeVocabCtx)
1737
1203
  : w.content;
@@ -1741,42 +1207,31 @@ export async function runHandshake(options = {}) {
1741
1207
  const currentNormalized = normalizeHandshakeContentForComparison(current);
1742
1208
  if (nextNormalized === currentNormalized) {
1743
1209
  filesSkipped.push({ path: w.relative, reason: 'unchanged' });
1744
- recordProjectedHash(w.dbAssetEntryId);
1745
1210
  continue;
1746
1211
  }
1747
1212
  }
1748
1213
  writeFileSync(w.path, resolvedContent);
1749
1214
  filesWritten.push(w.relative);
1750
- recordProjectedHash(w.dbAssetEntryId);
1751
1215
  }
1752
- if (projectedHashUpdates.size > 0) {
1753
- const updates = [...projectedHashUpdates];
1754
- const results = await Promise.allSettled(updates.map(([entryId, hash]) => kernelCall('setup.updateLastProjectedHash', { entryId, hash })));
1755
- results.forEach((result, index) => {
1756
- if (result.status === 'rejected') {
1757
- const [entryId] = updates[index];
1758
- trackEvent('skill.projection.failed', {
1759
- entryId,
1760
- reason: result.reason instanceof Error ? result.reason.message : String(result.reason),
1761
- });
1762
- }
1216
+ // Runs AFTER the write loop (malformed files were never written, nothing to record). TEN-2155:
1217
+ // non-interactive apply refuses on a malformed region — gated on applyMode per STD-263 vi.
1218
+ if (applyMode && malformedRegionPaths.length > 0 && (options.noPrompt || !process.stdout.isTTY)) {
1219
+ throw new CLIError(`Malformed PB region in: ${malformedRegionPaths.join(', ')}`, {
1220
+ code: ErrorCode.VALIDATION_FAILED,
1221
+ category: 'validation',
1222
+ guidance: 'Fix the `<!-- pb:region:start -->` / `<!-- pb:region:end -->` sentinels (one balanced pair), then re-run `pb handshake`.',
1763
1223
  });
1764
1224
  }
1765
- // ── WP-421 S3: tampered-bucket resolution (doneWhen #17) ────────────────────
1766
- // Apply mode only. Tampered files were DEFERRED in the write loop above;
1767
- // here we either prompt the user (interactive TTY) or refuse (headless).
1768
- //
1769
- // Headless = `--no-prompt` flag OR `process.stdout.isTTY === false`. When
1770
- // headless: enumerate each tampered file to stderr, write a setup_receipt
1771
- // row with kind='transition' (DEC-962) capturing `refusedTamperedFiles[]`,
1772
- // then exit non-zero. NEVER auto-resolve. (#17 + exclusions: edits to
1773
- // projection dirs are detected, NOT silently overwritten.)
1774
- //
1775
- // Interactive: for each tampered file, present adopt-or-revert. Adopt =
1776
- // create a personal-scoped setup_asset draft from the tampered content
1777
- // (see helper below). Revert = re-project canonical content over the
1778
- // tampered file (write w.content to w.path).
1779
- const adoptedTamperedPaths = [];
1225
+ // ── WP-421 S3: tampered-bucket resolution (doneWhen #17), apply mode only — headless (--no-prompt
1226
+ // / non-TTY) refuses, exit non-zero. WP-776 S3d/S3f: the setup-assets system this resolution used
1227
+ // to offer as an "adopt" alternative (capture tampered edits as a personal-scoped draft via
1228
+ // setup.ingestSetupAsset) is deleted, and with it the only OTHER option besides overwriting —
1229
+ // per DEC-1771 (delete, never hide) there is no shim standing in for that capability. Revert
1230
+ // (re-project canonical content) is the only resolution left; this is a real capability loss
1231
+ // for anyone who was relying on "adopt" to preserve hand-edits, named here rather than silently
1232
+ // dropped. The refusal receipt (`setup.recordTamperRefusal`) is deleted along with the rest of
1233
+ // the setup-assets gateway routes — headless mode still refuses and reports, it just no longer
1234
+ // writes an audit row for the refusal.
1780
1235
  const revertedTamperedPaths = [];
1781
1236
  if (writeMode && tamperedBucket.length > 0) {
1782
1237
  const headless = options.noPrompt === true || !process.stdout.isTTY;
@@ -1784,7 +1239,7 @@ export async function runHandshake(options = {}) {
1784
1239
  // ── Headless refusal path (doneWhen #17) ────────────────────────────────
1785
1240
  logErr('');
1786
1241
  logErr(`pb handshake: ${tamperedBucket.length} PB-managed projection file(s) were edited downstream of the auto-gen marker.`);
1787
- logErr('Headless mode (--no-prompt or no TTY) cannot resolve adopt-or-revert — refusing.');
1242
+ logErr('Headless mode (--no-prompt or no TTY) cannot confirm an overwrite — refusing.');
1788
1243
  logErr('');
1789
1244
  const refusedTamperedFiles = tamperedBucket.map((t) => ({
1790
1245
  path: t.relative,
@@ -1798,105 +1253,47 @@ export async function runHandshake(options = {}) {
1798
1253
  }
1799
1254
  logErr('');
1800
1255
  logErr('Re-run interactively to resolve, or use --force to overwrite (data loss).');
1801
- // Write the kind='transition' setup_receipt row. Fail-open on the
1802
- // network/auth side: if the row cannot be written, we still exit non-zero
1803
- // (the audit trail is best-effort; refusal is mandatory).
1804
- try {
1805
- const manifestStatus = readManifestStatus(pbDir);
1806
- await kernelCall('setup.recordTamperRefusal', {
1807
- mode: manifestStatus.mode,
1808
- refusedTamperedFiles,
1809
- });
1810
- trackEvent('setup.transition.refused', {
1811
- fileCount: refusedTamperedFiles.length,
1812
- mode: manifestStatus.mode,
1813
- });
1814
- }
1815
- catch (err) {
1816
- trackEvent('setup.transition.refused.write_failed', {
1817
- error: err instanceof Error ? err.message : String(err),
1818
- });
1819
- logErr(`Warning: could not record transition receipt — ${err instanceof Error ? err.message : String(err)}`);
1820
- }
1821
1256
  // Surface the report counts before exit (visibility for CI logs).
1822
1257
  if (!quiet) {
1823
- process.stdout.write('\n');
1824
- process.stdout.write(formatHandshakeReport({
1258
+ const refusalReport = {
1825
1259
  filesWritten,
1826
1260
  filesSkipped,
1827
1261
  matchedEntries,
1828
1262
  searchQueries: uniqueQueries,
1829
1263
  repo,
1830
1264
  codexWarnings: codexWarnings.length > 0 ? codexWarnings : undefined,
1831
- chainRulesStats: chainRulesStats ?? undefined,
1832
- chainGaps: chainGaps.length > 0 ? chainGaps : undefined,
1833
1265
  adoptedCount: adoptedRulesCount,
1834
1266
  rejectedCount: rejectedRulesCount,
1835
1267
  personalRuleCount: personalRules.length > 0 ? personalRules.length : undefined,
1836
1268
  personalSkillCount: personalSkills.length > 0 ? personalSkills.length : undefined,
1837
1269
  registrySource,
1838
1270
  registryStale,
1839
- driftConflicts: forkedPaths.length > 0 ? forkedPaths : undefined,
1271
+ userOwnedSkipped: userOwnedSkipped.length > 0 ? userOwnedSkipped : undefined,
1840
1272
  managedCleanCount: cleanBucketPaths.length || undefined,
1841
1273
  tamperedFiles: refusedTamperedFiles,
1842
- }) + '\n');
1274
+ leftoverFiles: leftoverFiles.length > 0 ? leftoverFiles : undefined,
1275
+ leftoverFilesTruncated: leftoverFilesTruncated || undefined, noProjectionAssets: noProjectionAssets.length > 0 ? noProjectionAssets : undefined, // same-line combine, shrink-only budget
1276
+ };
1277
+ process.stdout.write('\n');
1278
+ process.stdout.write(isJsonMode() ? JSON.stringify(toPublicJsonReport(refusalReport)) + '\n' : formatHandshakeReport(refusalReport) + '\n');
1843
1279
  }
1844
1280
  // Exit non-zero per #17.
1845
1281
  process.exit(1);
1846
1282
  }
1847
- // ── Interactive path: prompt adopt-or-revert per file ──────────────────────
1283
+ // ── Interactive path: confirm, then revert every tampered file ─────────────
1848
1284
  log('');
1849
1285
  log(`pb handshake: ${tamperedBucket.length} PB-managed projection file(s) were edited downstream of the auto-gen marker.`);
1850
- log('You can ADOPT (capture your edits as a personal-scoped draft) or REVERT (overwrite with canonical content).');
1851
- // Batch yes-to-all / no-to-all when the user has many tampered files.
1852
- // Threshold: 5 (arbitrary; mirrors the typical handshake projection set).
1853
- let batchChoice = null;
1854
- if (tamperedBucket.length >= 5) {
1855
- const useBatch = await promptConfirm({
1856
- message: `Apply the same choice to all ${tamperedBucket.length} tampered files?`,
1857
- initialValue: false,
1858
- });
1859
- if (useBatch) {
1860
- const choice = await promptSelect({
1861
- message: 'Apply to all:',
1862
- options: [
1863
- { value: 'adopt', label: 'Adopt all — capture each as a personal-scoped draft' },
1864
- { value: 'revert', label: 'Revert all — overwrite with canonical content' },
1865
- ],
1866
- });
1867
- batchChoice = choice === 'adopt' ? 'adopt-all' : 'revert-all';
1868
- }
1869
- }
1870
- for (const tamper of tamperedBucket) {
1871
- // Reverse-map the projection path back to the canonical authoring path.
1872
- const reverse = canonicalPathForAnySurface(tamper.relative);
1873
- const canonicalHint = reverse
1874
- ? `Canonical authoring path: ${reverse.canonicalPath}`
1875
- : (() => {
1876
- // Telemetry + fallback message per surfaces/telemetry.ts.
1877
- reportReverseMapMissing({ surface: 'unknown', projectionPath: tamper.relative }, logErr);
1878
- return `Canonical authoring path: ${getReverseMapFallbackMessage()}`;
1879
- })();
1880
- log('');
1881
- log(`Tampered: ${tamper.relative}`);
1882
- log(` expected: ${tamper.expectedHash}`);
1883
- log(` actual: ${tamper.actualHash}`);
1884
- log(` ${canonicalHint}`);
1885
- let action;
1886
- if (batchChoice === 'adopt-all')
1887
- action = 'adopt';
1888
- else if (batchChoice === 'revert-all')
1889
- action = 'revert';
1890
- else {
1891
- action = await promptSelect({
1892
- message: 'Adopt or revert?',
1893
- options: [
1894
- { value: 'adopt', label: 'Adopt — capture this as a personal-scoped setup_asset draft' },
1895
- { value: 'revert', label: 'Revert — overwrite with canonical content' },
1896
- ],
1897
- });
1898
- }
1899
- if (action === 'revert') {
1286
+ log('These will be REVERTED (overwritten with canonical content) — there is no adopt/draft path any more.');
1287
+ const proceed = await promptConfirm({
1288
+ message: `Overwrite ${tamperedBucket.length} tampered file(s) with canonical content?`,
1289
+ initialValue: false,
1290
+ });
1291
+ if (proceed) {
1292
+ for (const tamper of tamperedBucket) {
1293
+ log('');
1294
+ log(`Reverting: ${tamper.relative}`);
1295
+ log(` expected: ${tamper.expectedHash}`);
1296
+ log(` actual: ${tamper.actualHash}`);
1900
1297
  // Re-project canonical content over the tampered file.
1901
1298
  // WP-436 S3: resolve vocab tokens before writing (all tampered files are adapters).
1902
1299
  if (tamper.dirs)
@@ -1904,194 +1301,22 @@ export async function runHandshake(options = {}) {
1904
1301
  assertSetupWritePath(tamper.path, perimeterManifest);
1905
1302
  writeFileSync(tamper.path, replaceVocabTokens(tamper.content, handshakeVocabCtx));
1906
1303
  revertedTamperedPaths.push(tamper.relative);
1907
- recordProjectedHash(tamper.dbAssetEntryId);
1908
- trackEvent('setup.tampered.reverted', { path: tamper.relative });
1909
1304
  }
1910
- else {
1911
- // Adopt: capture the tampered content as a personal-scoped draft.
1912
- // Per DEC-953 sync rules: personal scope = push (no fork required).
1913
- // The mutation is best-effort — if the adopt write fails, the file is
1914
- // kept on disk untouched and a warning is logged. Adopt does NOT
1915
- // revert; it preserves the user's edits AND records them as a draft.
1916
- const draftName = basename(tamper.relative).replace(/\.(md|mdc)$/, '') + ' (adopted)';
1917
- try {
1918
- const tamperedContent = readFileSync(tamper.path, 'utf8');
1919
- const session = readSession();
1920
- const caller = session ? kernelCallWithSession : kernelCall;
1921
- await caller('setup.ingestSetupAsset', {
1922
- entryId: `SETUP-ADOPTED-${Date.now()}-${draftName.replace(/\s+/g, '-')}`,
1923
- name: draftName,
1924
- description: `Adopted from tampered projection at ${tamper.relative} (WP-421 S3).`,
1925
- body: tamperedContent,
1926
- assetKind: tamper.relative.includes('/skills/') ? 'skill' : 'rule',
1927
- triggers: [],
1928
- semanticRefs: [],
1929
- });
1930
- adoptedTamperedPaths.push(tamper.relative);
1931
- trackEvent('setup.tampered.adopted', { path: tamper.relative });
1932
- }
1933
- catch (err) {
1934
- logErr(`Warning: could not adopt ${tamper.relative} as draft — ${err instanceof Error ? err.message : String(err)}`);
1935
- trackEvent('setup.tampered.adopt_failed', {
1936
- path: tamper.relative,
1937
- error: err instanceof Error ? err.message : String(err),
1938
- });
1939
- }
1940
- }
1941
- }
1942
- }
1943
- // 8a. Dormant marker writes (WP-379 S4) — apply mode only.
1944
- // For each dormant asset (gate-filtered by the server), locate any previously-projected
1945
- // on-disk files and append the DORMANT_MARKER trailer. Files are NOT deleted.
1946
- //
1947
- // Drift TEN exclusion: dormant-marked files have the auto-gen MARKER, so
1948
- // shouldWriteAdapter() returns true for them. However, because the asset is dormant,
1949
- // it is NOT in the `writes` array — it was never queued for a fresh write. Therefore,
1950
- // dormant files will never appear in forkedPaths (forkedPaths only catches files that
1951
- // ARE in the writes array but fail shouldWriteAdapter). The dormant marker write is a
1952
- // separate, independent pass that runs BEFORE the drift TEN check — intentionally
1953
- // after the main write loop to avoid interfering with active asset writes.
1954
- //
1955
- // Fail-open: if a dormant marker write fails, log and continue. Never crash the handshake.
1956
- const dormantMarkedPaths = [];
1957
- if (writeMode && dormantDbAssetRows.length > 0) {
1958
- for (const dormantAsset of dormantDbAssetRows) {
1959
- const candidatePaths = deriveDormantFilePaths(dormantAsset, cwd);
1960
- for (const filePath of candidatePaths) {
1961
- try {
1962
- assertSetupWritePath(filePath, perimeterManifest);
1963
- const markerResult = writeDormantMarkerToFile(filePath);
1964
- if (markerResult === 'written') {
1965
- dormantMarkedPaths.push(filePath);
1966
- log(`Dormant marker written: ${filePath}`);
1967
- }
1968
- // 'already-dormant' and 'skipped' are silent no-ops — idempotent.
1969
- }
1970
- catch (err) {
1971
- // Fail-open: dormant marker write is advisory. Log, never throw.
1972
- logErr(`Warning: could not write dormant marker to ${filePath} — ${err instanceof Error ? err.message : String(err)}`);
1973
- }
1974
- }
1975
- }
1976
- }
1977
- // 8. Drift logging — if apply mode encountered forked adapters and a session is active, log a draft TEN.
1978
- // Dormant-marked files are NOT forked — they were intentionally deactivated and have the auto-gen MARKER.
1979
- // They will never appear in forkedPaths because they are excluded from the `writes` array entirely.
1980
- //
1981
- // WP-379 S5b — First-run UX rule:
1982
- // When `hasAnyReceipt` is false OR undefined (unknown / pre-S5b server), drift TENs are suppressed.
1983
- // Rationale: on the first handshake, users may have pre-existing non-marked files from manual
1984
- // setup; we must not flood them with TENs before they've even had one successful materialization.
1985
- // A TEN fires only after setup_receipt.count >= 1 for this workspace.
1986
- //
1987
- // Conservative unknown-treatment: if the server does not provide hasAnyReceipt (old server),
1988
- // we treat it as "no receipt exists" and suppress the TEN. The day-1 experience is more important
1989
- // than catching every early drift case; the TEN will fire on the next run once the server is updated.
1990
- const isFirstRun = hasAnyReceipt !== true; // true when no receipts or unknown
1991
- if (forkedPaths.length > 0) {
1992
- if (isFirstRun) {
1993
- log(`Info: ${forkedPaths.length} adapter(s) skipped (user files without auto-gen marker). ` +
1994
- 'Drift TEN suppressed — first run (no setup receipt yet). Files: ' +
1995
- forkedPaths.join(', '));
1996
1305
  }
1997
1306
  else {
1998
- const session = readSession();
1999
- if (session) {
2000
- const names = forkedPaths.join(', ');
2001
- kernelCallWithSession('chain.createEntry', {
2002
- collectionSlug: 'tensions',
2003
- name: `TEN: handshake drift — ${forkedPaths.length} adapter(s) forked, sync blocked`,
2004
- // Drift audit TENs intentionally stay draft — they need explicit human review,
2005
- // not auto-commit, even in Open mode (mirrors smart-capture.ts recordCommitFailure).
2006
- status: 'draft',
2007
- data: {
2008
- description: `pb handshake --apply encountered forked adapters that blocked sync. Files: ${names}. Use --force to overwrite or resolve drift manually.`,
2009
- },
2010
- sessionId: session.sessionId,
2011
- createdBy: `agent:${session.sessionId}`,
2012
- }).catch(() => { });
2013
- }
2014
- }
2015
- }
2016
- if (syncDriftTensToFire.length > 0) {
2017
- const session = readSession();
2018
- if (session) {
2019
- for (const driftDescription of syncDriftTensToFire) {
2020
- kernelCallWithSession('chain.createEntry', {
2021
- collectionSlug: 'tensions',
2022
- name: 'TEN: setup authoring sync drift — repo wins',
2023
- status: 'draft',
2024
- data: {
2025
- kind: 'drift',
2026
- description: driftDescription,
2027
- },
2028
- sessionId: session.sessionId,
2029
- createdBy: `agent:${session.sessionId}`,
2030
- }).catch(() => { });
2031
- }
2032
- }
2033
- }
2034
- // 8. Case-collision TENs (WP-379 S5b) — fire after the first-run gate.
2035
- // These are distinct from drift TENs: they record ambiguous filename collisions
2036
- // where the "newest mtime wins" heuristic was applied. They fire regardless of
2037
- // first-run status (collision is a data quality issue, not a drift issue).
2038
- if (collisionTensToFire.length > 0) {
2039
- const session = readSession();
2040
- if (session) {
2041
- for (const tenDescription of collisionTensToFire) {
2042
- kernelCallWithSession('chain.createEntry', {
2043
- collectionSlug: 'tensions',
2044
- name: `TEN: handshake case-collision — ambiguous filename resolved by mtime`,
2045
- // Collision audit TENs intentionally stay draft — they need explicit human review,
2046
- // not auto-commit, even in Open mode (mirrors smart-capture.ts recordCommitFailure).
2047
- status: 'draft',
2048
- data: { description: tenDescription },
2049
- sessionId: session.sessionId,
2050
- createdBy: `agent:${session.sessionId}`,
2051
- }).catch(() => { });
2052
- }
2053
- }
2054
- }
2055
- // 8b. Setup receipt — record which assets were materialized (apply mode only)
2056
- // Fail-open: receipt write is advisory, never blocks the handshake.
2057
- if (applyMode) {
2058
- const session = readSession();
2059
- const caller = session ? kernelCallWithSession : kernelCall;
2060
- try {
2061
- const currentState = await caller('setup.getCurrentSetupState', {});
2062
- const fromMode = currentState?.effectiveMode ?? 'observe';
2063
- if (fromMode !== manifestStatus.mode) {
2064
- await caller('setup.recordTransition', {
2065
- fromMode,
2066
- toMode: manifestStatus.mode,
2067
- parseStatus: manifestStatus.parseStatus,
2068
- surfaces: manifestStatus.surfaces,
2069
- lock: manifestStatus.lock,
2070
- });
2071
- if (modeRank(manifestStatus.mode) < modeRank(fromMode)) {
2072
- trackEvent('setup.transition.lowered', { fromMode, toMode: manifestStatus.mode });
2073
- }
2074
- }
2075
- }
2076
- catch (err) {
2077
- trackEvent('setup.transition.write_failed', { error: err instanceof Error ? err.message : String(err) });
2078
- logErr(`Warning: could not record setup transition — ${err instanceof Error ? err.message : String(err)}`);
2079
- }
2080
- }
2081
- if (writeMode) {
2082
- const session = readSession();
2083
- const caller = session ? kernelCallWithSession : kernelCall;
2084
- try {
2085
- const receiptResult = await caller('setup.materializeSetup', {});
2086
- if (receiptResult?.assetCount > 0) {
2087
- log(`Setup receipt: ${receiptResult.assetCount} asset(s) recorded.`);
2088
- }
2089
- }
2090
- catch (err) {
2091
- trackEvent('setup.receipt.write_failed', { error: err instanceof Error ? err.message : String(err) });
2092
- logErr(`Warning: could not write setup receipt — ${err instanceof Error ? err.message : String(err)}`);
1307
+ logErr('Skipped — tampered files left as-is; re-run to resolve.');
1308
+ process.exit(1); // doneWhen #17: never exit 0 with a tampered file unresolved (codex review round 3)
2093
1309
  }
2094
1310
  }
1311
+ // DEC-1690: a dormant (gate-failed) asset is simply not projected — dbAssets already comes
1312
+ // from the server's activeAssets list. The WP-379 S4 / WP-426 E4 on-disk marker/rename/restore
1313
+ // machinery (and its .authoring-sync.json registries) is retired: nothing to reconcile.
1314
+ // 8. User-owned files left untouched are NOT drift (TEN-2150) — a marker-less adapter-path
1315
+ // file is the user's own; handshake never wrote it, so no "sync", no draft TEN, just a benign
1316
+ // "Skipped:" surfaced via report.userOwnedSkipped.
1317
+ // 8. Case-collision and dormant-drift TENs are gone (coordinator ruling, PR #912 round 10) —
1318
+ // they existed only to audit automated deletions that no longer happen; `report.leftoverFiles`
1319
+ // below is the single reporting surface now.
2095
1320
  // 9. Report
2096
1321
  const report = {
2097
1322
  filesWritten,
@@ -2100,8 +1325,6 @@ export async function runHandshake(options = {}) {
2100
1325
  searchQueries: uniqueQueries,
2101
1326
  repo,
2102
1327
  codexWarnings: codexWarnings.length > 0 ? codexWarnings : undefined,
2103
- chainRulesStats: chainRulesStats ?? undefined,
2104
- chainGaps: chainGaps.length > 0 ? chainGaps : undefined,
2105
1328
  adoptedCount: adoptedRulesCount,
2106
1329
  rejectedCount: rejectedRulesCount,
2107
1330
  personalRuleCount: personalRules.length > 0 ? personalRules.length : undefined,
@@ -2110,17 +1333,27 @@ export async function runHandshake(options = {}) {
2110
1333
  registryStale,
2111
1334
  preview: preview ? true : undefined,
2112
1335
  previewPlan: preview && previewPlan.length > 0 ? previewPlan : undefined,
2113
- driftConflicts: forkedPaths.length > 0 ? forkedPaths : undefined,
1336
+ userOwnedSkipped: userOwnedSkipped.length > 0 ? userOwnedSkipped : undefined,
2114
1337
  // WP-421 S3: three-bucket drift report (doneWhen #17). PB-managed-clean is
2115
1338
  // the count of files whose marker + hash matched. Tampered files were
2116
- // resolved (adopted/reverted) above and are reported separately.
1339
+ // resolved (reverted) above and are reported separately. WP-776 S3d/S3f:
1340
+ // adoptedTamperedPaths is gone — "adopt" is no longer an option (see the
1341
+ // tampered-bucket resolution comment above).
2117
1342
  managedCleanCount: cleanBucketPaths.length > 0 ? cleanBucketPaths.length : undefined,
2118
- adoptedTamperedPaths: adoptedTamperedPaths.length > 0 ? adoptedTamperedPaths : undefined,
2119
1343
  revertedTamperedPaths: revertedTamperedPaths.length > 0 ? revertedTamperedPaths : undefined,
1344
+ // REPORT-ONLY leftover-file listing (coordinator ruling, PR #912 round 10) — the human removes these.
1345
+ leftoverFiles: leftoverFiles.length > 0 ? leftoverFiles : undefined,
1346
+ leftoverFilesTruncated: leftoverFilesTruncated || undefined, noProjectionAssets: noProjectionAssets.length > 0 ? noProjectionAssets : undefined, // WP-660 S2 combine
2120
1347
  };
2121
1348
  if (!quiet) {
2122
1349
  process.stdout.write('\n');
2123
- process.stdout.write(formatHandshakeReport(report) + '\n');
1350
+ process.stdout.write(isJsonMode() ? JSON.stringify(toPublicJsonReport(report)) + '\n' : formatHandshakeReport(report) + '\n');
2124
1351
  }
1352
+ // Return the report so non-UI callers (e.g. prepareConnectContext) can surface
1353
+ // skipped/user-owned files without re-deriving the skip logic (TEN-2107).
1354
+ return report;
2125
1355
  }
1356
+ // WP-426 E3/E4: exported test-only surface (not part of the public CLI API). setupAuthoringPath
1357
+ // and loadAuthoringSyncState are gone with the setup-authoring sync machinery (WP-776 S3d/S3f).
1358
+ export const __test = { MARKER };
2126
1359
  //# sourceMappingURL=handshake.js.map