agent-nuvira 3.3.3 → 3.3.5

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 (366) hide show
  1. package/README.md +13 -5
  2. package/dist/agent-sdk/src/agent.d.ts +2 -0
  3. package/dist/agent-sdk/src/agent.d.ts.map +1 -1
  4. package/dist/agent-sdk/src/define.d.ts +64 -0
  5. package/dist/agent-sdk/src/define.d.ts.map +1 -0
  6. package/dist/agent-sdk/src/define.js +76 -0
  7. package/dist/agent-sdk/src/define.js.map +1 -0
  8. package/dist/agent-sdk/src/index.d.ts +9 -0
  9. package/dist/agent-sdk/src/index.d.ts.map +1 -1
  10. package/dist/agent-sdk/src/index.js +9 -0
  11. package/dist/agent-sdk/src/index.js.map +1 -1
  12. package/dist/agent-sdk/src/scaffold.d.ts +11 -0
  13. package/dist/agent-sdk/src/scaffold.d.ts.map +1 -1
  14. package/dist/agent-sdk/src/scaffold.js +16 -6
  15. package/dist/agent-sdk/src/scaffold.js.map +1 -1
  16. package/dist/agents/long-form-plan.d.ts.map +1 -1
  17. package/dist/agents/long-form-plan.js +2 -1
  18. package/dist/agents/long-form-plan.js.map +1 -1
  19. package/dist/agents/orchestrator.d.ts.map +1 -1
  20. package/dist/agents/orchestrator.js +5 -4
  21. package/dist/agents/orchestrator.js.map +1 -1
  22. package/dist/cli/agent.d.ts +2 -2
  23. package/dist/cli/agent.js +10 -10
  24. package/dist/cli/chat.d.ts +94 -0
  25. package/dist/cli/chat.d.ts.map +1 -1
  26. package/dist/cli/chat.js +354 -20
  27. package/dist/cli/chat.js.map +1 -1
  28. package/dist/cli/cli-program.d.ts.map +1 -1
  29. package/dist/cli/cli-program.js +5 -0
  30. package/dist/cli/cli-program.js.map +1 -1
  31. package/dist/cli/config.d.ts.map +1 -1
  32. package/dist/cli/config.js +9 -1
  33. package/dist/cli/config.js.map +1 -1
  34. package/dist/cli/doctor.d.ts.map +1 -1
  35. package/dist/cli/doctor.js +3 -2
  36. package/dist/cli/doctor.js.map +1 -1
  37. package/dist/cli/edit.js +2 -2
  38. package/dist/cli/eval.d.ts +17 -0
  39. package/dist/cli/eval.d.ts.map +1 -1
  40. package/dist/cli/eval.js +105 -2
  41. package/dist/cli/eval.js.map +1 -1
  42. package/dist/cli/execute.d.ts +16 -1
  43. package/dist/cli/execute.d.ts.map +1 -1
  44. package/dist/cli/execute.js +192 -22
  45. package/dist/cli/execute.js.map +1 -1
  46. package/dist/cli/loop-executor.d.ts +55 -0
  47. package/dist/cli/loop-executor.d.ts.map +1 -1
  48. package/dist/cli/loop-executor.js +212 -13
  49. package/dist/cli/loop-executor.js.map +1 -1
  50. package/dist/cli/model.d.ts.map +1 -1
  51. package/dist/cli/model.js +9 -8
  52. package/dist/cli/model.js.map +1 -1
  53. package/dist/cli/models.d.ts +1 -1
  54. package/dist/cli/models.js +4 -4
  55. package/dist/cli/parity.d.ts +85 -0
  56. package/dist/cli/parity.d.ts.map +1 -0
  57. package/dist/cli/parity.js +506 -0
  58. package/dist/cli/parity.js.map +1 -0
  59. package/dist/cli/plan.d.ts.map +1 -1
  60. package/dist/cli/plan.js +2 -1
  61. package/dist/cli/plan.js.map +1 -1
  62. package/dist/cli/retrieval.d.ts.map +1 -1
  63. package/dist/cli/retrieval.js +5 -4
  64. package/dist/cli/retrieval.js.map +1 -1
  65. package/dist/cli/sdk.js +4 -4
  66. package/dist/cli/sdk.js.map +1 -1
  67. package/dist/cli/trace.d.ts.map +1 -1
  68. package/dist/cli/trace.js +2 -1
  69. package/dist/cli/trace.js.map +1 -1
  70. package/dist/cli/workflow.js +2 -2
  71. package/dist/cli/workflow.js.map +1 -1
  72. package/dist/config/process-env.d.ts +136 -0
  73. package/dist/config/process-env.d.ts.map +1 -0
  74. package/dist/config/process-env.js +217 -0
  75. package/dist/config/process-env.js.map +1 -0
  76. package/dist/config/types.d.ts +44 -0
  77. package/dist/config/types.d.ts.map +1 -1
  78. package/dist/findings/verdicts.d.ts +241 -0
  79. package/dist/findings/verdicts.d.ts.map +1 -0
  80. package/dist/findings/verdicts.js +284 -0
  81. package/dist/findings/verdicts.js.map +1 -0
  82. package/dist/gateway/adapters.d.ts +65 -0
  83. package/dist/gateway/adapters.d.ts.map +1 -1
  84. package/dist/gateway/adapters.js +216 -10
  85. package/dist/gateway/adapters.js.map +1 -1
  86. package/dist/gateway/channel-directory.d.ts +31 -0
  87. package/dist/gateway/channel-directory.d.ts.map +1 -1
  88. package/dist/gateway/channel-directory.js +40 -0
  89. package/dist/gateway/channel-directory.js.map +1 -1
  90. package/dist/gateway/gateway-log.d.ts +1 -1
  91. package/dist/gateway/gateway-log.d.ts.map +1 -1
  92. package/dist/gateway/gateway-log.js.map +1 -1
  93. package/dist/gateway/hooks.d.ts +87 -19
  94. package/dist/gateway/hooks.d.ts.map +1 -1
  95. package/dist/gateway/hooks.js +62 -23
  96. package/dist/gateway/hooks.js.map +1 -1
  97. package/dist/gateway/inbound-media.d.ts +147 -0
  98. package/dist/gateway/inbound-media.d.ts.map +1 -0
  99. package/dist/gateway/inbound-media.js +317 -0
  100. package/dist/gateway/inbound-media.js.map +1 -0
  101. package/dist/gateway/inbox.d.ts +8 -1
  102. package/dist/gateway/inbox.d.ts.map +1 -1
  103. package/dist/gateway/inbox.js.map +1 -1
  104. package/dist/gateway/platform-config.d.ts +14 -0
  105. package/dist/gateway/platform-config.d.ts.map +1 -1
  106. package/dist/gateway/platform-config.js +26 -8
  107. package/dist/gateway/platform-config.js.map +1 -1
  108. package/dist/gateway/realtime.d.ts +114 -0
  109. package/dist/gateway/realtime.d.ts.map +1 -0
  110. package/dist/gateway/realtime.js +402 -0
  111. package/dist/gateway/realtime.js.map +1 -0
  112. package/dist/gateway/registry.d.ts +31 -0
  113. package/dist/gateway/registry.d.ts.map +1 -1
  114. package/dist/gateway/registry.js +224 -4
  115. package/dist/gateway/registry.js.map +1 -1
  116. package/dist/gateway/whatsapp/baileys-bridge.d.ts +11 -1
  117. package/dist/gateway/whatsapp/baileys-bridge.d.ts.map +1 -1
  118. package/dist/gateway/whatsapp/baileys-bridge.js +123 -4
  119. package/dist/gateway/whatsapp/baileys-bridge.js.map +1 -1
  120. package/dist/gateway/whatsapp/bridge.d.ts +6 -2
  121. package/dist/gateway/whatsapp/bridge.d.ts.map +1 -1
  122. package/dist/gateway/whatsapp/bridge.js.map +1 -1
  123. package/dist/index.js +8 -0
  124. package/dist/index.js.map +1 -1
  125. package/dist/inference/factory.d.ts +14 -0
  126. package/dist/inference/factory.d.ts.map +1 -1
  127. package/dist/inference/factory.js +17 -0
  128. package/dist/inference/factory.js.map +1 -1
  129. package/dist/inference/groq-adapter.d.ts +2 -0
  130. package/dist/inference/groq-adapter.d.ts.map +1 -1
  131. package/dist/inference/groq-adapter.js +16 -6
  132. package/dist/inference/groq-adapter.js.map +1 -1
  133. package/dist/inference/tools.d.ts.map +1 -1
  134. package/dist/inference/tools.js +29 -0
  135. package/dist/inference/tools.js.map +1 -1
  136. package/dist/learning/benchmark.d.ts.map +1 -1
  137. package/dist/learning/benchmark.js +3 -2
  138. package/dist/learning/benchmark.js.map +1 -1
  139. package/dist/learning/continuation.d.ts.map +1 -1
  140. package/dist/learning/continuation.js +2 -1
  141. package/dist/learning/continuation.js.map +1 -1
  142. package/dist/learning/cost-tracker.d.ts.map +1 -1
  143. package/dist/learning/cost-tracker.js +2 -1
  144. package/dist/learning/cost-tracker.js.map +1 -1
  145. package/dist/learning/deferred-task.d.ts.map +1 -1
  146. package/dist/learning/deferred-task.js +13 -4
  147. package/dist/learning/deferred-task.js.map +1 -1
  148. package/dist/learning/eval-framework.d.ts.map +1 -1
  149. package/dist/learning/eval-framework.js +2 -1
  150. package/dist/learning/eval-framework.js.map +1 -1
  151. package/dist/learning/long-form.d.ts.map +1 -1
  152. package/dist/learning/long-form.js +2 -1
  153. package/dist/learning/long-form.js.map +1 -1
  154. package/dist/learning/model-reachability.d.ts +95 -0
  155. package/dist/learning/model-reachability.d.ts.map +1 -0
  156. package/dist/learning/model-reachability.js +111 -0
  157. package/dist/learning/model-reachability.js.map +1 -0
  158. package/dist/learning/model-registry.d.ts +22 -0
  159. package/dist/learning/model-registry.d.ts.map +1 -1
  160. package/dist/learning/model-registry.js +26 -1
  161. package/dist/learning/model-registry.js.map +1 -1
  162. package/dist/learning/model-verify-job.d.ts +131 -0
  163. package/dist/learning/model-verify-job.d.ts.map +1 -0
  164. package/dist/learning/model-verify-job.js +221 -0
  165. package/dist/learning/model-verify-job.js.map +1 -0
  166. package/dist/learning/reasoning-cache.d.ts.map +1 -1
  167. package/dist/learning/reasoning-cache.js +2 -1
  168. package/dist/learning/reasoning-cache.js.map +1 -1
  169. package/dist/learning/reasoning-trace.d.ts +37 -1
  170. package/dist/learning/reasoning-trace.d.ts.map +1 -1
  171. package/dist/learning/reasoning-trace.js +66 -0
  172. package/dist/learning/reasoning-trace.js.map +1 -1
  173. package/dist/learning/resilient-call.d.ts.map +1 -1
  174. package/dist/learning/resilient-call.js +2 -1
  175. package/dist/learning/resilient-call.js.map +1 -1
  176. package/dist/learning/retrieval.d.ts.map +1 -1
  177. package/dist/learning/retrieval.js +2 -1
  178. package/dist/learning/retrieval.js.map +1 -1
  179. package/dist/learning/seeded-benchmark.d.ts +160 -0
  180. package/dist/learning/seeded-benchmark.d.ts.map +1 -0
  181. package/dist/learning/seeded-benchmark.js +321 -0
  182. package/dist/learning/seeded-benchmark.js.map +1 -0
  183. package/dist/learning/seeded-bugs.d.ts +142 -0
  184. package/dist/learning/seeded-bugs.d.ts.map +1 -0
  185. package/dist/learning/seeded-bugs.js +535 -0
  186. package/dist/learning/seeded-bugs.js.map +1 -0
  187. package/dist/learning/step-checkpoint.d.ts +127 -0
  188. package/dist/learning/step-checkpoint.d.ts.map +1 -0
  189. package/dist/learning/step-checkpoint.js +244 -0
  190. package/dist/learning/step-checkpoint.js.map +1 -0
  191. package/dist/nlu/intent-confirm.d.ts +23 -1
  192. package/dist/nlu/intent-confirm.d.ts.map +1 -1
  193. package/dist/nlu/intent-confirm.js +85 -2
  194. package/dist/nlu/intent-confirm.js.map +1 -1
  195. package/dist/nlu/learnings.d.ts +7 -0
  196. package/dist/nlu/learnings.d.ts.map +1 -1
  197. package/dist/nlu/learnings.js +7 -0
  198. package/dist/nlu/learnings.js.map +1 -1
  199. package/dist/observability/debug-log.d.ts +250 -0
  200. package/dist/observability/debug-log.d.ts.map +1 -0
  201. package/dist/observability/debug-log.js +500 -0
  202. package/dist/observability/debug-log.js.map +1 -0
  203. package/dist/observability/event-bus.d.ts.map +1 -1
  204. package/dist/observability/event-bus.js +4 -1
  205. package/dist/observability/event-bus.js.map +1 -1
  206. package/dist/observability/otel.d.ts +278 -0
  207. package/dist/observability/otel.d.ts.map +1 -0
  208. package/dist/observability/otel.js +590 -0
  209. package/dist/observability/otel.js.map +1 -0
  210. package/dist/parity/drivers.d.ts +99 -0
  211. package/dist/parity/drivers.d.ts.map +1 -0
  212. package/dist/parity/drivers.js +1362 -0
  213. package/dist/parity/drivers.js.map +1 -0
  214. package/dist/parity/graph.d.ts +73 -0
  215. package/dist/parity/graph.d.ts.map +1 -0
  216. package/dist/parity/graph.js +162 -0
  217. package/dist/parity/graph.js.map +1 -0
  218. package/dist/parity/matrix.d.ts +105 -0
  219. package/dist/parity/matrix.d.ts.map +1 -0
  220. package/dist/parity/matrix.js +352 -0
  221. package/dist/parity/matrix.js.map +1 -0
  222. package/dist/parity/observation.d.ts +444 -0
  223. package/dist/parity/observation.d.ts.map +1 -0
  224. package/dist/parity/observation.js +333 -0
  225. package/dist/parity/observation.js.map +1 -0
  226. package/dist/parity/scenarios.d.ts +229 -0
  227. package/dist/parity/scenarios.d.ts.map +1 -0
  228. package/dist/parity/scenarios.js +175 -0
  229. package/dist/parity/scenarios.js.map +1 -0
  230. package/dist/parity/surfaces.d.ts +122 -0
  231. package/dist/parity/surfaces.d.ts.map +1 -0
  232. package/dist/parity/surfaces.js +190 -0
  233. package/dist/parity/surfaces.js.map +1 -0
  234. package/dist/runtime/fault-injection.d.ts +173 -0
  235. package/dist/runtime/fault-injection.d.ts.map +1 -0
  236. package/dist/runtime/fault-injection.js +281 -0
  237. package/dist/runtime/fault-injection.js.map +1 -0
  238. package/dist/tools/child-agent-entry.d.ts +23 -0
  239. package/dist/tools/child-agent-entry.d.ts.map +1 -0
  240. package/dist/tools/child-agent-entry.js +129 -0
  241. package/dist/tools/child-agent-entry.js.map +1 -0
  242. package/dist/tools/child-agent-runtime.d.ts +124 -0
  243. package/dist/tools/child-agent-runtime.d.ts.map +1 -0
  244. package/dist/tools/child-agent-runtime.js +704 -0
  245. package/dist/tools/child-agent-runtime.js.map +1 -0
  246. package/dist/tools/coding-tools.d.ts.map +1 -1
  247. package/dist/tools/coding-tools.js +82 -10
  248. package/dist/tools/coding-tools.js.map +1 -1
  249. package/dist/tools/delegation-system.d.ts +31 -0
  250. package/dist/tools/delegation-system.d.ts.map +1 -1
  251. package/dist/tools/delegation-system.js +70 -9
  252. package/dist/tools/delegation-system.js.map +1 -1
  253. package/dist/tools/extract/docx.d.ts +27 -0
  254. package/dist/tools/extract/docx.d.ts.map +1 -0
  255. package/dist/tools/extract/docx.js +48 -0
  256. package/dist/tools/extract/docx.js.map +1 -0
  257. package/dist/tools/extract/html-text.d.ts +27 -0
  258. package/dist/tools/extract/html-text.d.ts.map +1 -0
  259. package/dist/tools/extract/html-text.js +86 -0
  260. package/dist/tools/extract/html-text.js.map +1 -0
  261. package/dist/tools/extract/pdf-ocr.d.ts +58 -0
  262. package/dist/tools/extract/pdf-ocr.d.ts.map +1 -0
  263. package/dist/tools/extract/pdf-ocr.js +116 -0
  264. package/dist/tools/extract/pdf-ocr.js.map +1 -0
  265. package/dist/tools/extract/pdf.d.ts +65 -0
  266. package/dist/tools/extract/pdf.d.ts.map +1 -0
  267. package/dist/tools/extract/pdf.js +197 -0
  268. package/dist/tools/extract/pdf.js.map +1 -0
  269. package/dist/tools/extract/pptx.d.ts +32 -0
  270. package/dist/tools/extract/pptx.d.ts.map +1 -0
  271. package/dist/tools/extract/pptx.js +77 -0
  272. package/dist/tools/extract/pptx.js.map +1 -0
  273. package/dist/tools/extract/xlsx.d.ts +47 -0
  274. package/dist/tools/extract/xlsx.d.ts.map +1 -0
  275. package/dist/tools/extract/xlsx.js +111 -0
  276. package/dist/tools/extract/xlsx.js.map +1 -0
  277. package/dist/tools/finding-tool.d.ts +76 -0
  278. package/dist/tools/finding-tool.d.ts.map +1 -0
  279. package/dist/tools/finding-tool.js +125 -0
  280. package/dist/tools/finding-tool.js.map +1 -0
  281. package/dist/tools/messaging-tools.d.ts +41 -11
  282. package/dist/tools/messaging-tools.d.ts.map +1 -1
  283. package/dist/tools/messaging-tools.js +104 -55
  284. package/dist/tools/messaging-tools.js.map +1 -1
  285. package/dist/tools/neutts-synth.d.ts +27 -3
  286. package/dist/tools/neutts-synth.d.ts.map +1 -1
  287. package/dist/tools/neutts-synth.js +57 -13
  288. package/dist/tools/neutts-synth.js.map +1 -1
  289. package/dist/tools/pipeline-tool.d.ts +43 -1
  290. package/dist/tools/pipeline-tool.d.ts.map +1 -1
  291. package/dist/tools/pipeline-tool.js +13 -2
  292. package/dist/tools/pipeline-tool.js.map +1 -1
  293. package/dist/tools/read-extract.d.ts +116 -45
  294. package/dist/tools/read-extract.d.ts.map +1 -1
  295. package/dist/tools/read-extract.js +494 -158
  296. package/dist/tools/read-extract.js.map +1 -1
  297. package/dist/tools/registry.d.ts +2 -2
  298. package/dist/tools/registry.d.ts.map +1 -1
  299. package/dist/tools/registry.js +152 -23
  300. package/dist/tools/registry.js.map +1 -1
  301. package/dist/tools/subagent-refusal.d.ts +15 -0
  302. package/dist/tools/subagent-refusal.d.ts.map +1 -0
  303. package/dist/tools/subagent-refusal.js +18 -0
  304. package/dist/tools/subagent-refusal.js.map +1 -0
  305. package/dist/tools/subagent-spawner.d.ts +122 -0
  306. package/dist/tools/subagent-spawner.d.ts.map +1 -1
  307. package/dist/tools/subagent-spawner.js +249 -28
  308. package/dist/tools/subagent-spawner.js.map +1 -1
  309. package/dist/tools/tool-hooks.d.ts +177 -0
  310. package/dist/tools/tool-hooks.d.ts.map +1 -0
  311. package/dist/tools/tool-hooks.js +427 -0
  312. package/dist/tools/tool-hooks.js.map +1 -0
  313. package/dist/tools/tool-loop.d.ts +82 -0
  314. package/dist/tools/tool-loop.d.ts.map +1 -1
  315. package/dist/tools/tool-loop.js +167 -9
  316. package/dist/tools/tool-loop.js.map +1 -1
  317. package/dist/tools/tool-refusal.d.ts +68 -0
  318. package/dist/tools/tool-refusal.d.ts.map +1 -0
  319. package/dist/tools/tool-refusal.js +78 -0
  320. package/dist/tools/tool-refusal.js.map +1 -0
  321. package/dist/tools/toolsets.d.ts +8 -0
  322. package/dist/tools/toolsets.d.ts.map +1 -1
  323. package/dist/tools/toolsets.js +12 -2
  324. package/dist/tools/toolsets.js.map +1 -1
  325. package/dist/tools/vision-tools.d.ts +88 -83
  326. package/dist/tools/vision-tools.d.ts.map +1 -1
  327. package/dist/tools/vision-tools.js +134 -103
  328. package/dist/tools/vision-tools.js.map +1 -1
  329. package/dist/tools/worktree.d.ts +210 -0
  330. package/dist/tools/worktree.d.ts.map +1 -0
  331. package/dist/tools/worktree.js +374 -0
  332. package/dist/tools/worktree.js.map +1 -0
  333. package/dist/utils/format.d.ts +3 -0
  334. package/dist/utils/format.d.ts.map +1 -0
  335. package/dist/utils/format.js +32 -0
  336. package/dist/utils/format.js.map +1 -0
  337. package/dist/web-dashboard/attachment-extract.d.ts +64 -0
  338. package/dist/web-dashboard/attachment-extract.d.ts.map +1 -0
  339. package/dist/web-dashboard/attachment-extract.js +154 -0
  340. package/dist/web-dashboard/attachment-extract.js.map +1 -0
  341. package/dist/web-dashboard/chat-console.d.ts +108 -1
  342. package/dist/web-dashboard/chat-console.d.ts.map +1 -1
  343. package/dist/web-dashboard/chat-console.js +36 -0
  344. package/dist/web-dashboard/chat-console.js.map +1 -1
  345. package/dist/web-dashboard/hub-data.d.ts +37 -0
  346. package/dist/web-dashboard/hub-data.d.ts.map +1 -1
  347. package/dist/web-dashboard/hub-data.js +61 -1
  348. package/dist/web-dashboard/hub-data.js.map +1 -1
  349. package/dist/web-dashboard/process-env-inventory.d.ts +57 -0
  350. package/dist/web-dashboard/process-env-inventory.d.ts.map +1 -0
  351. package/dist/web-dashboard/process-env-inventory.js +96 -0
  352. package/dist/web-dashboard/process-env-inventory.js.map +1 -0
  353. package/dist/web-dashboard/server.d.ts +14 -0
  354. package/dist/web-dashboard/server.d.ts.map +1 -1
  355. package/dist/web-dashboard/server.js +493 -30
  356. package/dist/web-dashboard/server.js.map +1 -1
  357. package/dist/web-dashboard/src/types.d.ts +261 -48
  358. package/dist/web-dashboard/src/types.d.ts.map +1 -1
  359. package/package.json +18 -3
  360. package/src/web-dashboard/public/assets/{index-Cyd6tIew.css → index-CIJ6FHHZ.css} +1 -1
  361. package/src/web-dashboard/public/assets/index-CsySzR41.js +207 -0
  362. package/src/web-dashboard/public/assets/index-CsySzR41.js.map +1 -0
  363. package/src/web-dashboard/public/index.html +2 -2
  364. package/dist/tools/child-agent-worker.js +0 -212
  365. package/src/web-dashboard/public/assets/index-CxDj7p6i.js +0 -207
  366. package/src/web-dashboard/public/assets/index-CxDj7p6i.js.map +0 -1
@@ -0,0 +1,175 @@
1
+ /**
2
+ * WS0 (#22) — one scenario, every surface, one verdict.
3
+ *
4
+ * The registry (`surfaces.ts`) answers "which surfaces exist and what do they
5
+ * run through". This module answers the harder question: did they behave the
6
+ * same, and is the verdict trustworthy.
7
+ *
8
+ * THREE RULES, each closing a way a parity test lies:
9
+ *
10
+ * 1. STUB DEPTH MUST BE COMPARABLE. Every driver records where its stub sits.
11
+ * `provider` (a stub provider object) and `transport` (a real provider
12
+ * object talking to a stub SERVER — the forked subagent child) both run the
13
+ * real turn code end to end, so they are ONE comparable class; folding them
14
+ * together is what makes the child readable against the in-process
15
+ * surfaces. `engine` replaces the very behaviour under test, so it never
16
+ * compares with anything, itself included. A run that would have to compare
17
+ * incomparable depths is refused rather than answered.
18
+ *
19
+ * 2. SKIPPED SURFACES ARE NAMED. A surface that cannot be driven appears in
20
+ * `skipped` with the reason it is missing. Silence is how a harness ends up
21
+ * "passing" for months while covering one surface.
22
+ *
23
+ * 3. TWO SURFACES IS THE MINIMUM. One available driver is not a parity run; it
24
+ * is a smoke test wearing a parity label. That case reports
25
+ * `insufficient`, never `at-par`.
26
+ *
27
+ * 4. THE TURN MUST HAVE REACHED A MODEL. The response cache is shared and
28
+ * enabled on the `answerOnce` path, so the second surface of a run can be
29
+ * served from the first one's entry — same answer, no model call, no tool
30
+ * lifecycle, and a flawless "agreement" between two replays that proves
31
+ * nothing. Measured, not hypothetical: before this rule existed, the second
32
+ * surface of every two-driver run was a cache hit (the drivers now isolate
33
+ * the cache per turn as well — belt and braces, because either guard alone
34
+ * would be one edit away from being removed).
35
+ * A zero is refused as `unreached-model` rather than compared.
36
+ *
37
+ * Pure by construction: no `fs`, no `vi`, no process env — which is what lets
38
+ * both the test suite and `nuvira parity run` import it. The drivers that
39
+ * actually drive a turn live in `./drivers.ts` (transport depth, a loopback stub
40
+ * server), so the CLI and CI run the SAME mechanism instead of two copies that
41
+ * could disagree.
42
+ */
43
+ import { compare } from './observation.js';
44
+ /**
45
+ * Drive one scenario through every available driver and compare the results.
46
+ *
47
+ * Order matters only for the report: the first available driver is the baseline.
48
+ * Driver order is the caller's, so a scenario can pin a baseline deliberately.
49
+ */
50
+ export async function runParityScenario(scenario, drivers) {
51
+ const skipped = drivers
52
+ .filter((d) => !d.available)
53
+ .map((d) => ({ surface: d.surface, reason: d.blockedBy ?? 'no reason recorded' }));
54
+ const available = drivers.filter((d) => d.available);
55
+ if (available.length < 2) {
56
+ return {
57
+ scenario: scenario.id,
58
+ depth: null,
59
+ observations: [],
60
+ differences: [],
61
+ skipped,
62
+ verdict: 'not-run',
63
+ refusal: {
64
+ kind: 'insufficient-coverage',
65
+ available: available.map((d) => d.surface),
66
+ message: `only ${available.length} surface(s) can be driven for "${scenario.id}"` +
67
+ (skipped.length > 0 ? `; skipped: ${skipped.map((s) => `${s.surface} (${s.reason})`).join('; ')}` : '') +
68
+ '. A parity verdict needs at least two.',
69
+ },
70
+ };
71
+ }
72
+ const depths = [...new Set(available.map((d) => d.depth))];
73
+ // R2 — `provider` and `transport` are one comparable class (see rule 1 in the
74
+ // header). `engine` never compares, whether or not it is paired with anything.
75
+ if (depths.includes('engine')) {
76
+ return {
77
+ scenario: scenario.id,
78
+ depth: null,
79
+ observations: [],
80
+ differences: [],
81
+ skipped,
82
+ verdict: 'not-run',
83
+ refusal: {
84
+ kind: 'depth-mismatch',
85
+ depths: available.map((d) => ({ surface: d.surface, depth: d.depth })),
86
+ message: `a stub sits at the ENGINE depth (${depths.join(', ')}), so a verdict would be meaningless: ` +
87
+ 'that surface has had the behaviour under test replaced, and it can never be compared — ' +
88
+ 'not with a provider stub, and not with another engine stub. ' +
89
+ 'Re-drive it at provider or transport depth, or declare the gap.',
90
+ },
91
+ };
92
+ }
93
+ /** No single depth to report when comparable depths were mixed. */
94
+ const reportedDepth = depths.length === 1 ? depths[0] : null;
95
+ const observations = [];
96
+ for (const driver of available)
97
+ observations.push(await driver.run(scenario));
98
+ // Rule 4. Checked BEFORE comparing, because a zero would otherwise surface as
99
+ // a "divergence" in modelCalls — the right refusal with the wrong name.
100
+ const unreached = observations.filter((observation) => observation.modelCalls === 0);
101
+ if (unreached.length > 0) {
102
+ return {
103
+ scenario: scenario.id,
104
+ depth: reportedDepth,
105
+ observations,
106
+ differences: [],
107
+ skipped,
108
+ verdict: 'not-run',
109
+ refusal: {
110
+ kind: 'unreached-model',
111
+ surfaces: unreached.map((observation) => observation.surface),
112
+ message: `no model call on: ${unreached.map((o) => o.surface).join(', ')}. ` +
113
+ 'A turn served without reaching a model — a response-cache replay, or a ' +
114
+ 'surface answering from a shortcut — did no routing and no tool work, so ' +
115
+ 'comparing it says nothing. Isolate the cache (or use a distinct message) ' +
116
+ 'and re-run before reading any verdict from this scenario.',
117
+ },
118
+ };
119
+ }
120
+ const [baseline, ...rest] = observations;
121
+ // WS6 (#28) — a scenario that DECLARES a fault is compared on the FAULT-HONESTY
122
+ // projection instead of the full one, and the reason is measured rather than
123
+ // aesthetic: under a fatal dependency failure the surfaces legitimately differ in
124
+ // every other field. The CLI, the GUI, a messaging bridge and a forked child
125
+ // have different user-facing copy, different error taxonomies, different
126
+ // last-attempt attributions and different retry counts — comparing those would
127
+ // report four correct surfaces as divergent and bury the one fact the row is
128
+ // about. What must NOT differ is whether the failure was reported as a failure.
129
+ const differences = scenario.fault
130
+ ? rest.flatMap((observation) => compareFaultHonesty(baseline, observation))
131
+ : rest.flatMap((observation) => compare(baseline, observation));
132
+ return {
133
+ scenario: scenario.id,
134
+ depth: reportedDepth,
135
+ observations,
136
+ differences,
137
+ skipped,
138
+ verdict: differences.length === 0 ? 'at-par' : 'divergent',
139
+ };
140
+ }
141
+ /**
142
+ * WS6 (#28) — the fields a FAULT row is compared on: what the turn was given, and
143
+ * whether it reported the consequence.
144
+ *
145
+ * `status` and the fault's own `asked`/`site`/`kind` say both surfaces were told
146
+ * the same thing and ended the same way; `took` is the load-bearing one, because a
147
+ * surface that SWALLOWED the fault — completed a turn the backend never served, or
148
+ * reported an injected tool failure as a success — reads `took: false` against
149
+ * every other surface's `true`. A swallowed fault leaves no other trace, which is
150
+ * why it is a compared field and not something a test reads off one surface.
151
+ *
152
+ * Deliberately absent: `answer`, `errorCode`, `provider`/`transport`/`model`,
153
+ * `debugLog`, `otel`, `modelCalls` and `toolCalls`. Each of those legitimately
154
+ * differs under a fatal fault (a messaging surface has no bubble to fill; a child
155
+ * announces its transport before it fails; the last attempt a debug header names
156
+ * is the fallback, not the provider that errored). They are still recorded on the
157
+ * observation for the failure report — only the comparison excludes them.
158
+ */
159
+ export function compareFaultHonesty(a, b) {
160
+ const differences = [];
161
+ const who = `${a.surface} vs ${b.surface}`;
162
+ if (a.status !== b.status) {
163
+ differences.push(`${who}: status differs — ${a.status} vs ${b.status}`);
164
+ }
165
+ const fields = ['asked', 'site', 'kind', 'took'];
166
+ for (const field of fields) {
167
+ const l = a.fault[field];
168
+ const r = b.fault[field];
169
+ if (l !== r) {
170
+ differences.push(`${who}: fault.${field} differs — ${String(l)} vs ${String(r)}`);
171
+ }
172
+ }
173
+ return differences;
174
+ }
175
+ //# sourceMappingURL=scenarios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenarios.js","sourceRoot":"","sources":["../../src/parity/scenarios.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * WS0 (#22) — the surface registry.
3
+ *
4
+ * WHY THIS FILE EXISTS. Before a capability can be promised on "every surface"
5
+ * (WS1-WS7), the set of surfaces has to be DECLARED. Inferred from whatever
6
+ * happens to import what, it is invisible: nothing fails when a new
7
+ * implementation appears beside the shared one, and nothing fails when a
8
+ * capability lands on one surface and quietly misses three.
9
+ *
10
+ * MEASURED, and the reason this is not paranoia — four ways to run an agent turn
11
+ * already exist over three engine labels:
12
+ *
13
+ * - `src/cli/chat.ts` runs a turn through its own `answerOnce`
14
+ * (`cli/chat.ts:502`), which the dashboard drives too
15
+ * (`web-dashboard/chat-console.ts:391` lazily imports ChatCommand, `:618`
16
+ * awaits `engine.answerOnce`), and which the gateway chat engine also calls
17
+ * (`cli/chat.ts:625` — "the chat console and the gateway chat engine both
18
+ * call answerOnce"). This one IS shared, and it is the model for the rest.
19
+ * - `src/cli/loop-executor.ts:196` `runLoopExecutor` — the loop engine.
20
+ * - `src/tools/pipeline-tool.ts:76` `runPipelineTool` — the pipeline engine,
21
+ * which is the ONLY way the gateway runs a non-chat turn.
22
+ * - `src/cli/execute.ts` picks between them itself (`:1655` direct, `:1725`
23
+ * loop, `:2009` pipeline) and reaches the provider factory directly, so its
24
+ * engine choice and provider construction live in the surface.
25
+ *
26
+ * Also measured: `src/web-dashboard/server.ts` does not import any turn entry —
27
+ * it reaches `answerOnce` indirectly through `chat-console.ts`, which is why
28
+ * `turnEntries` below records what a surface ends up using rather than what it
29
+ * imports literally. `surfacesReaching` (see `parity/graph.ts`) does the
30
+ * transitive check.
31
+ *
32
+ * This module is DATA plus pure lookups on purpose: it is what the parity test
33
+ * and the capability matrix read, so it must be cheap to import from a test and
34
+ * free of side effects.
35
+ */
36
+ import type { EngineMode } from '../learning/engine-router.js';
37
+ /** The surfaces a person can talk to agent-nuvira through. */
38
+ export type SurfaceId = 'cli-chat' | 'cli-execute' | 'dashboard-chat' | 'gateway-chat' | 'subagent';
39
+ /**
40
+ * The shared turn entries. A surface runs a turn through one of these, or it is
41
+ * a silo — which is exactly what the architecture test in
42
+ * `tests/parity/cross-surface.test.ts` fails on.
43
+ */
44
+ export type TurnEntryId = 'chat-once' | 'loop-executor' | 'pipeline-tool' | 'orchestrator' | 'child-runtime';
45
+ export interface TurnEntry {
46
+ id: TurnEntryId;
47
+ /** Repo-relative module that exports the entry. */
48
+ module: string;
49
+ /** The exported symbol a surface calls. */
50
+ symbol: string;
51
+ /** Engines this entry can serve. */
52
+ engines: readonly EngineMode[];
53
+ note: string;
54
+ }
55
+ export interface SurfaceDescriptor {
56
+ id: SurfaceId;
57
+ label: string;
58
+ /**
59
+ * Repo-relative modules that OWN the surface (the thing a person addresses).
60
+ * Paths, not globs: the registry is meant to be read.
61
+ */
62
+ modules: readonly string[];
63
+ /** Shared turn entries this surface uses, transitively. */
64
+ turnEntries: readonly TurnEntryId[];
65
+ /**
66
+ * Engine labels observable through this surface. More than one entry means
67
+ * the surface chooses, and a parity test must exercise each.
68
+ */
69
+ engines: readonly EngineMode[];
70
+ /**
71
+ * True when the surface runs in its own process. Such a surface legitimately
72
+ * builds its own provider and loop (that IS the isolation), so the
73
+ * in-process rules below do not apply to it — but its observable behaviour
74
+ * still must match, which is what the normalised observation checks.
75
+ */
76
+ separateProcess?: boolean;
77
+ /** How a parity test drives this surface headlessly. */
78
+ headless: string;
79
+ }
80
+ /**
81
+ * The shared entries. `engines` is what the entry can serve, not what every
82
+ * caller uses: the gateway only ever asks `pipeline-tool` for pipeline work.
83
+ */
84
+ export declare const TURN_ENTRIES: Record<TurnEntryId, TurnEntry>;
85
+ /**
86
+ * Known surface-level debt, keyed by what is wrong and why it is still here.
87
+ *
88
+ * This is a RATCHET, not an allowlist of convenience: the architecture test
89
+ * asserts the observed violations EQUAL this list, so adding a new bypass fails,
90
+ * and removing one without deleting its entry fails too (a stale entry would
91
+ * otherwise hide the next one). Every entry is somebody's workstream.
92
+ *
93
+ * BOTH ARE EMPTY NOW. `src/cli/execute.ts` was the whole list: it built its own
94
+ * provider and drove the pipeline engine through a private `Orchestrator`. It
95
+ * now resolves through the shared `resolveProvider` and runs pipeline turns
96
+ * through `runPipelineTool`. The keys stay declared with empty arrays on
97
+ * purpose — deleting a key would stop the rule from being measured at all, and
98
+ * the next bypass would then be invisible instead of a one-line diff here.
99
+ */
100
+ export declare const SURFACE_DEBT: Record<string, readonly string[]>;
101
+ /**
102
+ * Every surface, with the evidence that it exists. Order is display order only.
103
+ */
104
+ export declare const SURFACES: readonly SurfaceDescriptor[];
105
+ /** A surface by id, or undefined. */
106
+ export declare function surfaceById(id: SurfaceId): SurfaceDescriptor | undefined;
107
+ /** Every surface that runs a turn through `entry`, directly or transitively. */
108
+ export declare function surfacesReaching(entry: TurnEntryId): SurfaceDescriptor[];
109
+ /**
110
+ * Every (surface, engine) pair a parity test must exercise. A surface that can
111
+ * select between engines contributes one pair per engine, so a capability that
112
+ * works under `loop` and fails under `pipeline` cannot pass unnoticed.
113
+ */
114
+ export declare function parityMatrix(): Array<{
115
+ surface: SurfaceId;
116
+ engine: EngineMode;
117
+ }>;
118
+ /** Repo-relative paths of the surface-owned modules. */
119
+ export declare function surfaceModulePaths(): string[];
120
+ /** Repo-relative paths of the shared turn entries. */
121
+ export declare function turnEntryModulePaths(): string[];
122
+ //# sourceMappingURL=surfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../../src/parity/surfaces.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE/D,8DAA8D;AAC9D,MAAM,MAAM,SAAS,GACjB,UAAU,GACV,aAAa,GACb,gBAAgB,GAChB,cAAc,GACd,UAAU,CAAC;AAEf;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,eAAe,GACf,eAAe,GACf,cAAc,GACd,eAAe,CAAC;AAEpB,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,WAAW,CAAC;IAChB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,SAAS,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,2DAA2D;IAC3D,WAAW,EAAE,SAAS,WAAW,EAAE,CAAC;IACpC;;;OAGG;IACH,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,WAAW,EAAE,SAAS,CAoCvD,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAK1D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,iBAAiB,EA2DhD,CAAC;AAEF,qCAAqC;AACrC,wBAAgB,WAAW,CAAC,EAAE,EAAE,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAExE;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,iBAAiB,EAAE,CAExE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,KAAK,CAAC;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,CAMhF;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAE7C;AAED,sDAAsD;AACtD,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * WS0 (#22) — the surface registry.
3
+ *
4
+ * WHY THIS FILE EXISTS. Before a capability can be promised on "every surface"
5
+ * (WS1-WS7), the set of surfaces has to be DECLARED. Inferred from whatever
6
+ * happens to import what, it is invisible: nothing fails when a new
7
+ * implementation appears beside the shared one, and nothing fails when a
8
+ * capability lands on one surface and quietly misses three.
9
+ *
10
+ * MEASURED, and the reason this is not paranoia — four ways to run an agent turn
11
+ * already exist over three engine labels:
12
+ *
13
+ * - `src/cli/chat.ts` runs a turn through its own `answerOnce`
14
+ * (`cli/chat.ts:502`), which the dashboard drives too
15
+ * (`web-dashboard/chat-console.ts:391` lazily imports ChatCommand, `:618`
16
+ * awaits `engine.answerOnce`), and which the gateway chat engine also calls
17
+ * (`cli/chat.ts:625` — "the chat console and the gateway chat engine both
18
+ * call answerOnce"). This one IS shared, and it is the model for the rest.
19
+ * - `src/cli/loop-executor.ts:196` `runLoopExecutor` — the loop engine.
20
+ * - `src/tools/pipeline-tool.ts:76` `runPipelineTool` — the pipeline engine,
21
+ * which is the ONLY way the gateway runs a non-chat turn.
22
+ * - `src/cli/execute.ts` picks between them itself (`:1655` direct, `:1725`
23
+ * loop, `:2009` pipeline) and reaches the provider factory directly, so its
24
+ * engine choice and provider construction live in the surface.
25
+ *
26
+ * Also measured: `src/web-dashboard/server.ts` does not import any turn entry —
27
+ * it reaches `answerOnce` indirectly through `chat-console.ts`, which is why
28
+ * `turnEntries` below records what a surface ends up using rather than what it
29
+ * imports literally. `surfacesReaching` (see `parity/graph.ts`) does the
30
+ * transitive check.
31
+ *
32
+ * This module is DATA plus pure lookups on purpose: it is what the parity test
33
+ * and the capability matrix read, so it must be cheap to import from a test and
34
+ * free of side effects.
35
+ */
36
+ /**
37
+ * The shared entries. `engines` is what the entry can serve, not what every
38
+ * caller uses: the gateway only ever asks `pipeline-tool` for pipeline work.
39
+ */
40
+ export const TURN_ENTRIES = {
41
+ 'chat-once': {
42
+ id: 'chat-once',
43
+ module: 'src/cli/chat.ts',
44
+ symbol: 'ChatCommand.answerOnce',
45
+ engines: ['loop'],
46
+ note: 'The interactive engine. Shared by the CLI chat, the dashboard console and the gateway chat path — the only entry that is genuinely cross-surface today, and therefore the template for the others.',
47
+ },
48
+ 'loop-executor': {
49
+ id: 'loop-executor',
50
+ module: 'src/cli/loop-executor.ts',
51
+ symbol: 'runLoopExecutor',
52
+ engines: ['loop'],
53
+ note: 'The loop engine as a library. Written to give `nuvira execute` the exposure the chat path already had, so it is the intended replacement for the surface-level branch in execute.ts.',
54
+ },
55
+ 'pipeline-tool': {
56
+ id: 'pipeline-tool',
57
+ module: 'src/tools/pipeline-tool.ts',
58
+ symbol: 'runPipelineTool',
59
+ engines: ['pipeline'],
60
+ note: 'The pipeline engine, reached through the orchestrator. The gateway runs every non-chat turn through this, which is why the gateway is pipeline-only.',
61
+ },
62
+ orchestrator: {
63
+ id: 'orchestrator',
64
+ module: 'src/agents/orchestrator.ts',
65
+ symbol: 'Orchestrator',
66
+ engines: ['pipeline'],
67
+ note: 'The pipeline engine core, owned by the `pipeline-tool` wrapper. A surface that reaches it DIRECTLY is driving pipeline turns itself — legitimate, but it bypasses the wrapper`s provider resolution, understand-card and checkpoint default, which is what SURFACE_DEBT used to record for `cli/execute.ts`. No surface does today; the entry stays declared because the wrapper itself is one, and the rule needs something to measure against.',
68
+ },
69
+ 'child-runtime': {
70
+ id: 'child-runtime',
71
+ module: 'src/tools/child-agent-runtime.ts',
72
+ symbol: 'runSubagent',
73
+ engines: ['loop'],
74
+ note: 'The subagent child process. It builds its own provider and loop on purpose: it is the isolation boundary, and it reports the provider/model/transport it actually used so the parent can attribute the run.',
75
+ },
76
+ };
77
+ /**
78
+ * Known surface-level debt, keyed by what is wrong and why it is still here.
79
+ *
80
+ * This is a RATCHET, not an allowlist of convenience: the architecture test
81
+ * asserts the observed violations EQUAL this list, so adding a new bypass fails,
82
+ * and removing one without deleting its entry fails too (a stale entry would
83
+ * otherwise hide the next one). Every entry is somebody's workstream.
84
+ *
85
+ * BOTH ARE EMPTY NOW. `src/cli/execute.ts` was the whole list: it built its own
86
+ * provider and drove the pipeline engine through a private `Orchestrator`. It
87
+ * now resolves through the shared `resolveProvider` and runs pipeline turns
88
+ * through `runPipelineTool`. The keys stay declared with empty arrays on
89
+ * purpose — deleting a key would stop the rule from being measured at all, and
90
+ * the next bypass would then be invisible instead of a one-line diff here.
91
+ */
92
+ export const SURFACE_DEBT = {
93
+ /** Surface modules that construct their own provider instead of going through a shared entry. */
94
+ 'provider-factory': [],
95
+ /** Surface modules that drive the pipeline engine without the `pipeline-tool` wrapper. */
96
+ 'pipeline-wrapper-bypass': [],
97
+ };
98
+ /**
99
+ * Every surface, with the evidence that it exists. Order is display order only.
100
+ */
101
+ export const SURFACES = [
102
+ {
103
+ id: 'cli-chat',
104
+ label: 'CLI chat',
105
+ modules: ['src/cli/chat.ts', 'src/cli/cli-program.ts'],
106
+ // Two entries, not one: measured, `chat.ts:87` imports `runPipelineTool` and
107
+ // calls it at `:702`, so the chat surface can also run a pipeline turn. The
108
+ // engine is chosen by the user's explicit command (`:298` checks
109
+ // `action.run === 'pipeline'`), NOT by the router — which is why this
110
+ // surface declares both engines and the parity matrix exercises both.
111
+ turnEntries: ['chat-once', 'pipeline-tool'],
112
+ engines: ['loop', 'pipeline'],
113
+ headless: 'Drive ChatCommand.answerOnce with a stub provider and an in-memory askUser responder (the shape chat-console.ts already uses); drive the pipeline path through the same runPipelineTool wrapper.',
114
+ },
115
+ {
116
+ id: 'cli-execute',
117
+ label: 'CLI execute / one-shot',
118
+ modules: ['src/cli/execute.ts', 'src/cli/run.ts'],
119
+ // `pipeline-tool` IS here now: measured, `execute.ts` drives its pipeline
120
+ // runs through the wrapper. It used to import the Orchestrator directly and
121
+ // never reach the wrapper — exactly the drift this registry exists to
122
+ // surface, and the reason it was the sole entry on
123
+ // `SURFACE_DEBT['pipeline-wrapper-bypass']`.
124
+ // `chat-once` is here for the same measured reason as ever: execute.ts
125
+ // reaches the chat engine through `import('./chat.js')`, which is also how
126
+ // its interactive mode works.
127
+ turnEntries: ['chat-once', 'loop-executor', 'pipeline-tool'],
128
+ engines: ['loop', 'pipeline'],
129
+ headless: 'Drive the command`s own single-goal path (`runSingleGoal`) with the provider stubbed at the shared factory and the engine pinned to loop, and read the turn AND its attribution (provider/model/transport) and its per-call tool outcomes off what the command returns. Both of the command`s arms report now — the loop engine through `runLoopExecutor` and the direct chat answer through the engine`s `onToolCall`.',
130
+ },
131
+ {
132
+ id: 'dashboard-chat',
133
+ label: 'Dashboard chat',
134
+ modules: ['src/web-dashboard/server.ts', 'src/web-dashboard/chat-console.ts'],
135
+ turnEntries: ['chat-once'],
136
+ engines: ['loop'],
137
+ headless: 'Call the turn through chat-console with a stub provider and no HTTP transport; the console is the seam, not the server.',
138
+ },
139
+ {
140
+ id: 'gateway-chat',
141
+ label: 'Gateway (Slack / Discord / Telegram / …)',
142
+ modules: [
143
+ 'src/gateway/registry.ts',
144
+ 'src/gateway/adapters.ts',
145
+ 'src/gateway/realtime.ts',
146
+ ],
147
+ turnEntries: ['chat-once', 'pipeline-tool'],
148
+ engines: ['loop', 'pipeline'],
149
+ headless: 'Invoke the registry handler with a synthetic inbound message and a stub adapter; no live transport, no credentials.',
150
+ },
151
+ {
152
+ id: 'subagent',
153
+ label: 'Subagent child process',
154
+ modules: ['src/tools/child-agent-runtime.ts', 'src/tools/child-agent-entry.ts'],
155
+ turnEntries: ['child-runtime'],
156
+ engines: ['loop'],
157
+ separateProcess: true,
158
+ headless: 'Spawn the child entry with a stub provider over its IPC frames, as tests/tools/subagent-end-to-end.test.ts does.',
159
+ },
160
+ ];
161
+ /** A surface by id, or undefined. */
162
+ export function surfaceById(id) {
163
+ return SURFACES.find((s) => s.id === id);
164
+ }
165
+ /** Every surface that runs a turn through `entry`, directly or transitively. */
166
+ export function surfacesReaching(entry) {
167
+ return SURFACES.filter((s) => s.turnEntries.includes(entry));
168
+ }
169
+ /**
170
+ * Every (surface, engine) pair a parity test must exercise. A surface that can
171
+ * select between engines contributes one pair per engine, so a capability that
172
+ * works under `loop` and fails under `pipeline` cannot pass unnoticed.
173
+ */
174
+ export function parityMatrix() {
175
+ const pairs = [];
176
+ for (const surface of SURFACES) {
177
+ for (const engine of surface.engines)
178
+ pairs.push({ surface: surface.id, engine });
179
+ }
180
+ return pairs;
181
+ }
182
+ /** Repo-relative paths of the surface-owned modules. */
183
+ export function surfaceModulePaths() {
184
+ return [...new Set(SURFACES.flatMap((s) => s.modules))].sort();
185
+ }
186
+ /** Repo-relative paths of the shared turn entries. */
187
+ export function turnEntryModulePaths() {
188
+ return Object.values(TURN_ENTRIES).map((e) => e.module).sort();
189
+ }
190
+ //# sourceMappingURL=surfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surfaces.js","sourceRoot":"","sources":["../../src/parity/surfaces.ts"],"names":[],"mappings":"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"}