@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
@@ -1,3 +1,4 @@
1
+ import { type GitObservationScope } from '../infra/git.js';
1
2
  import { type Outcome } from '../schemas/outcome.js';
2
3
  import { type CodeIdentity } from '../schemas/code.js';
3
4
  export interface ComputeCodeIdentityInput {
@@ -8,6 +9,12 @@ export interface ComputeCodeIdentityInput {
8
9
  readonly configStatus?: 'default' | 'observed' | 'unknown';
9
10
  readonly excludedRoots?: readonly string[];
10
11
  readonly signal?: AbortSignal;
12
+ /**
13
+ * One operation's Git probe scope. When supplied, the repository probe is
14
+ * shared with workspace discovery instead of being spawned a second time for
15
+ * the same checkout. Working-tree diffs are never taken from the scope.
16
+ */
17
+ readonly observations?: GitObservationScope;
11
18
  }
12
19
  export declare function computeCodeIdentity(input: ComputeCodeIdentityInput): Promise<Outcome<CodeIdentity>>;
13
20
  export declare function codeIdentityDigest(identity: CodeIdentity): string;
@@ -1,7 +1,6 @@
1
1
  import { readlink } from 'node:fs/promises';
2
2
  import { join, relative, sep } from 'node:path';
3
- import { inspectGitRepository } from '../infra/git.js';
4
- import { runGit } from '../infra/git.js';
3
+ import { inspectGitRepository, runGit, } from '../infra/git.js';
5
4
  import { observePath, readFileBounded, sha256Digest } from '../infra/fs.js';
6
5
  import { diagnosticCodes } from '../schemas/errors.js';
7
6
  import { failed, succeeded } from '../schemas/outcome.js';
@@ -34,6 +33,8 @@ async function observeWorkingTree(root, excludedRoots, signal) {
34
33
  }
35
34
  const cached = await readDiff([
36
35
  'diff',
36
+ '--no-ext-diff',
37
+ '--no-textconv',
37
38
  '--binary',
38
39
  '--cached',
39
40
  '--',
@@ -42,6 +43,8 @@ async function observeWorkingTree(root, excludedRoots, signal) {
42
43
  ]);
43
44
  const unstaged = await readDiff([
44
45
  'diff',
46
+ '--no-ext-diff',
47
+ '--no-textconv',
45
48
  '--binary',
46
49
  '--',
47
50
  '.',
@@ -172,7 +175,8 @@ async function observeWorkingTree(root, excludedRoots, signal) {
172
175
  };
173
176
  }
174
177
  export async function computeCodeIdentity(input) {
175
- const observed = await inspectGitRepository(input.root, {
178
+ const inspect = input.observations?.repository ?? inspectGitRepository;
179
+ const observed = await inspect(input.root, {
176
180
  timeoutMs: GIT_TIMEOUT_MS,
177
181
  ...(input.signal === undefined ? {} : { signal: input.signal }),
178
182
  });
@@ -1,4 +1,5 @@
1
1
  import { mkdir, open, rename, rm } from 'node:fs/promises';
2
+ import { ensurePrivateState } from '../infra/private-state.js';
2
3
  import { randomUUID } from 'node:crypto';
3
4
  import { join, relative, sep } from 'node:path';
4
5
  import { observePath, readFileBounded, resolveRealpath, sha256Digest, } from '../infra/fs.js';
@@ -62,6 +63,9 @@ export async function acquireCodePrepareLock(root, excludedRoots = []) {
62
63
  const boundary = await ensureCodeMutationBoundary(root, path, excludedRoots);
63
64
  if (!boundary.ok)
64
65
  return boundary;
66
+ const prepared = await ensurePrivateState(root);
67
+ if (!prepared.ok)
68
+ return prepared;
65
69
  try {
66
70
  await mkdir(directory, { recursive: true, mode: 0o700 });
67
71
  const content = Buffer.from(`${JSON.stringify({ pid: process.pid, token: randomUUID(), acquiredAt: new Date().toISOString() })}\n`);
@@ -249,6 +253,9 @@ export async function writeCodeRegistration(root, registration, excludedRoots =
249
253
  const boundary = await ensureCodeMutationBoundary(root, path, excludedRoots);
250
254
  if (!boundary.ok)
251
255
  return boundary;
256
+ const prepared = await ensurePrivateState(root);
257
+ if (!prepared.ok)
258
+ return prepared;
252
259
  const temporary = `${path}.tmp-${randomUUID()}`;
253
260
  const content = Buffer.from(`${JSON.stringify(registration, null, 2)}\n`);
254
261
  let owned = null;
@@ -1,3 +1,4 @@
1
+ import { type GitObservationScope } from '../infra/git.js';
1
2
  import type { Diagnostic } from '../schemas/diagnostics.js';
2
3
  import { type CodeIdentity, type CodeIndexHealth, type CodeIndexRegistration, type CodePreparePlan, type CodePrepareResult, type CodeQueryKind, type CodeQueryLimits, type CodeQueryResult } from '../schemas/code.js';
3
4
  import { codeIdentityDigest } from './identity.js';
@@ -13,6 +14,14 @@ export interface CodeStatusInput {
13
14
  readonly root: string;
14
15
  readonly repositoryId: string;
15
16
  readonly signal?: AbortSignal;
17
+ /**
18
+ * One operation's Git probe scope. Callers that run several service methods
19
+ * for a single command may pass one scope so workspace discovery and every
20
+ * identity probe share immutable repository observations. Omitted callers get
21
+ * a scope that lives only for this call: no result is ever cached across
22
+ * operations.
23
+ */
24
+ readonly observations?: GitObservationScope;
16
25
  }
17
26
  export interface CodePrepareInput extends CodeStatusInput {
18
27
  readonly apply: boolean;
@@ -1,3 +1,4 @@
1
+ import { createGitObservationScope, } from '../infra/git.js';
1
2
  import { sha256Digest } from '../infra/fs.js';
2
3
  import { createDiagnostic } from '../schemas/diagnostics.js';
3
4
  import { diagnosticCodes } from '../schemas/errors.js';
@@ -43,7 +44,7 @@ function fallbackHealth(state, reason, engineVersion = 'unknown') {
43
44
  observedAt: new Date().toISOString(),
44
45
  });
45
46
  }
46
- async function loadWorkspace(root) {
47
+ async function loadWorkspace(root, observations) {
47
48
  const config = await inspectWorkspaceConfig(root);
48
49
  const diagnostics = [...config.diagnostics];
49
50
  if (config.value === null) {
@@ -57,6 +58,7 @@ async function loadWorkspace(root) {
57
58
  machine: machine.value,
58
59
  configPath: config.path,
59
60
  options: discoveryOptions,
61
+ observations,
60
62
  });
61
63
  diagnostics.push(...repositories.diagnostics);
62
64
  return {
@@ -99,7 +101,9 @@ function overlayRegistration(raw, registration, registrationFailure, identity) {
99
101
  return raw;
100
102
  }
101
103
  async function observeCode(input) {
102
- const view = await loadWorkspace(input.root);
104
+ const observations = input.observations ??
105
+ createGitObservationScope({ workingTreeState: false });
106
+ const view = await loadWorkspace(input.root, observations);
103
107
  const diagnostics = [...view.diagnostics];
104
108
  const repository = selectRepository(view, input.repositoryId);
105
109
  if (repository === null) {
@@ -156,6 +160,7 @@ async function observeCode(input) {
156
160
  configStatus,
157
161
  excludedRoots,
158
162
  ...(input.signal === undefined ? {} : { signal: input.signal }),
163
+ observations,
159
164
  });
160
165
  if (!identity.ok) {
161
166
  diagnostics.push(outcomeDiagnostic(identity, repository.root));
@@ -297,7 +302,14 @@ export class CodeIntelligenceService {
297
302
  return { observed, plan };
298
303
  }
299
304
  async prepare(input) {
300
- const { observed, plan } = await this.planPrepare(input);
305
+ // Reuse probes within planning; refresh after external preparation because
306
+ // another writer or the engine may change HEAD while this call is awaiting.
307
+ const observations = input.observations ??
308
+ createGitObservationScope({ workingTreeState: false });
309
+ const { observed, plan } = await this.planPrepare({
310
+ ...input,
311
+ observations,
312
+ });
301
313
  if (!input.apply) {
302
314
  return {
303
315
  schema: 'pappra/code-prepare-result/1',
@@ -448,6 +460,7 @@ export class CodeIntelligenceService {
448
460
  configStatus: afterConfig.value.status,
449
461
  excludedRoots: observed.excludedRoots,
450
462
  ...(input.signal === undefined ? {} : { signal: input.signal }),
463
+ observations: createGitObservationScope({ workingTreeState: false }),
451
464
  });
452
465
  if (!afterIdentity.ok) {
453
466
  return {
package/dist/code/text.js CHANGED
@@ -8,6 +8,8 @@ import { failed, succeeded } from '../schemas/outcome.js';
8
8
  import { boundCodeItems } from './budget.js';
9
9
  const MAX_FILE_BYTES = 256 * 1024;
10
10
  const MAX_FILE_COUNT = 5000;
11
+ // Scanning and emitted JSON have independent budgets.
12
+ const MAX_SCAN_BYTES = 64 * 1024 * 1024;
11
13
  const EXCLUDES = [
12
14
  ':(exclude).codegraph',
13
15
  ':(exclude).pappra/local',
@@ -100,11 +102,18 @@ export async function runTextQuery(request, mode, signal) {
100
102
  const items = [];
101
103
  const evidence = [];
102
104
  const reasons = [];
103
- let bytes = 0;
105
+ let scannedBytes = 0;
104
106
  let truncated = list.value.stdout.split('\0').filter(Boolean).length > paths.length;
107
+ if (truncated)
108
+ reasons.push('file_limit');
105
109
  for (const path of paths) {
106
- if (items.length >= request.limits.maxResults ||
107
- bytes >= request.limits.maxBytes) {
110
+ if (signal?.aborted) {
111
+ reasons.push('cancelled');
112
+ truncated = true;
113
+ break;
114
+ }
115
+ if (items.length >= request.limits.maxResults) {
116
+ reasons.push('result_limit');
108
117
  truncated = true;
109
118
  break;
110
119
  }
@@ -135,9 +144,9 @@ export async function runTextQuery(request, mode, signal) {
135
144
  reasons.push('binary_skipped');
136
145
  continue;
137
146
  }
138
- bytes += read.value.size;
139
- if (bytes > request.limits.maxBytes) {
140
- bytes = request.limits.maxBytes;
147
+ scannedBytes += read.value.size;
148
+ if (scannedBytes > MAX_SCAN_BYTES) {
149
+ reasons.push('scan_budget');
141
150
  truncated = true;
142
151
  break;
143
152
  }
@@ -159,14 +168,17 @@ export async function runTextQuery(request, mode, signal) {
159
168
  });
160
169
  offset = lower.indexOf(needle, offset + Math.max(1, needle.length));
161
170
  }
162
- if (offset !== -1)
171
+ if (offset !== -1) {
163
172
  truncated = true;
173
+ reasons.push('result_limit');
174
+ }
164
175
  }
165
176
  else {
166
177
  const matches = structureMatches(text, request.query);
167
178
  for (const match of matches) {
168
179
  if (items.length >= request.limits.maxResults) {
169
180
  truncated = true;
181
+ reasons.push('result_limit');
170
182
  break;
171
183
  }
172
184
  items.push({ ...match, path });
@@ -38,6 +38,8 @@ export declare const TOOL_PROFILES: {
38
38
  reviewer: string;
39
39
  };
40
40
  };
41
+ /** Returns a runner only for an own supported harness key with a string value. */
42
+ export declare function runnerForHarness(harness: unknown): string | null;
41
43
  /**
42
44
  * Pre-dispatch admission. A launcher that started a native process without checking the
43
45
  * assignment, the capability snapshot, the collaboration record and the actual resource
@@ -50,6 +52,10 @@ export declare const TOOL_PROFILES: {
50
52
  * anything it has not observed
51
53
  */
52
54
  export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot, cwd, sessionId, harness, profile, launchKind, discovery, resumeSelector, now, maxAgeMinutes, }: AdmissionOptions): {
55
+ owner_epoch?: never;
56
+ detail?: never;
57
+ state?: never;
58
+ state_revision?: never;
53
59
  ok: false;
54
60
  reason: string;
55
61
  checks: Record<string, unknown>[];
@@ -58,10 +64,6 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
58
64
  required_skills?: never;
59
65
  required_tools?: never;
60
66
  preflight?: never;
61
- state?: never;
62
- detail?: never;
63
- state_revision?: never;
64
- owner_epoch?: never;
65
67
  attempt_state?: never;
66
68
  resources?: never;
67
69
  mode?: never;
@@ -73,18 +75,18 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
73
75
  assignment_digest?: never;
74
76
  input_revision?: never;
75
77
  } | {
78
+ expected?: never;
79
+ owner_epoch?: never;
80
+ detail?: never;
81
+ state?: never;
82
+ state_revision?: never;
76
83
  ok: false;
77
84
  reason: string;
78
85
  checks: Record<string, unknown>[];
79
- detail: string;
86
+ actual: string;
80
87
  required_skills?: never;
81
88
  required_tools?: never;
82
89
  preflight?: never;
83
- state?: never;
84
- expected?: never;
85
- actual?: never;
86
- state_revision?: never;
87
- owner_epoch?: never;
88
90
  attempt_state?: never;
89
91
  resources?: never;
90
92
  mode?: never;
@@ -96,18 +98,41 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
96
98
  assignment_digest?: never;
97
99
  input_revision?: never;
98
100
  } | {
101
+ expected?: never;
102
+ actual?: never;
103
+ owner_epoch?: never;
104
+ state?: never;
105
+ state_revision?: never;
99
106
  ok: false;
100
107
  reason: string;
101
108
  checks: Record<string, unknown>[];
109
+ detail: string;
102
110
  required_skills?: never;
103
111
  required_tools?: never;
104
112
  preflight?: never;
105
- state?: never;
106
- detail?: never;
113
+ attempt_state?: never;
114
+ resources?: never;
115
+ mode?: never;
116
+ launch_kind?: never;
117
+ resume_selector?: never;
118
+ pre_bound_identity?: never;
119
+ expected_identity?: never;
120
+ capability_evidence?: never;
121
+ assignment_digest?: never;
122
+ input_revision?: never;
123
+ } | {
107
124
  expected?: never;
108
125
  actual?: never;
109
- state_revision?: never;
110
126
  owner_epoch?: never;
127
+ detail?: never;
128
+ state?: never;
129
+ state_revision?: never;
130
+ ok: false;
131
+ reason: string;
132
+ checks: Record<string, unknown>[];
133
+ required_skills?: never;
134
+ required_tools?: never;
135
+ preflight?: never;
111
136
  attempt_state?: never;
112
137
  resources?: never;
113
138
  mode?: never;
@@ -119,6 +144,10 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
119
144
  assignment_digest?: never;
120
145
  input_revision?: never;
121
146
  } | {
147
+ owner_epoch?: never;
148
+ detail?: never;
149
+ state?: never;
150
+ state_revision?: never;
122
151
  ok: false;
123
152
  reason: string;
124
153
  checks: Record<string, unknown>[];
@@ -127,10 +156,6 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
127
156
  required_skills?: never;
128
157
  required_tools?: never;
129
158
  preflight?: never;
130
- state?: never;
131
- detail?: never;
132
- state_revision?: never;
133
- owner_epoch?: never;
134
159
  attempt_state?: never;
135
160
  resources?: never;
136
161
  mode?: never;
@@ -142,6 +167,10 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
142
167
  assignment_digest?: never;
143
168
  input_revision?: never;
144
169
  } | {
170
+ owner_epoch?: never;
171
+ detail?: never;
172
+ state?: never;
173
+ state_revision?: never;
145
174
  ok: false;
146
175
  reason: string;
147
176
  checks: Record<string, unknown>[];
@@ -155,10 +184,6 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
155
184
  required_skills?: never;
156
185
  required_tools?: never;
157
186
  preflight?: never;
158
- state?: never;
159
- detail?: never;
160
- state_revision?: never;
161
- owner_epoch?: never;
162
187
  attempt_state?: never;
163
188
  resources?: never;
164
189
  mode?: never;
@@ -170,6 +195,9 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
170
195
  assignment_digest?: never;
171
196
  input_revision?: never;
172
197
  } | {
198
+ owner_epoch?: never;
199
+ state?: never;
200
+ state_revision?: never;
173
201
  ok: false;
174
202
  reason: string;
175
203
  checks: Record<string, unknown>[];
@@ -179,9 +207,6 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
179
207
  required_skills?: never;
180
208
  required_tools?: never;
181
209
  preflight?: never;
182
- state?: never;
183
- state_revision?: never;
184
- owner_epoch?: never;
185
210
  attempt_state?: never;
186
211
  resources?: never;
187
212
  mode?: never;
@@ -193,18 +218,18 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
193
218
  assignment_digest?: never;
194
219
  input_revision?: never;
195
220
  } | {
221
+ expected?: never;
222
+ actual?: never;
223
+ owner_epoch?: never;
224
+ detail?: never;
225
+ state?: never;
226
+ state_revision?: never;
196
227
  ok: false;
197
228
  reason: string;
198
229
  checks: Record<string, unknown>[];
199
230
  required_skills: number;
200
231
  required_tools: number;
201
232
  preflight?: never;
202
- state?: never;
203
- detail?: never;
204
- expected?: never;
205
- actual?: never;
206
- state_revision?: never;
207
- owner_epoch?: never;
208
233
  attempt_state?: never;
209
234
  resources?: never;
210
235
  mode?: never;
@@ -216,19 +241,25 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
216
241
  assignment_digest?: never;
217
242
  input_revision?: never;
218
243
  } | {
244
+ expected?: never;
245
+ actual?: never;
246
+ owner_epoch?: never;
247
+ detail?: never;
248
+ state?: never;
249
+ state_revision?: never;
219
250
  required_skills?: never;
220
251
  required_tools?: never;
221
252
  ok: false;
222
253
  reason: string;
223
254
  checks: Record<string, unknown>[];
224
255
  preflight: {
256
+ attempt?: never;
225
257
  status: string;
226
258
  errors: string[];
227
259
  blockers: never[];
228
260
  warnings: never[];
229
261
  task_id?: never;
230
262
  assignment_id?: never;
231
- attempt?: never;
232
263
  checked_at?: never;
233
264
  limits?: never;
234
265
  } | {
@@ -242,12 +273,6 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
242
273
  warnings: import("./preflight.js").Check[];
243
274
  limits: string[];
244
275
  };
245
- state?: never;
246
- detail?: never;
247
- expected?: never;
248
- actual?: never;
249
- state_revision?: never;
250
- owner_epoch?: never;
251
276
  attempt_state?: never;
252
277
  resources?: never;
253
278
  mode?: never;
@@ -259,6 +284,11 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
259
284
  assignment_digest?: never;
260
285
  input_revision?: never;
261
286
  } | {
287
+ expected?: never;
288
+ actual?: never;
289
+ owner_epoch?: never;
290
+ detail?: never;
291
+ state_revision?: never;
262
292
  required_skills?: never;
263
293
  required_tools?: never;
264
294
  preflight?: never;
@@ -266,11 +296,6 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
266
296
  reason: string;
267
297
  checks: Record<string, unknown>[];
268
298
  state: string;
269
- detail?: never;
270
- expected?: never;
271
- actual?: never;
272
- state_revision?: never;
273
- owner_epoch?: never;
274
299
  attempt_state?: never;
275
300
  resources?: never;
276
301
  mode?: never;
@@ -282,18 +307,18 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
282
307
  assignment_digest?: never;
283
308
  input_revision?: never;
284
309
  } | {
310
+ owner_epoch?: never;
311
+ detail?: never;
312
+ state?: never;
313
+ state_revision?: never;
285
314
  required_skills?: never;
286
315
  required_tools?: never;
287
316
  preflight?: never;
288
- state?: never;
289
317
  ok: false;
290
318
  reason: string;
291
319
  checks: Record<string, unknown>[];
292
320
  expected: (string | null)[];
293
321
  actual: string;
294
- detail?: never;
295
- state_revision?: never;
296
- owner_epoch?: never;
297
322
  attempt_state?: never;
298
323
  resources?: never;
299
324
  mode?: never;
@@ -305,19 +330,19 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
305
330
  assignment_digest?: never;
306
331
  input_revision?: never;
307
332
  } | {
333
+ expected?: never;
334
+ actual?: never;
335
+ owner_epoch?: never;
336
+ state?: never;
337
+ state_revision?: never;
308
338
  required_skills?: never;
309
339
  required_tools?: never;
310
340
  preflight?: never;
311
- state?: never;
312
341
  ok: false;
313
342
  reason: string;
314
343
  checks: Record<string, unknown>[];
315
344
  resources: Record<string, unknown>[];
316
345
  detail: string;
317
- expected?: never;
318
- actual?: never;
319
- state_revision?: never;
320
- owner_epoch?: never;
321
346
  attempt_state?: never;
322
347
  mode?: never;
323
348
  launch_kind?: never;
@@ -328,19 +353,19 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
328
353
  assignment_digest?: never;
329
354
  input_revision?: never;
330
355
  } | {
356
+ owner_epoch?: never;
357
+ detail?: never;
358
+ state?: never;
359
+ state_revision?: never;
331
360
  required_skills?: never;
332
361
  required_tools?: never;
333
362
  preflight?: never;
334
- state?: never;
335
- detail?: never;
336
363
  ok: false;
337
364
  reason: string;
338
365
  checks: Record<string, unknown>[];
339
366
  resources: Record<string, unknown>[];
340
367
  expected: number | undefined;
341
368
  actual: number;
342
- state_revision?: never;
343
- owner_epoch?: never;
344
369
  attempt_state?: never;
345
370
  mode?: never;
346
371
  launch_kind?: never;
@@ -351,19 +376,19 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
351
376
  assignment_digest?: never;
352
377
  input_revision?: never;
353
378
  } | {
379
+ expected?: never;
380
+ actual?: never;
381
+ owner_epoch?: never;
382
+ detail?: never;
383
+ state?: never;
384
+ state_revision?: never;
354
385
  required_skills?: never;
355
386
  required_tools?: never;
356
387
  preflight?: never;
357
- state?: never;
358
- detail?: never;
359
- expected?: never;
360
- actual?: never;
361
388
  ok: false;
362
389
  reason: string;
363
390
  checks: Record<string, unknown>[];
364
391
  resources: Record<string, unknown>[];
365
- state_revision?: never;
366
- owner_epoch?: never;
367
392
  attempt_state?: never;
368
393
  mode?: never;
369
394
  launch_kind?: never;
@@ -374,14 +399,14 @@ export declare function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot
374
399
  assignment_digest?: never;
375
400
  input_revision?: never;
376
401
  } | {
402
+ reason?: never;
403
+ expected?: never;
404
+ actual?: never;
405
+ detail?: never;
406
+ state?: never;
377
407
  required_skills?: never;
378
408
  required_tools?: never;
379
409
  preflight?: never;
380
- state?: never;
381
- detail?: never;
382
- expected?: never;
383
- actual?: never;
384
- reason?: never;
385
410
  ok: true;
386
411
  checks: Record<string, unknown>[];
387
412
  state_revision: number;
@@ -35,11 +35,19 @@ export const TOOL_PROFILES = {
35
35
  },
36
36
  };
37
37
  /** The runner an assignment must name for a given harness; the launcher will not substitute one. */
38
- const RUNNER_FOR_HARNESS = {
38
+ const RUNNER_FOR_HARNESS = Object.freeze({
39
39
  pi: 'pi-cli',
40
40
  codex: 'codex-exec',
41
41
  claude: 'claude-cli',
42
- };
42
+ });
43
+ /** Returns a runner only for an own supported harness key with a string value. */
44
+ export function runnerForHarness(harness) {
45
+ if (typeof harness !== 'string' ||
46
+ !Object.hasOwn(RUNNER_FOR_HARNESS, harness))
47
+ return null;
48
+ const runner = RUNNER_FOR_HARNESS[harness];
49
+ return typeof runner === 'string' && runner.length > 0 ? runner : null;
50
+ }
43
51
  /** Whether the assignment can name the native session before the process starts. Pi and Claude
44
52
  * accept an explicit session id; `codex exec` chooses the thread id itself. */
45
53
  const PRE_BOUND_IDENTITY = {
@@ -83,10 +91,17 @@ export function admitLaunch({ assignmentFile, capabilitiesFile, taskRoot, cwd, s
83
91
  actual: harness,
84
92
  };
85
93
  }
86
- const expectedRunner = RUNNER_FOR_HARNESS[harness ?? assignment.assignee.harness];
87
- if (assignment.runner?.name &&
88
- expectedRunner &&
89
- assignment.runner.name !== expectedRunner) {
94
+ const requestedHarness = harness ?? assignment.assignee.harness;
95
+ const expectedRunner = runnerForHarness(requestedHarness);
96
+ if (expectedRunner === null) {
97
+ return {
98
+ ok: false,
99
+ reason: 'unsupported_harness',
100
+ checks,
101
+ actual: requestedHarness,
102
+ };
103
+ }
104
+ if (assignment.runner.name !== expectedRunner) {
90
105
  return {
91
106
  ok: false,
92
107
  reason: 'runner_contract_mismatch',
@@ -3,7 +3,7 @@ export declare const RESOURCE_KINDS: readonly string[];
3
3
  /**
4
4
  * Resolve the longest existing ancestor with realpath and append the not-yet-existing
5
5
  * suffix. Symlink aliases therefore collapse to one key. The suffix keeps the caller's
6
- * spelling, so a differently-cased non-existent target is not normalised.
6
+ * spelling for I/O; comparison keys account for the containing filesystem's case behavior.
7
7
  */
8
8
  export declare function canonicalizeTarget(input: string): {
9
9
  path: string;