nexus-agents 12.0.0 → 12.2.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 (141) hide show
  1. package/dist/{ast-rule-runner-AOOIUG3P.js → ast-rule-runner-TUZJYSHY.js} +6 -6
  2. package/dist/{child-mcp-config-MHLK4XJS.js → child-mcp-config-G6ACPX64.js} +5 -5
  3. package/dist/{chunk-SUTWBXRU.js → chunk-4FSQWESM.js} +8 -8
  4. package/dist/{chunk-GX7RTQ72.js → chunk-4HXQJ5CA.js} +2 -2
  5. package/dist/{chunk-3O2NKHMC.js → chunk-6QUSTQ57.js} +9 -9
  6. package/dist/chunk-6QUSTQ57.js.map +1 -0
  7. package/dist/{chunk-5Z7ZVR2Z.js → chunk-7H2SQVVG.js} +3 -3
  8. package/dist/{chunk-73PYZXMP.js → chunk-7NCAEQWG.js} +4 -4
  9. package/dist/{chunk-6NERIVWA.js → chunk-CDIDN6YT.js} +2 -2
  10. package/dist/{chunk-HQRJRA5L.js → chunk-CGW57HUC.js} +4 -4
  11. package/dist/{chunk-HXST42DL.js → chunk-D23AGH2N.js} +8 -8
  12. package/dist/{chunk-TXDJE3BB.js → chunk-DNBNM35J.js} +2 -2
  13. package/dist/{chunk-TCADJ2YV.js → chunk-ETEZXSPM.js} +5 -5
  14. package/dist/{chunk-ON65PTMT.js → chunk-HFL4QVDQ.js} +6 -6
  15. package/dist/{chunk-KOQORWFZ.js → chunk-HTWXUN4F.js} +4 -4
  16. package/dist/{chunk-2FP6YFHW.js → chunk-I2SLK5RS.js} +4 -4
  17. package/dist/{chunk-XBNAIMR2.js → chunk-I527FJJZ.js} +2 -2
  18. package/dist/{chunk-4NXA64HN.js → chunk-ITUUK6GW.js} +4 -4
  19. package/dist/{chunk-MUX5WMU5.js → chunk-JEGNHWW3.js} +4 -4
  20. package/dist/{chunk-3QW7PDUF.js → chunk-JG6RTOEO.js} +4 -4
  21. package/dist/{chunk-I2KRFRQN.js → chunk-JZQ4XZKS.js} +3 -3
  22. package/dist/{chunk-GEBTH3NI.js → chunk-KEU6X3MM.js} +12 -12
  23. package/dist/{chunk-IFLQEOXB.js → chunk-KU5M5VBE.js} +3 -3
  24. package/dist/{chunk-6W6Q55WT.js → chunk-MDLDQCYX.js} +15 -16
  25. package/dist/chunk-MDLDQCYX.js.map +1 -0
  26. package/dist/{chunk-3UCQ242K.js → chunk-MQYBHIOL.js} +25 -28
  27. package/dist/chunk-MQYBHIOL.js.map +1 -0
  28. package/dist/{chunk-5DVFGYPU.js → chunk-P6MWAYCD.js} +2 -2
  29. package/dist/{chunk-MPDSAFKU.js → chunk-POLWDIVY.js} +7 -1
  30. package/dist/chunk-POLWDIVY.js.map +1 -0
  31. package/dist/{chunk-VV4OWT42.js → chunk-RY6ICQME.js} +2 -2
  32. package/dist/{chunk-42Z2Z2FP.js → chunk-TOQ7HR2R.js} +39 -39
  33. package/dist/{chunk-42Z2Z2FP.js.map → chunk-TOQ7HR2R.js.map} +1 -1
  34. package/dist/{chunk-4PV3BRCA.js → chunk-WH4KOFGZ.js} +2 -2
  35. package/dist/{chunk-P4Z7ASRK.js → chunk-X3ZVXL5R.js} +2 -2
  36. package/dist/{chunk-T7XQUVDD.js → chunk-XODHLPFS.js} +10 -8
  37. package/dist/chunk-XODHLPFS.js.map +1 -0
  38. package/dist/{chunk-TGO3FUMI.js → chunk-XUMJ26GK.js} +2 -2
  39. package/dist/{chunk-UL6R3RVK.js → chunk-YD3Y55SM.js} +2 -2
  40. package/dist/{chunk-553Q7HCB.js → chunk-YVCYTNMK.js} +2 -2
  41. package/dist/{chunk-MLRCKVSX.js → chunk-YWIN42G5.js} +3 -3
  42. package/dist/{chunk-XQ4T3HTK.js → chunk-ZQJ74T3F.js} +2 -2
  43. package/dist/{cli-circuit-breaker-VADUCZE3.js → cli-circuit-breaker-2XZ5B2OD.js} +6 -6
  44. package/dist/{cli-readiness-Z7V7LS24.js → cli-readiness-FKZLN2FX.js} +10 -10
  45. package/dist/{cli-server-gateway-2UFFXEZH.js → cli-server-gateway-4VL4RO4G.js} +15 -15
  46. package/dist/cli.js +46 -46
  47. package/dist/{composite-router-GDIBENBF.js → composite-router-QYMRSNZZ.js} +5 -5
  48. package/dist/{consensus-vote-BHTMG2B3.js → consensus-vote-BUDINEFA.js} +18 -18
  49. package/dist/{context-retriever-G7C5I37C.js → context-retriever-DJQ6WK5U.js} +11 -11
  50. package/dist/{doctor-deep-D5ESLAR7.js → doctor-deep-RZ47L46X.js} +6 -6
  51. package/dist/{doctor-gateway-report-JXEBNFYN.js → doctor-gateway-report-TPKJVFQF.js} +8 -8
  52. package/dist/{doctor-live-LP3IGZ7B.js → doctor-live-ZBGMYUWC.js} +15 -15
  53. package/dist/{expert-bridge-R2DHWMIM.js → expert-bridge-ITQMWAKA.js} +7 -7
  54. package/dist/{factory-Q4GOORZG.js → factory-7KG4FG7V.js} +14 -14
  55. package/dist/{factory-AWJDMMF3.js → factory-XWEHISQV.js} +8 -8
  56. package/dist/{gemini-adapter-IAX4A5S4.js → gemini-adapter-7JM7AOP2.js} +9 -9
  57. package/dist/{improvement-review-BXMM2N7I.js → improvement-review-DJQ3UIHM.js} +7 -7
  58. package/dist/index.d.ts +6 -6
  59. package/dist/index.js +28 -28
  60. package/dist/{init-opencode-G3FCQFLM.js → init-opencode-CTRFOKQA.js} +7 -7
  61. package/dist/{issue-triage-2CI5HWES.js → issue-triage-B2B4IYDA.js} +8 -8
  62. package/dist/{model-config-helpers-CDT3RBMY.js → model-config-helpers-LP4LIM3Q.js} +3 -3
  63. package/dist/{openai-compat-adapter-NFLZBHGU.js → openai-compat-adapter-OINWDEMM.js} +7 -7
  64. package/dist/{outcome-store-adapter-2HM4I4JI.js → outcome-store-adapter-X2M6WDEK.js} +2 -2
  65. package/dist/{pr-reviewer-helpers-UURSWH62.js → pr-reviewer-helpers-R5ZXXTY4.js} +6 -6
  66. package/dist/{registry-command-6BR25RGP.js → registry-command-6DLV5SRW.js} +2 -2
  67. package/dist/{repo-security-plan-J6B4DBYR.js → repo-security-plan-QPI4B4UQ.js} +5 -5
  68. package/dist/{research-helpers-synthesize-MLXWMK3P.js → research-helpers-synthesize-JRWNQZR7.js} +7 -7
  69. package/dist/{routing-memory-ZH74FCIT.js → routing-memory-XFFA6XQW.js} +5 -5
  70. package/dist/{session-memory-JQLZO3XD.js → session-memory-EDNBL5AG.js} +6 -6
  71. package/dist/{setup-config-FWCTSQ3E.js → setup-config-PKNAGTMJ.js} +6 -6
  72. package/dist/{setup-custom-api-CQLTAWUB.js → setup-custom-api-OER43IZH.js} +6 -6
  73. package/dist/{tool-memory-C3Y5QFFS.js → tool-memory-VRJEGMA3.js} +8 -8
  74. package/dist/{unified-registry-MQU75RZ2.js → unified-registry-KETKSBQE.js} +14 -14
  75. package/dist/{weather-report-WFALQQCE.js → weather-report-MJWGQNR3.js} +5 -5
  76. package/package.json +1 -1
  77. package/dist/chunk-3O2NKHMC.js.map +0 -1
  78. package/dist/chunk-3UCQ242K.js.map +0 -1
  79. package/dist/chunk-6W6Q55WT.js.map +0 -1
  80. package/dist/chunk-MPDSAFKU.js.map +0 -1
  81. package/dist/chunk-T7XQUVDD.js.map +0 -1
  82. /package/dist/{ast-rule-runner-AOOIUG3P.js.map → ast-rule-runner-TUZJYSHY.js.map} +0 -0
  83. /package/dist/{child-mcp-config-MHLK4XJS.js.map → child-mcp-config-G6ACPX64.js.map} +0 -0
  84. /package/dist/{chunk-SUTWBXRU.js.map → chunk-4FSQWESM.js.map} +0 -0
  85. /package/dist/{chunk-GX7RTQ72.js.map → chunk-4HXQJ5CA.js.map} +0 -0
  86. /package/dist/{chunk-5Z7ZVR2Z.js.map → chunk-7H2SQVVG.js.map} +0 -0
  87. /package/dist/{chunk-73PYZXMP.js.map → chunk-7NCAEQWG.js.map} +0 -0
  88. /package/dist/{chunk-6NERIVWA.js.map → chunk-CDIDN6YT.js.map} +0 -0
  89. /package/dist/{chunk-HQRJRA5L.js.map → chunk-CGW57HUC.js.map} +0 -0
  90. /package/dist/{chunk-HXST42DL.js.map → chunk-D23AGH2N.js.map} +0 -0
  91. /package/dist/{chunk-TXDJE3BB.js.map → chunk-DNBNM35J.js.map} +0 -0
  92. /package/dist/{chunk-TCADJ2YV.js.map → chunk-ETEZXSPM.js.map} +0 -0
  93. /package/dist/{chunk-ON65PTMT.js.map → chunk-HFL4QVDQ.js.map} +0 -0
  94. /package/dist/{chunk-KOQORWFZ.js.map → chunk-HTWXUN4F.js.map} +0 -0
  95. /package/dist/{chunk-2FP6YFHW.js.map → chunk-I2SLK5RS.js.map} +0 -0
  96. /package/dist/{chunk-XBNAIMR2.js.map → chunk-I527FJJZ.js.map} +0 -0
  97. /package/dist/{chunk-4NXA64HN.js.map → chunk-ITUUK6GW.js.map} +0 -0
  98. /package/dist/{chunk-MUX5WMU5.js.map → chunk-JEGNHWW3.js.map} +0 -0
  99. /package/dist/{chunk-3QW7PDUF.js.map → chunk-JG6RTOEO.js.map} +0 -0
  100. /package/dist/{chunk-I2KRFRQN.js.map → chunk-JZQ4XZKS.js.map} +0 -0
  101. /package/dist/{chunk-GEBTH3NI.js.map → chunk-KEU6X3MM.js.map} +0 -0
  102. /package/dist/{chunk-IFLQEOXB.js.map → chunk-KU5M5VBE.js.map} +0 -0
  103. /package/dist/{chunk-5DVFGYPU.js.map → chunk-P6MWAYCD.js.map} +0 -0
  104. /package/dist/{chunk-VV4OWT42.js.map → chunk-RY6ICQME.js.map} +0 -0
  105. /package/dist/{chunk-4PV3BRCA.js.map → chunk-WH4KOFGZ.js.map} +0 -0
  106. /package/dist/{chunk-P4Z7ASRK.js.map → chunk-X3ZVXL5R.js.map} +0 -0
  107. /package/dist/{chunk-TGO3FUMI.js.map → chunk-XUMJ26GK.js.map} +0 -0
  108. /package/dist/{chunk-UL6R3RVK.js.map → chunk-YD3Y55SM.js.map} +0 -0
  109. /package/dist/{chunk-553Q7HCB.js.map → chunk-YVCYTNMK.js.map} +0 -0
  110. /package/dist/{chunk-MLRCKVSX.js.map → chunk-YWIN42G5.js.map} +0 -0
  111. /package/dist/{chunk-XQ4T3HTK.js.map → chunk-ZQJ74T3F.js.map} +0 -0
  112. /package/dist/{cli-circuit-breaker-VADUCZE3.js.map → cli-circuit-breaker-2XZ5B2OD.js.map} +0 -0
  113. /package/dist/{cli-readiness-Z7V7LS24.js.map → cli-readiness-FKZLN2FX.js.map} +0 -0
  114. /package/dist/{cli-server-gateway-2UFFXEZH.js.map → cli-server-gateway-4VL4RO4G.js.map} +0 -0
  115. /package/dist/{composite-router-GDIBENBF.js.map → composite-router-QYMRSNZZ.js.map} +0 -0
  116. /package/dist/{consensus-vote-BHTMG2B3.js.map → consensus-vote-BUDINEFA.js.map} +0 -0
  117. /package/dist/{context-retriever-G7C5I37C.js.map → context-retriever-DJQ6WK5U.js.map} +0 -0
  118. /package/dist/{doctor-deep-D5ESLAR7.js.map → doctor-deep-RZ47L46X.js.map} +0 -0
  119. /package/dist/{doctor-gateway-report-JXEBNFYN.js.map → doctor-gateway-report-TPKJVFQF.js.map} +0 -0
  120. /package/dist/{doctor-live-LP3IGZ7B.js.map → doctor-live-ZBGMYUWC.js.map} +0 -0
  121. /package/dist/{expert-bridge-R2DHWMIM.js.map → expert-bridge-ITQMWAKA.js.map} +0 -0
  122. /package/dist/{factory-AWJDMMF3.js.map → factory-7KG4FG7V.js.map} +0 -0
  123. /package/dist/{factory-Q4GOORZG.js.map → factory-XWEHISQV.js.map} +0 -0
  124. /package/dist/{gemini-adapter-IAX4A5S4.js.map → gemini-adapter-7JM7AOP2.js.map} +0 -0
  125. /package/dist/{improvement-review-BXMM2N7I.js.map → improvement-review-DJQ3UIHM.js.map} +0 -0
  126. /package/dist/{init-opencode-G3FCQFLM.js.map → init-opencode-CTRFOKQA.js.map} +0 -0
  127. /package/dist/{issue-triage-2CI5HWES.js.map → issue-triage-B2B4IYDA.js.map} +0 -0
  128. /package/dist/{model-config-helpers-CDT3RBMY.js.map → model-config-helpers-LP4LIM3Q.js.map} +0 -0
  129. /package/dist/{openai-compat-adapter-NFLZBHGU.js.map → openai-compat-adapter-OINWDEMM.js.map} +0 -0
  130. /package/dist/{outcome-store-adapter-2HM4I4JI.js.map → outcome-store-adapter-X2M6WDEK.js.map} +0 -0
  131. /package/dist/{pr-reviewer-helpers-UURSWH62.js.map → pr-reviewer-helpers-R5ZXXTY4.js.map} +0 -0
  132. /package/dist/{registry-command-6BR25RGP.js.map → registry-command-6DLV5SRW.js.map} +0 -0
  133. /package/dist/{repo-security-plan-J6B4DBYR.js.map → repo-security-plan-QPI4B4UQ.js.map} +0 -0
  134. /package/dist/{research-helpers-synthesize-MLXWMK3P.js.map → research-helpers-synthesize-JRWNQZR7.js.map} +0 -0
  135. /package/dist/{routing-memory-ZH74FCIT.js.map → routing-memory-XFFA6XQW.js.map} +0 -0
  136. /package/dist/{session-memory-JQLZO3XD.js.map → session-memory-EDNBL5AG.js.map} +0 -0
  137. /package/dist/{setup-config-FWCTSQ3E.js.map → setup-config-PKNAGTMJ.js.map} +0 -0
  138. /package/dist/{setup-custom-api-CQLTAWUB.js.map → setup-custom-api-OER43IZH.js.map} +0 -0
  139. /package/dist/{tool-memory-C3Y5QFFS.js.map → tool-memory-VRJEGMA3.js.map} +0 -0
  140. /package/dist/{unified-registry-MQU75RZ2.js.map → unified-registry-KETKSBQE.js.map} +0 -0
  141. /package/dist/{weather-report-WFALQQCE.js.map → weather-report-MJWGQNR3.js.map} +0 -0
@@ -12,7 +12,7 @@ import {
12
12
  import {
13
13
  err,
14
14
  ok
15
- } from "./chunk-3UCQ242K.js";
15
+ } from "./chunk-MQYBHIOL.js";
16
16
  import {
17
17
  createLogger,
18
18
  getTimeProvider
@@ -437,4 +437,4 @@ export {
437
437
  createFailedReview,
438
438
  reviewPostingBlock
439
439
  };
440
- //# sourceMappingURL=chunk-5DVFGYPU.js.map
440
+ //# sourceMappingURL=chunk-P6MWAYCD.js.map
@@ -50,6 +50,10 @@ var EndpointArmIdSchema = z.templateLiteral([
50
50
  function isEndpointArmId(value) {
51
51
  return EndpointArmIdSchema.safeParse(value).success;
52
52
  }
53
+ var RoutingArmIdSchema = z.union([CliNameSchema, EndpointArmIdSchema]);
54
+ function isRoutingArmId(value) {
55
+ return isCliName(value) || isEndpointArmId(value);
56
+ }
53
57
  var UNKNOWN_ENDPOINT_ARM_DISPLAY_SLOT = "opencode";
54
58
  function observedArmDisplaySlot(armId) {
55
59
  return routingArmCliSlot(armId) ?? UNKNOWN_ENDPOINT_ARM_DISPLAY_SLOT;
@@ -415,6 +419,8 @@ export {
415
419
  routingArmDisplaySlot,
416
420
  routingArmCliSlot,
417
421
  isEndpointArmId,
422
+ RoutingArmIdSchema,
423
+ isRoutingArmId,
418
424
  observedArmDisplaySlot,
419
425
  PriceBasisSchema,
420
426
  priceBasisCaveat,
@@ -430,4 +436,4 @@ export {
430
436
  outcomeFailureFields,
431
437
  accessModeSignal
432
438
  };
433
- //# sourceMappingURL=chunk-MPDSAFKU.js.map
439
+ //# sourceMappingURL=chunk-POLWDIVY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-adapters/types-core.ts","../src/orchestration/outcomes/outcome-types.ts","../src/core/price-basis.ts"],"sourcesContent":["/**\n * nexus-agents/cli-adapters - Core Type Definitions\n *\n * Core CLI types: CliName, CliTransport, CliResponse, CliError, etc.\n *\n * (Source: cli-project_plan.md v2.1.0)\n * (Source: docs/research/cli-integration-architecture.md)\n */\n\nimport {\n CLI_NAMES,\n CliNameSchema,\n type CliNameLiteral,\n} from '../config/model-capabilities-types.js';\nimport { z } from 'zod';\nimport type { ExecutionAccessMode } from '../core/types/model.js';\n\n/**\n * Supported CLI names.\n * Derived from canonical source: config/model-capabilities-types.ts CliNameLiteral\n */\nexport type CliName = CliNameLiteral;\n\n/**\n * Runtime guard for {@link CliName}: true iff `value` is one of the four CLI\n * slots. Use at slot-level boundaries to distinguish CLI names from API arms.\n */\nexport function isCliName(value: string): value is CliName {\n return (CLI_NAMES as readonly string[]).includes(value);\n}\n\n/**\n * API-vendor identifiers an `AdapterSelection{source:'api'}` reports (#3422).\n * Distinct from the four CLI slots: a direct vendor API and the same vendor's\n * CLI binary have different latency/failure profiles, so they must NOT share a\n * routing/bandit arm (would pollute the learned model).\n */\nexport type ApiVendor = 'anthropic' | 'openai' | 'google' | 'custom-openai';\n\n/** Prefixed routing arm id for a direct-API adapter, e.g. `api:anthropic` (#3422). */\nexport type ApiArmId = `api:${ApiVendor}`;\n\n/**\n * Zod schema for {@link ApiArmId}, so persisted records can validate an API arm\n * (#4400). Kept next to the type rather than in the outcome schema so the two\n * cannot drift as `ApiVendor` changes.\n */\nexport const ApiArmIdSchema = z.enum([\n 'api:anthropic',\n 'api:openai',\n 'api:google',\n 'api:custom-openai',\n]);\n\n/**\n * A LinUCB/routing arm id — a canonical CLI slot, a vendor API arm or a validated gateway arm\n * (#3317 step 1 / #3422). Confined to the router/bandit/outcome surface so the\n * exhaustive `Record<CliName, …>` maps elsewhere stay narrow and untouched.\n */\nexport type RoutingArmId = CliName | ApiArmId | EndpointArmId;\n\n/** Build the routing arm id for an API vendor. */\nexport function apiArmId(vendor: ApiVendor): ApiArmId {\n return `api:${vendor}`;\n}\n\n/**\n * Map a routing arm id to its display CLI slot (#3422) — identity for CLI\n * slots, vendor→slot for API arms. Used where a feature is intrinsically\n * slot-level (e.g. ZeroRouter difficulty calibration) and must collapse the\n * distinct API arm to its attribution slot. The bandit keeps the distinct arm;\n * only slot-level surfaces collapse.\n */\nexport function routingArmDisplaySlot(armId: CliName | ApiArmId): CliName {\n switch (armId) {\n case 'api:anthropic':\n return 'claude';\n case 'api:openai':\n return 'codex';\n case 'api:google':\n return 'gemini';\n case 'api:custom-openai':\n return 'opencode';\n default:\n return armId;\n }\n}\n\n/**\n * CLI slot for a slot-level measurement. Dynamic gateway endpoints have no\n * CLI slot; the built-in vendor API arms retain their existing slot mapping.\n * Gateway endpoint validation reserves those vendor names (#6409).\n */\nexport function routingArmCliSlot(armId: RoutingArmId): CliName | undefined {\n if (isCliName(armId)) return armId;\n const parsed = ApiArmIdSchema.safeParse(armId);\n return parsed.success ? routingArmDisplaySlot(parsed.data) : undefined;\n}\n\n/**\n * Endpoint-identity segment of an {@link EndpointArmId} (#4392): an\n * operator-named endpoint. Lowercase alphanumerics plus `.`, `_`, `-`; must\n * start alphanumeric; 1–64 chars. `:`, `/`, `@` and whitespace are excluded\n * ON PURPOSE so a base URL — and any userinfo credential inside one — can\n * never become an arm id, telemetry key or display string. The four\n * {@link ApiVendor} names all satisfy it, so every {@link ApiArmId} is also a\n * valid endpoint arm id.\n */\nconst API_ENDPOINT_ID_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;\n\n/**\n * Routing arm id for a dynamically registered API endpoint (#4392 increment\n * 1): `api:` plus a validated endpoint identity — one arm per GATEWAY, so two\n * operator-named endpoints are distinct routing and persisted outcome arms\n * (#6291, 10.0). The type alone admits any `api:` string; the runtime shape\n * is enforced by {@link isEndpointArmId}. Validate discovered or operator\n * supplied names before they enter routing, outcomes or telemetry.\n */\nexport type EndpointArmId = `api:${string}`;\n\n/** Zod schema for {@link EndpointArmId}; the single source for {@link isEndpointArmId}. */\nexport const EndpointArmIdSchema = z.templateLiteral([\n 'api:',\n z.string().regex(API_ENDPOINT_ID_PATTERN),\n]);\n\n/**\n * Runtime guard for {@link EndpointArmId} (#4392): true iff `value` is `api:`\n * plus a valid endpoint identity. Use it before a discovered or\n * operator-supplied name becomes an arm id. Every {@link ApiArmId} passes.\n */\nexport function isEndpointArmId(value: string): value is EndpointArmId {\n return EndpointArmIdSchema.safeParse(value).success;\n}\n\n/** Zod schema for {@link RoutingArmId} (#6555). */\nexport const RoutingArmIdSchema = z.union([CliNameSchema, EndpointArmIdSchema]);\n\n/**\n * Runtime guard for {@link RoutingArmId} (#6555): true iff `value` is a canonical\n * CLI slot or a valid endpoint arm id.\n */\nexport function isRoutingArmId(value: string): value is RoutingArmId {\n return isCliName(value) || isEndpointArmId(value);\n}\n\n/**\n * Every arm the circuit-breaker and adapter registries can hold. Since 10.0\n * (#6291), the observed and routing unions admit the same gateway identities.\n * Retained for consumers of the arm-typed registry methods and `armId` fields.\n */\nexport type ObservedArmId = RoutingArmId | EndpointArmId;\n\n/**\n * Legacy display-only fallback for an unknown endpoint (#4392). This label\n * carries no evidence about the endpoint's model, capabilities or pricing.\n * Records and routing measurements must use the arm or its resolved metadata.\n */\nconst UNKNOWN_ENDPOINT_ARM_DISPLAY_SLOT: CliName = 'opencode';\n\n/**\n * Legacy display slot for any observed arm (#4392). Unknown endpoints use an\n * explicit display-only fallback. Records, admission and model recommendations\n * must preserve endpoint identity or use the endpoint's own metadata instead.\n */\nexport function observedArmDisplaySlot(armId: ObservedArmId): CliName {\n return routingArmCliSlot(armId) ?? UNKNOWN_ENDPOINT_ARM_DISPLAY_SLOT;\n}\n\n/**\n * Transport type for CLI communication.\n * - 'mcp': Uses Model Context Protocol (most stable)\n * - 'subprocess': Spawns CLI process with JSON output\n */\nexport type CliTransport = 'mcp' | 'subprocess';\n\n/**\n * Token usage information from CLI response — ONE call's usage as the CLI\n * parsers emit it.\n *\n * This is deliberately a separate type from the adapter response contract's\n * `TokenUsage` in `core/types/model.ts` (#4440): here `totalTokens` is\n * optional because not every CLI prints one, there it is required. The two\n * cross only in the two adapter bridges, and every crossing goes through\n * `token-usage-bridge.ts` so no field is narrowed silently.\n */\nexport interface TokenUsage {\n /** Input tokens consumed */\n readonly inputTokens: number;\n /** Output tokens generated */\n readonly outputTokens: number;\n /** Cached input tokens READ from an existing cache (if applicable). */\n readonly cachedInputTokens?: number;\n /**\n * Input tokens spent WRITING the cache, when the vendor reports them\n * separately (#4435). Kept distinct from {@link cachedInputTokens} because\n * they bill at opposite ends: cache writes are ~1.25x the uncached input\n * rate, cache reads ~0.1x. Collapsing them would make correct pricing\n * impossible.\n */\n readonly cacheCreationInputTokens?: number;\n /** Total tokens (input + output) */\n readonly totalTokens?: number;\n /**\n * Whether `inputTokens` is a measurement (#4835); `false` means it is a\n * placeholder `0` and `totalTokens` a lower bound. Absent means measured.\n *\n * No CLI parser sets this. It exists so the model→CLI bridge\n * (`toCliTokenUsage`, #4440) can carry a direct-API adapter's flag instead of\n * dropping it, which turned a placeholder count into a measured zero.\n */\n readonly inputTokensMeasured?: boolean;\n}\n\n/**\n * Unified CLI response format.\n * Normalized across all CLI output formats.\n */\nexport interface CliResponse {\n /** The response text */\n readonly text: string;\n /** Token usage statistics */\n readonly usage?: TokenUsage;\n /** Session ID for resumption */\n readonly sessionId?: string;\n /** Cost in USD (if available) */\n readonly costUsd?: number;\n /** Model used for generation */\n readonly model?: string;\n /**\n * The gateway arm that served this response, when a gateway model answered\n * it (#6624). Set by the model-to-CLI bridge from the model adapter's\n * gateway-arm marker. A telemetry writer prices the call by this arm's\n * `NEXUS_GATEWAY_COST` declaration, never by `model`'s list rate. Absent for\n * a CLI subprocess or a direct vendor API.\n */\n readonly gatewayArm?: EndpointArmId;\n /**\n * The model the caller asked for, when the adapter answered with a\n * different one from the same CLI family (#6120). Present only on a\n * substituted response — the claude adapter sets it after an\n * out-of-credits envelope for the requested model made it retry the next\n * registry alias — so a record consumer (#6115) can say which model\n * actually voted. Absent means the requested model answered.\n */\n readonly fallbackFrom?: string;\n /** Duration in milliseconds */\n readonly durationMs?: number;\n /**\n * CLI slot of the arm `CompositeRouter.executeTask` selected and ran (#6521).\n * Set only by the router, never by an adapter. CLI subprocess adapters report\n * no `model`, so without this a caller cannot attribute a routed outcome.\n * This is the DISPLAY slot: an `api:anthropic` run reads `claude` here. An\n * outcome record wants {@link routedArm}.\n */\n readonly routedCli?: CliName;\n /**\n * Routing arm id of the arm the router ran (#6552): `api:anthropic` for the\n * Anthropic API arm, `claude` for the claude CLI arm. Set only by the\n * router, alongside {@link routedCli}. This is what a persisted outcome's\n * `cli` records, so warm start credits the arm that ran, not its slot.\n */\n readonly routedArm?: RoutingArmId;\n /**\n * Wall time of the routed arm's `execute` call alone, in ms (#6521). Set only\n * by `CompositeRouter.executeTask`; excludes routing and caller overhead.\n */\n readonly routedDurationMs?: number;\n /** Raw response (for debugging) */\n readonly raw?: unknown;\n /**\n * Stderr the transport captured during a SUCCESSFUL call, when non-empty\n * (#6094). On the subprocess path this is the CLI's stderr; on the codex MCP\n * path it is what `codex mcp-server` wrote to its piped stderr while the tool\n * call was in flight. A sandbox failure inside the CLI's tool loop surfaces\n * here while `text` still carries a parsed answer. Absent on a clean run.\n */\n readonly stderr?: string;\n /**\n * The access mode the adapter that served this call enforced (#6792),\n * stamped by the adapter itself after it ran, so a caller records what was\n * enforced rather than what was requested. Absent when the serving adapter\n * does not report it.\n */\n readonly accessMode?: ExecutionAccessMode;\n /**\n * True when the serving arm runs nothing on the host (#6792): a direct-API\n * or gateway arm sends the task with no tools, so no file was read or\n * edited, whatever the access mode allowed. Absent for a CLI arm.\n */\n readonly textOnly?: true;\n /**\n * Tool calls the CLI's own permission layer refused during this call\n * (#6792), when the CLI reports them (claude's `permission_denials`).\n * Absent when none were reported.\n */\n readonly permissionDenials?: readonly CliPermissionDenial[];\n}\n\n/** One tool call a CLI's permission layer refused (#6792). */\nexport interface CliPermissionDenial {\n readonly toolName: string;\n /** The file the refused call targeted, when it named one. */\n readonly filePath?: string;\n}\n\n/**\n * Error codes for CLI operations.\n */\nexport type CliErrorCode =\n | 'NOT_FOUND' // CLI not installed\n | 'NOT_AUTHENTICATED' // OAuth/auth required\n | 'RATE_LIMITED' // Rate limit exceeded\n | 'TIMEOUT' // Execution timed out\n | 'PARSE_ERROR' // Response parsing failed\n | 'CONNECTION_ERROR' // MCP connection failed\n | 'EXECUTION_ERROR' // CLI returned error\n | 'UNSUPPORTED_VERSION' // CLI version not supported\n | 'BUDGET_EXCEEDED' // Budget limit exceeded\n | 'UNKNOWN'; // Unknown error\n\n/**\n * CLI execution error.\n */\nexport interface CliError {\n /** Error code */\n readonly code: CliErrorCode;\n /** Human-readable message */\n readonly message: string;\n /** CLI slot or API endpoint that produced the error. */\n readonly cli: RoutingArmId;\n /** Underlying error (if any) */\n readonly cause?: Error;\n /** Whether the error is retryable */\n readonly retryable: boolean;\n /**\n * How long the provider asked us to wait before retrying, in milliseconds\n * (#4373). Present only when the CLI's own message stated one — parsed by\n * `parseRetryAfterMs`. The retry loop prefers this over its computed\n * exponential backoff, since a provider that names its window knows better\n * than our guess.\n */\n readonly retryAfterMs?: number;\n /**\n * CLI slot of the arm `CompositeRouter.executeTask` selected, when that arm\n * ran and failed (#6521). Set only by the router, so a caller can record\n * the failure against the arm it routed to. Absent when routing itself failed.\n * The display slot; see {@link CliResponse.routedArm} for the arm id.\n */\n readonly routedCli?: CliName;\n /** Routing arm id of the arm that ran and failed (#6552); see {@link CliResponse.routedArm}. */\n readonly routedArm?: RoutingArmId;\n /** Wall time of the failed arm's `execute` call alone, in ms (#6521). */\n readonly routedDurationMs?: number;\n}\n\n/**\n * Version compatibility status.\n */\nexport type VersionStatus = 'supported' | 'outdated' | 'breaking' | 'unsupported';\n\n/**\n * Health check status for a CLI.\n */\nexport interface HealthStatus {\n /** Whether the CLI is healthy */\n readonly healthy: boolean;\n /** CLI version */\n readonly version: string;\n /** Version compatibility status */\n readonly versionStatus: VersionStatus;\n /** Optional message (e.g., upgrade recommendation) */\n readonly message?: string;\n /**\n * Whether the underlying CLI could be reached at all (#5060).\n *\n * `healthCheck` catches its own failures and returns rather than throwing, so\n * a `healthy: false` result covers two very different states: the binary ran\n * and reported an unsupported version, or the binary could not be run at all\n * (`spawn ENOENT`). Both arrive as `versionStatus: 'unsupported'`, and a\n * consumer reading only `healthy` told users to authenticate a CLI they had\n * not installed.\n *\n * Absent means the producer predates the distinction — unknown, not\n * unreachable. Consumers should treat `reachable !== false` as \"present\".\n */\n readonly reachable?: boolean;\n /**\n * When the evidence behind {@link reachable} was actually gathered (#5864).\n *\n * `BaseCliAdapter` caches the version string forever — no TTL, no reset, not\n * even on `dispose()` — so every `healthCheck` after the first for a given\n * instance returns without spawning anything. `reachable: true` then restates\n * a past observation as a present one, and `lastChecked` is stamped `now`,\n * which dates a replay as if it were a fresh probe.\n *\n * Compare the two: equal (to the probe) means this check ran the binary;\n * earlier means `reachable` rests on a cached reading and the binary may have\n * gone away since. Absent means the producer does not probe a binary at all\n * (an in-process adapter) or predates the distinction — unknown, not stale.\n */\n readonly versionProbedAt?: Date;\n /** Last successful health check */\n readonly lastChecked: Date;\n}\n\n/**\n * Capacity status for rate limiting.\n */\nexport interface CapacityStatus {\n /** Remaining tokens in current window */\n readonly remainingTokens: number;\n /** Remaining requests in current window */\n readonly remainingRequests: number;\n /** When the rate limit resets */\n readonly resetTime: Date;\n /** Current utilization percentage (0-100) */\n readonly utilizationPercent: number;\n /**\n * Whether this process's rolling rate window is used up (#4456).\n *\n * Local arithmetic only: this process's own spend over the last\n * {@link RATE_LIMIT_WINDOW_MS}, measured against a per-CLI constant the\n * source calls a conservative estimate. It self-clears within the window,\n * and an ordinary burst (a 7-voter panel, a subagent fan-out) sets it while\n * plenty of provider quota remains.\n *\n * This is a throttling hint, NOT evidence that the account is out of\n * capacity. Do not exclude a candidate on it — see {@link quotaExhausted}.\n */\n readonly rateLimited: boolean;\n /**\n * @deprecated Since #4456 — renamed to {@link rateLimited}, which says what\n * it actually measures. The name `exhausted` promised an account/plan\n * capacity signal while reporting a 60-second local rate heuristic, so every\n * reader inherited a claim the value could not support. Identical value;\n * scheduled for removal in the next major.\n */\n readonly exhausted: boolean;\n /**\n * Whether a PROVIDER asserted that durable quota is gone (#4456).\n *\n * Set only from provider-asserted evidence — a rate-limit error whose\n * `retry-after` exceeds the local window, which is the provider itself\n * saying the wait is longer than a per-minute throttle. Never inferred from\n * local counting.\n *\n * `false` means \"no provider has asserted exhaustion to THIS process\". It is\n * NOT a measurement that quota remains: a weekly quota burned by another\n * process is invisible here. Read it with {@link observed}; absence of\n * evidence must not be presented as capacity.\n */\n readonly quotaExhausted: boolean;\n /**\n * When the provider said the quota window clears, from `retry-after`.\n *\n * Present only alongside `quotaExhausted: true`. Absent means the provider\n * asserted exhaustion without a horizon, which is a weaker signal, not a\n * shorter one.\n */\n readonly quotaResetAt?: Date;\n /**\n * Whether this process has observed any usage of the adapter (#4374).\n *\n * When false, every other field is a *default*, not a measurement: a tracker\n * that has never recorded a request reports the full token limit remaining and\n * 0% utilization, which is indistinguishable from a genuinely idle adapter.\n * Consumers must not present an unobserved reading as health.\n *\n * Note the narrower guarantee even when true: the tracker sees only THIS\n * process's spend. It has no visibility into a provider-side weekly quota\n * consumed elsewhere, so `remainingTokens` is a local upper bound on what is\n * left, never an authoritative one.\n */\n readonly observed: boolean;\n}\n","/**\n * Type definitions for task outcome tracking.\n *\n * Records the result of each model delegation or consensus vote\n * to enable performance measurement across CLIs and task categories.\n *\n * @module orchestration/outcomes/outcome-types\n * (Source: Issue #861 — Task outcome tracking)\n */\n\nimport { z } from 'zod';\nimport { CliNameSchema } from '../../config/model-capabilities-types.js';\nimport { EndpointArmIdSchema } from '../../cli-adapters/types-core.js';\nimport { TaskCategorySchema } from '../../config/task-specialization-types.js';\nimport type { TaskCategory } from '../../config/task-specialization-types.js';\nimport { createLogger } from '../../core/logger.js';\nimport type { ExecutionAccessMode } from '../../core/index.js';\nimport { PriceBasisSchema } from '../../core/price-basis.js';\n\nconst logger = createLogger({ component: 'outcome-error-taxonomy' });\n\n// ============================================================================\n// Schemas\n// ============================================================================\n\n// CliNameSchema imported from config/model-capabilities-types.ts (canonical source)\n\n/** Source of the task outcome. */\nconst OutcomeSourceSchema = z.enum(['delegate', 'consensus', 'manual']);\n\n/** Failure category for failed task outcomes (Issue #1025). */\nexport const OutcomeFailureCategorySchema = z.enum([\n 'timeout',\n 'authentication',\n 'rate_limit',\n 'connection',\n 'crash',\n 'adapter_unavailable',\n 'validation',\n 'parse',\n 'execution',\n 'generic',\n 'unknown',\n]);\n\n/**\n * Routing-arm attribution for an outcome.\n *\n * Widened beyond {@link CliNameSchema} for the following attribution cases:\n *\n * - an explicit `'unknown'` (#3624) — for outcomes (e.g. expert executions)\n * whose real executing CLI can't be resolved from the model. `'unknown'` is\n * excluded from CLI-quality signals (detectCliPerformanceFloor) so it can't\n * skew a real CLI, but is retained for category/failure analysis rather than\n * fabricated.\n * - `api:*` routing arms (#4400). The router genuinely registers\n * `api:anthropic`, `api:openai`, `api:google` and `api:custom-openai` as arms\n * under `NEXUS_BILLING_MODE=api`, but this schema could not represent them —\n * so no outcome could be recorded under an API arm's own id.\n * `LinUCBBandit.warmStart` matches arms BY NAME, so those arms could never\n * warm-start: every process began cold no matter how much history existed,\n * and the skip was silent.\n *\n * - Validated gateway endpoint arms (#6291, 10.0), using the same identity\n * schema as endpoint registration. URL/userinfo and malformed ids fail closed.\n *\n * This additive widening retains all existing JSONL values and their arm\n * attribution unchanged. No schema version, migration or file rewrite is needed;\n * legacy CLI/API histories still replay into LinUCB by their original names.\n */\nexport const OutcomeCliSchema = z.union([CliNameSchema, EndpointArmIdSchema, z.literal('unknown')]);\nexport type OutcomeCli = z.infer<typeof OutcomeCliSchema>;\n\n/** Provenance for the CLI attributed to an outcome. */\nconst OutcomeCliSourceSchema = z.enum(['executed', 'category-default']);\n\n/**\n * Which selector chose the CLI for this outcome (#6521). `'composite-router'`\n * means `CompositeRouter` routed THIS task and the outcome is the result of\n * running the arm it picked. An additive field, not a new `source` value:\n * `source` is a published union, and a writer that did not route leaves this\n * absent rather than claiming a routing decision it never made.\n */\nconst OutcomeRoutedBySchema = z.enum(['composite-router']);\n\n/**\n * How `category` was obtained (#6549). `'defaulted'` means no category was\n * detected and `category` holds {@link UNDETECTED_CATEGORY_FALLBACK} only\n * because the published field is required. An additive field, not a new\n * `TaskCategory` value: that union is published, and widening it is a\n * semver decision. Absent on legacy rows, which cannot be told apart and are\n * read as before.\n */\nconst OutcomeCategorySourceSchema = z.enum(['detected', 'defaulted']);\n\n/** Longest `traceId` a persisted outcome row accepts; a longer id fails the row on reload. */\nexport const TRACE_ID_MAX_LENGTH = 128;\n\n/** Schema for a single recorded task outcome. */\nexport const TaskOutcomeSchema = z.object({\n id: z.string().min(1),\n cli: OutcomeCliSchema,\n /** How the CLI attribution was obtained. Absent on legacy, unmeasured records. */\n cliSource: OutcomeCliSourceSchema.optional(),\n /** Set only when `CompositeRouter` selected the CLI for this task (#6521). */\n routedBy: OutcomeRoutedBySchema.optional(),\n category: TaskCategorySchema,\n /** Whether `category` was detected or defaulted (#6549). Absent on legacy rows. */\n categorySource: OutcomeCategorySourceSchema.optional(),\n model: z.string().min(1),\n success: z.boolean(),\n durationMs: z.number().nonnegative(),\n timestamp: z.string().min(1),\n qualitySignals: z.array(z.string()).optional(),\n failureCategory: OutcomeFailureCategorySchema.optional(),\n errorMessage: z.string().max(500).optional(),\n source: OutcomeSourceSchema,\n /** Whether this outcome came from a triage-initiated retry (#1506). */\n wasRetried: z.boolean().optional(),\n /** Triage action taken on the failure (#1506). */\n triageAction: z.string().max(30).optional(),\n /** Routing stage that selected this CLI (#1785). */\n routingStage: z.string().max(50).optional(),\n /** Number of retry attempts before this outcome (#1785). */\n retryCount: z.number().int().nonnegative().optional(),\n /** Vendor resolved from `model` via ModelRegistry at write time (#2548). */\n vendor: z.string().min(1).max(40).optional(),\n /** Family resolved from `model` via ModelRegistry at write time (#2548). */\n family: z.string().min(1).max(80).optional(),\n /**\n * Voter role for `source: 'consensus'` outcomes (#2662) — `architect`,\n * `security`, etc. Absent on non-consensus outcomes. Lets the\n * stratified outcome report break results down by voter role.\n */\n voterRole: z.string().min(1).max(40).optional(),\n /**\n * Baseline this outcome forked from (#2697 / Epic F follow-up to #2665).\n * Set on outcomes recorded inside a fork-then-merge graph branch so\n * `query({ baselineId: 'B' })` returns every branch outcome forked\n * from baseline B — letting later analysis compare branches as a\n * cohort. Free-form string (caller-assigned); typically the parent\n * node's `executionId` or `taskId`.\n */\n baselineId: z.string().min(1).max(64).optional(),\n /**\n * Distributed trace id correlating this outcome across the pipeline (#3146).\n * Consensus rows carry the decision ID shared by cost and vote records (#6857).\n * Optional + backward-compatible: older JSONL records without it hydrate fine.\n */\n traceId: z.string().min(1).max(TRACE_ID_MAX_LENGTH).optional(),\n /** Request id correlating this outcome to its originating invocation (#3146). */\n requestId: z.string().min(1).max(128).optional(),\n /**\n * The model id the adapter reported serving the call (#6624). `model` stays\n * what the writer has always put there: some writers store a role or\n * aggregate marker in it (`pipeline`, `worker-<role>`, `consensus`) and\n * readers group on that marker. Absent when the writer had no served model:\n * the call failed, or the adapter reported none.\n */\n servedModel: z.string().min(1).max(200).optional(),\n /**\n * USD cost of the call (#6624), from the ledger's cost wrappers: the gateway\n * arm's declaration when a gateway served it, else the registry rate for\n * `servedModel`. Present ONLY when a price was found. Absent means the cost\n * is unknown — never read an absent cost as $0.\n */\n costUsd: z.number().nonnegative().optional(),\n /**\n * What `costUsd` rests on (#6624): `'list'` for an assumed published\n * registry-chain rate, `'declared'` for a manifest-overlay price (user or\n * operator tier) or an explicit gateway rate (including free/local), and\n * `'unknown'` when pricing was attempted but none resolved. Absent when no\n * lookup was made because the adapter reported no token usage.\n */\n priceBasis: PriceBasisSchema.optional(),\n /**\n * Gateway endpoint arm that served the call (#7082), when a gateway served\n * it. Carries the arm id (e.g. `api:anthropic`, `api:openrouter`, `api:custom-openai`)\n * enabling shadow route evaluation (#7071) and LinUCB warm-start attribution.\n * Absent when the call was served directly by a local CLI or when the\n * adapter reported no gateway arm.\n */\n gatewayArm: EndpointArmIdSchema.optional(),\n});\n\n/** Schema for filtering outcomes. */\nexport const OutcomeQuerySchema = z.object({\n cli: OutcomeCliSchema.optional(),\n category: TaskCategorySchema.optional(),\n source: OutcomeSourceSchema.optional(),\n success: z.boolean().optional(),\n failureCategory: OutcomeFailureCategorySchema.optional(),\n since: z.string().optional(),\n limit: z.number().int().positive().optional(),\n /** Exclude outcomes with any of these quality signals (#1680). */\n excludeQualitySignals: z.array(z.string()).optional(),\n /** Restrict to outcomes recorded against a specific baseline (#2697). */\n baselineId: z.string().min(1).max(64).optional(),\n /** Restrict to outcomes served by a specific gateway arm (#7082). */\n gatewayArm: EndpointArmIdSchema.optional(),\n});\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** A single recorded task execution outcome. */\nexport type TaskOutcome = z.infer<typeof TaskOutcomeSchema>;\n\n/** Filter for querying stored outcomes. */\nexport type OutcomeQuery = z.infer<typeof OutcomeQuerySchema>;\n\n/** Source of the outcome record. */\nexport type OutcomeSource = z.infer<typeof OutcomeSourceSchema>;\n\n/** Selector that chose the CLI for a routed outcome (#6521). */\nexport type OutcomeRoutedBy = z.infer<typeof OutcomeRoutedBySchema>;\n\n/** Category of failure for failed outcomes (Issue #1025). */\nexport type OutcomeFailureCategory = z.infer<typeof OutcomeFailureCategorySchema>;\n\n/** Provenance of an outcome's `category` (#6549). */\nexport type OutcomeCategorySource = z.infer<typeof OutcomeCategorySourceSchema>;\n\n// ============================================================================\n// Undetected category (#6549)\n// ============================================================================\n\n/**\n * The value an outcome writer stores in the required `category` field when no\n * category was detected. It is a placeholder, not a measurement: the row is\n * marked `categorySource: 'defaulted'` and per-category readers skip it.\n */\nconst UNDETECTED_CATEGORY_FALLBACK: TaskCategory = 'exploration';\n\n/**\n * The `category` and `categorySource` fields for an outcome row, given the\n * detected category (`undefined` when detection found none).\n */\nexport function resolveOutcomeCategory(detected: TaskCategory | undefined): {\n readonly category: TaskCategory;\n readonly categorySource: OutcomeCategorySource;\n} {\n if (detected === undefined) {\n return { category: UNDETECTED_CATEGORY_FALLBACK, categorySource: 'defaulted' };\n }\n return { category: detected, categorySource: 'detected' };\n}\n\n/**\n * Whether an outcome's `category` may be read as a measured category. False\n * only for a row marked `'defaulted'`; a legacy row with no marker is read as\n * it always was, since nothing on it says otherwise. Per-category readers\n * (group-bys, category filters, cli×category keys) must skip rows for which\n * this is false; whole-population totals still count them.\n */\nexport function hasMeasuredCategory(outcome: Pick<TaskOutcome, 'categorySource'>): boolean {\n return outcome.categorySource !== 'defaulted';\n}\n\n// ============================================================================\n// Error Classification (Issue #1025)\n// ============================================================================\n\nconst TIMEOUT_PATTERNS = ['timeout', 'timed out', 'deadline exceeded', 'socket hang up', 'aborted'];\nconst AUTH_PATTERNS = [\n 'auth',\n 'unauthorized',\n 'forbidden',\n 'oauth',\n 'permission denied',\n '401',\n '403',\n];\nconst RATE_LIMIT_PATTERNS = [\n 'rate limit',\n 'too many requests',\n '429',\n 'throttl',\n 'quota exceeded',\n 'max retries',\n 'retry limit',\n];\nconst CONNECTION_PATTERNS = [\n 'connection',\n 'connect',\n 'econnrefused',\n 'enotfound',\n 'econnreset',\n 'dns',\n 'network',\n 'getaddrinfo',\n 'certificate',\n 'ssl',\n 'tls',\n 'proxy',\n 'epipe',\n 'etimedout',\n // HTTP 5xx — transient server errors, not execution failures (#1530)\n '500',\n '502',\n '503',\n '504',\n 'internal server error',\n 'bad gateway',\n 'service unavailable',\n // Port binding failures — transient, not execution errors (#subprocess-adapter parity)\n 'eaddrinuse',\n 'address already in use',\n];\nconst CRASH_PATTERNS = [\n 'crash',\n 'exited',\n 'killed',\n 'sigterm',\n 'sigkill',\n 'spawn error',\n 'out of memory',\n 'oom',\n 'enomem',\n 'fatal',\n 'segfault',\n 'heap',\n];\nconst ADAPTER_PATTERNS = [\n 'no model adapter',\n 'adapter unavailable',\n 'no adapter',\n 'model not found',\n 'no model',\n 'unknown model',\n 'model does not exist',\n];\nconst VALIDATION_PATTERNS = [\n 'validation',\n 'invalid input',\n 'parse error',\n 'zod',\n 'schema',\n 'unknown workflow',\n 'unknown template',\n 'unknown type',\n 'not recognized',\n 'available:',\n];\nconst PARSE_PATTERNS = [\n 'json parse',\n 'unexpected token',\n 'unexpected end of json',\n 'syntax error',\n 'failed to parse',\n 'cannot parse',\n 'ndjson',\n 'malformed',\n // Model output issues — not execution failures (#1530)\n 'empty response',\n 'no output',\n 'no content',\n 'truncated',\n 'incomplete',\n];\nconst EXECUTION_PATTERNS = [\n 'api error',\n 'apierror',\n 'sdk error',\n 'failed to',\n 'cannot',\n 'typeerror',\n 'referenceerror',\n 'assertion',\n 'expect',\n 'undefined is not',\n 'null is not',\n 'is not a function',\n 'unhandled',\n 'rejected',\n 'enoent',\n 'permission denied',\n 'eperm',\n 'eacces',\n 'command failed',\n 'non-zero exit',\n 'exit code',\n];\n// Generic catch-all patterns — separated from execution for observability (#1457)\nconst GENERIC_PATTERNS = [\n 'error:',\n 'error occurred',\n 'failed',\n 'failure',\n 'exception',\n 'not found',\n 'not supported',\n 'not implemented',\n 'not available',\n 'invalid',\n 'unable to',\n 'could not',\n 'unexpected',\n 'missing',\n 'unsupported',\n];\n\nfunction matchesAny(text: string, patterns: string[]): boolean {\n return patterns.some((p) => text.includes(p));\n}\n\n/** Classify execution vs generic catch-all patterns (#1457). */\nfunction classifyExecutionOrGeneric(text: string): OutcomeFailureCategory {\n if (matchesAny(text, EXECUTION_PATTERNS)) return 'execution';\n if (matchesAny(text, GENERIC_PATTERNS)) return 'generic';\n // Log unknown classifications for pattern analysis (#1499 diagnostics)\n logger.debug('Unclassified error string', { sample: text.slice(0, 200) });\n return 'unknown';\n}\n\n/**\n * Classifies a lowercase text string against all known failure patterns.\n * Order: most-specific categories first, broad execution/generic last (#1461).\n * Empty/whitespace-only strings default to 'execution' (#1475).\n */\nfunction classifyText(text: string): OutcomeFailureCategory {\n if (text.trim() === '') return 'execution';\n if (matchesAny(text, ADAPTER_PATTERNS)) return 'adapter_unavailable';\n if (matchesAny(text, AUTH_PATTERNS)) return 'authentication';\n if (matchesAny(text, RATE_LIMIT_PATTERNS)) return 'rate_limit';\n if (matchesAny(text, TIMEOUT_PATTERNS)) return 'timeout';\n if (matchesAny(text, CONNECTION_PATTERNS)) return 'connection';\n if (matchesAny(text, CRASH_PATTERNS)) return 'crash';\n if (matchesAny(text, VALIDATION_PATTERNS)) return 'validation';\n if (matchesAny(text, PARSE_PATTERNS)) return 'parse';\n return classifyExecutionOrGeneric(text);\n}\n\n/** Maximum length for extracted error messages to prevent unbounded strings. */\nconst MAX_ERROR_MESSAGE_LENGTH = 500;\n\n/**\n * Extracts a classifiable message string from a non-Error value.\n * Returns undefined if the value is truly unclassifiable (#1466).\n */\nexport function extractNonErrorMessage(error: unknown): string | undefined {\n if (error === null || error === undefined) return undefined;\n if (typeof error === 'string') {\n return error.slice(0, MAX_ERROR_MESSAGE_LENGTH);\n }\n if (typeof error === 'object') {\n const record = error as Record<string, unknown>;\n if (typeof record['message'] === 'string') {\n return record['message'].slice(0, MAX_ERROR_MESSAGE_LENGTH);\n }\n try {\n const json = JSON.stringify(error);\n return json.slice(0, MAX_ERROR_MESSAGE_LENGTH);\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\n/** Classifies an error into an OutcomeFailureCategory for recording. */\nexport function categorizeOutcomeError(error: unknown): OutcomeFailureCategory {\n if (error instanceof Error) {\n const text = `${error.message.toLowerCase()} ${error.name.toLowerCase()}`;\n return classifyText(text);\n }\n const extracted = extractNonErrorMessage(error);\n // Null/undefined/unserializable errors default to 'execution' (#1494).\n // Consistent with #1475 (empty strings → execution, not unknown).\n if (extracted === undefined) return 'execution';\n return classifyText(extracted.toLowerCase());\n}\n\n/** Classifies an error message string into an OutcomeFailureCategory. */\nexport function categorizeOutcomeErrorMessage(msg: string): OutcomeFailureCategory {\n return classifyText(msg.toLowerCase());\n}\n\n/**\n * `failureCategory` + `errorMessage` for a failed outcome row, so no failure\n * is written unclassified (#6521). Empty for a success or an absent message.\n */\nexport function outcomeFailureFields(\n success: boolean,\n error: string | undefined\n): { failureCategory?: OutcomeFailureCategory; errorMessage?: string } {\n if (success || error === undefined || error.length === 0) return {};\n return {\n failureCategory: categorizeOutcomeErrorMessage(error),\n errorMessage: error.slice(0, 500),\n };\n}\n\n/**\n * The quality signal that records an outcome's access mode (#6792). One\n * spelling for every writer, so a reader can filter on it:\n * - `access-mode:<mode>` (`'enforced'`): the mode the arm that served the call\n * reported enforcing;\n * - `access-mode-requested:<mode>` (`'requested'`): only what the caller asked\n * for, when no served arm reported a mode (the call failed before an arm\n * ran, or the path cannot observe enforcement).\n */\nexport function accessModeSignal(\n mode: ExecutionAccessMode,\n kind: 'enforced' | 'requested'\n): string {\n return kind === 'enforced' ? `access-mode:${mode}` : `access-mode-requested:${mode}`;\n}\n\n/** Aggregated stats for a group of outcomes. */\nexport interface GroupStats {\n readonly count: number;\n readonly successRate: number;\n readonly avgDurationMs: number;\n}\n\n/** Aggregated performance summary from recorded outcomes. */\nexport interface PerformanceSummary {\n readonly totalTasks: number;\n readonly successRate: number;\n readonly avgDurationMs: number;\n readonly byCli: ReadonlyMap<string, GroupStats>;\n readonly byCategory: ReadonlyMap<string, GroupStats>;\n}\n","/**\n * nexus-agents/core - Price-basis vocabulary (#4406)\n *\n * The kind of rate a recorded dollar figure rests on, defined ONCE for both\n * consumers: the pricing chain (`core/trace-pricing.ts`, which turns a model id\n * into a cost) and the persisted decision-cost records\n * (`observability/decision-cost.ts`, which have to transport the basis into\n * JSONL and an MCP `outputSchema`).\n *\n * WHY A SEPARATE LEAF MODULE. `core/trace-pricing` pulls in the model registry,\n * and a runtime edge from `observability/decision-cost` to it closes a cycle\n * back through weather-report → decision-cost-store → decision-cost, which left\n * the zod schema `undefined` at evaluation time. The first fix was a type-only\n * import plus a hand-written `['list', 'unknown'] as const satisfies readonly\n * PriceBasis[]` mirror in decision-cost.ts. That mirror was a data-loss hazard:\n * `satisfies` rejects a member being RENAMED or DROPPED but happily accepts the\n * union GAINING one, so an added member would compile, fail validation at the\n * persistence boundary, and make `JsonlStore` reject the ENTIRE decision record\n * — `append` returning `persisted: false`, and on read the line skipped with\n * only an aggregate debug count. Governance and billing data lost wholesale\n * over one unrecognised field value.\n *\n * This module has no imports beyond zod, so both sides can import it at runtime\n * without a cycle, and the duplication is gone rather than merely guarded: the\n * schema is the single definition and the TypeScript union is DERIVED from it,\n * so a new member cannot be added to one and not the other.\n *\n * @module core/price-basis\n * (Source: Issue #4406)\n */\n\nimport { z } from 'zod';\n\n/**\n * The vocabulary itself. Members:\n *\n * - `'list'` — a registry-chain rate, read as an assumed published rate;\n * the fuzzy-match caveat on {@link PriceBasis} applies.\n * - `'declared'` — an operator-asserted manifest-overlay price (#4600) or\n * `NEXUS_GATEWAY_COST` statement: `priced:<in>,<out>`, `free`, or `local`\n * (#6664). The assertion does not verify the vendor's billing rate.\n * - `'unknown'` — no price was resolved for this model. Read it as \"the chain\n * produced nothing\", not \"no price exists in the world\": the generated\n * catalog loader (`config/models-generated-loader.ts`) deliberately discards\n * a published $0/$0 rate unless the id ends `:free`, so a genuinely free\n * model can land here.\n *\n * Deriving the type from the schema (rather than the reverse) is what keeps the\n * runtime validator and the compile-time union from drifting.\n */\nexport const PriceBasisSchema = z.enum(['list', 'declared', 'unknown']);\n\n/**\n * Where a price came from, so a consumer can caveat it honestly (#4406).\n *\n * `'list'` is an ASSUMPTION about the pricing chain, not a verified property\n * of the number. Most tiers supply vendors' advertised public rates. The\n * normalized/fuzzy identity tier (`config/model-registry.ts`\n * `mergeMatchedWithDerived`) can grant a decorated gateway id the pricing of\n * a DIFFERENT canonical entry it matched, so a resolved published rate need\n * not belong to the id being priced.\n *\n * The manifest overlay (`config/manifest-overlay.ts`) is the highest pricing\n * tier. A price supplied there reports `'declared'`, using the rate's supplying\n * tier, including through a fuzzy match's `resolvedFrom`. Metadata-only overlays\n * inherit the lower tier's rate and basis; the overall entry can be a manifest\n * while its price remains `list`.\n *\n * Explicit `NEXUS_GATEWAY_COST` rates (`priced:<in>,<out>`, `free`, `local`)\n * also report `'declared'`, including measured zero. Bare `priced` delegates\n * to the registry and inherits its basis. Missing or invalid declarations\n * remain `'unknown'`. `'unknown'` does not claim that no price exists; see\n * the loader caveat above.\n *\n * There is deliberately no `'contract'` member: manifest-overlay prices use\n * the existing `'declared'` label for operator assertions, whether negotiated\n * or otherwise. Neither declaration path verifies an account's contract.\n * Reusing this vocabulary preserves older JSONL readers and MCP output schemas.\n */\nexport type PriceBasis = z.infer<typeof PriceBasisSchema>;\n\n/**\n * Human-readable caveat for a {@link PriceBasis}, for surfaces that show a cost\n * to a person. Keeps the wording in one place rather than restated per caller.\n *\n * Returns undefined for `'unknown'`: there is no price to caveat.\n */\nexport function priceBasisCaveat(basis: PriceBasis): string | undefined {\n switch (basis) {\n case 'list':\n return 'Estimated from public list prices — your contract, gateway or free-tier rate may differ.';\n case 'declared':\n return 'Based on an operator-declared rate, not a verified published price.';\n case 'unknown':\n return undefined;\n default: {\n const unreachable: never = basis;\n throw new Error(`Unhandled price basis: ${String(unreachable)}`);\n }\n }\n}\n"],"mappings":"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","names":["z","z","z"]}
@@ -1833,7 +1833,7 @@ function setDefaultRegistry(registry) {
1833
1833
  }
1834
1834
  async function reloadDefaultRegistry() {
1835
1835
  globalRegistry = buildDefaultRegistry();
1836
- const { resetGlobalRegistry } = await import("./unified-registry-MQU75RZ2.js");
1836
+ const { resetGlobalRegistry } = await import("./unified-registry-KETKSBQE.js");
1837
1837
  resetGlobalRegistry();
1838
1838
  return globalRegistry;
1839
1839
  }
@@ -1863,4 +1863,4 @@ export {
1863
1863
  setDefaultRegistry,
1864
1864
  reloadDefaultRegistry
1865
1865
  };
1866
- //# sourceMappingURL=chunk-VV4OWT42.js.map
1866
+ //# sourceMappingURL=chunk-RY6ICQME.js.map
@@ -62,7 +62,7 @@ import {
62
62
  updateStage,
63
63
  withFileLock,
64
64
  writeJobCancelled
65
- } from "./chunk-6W6Q55WT.js";
65
+ } from "./chunk-MDLDQCYX.js";
66
66
  import {
67
67
  allOf,
68
68
  anyOf
@@ -70,7 +70,7 @@ import {
70
70
  import {
71
71
  normalizeTopicToCanonical,
72
72
  synthesizeResearch
73
- } from "./chunk-5Z7ZVR2Z.js";
73
+ } from "./chunk-7H2SQVVG.js";
74
74
  import {
75
75
  IssueTriage,
76
76
  createAuditTrail,
@@ -79,13 +79,13 @@ import {
79
79
  createGraphAuditBridge,
80
80
  emitPipelinePolicyEvent,
81
81
  readActionRefusal
82
- } from "./chunk-73PYZXMP.js";
82
+ } from "./chunk-7NCAEQWG.js";
83
83
  import {
84
84
  sanitizeInput
85
85
  } from "./chunk-RYDTFPVI.js";
86
86
  import {
87
87
  withPrerequisite
88
- } from "./chunk-T7XQUVDD.js";
88
+ } from "./chunk-XODHLPFS.js";
89
89
  import {
90
90
  NOOP_NOTIFIER,
91
91
  RateLimiter,
@@ -117,7 +117,7 @@ import {
117
117
  toolSuccess,
118
118
  withProgressHeartbeat,
119
119
  wrapToolWithTimeout
120
- } from "./chunk-I2KRFRQN.js";
120
+ } from "./chunk-JZQ4XZKS.js";
121
121
  import {
122
122
  generateSecurityPlan
123
123
  } from "./chunk-KMGKOF5P.js";
@@ -163,7 +163,7 @@ import {
163
163
  parseRegistry,
164
164
  sourceExistsInRegistry,
165
165
  summarizeContextForPrompt
166
- } from "./chunk-3O2NKHMC.js";
166
+ } from "./chunk-6QUSTQ57.js";
167
167
  import {
168
168
  REGISTRY_PATH,
169
169
  computeSourceQualityScore,
@@ -171,11 +171,11 @@ import {
171
171
  loadPapersRegistry,
172
172
  loadTechniquesRegistry,
173
173
  resolveRegistryRoot
174
- } from "./chunk-P4Z7ASRK.js";
174
+ } from "./chunk-X3ZVXL5R.js";
175
175
  import {
176
176
  getTokenEnvVars,
177
177
  resolveToken
178
- } from "./chunk-GX7RTQ72.js";
178
+ } from "./chunk-4HXQJ5CA.js";
179
179
  import {
180
180
  DEFAULT_RELEVANCE_CONFIG,
181
181
  MemoryImportance,
@@ -183,7 +183,7 @@ import {
183
183
  calculateTextJaccardSimilarity,
184
184
  getToolMemory,
185
185
  memoryTrustTierTag
186
- } from "./chunk-4NXA64HN.js";
186
+ } from "./chunk-ITUUK6GW.js";
187
187
  import {
188
188
  EXTERNAL_CONTENT_TRUST_TIER,
189
189
  resolveContentTrustProvenance,
@@ -192,7 +192,7 @@ import {
192
192
  } from "./chunk-RGB5OTRZ.js";
193
193
  import {
194
194
  createSessionMemory
195
- } from "./chunk-XQ4T3HTK.js";
195
+ } from "./chunk-ZQJ74T3F.js";
196
196
  import {
197
197
  TrustTierSchema
198
198
  } from "./chunk-BFO2NZPO.js";
@@ -207,7 +207,7 @@ import {
207
207
  } from "./chunk-MZWHXERV.js";
208
208
  import {
209
209
  executeExpert
210
- } from "./chunk-HXST42DL.js";
210
+ } from "./chunk-D23AGH2N.js";
211
211
  import {
212
212
  CliDetectionCache,
213
213
  EventTopics,
@@ -218,7 +218,7 @@ import {
218
218
  getAvailableClis,
219
219
  getGlobalEventBus,
220
220
  getGlobalRegistry
221
- } from "./chunk-GEBTH3NI.js";
221
+ } from "./chunk-KEU6X3MM.js";
222
222
  import {
223
223
  DEFAULTS
224
224
  } from "./chunk-L47UF7ET.js";
@@ -235,7 +235,7 @@ import {
235
235
  getAvailabilityCache,
236
236
  getCliForModelId,
237
237
  resolveFallback
238
- } from "./chunk-KOQORWFZ.js";
238
+ } from "./chunk-HTWXUN4F.js";
239
239
  import {
240
240
  BaseAdapter,
241
241
  createStream,
@@ -243,11 +243,11 @@ import {
243
243
  parseGatewayExtraHeaders,
244
244
  requireApiKey,
245
245
  validateApiKeyPresence
246
- } from "./chunk-ON65PTMT.js";
246
+ } from "./chunk-HFL4QVDQ.js";
247
247
  import {
248
248
  BWRAP_READ_ONLY_ARGS,
249
249
  createBwrapPreflight
250
- } from "./chunk-2FP6YFHW.js";
250
+ } from "./chunk-I2SLK5RS.js";
251
251
  import {
252
252
  getMemoryRegistry
253
253
  } from "./chunk-ROYGBFVE.js";
@@ -255,14 +255,14 @@ import {
255
255
  SIGKILL_GRACE_MS,
256
256
  terminateProcessTree,
257
257
  trackProcessTree
258
- } from "./chunk-3QW7PDUF.js";
258
+ } from "./chunk-JG6RTOEO.js";
259
259
  import {
260
260
  generateHyphenId,
261
261
  generateUUID
262
- } from "./chunk-XBNAIMR2.js";
262
+ } from "./chunk-I527FJJZ.js";
263
263
  import {
264
264
  getDefaultCliCircuitBreakerRegistry
265
- } from "./chunk-TXDJE3BB.js";
265
+ } from "./chunk-DNBNM35J.js";
266
266
  import {
267
267
  sanitizeErrorDetails,
268
268
  sanitizeOutput
@@ -372,7 +372,7 @@ import {
372
372
  truncateWithInfo,
373
373
  withStep,
374
374
  withTimeout
375
- } from "./chunk-3UCQ242K.js";
375
+ } from "./chunk-MQYBHIOL.js";
376
376
  import {
377
377
  SUPPORTED_EXTENSIONS
378
378
  } from "./chunk-XBEKMUTO.js";
@@ -387,13 +387,13 @@ import {
387
387
  lookupInTreeCapability,
388
388
  modelSupportsAll,
389
389
  resolveOwnerCli
390
- } from "./chunk-UL6R3RVK.js";
390
+ } from "./chunk-YD3Y55SM.js";
391
391
  import {
392
392
  deriveEntry,
393
393
  getDefaultRegistry,
394
394
  resolveModelIdentity,
395
395
  resolveModelIdentitySync
396
- } from "./chunk-VV4OWT42.js";
396
+ } from "./chunk-RY6ICQME.js";
397
397
  import {
398
398
  ensureLearningDir,
399
399
  getMetaOutcomesFile,
@@ -409,7 +409,7 @@ import {
409
409
  outcomeFailureFields,
410
410
  resolveOutcomeCategory,
411
411
  routingArmCliSlot
412
- } from "./chunk-MPDSAFKU.js";
412
+ } from "./chunk-POLWDIVY.js";
413
413
  import {
414
414
  createLogger,
415
415
  getTimeProvider
@@ -31312,7 +31312,7 @@ function execIdFields(executionId) {
31312
31312
  async function populateUnifiedContextOnState(state, options) {
31313
31313
  const taskCandidate = state["task"];
31314
31314
  if (typeof taskCandidate !== "string" || taskCandidate === "") return;
31315
- const { getContextForTask: getContextForTask2, inferTaskCategory: inferTaskCategory2 } = await import("./context-retriever-G7C5I37C.js");
31315
+ const { getContextForTask: getContextForTask2, inferTaskCategory: inferTaskCategory2 } = await import("./context-retriever-DJQ6WK5U.js");
31316
31316
  const category = inferTaskCategory2(taskCandidate);
31317
31317
  const executionId = options?.executionId;
31318
31318
  const execFields = execIdFields(executionId);
@@ -48483,7 +48483,7 @@ async function tryIssueTriage(task) {
48483
48483
  try {
48484
48484
  const issueMatch = task.match(/github\.com\/([^/]+\/[^/]+)\/issues\/(\d+)/);
48485
48485
  if (issueMatch === null) return null;
48486
- const { createIssueTriage } = await import("./issue-triage-2CI5HWES.js");
48486
+ const { createIssueTriage } = await import("./issue-triage-B2B4IYDA.js");
48487
48487
  const triage = createIssueTriage();
48488
48488
  const owner = issueMatch[1] ?? "";
48489
48489
  const num2 = issueMatch[2] ?? "";
@@ -48511,7 +48511,7 @@ var VALID_TEMPLATES = /* @__PURE__ */ new Set([
48511
48511
  ]);
48512
48512
  async function classifyWithLLM(task) {
48513
48513
  try {
48514
- const { executeExpert: executeExpert2 } = await import("./expert-bridge-R2DHWMIM.js");
48514
+ const { executeExpert: executeExpert2 } = await import("./expert-bridge-ITQMWAKA.js");
48515
48515
  const prompt = [
48516
48516
  "Classify this task into exactly one pipeline template.",
48517
48517
  "Templates: dev (implementation/bug fix/refactor), research (investigate/evaluate/compare),",
@@ -48880,7 +48880,7 @@ function buildVotingInput(plan, config) {
48880
48880
  }
48881
48881
  async function executeSingleVote(plan, config, log) {
48882
48882
  try {
48883
- const { executeVoting } = await import("./consensus-vote-BHTMG2B3.js");
48883
+ const { executeVoting } = await import("./consensus-vote-BUDINEFA.js");
48884
48884
  const input = buildVotingInput(plan, config);
48885
48885
  const result = await executeVoting(input, log);
48886
48886
  return parseVotingResult(result);
@@ -50613,7 +50613,7 @@ function coerceSeverity(raw) {
50613
50613
  return raw;
50614
50614
  return "medium";
50615
50615
  }
50616
- var FINDINGS_FORMAT_INSTRUCTIONS = `If you have one or more findings (claims that justify request_changes), emit them in a fenced YAML block at the END of your reasoning, exactly as below. If you're approving, OMIT the block entirely.
50616
+ var FINDINGS_FORMAT_INSTRUCTIONS = `If you have one or more findings (claims that justify request_changes), emit them in a fenced YAML block at the END of your reasoning, exactly as below. Flag ONLY concrete, reachable, medium-or-higher severity defects; forbid style preferences, formatting, nits, and speculative concerns. If you're approving, OMIT the block entirely.
50617
50617
 
50618
50618
  \`\`\`yaml findings
50619
50619
  - summary: 'One-line summary of the issue'
@@ -50706,7 +50706,7 @@ ${safe.prDiff}
50706
50706
  parts.push(`- **APPROVE** if the diff is correct, complete, and aligned with your role.
50707
50707
  `);
50708
50708
  parts.push(
50709
- `- **REJECT** (= "request changes") if there is at least one concrete defect, missing requirement, or violation that justifies blocking the merge.
50709
+ `- **REJECT** (= "request changes") if there is at least one concrete, reachable defect of medium or higher severity that justifies blocking the merge. Forbid style/formatting preferences, nitpicks, and speculative concerns.
50710
50710
  `
50711
50711
  );
50712
50712
  parts.push(`- **ABSTAIN** if the diff is outside your role's concerns.
@@ -50724,7 +50724,7 @@ var memoryInitPromise = null;
50724
50724
  async function initPipelineMemory() {
50725
50725
  if (cachedMemory !== null) return cachedMemory;
50726
50726
  try {
50727
- const { createSessionMemory: createSessionMemory2 } = await import("./session-memory-JQLZO3XD.js");
50727
+ const { createSessionMemory: createSessionMemory2 } = await import("./session-memory-EDNBL5AG.js");
50728
50728
  const { getLearningDir } = await import("./learning-persistence-NW5AE222.js");
50729
50729
  const mem = createSessionMemory2(getLearningDir());
50730
50730
  mem.startSession(`pipeline-${String(getTimeProvider().now())}`);
@@ -50786,7 +50786,7 @@ function recordRoutingExperience(category, success, durationMs, tokensUsed = 0,
50786
50786
  callRecord(routingMemoryCache);
50787
50787
  return;
50788
50788
  }
50789
- routingMemoryInitPromise ??= import("./routing-memory-ZH74FCIT.js").then(({ createRoutingMemory }) => {
50789
+ routingMemoryInitPromise ??= import("./routing-memory-XFFA6XQW.js").then(({ createRoutingMemory }) => {
50790
50790
  routingMemoryCache ??= createRoutingMemory();
50791
50791
  return routingMemoryCache;
50792
50792
  }).catch((error) => {
@@ -51356,7 +51356,7 @@ async function prepareCompletePlanVote(plan, research, config, signal) {
51356
51356
  return { proposal, roleAdapters: panel.seats };
51357
51357
  }
51358
51358
  async function executePlanVote(plan, research, config, strategy, signal) {
51359
- const { executeVoting } = await import("./consensus-vote-BHTMG2B3.js");
51359
+ const { executeVoting } = await import("./consensus-vote-BUDINEFA.js");
51360
51360
  const { proposal, roleAdapters } = await prepareCompletePlanVote(plan, research, config, signal);
51361
51361
  const votingResult = await executeVoting(
51362
51362
  {
@@ -53167,7 +53167,7 @@ ${text}` : "";
53167
53167
  }
53168
53168
  async function getWeatherContext() {
53169
53169
  try {
53170
- const { generateWeatherReport: generateWeatherReport2 } = await import("./weather-report-WFALQQCE.js");
53170
+ const { generateWeatherReport: generateWeatherReport2 } = await import("./weather-report-MJWGQNR3.js");
53171
53171
  const report = generateWeatherReport2({ includeAdaptive: true });
53172
53172
  const mappings = "recommendedMappings" in report ? report.recommendedMappings : [];
53173
53173
  if (!Array.isArray(mappings) || mappings.length === 0) return "";
@@ -53185,7 +53185,7 @@ ${lines}
53185
53185
  }
53186
53186
  async function getMemoryContext(task) {
53187
53187
  try {
53188
- const { createSessionMemory: createSessionMemory2 } = await import("./session-memory-JQLZO3XD.js");
53188
+ const { createSessionMemory: createSessionMemory2 } = await import("./session-memory-EDNBL5AG.js");
53189
53189
  const { getLearningDir } = await import("./learning-persistence-NW5AE222.js");
53190
53190
  const memory = createSessionMemory2(getLearningDir(), { maxLearningsInContext: 10 });
53191
53191
  const learnings = memory.searchLearnings(task.slice(0, 200));
@@ -53944,7 +53944,7 @@ async function searchCodebaseForTask(task) {
53944
53944
  }
53945
53945
  async function queryResearchRegistry(task) {
53946
53946
  try {
53947
- const { synthesizeResearch: synthesizeResearch2 } = await import("./research-helpers-synthesize-MLXWMK3P.js");
53947
+ const { synthesizeResearch: synthesizeResearch2 } = await import("./research-helpers-synthesize-JRWNQZR7.js");
53948
53948
  const topic = task.split(/[.!?\n]/).filter((s) => s.trim().length > 10)[0]?.trim();
53949
53949
  if (topic === void 0) return null;
53950
53950
  const result = await synthesizeResearch2(topic.slice(0, 50));
@@ -54063,7 +54063,7 @@ function createScanStageWrapper() {
54063
54063
  try {
54064
54064
  const repo = await selectAuditRepository(ctx.task);
54065
54065
  if (!repo.ok) return failOutput(PIPELINE_STATE_KEYS.FINDINGS, repo.error, getTimeProvider().now() - start);
54066
- const { generateSecurityPlan: generateSecurityPlan2 } = await import("./repo-security-plan-J6B4DBYR.js");
54066
+ const { generateSecurityPlan: generateSecurityPlan2 } = await import("./repo-security-plan-QPI4B4UQ.js");
54067
54067
  const plan = await generateSecurityPlan2({ repo: repo.value, maxScanners: 10 });
54068
54068
  const recs = plan.recommendations.slice(0, 5).map((r) => `${r.priority}: ${r.displayName} (${r.category})`).join("; ");
54069
54069
  return output(PIPELINE_STATE_KEYS.FINDINGS, recs, getTimeProvider().now() - start, true);
@@ -57436,7 +57436,7 @@ var GitHubTaskTracker = class {
57436
57436
  cachedProvider = null;
57437
57437
  async getProvider() {
57438
57438
  if (this.cachedProvider !== null) return this.cachedProvider;
57439
- const { createScmProvider } = await import("./factory-AWJDMMF3.js");
57439
+ const { createScmProvider } = await import("./factory-XWEHISQV.js");
57440
57440
  const result = await createScmProvider({ repo: this.config.repo ?? "" });
57441
57441
  if (!result.ok) throw new Error(`SCM provider error: ${result.error.message}`);
57442
57442
  this.cachedProvider = result.value;
@@ -58555,7 +58555,7 @@ function withCatalogueCaveat(report) {
58555
58555
  var GATEWAY_TRANSPORT = "gateway";
58556
58556
  var GATEWAY_API_ARM = "api:custom-openai";
58557
58557
  async function gatewaySource(apiArm) {
58558
- const { discoverModels, readOpenAICompatEnv } = await import("./openai-compat-adapter-NFLZBHGU.js");
58558
+ const { discoverModels, readOpenAICompatEnv } = await import("./openai-compat-adapter-OINWDEMM.js");
58559
58559
  const config = readOpenAICompatEnv();
58560
58560
  if (config !== null) {
58561
58561
  return {
@@ -58574,7 +58574,7 @@ async function gatewaySource(apiArm) {
58574
58574
  }
58575
58575
  async function defaultSources(includeOpenRouter, adaptersFactory) {
58576
58576
  const adapters = new Map(
58577
- adaptersFactory !== void 0 ? adaptersFactory() : (await import("./factory-Q4GOORZG.js")).createAllAdapters()
58577
+ adaptersFactory !== void 0 ? adaptersFactory() : (await import("./factory-7KG4FG7V.js")).createAllAdapters()
58578
58578
  );
58579
58579
  const apiArm = adapters.get(GATEWAY_API_ARM);
58580
58580
  adapters.delete(GATEWAY_API_ARM);
@@ -61845,4 +61845,4 @@ export {
61845
61845
  initializeSandbox,
61846
61846
  getSandboxMode
61847
61847
  };
61848
- //# sourceMappingURL=chunk-42Z2Z2FP.js.map
61848
+ //# sourceMappingURL=chunk-TOQ7HR2R.js.map