@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,134 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import crypto from 'node:crypto';
4
+ import { canonicalJson } from '../collab/envelope.js';
5
+ import { readBoundedFile } from './bounded-file.js';
6
+ import { tickAutomaticHandoff, } from './collab-auto-handoff.js';
7
+ export function loadAutomaticHandoffConfig(file) {
8
+ const loaded = readBoundedFile(file, 64 * 1024);
9
+ if (!loaded.ok)
10
+ throw new Error('automatic_handoff_config_unreadable');
11
+ const value = JSON.parse(loaded.text);
12
+ if (!value ||
13
+ value.schema !== 'pappra/automatic-handoff/1' ||
14
+ !value.transition ||
15
+ !path.isAbsolute(value.transition.task_root))
16
+ throw new Error('automatic_handoff_config_invalid');
17
+ if (value.sourceReadiness !== undefined) {
18
+ const readiness = value.sourceReadiness;
19
+ const keys = ['assignmentFile', 'templateFile', 'cardFile'];
20
+ if (!readiness ||
21
+ typeof readiness !== 'object' ||
22
+ Array.isArray(readiness) ||
23
+ Object.keys(readiness).some((key) => !keys.includes(key)) ||
24
+ !keys.every((key) => typeof readiness[key] === 'string' && path.isAbsolute(readiness[key])) ||
25
+ new Set(keys.map((key) => path.resolve(readiness[key]))).size !==
26
+ keys.length)
27
+ throw new Error('automatic_handoff_source_readiness_invalid');
28
+ }
29
+ return value;
30
+ }
31
+ /** A native settled event or registered task update advances one guarded transition. */
32
+ export function watchAutomaticHandoff(config, runtime, dependencies = {}, onRetirement) {
33
+ const directory = config.transition.task_root;
34
+ const pin = fs.lstatSync(directory);
35
+ if (!pin.isDirectory() ||
36
+ pin.isSymbolicLink() ||
37
+ fs.realpathSync(directory) !== directory)
38
+ throw new Error('automatic_handoff_task_redirected');
39
+ let closed = false;
40
+ let pending = false;
41
+ let running = false;
42
+ let active = Promise.resolve();
43
+ let last = null;
44
+ let error = null;
45
+ let previousCause = null;
46
+ let completion = null;
47
+ let resolveCompleted;
48
+ const completed = new Promise((resolve) => {
49
+ resolveCompleted = resolve;
50
+ });
51
+ const refresh = () => {
52
+ if (closed)
53
+ return active;
54
+ pending = true;
55
+ if (running)
56
+ return active;
57
+ running = true;
58
+ active = (async () => {
59
+ try {
60
+ while (pending && !closed) {
61
+ pending = false;
62
+ const now = fs.lstatSync(directory);
63
+ if (now.dev !== pin.dev ||
64
+ now.ino !== pin.ino ||
65
+ now.isSymbolicLink())
66
+ throw new Error('automatic_handoff_task_changed');
67
+ const task = readBoundedFile(path.join(directory, 'task.json'), 8 * 1024 * 1024);
68
+ if (!task.ok)
69
+ throw new Error('automatic_handoff_task_unreadable');
70
+ const state = JSON.parse(task.text);
71
+ delete state.automatic_handoff_journal;
72
+ delete state.session_transition_journal;
73
+ delete state.state_revision;
74
+ delete state.updated_at;
75
+ const cause = crypto
76
+ .createHash('sha256')
77
+ .update(canonicalJson({ state, observation: runtime.observe() }))
78
+ .digest('hex');
79
+ if (cause === previousCause)
80
+ continue;
81
+ previousCause = cause;
82
+ last = await tickAutomaticHandoff(config, runtime, dependencies);
83
+ if (last.status === 'complete') {
84
+ try {
85
+ await onRetirement?.(last);
86
+ completion = { ok: true };
87
+ }
88
+ catch {
89
+ error = 'automatic_handoff_retirement_failed';
90
+ completion = { ok: false, code: error };
91
+ }
92
+ closed = true;
93
+ watcher.close();
94
+ unsubscribe();
95
+ resolveCompleted(completion);
96
+ }
97
+ }
98
+ }
99
+ catch {
100
+ error = 'automatic_handoff_event_failed';
101
+ }
102
+ finally {
103
+ running = false;
104
+ }
105
+ })();
106
+ return active;
107
+ };
108
+ const watcher = fs.watch(directory, (_event, name) => {
109
+ if (name === null || name.toString() === 'task.json')
110
+ void refresh();
111
+ });
112
+ watcher.on('error', () => {
113
+ error = 'automatic_handoff_watch_failed';
114
+ });
115
+ const unsubscribe = runtime.subscribe((event) => {
116
+ if (typeof event === 'object' &&
117
+ event !== null &&
118
+ 'type' in event &&
119
+ event.type === 'agent_settled')
120
+ void refresh();
121
+ });
122
+ // Startup also reconciles a durable prior transition; it never recaptures a reserved summary.
123
+ void refresh();
124
+ return {
125
+ refresh,
126
+ completed,
127
+ status: () => ({ result: last, error, completion }),
128
+ close() {
129
+ closed = true;
130
+ watcher.close();
131
+ unsubscribe();
132
+ },
133
+ };
134
+ }
@@ -0,0 +1,2 @@
1
+ /** Shared descriptor-bounded reads live in infrastructure. */
2
+ export * from '../infra/bounded-file.js';
@@ -0,0 +1,2 @@
1
+ /** Shared descriptor-bounded reads live in infrastructure. */
2
+ export * from '../infra/bounded-file.js';
@@ -0,0 +1,37 @@
1
+ import type { Assignment, CapabilityCard } from '../../collab/contracts.js';
2
+ import { type CapabilityDerivation } from './shared.js';
3
+ interface ClaudeCall {
4
+ readonly id: string;
5
+ readonly name: string;
6
+ readonly input?: Record<string, unknown>;
7
+ }
8
+ interface ClaudeResult {
9
+ readonly is_error?: boolean;
10
+ }
11
+ export interface ClaudeNativeExecution {
12
+ readonly rows: Record<string, unknown>[];
13
+ readonly execution: Record<string, unknown>;
14
+ readonly init: Record<string, unknown>;
15
+ readonly result: Record<string, unknown>;
16
+ readonly calls: Map<string, ClaudeCall>;
17
+ readonly results: Map<string, ClaudeResult>;
18
+ readonly injections: Map<string, string>;
19
+ readonly evidenceRecords: {
20
+ ref: string;
21
+ digest: string;
22
+ }[];
23
+ }
24
+ export interface ClaudeEvidenceOptions {
25
+ readonly eventsFile: string;
26
+ readonly executionFile: string;
27
+ readonly sessionId: string;
28
+ readonly cwd: string;
29
+ }
30
+ export declare function readClaudeExecution(options: ClaudeEvidenceOptions): ClaudeNativeExecution;
31
+ export declare function deriveClaudeCard(options: {
32
+ readonly assignment: Assignment;
33
+ readonly template: CapabilityCard;
34
+ readonly eventsFile: string;
35
+ readonly executionFile: string;
36
+ }): CapabilityDerivation;
37
+ export {};
@@ -0,0 +1,206 @@
1
+ import path from 'node:path';
2
+ import { assertTemplateIdentity, deriveOutcome, evidenceRecords, fail, fingerprintTemplateSkill, isTimestamp, parseExecution, readNativeEvidence, realPath, record, samePath, } from './shared.js';
3
+ /**
4
+ * Derive a runtime capability card from a saved Claude CLI stream.
5
+ *
6
+ * Preserved maintained semantics: a discovery/bootstrap execution may only use
7
+ * Read and Skill; successful call/result correlation is required for `verified`;
8
+ * a skill is `verified` only when the injected base directory matches the
9
+ * fingerprinted skill source. Unknown or unobserved states stay unknown.
10
+ */
11
+ const MAX_CLAUDE_EVENTS = 10000;
12
+ function stringArray(value) {
13
+ if (!Array.isArray(value) ||
14
+ value.some((item) => typeof item !== 'string') ||
15
+ new Set(value).size !== value.length)
16
+ return fail('unsupported_native_tools');
17
+ return value;
18
+ }
19
+ export function readClaudeExecution(options) {
20
+ const eventsBytes = readNativeEvidence(options.eventsFile);
21
+ const executionBytes = readNativeEvidence(options.executionFile);
22
+ let rows;
23
+ let execution;
24
+ try {
25
+ const lines = eventsBytes.text.trim().split('\n');
26
+ if (lines.length > MAX_CLAUDE_EVENTS)
27
+ fail('event_limit');
28
+ rows = lines.map((line) => {
29
+ const value = JSON.parse(line);
30
+ if (!record(value))
31
+ fail('unsupported_event_shape');
32
+ return value;
33
+ });
34
+ execution = parseExecution(executionBytes.text);
35
+ }
36
+ catch {
37
+ return fail('invalid_native_json');
38
+ }
39
+ if (execution.status !== 'exited' || execution.exit_code !== 0)
40
+ fail('native_process_not_successfully_exited');
41
+ if (!isTimestamp(execution.started_at) ||
42
+ !isTimestamp(execution.finished_at) ||
43
+ Date.parse(execution.finished_at) <
44
+ Date.parse(execution.started_at))
45
+ fail('invalid_execution_clock');
46
+ if (rows.some((row) => typeof row.type !== 'string'))
47
+ fail('unsupported_event_shape');
48
+ const inits = rows.filter((row) => row.type === 'system' && row.subtype === 'init');
49
+ const terminals = rows.filter((row) => row.type === 'result');
50
+ if (inits.length !== 1 ||
51
+ terminals.length !== 1 ||
52
+ rows[rows.length - 1] !== terminals[0])
53
+ fail('ambiguous_native_lifecycle');
54
+ const init = inits[0];
55
+ const result = terminals[0];
56
+ if (result.is_error !== false || result.subtype !== 'success')
57
+ fail('native_result_failed');
58
+ if (init.session_id !== options.sessionId ||
59
+ result.session_id !== options.sessionId)
60
+ fail('native_identity_mismatch');
61
+ if (typeof init.cwd !== 'string' || !samePath(init.cwd, options.cwd))
62
+ fail('native_cwd_mismatch');
63
+ const tools = stringArray(init.tools);
64
+ const calls = new Map();
65
+ const results = new Map();
66
+ const injections = new Map();
67
+ let initialized = false;
68
+ let pendingSkill;
69
+ for (const row of rows) {
70
+ if (row === init)
71
+ initialized = true;
72
+ if (row.type !== 'assistant' && row.type !== 'user')
73
+ continue;
74
+ if (!initialized)
75
+ fail('message_before_native_init');
76
+ if (row.session_id !== options.sessionId || row.parent_tool_use_id != null)
77
+ fail('foreign_or_nested_session_event');
78
+ const message = record(row.message) ? row.message : null;
79
+ if (!message || !Array.isArray(message.content))
80
+ fail('unsupported_message_shape');
81
+ for (const item of message.content) {
82
+ if (!record(item))
83
+ continue;
84
+ if (item.type === 'tool_use') {
85
+ if (row.type !== 'assistant' ||
86
+ typeof item.id !== 'string' ||
87
+ !item.id ||
88
+ calls.has(item.id) ||
89
+ typeof item.name !== 'string' ||
90
+ !tools.includes(item.name))
91
+ fail('unsupported_tool_call');
92
+ const call = {
93
+ id: item.id,
94
+ name: item.name,
95
+ ...(record(item.input) ? { input: item.input } : {}),
96
+ };
97
+ calls.set(item.id, call);
98
+ pendingSkill = undefined;
99
+ }
100
+ else if (item.type === 'tool_result') {
101
+ if (row.type !== 'user' ||
102
+ typeof item.tool_use_id !== 'string' ||
103
+ !calls.has(item.tool_use_id) ||
104
+ results.has(item.tool_use_id) ||
105
+ (item.is_error !== undefined && typeof item.is_error !== 'boolean'))
106
+ fail('unsupported_tool_result');
107
+ const outcome = item.is_error === undefined ? {} : { is_error: item.is_error };
108
+ results.set(item.tool_use_id, outcome);
109
+ const call = calls.get(item.tool_use_id);
110
+ pendingSkill =
111
+ call.name === 'Skill' && !outcome.is_error ? call : undefined;
112
+ }
113
+ else if (row.type === 'user' &&
114
+ row.isSynthetic === true &&
115
+ item.type === 'text' &&
116
+ typeof item.text === 'string' &&
117
+ item.text.startsWith('Base directory for this skill: ')) {
118
+ const base = item.text
119
+ .split('\n')[0]
120
+ .slice('Base directory for this skill: '.length)
121
+ .trim();
122
+ if (!pendingSkill || !path.isAbsolute(base))
123
+ fail('ambiguous_skill_injection');
124
+ injections.set(pendingSkill.id, realPath(base));
125
+ pendingSkill = undefined;
126
+ }
127
+ }
128
+ }
129
+ if ([...calls.keys()].some((id) => !results.has(id)))
130
+ fail('incomplete_tool_results');
131
+ return {
132
+ rows,
133
+ execution,
134
+ init,
135
+ result,
136
+ calls,
137
+ results,
138
+ injections,
139
+ evidenceRecords: evidenceRecords(eventsBytes, options.eventsFile, executionBytes, options.executionFile),
140
+ };
141
+ }
142
+ export function deriveClaudeCard(options) {
143
+ return deriveOutcome(options.assignment, options.template, () => {
144
+ if (options.assignment.assignee.harness !== 'claude' ||
145
+ options.assignment.assignee.surface !== 'cli')
146
+ fail('unsupported_harness_surface');
147
+ assertTemplateIdentity(options.assignment, options.template, 'claude');
148
+ const native = readClaudeExecution({
149
+ eventsFile: options.eventsFile,
150
+ executionFile: options.executionFile,
151
+ sessionId: options.template.session_id,
152
+ cwd: options.template.cwd,
153
+ });
154
+ if (!['bootstrap', 'discovery'].includes(String(native.execution.phase)))
155
+ fail('not_a_discovery_execution');
156
+ if ([...native.calls.values()].some((call) => !['Read', 'Skill'].includes(call.name)))
157
+ fail('discovery_performed_unexpected_action');
158
+ const successful = (name) => [...native.calls.values()].some((call) => call.name === name && !native.results.get(call.id)?.is_error);
159
+ const card = structuredClone(options.template);
160
+ card.evidence_level = 'runtime';
161
+ card.observed_at = native.execution.finished_at;
162
+ card.evidence_records = native.evidenceRecords;
163
+ card.native_observation = {
164
+ model: native.init.model,
165
+ tools: native.init.tools,
166
+ source: 'claude-cli-stream',
167
+ };
168
+ card.tools = card.tools.map((tool) => ({
169
+ ...tool,
170
+ state: !stringArray(native.init.tools).includes(tool.id)
171
+ ? 'unknown'
172
+ : successful(tool.id)
173
+ ? 'verified'
174
+ : 'callable',
175
+ evidence_ref: options.eventsFile,
176
+ }));
177
+ card.skills = card.skills.map((skill) => {
178
+ const snapshot = fingerprintTemplateSkill(skill);
179
+ const pinned = skill;
180
+ const nativeName = typeof pinned.native_name === 'string'
181
+ ? pinned.native_name
182
+ : path.basename(path.dirname(snapshot.entry));
183
+ const discoveredNames = [
184
+ ...(Array.isArray(native.init.skills) ? native.init.skills : []),
185
+ ...(Array.isArray(native.init.slash_commands)
186
+ ? native.init.slash_commands
187
+ : []),
188
+ ];
189
+ const discovered = discoveredNames.includes(nativeName);
190
+ const loaded = [...native.calls.values()].filter((call) => call.name === 'Skill' &&
191
+ call.input?.skill === nativeName &&
192
+ !native.results.get(call.id)?.is_error);
193
+ const sourceMatched = loaded.some((call) => native.injections.get(call.id) === snapshot.directory);
194
+ return {
195
+ ...skill,
196
+ state: sourceMatched
197
+ ? 'verified'
198
+ : discovered
199
+ ? 'discovered'
200
+ : 'unknown',
201
+ evidence_ref: options.eventsFile,
202
+ };
203
+ });
204
+ return { card };
205
+ });
206
+ }
@@ -0,0 +1,35 @@
1
+ import type { Assignment, CapabilityCard } from '../../collab/contracts.js';
2
+ import { type CapabilityDerivation } from './shared.js';
3
+ interface CodexToolCall {
4
+ readonly id: unknown;
5
+ readonly tool: string;
6
+ readonly item_type: string;
7
+ readonly succeeded: boolean;
8
+ readonly payload: string[];
9
+ }
10
+ export interface CodexNativeExecution {
11
+ readonly rows: Record<string, unknown>[];
12
+ readonly execution: Record<string, unknown>;
13
+ readonly items: Record<string, unknown>[];
14
+ readonly toolCalls: CodexToolCall[];
15
+ readonly unknownItemTypes: string[];
16
+ readonly usage: unknown;
17
+ readonly evidenceRecords: {
18
+ ref: string;
19
+ digest: string;
20
+ }[];
21
+ }
22
+ export interface CodexEvidenceOptions {
23
+ readonly eventsFile: string;
24
+ readonly executionFile: string;
25
+ readonly sessionId: string;
26
+ readonly cwd: string;
27
+ }
28
+ export declare function readCodexExecution(options: CodexEvidenceOptions): CodexNativeExecution;
29
+ export declare function deriveCodexCard(options: {
30
+ readonly assignment: Assignment;
31
+ readonly template: CapabilityCard;
32
+ readonly eventsFile: string;
33
+ readonly executionFile: string;
34
+ }): CapabilityDerivation;
35
+ export {};
@@ -0,0 +1,193 @@
1
+ import { assertTemplateIdentity, deriveOutcome, evidenceRecords, fail, fingerprintTemplateSkill, isTimestamp, MAX_EVENTS, parseExecution, payloadStrings, readNativeEvidence, record, samePath, } from './shared.js';
2
+ /**
3
+ * Derive a runtime capability card from a saved `codex exec --json` run.
4
+ *
5
+ * Observed Codex CLI 0.162.1 event shape:
6
+ * {"type":"thread.started","thread_id":"..."}
7
+ * {"type":"turn.started"}
8
+ * {"type":"item.completed","item":{"id":"item_0","type":"agent_message","text":"..."}}
9
+ * {"type":"turn.completed","usage":{...}}
10
+ *
11
+ * Limits this parser states rather than hides:
12
+ * * Only the shapes above are understood. An unknown row type, an unknown item
13
+ * type or a bare `turn.failed` fails closed instead of being guessed into a
14
+ * success.
15
+ * * The exec stream does not report skill invocation in this version, so a skill
16
+ * can never be promoted to `verified` here; it stays `unknown` and a required
17
+ * skill fails closed.
18
+ * * Tool ids are the receiving runtime's own reported item types, mapped
19
+ * explicitly by ITEM_TOOL_MAP below; no aliasing by display name.
20
+ */
21
+ const TERMINAL_ROWS = new Set(['turn.completed']);
22
+ const FAILURE_ROWS = new Set(['turn.failed', 'error']);
23
+ const NON_TOOL_ITEMS = new Set(['agent_message', 'reasoning', 'message']);
24
+ const ITEM_TOOL_MAP = {
25
+ command_execution: 'shell',
26
+ file_change: 'apply_patch',
27
+ mcp_tool_call: 'mcp',
28
+ web_search: 'web_search',
29
+ };
30
+ /** True when the item reports success: no explicit failure signal and a non-failed status. */
31
+ function itemSucceeded(item) {
32
+ if (typeof item.status === 'string' && item.status !== 'completed')
33
+ return false;
34
+ if (item.exit_code !== undefined &&
35
+ item.exit_code !== null &&
36
+ item.exit_code !== 0)
37
+ return false;
38
+ return true;
39
+ }
40
+ export function readCodexExecution(options) {
41
+ const eventsBytes = readNativeEvidence(options.eventsFile);
42
+ const executionBytes = readNativeEvidence(options.executionFile);
43
+ let rows;
44
+ let execution;
45
+ try {
46
+ const lines = eventsBytes.text
47
+ .split('\n')
48
+ .filter((line) => line.trim().length);
49
+ if (lines.length > MAX_EVENTS)
50
+ fail('event_limit');
51
+ rows = lines.map((line) => {
52
+ const value = JSON.parse(line);
53
+ if (!record(value))
54
+ fail('unsupported_event_shape');
55
+ return value;
56
+ });
57
+ execution = parseExecution(executionBytes.text);
58
+ }
59
+ catch {
60
+ return fail('invalid_native_json');
61
+ }
62
+ if (execution.status !== 'exited' || execution.exit_code !== 0)
63
+ fail('native_process_not_successfully_exited');
64
+ if (!isTimestamp(execution.started_at) ||
65
+ !isTimestamp(execution.finished_at) ||
66
+ Date.parse(execution.finished_at) <
67
+ Date.parse(execution.started_at))
68
+ fail('invalid_execution_clock');
69
+ if (execution.events_file &&
70
+ !samePath(execution.events_file, options.eventsFile))
71
+ fail('execution_evidence_mismatch');
72
+ if (execution.cwd && !samePath(execution.cwd, options.cwd))
73
+ fail('native_cwd_mismatch');
74
+ if (rows.some((row) => typeof row.type !== 'string'))
75
+ fail('unsupported_event_shape');
76
+ const started = rows.filter((row) => row.type === 'thread.started');
77
+ if (started.length !== 1 || rows[0] !== started[0])
78
+ fail('ambiguous_native_lifecycle');
79
+ const terminal = rows.filter((row) => TERMINAL_ROWS.has(row.type) ||
80
+ FAILURE_ROWS.has(row.type));
81
+ if (terminal.length !== 1 || rows[rows.length - 1] !== terminal[0])
82
+ fail('ambiguous_native_lifecycle');
83
+ const terminalItem = terminal[0];
84
+ if (FAILURE_ROWS.has(terminalItem.type) ||
85
+ terminalItem.success === false)
86
+ fail('native_result_failed');
87
+ if (started[0].thread_id !== options.sessionId)
88
+ fail('native_identity_mismatch');
89
+ const known = new Set([
90
+ 'thread.started',
91
+ 'turn.started',
92
+ 'item.started',
93
+ 'item.updated',
94
+ 'item.completed',
95
+ ...TERMINAL_ROWS,
96
+ ]);
97
+ const unknownRows = [
98
+ ...new Set(rows.map((row) => String(row.type)).filter((type) => !known.has(type))),
99
+ ];
100
+ if (unknownRows.length)
101
+ fail(`unsupported_row_types:${unknownRows.join(',')}`);
102
+ const items = [];
103
+ const unknownItemTypes = new Set();
104
+ for (const row of rows) {
105
+ if (row.type !== 'item.completed' && row.type !== 'item.started')
106
+ continue;
107
+ const item = row.item;
108
+ if (!record(item) || typeof item.type !== 'string')
109
+ fail('unsupported_item_shape');
110
+ if (!NON_TOOL_ITEMS.has(item.type) && !ITEM_TOOL_MAP[item.type])
111
+ unknownItemTypes.add(item.type);
112
+ items.push({ ...item, __row: row.type });
113
+ }
114
+ const completed = items.filter((item) => item.__row === 'item.completed');
115
+ const toolCalls = completed
116
+ .filter((item) => typeof item.type === 'string' && ITEM_TOOL_MAP[item.type] !== undefined)
117
+ .map((item) => ({
118
+ id: item.id ?? null,
119
+ tool: ITEM_TOOL_MAP[item.type],
120
+ item_type: item.type,
121
+ succeeded: itemSucceeded(item),
122
+ payload: payloadStrings(item).slice(0, 40),
123
+ }));
124
+ return {
125
+ rows,
126
+ execution,
127
+ items,
128
+ toolCalls,
129
+ unknownItemTypes: [...unknownItemTypes].sort(),
130
+ usage: terminalItem.usage ?? null,
131
+ evidenceRecords: evidenceRecords(eventsBytes, options.eventsFile, executionBytes, options.executionFile),
132
+ };
133
+ }
134
+ export function deriveCodexCard(options) {
135
+ return deriveOutcome(options.assignment, options.template, () => {
136
+ assertTemplateIdentity(options.assignment, options.template, 'codex');
137
+ const native = readCodexExecution({
138
+ eventsFile: options.eventsFile,
139
+ executionFile: options.executionFile,
140
+ sessionId: options.template.session_id,
141
+ cwd: options.template.cwd,
142
+ });
143
+ const successfulTool = (tool) => native.toolCalls.some((call) => call.tool === tool && call.succeeded);
144
+ const card = structuredClone(options.template);
145
+ card.evidence_level = 'runtime';
146
+ card.observed_at = native.execution.finished_at;
147
+ card.evidence_records = native.evidenceRecords;
148
+ card.native_observation = {
149
+ source: 'codex-exec-json',
150
+ thread_id: options.template.session_id,
151
+ cwd: native.execution.cwd,
152
+ sandbox: native.execution.sandbox ?? null,
153
+ resumed_from: native.execution.resumed_from ?? null,
154
+ item_types_observed: [
155
+ ...new Set(native.items.map((item) => String(item.type))),
156
+ ].sort(),
157
+ unmapped_item_types: native.unknownItemTypes,
158
+ tool_calls: native.toolCalls.map((call) => ({
159
+ tool: call.tool,
160
+ item_type: call.item_type,
161
+ succeeded: call.succeeded,
162
+ })),
163
+ usage: native.usage,
164
+ skill_evidence: 'not_reported_by_this_cli_version: skills stay unknown and can never satisfy a required capability from this stream alone',
165
+ };
166
+ card.tools = card.tools.map((tool) => {
167
+ const known = Object.values(ITEM_TOOL_MAP).includes(tool.id);
168
+ const verified = known && successfulTool(tool.id);
169
+ const next = {
170
+ ...tool,
171
+ state: verified ? 'verified' : 'unknown',
172
+ };
173
+ if (verified)
174
+ next.evidence_ref = options.eventsFile;
175
+ return next;
176
+ });
177
+ card.skills = card.skills.map((skill) => {
178
+ fingerprintTemplateSkill(skill);
179
+ // `codex exec --json` does not report skill invocation and shell payloads
180
+ // cannot prove that a skill was loaded or followed. Skills therefore never
181
+ // reach `verified` here; they stay `unknown` so a required skill fails
182
+ // closed and the caller must use `preferred` or provide in-host evidence.
183
+ return { ...skill, state: 'unknown' };
184
+ });
185
+ return {
186
+ card,
187
+ limitations: [
188
+ 'skill_invocation_not_reported_by_codex_exec_json',
189
+ 'unmapped_item_types_are_not_promoted',
190
+ ],
191
+ };
192
+ });
193
+ }
@@ -0,0 +1,33 @@
1
+ import type { CapabilityCard } from '../../collab/contracts.js';
2
+ import { type CapabilityDerivation } from './shared.js';
3
+ /**
4
+ * Read-only native capability evidence derivation.
5
+ *
6
+ * A derived runtime card is a claim derived from the supplied evidence only; no
7
+ * authentication, process ownership, admission or task completion is implied.
8
+ * Deriving never writes a file, launches a process or calls a model.
9
+ */
10
+ export declare const CAPABILITIES_SCHEMA = "pappra/collaboration-capabilities/1";
11
+ export type EvidenceHarness = 'pi' | 'codex' | 'claude';
12
+ export interface DeriveCapabilitiesOptions {
13
+ readonly harness: EvidenceHarness;
14
+ readonly assignmentFile: string;
15
+ readonly templateFile: string;
16
+ readonly executionFile?: string | null;
17
+ readonly live?: boolean;
18
+ readonly sessionFile?: string | null;
19
+ readonly eventsFile?: string | null;
20
+ }
21
+ export interface CapabilityEvidenceResult {
22
+ readonly schema: typeof CAPABILITIES_SCHEMA;
23
+ readonly ok: boolean;
24
+ readonly status: CapabilityDerivation['status'];
25
+ readonly harness: EvidenceHarness;
26
+ readonly card?: CapabilityCard;
27
+ readonly blockers?: readonly string[];
28
+ readonly limitations?: readonly string[];
29
+ readonly errors?: readonly string[];
30
+ readonly limits: readonly string[];
31
+ }
32
+ export declare const CAPABILITY_LIMITS: readonly ['reported_native_evidence_only', 'evidence_not_authenticated', 'no_dispatch'];
33
+ export declare function deriveCapabilityCard(options: DeriveCapabilitiesOptions): CapabilityEvidenceResult;