@iislee/opencodex 2.11.0 → 2.35.0

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 (733) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +117 -22
  3. package/bin/ocx.mjs +245 -88
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-Be1sDpWw.css +1 -0
  6. package/gui/dist/assets/index-D4OKgUV4.js +114 -0
  7. package/gui/dist/index.html +2 -2
  8. package/gui/dist/provider-icons/alibaba-color.svg +1 -1
  9. package/gui/dist/provider-icons/antigravity-color.svg +1 -1
  10. package/gui/dist/provider-icons/claude-color.svg +1 -1
  11. package/gui/dist/provider-icons/cline-color.svg +16 -0
  12. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
  13. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  14. package/gui/dist/provider-icons/copilot-color.svg +1 -1
  15. package/gui/dist/provider-icons/cursor-color.svg +1 -1
  16. package/gui/dist/provider-icons/deepseek-color.svg +1 -1
  17. package/gui/dist/provider-icons/firepass-color.svg +1 -1
  18. package/gui/dist/provider-icons/fireworks-color.svg +1 -1
  19. package/gui/dist/provider-icons/gemini-color.svg +1 -1
  20. package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
  21. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
  22. package/gui/dist/provider-icons/grok.svg +1 -1
  23. package/gui/dist/provider-icons/groq-color.svg +1 -1
  24. package/gui/dist/provider-icons/huggingface-color.svg +1 -1
  25. package/gui/dist/provider-icons/kimi-color.svg +1 -1
  26. package/gui/dist/provider-icons/kiro-color.svg +2 -2
  27. package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
  28. package/gui/dist/provider-icons/mistral-color.svg +1 -1
  29. package/gui/dist/provider-icons/moonshot-color.svg +1 -1
  30. package/gui/dist/provider-icons/nvidia-color.svg +1 -1
  31. package/gui/dist/provider-icons/ollama-color.svg +1 -1
  32. package/gui/dist/provider-icons/openai.svg +1 -1
  33. package/gui/dist/provider-icons/opencode.svg +2 -1
  34. package/gui/dist/provider-icons/openrouter-color.svg +1 -1
  35. package/gui/dist/provider-icons/pi.svg +2 -2
  36. package/gui/dist/provider-icons/qianfan-color.svg +1 -1
  37. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
  38. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
  39. package/gui/dist/provider-icons/vllm-color.svg +1 -1
  40. package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
  41. package/package.json +21 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +475 -62
  44. package/src/adapters/base.ts +82 -7
  45. package/src/adapters/client-fingerprint.ts +18 -12
  46. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  47. package/src/adapters/command-code.ts +637 -0
  48. package/src/adapters/cursor/call-id.ts +44 -0
  49. package/src/adapters/cursor/catalog.ts +541 -0
  50. package/src/adapters/cursor/checkpoint-store.ts +308 -0
  51. package/src/adapters/cursor/cursor-errors.ts +144 -6
  52. package/src/adapters/cursor/discovery.ts +122 -14
  53. package/src/adapters/cursor/effort-map.ts +106 -4
  54. package/src/adapters/cursor/envelope-echo.ts +290 -0
  55. package/src/adapters/cursor/framing.ts +39 -0
  56. package/src/adapters/cursor/h2-pool.ts +123 -0
  57. package/src/adapters/cursor/http1-bidi.ts +361 -0
  58. package/src/adapters/cursor/images.ts +704 -0
  59. package/src/adapters/cursor/live-models.ts +180 -59
  60. package/src/adapters/cursor/live-transport.ts +623 -170
  61. package/src/adapters/cursor/message-mapper.ts +4 -1
  62. package/src/adapters/cursor/native-exec-common.ts +23 -2
  63. package/src/adapters/cursor/native-exec-desktop.ts +23 -0
  64. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  65. package/src/adapters/cursor/native-exec-network.ts +1 -1
  66. package/src/adapters/cursor/native-exec-shell.ts +5 -3
  67. package/src/adapters/cursor/native-exec.ts +121 -14
  68. package/src/adapters/cursor/protobuf-events.ts +829 -11
  69. package/src/adapters/cursor/protobuf-request.ts +447 -75
  70. package/src/adapters/cursor/request-builder.ts +271 -35
  71. package/src/adapters/cursor/tool-definitions.ts +252 -12
  72. package/src/adapters/cursor/tool-result-normalize.ts +115 -0
  73. package/src/adapters/cursor/transport.ts +22 -0
  74. package/src/adapters/cursor/types.ts +48 -1
  75. package/src/adapters/cursor.ts +336 -39
  76. package/src/adapters/exec-tool-result-normalize.ts +99 -0
  77. package/src/adapters/google-antigravity-replay.ts +713 -41
  78. package/src/adapters/google-antigravity-wire.ts +48 -10
  79. package/src/adapters/google-errors.ts +44 -12
  80. package/src/adapters/google-http.ts +38 -10
  81. package/src/adapters/google-tool-schema.ts +80 -15
  82. package/src/adapters/google-truncation.ts +11 -0
  83. package/src/adapters/google.ts +742 -86
  84. package/src/adapters/identity.ts +39 -6
  85. package/src/adapters/image.ts +1 -1
  86. package/src/adapters/kiro-constants.ts +27 -0
  87. package/src/adapters/kiro-errors.ts +11 -0
  88. package/src/adapters/kiro-events.ts +19 -1
  89. package/src/adapters/kiro-thinking.ts +18 -2
  90. package/src/adapters/kiro-tools.ts +65 -17
  91. package/src/adapters/kiro.ts +270 -73
  92. package/src/adapters/mimo-free.ts +17 -0
  93. package/src/adapters/openai-chat-url.ts +11 -0
  94. package/src/adapters/openai-chat.ts +1377 -344
  95. package/src/adapters/openai-responses-url.ts +16 -0
  96. package/src/adapters/openai-responses.ts +1164 -64
  97. package/src/adapters/registry.ts +175 -0
  98. package/src/adapters/responses-tool-schema.ts +67 -0
  99. package/src/adapters/run-turn-queue.ts +36 -1
  100. package/src/adapters/tool-call-id.ts +119 -0
  101. package/src/adapters/tool-catalog-nudge.ts +105 -21
  102. package/src/adapters/xai-tool-schema.ts +436 -0
  103. package/src/adapters/xai-web-search.ts +186 -0
  104. package/src/bridge.ts +512 -92
  105. package/src/chat/inbound.ts +57 -20
  106. package/src/chat/outbound.ts +97 -33
  107. package/src/claude/agents-inject.ts +40 -10
  108. package/src/claude/context-windows.ts +37 -14
  109. package/src/claude/desktop-3p.ts +243 -9
  110. package/src/claude/gateway-cache.ts +41 -4
  111. package/src/claude/inbound.ts +72 -3
  112. package/src/claude/model-info.ts +38 -15
  113. package/src/claude/outbound.ts +88 -21
  114. package/src/cli/access.ts +46 -3
  115. package/src/cli/account-api.ts +150 -19
  116. package/src/cli/account-auth.ts +33 -6
  117. package/src/cli/account-catalog-refresh.ts +14 -0
  118. package/src/cli/account-extended.ts +648 -28
  119. package/src/cli/account-main.ts +317 -0
  120. package/src/cli/account.ts +97 -19
  121. package/src/cli/agent.ts +53 -2
  122. package/src/cli/alias.ts +66 -0
  123. package/src/cli/capabilities-command.ts +94 -0
  124. package/src/cli/capabilities.ts +496 -0
  125. package/src/cli/claude-agent-startup-sync.ts +73 -0
  126. package/src/cli/claude-desktop.ts +60 -15
  127. package/src/cli/claude.ts +129 -35
  128. package/src/cli/codex-log-guard-doctor.ts +103 -0
  129. package/src/cli/codex-shim-autorestore.ts +2 -0
  130. package/src/cli/codex-shim-readiness.ts +76 -0
  131. package/src/cli/combo.ts +8 -0
  132. package/src/cli/config-command.ts +74 -10
  133. package/src/cli/dispatch.ts +821 -0
  134. package/src/cli/doctor.ts +440 -56
  135. package/src/cli/ensure-desired-integrations.ts +152 -0
  136. package/src/cli/export-command.ts +46 -20
  137. package/src/cli/help.ts +34 -274
  138. package/src/cli/index.ts +417 -528
  139. package/src/cli/init.ts +5 -17
  140. package/src/cli/inspect.ts +230 -0
  141. package/src/cli/integrations.ts +120 -2
  142. package/src/cli/lab.ts +607 -0
  143. package/src/cli/launcher-context.ts +77 -0
  144. package/src/cli/minimax.ts +497 -0
  145. package/src/cli/models-runtime.ts +130 -2
  146. package/src/cli/models.ts +118 -16
  147. package/src/cli/observe.ts +123 -11
  148. package/src/cli/opencode.ts +4 -2
  149. package/src/cli/provider-runtime.ts +34 -3
  150. package/src/cli/provider.ts +25 -3
  151. package/src/cli/ready.ts +301 -0
  152. package/src/cli/registry.ts +476 -0
  153. package/src/cli/root.ts +86 -0
  154. package/src/cli/route-policy.ts +92 -0
  155. package/src/cli/runtime-api.ts +57 -10
  156. package/src/cli/star-prompt.ts +71 -15
  157. package/src/cli/status.ts +51 -4
  158. package/src/cli/storage.ts +234 -0
  159. package/src/cli/system-command.ts +16 -0
  160. package/src/cli/system-restart-client.ts +146 -0
  161. package/src/cli/tray-proxy.ts +153 -6
  162. package/src/cli/usage-report.ts +184 -0
  163. package/src/cli/v2.ts +137 -18
  164. package/src/cli/version-skew.ts +46 -0
  165. package/src/cli.ts +1 -1
  166. package/src/clients/config-export.ts +1442 -23
  167. package/src/clients/effective-status.ts +30 -2
  168. package/src/clients/probes/cline.ts +81 -0
  169. package/src/codex/account-label.ts +35 -1
  170. package/src/codex/account-lifecycle.ts +130 -13
  171. package/src/codex/account-namespaces.ts +49 -3
  172. package/src/codex/account-pause.ts +2 -1
  173. package/src/codex/account-priority.ts +84 -0
  174. package/src/codex/account-store.ts +29 -2
  175. package/src/codex/account-usability.ts +25 -2
  176. package/src/codex/admission.ts +256 -0
  177. package/src/codex/affinity-debug.ts +162 -0
  178. package/src/codex/app-server-processes.ts +570 -107
  179. package/src/codex/app-server-restart-service.ts +232 -0
  180. package/src/codex/auth-api.ts +893 -246
  181. package/src/codex/auth-collision.ts +5 -3
  182. package/src/codex/auth-context.ts +348 -32
  183. package/src/codex/autostart-health.ts +24 -1
  184. package/src/codex/catalog/account-models.ts +67 -0
  185. package/src/codex/catalog/aggregation.ts +86 -10
  186. package/src/codex/catalog/bundled.ts +331 -33
  187. package/src/codex/catalog/effort.ts +138 -32
  188. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  189. package/src/codex/catalog/kinds.ts +2 -0
  190. package/src/codex/catalog/metadata.ts +555 -45
  191. package/src/codex/catalog/native-models.ts +75 -0
  192. package/src/codex/catalog/parsing.ts +269 -30
  193. package/src/codex/catalog/provider-fetch.ts +1626 -144
  194. package/src/codex/catalog/sync.ts +1576 -187
  195. package/src/codex/catalog-admission.ts +199 -0
  196. package/src/codex/catalog-refresh-status.ts +105 -0
  197. package/src/codex/catalog-write-serialization.ts +242 -0
  198. package/src/codex/catalog.ts +6 -3
  199. package/src/codex/codex-write-lock.ts +386 -0
  200. package/src/codex/convergence-types.ts +614 -0
  201. package/src/codex/convergence.ts +676 -0
  202. package/src/codex/coordinator-doctor.ts +332 -0
  203. package/src/codex/custom-model-catalog-migration.ts +176 -0
  204. package/src/codex/desired-state.ts +230 -0
  205. package/src/codex/desktop-app-restart.ts +355 -0
  206. package/src/codex/features.ts +636 -39
  207. package/src/codex/generation.ts +202 -0
  208. package/src/codex/history-job.ts +436 -0
  209. package/src/codex/history-lock.ts +242 -0
  210. package/src/codex/history-manifest.ts +112 -0
  211. package/src/codex/history-migration-guardian.ts +30 -24
  212. package/src/codex/history-provider.ts +1016 -235
  213. package/src/codex/history-transition.ts +105 -0
  214. package/src/codex/history-worker.ts +223 -0
  215. package/src/codex/inject-coordination.ts +373 -0
  216. package/src/codex/inject.ts +1114 -152
  217. package/src/codex/injected-marker.ts +37 -3
  218. package/src/codex/integration-record.ts +266 -0
  219. package/src/codex/internal/catalog-writer.ts +203 -0
  220. package/src/codex/internal/history-writer.ts +81 -0
  221. package/src/codex/journal.ts +66 -4
  222. package/src/codex/log-guard/inspect.ts +524 -0
  223. package/src/codex/log-guard/lock.ts +150 -0
  224. package/src/codex/log-guard/maintenance.ts +403 -0
  225. package/src/codex/log-guard/path-safety.ts +88 -0
  226. package/src/codex/log-guard/policy.ts +44 -0
  227. package/src/codex/log-guard/processes.ts +205 -0
  228. package/src/codex/log-guard/protection.ts +489 -0
  229. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  230. package/src/codex/main-account-cache.ts +24 -0
  231. package/src/codex/main-account.ts +29 -1
  232. package/src/codex/management-convergence.ts +167 -0
  233. package/src/codex/model-cache.ts +56 -10
  234. package/src/codex/model-entitlements.ts +360 -0
  235. package/src/codex/native-main-admission.ts +47 -0
  236. package/src/codex/native-main-auth-temp.ts +187 -0
  237. package/src/codex/native-main-claim.ts +178 -0
  238. package/src/codex/native-main-lock-file.ts +162 -0
  239. package/src/codex/native-main-owner.ts +329 -0
  240. package/src/codex/native-profile-api.ts +247 -0
  241. package/src/codex/native-profile-manager.ts +1531 -0
  242. package/src/codex/native-profile-processes.ts +121 -0
  243. package/src/codex/native-profile-recovery.ts +99 -0
  244. package/src/codex/native-profile-stage-store.ts +387 -0
  245. package/src/codex/native-profile-startup.ts +622 -0
  246. package/src/codex/native-profile-store.ts +855 -0
  247. package/src/codex/native-profile-types.ts +120 -0
  248. package/src/codex/native-residue.ts +675 -0
  249. package/src/codex/paths.ts +80 -1
  250. package/src/codex/plan-from-token.ts +140 -0
  251. package/src/codex/plan.ts +40 -0
  252. package/src/codex/plugins-doctor.ts +1 -1
  253. package/src/codex/pool-rotation.ts +74 -4
  254. package/src/codex/project-config-warnings.ts +20 -6
  255. package/src/codex/prompt-journal.ts +352 -0
  256. package/src/codex/prompt-layers.ts +1313 -0
  257. package/src/codex/prompt-lock.ts +143 -0
  258. package/src/codex/prompt-text-probe.ts +238 -0
  259. package/src/codex/quota-rejection.ts +298 -0
  260. package/src/codex/quota.ts +264 -21
  261. package/src/codex/refresh.ts +11 -2
  262. package/src/codex/reset-credit-recovery.ts +1044 -0
  263. package/src/codex/routing.ts +514 -94
  264. package/src/codex/runtime.ts +159 -38
  265. package/src/codex/shim.ts +1065 -31
  266. package/src/codex/subagent-model-fallback.ts +437 -43
  267. package/src/codex/sync.ts +191 -2
  268. package/src/codex/transition-state.ts +720 -0
  269. package/src/codex/upstream-host-health.ts +368 -0
  270. package/src/codex/user-identity.ts +557 -0
  271. package/src/codex/warmup.ts +187 -81
  272. package/src/codex/write-coordination.ts +114 -0
  273. package/src/combos/failover.ts +47 -0
  274. package/src/combos/index.ts +4 -0
  275. package/src/combos/request.ts +32 -0
  276. package/src/combos/types.ts +91 -9
  277. package/src/compatibility/index.ts +26 -0
  278. package/src/compatibility/manifest.ts +253 -0
  279. package/src/compatibility/openai-responses.ts +121 -0
  280. package/src/config/atomic-write.ts +219 -0
  281. package/src/config/paths.ts +40 -0
  282. package/src/config/process-state.ts +309 -0
  283. package/src/config/provider-name.ts +24 -0
  284. package/src/config/provider-validation.ts +177 -0
  285. package/src/config/rebase-provenance.ts +68 -0
  286. package/src/config.ts +1713 -709
  287. package/src/generated/compatibility-version.json +3324 -0
  288. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  289. package/src/grok/inject.ts +16 -5
  290. package/src/grok/inspect.ts +45 -0
  291. package/src/grok/sync.ts +2 -2
  292. package/src/images/loop.ts +157 -33
  293. package/src/images/plan.ts +24 -13
  294. package/src/integrations/config-io.ts +269 -0
  295. package/src/integrations/journal.ts +315 -0
  296. package/src/integrations/merge.ts +135 -0
  297. package/src/integrations/mutation-flight.ts +71 -0
  298. package/src/integrations/native/ownership-preflight.ts +202 -0
  299. package/src/integrations/omp-yaml-source.ts +358 -0
  300. package/src/integrations/owned-refresh.ts +74 -0
  301. package/src/integrations/ownership-policy.ts +160 -0
  302. package/src/integrations/ownership.ts +155 -0
  303. package/src/integrations/registry.ts +166 -0
  304. package/src/integrations/serialize.ts +314 -0
  305. package/src/integrations/state.ts +433 -0
  306. package/src/integrations/store.ts +103 -0
  307. package/src/integrations/writer-lock.ts +98 -0
  308. package/src/integrations/writer.ts +715 -0
  309. package/src/lab/artifacts/sanitize.ts +586 -0
  310. package/src/lab/artifacts/secure-fs.ts +475 -0
  311. package/src/lab/artifacts/store.ts +310 -0
  312. package/src/lab/automation/budgets.ts +78 -0
  313. package/src/lab/automation/config-persistence.ts +256 -0
  314. package/src/lab/automation/constants.ts +39 -0
  315. package/src/lab/automation/cooldown.ts +103 -0
  316. package/src/lab/automation/dispatch.ts +211 -0
  317. package/src/lab/automation/index.ts +13 -0
  318. package/src/lab/automation/orchestrator.ts +499 -0
  319. package/src/lab/automation/persistence.ts +512 -0
  320. package/src/lab/automation/planner.ts +371 -0
  321. package/src/lab/automation/policy.ts +136 -0
  322. package/src/lab/automation/queue.ts +191 -0
  323. package/src/lab/automation/recovery.ts +24 -0
  324. package/src/lab/automation/route-context.ts +21 -0
  325. package/src/lab/automation/run-key.ts +44 -0
  326. package/src/lab/automation/runs-query.ts +34 -0
  327. package/src/lab/automation/types.ts +160 -0
  328. package/src/lab/conformance/assertion.ts +325 -0
  329. package/src/lab/conformance/digest.ts +22 -0
  330. package/src/lab/conformance/executor.ts +741 -0
  331. package/src/lab/conformance/fixture-provider.ts +27 -0
  332. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  333. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  334. package/src/lab/conformance/harness-budget.ts +47 -0
  335. package/src/lab/conformance/index.ts +5 -0
  336. package/src/lab/conformance/jcs.ts +64 -0
  337. package/src/lab/conformance/json-pointer.ts +39 -0
  338. package/src/lab/conformance/manifest.ts +180 -0
  339. package/src/lab/conformance/mcp-stub.ts +179 -0
  340. package/src/lab/conformance/negative-controls.ts +164 -0
  341. package/src/lab/conformance/observation.ts +355 -0
  342. package/src/lab/conformance/runner.ts +68 -0
  343. package/src/lab/conformance/sse-normalize.ts +59 -0
  344. package/src/lab/conformance/suite-manifest.ts +78 -0
  345. package/src/lab/conformance/types.ts +214 -0
  346. package/src/lab/constants.ts +126 -0
  347. package/src/lab/digest.ts +64 -0
  348. package/src/lab/events/errors.ts +9 -0
  349. package/src/lab/events/limits.ts +117 -0
  350. package/src/lab/events/types.ts +229 -0
  351. package/src/lab/events/validate.ts +781 -0
  352. package/src/lab/fabric/constants.ts +40 -0
  353. package/src/lab/fabric/executor.ts +492 -0
  354. package/src/lab/fabric/index.ts +80 -0
  355. package/src/lab/fabric/manifest.ts +222 -0
  356. package/src/lab/fabric/observe.ts +489 -0
  357. package/src/lab/fabric/patch.ts +79 -0
  358. package/src/lab/fabric/producer-child.ts +139 -0
  359. package/src/lab/fabric/producer-isolate.ts +276 -0
  360. package/src/lab/fabric/producer-protocol.ts +61 -0
  361. package/src/lab/fabric/scratch.ts +439 -0
  362. package/src/lab/fabric/subject.ts +106 -0
  363. package/src/lab/fabric/types.ts +134 -0
  364. package/src/lab/fabric/verifier.ts +98 -0
  365. package/src/lab/index.ts +54 -0
  366. package/src/lab/ledger/artifact-refs.ts +127 -0
  367. package/src/lab/ledger/invalidation.ts +136 -0
  368. package/src/lab/ledger/purge.ts +310 -0
  369. package/src/lab/ledger/store.ts +532 -0
  370. package/src/lab/live/credential-lease.ts +53 -0
  371. package/src/lab/live/destination.ts +155 -0
  372. package/src/lab/live/executor.ts +336 -0
  373. package/src/lab/live/inert-tools.ts +56 -0
  374. package/src/lab/live/manifest.ts +85 -0
  375. package/src/lab/live/mcp-loopback.ts +57 -0
  376. package/src/lab/live/runner.ts +19 -0
  377. package/src/lab/live/sandbox.ts +61 -0
  378. package/src/lab/live/suite-manifest.ts +41 -0
  379. package/src/lab/live/transport.ts +118 -0
  380. package/src/lab/live/types.ts +197 -0
  381. package/src/lab/observe/from-conformance.ts +301 -0
  382. package/src/lab/observe/from-live.ts +117 -0
  383. package/src/lab/paths.ts +153 -0
  384. package/src/lab/projection/rebuild.ts +495 -0
  385. package/src/lab/projection/schema.ts +135 -0
  386. package/src/lab/projection/verdicts.ts +474 -0
  387. package/src/lab/projection/verification.ts +412 -0
  388. package/src/lab/public/bundle.ts +217 -0
  389. package/src/lab/public/community-authority.ts +175 -0
  390. package/src/lab/public/community-files.ts +29 -0
  391. package/src/lab/public/community.ts +479 -0
  392. package/src/lab/public/file-safety.ts +155 -0
  393. package/src/lab/public/ids.ts +26 -0
  394. package/src/lab/public/index.ts +16 -0
  395. package/src/lab/public/mutation-lock.ts +424 -0
  396. package/src/lab/public/operator.ts +353 -0
  397. package/src/lab/public/origin-purge.ts +79 -0
  398. package/src/lab/public/origin.ts +203 -0
  399. package/src/lab/public/privacy.ts +143 -0
  400. package/src/lab/public/private-file.ts +261 -0
  401. package/src/lab/public/project.ts +124 -0
  402. package/src/lab/public/purge-test-fault.ts +21 -0
  403. package/src/lab/public/purge.ts +223 -0
  404. package/src/lab/public/registry.ts +44 -0
  405. package/src/lab/public/revocation.ts +252 -0
  406. package/src/lab/public/signature.ts +243 -0
  407. package/src/lab/public/storage.ts +105 -0
  408. package/src/lab/public/strict-json.ts +206 -0
  409. package/src/lab/public/time.ts +26 -0
  410. package/src/lab/public/types.ts +172 -0
  411. package/src/lab/public/validate.ts +391 -0
  412. package/src/lab/query/catalog.ts +101 -0
  413. package/src/lab/query/connection.ts +107 -0
  414. package/src/lab/query/constants.ts +4 -0
  415. package/src/lab/query/cursor.ts +132 -0
  416. package/src/lab/query/dto-map.ts +277 -0
  417. package/src/lab/query/errors.ts +22 -0
  418. package/src/lab/query/freshness.ts +53 -0
  419. package/src/lab/query/index.ts +45 -0
  420. package/src/lab/query/latest-observation.ts +59 -0
  421. package/src/lab/query/passive-production.ts +159 -0
  422. package/src/lab/query/queries.ts +444 -0
  423. package/src/lab/query/types.ts +266 -0
  424. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  425. package/src/lab/subject/installation-salt.ts +112 -0
  426. package/src/lab/subject/protocol-subject.ts +80 -0
  427. package/src/lab/subject/route-subject.ts +74 -0
  428. package/src/lib/admin-secrets.ts +24 -0
  429. package/src/lib/app-owned-memory-stores.ts +22 -0
  430. package/src/lib/bounded-body.ts +167 -11
  431. package/src/lib/bun-runtime.ts +125 -12
  432. package/src/lib/bun-stream-caps.ts +13 -9
  433. package/src/lib/codex-restart-contract.ts +120 -0
  434. package/src/lib/config-ownership.ts +26 -2
  435. package/src/lib/destination-policy.ts +65 -1
  436. package/src/lib/errors.ts +80 -5
  437. package/src/lib/fabric-task-execution-authority.ts +7 -0
  438. package/src/lib/fabric-task-host.ts +29 -0
  439. package/src/lib/lab-activation.ts +223 -0
  440. package/src/lib/lab-live-execution-authority.ts +13 -0
  441. package/src/lib/lab-live-host.ts +30 -0
  442. package/src/lib/lab-live-pinned-sender.ts +56 -0
  443. package/src/lib/lab-live-route-production.ts +130 -0
  444. package/src/lib/lab-passive-linker-registration.ts +26 -0
  445. package/src/lib/local-management-attestation.ts +51 -0
  446. package/src/lib/local-management-capability.ts +100 -0
  447. package/src/lib/local-provider-reload-contract.ts +100 -0
  448. package/src/lib/optional-shutdown-hooks.ts +57 -0
  449. package/src/lib/package-tree-integrity.ts +101 -0
  450. package/src/lib/pinned-http.ts +145 -26
  451. package/src/lib/process-control.ts +6 -2
  452. package/src/lib/provider-outbound.ts +49 -9
  453. package/src/lib/redact.ts +419 -3
  454. package/src/lib/self-launch-argv.ts +15 -0
  455. package/src/lib/server-resource-ownership.ts +71 -0
  456. package/src/lib/service-secrets.ts +15 -0
  457. package/src/lib/shadow-call.ts +35 -4
  458. package/src/lib/sse-decoder.ts +41 -0
  459. package/src/lib/state-store-registrations.ts +10 -2
  460. package/src/lib/system-restart-contract.ts +73 -0
  461. package/src/lib/token-estimate.ts +19 -2
  462. package/src/lib/tool-argument-integers.ts +253 -0
  463. package/src/lib/translator-budget.ts +44 -0
  464. package/src/lib/upstream-http-version.ts +57 -0
  465. package/src/lib/upstream-reachability.ts +95 -0
  466. package/src/lib/upstream-retry.ts +156 -3
  467. package/src/lib/windows-atomic-replace.ts +155 -0
  468. package/src/lib/windows-elevation.ts +70 -2
  469. package/src/lib/windows-secret-acl.ts +409 -69
  470. package/src/lib/windows-service-wrappers.ts +72 -0
  471. package/src/lib/windows-text.ts +106 -0
  472. package/src/lib/windows-user-principal.ts +341 -0
  473. package/src/lib/winsw.ts +33 -5
  474. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  475. package/src/oauth/account-import/index.ts +15 -0
  476. package/src/oauth/account-import/parser.ts +83 -0
  477. package/src/oauth/account-import/registry.ts +18 -0
  478. package/src/oauth/account-import/service.ts +75 -0
  479. package/src/oauth/account-import/types.ts +91 -0
  480. package/src/oauth/anthropic.ts +12 -1
  481. package/src/oauth/callback-server.ts +30 -4
  482. package/src/oauth/chatgpt.ts +12 -1
  483. package/src/oauth/cline.ts +203 -0
  484. package/src/oauth/command-code.ts +239 -0
  485. package/src/oauth/cursor.ts +46 -5
  486. package/src/oauth/generic-account-failover.ts +231 -0
  487. package/src/oauth/google-antigravity.ts +35 -3
  488. package/src/oauth/health.ts +20 -12
  489. package/src/oauth/index.ts +462 -71
  490. package/src/oauth/key-providers.ts +25 -0
  491. package/src/oauth/kimi.ts +25 -3
  492. package/src/oauth/kiro.ts +95 -6
  493. package/src/oauth/local-token-detect.ts +13 -2
  494. package/src/oauth/log.ts +3 -1
  495. package/src/oauth/login-cli.ts +88 -28
  496. package/src/oauth/nous.ts +798 -0
  497. package/src/oauth/open-browser-choice.ts +26 -0
  498. package/src/oauth/store.ts +133 -26
  499. package/src/oauth/token-guardian.ts +9 -3
  500. package/src/oauth/types.ts +15 -0
  501. package/src/pi/models.ts +2 -2
  502. package/src/providers/alibaba-region-migration.ts +1 -1
  503. package/src/providers/antigravity-models.ts +521 -31
  504. package/src/providers/auto-compact-budget.ts +65 -0
  505. package/src/providers/base-url-choices.ts +10 -0
  506. package/src/providers/codex-capacity.ts +292 -0
  507. package/src/providers/command-code-efforts.ts +176 -0
  508. package/src/providers/context-cap.ts +26 -8
  509. package/src/providers/cursor-pool.ts +72 -0
  510. package/src/providers/default-aliases.ts +65 -0
  511. package/src/providers/derive.ts +281 -6
  512. package/src/providers/fastwire.ts +507 -0
  513. package/src/providers/free-directory.ts +10 -7
  514. package/src/providers/google-vertex-location.ts +14 -0
  515. package/src/providers/key-failover.ts +71 -3
  516. package/src/providers/label.ts +35 -2
  517. package/src/providers/model-discovery-limits.ts +16 -0
  518. package/src/providers/model-discovery.ts +115 -22
  519. package/src/providers/model-presets.ts +119 -0
  520. package/src/providers/model-rename-migration.ts +255 -0
  521. package/src/providers/model-rename-startup.ts +28 -0
  522. package/src/providers/new-model-policy.ts +146 -0
  523. package/src/providers/openai-sidecar.ts +72 -4
  524. package/src/providers/openai-tier-startup.ts +31 -2
  525. package/src/providers/openai-tiers.ts +119 -4
  526. package/src/providers/openai-virtual-models.ts +1 -0
  527. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  528. package/src/providers/provider-id-rewrite.ts +30 -0
  529. package/src/providers/quota.ts +1379 -40
  530. package/src/providers/registry.ts +1545 -112
  531. package/src/providers/request-pacing.ts +310 -0
  532. package/src/providers/service-tier.ts +277 -0
  533. package/src/providers/slug-codec.ts +94 -6
  534. package/src/providers/static-model-discovery.ts +86 -0
  535. package/src/providers/xai-responses-opt-in.ts +15 -0
  536. package/src/providers/xai-transport.ts +32 -4
  537. package/src/reasoning-effort.ts +68 -3
  538. package/src/responses/apply-patch-envelope.ts +63 -0
  539. package/src/responses/code-mode-helper-compat.ts +50 -0
  540. package/src/responses/compaction.ts +26 -1
  541. package/src/responses/custom-tool-compat.ts +384 -0
  542. package/src/responses/hosted-tool-policy.ts +9 -0
  543. package/src/responses/namespace-tool-compat.ts +435 -0
  544. package/src/responses/parser.ts +225 -38
  545. package/src/responses/provider-continuation.ts +98 -0
  546. package/src/responses/provider-opaque-metadata.ts +73 -0
  547. package/src/responses/reasoning-envelope.ts +9 -1
  548. package/src/responses/reasoning-replay-cache.ts +504 -0
  549. package/src/responses/schema.ts +12 -2
  550. package/src/responses/spill-store.ts +75 -10
  551. package/src/responses/state.ts +659 -31
  552. package/src/responses/thought-signature-replay.ts +364 -0
  553. package/src/responses/tool-search-compat.ts +301 -0
  554. package/src/responses/truncated-stop-reason.ts +60 -0
  555. package/src/responses/turn-termination.ts +107 -0
  556. package/src/router.ts +405 -31
  557. package/src/routing/analytics.ts +379 -0
  558. package/src/routing/capability.ts +244 -0
  559. package/src/routing/compatibility/assemble.ts +73 -0
  560. package/src/routing/compatibility/behavior.ts +278 -0
  561. package/src/routing/compatibility/catalog.ts +99 -0
  562. package/src/routing/compatibility/endpoint.ts +52 -0
  563. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  564. package/src/routing/compatibility/policy.ts +181 -0
  565. package/src/routing/compatibility/provider-slot.ts +56 -0
  566. package/src/routing/compatibility/reader.ts +110 -0
  567. package/src/routing/compatibility/subject.ts +191 -0
  568. package/src/routing/compatibility/types.ts +64 -0
  569. package/src/routing/compatibility/version.ts +104 -0
  570. package/src/routing/cost.ts +77 -0
  571. package/src/routing/evaluator.ts +495 -0
  572. package/src/routing/health.ts +412 -0
  573. package/src/routing/history/cursor.ts +43 -0
  574. package/src/routing/history/indexer.ts +605 -0
  575. package/src/routing/history/schema.ts +72 -0
  576. package/src/routing/profile-namespace.ts +15 -0
  577. package/src/routing/profile.ts +547 -0
  578. package/src/routing/quota.ts +155 -0
  579. package/src/routing/request-evidence.ts +45 -0
  580. package/src/routing/trace.ts +776 -0
  581. package/src/server/adapter-resolve.ts +2 -29
  582. package/src/server/auth-cors.ts +289 -48
  583. package/src/server/background-lifecycle.ts +182 -0
  584. package/src/server/chat-completions.ts +154 -72
  585. package/src/server/chat-native-sse.ts +331 -0
  586. package/src/server/chat-native.ts +445 -0
  587. package/src/server/claude-messages.ts +160 -44
  588. package/src/server/direct-local-http.ts +347 -0
  589. package/src/server/effort-policy.ts +18 -0
  590. package/src/server/github-copilot-responses-repair.ts +338 -0
  591. package/src/server/gui-static.ts +39 -10
  592. package/src/server/images.ts +94 -12
  593. package/src/server/index.ts +1021 -190
  594. package/src/server/lifecycle.ts +336 -14
  595. package/src/server/live.ts +136 -17
  596. package/src/server/local-management-read-client.ts +90 -0
  597. package/src/server/local-provider-reload-client.ts +137 -0
  598. package/src/server/management/agent-settings-routes.ts +433 -116
  599. package/src/server/management/api-key-usage.ts +31 -5
  600. package/src/server/management/body.ts +6 -0
  601. package/src/server/management/codex-prompt-routes.ts +570 -0
  602. package/src/server/management/combo-routes.ts +64 -25
  603. package/src/server/management/config-routes.ts +511 -51
  604. package/src/server/management/context.ts +89 -2
  605. package/src/server/management/integration-routes.ts +498 -0
  606. package/src/server/management/lab-automation-routes.ts +206 -0
  607. package/src/server/management/lab-routes.ts +563 -0
  608. package/src/server/management/logs-usage-routes.ts +127 -52
  609. package/src/server/management/model-routes.ts +461 -133
  610. package/src/server/management/model-rows.ts +167 -0
  611. package/src/server/management/native-integration-routes.ts +770 -0
  612. package/src/server/management/oauth-account-routes.ts +90 -8
  613. package/src/server/management/provider-capability-config.ts +48 -0
  614. package/src/server/management/provider-routes.ts +836 -159
  615. package/src/server/management/request-history-routes.ts +191 -0
  616. package/src/server/management/route-registry.ts +332 -0
  617. package/src/server/management/routing-analytics-routes.ts +74 -0
  618. package/src/server/management/routing-profile-routes.ts +380 -0
  619. package/src/server/management/shared.ts +27 -11
  620. package/src/server/management/sidebar-routes.ts +47 -31
  621. package/src/server/management/storage-log-guard-routes.ts +186 -0
  622. package/src/server/management/sync-response.ts +69 -0
  623. package/src/server/management/system-restart.ts +289 -33
  624. package/src/server/management/system-routes.ts +77 -0
  625. package/src/server/management/usage-summary-cache.ts +9 -1
  626. package/src/server/management/vision-sidecar-options.ts +167 -0
  627. package/src/server/management/web-search-sidecar-options.ts +120 -0
  628. package/src/server/management-api.ts +126 -23
  629. package/src/server/management-auth.ts +220 -5
  630. package/src/server/passive-route-linker.ts +66 -0
  631. package/src/server/port-reclaim.ts +1 -1
  632. package/src/server/ports.ts +41 -1
  633. package/src/server/proxy-liveness.ts +161 -10
  634. package/src/server/readiness.ts +99 -0
  635. package/src/server/relay-eager.ts +221 -54
  636. package/src/server/relay.ts +479 -87
  637. package/src/server/request-decompress.ts +113 -6
  638. package/src/server/request-log-conversation.ts +51 -0
  639. package/src/server/request-log.ts +298 -31
  640. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  641. package/src/server/responses/agent-task-recovery.ts +465 -0
  642. package/src/server/responses/codex-auth-error.ts +55 -0
  643. package/src/server/responses/collaboration.ts +239 -36
  644. package/src/server/responses/combo-stream-preflight.ts +178 -0
  645. package/src/server/responses/compact.ts +444 -72
  646. package/src/server/responses/core.ts +3579 -436
  647. package/src/server/responses/empty-completion-guard.ts +333 -0
  648. package/src/server/responses/encrypted-payload.ts +62 -39
  649. package/src/server/responses/fetch-helpers.ts +89 -99
  650. package/src/server/responses/input-admission.ts +187 -0
  651. package/src/server/responses/pacing-overload.ts +13 -0
  652. package/src/server/responses/passthrough-error.ts +33 -9
  653. package/src/server/responses/policy-fallback.ts +178 -0
  654. package/src/server/responses/responses-field-backfill.ts +343 -0
  655. package/src/server/responses/terminal-guard.ts +26 -5
  656. package/src/server/responses/upstream-error.ts +5 -0
  657. package/src/server/responses/ws-upstream.ts +381 -0
  658. package/src/server/responses-custom-tool-repair.ts +363 -0
  659. package/src/server/responses-item-id-repair.ts +54 -6
  660. package/src/server/responses-json-events.ts +90 -0
  661. package/src/server/responses-model-rewrite.ts +29 -0
  662. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  663. package/src/server/responses-snapshot-repair.ts +621 -0
  664. package/src/server/responses-terminal-repair.ts +363 -0
  665. package/src/server/responses-tool-search-repair.ts +267 -0
  666. package/src/server/responses-undeclared-tool-guard.ts +376 -0
  667. package/src/server/responses.ts +18 -2
  668. package/src/server/search.ts +78 -13
  669. package/src/server/sse-frame-buffer.ts +319 -0
  670. package/src/server/sse-payload-rewrite.ts +110 -22
  671. package/src/server/startup-action-control.ts +8 -1
  672. package/src/server/startup-health-cache.ts +19 -1
  673. package/src/server/system-env.ts +80 -9
  674. package/src/server/ws-bridge.ts +53 -40
  675. package/src/service-manager-probe.ts +892 -0
  676. package/src/service.ts +1153 -94
  677. package/src/sidecar/auth.ts +92 -0
  678. package/src/sidecar/candidates.ts +83 -0
  679. package/src/storage/cleanup.ts +2 -2
  680. package/src/storage/policy-job.ts +14 -4
  681. package/src/storage/policy.ts +88 -23
  682. package/src/storage/scanner.ts +1 -1
  683. package/src/storage/worker-lifecycle.ts +14 -14
  684. package/src/tray/windows-tray.ps1 +83 -9
  685. package/src/tray/windows.ts +43 -16
  686. package/src/types/accounts.ts +37 -0
  687. package/src/types/config.ts +911 -0
  688. package/src/types/provider.ts +614 -0
  689. package/src/types/request.ts +397 -0
  690. package/src/types/tools.ts +236 -0
  691. package/src/types/wire.ts +80 -0
  692. package/src/types.ts +107 -1237
  693. package/src/update/index.ts +37 -23
  694. package/src/update/job.ts +445 -68
  695. package/src/update/notify.ts +12 -6
  696. package/src/update/npm-cache-preflight.d.mts +47 -0
  697. package/src/update/npm-cache-preflight.mjs +201 -0
  698. package/src/update/transactional-install.d.mts +22 -0
  699. package/src/update/transactional-install.mjs +266 -0
  700. package/src/usage/cost.ts +0 -0
  701. package/src/usage/expected-prices.ts +287 -16
  702. package/src/usage/log.ts +666 -50
  703. package/src/usage/summary.ts +388 -17
  704. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  705. package/src/usage/user-cost-overlays.ts +314 -0
  706. package/src/vision/anthropic-describe.ts +10 -6
  707. package/src/vision/backends.ts +97 -0
  708. package/src/vision/describe.ts +27 -16
  709. package/src/vision/eligibility.ts +250 -0
  710. package/src/vision/index.ts +238 -24
  711. package/src/vision/reasoning.ts +55 -0
  712. package/src/vision/routed-describe.ts +175 -0
  713. package/src/vision/timeout-bounds.ts +9 -0
  714. package/src/web-search/anthropic-executor.ts +13 -7
  715. package/src/web-search/backends.ts +108 -0
  716. package/src/web-search/exa-executor.ts +119 -0
  717. package/src/web-search/executor.ts +21 -6
  718. package/src/web-search/gemini-executor.ts +141 -0
  719. package/src/web-search/index.ts +150 -15
  720. package/src/web-search/loop.ts +284 -54
  721. package/src/web-search/parse.ts +125 -30
  722. package/src/web-search/sources.ts +60 -0
  723. package/src/web-search/xai-executor.ts +219 -0
  724. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  725. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  726. package/gui/dist/provider-icons/antigravity.svg +0 -1
  727. package/gui/dist/provider-icons/claude.svg +0 -1
  728. package/gui/dist/provider-icons/copilot.svg +0 -1
  729. package/gui/dist/provider-icons/cursor.svg +0 -2
  730. package/gui/dist/provider-icons/gemini.svg +0 -1
  731. package/gui/dist/provider-icons/grok-color.svg +0 -1
  732. package/gui/dist/provider-icons/kiro.svg +0 -14
  733. package/src/cli/internal-dispatch.ts +0 -20
@@ -0,0 +1,439 @@
1
+ import {
2
+ closeSync,
3
+ constants as fsConstants,
4
+ existsSync,
5
+ fstatSync,
6
+ lstatSync,
7
+ mkdirSync,
8
+ openSync,
9
+ readdirSync,
10
+ readSync,
11
+ rmSync,
12
+ writeSync,
13
+ type Stats,
14
+ } from "node:fs";
15
+ import { dirname, join, posix, relative, resolve, sep } from "node:path";
16
+ import { randomBytes } from "node:crypto";
17
+ import { ensureLabDirs, ensureRestrictedDir, labRoot, labScratchDir } from "../paths";
18
+ import { FABRIC_LIMITS, SYNTHETIC_BEFORE_UTF8, SYNTHETIC_VALUE_PATH } from "./constants";
19
+ import { FabricTaskError } from "./types";
20
+
21
+ /** CL-07 restricted scratch tree IO for the synthetic-patch fabric task. */
22
+
23
+ const O_DIRECTORY = (fsConstants as { O_DIRECTORY?: number }).O_DIRECTORY;
24
+ const O_NOFOLLOW = (fsConstants as { O_NOFOLLOW?: number }).O_NOFOLLOW;
25
+ const FILE_MODE = 0o600;
26
+
27
+ interface TrustedScratchDir {
28
+ path: string;
29
+ fd: number;
30
+ identity: string;
31
+ }
32
+
33
+ /** Require stats to describe a regular file, not a symlink or special node. */
34
+ function assertRegularFile(stats: Stats, label: string): void {
35
+ if (!stats.isFile() || stats.isSymbolicLink() || stats.isDirectory() || stats.isFIFO() || stats.isSocket() || stats.isCharacterDevice() || stats.isBlockDevice()) {
36
+ throw new FabricTaskError(`${label} must be a regular file`, "sandbox_violation", "harness");
37
+ }
38
+ }
39
+
40
+ /** Require stats to describe a real directory, not a symlink. */
41
+ function assertRealDirectory(stats: Stats, label: string): void {
42
+ if (stats.isSymbolicLink() || !stats.isDirectory()) {
43
+ throw new FabricTaskError(`${label} must be a real directory`, "sandbox_violation", "harness");
44
+ }
45
+ }
46
+
47
+ /** Stable device/inode identity string for a filesystem node. */
48
+ function identityOf(stats: Stats): string {
49
+ return `${stats.dev}:${stats.ino}`;
50
+ }
51
+
52
+ /** Whether the host supports O_NOFOLLOW for scratch open operations. */
53
+ function platformSupportsNoFollow(): boolean {
54
+ return typeof O_NOFOLLOW === "number" && O_NOFOLLOW !== 0;
55
+ }
56
+
57
+ /** Compose open flags, optionally adding O_NOFOLLOW when supported. */
58
+ function openFlags(base: number, noFollow = true): number {
59
+ if (noFollow && platformSupportsNoFollow()) return base | O_NOFOLLOW!;
60
+ return base;
61
+ }
62
+
63
+ /** Reject scratch relative names that traverse or embed forbidden characters. */
64
+ function assertScratchName(name: string): void {
65
+ if (name.includes("/") || name.includes("\\") || name.includes("..") || name.includes("\0")) {
66
+ throw new FabricTaskError("invalid scratch relative name", "sandbox_violation", "harness");
67
+ }
68
+ }
69
+
70
+ /** Confirm the scratch root path still refers to the same directory inode. */
71
+ function revalidateScratchDir(dir: TrustedScratchDir): void {
72
+ const stats = lstatSync(dir.path);
73
+ assertRealDirectory(stats, "scratch dir");
74
+ if (identityOf(stats) !== dir.identity) {
75
+ throw new FabricTaskError("scratch directory identity changed", "sandbox_violation", "harness");
76
+ }
77
+ }
78
+
79
+ /** Resolve a single path segment under a trusted scratch directory. */
80
+ function childScratchPath(dir: TrustedScratchDir, name: string): string {
81
+ revalidateScratchDir(dir);
82
+ assertScratchName(name);
83
+ return join(dir.path, name);
84
+ }
85
+
86
+ /** Open a single name relative to a trusted scratch directory using pinned paths. */
87
+ function openAtScratch(dir: TrustedScratchDir, name: string, flags: number, mode = 0, expectDirectory = false): number {
88
+ revalidateScratchDir(dir);
89
+ assertScratchName(name);
90
+ const path = childScratchPath(dir, name);
91
+ const fd = openSync(path, openFlags(flags), mode);
92
+ const opened = fstatSync(fd);
93
+ if (expectDirectory) {
94
+ assertRealDirectory(opened, name);
95
+ } else {
96
+ assertRegularFile(opened, name);
97
+ const pathEntry = lstatSync(path);
98
+ if (identityOf(opened) !== identityOf(pathEntry)) {
99
+ throw new FabricTaskError("scratch path redirection detected", "sandbox_violation", "harness");
100
+ }
101
+ }
102
+ return fd;
103
+ }
104
+
105
+ /** Pin an absolute scratch root path into a trusted directory handle. */
106
+ function openTrustedScratchRoot(scratchRoot: string): TrustedScratchDir {
107
+ const abs = resolve(scratchRoot);
108
+ let fd: number;
109
+ if (typeof O_DIRECTORY === "number") {
110
+ fd = openSync(abs, openFlags(fsConstants.O_RDONLY | O_DIRECTORY, true));
111
+ } else {
112
+ fd = openSync(abs, fsConstants.O_RDONLY);
113
+ }
114
+ const stats = fstatSync(fd);
115
+ assertRealDirectory(stats, "scratch root");
116
+ return { path: abs, fd, identity: identityOf(stats) };
117
+ }
118
+
119
+ /** Close a trusted scratch directory handle. */
120
+ function closeTrustedScratchRoot(dir: TrustedScratchDir): void {
121
+ try {
122
+ closeSync(dir.fd);
123
+ } catch {
124
+ /* ignore */
125
+ }
126
+ }
127
+
128
+ /** Open a relative scratch path by walking trusted directory handles. */
129
+ function openScratchRelativePath(
130
+ root: TrustedScratchDir,
131
+ relativePath: string,
132
+ flags: number,
133
+ mode: number,
134
+ ): number {
135
+ const parts = assertSafeRelativePosixPath(relativePath).split("/");
136
+ let current = root;
137
+ const intermediateFds: number[] = [];
138
+ try {
139
+ for (let i = 0; i < parts.length; i++) {
140
+ const isFinal = i === parts.length - 1;
141
+ const part = parts[i]!;
142
+ if (!isFinal) {
143
+ const dirFlags = typeof O_DIRECTORY === "number"
144
+ ? openFlags(fsConstants.O_RDONLY | O_DIRECTORY, true)
145
+ : openFlags(fsConstants.O_RDONLY, true);
146
+ const subFd = openAtScratch(current, part, dirFlags, 0, true);
147
+ intermediateFds.push(subFd);
148
+ const subStats = fstatSync(subFd);
149
+ assertRealDirectory(subStats, part);
150
+ current = { path: join(current.path, part), fd: subFd, identity: identityOf(subStats) };
151
+ continue;
152
+ }
153
+ return openAtScratch(current, part, flags, mode);
154
+ }
155
+ throw new FabricTaskError("empty scratch path", "sandbox_violation", "harness");
156
+ } finally {
157
+ for (const fd of intermediateFds) {
158
+ try {
159
+ closeSync(fd);
160
+ } catch {
161
+ /* ignore */
162
+ }
163
+ }
164
+ }
165
+ }
166
+
167
+ /** Read exactly size bytes from an open scratch file descriptor. */
168
+ function readAllFromFd(fd: number, size: number): string {
169
+ const buf = Buffer.alloc(size);
170
+ let offset = 0;
171
+ while (offset < buf.length) {
172
+ const n = readSync(fd, buf, offset, buf.length - offset, offset);
173
+ if (n <= 0) break;
174
+ offset += n;
175
+ }
176
+ if (offset !== size) {
177
+ throw new FabricTaskError("short read from scratch file", "sandbox_violation", "harness");
178
+ }
179
+ return buf.toString("utf8");
180
+ }
181
+
182
+ /** Normalize and reject traversal / absolute / Windows drive / NUL paths. */
183
+ export function assertSafeRelativePosixPath(raw: string): string {
184
+ if (typeof raw !== "string" || raw.length === 0) {
185
+ throw new FabricTaskError("path required", "sandbox_violation", "harness");
186
+ }
187
+ if (raw.includes("\0") || raw.includes("\\")) {
188
+ throw new FabricTaskError("path contains forbidden characters", "sandbox_violation", "harness");
189
+ }
190
+ if (raw.startsWith("/") || /^[A-Za-z]:/.test(raw)) {
191
+ throw new FabricTaskError("absolute paths are forbidden", "sandbox_violation", "harness");
192
+ }
193
+ const normalized = posix.normalize(raw);
194
+ if (normalized === "." || normalized.startsWith("../") || normalized === ".." || normalized.includes("/../")) {
195
+ throw new FabricTaskError("path traversal is forbidden", "sandbox_violation", "harness");
196
+ }
197
+ if (normalized.split("/").some((part) => part === ".." || part === "")) {
198
+ throw new FabricTaskError("invalid path segments", "sandbox_violation", "harness");
199
+ }
200
+ return normalized;
201
+ }
202
+
203
+ /** Prove a resolved path remains under the scratch root prefix. */
204
+ function assertUnderScratchRoot(root: string, target: string): void {
205
+ if (target !== root && !target.startsWith(root + sep)) {
206
+ throw new FabricTaskError("path escapes scratch root", "sandbox_violation", "harness");
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Resolve a relative path under scratch without following intermediate symlinks.
212
+ * Missing final component is allowed (for create); intermediate components must exist.
213
+ */
214
+ export function resolveInsideScratch(scratchRoot: string, relativePath: string, opts: { allowMissingFinal?: boolean } = {}): string {
215
+ const safe = assertSafeRelativePosixPath(relativePath);
216
+ const root = resolve(scratchRoot);
217
+ const rootStats = lstatSync(root);
218
+ assertRealDirectory(rootStats, "scratch root");
219
+
220
+ let current = root;
221
+ const parts = safe.split("/");
222
+ for (let i = 0; i < parts.length; i++) {
223
+ const next = join(current, parts[i]!);
224
+ assertUnderScratchRoot(root, next);
225
+ const isFinal = i === parts.length - 1;
226
+ if (!existsSync(next)) {
227
+ if (isFinal && opts.allowMissingFinal) return next;
228
+ throw new FabricTaskError(isFinal ? `missing file ${relativePath}` : "missing intermediate directory", "sandbox_violation", "harness");
229
+ }
230
+ const stats = lstatSync(next);
231
+ if (stats.isSymbolicLink()) {
232
+ throw new FabricTaskError("symlink rejected", "sandbox_violation", "harness");
233
+ }
234
+ if (!isFinal) {
235
+ assertRealDirectory(stats, next);
236
+ }
237
+ current = next;
238
+ }
239
+ return current;
240
+ }
241
+
242
+ /** Create a relative directory tree under scratch without following symlink components. */
243
+ function ensureScratchRelativeDir(scratchRoot: string, relativeDir: string): void {
244
+ const safe = assertSafeRelativePosixPath(relativeDir);
245
+ const root = resolve(scratchRoot);
246
+ const rootStats = lstatSync(root);
247
+ assertRealDirectory(rootStats, "scratch root");
248
+ let current = root;
249
+ for (const part of safe.split("/")) {
250
+ const next = join(current, part);
251
+ assertUnderScratchRoot(root, next);
252
+ if (!existsSync(next)) {
253
+ try {
254
+ mkdirSync(next, { mode: 0o700 });
255
+ } catch (error) {
256
+ const code = (error as NodeJS.ErrnoException).code;
257
+ if (code !== "EEXIST") throw error;
258
+ }
259
+ }
260
+ const stats = lstatSync(next);
261
+ if (stats.isSymbolicLink()) {
262
+ throw new FabricTaskError("symlink rejected", "sandbox_violation", "harness");
263
+ }
264
+ assertRealDirectory(stats, next);
265
+ current = next;
266
+ }
267
+ }
268
+
269
+ /** Handle for a fabric scratch tree and its best-effort cleanup callback. */
270
+ export interface ScratchTree {
271
+ root: string;
272
+ cleanup: () => void;
273
+ }
274
+
275
+ /** Create an isolated scratch tree with the frozen synthetic-patch fixture file. */
276
+ export function createSyntheticScratch(configDir?: string): ScratchTree {
277
+ ensureLabDirs(configDir);
278
+ const labBoundary = labRoot(configDir);
279
+ const base = labScratchDir(configDir);
280
+ ensureRestrictedDir(base, labBoundary);
281
+ const root = join(base, `fabric-${Date.now().toString(36)}-${randomBytes(6).toString("hex")}`);
282
+ let trusted: TrustedScratchDir | undefined;
283
+ try {
284
+ ensureRestrictedDir(root, labBoundary);
285
+ ensureRestrictedDir(join(root, dirname(SYNTHETIC_VALUE_PATH)), labBoundary);
286
+ trusted = openTrustedScratchRoot(root);
287
+ const bytes = Buffer.from(SYNTHETIC_BEFORE_UTF8, "utf8");
288
+ if (bytes.byteLength > FABRIC_LIMITS.maxAggregateIoBytes) {
289
+ throw new FabricTaskError("fixture exceeds io budget", "budget_exhausted", "harness");
290
+ }
291
+ const fd = openScratchRelativePath(
292
+ trusted,
293
+ SYNTHETIC_VALUE_PATH,
294
+ openFlags(fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL, true),
295
+ FILE_MODE,
296
+ );
297
+ try {
298
+ writeSync(fd, bytes);
299
+ } finally {
300
+ closeSync(fd);
301
+ }
302
+ const trustedForCleanup = trusted;
303
+ return {
304
+ root,
305
+ cleanup: () => {
306
+ closeTrustedScratchRoot(trustedForCleanup);
307
+ try {
308
+ rmSync(root, { recursive: true, force: true, maxRetries: 3 });
309
+ } catch {
310
+ // best-effort cleanup
311
+ }
312
+ },
313
+ };
314
+ } catch (error) {
315
+ if (trusted) closeTrustedScratchRoot(trusted);
316
+ try {
317
+ rmSync(root, { recursive: true, force: true, maxRetries: 3 });
318
+ } catch {
319
+ /* best-effort */
320
+ }
321
+ throw error;
322
+ }
323
+ }
324
+
325
+ /** One regular file discovered during a bounded scratch tree walk. */
326
+ export interface WalkedFile {
327
+ relativePosix: string;
328
+ absolute: string;
329
+ byteLength: number;
330
+ }
331
+
332
+ /** No-follow walk; rejects symlinks and special files; enforces file/byte budgets. */
333
+ export function walkScratchFiles(scratchRoot: string): WalkedFile[] {
334
+ const root = resolve(scratchRoot);
335
+ const rootStats = lstatSync(root);
336
+ assertRealDirectory(rootStats, "scratch root");
337
+ const out: WalkedFile[] = [];
338
+ const stack: string[] = [root];
339
+ let aggregateBytes = 0;
340
+ while (stack.length > 0) {
341
+ const current = stack.pop()!;
342
+ const stats = lstatSync(current);
343
+ if (stats.isSymbolicLink()) {
344
+ throw new FabricTaskError("symlink rejected", "sandbox_violation", "harness");
345
+ }
346
+ if (stats.isDirectory()) {
347
+ const entries = readdirSync(current, { withFileTypes: true });
348
+ for (const entry of entries) {
349
+ stack.push(join(current, entry.name));
350
+ }
351
+ continue;
352
+ }
353
+ assertRegularFile(stats, current);
354
+ if (out.length >= FABRIC_LIMITS.maxScratchFiles) {
355
+ throw new FabricTaskError("scratch file count exceeds budget", "budget_exhausted", "harness");
356
+ }
357
+ aggregateBytes += stats.size;
358
+ if (aggregateBytes > FABRIC_LIMITS.maxAggregateIoBytes) {
359
+ throw new FabricTaskError("scratch aggregate bytes exceed budget", "budget_exhausted", "harness");
360
+ }
361
+ const rel = relative(root, current).split(sep).join("/");
362
+ const safe = assertSafeRelativePosixPath(rel);
363
+ out.push({ relativePosix: safe, absolute: current, byteLength: stats.size });
364
+ }
365
+ out.sort((a, b) => {
366
+ const left = Buffer.from(a.relativePosix, "utf8");
367
+ const right = Buffer.from(b.relativePosix, "utf8");
368
+ const n = Math.min(left.length, right.length);
369
+ for (let i = 0; i < n; i++) {
370
+ const d = left[i]! - right[i]!;
371
+ if (d !== 0) return d;
372
+ }
373
+ return left.length - right.length;
374
+ });
375
+ return out;
376
+ }
377
+
378
+ /** Read a scratch file as UTF-8 text under a byte budget. */
379
+ export function readScratchFileUtf8(scratchRoot: string, relativePath: string, maxBytes: number): string {
380
+ resolveInsideScratch(scratchRoot, relativePath);
381
+ const trusted = openTrustedScratchRoot(scratchRoot);
382
+ try {
383
+ const fd = openScratchRelativePath(trusted, relativePath, openFlags(fsConstants.O_RDONLY, true), 0);
384
+ try {
385
+ const stats = fstatSync(fd);
386
+ assertRegularFile(stats, relativePath);
387
+ if (stats.size > maxBytes) {
388
+ throw new FabricTaskError("file exceeds io budget", "budget_exhausted", "environment");
389
+ }
390
+ return readAllFromFd(fd, stats.size);
391
+ } finally {
392
+ closeSync(fd);
393
+ }
394
+ } finally {
395
+ closeTrustedScratchRoot(trusted);
396
+ }
397
+ }
398
+
399
+ /** Write UTF-8 content to a scratch file, replacing any existing bytes. */
400
+ export function writeScratchFileUtf8(scratchRoot: string, relativePath: string, contentUtf8: string, maxBytes: number): number {
401
+ const bytes = Buffer.from(contentUtf8, "utf8");
402
+ if (bytes.byteLength > maxBytes) {
403
+ throw new FabricTaskError("write exceeds io budget", "budget_exhausted", "environment");
404
+ }
405
+ const safe = assertSafeRelativePosixPath(relativePath);
406
+ const parentPath = safe.includes("/") ? safe.slice(0, safe.lastIndexOf("/")) : "";
407
+ resolveInsideScratch(scratchRoot, relativePath, { allowMissingFinal: true });
408
+ if (parentPath) {
409
+ ensureScratchRelativeDir(scratchRoot, parentPath);
410
+ }
411
+ const trusted = openTrustedScratchRoot(scratchRoot);
412
+ try {
413
+ const fd = openScratchRelativePath(
414
+ trusted,
415
+ relativePath,
416
+ openFlags(fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_TRUNC, true),
417
+ FILE_MODE,
418
+ );
419
+ try {
420
+ const stats = fstatSync(fd);
421
+ assertRegularFile(stats, relativePath);
422
+ writeSync(fd, bytes);
423
+ } finally {
424
+ closeSync(fd);
425
+ }
426
+ } finally {
427
+ closeTrustedScratchRoot(trusted);
428
+ }
429
+ return bytes.byteLength;
430
+ }
431
+
432
+ /** Prove the resolved path cannot escape into a caller-provided user repository root. */
433
+ export function assertNotUnderUserRepo(scratchRoot: string, userRepoRoot: string): void {
434
+ const scratch = resolve(scratchRoot);
435
+ const repo = resolve(userRepoRoot);
436
+ if (scratch === repo || scratch.startsWith(repo + sep)) {
437
+ throw new FabricTaskError("scratch must not live inside user repository", "sandbox_violation", "harness");
438
+ }
439
+ }
@@ -0,0 +1,106 @@
1
+ import { domainHash, jcsStringify, subjectIdForSubject } from "../digest";
2
+ import type { RouteSubjectV1, TaskSubjectV1 } from "../events/types";
3
+ import { freezeRouteSubject } from "../subject/route-subject";
4
+ import {
5
+ FABRIC_COMPATIBILITY_VERSION,
6
+ FABRIC_TASK_CLASS_ID,
7
+ FABRIC_TASK_CLASS_VERSION,
8
+ FABRIC_VERIFIER_ID,
9
+ SANDBOX_PROFILE_V1,
10
+ SYNTHETIC_AFTER_UTF8,
11
+ SYNTHETIC_BEFORE_UTF8,
12
+ SYNTHETIC_VALUE_PATH,
13
+ } from "./constants";
14
+
15
+ const SANDBOX_DOMAIN = "ocx-lab:fabric-sandbox-profile:v1";
16
+ const VERIFIER_DOMAIN = "ocx-lab:fabric-verifier-manifest:v1";
17
+ const FIXTURE_DOMAIN = "ocx-lab:fabric-task-fixture:v1";
18
+
19
+ /** Domain hash of the frozen fabric sandbox profile object. */
20
+ export function sandboxProfileDigest(profile: unknown = SANDBOX_PROFILE_V1): string {
21
+ return domainHash(SANDBOX_DOMAIN, jcsStringify(profile));
22
+ }
23
+
24
+ /** Canonical exact-tree-diff verifier manifest object for CL-07. */
25
+ export function verifierManifestObject(): Record<string, unknown> {
26
+ return {
27
+ schemaVersion: 1,
28
+ verifierId: FABRIC_VERIFIER_ID,
29
+ sort: "utf8-bytes-posix-path",
30
+ rejectSymlinks: true,
31
+ rejectSpecialFiles: true,
32
+ rejectPathTraversal: true,
33
+ allowAdds: false,
34
+ allowDeletes: false,
35
+ allowRenames: false,
36
+ requiredChange: {
37
+ path: SYNTHETIC_VALUE_PATH,
38
+ beforeUtf8: SYNTHETIC_BEFORE_UTF8,
39
+ afterUtf8: SYNTHETIC_AFTER_UTF8,
40
+ },
41
+ };
42
+ }
43
+
44
+ /** Domain hash of the fabric verifier manifest object. */
45
+ export function verifierManifestDigest(manifest: unknown = verifierManifestObject()): string {
46
+ return domainHash(VERIFIER_DOMAIN, jcsStringify(manifest));
47
+ }
48
+
49
+ /** Canonical synthetic-patch task fixture object for CL-07. */
50
+ export function taskFixtureObject(): Record<string, unknown> {
51
+ return {
52
+ schemaVersion: 1,
53
+ taskClassId: FABRIC_TASK_CLASS_ID,
54
+ taskClassVersion: FABRIC_TASK_CLASS_VERSION,
55
+ files: [
56
+ {
57
+ path: SYNTHETIC_VALUE_PATH,
58
+ contentUtf8: SYNTHETIC_BEFORE_UTF8,
59
+ },
60
+ ],
61
+ requestedFinal: [
62
+ {
63
+ path: SYNTHETIC_VALUE_PATH,
64
+ contentUtf8: SYNTHETIC_AFTER_UTF8,
65
+ },
66
+ ],
67
+ };
68
+ }
69
+
70
+ /** Domain hash of the fabric task fixture object. */
71
+ export function taskFixtureDigest(fixture: unknown = taskFixtureObject()): string {
72
+ return domainHash(FIXTURE_DOMAIN, jcsStringify(fixture));
73
+ }
74
+
75
+ /** Build a frozen TaskSubjectV1 for the synthetic-patch fabric task. */
76
+ export function buildTaskSubjectV1(input: {
77
+ routeSubject: RouteSubjectV1;
78
+ taskClassId?: string;
79
+ taskClassVersion?: string;
80
+ taskFixtureDigest?: string;
81
+ verifierManifestDigest?: string;
82
+ fabricCompatibilityVersion?: string;
83
+ sandboxProfileDigest?: string;
84
+ }): TaskSubjectV1 {
85
+ const routeSubject = freezeRouteSubject(input.routeSubject);
86
+ const subject: TaskSubjectV1 = {
87
+ subjectSchemaVersion: 1,
88
+ subjectKind: "task",
89
+ routeSubject,
90
+ taskClassId: input.taskClassId ?? FABRIC_TASK_CLASS_ID,
91
+ taskClassVersion: input.taskClassVersion ?? FABRIC_TASK_CLASS_VERSION,
92
+ taskFixtureDigest: input.taskFixtureDigest ?? taskFixtureDigest(),
93
+ verifierManifestDigest: input.verifierManifestDigest ?? verifierManifestDigest(),
94
+ fabricCompatibilityVersion: input.fabricCompatibilityVersion ?? FABRIC_COMPATIBILITY_VERSION,
95
+ sandboxProfileDigest: input.sandboxProfileDigest ?? sandboxProfileDigest(),
96
+ };
97
+ return Object.freeze({
98
+ ...subject,
99
+ routeSubject: freezeRouteSubject(subject.routeSubject),
100
+ });
101
+ }
102
+
103
+ /** Stable subject id for a fabric TaskSubjectV1. */
104
+ export function taskSubjectId(subject: TaskSubjectV1): string {
105
+ return subjectIdForSubject(subject);
106
+ }
@@ -0,0 +1,134 @@
1
+ import type { FailureClassification } from "../conformance/types";
2
+ import type { ObservationOutcome } from "../constants";
3
+ import type { FailureRecordV1, RouteSubjectV1, TaskSubjectV1 } from "../events/types";
4
+ import type { LabDestinationV1, LabRouteContext } from "../live/types";
5
+
6
+ export type FabricOutcomeKind = ObservationOutcome;
7
+
8
+ export type FabricFailureClass = FailureClassification;
9
+
10
+ export type FabricExecutionAuthority = "trusted_route" | "harness";
11
+
12
+ export interface FabricLimitsV1 {
13
+ maxFiles: number;
14
+ maxScratchFiles: number;
15
+ maxAggregateIoBytes: number;
16
+ maxPatchOperations: number;
17
+ totalTimeoutMs: number;
18
+ inactivityTimeoutMs: number;
19
+ aggregateArtifactBytes: number;
20
+ maxArtifacts: number;
21
+ }
22
+
23
+ export interface SyntheticPatchOperationV1 {
24
+ op: "replace";
25
+ path: string;
26
+ contentUtf8: string;
27
+ }
28
+
29
+ export interface SyntheticPatchV1 {
30
+ schemaVersion: 1;
31
+ operations: SyntheticPatchOperationV1[];
32
+ }
33
+
34
+ export interface FabricUsageV1 {
35
+ inputBytes: number;
36
+ outputBytes: number;
37
+ patchOperations: number;
38
+ filesTouched: number;
39
+ artifactBytes: number;
40
+ elapsedMs: number;
41
+ inactiveMs: number;
42
+ }
43
+
44
+ export interface ExactTreeDiffPathSummaryV1 {
45
+ path: string;
46
+ kind: "unchanged" | "modified" | "added" | "deleted" | "rejected";
47
+ beforeDigest?: string;
48
+ afterDigest?: string;
49
+ reason?: string;
50
+ }
51
+
52
+ export interface ExactTreeDiffResultV1 {
53
+ verifierId: string;
54
+ manifestDigest: string;
55
+ passed: boolean;
56
+ pathSummaries: ExactTreeDiffPathSummaryV1[];
57
+ reason?: string;
58
+ }
59
+
60
+ export interface FabricTaskOutcomeV1 {
61
+ schemaVersion: 1;
62
+ taskClassId: string;
63
+ taskClassVersion: string;
64
+ routeSubject: RouteSubjectV1;
65
+ taskSubject: TaskSubjectV1;
66
+ subjectId: string;
67
+ taskFixtureDigest: string;
68
+ verifierManifestDigest: string;
69
+ fabricCompatibilityVersion: string;
70
+ sandboxProfileDigest: string;
71
+ startedAt: number;
72
+ completedAt: number;
73
+ limits: FabricLimitsV1;
74
+ usage: FabricUsageV1;
75
+ outcome: FabricOutcomeKind;
76
+ verifier: ExactTreeDiffResultV1;
77
+ failure?: FailureRecordV1;
78
+ artifactDigests: string[];
79
+ sourceRefs?: string[];
80
+ }
81
+
82
+ /** Authoritative route execution input for trusted fabric patch producers. */
83
+ export interface FabricPatchExecutorInput {
84
+ routeContext: LabRouteContext;
85
+ destination: LabDestinationV1;
86
+ routeSubject: RouteSubjectV1;
87
+ scratchRoot: string;
88
+ reportActivity: () => void;
89
+ signal: AbortSignal;
90
+ }
91
+
92
+ export type FabricPatchExecutor = (input: FabricPatchExecutorInput) => SyntheticPatchV1 | Promise<SyntheticPatchV1>;
93
+
94
+ /** Opaque host-issued capability for exact-route fabric patch production. */
95
+ export interface TrustedFabricPatchExecutor {
96
+ execute(input: FabricPatchExecutorInput): Promise<SyntheticPatchV1>;
97
+ readonly executorModulePath: string;
98
+ }
99
+
100
+ /** Sealed fabric run result including evidence authority (not part of outcome JSON). */
101
+ export interface FabricTaskRunResult {
102
+ outcome: FabricTaskOutcomeV1;
103
+ executionAuthority: FabricExecutionAuthority;
104
+ }
105
+
106
+ export type FabricHarnessProducerKind =
107
+ | "deterministic_correct"
108
+ | "deterministic_wrong"
109
+ | "infinite_sync"
110
+ | "never_resolve"
111
+ | "mutate_after_delay"
112
+ | "periodic_activity"
113
+ | "activity_until_total"
114
+ | "flood_stdout";
115
+
116
+ /** @deprecated Test-only harness producer; use FabricHarnessProducerKind via runFabricSyntheticPatchTaskHarness. */
117
+ export type SyntheticPatchProducer = (ctx: {
118
+ taskClassId: string;
119
+ taskClassVersion: string;
120
+ scratchRoot: string;
121
+ reportActivity: () => void;
122
+ }) => SyntheticPatchV1 | Promise<SyntheticPatchV1>;
123
+
124
+ /** Typed error for fabric task producer, verifier, and sandbox failures. */
125
+ export class FabricTaskError extends Error {
126
+ override readonly name = "FabricTaskError";
127
+ constructor(
128
+ message: string,
129
+ readonly code: FabricFailureClass,
130
+ readonly attribution: FailureRecordV1["attribution"] = "harness",
131
+ ) {
132
+ super(message);
133
+ }
134
+ }