@phyzess/pappra 0.1.0-beta.13 → 0.1.0-beta.18

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