@phyzess/pappra 0.1.0-beta.14 → 0.1.0-beta.19

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 (365) hide show
  1. package/README.md +133 -14
  2. package/assets/integrations/skills/pappra/SKILL.md +56 -7
  3. package/assets/integrations/skills/pappra/references/collaboration.md +646 -0
  4. package/assets/integrations/skills/pappra/references/environment.md +367 -0
  5. package/assets/integrations/skills/pappra/references/hosts.md +20 -0
  6. package/assets/integrations/skills/pappra/references/operations.md +36 -5
  7. package/dist/adapters/pi/recovery-extension.d.ts +65 -0
  8. package/dist/adapters/pi/recovery-extension.js +238 -0
  9. package/dist/adapters/pi/session-transition-extension.d.ts +30 -0
  10. package/dist/adapters/pi/session-transition-extension.js +265 -0
  11. package/dist/app/automatic-handoff-events.d.ts +26 -0
  12. package/dist/app/automatic-handoff-events.js +134 -0
  13. package/dist/app/bounded-file.d.ts +2 -0
  14. package/dist/app/bounded-file.js +2 -0
  15. package/dist/app/capability-evidence/claude.d.ts +37 -0
  16. package/dist/app/capability-evidence/claude.js +206 -0
  17. package/dist/app/capability-evidence/codex.d.ts +35 -0
  18. package/dist/app/capability-evidence/codex.js +193 -0
  19. package/dist/app/capability-evidence/index.d.ts +33 -0
  20. package/dist/app/capability-evidence/index.js +117 -0
  21. package/dist/app/capability-evidence/pi.d.ts +73 -0
  22. package/dist/app/capability-evidence/pi.js +669 -0
  23. package/dist/app/capability-evidence/shared.d.ts +69 -0
  24. package/dist/app/capability-evidence/shared.js +195 -0
  25. package/dist/app/collab-auto-handoff.d.ts +55 -0
  26. package/dist/app/collab-auto-handoff.js +384 -0
  27. package/dist/app/collab-bindings.d.ts +57 -0
  28. package/dist/app/collab-bindings.js +1006 -0
  29. package/dist/app/collab-bootstrap-transport.d.ts +163 -0
  30. package/dist/app/collab-bootstrap-transport.js +769 -0
  31. package/dist/app/collab-bootstrap.d.ts +137 -0
  32. package/dist/app/collab-bootstrap.js +3455 -0
  33. package/dist/app/collab-handoff.d.ts +12 -0
  34. package/dist/app/collab-handoff.js +511 -0
  35. package/dist/app/collab-messages.d.ts +2 -0
  36. package/dist/app/collab-messages.js +2 -0
  37. package/dist/app/collab-notify.d.ts +156 -0
  38. package/dist/app/collab-notify.js +1208 -0
  39. package/dist/app/collab-preflight.d.ts +34 -0
  40. package/dist/app/collab-preflight.js +96 -0
  41. package/dist/app/collab-recovery-executor.d.ts +161 -0
  42. package/dist/app/collab-recovery-executor.js +1153 -0
  43. package/dist/app/collab-recovery-projection.d.ts +103 -0
  44. package/dist/app/collab-recovery-projection.js +659 -0
  45. package/dist/app/collab-recovery.d.ts +25 -0
  46. package/dist/app/collab-recovery.js +429 -0
  47. package/dist/app/collab-resources.d.ts +16 -0
  48. package/dist/app/collab-resources.js +278 -0
  49. package/dist/app/collab-role-events.d.ts +22 -0
  50. package/dist/app/collab-role-events.js +329 -0
  51. package/dist/app/collab-role-orchestration.d.ts +53 -0
  52. package/dist/app/collab-role-orchestration.js +601 -0
  53. package/dist/app/collab-role-plan.d.ts +81 -0
  54. package/dist/app/collab-role-plan.js +504 -0
  55. package/dist/app/collab-role-repair.d.ts +109 -0
  56. package/dist/app/collab-role-repair.js +821 -0
  57. package/dist/app/collab-rollover.d.ts +263 -0
  58. package/dist/app/collab-rollover.js +1112 -0
  59. package/dist/app/collab-route.d.ts +64 -0
  60. package/dist/app/collab-route.js +240 -0
  61. package/dist/app/collab-session-transition-request.d.ts +50 -0
  62. package/dist/app/collab-session-transition-request.js +339 -0
  63. package/dist/app/collab-session-transition-validation.d.ts +19 -0
  64. package/dist/app/collab-session-transition-validation.js +44 -0
  65. package/dist/app/collab-session-transition.d.ts +181 -0
  66. package/dist/app/collab-session-transition.js +2970 -0
  67. package/dist/app/collab-state.d.ts +7 -0
  68. package/dist/app/collab-state.js +162 -0
  69. package/dist/app/collab-task-store.d.ts +22 -0
  70. package/dist/app/collab-task-store.js +204 -0
  71. package/dist/app/collab-work-execution.d.ts +127 -0
  72. package/dist/app/collab-work-execution.js +1027 -0
  73. package/dist/app/collab-work-plan.d.ts +87 -0
  74. package/dist/app/collab-work-plan.js +437 -0
  75. package/dist/app/collaboration.d.ts +8 -2
  76. package/dist/app/collaboration.js +101 -12
  77. package/dist/app/doctor.js +104 -3
  78. package/dist/app/host-mcp.js +34 -8
  79. package/dist/app/host-probe.js +4 -4
  80. package/dist/app/init.d.ts +58 -4
  81. package/dist/app/init.js +768 -155
  82. package/dist/app/managed-pi-bootstrap-admission.d.ts +14 -0
  83. package/dist/app/managed-pi-bootstrap-admission.js +104 -0
  84. package/dist/app/managed-pi-bootstrap-refresh.d.ts +10 -0
  85. package/dist/app/managed-pi-bootstrap-refresh.js +78 -0
  86. package/dist/app/managed-pi-delivery.d.ts +8 -0
  87. package/dist/app/managed-pi-delivery.js +110 -0
  88. package/dist/app/managed-pi-handoff-receiver.d.ts +15 -0
  89. package/dist/app/managed-pi-handoff-receiver.js +263 -0
  90. package/dist/app/managed-pi-handoff-reference.d.ts +3 -0
  91. package/dist/app/managed-pi-handoff-reference.js +60 -0
  92. package/dist/app/managed-pi-herdr.d.ts +21 -0
  93. package/dist/app/managed-pi-herdr.js +185 -0
  94. package/dist/app/managed-pi-initial-admission.d.ts +28 -0
  95. package/dist/app/managed-pi-initial-admission.js +416 -0
  96. package/dist/app/managed-pi-initial-launch.d.ts +5 -0
  97. package/dist/app/managed-pi-initial-launch.js +61 -0
  98. package/dist/app/managed-pi-native-observation.d.ts +36 -0
  99. package/dist/app/managed-pi-native-observation.js +191 -0
  100. package/dist/app/managed-pi-readiness.d.ts +29 -0
  101. package/dist/app/managed-pi-readiness.js +288 -0
  102. package/dist/app/managed-pi-repair-stop.d.ts +21 -0
  103. package/dist/app/managed-pi-repair-stop.js +371 -0
  104. package/dist/app/managed-pi-resume-admission.d.ts +32 -0
  105. package/dist/app/managed-pi-resume-admission.js +618 -0
  106. package/dist/app/managed-pi-retirement.d.ts +28 -0
  107. package/dist/app/managed-pi-retirement.js +112 -0
  108. package/dist/app/managed-pi-sdk-control.d.ts +7 -0
  109. package/dist/app/managed-pi-sdk-control.js +169 -0
  110. package/dist/app/managed-pi-sdk-runtime.d.ts +3 -0
  111. package/dist/app/managed-pi-sdk-runtime.js +483 -0
  112. package/dist/app/managed-pi-source-admission.d.ts +14 -0
  113. package/dist/app/managed-pi-source-admission.js +323 -0
  114. package/dist/app/managed-pi-transition-host.d.ts +36 -0
  115. package/dist/app/managed-pi-transition-host.js +292 -0
  116. package/dist/app/managed-pi.d.ts +54 -0
  117. package/dist/app/managed-pi.js +248 -0
  118. package/dist/app/shell-readiness.d.ts +66 -0
  119. package/dist/app/shell-readiness.js +368 -0
  120. package/dist/app/task-pin.d.ts +2 -23
  121. package/dist/app/task-pin.js +2 -113
  122. package/dist/cli/collaboration-router.d.ts +17 -0
  123. package/dist/cli/collaboration-router.js +604 -0
  124. package/dist/cli/commands/collaboration-binding.d.ts +13 -0
  125. package/dist/cli/commands/collaboration-binding.js +118 -0
  126. package/dist/cli/commands/collaboration-bootstrap.d.ts +10 -0
  127. package/dist/cli/commands/collaboration-bootstrap.js +84 -0
  128. package/dist/cli/commands/collaboration-capabilities.d.ts +13 -0
  129. package/dist/cli/commands/collaboration-capabilities.js +127 -0
  130. package/dist/cli/commands/collaboration-handoff.d.ts +13 -0
  131. package/dist/cli/commands/collaboration-handoff.js +102 -0
  132. package/dist/cli/commands/collaboration-message.d.ts +17 -0
  133. package/dist/cli/commands/collaboration-message.js +177 -0
  134. package/dist/cli/commands/collaboration-plan.d.ts +8 -0
  135. package/dist/cli/commands/collaboration-plan.js +108 -0
  136. package/dist/cli/commands/collaboration-preflight.d.ts +10 -0
  137. package/dist/cli/commands/collaboration-preflight.js +167 -0
  138. package/dist/cli/commands/collaboration-recovery-run.d.ts +46 -0
  139. package/dist/cli/commands/collaboration-recovery-run.js +224 -0
  140. package/dist/cli/commands/collaboration-recovery.d.ts +11 -0
  141. package/dist/cli/commands/collaboration-recovery.js +104 -0
  142. package/dist/cli/commands/collaboration-resources.d.ts +11 -0
  143. package/dist/cli/commands/collaboration-resources.js +96 -0
  144. package/dist/cli/commands/collaboration-role-plan.d.ts +9 -0
  145. package/dist/cli/commands/collaboration-role-plan.js +69 -0
  146. package/dist/cli/commands/collaboration-role-run.d.ts +11 -0
  147. package/dist/cli/commands/collaboration-role-run.js +128 -0
  148. package/dist/cli/commands/collaboration-rollover.d.ts +10 -0
  149. package/dist/cli/commands/collaboration-rollover.js +103 -0
  150. package/dist/cli/commands/collaboration-state.d.ts +10 -0
  151. package/dist/cli/commands/collaboration-state.js +96 -0
  152. package/dist/cli/commands/collaboration-transition.d.ts +10 -0
  153. package/dist/cli/commands/collaboration-transition.js +75 -0
  154. package/dist/cli/commands/collaboration-work-run.d.ts +34 -0
  155. package/dist/cli/commands/collaboration-work-run.js +178 -0
  156. package/dist/cli/commands/collaboration.d.ts +4 -0
  157. package/dist/cli/commands/collaboration.js +39 -4
  158. package/dist/cli/commands/continuity.js +2 -6
  159. package/dist/cli/commands/docs.d.ts +2 -0
  160. package/dist/cli/commands/docs.js +89 -15
  161. package/dist/cli/commands/host.d.ts +7 -1
  162. package/dist/cli/commands/host.js +122 -7
  163. package/dist/cli/commands/init.d.ts +20 -3
  164. package/dist/cli/commands/init.js +897 -232
  165. package/dist/cli/commands/mcp.d.ts +1 -0
  166. package/dist/cli/commands/mcp.js +11 -5
  167. package/dist/cli/commands/repair.d.ts +12 -0
  168. package/dist/cli/commands/repair.js +41 -0
  169. package/dist/cli/commands/runtime.d.ts +1 -1
  170. package/dist/cli/commands/runtime.js +139 -38
  171. package/dist/cli/commands/session.d.ts +7 -0
  172. package/dist/cli/commands/session.js +82 -0
  173. package/dist/cli/commands/task.js +19 -5
  174. package/dist/cli/options.d.ts +806 -0
  175. package/dist/cli/options.js +293 -0
  176. package/dist/cli/run.js +280 -310
  177. package/dist/code/identity.d.ts +7 -0
  178. package/dist/code/identity.js +7 -3
  179. package/dist/code/registration.js +7 -0
  180. package/dist/code/service.d.ts +9 -0
  181. package/dist/code/service.js +16 -3
  182. package/dist/code/text.js +19 -7
  183. package/dist/collab/admission.d.ts +91 -66
  184. package/dist/collab/admission.js +21 -6
  185. package/dist/collab/canonical.d.ts +1 -1
  186. package/dist/collab/canonical.js +44 -3
  187. package/dist/collab/envelope.d.ts +2 -2
  188. package/dist/collab/envelope.js +12 -12
  189. package/dist/collab/first-work.d.ts +3 -0
  190. package/dist/collab/first-work.js +15 -0
  191. package/dist/collab/handoff.d.ts +16 -0
  192. package/dist/collab/handoff.js +39 -5
  193. package/dist/collab/index.d.ts +97 -1
  194. package/dist/collab/index.js +9 -1
  195. package/dist/collab/messages.js +126 -3
  196. package/dist/collab/persisted-messages.d.ts +123 -0
  197. package/dist/collab/persisted-messages.js +496 -0
  198. package/dist/collab/preflight.d.ts +1 -1
  199. package/dist/collab/resources.d.ts +13 -3
  200. package/dist/collab/resources.js +37 -6
  201. package/dist/collab/rollover.d.ts +311 -0
  202. package/dist/collab/rollover.js +1024 -0
  203. package/dist/collab/store.d.ts +1 -0
  204. package/dist/collab/store.js +1 -4
  205. package/dist/collab/types.d.ts +2 -354
  206. package/dist/collab/validation.d.ts +2 -10
  207. package/dist/collab/validation.js +2 -303
  208. package/dist/collab/work-plan.d.ts +105 -0
  209. package/dist/collab/work-plan.js +843 -0
  210. package/dist/continuity/context.d.ts +11 -2
  211. package/dist/continuity/context.js +100 -13
  212. package/dist/continuity/handoff-bundle.d.ts +296 -0
  213. package/dist/continuity/handoff-bundle.js +477 -0
  214. package/dist/continuity/index.d.ts +2 -0
  215. package/dist/continuity/index.js +1 -0
  216. package/dist/continuity/paths.js +10 -2
  217. package/dist/continuity/service.js +91 -15
  218. package/dist/continuity/task-pin.d.ts +24 -0
  219. package/dist/continuity/task-pin.js +590 -0
  220. package/dist/doctor.d.ts +1 -0
  221. package/dist/doctor.js +6 -0
  222. package/dist/experimental/index.d.ts +13 -0
  223. package/dist/experimental/index.js +25 -0
  224. package/dist/experimental/pi.d.ts +4 -0
  225. package/dist/experimental/pi.js +12 -0
  226. package/dist/hosts/claude/native.js +1 -1
  227. package/dist/hosts/codex/native.js +1 -1
  228. package/dist/hosts/codex/protocol.js +1 -1
  229. package/dist/hosts/integration/bootstrap-config.d.ts +58 -0
  230. package/dist/hosts/integration/bootstrap-config.js +254 -0
  231. package/dist/hosts/integration/bundle-export.d.ts +44 -0
  232. package/dist/hosts/integration/bundle-export.js +366 -3
  233. package/dist/hosts/integration/bundle.js +3 -0
  234. package/dist/hosts/integration/hook.js +36 -9
  235. package/dist/hosts/integration/pappra-bootstrap-extension.mjs +80 -0
  236. package/dist/hosts/integration/pappra-extension-runtime.mjs +59 -24631
  237. package/dist/hosts/integration/pappra-hook.mjs +61 -24749
  238. package/dist/hosts/integration/pappra-recovery-extension.mjs +259 -0
  239. package/dist/hosts/integration/pappra-session-transition-extension.mjs +276 -0
  240. package/dist/hosts/integration/pi-bootstrap-extension.d.ts +36 -0
  241. package/dist/hosts/integration/pi-bootstrap-extension.js +101 -0
  242. package/dist/hosts/integration/pi-bootstrap-guard.d.ts +125 -0
  243. package/dist/hosts/integration/pi-bootstrap-guard.js +438 -0
  244. package/dist/hosts/integration/pi-bootstrap-runtime.d.ts +63 -0
  245. package/dist/hosts/integration/pi-bootstrap-runtime.js +223 -0
  246. package/dist/hosts/integration/pi-native-events.d.ts +112 -0
  247. package/dist/hosts/integration/pi-native-events.js +348 -0
  248. package/dist/hosts/integration/pi-rollover-extension.d.ts +166 -0
  249. package/dist/hosts/integration/pi-rollover-extension.js +431 -0
  250. package/dist/hosts/integration/recovery-config.d.ts +48 -0
  251. package/dist/hosts/integration/recovery-config.js +117 -0
  252. package/dist/hosts/integration/service.d.ts +6 -1
  253. package/dist/hosts/integration/service.js +485 -35
  254. package/dist/hosts/integration/support.d.ts +7 -0
  255. package/dist/hosts/integration/support.js +9 -1
  256. package/dist/hosts/integration/templates.d.ts +3 -0
  257. package/dist/hosts/integration/templates.js +26 -3
  258. package/dist/hosts/pi/managed-host-identity.d.ts +2 -0
  259. package/dist/hosts/pi/managed-host-identity.js +40 -0
  260. package/dist/hosts/pi/managed-provider-diagnostics.d.ts +6 -0
  261. package/dist/hosts/pi/managed-provider-diagnostics.js +184 -0
  262. package/dist/hosts/pi/managed-sdk-session.d.ts +335 -0
  263. package/dist/hosts/pi/managed-sdk-session.js +1639 -0
  264. package/dist/hosts/pi/managed-session-extension.d.ts +20 -0
  265. package/dist/hosts/pi/managed-session-extension.js +84 -0
  266. package/dist/hosts/pi/managed-session.d.ts +177 -0
  267. package/dist/hosts/pi/managed-session.js +1557 -0
  268. package/dist/hosts/pi/protocol.js +1 -1
  269. package/dist/hosts/pi/query-result.js +1 -1
  270. package/dist/hosts/pi/resume-capability.d.ts +41 -0
  271. package/dist/hosts/pi/resume-capability.js +33 -0
  272. package/dist/hosts/pi/rpc.d.ts +182 -134
  273. package/dist/hosts/pi/rpc.js +230 -37
  274. package/dist/hosts/pilot.d.ts +90 -67
  275. package/dist/hosts/pilot.js +5 -1
  276. package/dist/hosts/version.d.ts +3 -0
  277. package/dist/hosts/version.js +18 -0
  278. package/dist/index.d.ts +0 -1
  279. package/dist/index.js +0 -1
  280. package/dist/infra/bounded-file.d.ts +19 -0
  281. package/dist/infra/bounded-file.js +66 -0
  282. package/dist/infra/fs.js +10 -2
  283. package/dist/infra/git.d.ts +29 -0
  284. package/dist/infra/git.js +45 -9
  285. package/dist/infra/json-property.d.ts +2 -0
  286. package/dist/infra/json-property.js +69 -0
  287. package/dist/infra/json.d.ts +4 -0
  288. package/dist/infra/json.js +24 -0
  289. package/dist/infra/owned-process-group.js +1 -1
  290. package/dist/infra/private-lock.d.ts +16 -0
  291. package/dist/infra/private-lock.js +148 -0
  292. package/dist/infra/private-state.d.ts +7 -0
  293. package/dist/infra/private-state.js +146 -0
  294. package/dist/infra/process-identity.d.ts +12 -0
  295. package/dist/infra/process-identity.js +142 -0
  296. package/dist/infra/validation.d.ts +5 -0
  297. package/dist/infra/validation.js +15 -0
  298. package/dist/init.d.ts +1 -0
  299. package/dist/init.js +6 -0
  300. package/dist/install/apply.d.ts +9 -1
  301. package/dist/install/apply.js +176 -12
  302. package/dist/install/dependencies.d.ts +38 -0
  303. package/dist/install/dependencies.js +282 -0
  304. package/dist/install/ownership.js +30 -1
  305. package/dist/install/references.d.ts +31 -0
  306. package/dist/install/references.js +208 -0
  307. package/dist/install/repair.d.ts +37 -0
  308. package/dist/install/repair.js +798 -0
  309. package/dist/install/reset-local.d.ts +16 -0
  310. package/dist/install/reset-local.js +304 -0
  311. package/dist/install/rollback.d.ts +3 -0
  312. package/dist/install/rollback.js +9 -3
  313. package/dist/install/runtime.d.ts +10 -6
  314. package/dist/install/runtime.js +299 -59
  315. package/dist/install/source-fingerprint.d.ts +2 -0
  316. package/dist/install/source-fingerprint.js +103 -0
  317. package/dist/knowledge/catalog.d.ts +1 -0
  318. package/dist/knowledge/catalog.js +143 -10
  319. package/dist/knowledge/journal.js +17 -7
  320. package/dist/knowledge/paths.js +2 -1
  321. package/dist/knowledge/refs.js +4 -0
  322. package/dist/knowledge/register-batch.d.ts +4 -0
  323. package/dist/knowledge/register-batch.js +225 -0
  324. package/dist/knowledge/relocate.d.ts +5 -0
  325. package/dist/knowledge/relocate.js +92 -0
  326. package/dist/knowledge/scan.js +103 -47
  327. package/dist/knowledge/service.d.ts +3 -0
  328. package/dist/knowledge/service.js +33 -1
  329. package/dist/knowledge/write.d.ts +4 -1
  330. package/dist/knowledge/write.js +1 -1
  331. package/dist/mcp/server.d.ts +4 -2
  332. package/dist/mcp/server.js +87 -136
  333. package/dist/schemas/collaboration-state-validation.d.ts +6 -0
  334. package/dist/schemas/collaboration-state-validation.js +342 -0
  335. package/dist/schemas/collaboration-state.d.ts +436 -0
  336. package/dist/schemas/collaboration-state.js +1 -0
  337. package/dist/schemas/collaboration.d.ts +335 -0
  338. package/dist/schemas/collaboration.js +272 -0
  339. package/dist/schemas/continuity.d.ts +8 -0
  340. package/dist/schemas/continuity.js +13 -3
  341. package/dist/schemas/doctor.d.ts +1 -0
  342. package/dist/schemas/doctor.js +1 -0
  343. package/dist/schemas/document.d.ts +61 -0
  344. package/dist/schemas/document.js +9 -0
  345. package/dist/schemas/errors.d.ts +1 -0
  346. package/dist/schemas/errors.js +1 -0
  347. package/dist/schemas/host.d.ts +24 -0
  348. package/dist/schemas/host.js +19 -0
  349. package/dist/schemas/install.d.ts +8 -2
  350. package/dist/schemas/install.js +11 -1
  351. package/dist/schemas/managed-pi-execution.d.ts +16 -0
  352. package/dist/schemas/managed-pi-execution.js +2 -0
  353. package/dist/schemas/outcome.d.ts +9 -5
  354. package/dist/workspace/config-file.js +1 -3
  355. package/dist/workspace/documents.js +12 -2
  356. package/dist/workspace/repositories.d.ts +7 -0
  357. package/dist/workspace/repositories.js +14 -5
  358. package/package.json +37 -35
  359. package/skills/pappra/SKILL.md +56 -7
  360. package/skills/pappra/references/collaboration.md +646 -0
  361. package/skills/pappra/references/environment.md +367 -0
  362. package/skills/pappra/references/hosts.md +20 -0
  363. package/skills/pappra/references/operations.md +36 -5
  364. package/dist/app/collab-from.d.ts +0 -35
  365. package/dist/app/collab-from.js +0 -84
@@ -0,0 +1,646 @@
1
+ # Collaboration messages and notification
2
+
3
+ Use this reference when a task needs task-scoped messages between two agent
4
+ sessions. Persisting a message, notifying a recipient, the recipient's ACK, its
5
+ REPORT, and the coordinator's acceptance are five different facts. This surface
6
+ keeps them separate and never infers one from another.
7
+
8
+ ## MCP collaboration preparation
9
+
10
+ The default MCP server is read-only. A trusted host must enable
11
+ `pappra mcp --allow-workspace-writes` at server startup before checkpoint,
12
+ knowledge registration or workspace-private collaboration preparation can write.
13
+ Tool `apply`/`confirm` fields never grant that policy. Runtime installation,
14
+ external engine preparation and process launch require the authorized CLI.
15
+ MCP preparation domains resolve under `.pappra/local/collaboration`, with cwd
16
+ and resources inside the workspace; use the CLI for explicitly authorized
17
+ external domains. The CLI workflow below is independent of MCP write policy.
18
+
19
+ MCP `collab_prepare` uses the same strict `pappra/collaboration-goal/1` as the installed CLI and accepts exactly `{ domainRoot, goal }`:
20
+
21
+ ```json
22
+ {
23
+ "domainRoot": "/absolute/domain",
24
+ "goal": {
25
+ "schema": "pappra/collaboration-goal/1",
26
+ "task_id": "FIJI-123456",
27
+ "subtask_id": "implementation-slice",
28
+ "attempt": 1,
29
+ "phase": "implementation",
30
+ "objective": "Prepare one bounded collaboration slice.",
31
+ "acceptance": ["prepared references verify"],
32
+ "prompt": "Use only the frozen prompt.",
33
+ "roles": ["implementer"],
34
+ "coordinator": {
35
+ "agent_id": "pappra-coordinator",
36
+ "session_id": "coordinator-session",
37
+ "harness": "codex",
38
+ "owner_epoch": 1
39
+ },
40
+ "assignee": {
41
+ "agent_id": "pappra-implement",
42
+ "session_id": "assignee-session",
43
+ "harness": "pi",
44
+ "surface": "cli",
45
+ "configuration_id": "daily-herdr",
46
+ "cwd": "/absolute/assignee/workspace"
47
+ },
48
+ "resources": [{ "path": "/absolute/repository", "access": "write" }],
49
+ "required": { "skills": [], "tools": ["read"] },
50
+ "preferred": { "skills": [], "tools": [] }
51
+ }
52
+ }
53
+ ```
54
+
55
+ The former flat `objective`/`task`/`acceptance`/`resources`/`coordinatorSession`/`assigneeSession`/`harness`/`subtaskId` arguments are rejected before task or claim writes. Migrate by moving those values under `goal` with protocol names (`task_id`, `subtask_id`, snake_case identities and requirements); explicitly supply coordinator `owner_epoch` and assignee `surface`, `configuration_id`, and independent `cwd`. Unknown or mixed legacy fields are errors. Omitted `roles` retains the documented `['implementer']` compatibility default; explicit roles are bounded, unique, and copied to the assignment.
56
+
57
+ Preparation returns the prepared bundle and goal. It does not create a synthesized declared card and does not return the removed `cardPath`/`card` outputs. Supply actual runtime evidence separately by deriving a card from the receiving session and checking it with preflight. Runner metadata maps `pi`/`codex`/`claude` to `pi-cli`/`codex-exec`/`claude-cli`, but the only real live controller here is `pi-rpc` for Pi; `fixture` remains explicit test-only behavior. `collab_start` returns `cli_required` without launching; the user must run `pappra collab run` with confirmation and admitted runtime evidence in the CLI.
58
+
59
+ ## Before you start
60
+
61
+ A task root is `<domain>/tasks/<task-id>` and already contains `task.json`,
62
+ `messages/` and `ledger.jsonl`. `pappra collab prepare` creates it. All message
63
+ commands require the absolute `--task-root`; nothing is discovered from the
64
+ current directory, chat text, or another task.
65
+
66
+ ## Commands
67
+
68
+ ```sh
69
+ # Validate an envelope without writing anything (default is plan-only).
70
+ pappra collab message send --task-root <abs-task-root> \
71
+ --message <abs-envelope.json> --json
72
+
73
+ # Register and apply the message through the existing protocol.
74
+ pappra collab message send --task-root <abs-task-root> \
75
+ --message <abs-envelope.json> --apply --json
76
+
77
+ # Read one registered message and its record entry (read-only).
78
+ pappra collab message read --task-root <abs-task-root> \
79
+ --message-id <id> --json
80
+
81
+ # List the most recent applied messages (read-only, bounded by --limit 1-100).
82
+ pappra collab message list --task-root <abs-task-root> --limit 20 --json
83
+
84
+ # Validate task, message, binding and recipient without querying Herdr.
85
+ pappra collab message notify --task-root <abs-task-root> \
86
+ --message-id <id> --binding <abs-binding.json> --json
87
+
88
+ # Send exactly one pointer-only Herdr prompt for the registered message.
89
+ pappra collab message notify --task-root <abs-task-root> \
90
+ --message-id <id> --binding <abs-binding.json> --apply --json
91
+ ```
92
+
93
+ ```sh
94
+ # Inspect or plan one writer rollover (read-only; there is no apply action).
95
+ pappra collab rollover inspect --task-root <abs-task-root> \
96
+ --request <abs-rollover-request.json> --json
97
+ pappra collab rollover plan --task-root <abs-task-root> \
98
+ --request <abs-rollover-request.json> --json
99
+ ```
100
+
101
+ `send` never notifies and `notify` never changes the task record. A successful
102
+ `notify` means one prompt was submitted to a named Herdr agent; it does not mean
103
+ the recipient read it, consumed it, or accepted the work.
104
+
105
+ ## Envelope
106
+
107
+ Messages use `harness-collab/message/1`; validate them with the same rules the
108
+ protocol already applies (`type`, explicit `from`/`to` identities, required
109
+ `reply_to`/`subtask_id`/`attempt` per type, `body.status` restricted to the
110
+ report statuses). Message ids are single path segments: a letter or digit
111
+ followed by letters, digits, dot, dash or underscore (maximum 128 characters).
112
+
113
+ Protocol behaviour is unchanged:
114
+
115
+ - `ASSIGN` registers or updates the attempt and opens a
116
+ `registered_not_started` uncertainty; it does not launch anything.
117
+ - `ACK` correlates to the assignment and records consumption, not progress.
118
+ - `ASK` is evidence only. It records the question and changes no task state.
119
+ Blocking a clarification remains `BLOCK(kind=clarification)`.
120
+ - `ANSWER` resolves a correlated `needs_input`/clarification attempt back to
121
+ `running`; an uncorrelated ANSWER is recorded without a transition; an ANSWER
122
+ to an approval block is refused (`approval_not_auto_answerable`).
123
+ - `REPORT` is admitted only from the attempt's current assignee; a stale sender's
124
+ report is retained as evidence with an uncertainty and changes nothing.
125
+ - `CANCEL` records intent and keeps claims; `CANCELLED` requires stop evidence.
126
+ - `HANDOFF`, `STATUS`, `STATUS_QUERY` and `BLOCK` keep their existing semantics.
127
+
128
+ ## Binding document
129
+
130
+ A binding is task-local routing metadata, not authority. It maps the exact
131
+ protocol recipient to a named Herdr agent so a notification cannot target a
132
+ focused pane or an unrelated session.
133
+
134
+ ```json
135
+ {
136
+ "schema": "pappra/collab-binding/1",
137
+ "task_id": "FIJI-123456",
138
+ "task_root": "/absolute/domain/tasks/FIJI-123456",
139
+ "channel": "herdr",
140
+ "participants": [
141
+ {
142
+ "agent_id": "pappra-implement",
143
+ "harness": "pi",
144
+ "cwd": "/absolute/workspace",
145
+ "herdr_agent": "pappra-implement",
146
+ "pane_id": "w3:p3",
147
+ "native_session_id": "b4c18851-d297-4f99-9850-9be1a0f9a9a7"
148
+ }
149
+ ]
150
+ }
151
+ ```
152
+
153
+ `native_session_id` may be `null` when the harness exposes no native session.
154
+ Both sender and recipient must be in the binding. The selected sender pane must
155
+ equal the sender binding pane, and live sender/recipient name, pane, harness and
156
+ cwd must match. Routing has two modes:
157
+
158
+ - **current context (default):** requires a nonempty inherited `HERDR_PANE_ID`
159
+ before `herdr pane current --current`; missing context refuses rather than
160
+ resolving through focus, and stale IDs fail visibly.
161
+ - **explicit task-bound (`--caller-pane <id>`):** uses
162
+ `herdr pane current --pane <id>` without changing the environment or focus.
163
+ Stale inherited IDs do not override it.
164
+
165
+ Selecting a pane is routing, not sender authentication or process proof; hosted
166
+ or detached agents are supported through the task-bound binding. Native session
167
+ evidence is compared exactly, not by substring: for Pi (`kind: "path"`) the
168
+ native identity is the final `_<session-id>` segment; a different session in an
169
+ ancestor directory is a mismatch. Sender and recipient sessions are checked even
170
+ when a binding leaves `native_session_id` null. Missing session stays
171
+ `native_session: "unknown"` instead of claiming a match. A moved task or binding
172
+ must be revalidated and re-bound; nothing is relocated automatically.
173
+
174
+ ## Controller-owned native Pi sessions
175
+
176
+ `pappra session plan --config <abs managed-pi.json>` validates a fresh launch
177
+ request. `session start` runs the native Pi TUI in the calling visible terminal
178
+ with its normal daily configuration and an explicit OpenRouter model. The
179
+ request schema is `pappra/managed-pi-session-request/1` with `cwd`, `model` and
180
+ `journalPath`; use an existing private directory for the journal.
181
+
182
+ `session status|fence|stop --config <same-file> --json` uses only that launch's
183
+ private endpoint. Fencing stops terminal ingress; stopping waits for the exact
184
+ owned child. Neither proves complete queues, approvals or external-writer
185
+ quiescence, and automatic handoff/resource transfer remains blocked. Existing
186
+ interactive sessions cannot be adopted. Input journals can contain private
187
+ keystrokes; preserve their private permissions and never replay raw bytes.
188
+
189
+ ## Role-based planning
190
+
191
+ `pappra collab role-plan expand --request <abs role-plan.json> --json`
192
+ expands explicit participants, assignments and disjoint writer scopes into the
193
+ existing work-plan format. Save its `plan` field, then use `collab plan` and
194
+ `collab work-run` with their existing admission and capability requirements.
195
+ The reviewer depends on all writers and waits for coordinator acceptance.
196
+
197
+ `pappra collab role-plan aggregate --request <abs role-plan.json> --task-root <abs> --config <abs expanded-plan.json> --json`
198
+ checks the persisted plan against the request and reads authoritative task
199
+ evidence through the work-plan inspector. Rejected, unknown, missing and pending
200
+ outcomes remain visible. A delivery acknowledgement never becomes acceptance.
201
+ Neither command launches a model, claims resources or creates an assignment.
202
+
203
+ `pappra collab role-run --request <abs role-orchestration.json> [--apply]
204
+ [--watch] --json` advances the plan's recorded role/dependency events. Plan mode
205
+ reads authoritative state with no effects; `--apply` handles one bounded event
206
+ tick, reserves before dispatch and never infers acceptance; `--watch` requires
207
+ `--apply`. Repeated or ambiguous effects are reconciled, and rejected work needs an
208
+ authorized repair attempt. It notifies registered participants only and creates no
209
+ session, assignment or claim of its own.
210
+
211
+ Which roles exist, and how many writers or reviewers run, is the host agent's
212
+ judgment of the actual objective and change surface, not a product default.
213
+ Nothing here infers semantic roles: hooks record bounded lifecycle observations,
214
+ the backend resolves protocol state, and no command launches a model from prose.
215
+
216
+ ## Native capability evidence
217
+
218
+ `pappra collab capabilities derive --harness <pi|codex|claude> --assignment <abs assignment.json> --template <abs card.declared.json> --execution <abs execution.json> [--session <abs pi-session.jsonl> | --events <abs events.jsonl>] [--json]`
219
+ turns saved native evidence into a runtime capability card with the maintained
220
+ Pi, Codex and Claude semantics. It is read-only: deriving writes no file, starts
221
+ no process, spends no model turn and dispatches nothing. Pi requires `--session`;
222
+ Codex and Claude require `--events`; wrong-host, duplicate and unknown flags are
223
+ rejected. Exit 0 derived, 1 needs_input, 2 invalid request. JSON uses
224
+ `pappra/collaboration-capabilities/1`.
225
+
226
+ Assignment and template files are bounded at 1 MiB, native evidence at 16 MiB;
227
+ all paths must be absolute. Final symlinks, FIFOs and special files are refused
228
+ without blocking, with descriptor-level checks. Diagnostics never include
229
+ evidence content.
230
+
231
+ - **Pi:** tools need correlated successful results; a skill is verified only by a
232
+ successful read of its `SKILL.md`. Observation time is the session's own last
233
+ usable timestamp; incomplete results or an indeterminate `toolUse` turn end are
234
+ refused.
235
+ - **Codex:** only explicit item-to-tool mappings can promote tools; skills stay
236
+ unknown because `exec --json` does not report invocation. Unknown rows/items
237
+ fail closed.
238
+ - **Claude:** discovery/bootstrap may use only `Read` and `Skill`; verified skills
239
+ require the injected base directory to match the fingerprinted source.
240
+
241
+ Old evidence never becomes fresh and a fixture shape is not live-version proof.
242
+ The card remains a claim from the supplied evidence; preflight still checks it
243
+ separately and no authentication, ownership, admission or launch is implied.
244
+
245
+ For an interactive Pi session that is still open, replace `--execution <file>`
246
+ with `--live`. This derives the standard card directly from a settled saved
247
+ session, without fabricating a process-exit receipt or manually normalizing a
248
+ model-written card. Pending tool results, a trailing user message, a non-`stop`
249
+ assistant result or a later model change refuse derivation. Metadata appends do
250
+ not refresh the observation timestamp. This is a historical snapshot of observed
251
+ successful tools and skill reads, not proof of current tool registration, live
252
+ process state, queue contents, approvals or ownership.
253
+
254
+ ```nu
255
+ let derived = (^pappra collab capabilities derive --harness pi --assignment /abs/assignment.json --template /abs/card.declared.json --live --session /abs/session.jsonl --json | from json)
256
+ if $derived.status != 'derived' { error make {msg: $"derive refused: ($derived.status)"} }
257
+ $derived.card | to json | save --raw /abs/task/card.runtime.json
258
+ ```
259
+
260
+ ```nu
261
+ let derived = (^pappra collab capabilities derive --harness pi --assignment /abs/assignment.json --template /abs/card.declared.json --execution /abs/execution.json --session /abs/session.jsonl --json | from json)
262
+ if $derived.status != 'derived' { error make {msg: $"derive refused: ($derived.status)"} }
263
+ $derived.card | to json | save --raw /abs/task/card.runtime.json
264
+ ^pappra collab preflight --assignment /abs/assignment.json --capabilities /abs/task/card.runtime.json --json
265
+ ```
266
+
267
+ ## Task state and resource controls
268
+
269
+ ```sh
270
+ pappra collab state show|doctor --task-root <abs> [--json]
271
+ pappra collab state epoch-check --task-root <abs> --owner-epoch <positive> [--json]
272
+ pappra collab resource list --task-root <abs> [--json]
273
+ pappra collab resource claim|release --task-root <abs> --request <abs> [--apply] [--json]
274
+ ```
275
+
276
+ State commands reuse the existing record/lock/transaction/doctor primitives and
277
+ are read-only; doctor never repairs, breaks a lock, releases or launches.
278
+ Unresolved uncertain or invalid findings make doctor needs-input (exit 1); a live
279
+ lock observation alone is active evidence, not a readiness failure.
280
+ `resource list` reports domain claims and unreadable tasks as `state: "unknown"`;
281
+ its displayed claims share one global 500-claim budget across at most 100 tasks,
282
+ with full counts and actual `omitted`/`truncated` metadata.
283
+
284
+ Resource requests use `pappra/collaboration-resource-request/1` with an exact
285
+ action, explicit holder agent/session, canonical resource kinds and `access:
286
+ read|write`; release names one `claim_id`. Files are bounded at 1 MiB and read
287
+ with the special-file-safe loader. Plan without `--apply` validates only the
288
+ strict request and task namespace; it reserves nothing. Apply revalidates and
289
+ calls exactly the existing claim/release primitive. This is cooperative record
290
+ mutation, not OS fencing.
291
+
292
+ The namespace proof reuses the message task validator and also refuses redirected
293
+ or special `.write.lock`, transaction, ledger, aborted/broken-lock, `.domain.lock`
294
+ and neighboring task-record paths before reading or mutating them. System aliases
295
+ above the domain remain valid. Exit 0 success, 1 conflict/uncertainty/refusal,
296
+ 2 invalid request/options. Use fresh fixture domains in tests; never alter live
297
+ claims.
298
+
299
+ ## Recorded ownership handoff
300
+
301
+ ```sh
302
+ pappra collab handoff inventory --task-root <abs> [--subtask-id <id>] [--attempt <n>] [--json]
303
+ pappra collab handoff <begin|stopped|rebind|transfer|confirm|complete|abort|release-dispatch> \
304
+ --task-root <abs> --request <abs> [--apply] [--json]
305
+ ```
306
+
307
+ Requests use `pappra/collaboration-handoff-request/1` with an exact action, actor,
308
+ positive current `owner_epoch`, optional `expect_revision`, and action fields that
309
+ map to the existing primitives. Actor/epoch are editable protocol inputs, not
310
+ authentication. Plan without `--apply` validates request/namespace only and writes
311
+ nothing; apply revalidates and checks the epoch inside the guarded transaction,
312
+ preserving refusal rollback. This records cooperative ownership transfer; it is
313
+ not OS fencing, stop proof or a launch mechanism.
314
+
315
+ Confirmation is a registered message that is already present in the authoritative
316
+ record as an accepted/recorded ACK or HANDOFF entry. It must match its stored
317
+ content digest, come from the receiver to the current coordinator, carry the
318
+ current owner epoch, and explicitly correlate via `body.handoff_id` or `reply_to`
319
+ to the handoff with no conflicting body id. HANDOFF confirmations use a
320
+ non-request phase such as `confirmation`. Missing, unapplied, wrong-identity,
321
+ wrong-epoch, replayed, unrelated, symlink or FIFO confirmations cannot transfer
322
+ ownership. Writer completion transfers recorded claims and raises resource epochs;
323
+ coordinator completion raises owner_epoch and keeps dispatch frozen until an
324
+ explicit current-epoch `release-dispatch`.
325
+
326
+ Inventory is stored-state-only, bounded, read-only and never prints message bodies
327
+ or arbitrary inventory payloads. No command queries pane idle, stops a process,
328
+ answers an approval or launches an agent.
329
+
330
+ ## Explicit recovery
331
+
332
+ ```sh
333
+ pappra collab recovery inspect --task-root <abs> [--json]
334
+ pappra collab recovery reconcile --task-root <abs> --request <abs> [--apply] [--json]
335
+ pappra collab recovery lock-break --task-root <abs> --request <abs> [--apply] [--json]
336
+ ```
337
+
338
+ Requests use `pappra/collaboration-recovery-request/1`; results use
339
+ `pappra/collaboration-recovery/1`. Request JSON is bounded at 1 MiB through the
340
+ special-file-safe loader. Inspect is read-only and reports bounded uncertainty,
341
+ task lock/transactions and a stable lock-content fingerprint; PID liveness is an
342
+ observation, not stop proof. Exit 1 for open uncertainty, interrupted
343
+ transactions or an unavailable/oversized lock snapshot.
344
+
345
+ Reconcile records one explicit resolution and evidence reference, optionally
346
+ applying an existing state transition for that uncertainty's exact
347
+ subtask/attempt. Resolution and transition share one guarded transaction: an
348
+ invalid/approval-denied transition or missing context refuses both, without
349
+ committing resolution first. It does not release claims, clear `cancel_pending`
350
+ or invent native evidence.
351
+
352
+ An unexpected reconcile transaction exception is reported conservatively as
353
+ `reconcile_uncertain`: the record commit may already have happened even if ledger
354
+ evidence failed. Inspect the task record and ledger before any explicit retry; no
355
+ automatic rollback, retry or second journal is created.
356
+
357
+ Lock-break requires current epoch, reason, a literal `confirm_holder_stopped: true`
358
+ and the exact fingerprint from inspect; the operator assertion is not a Pappra
359
+ native proof. Plan writes nothing. Apply revalidates namespace, epoch and exact
360
+ lock content before the existing `breakLock`; changed/unavailable snapshots are
361
+ refused. The old lock, holder, transactions and break record are archived without
362
+ overwrite, age-based reclaim or deletion of unknown evidence. Ambiguous
363
+ post-mutation failure is reported as uncertain. Only the task write lock is
364
+ recovered, never the domain lock or an execution.
365
+
366
+ ## Portable task bindings
367
+
368
+ ```sh
369
+ pappra collab binding list [--root <abs>] [--json]
370
+ pappra collab binding resolve --task-id <alias> [--root <abs>] [--roots <abs roots.json>] [--json]
371
+ pappra collab binding bind --task-id <alias> --record <abs task.json> [--root <abs>] [--apply] [--json]
372
+ pappra collab binding unbind --task-id <alias> [--root <abs>] [--apply] [--json]
373
+ ```
374
+
375
+ The workspace-local `<workspace>/.pappra/local/collab-bindings.json` table
376
+ (schema `pappra/collaboration-bindings/1`, tied to `workspaceId`) stores pointer
377
+ metadata only: canonical record/task/domain paths, alias, protocol task ID,
378
+ domain identity, immutable record `created_at`, bound time, and explicit
379
+ tombstones. It never copies protocol content and is not execution authority.
380
+
381
+ Bind validates a real `<task_root>/task.json` before writing; normal revision or
382
+ inode replacement stays usable, while reinitialization/identity drift is a
383
+ conflict requiring explicit unbind. Plan writes nothing; apply serializes via
384
+ the existing private-state lock, rereads and atomically publishes. Unbind never
385
+ reads the target and leaves a tombstone; a later bind clears it. Present invalid
386
+ metadata is preserved and never bypassed.
387
+
388
+ The same 1 MiB ceiling applies to exact serialized publications: bind/unbind
389
+ returns `bindings_capacity` before index replacement if the new bytes exceed the
390
+ limit; previous bytes and every pointer/tombstone stay intact. Pappra never drops
391
+ entries to fit.
392
+
393
+ An alias present in both `bindings` and `unbound` makes the index invalid for
394
+ every action; the bytes are preserved and resolution never falls through to
395
+ discovery. A valid tombstone is removed only by a later explicit bind.
396
+
397
+ Resolve precedence is invalid index (fail), explicit binding (exclusive),
398
+ tombstone, explicit `--roots` discovery (≤32 absolute collaboration domain
399
+ roots, only `<root>/tasks/<alias>/task.json`, canonical dedupe, unique or
400
+ ambiguous/incomplete), then none. No home registry scan or automatic persistence
401
+ of discovered targets. A usable target reports persisted revision/coordinator/
402
+ freeze/attempt summaries with `scope: persisted-history` and
403
+ `liveStatus: unknown`; it never proves native running/stopped/accepted state.
404
+ List/resolve/plan are read-only.
405
+
406
+ `--json` emits one versioned result (`pappra/collaboration-binding-result/1`).
407
+ From an unrelated cwd with an explicit root:
408
+
409
+ ```sh
410
+ pappra collab binding bind --root /abs/ws --task-id workspace-experience \
411
+ --record /abs/domain/tasks/workspace-experience/task.json # plan, no write
412
+ pappra collab binding resolve --root /abs/ws --task-id workspace-experience
413
+ # Alias workspace-experience: binding (usable true).
414
+ pappra collab binding unbind --root /abs/ws --task-id workspace-experience --apply
415
+ # Unbind unbound; applied true. Later resolve reports unbound.
416
+ ```
417
+
418
+ Without `--root` the caller's nearest registered workspace is used; a caller
419
+ outside any workspace fails `workspace_unavailable` (exit 2) rather than
420
+ scanning home or an outer registry.
421
+
422
+ ## Readiness preflight
423
+
424
+ `pappra collab preflight --assignment <abs assignment.json> --capabilities <abs card.json> [--max-age-minutes <n>] [--json]`
425
+ checks reported readiness with the existing primitive. It is read-only: no
426
+ launch, claim, task mutation, evidence refresh, file-content output or model
427
+ turn. Exit codes: 0 ready, 1 needs_input, 2 invalid request/JSON/contract/card.
428
+ JSON uses `pappra/collaboration-preflight/1`; `ok` is true only for `ready`.
429
+
430
+ Pre-dispatch walkthrough:
431
+
432
+ ```sh
433
+ # A card observed from the real receiving session.
434
+ pappra collab preflight --assignment /abs/assignment.json \
435
+ --capabilities /abs/card.runtime.json --json
436
+
437
+ # A declared template only plans; it does not pass work readiness.
438
+ pappra collab preflight --assignment /abs/assignment.json \
439
+ --capabilities /abs/card.declared.json --json
440
+ # -> needs_input, blocker runtime_capabilities_unconfirmed
441
+ ```
442
+
443
+ Do not relabel a declared template as runtime. Derive a runtime card from
444
+ native evidence with `pappra collab capabilities derive`, or pass a separately
445
+ obtained card. `ready` means only current reported capability/evidence readiness;
446
+ self-reported facts, authorize dispatch, acquire resources, verify epochs,
447
+ launch, prove completion or replace launch admission. Warnings (for example a
448
+ write resource whose ownership is not enforced) and limits remain visible. The
449
+ default freshness window is 30 minutes; `--max-age-minutes` accepts a positive
450
+ finite override.
451
+
452
+ ### Model choice and readiness recovery
453
+
454
+ Model, provider and reasoning level are mutable **runtime observations** recorded in
455
+ a card's `native_observation`; they are not task identity, session identity,
456
+ `configuration_id`, ownership epoch or evidence freshness. A user-selected model
457
+ change alone therefore requires neither a new task identity nor reverting to the
458
+ original model, and no product check compares model or provider today.
459
+
460
+ Keep the current user model. When readiness fails, apply the recovery that matches
461
+ the actual blocker: derive _fresh_ evidence from the current receiving session for
462
+ stale evidence (never retimestamp older evidence); compare host and native
463
+ timestamps for future-clock evidence; treat an unavailable tool or skill code as
464
+ unconfirmed readiness rather than proven absence — inspect the current runtime
465
+ exposure, obtain actual current evidence, and restore or enable the capability when
466
+ it is in fact missing (changing a requirement is the coordinator's explicit scope
467
+ decision, not a worker recovery step); supply evidence for the exact
468
+ assignee identity/session/cwd/configuration for identity mismatches. Earlier
469
+ successful tool use does not prove the current runtime still exposes that tool, so
470
+ re-derive after a material change instead of promoting history into evidence.
471
+ Needs-input human output groups these recoveries; JSON status, blockers and exit
472
+ codes are unchanged, and unknown blockers keep their code without an invented
473
+ remedy.
474
+
475
+ ## Read-only work-plan inspection
476
+
477
+ ```nu
478
+ # Plan document: role/dependency nodes over the existing task protocol.
479
+ # A ready node is not authorization to run it.
480
+ ^pappra collab plan --task-root /abs/domain/tasks/example --config /abs/work-plan.json --json
481
+ | from json
482
+ | select status stale summary
483
+ ```
484
+
485
+ `collab plan` loads one bounded regular plan file and the exact task namespace,
486
+ then re-reads every registered decision envelope the evaluation needs. Each node
487
+ names a role label, the assignment attempt it expects, its pinned input revision,
488
+ its dependencies and its intended resource scope. Roles describe
489
+ responsibilities only; they grant no authority.
490
+
491
+ Node `assignment_id` is the existing task subtask identity
492
+ (`record.attempts[].subtask_id`); there is no second assignment registry.
493
+
494
+ Acceptance convention: a dependency advances only after the current coordinator
495
+ registers an `ANSWER` that is applied, digest-verifiable, and correlated to the
496
+ predecessor's assignment attempt, pinned input revision and registered report
497
+ digest. The complete registered decision set is authoritative, so an omitted
498
+ later rejection leaves acceptance `unknown`; sender timestamps never order
499
+ decisions (record application order does). A finished `REPORT` alone keeps the
500
+ node `awaiting_acceptance` and its dependents blocked.
501
+
502
+ Limits: the report is a persisted snapshot, advisory only, with no claim, launch,
503
+ dispatch, refresh, reconcile, native query or message write, and no resource
504
+ fencing. Evidence is scoped to the plan: only decisions addressed to the current
505
+ applied reports of the planned attempts are read, so unrelated task messages never
506
+ become required and are never counted. Plan documents are bounded at 512 KiB;
507
+ relevant decision evidence is bounded at 128 envelopes, 1 MiB per file and 4 MiB
508
+ aggregate, measured in the raw file bytes consumed by the bounded read (including
509
+ files later rejected by validation) before any full parse; record arrays are bounded
510
+ at 512 entries. Exceeding a bound reports `incomplete` with an explicit diagnostic
511
+ instead of returning truncated readiness. Read the human output for role, node
512
+ status, the blocking dependency/resource condition and the next action; message
513
+ bodies are never printed.
514
+
515
+ ## Read-only rollover inspection
516
+
517
+ ```nu
518
+ # Request: schema pappra/collaboration-rollover-request/1, bounded at 64 KiB.
519
+ ^pappra collab rollover inspect --task-root /abs/domain/tasks/example \
520
+ --request /abs/rollover-request.json --json
521
+ | from json
522
+ | select action ok plan_complete intent bundle steps
523
+ ```
524
+
525
+ `collab rollover <inspect|plan>` reads the exact authoritative task record and one
526
+ exact linked continuity handoff bundle, then reports the current rollover facts and
527
+ the steps a later execution would need. `--task-root` must equal the request
528
+ `task_root`; the working directory is never used to infer a workspace or task.
529
+
530
+ The request names the absolute task root, the bundle `root`,
531
+ `continuity_task_id`, `bundle_id` and pinned `digest`, and either a recorded
532
+ `intent_id` (`inspect`) or a `proposed_intent` (`plan`). A plan with no recorded
533
+ intent types the intent against the accepted record reducer on a clone and reports
534
+ its refusal code, so nothing is persisted.
535
+
536
+ A recorded intent pins one exact bundle: the request must name
537
+ `handoff-bundles/<bundleId>.json` under its continuity task with the digest recorded
538
+ at intent creation. Any other bundle, including a different valid one, is refused
539
+ with `bundle_pin_mismatch`; a freshly readable bundle is never substituted for the
540
+ originally pinned checkpoint context.
541
+
542
+ The bundle is read exactly, its digest must equal the pin, and it is verified with
543
+ the accepted handoff-bundle verifier. Its workspace, continuity task, collaboration
544
+ task/attempt/input/owner-epoch, source session agent/session/harness and the bounded
545
+ handoff snapshot must match the plan: the snapshot claims must equal the intent's
546
+ original holder/epoch, and claims plus pending tools/messages/approvals must all be
547
+ `complete` with no pending items. Partial or unknown inventory stays unknown and
548
+ blocks completion. Complete artifact context alone never grants authority;
549
+ `execution_allowed` stays `false`.
550
+
551
+ The report names the current `stage` and evaluates expected facts by stage. Before
552
+ transfer it expects the source assignee, the source-held claims at their intent
553
+ epochs and the pinned source native identity. After a completed transfer it expects
554
+ the successor assignee, the successor-held claims at epoch+1 and the pinned successor
555
+ native identity, so archived source history is not reported as current drift. An
556
+ aborted handoff is not executable. `plan_complete` is true only when every step is
557
+ satisfied, no drift or evidence issue exists, and the bundle association, snapshot
558
+ inventory and context integrity all agree.
559
+
560
+ Optional `evidence` ids name at most two registered `ACK`/`REPORT` envelopes. Each is
561
+ read descriptor-bounded through the safe id, namespace and realpath checks, and the
562
+ actual raw bytes are charged before JSON or envelope refusal, so a corrupt or padded
563
+ file is never inspected for free. Correlations include type, sender, recipient, task,
564
+ subtask, attempt, input revision, intent, generation, epoch, ledger identity and
565
+ first-work proof ordering; a missing, unreadable or contradictory id is a reported
566
+ blocker, never a report that stays complete.
567
+
568
+ Current-record drift is reported explicitly: coordinator epoch, handoff state, latest
569
+ attempt, assignee, input revision, waiting writer, claim holder/epoch/release, pinned
570
+ native identity and any missing transfer boundary. `prepare-transfer` stays
571
+ `unavailable` because no accepted host adapter produces authenticated quiescence
572
+ evidence; a caller-supplied stop observation, exit code or producer label is never
573
+ stop proof. `routing_removal` stays `pending` and `native_session_archive` stays
574
+ `unavailable`, so an applied transfer never claims that dispatch routing or the old
575
+ native session was archived.
576
+
577
+ There is no apply action: `rollover apply` and unknown actions are rejected with
578
+ exit 2. Exit 0 means the inspection ran (`plan_complete` reports whether every step
579
+ is satisfied), exit 1 means the exact record or bundle cannot support it, exit 2
580
+ means the request is invalid. Nothing is claimed, transferred, launched, archived,
581
+ routed, notified or written, and no native query is made.
582
+
583
+ A validated succession also excludes its archived old native identity from
584
+ `collab message notify`: an excluded sender or recipient fails with
585
+ `sender_route_excluded`/`recipient_route_excluded` before any caller or live Herdr
586
+ query and before any send, while stored messages, deliveries and bindings keep their
587
+ history unchanged. The current successor identity stays an active route.
588
+
589
+ A completed handoff alone is not proof. Exclusion requires the matching intent (task,
590
+ handoff, generation, source and successor identities), a recorded transfer boundary,
591
+ the registered applied first-work `REPORT` whose digest matches the retained proof and
592
+ which was applied after the boundary, and an admitted `completed` result entry for
593
+ that report. A missing or contradictory chain makes the queried identity `unknown`,
594
+ including when it matches the named successor, so a notify is refused instead of
595
+ silently rerouted.
596
+
597
+ ## Notification states
598
+
599
+ | Status | Meaning |
600
+ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
601
+ | `planned` | Task, message, binding and recipient validated; nothing sent. |
602
+ | `submitted` | One `herdr agent prompt` was accepted. Consumption is still unknown. |
603
+ | `blocked` | Herdr reported `agent_blocked`; a blocked native UI is never answered. |
604
+ | `refused` | Herdr rejected the prompt with an explicit recognized pre-submission refusal (`agent_not_found`). |
605
+ | `unknown` | The prompt may have been submitted (timeout, stalled, signal, nonzero exit without a recognized result, an unrecognized error code, or transport error after the reservation). Never resend implicitly. |
606
+ | `failed` | The transport failed without a possible submission (for example an unresolvable delivery directory). |
607
+ | `herdr_unavailable` | Not inside Herdr, or the CLI is not callable. The message stays persisted. |
608
+ | `herdr_caller_unverified` | The caller pane could not be resolved or the environment caller IDs are stale. Nothing was inspected or sent. |
609
+ | `already_recorded` | Delivery metadata already exists for this message id; no new wakeup was sent. |
610
+ | `in_flight_unknown` | A delivery reservation is still in flight or its outcome is unknown; it is never resent or reclaimed by age. |
611
+ | `retry_limit` | Explicit retry attempts are exhausted (3). |
612
+
613
+ Notification metadata lives in `<task-root>/notifications/<message-id>.json`; it
614
+ is delivery evidence, not a second task record. Each retry reserves a distinct
615
+ attempt under a task-private lock, so concurrent retries cannot lose an attempt
616
+ or exceed the bound. Retries are explicit operator actions with `--retry` on the
617
+ same message identity.
618
+
619
+ ## Working loop
620
+
621
+ 1. The coordinator prepares the task and claims the resources.
622
+ 2. The coordinator sends one `ASSIGN` envelope, then notifies the recipient once.
623
+ 3. The recipient ACKs by sending its own envelope and notifying the coordinator
624
+ once; it asks a question with `BLOCK(kind=clarification)` or `ASK`, and
625
+ reports with `REPORT`.
626
+ 4. The coordinator reads the report, checks the evidence, and answers with a
627
+ correlated message. Acceptance remains a separate decision.
628
+
629
+ No polling, timers, repeated status reads, or `herdr agent prompt --wait` are
630
+ part of this loop. If no reply arrives, the outcome is uncertain; inspect the
631
+ record before retrying rather than sending another wakeup.
632
+
633
+ ## Direct mode and receiver verification
634
+
635
+ This surface works without Herdr for persistence and reading. Notification
636
+ requires `HERDR_ENV=1` plus a routing mode: inherited current context (which must
637
+ be present and consistent) or an explicit task-bound `--caller-pane <id>` for
638
+ stale inherited IDs. Outside Herdr it returns `herdr_unavailable`; missing, stale
639
+ or unresolved context returns `herdr_caller_unverified`, with the persisted
640
+ pointer and no launch, focus change, pane creation, or channel switch. Direct
641
+ coordination uses the same envelopes and explicit sessions.
642
+
643
+ A pane id is not a native session id, and pane idle is not proof of stop or
644
+ acceptance. The receiver verifies its exact `to` identity (agent id, harness,
645
+ session id) before consuming a message, and never adopts an arbitrary PID or
646
+ session because a notification arrived.