dsh-llm-verifier 0.6.6 → 0.6.8

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 (70) hide show
  1. package/README.md +1 -0
  2. package/lib/{auto-DzlnuWAr.js → auto-DmyrNZXK.js} +172 -9
  3. package/lib/auto-DmyrNZXK.js.map +1 -0
  4. package/lib/{caller-BUK7OgUs.js → caller-Blp4l--v.js} +27 -6
  5. package/lib/caller-Blp4l--v.js.map +1 -0
  6. package/lib/caller.js +1 -1
  7. package/lib/client.js +8 -0
  8. package/lib/client.js.map +1 -1
  9. package/lib/index.js +336 -13
  10. package/lib/index.js.map +1 -1
  11. package/lib/replay.js +1 -1
  12. package/lib/types/auto.d.ts +15 -0
  13. package/lib/types/auto.d.ts.map +1 -1
  14. package/lib/types/auto.js +164 -7
  15. package/lib/types/auto.js.map +1 -1
  16. package/lib/types/cache.d.ts.map +1 -1
  17. package/lib/types/cache.js +30 -2
  18. package/lib/types/cache.js.map +1 -1
  19. package/lib/types/client-fields.d.ts +1 -0
  20. package/lib/types/client-fields.d.ts.map +1 -1
  21. package/lib/types/client-fields.js +3 -0
  22. package/lib/types/client-fields.js.map +1 -1
  23. package/lib/types/client-i18n.d.ts +6 -0
  24. package/lib/types/client-i18n.d.ts.map +1 -1
  25. package/lib/types/client-i18n.js +4 -0
  26. package/lib/types/client-i18n.js.map +1 -1
  27. package/lib/types/config.d.ts +9 -0
  28. package/lib/types/config.d.ts.map +1 -1
  29. package/lib/types/config.js +2 -0
  30. package/lib/types/config.js.map +1 -1
  31. package/lib/types/index.d.ts +12 -0
  32. package/lib/types/index.d.ts.map +1 -1
  33. package/lib/types/index.js +105 -10
  34. package/lib/types/index.js.map +1 -1
  35. package/lib/types/session.d.ts +12 -3
  36. package/lib/types/session.d.ts.map +1 -1
  37. package/lib/types/session.js +12 -3
  38. package/lib/types/session.js.map +1 -1
  39. package/lib/types/tool-decision.d.ts +45 -0
  40. package/lib/types/tool-decision.d.ts.map +1 -0
  41. package/lib/types/tool-decision.js +32 -0
  42. package/lib/types/tool-decision.js.map +1 -0
  43. package/lib/types/top-logprobs.d.ts.map +1 -1
  44. package/lib/types/top-logprobs.js +29 -8
  45. package/lib/types/top-logprobs.js.map +1 -1
  46. package/lib/types/workspace.d.ts +75 -0
  47. package/lib/types/workspace.d.ts.map +1 -0
  48. package/lib/types/workspace.js +243 -0
  49. package/lib/types/workspace.js.map +1 -0
  50. package/package.json +10 -10
  51. package/scripts/check-harness-types.mjs +114 -0
  52. package/src/auto.test.ts +140 -1
  53. package/src/auto.ts +149 -7
  54. package/src/cache.test.ts +78 -0
  55. package/src/cache.ts +31 -2
  56. package/src/client-fields.ts +4 -0
  57. package/src/client-i18n.ts +4 -0
  58. package/src/config.test.ts +12 -0
  59. package/src/config.ts +11 -0
  60. package/src/index.test.ts +180 -3
  61. package/src/index.ts +110 -12
  62. package/src/session.ts +12 -3
  63. package/src/tool-decision.test.ts +24 -0
  64. package/src/tool-decision.ts +51 -0
  65. package/src/top-logprobs.test.ts +15 -0
  66. package/src/top-logprobs.ts +28 -6
  67. package/src/workspace.test.ts +195 -0
  68. package/src/workspace.ts +312 -0
  69. package/lib/auto-DzlnuWAr.js.map +0 -1
  70. package/lib/caller-BUK7OgUs.js.map +0 -1
package/README.md CHANGED
@@ -263,6 +263,7 @@ flowchart LR
263
263
  | **最多候选数** | 自动 `select` 一次最多纳入的候选数,默认 `8` |
264
264
  | **每任务/每会话最多路由** | 限制自动路由**周期**的次数:`compare/select/track`、语义分类、团队任务闸、计划预审与 P06 的过程选优周期(过程周期同样消耗本项额度,因此它受既有路由额度约束;另有独立的过程周期每任务上限——恢复触发档 1 次,每步选优档 `maxProcessCyclesPerTask` 次)。**一次周期只消耗一次**——语义分类成立时会在同一个预约上直接提升为它解析出的 `compare/select/track`(分类+执行=1 次),因此默认 2 次足以完成「计划预审 → 分类+compare」;解析为 `none`、低置信、非法引用,或分类成功但执行预算不足时同样消费该周期(后者记录为 `classification-only-budget`,不会伪装成"未路由"或"已评审")。它与最终验收**各自独立计数**(路由用本项,最终验收用「每任务/每会话最多验收」,互不占用),因此被路由要求过的最终验收一定有额度可用;旧版共享一个计数器时,路由可以把最终验收的额度花光,导致 turn 在从未验收的情况下静默关闭。预算按真实对局数估算(8 候选约需 108 次调用);被拒绝时写入宿主日志并区分「预算不足 / 已有 verifier 在跑 / 同一证据已路由」,strict 下额外注入一次提示。每个周期还会在统计里留下一条 `route` 观测:周期 id、触发点、去向、预约调用数、证据保留/省略数与取消标记——它是诊断口径,**不是**模型调用数。分类去重按**渲染后的证据(提示词)**而非最后事件序号,追加纯叙述不会再次付费分类;周期 id 取 epoch+实例+序号,跨插件重载唯一,重载前后两个不同周期不会在看板与离线汇总里合并;没有预约的诊断行(预算丢弃、交付阶段跳过、证据读取失败 evidence-unreadable)共用同一套 epoch 命名空间 |
265
265
  | **同时验收子 Agent** | 默认关闭;开启后 `subagent` / fork 子会话也会执行自动路由与最终验收 |
266
+ | **接入真实文件改动证据** | 默认**开启**。会话验收(显式 `verifier_current_session` 与自动最终验收)把**宿主自己记录的**本轮文件改动作为证据交给裁判:改动文件清单(路径 + 增删行数)与逐文件前后对比(`@@` 块 + 带 `+`/`-`/空格前缀的行),经参考上下文分隔块进入提示词(因此改动不同必然重新评分,评分缓存键包含该文本)。它修的是「裁判只能从 `tool/call` 的参数反推 Agent 声称改了什么」——改完没落盘、或事后又被改写,过去与真实改动无从区分。限长沿用同一套预算:整块不超过「单项字符上限」(截断提示计入),最多渲染 8 个文件(超出在表头注明),其余字符按文件数用 `itemBudget` 分摊、逐文件按行截断并注明省略行数;`binary` / `oversized` 文件只列一行说明、不读取对比。宿主未提供该服务(0.1.1/0.1.5)、会话已销毁、`summary` 或 `diff` 报错时一律**静默降级为不带该证据**并在宿主日志告警,绝不阻断验收。需要 DSH 0.1.6+ 宿主 |
266
267
  | **过程选优** | 三档(旧布尔值兼容:`true`→`recovery`,`false`/缺省→`off`):`off`(默认)完全不进入该路径(不生成候选、不调用裁判、不缓冲响应);`recovery`(恢复触发)仅当同一任务最近两次已完成的验证运行**都失败**(「失败」从运行自己的判决读:`[exit code: N≠0]`、`N failed`、`error TS…`、`test result: FAILED`、`FAIL` 都算,工具级报错也算;`0 failed` 不算失败)时,为**下一次主模型请求**额外生成备选回复,每任务最多 1 个周期;`every-step`(每步选优)为**每个主循环请求**登记选优意图,无需失败信号,每任务最多 `maxProcessCyclesPerTask` 个周期。三档均**仅 smart 模式**生效(manual/strict 不进入该路径),触发后机制相同:额外生成备选(默认 N=2:原回复=候选 0,新增一份=候选 1;`autoProcessCandidates` 可提到 3 或 4,那时按锦标赛判定;采样温度不低于生成档位,避免低温会话买到原回复的副本),按 **process 判据**(失败靶向 / 与已失败尝试不同 / 可验证的一步)比较后**只回放胜者**。过程周期有自己的每任务上限(独立于路由与最终验收的第三本账),同时也消耗「每任务/每会话最多路由」额度,并受任务/会话模型调用预算与最终验收保留额度共同限制;生成与比较共用一个 `timeoutMs` 阶段截止时间。裁判视图里的任务、约束、最近失败证据与两份候选(含工具名与参数)**先脱敏再限长**,并按实际渲染文本计量总量,工具动作无法完整容纳时回退原回复。选优**不是**验收:胜者交给宿主后,最终验收照常覆盖随后产生的实际工作 |
267
268
  | **备选带上失败证据** | 默认**开启**,仅在过程选优非 `off` 时生效。`recovery` 档把触发本周期的那两次失败验证运行(先 `sanitizeVerifierText` 脱敏,再按单项/总量双层限长,总量 4000 字符)作为一条插件 user 消息附在备选请求之后,让额外生成的候选是针对真实失败的一次不同尝试,而不是同一提示词的再抽样;`every-step` 档只在任务恰好出现两连败信号时附带,无信号则不带;关闭即对照组(两份候选掌握的信息完全相同,周期照买)。裁判**不被告知**哪份候选带了证据,避免按来源而不是按内容打分;统计行的 `route.alternativeAugmented` 记录该差异,供真实任务对照读取。 |
268
269
  | **备选用另一个模型** | 默认留空:备选由当前会话模型再采样。可填**逗号分隔**的 `provider/model` 列表(例如 `deepseek-official/deepseek-v4-flash, openai/gpt-5`):第 i 份备选使用第 i 项,列表短于备选数时循环取用,候选之间因此是真正的不同假设;跨 provider 时**不继承**原请求的推理强度(适配器可能不认识该 id),`maxTokens` 与生成温度下限照旧,归一化后的整个列表记进 `route.alternativeModel`。代价是比较同时也在比「哪个模型更好」,与任务本身的质量不可分——所以它是实验臂,不是推荐配置。 |
@@ -122,10 +122,10 @@ var ScoreCache = class {
122
122
  };
123
123
  this.writing = this.writing.catch(() => {}).then(async () => {
124
124
  await mkdir(dirname(this.file), { recursive: true });
125
- const temporary = this.file + ".tmp-" + process.pid;
125
+ const temporary = this.file + ".tmp-" + process.pid + "-" + (replaceOrdinal += 1);
126
126
  await writeFile(temporary, JSON.stringify(snapshot), "utf8");
127
127
  try {
128
- await rename(temporary, this.file);
128
+ await replaceFile(temporary, this.file);
129
129
  } catch (error) {
130
130
  await unlink(temporary).catch(() => {});
131
131
  throw error;
@@ -134,14 +134,48 @@ var ScoreCache = class {
134
134
  await this.writing;
135
135
  }
136
136
  };
137
+ /** Replace failures that are a transient lock rather than a verdict about the cache directory. */
138
+ const TRANSIENT_REPLACE_CODES = /* @__PURE__ */ new Set([
139
+ "EPERM",
140
+ "EACCES",
141
+ "EBUSY"
142
+ ]);
143
+ /** Distinguishes the temporary file of every write in this process, across all cache instances. */
144
+ let replaceOrdinal = 0;
145
+ /**
146
+ * Windows refuses the replace with a transient sharing violation while a scanner or indexer still
147
+ * holds the freshly written file. The score this snapshot carries was already paid for, so those
148
+ * codes are retried; anything else, or a persistent failure, still fails the write.
149
+ * @param temporary - the written snapshot, or the named source of the replace.
150
+ * @param target - the cache file every reader opens.
151
+ */
152
+ async function replaceFile(temporary, target) {
153
+ for (let attempt = 1;; attempt += 1) try {
154
+ await rename(temporary, target);
155
+ return;
156
+ } catch (error) {
157
+ const code = error.code;
158
+ if (attempt >= 5 || code === void 0 || !TRANSIENT_REPLACE_CODES.has(code)) throw error;
159
+ await new Promise((resolve) => setTimeout(resolve, attempt * 10));
160
+ }
161
+ }
137
162
  //#endregion
138
163
  //#region src/session.ts
139
164
  /**
140
165
  * Read one session's event log.
141
166
  *
142
- * DSH 0.1.5 replaced the `events` array with `snapshotEvents()`; older hosts
143
- * expose the array directly. Both shapes are accepted so the plugin keeps
144
- * working across the versions it declares support for.
167
+ * DSH 0.1.5 replaced the `events` array with `snapshotEvents()`; older hosts expose the array
168
+ * directly. Both shapes are accepted so the plugin keeps working across the versions it declares
169
+ * support for.
170
+ *
171
+ * DSH 0.1.6 deprecated `snapshotEvents()`: existing logic may stay unmigrated, but new calls are
172
+ * prohibited, and so are wrappers that expose the same synchronous history — this function is such
173
+ * a wrapper and is kept deliberately. The replacement the host offers, `SessionController.page()`,
174
+ * is filtered to `user/message` and `assistant/message`, so `tool/call`, `tool/result` and the PTC
175
+ * dispatches this plugin scores on do not come back through it; the host's own `auto-review`
176
+ * carries the same waiver for the same reason. The migration is to maintain the evidence these
177
+ * readers need through a registered Session projection instead of looking back through the log;
178
+ * `AGENTS.md` records the decision and what would force it.
145
179
  * @param session - Agent session, or any object exposing one of the two shapes.
146
180
  * @returns The session's events in log order, or an empty array.
147
181
  */
@@ -614,7 +648,7 @@ const VERIFIER_EVIDENCE_TOOLS = /* @__PURE__ */ new Set([
614
648
  "verifier_current_session"
615
649
  ]);
616
650
  /** Tools that return either a child's report (evidence) or a bare start acknowledgement (not evidence). */
617
- const SUBAGENT_TOOLS = /* @__PURE__ */ new Set(["subagent", "subagent_fork"]);
651
+ const SUBAGENT_TOOLS$1 = /* @__PURE__ */ new Set(["subagent", "subagent_fork"]);
618
652
  /**
619
653
  * Start acknowledgement of a background child.
620
654
  *
@@ -638,7 +672,7 @@ function isEvidenceOutput(name, text) {
638
672
  if (BOOKKEEPING_TOOLS.has(name) || VERIFIER_EVIDENCE_TOOLS.has(name)) return false;
639
673
  const body = text.trim();
640
674
  if (!body) return false;
641
- return !(SUBAGENT_TOOLS.has(name) && CHILD_START_ACKNOWLEDGEMENT.test(body));
675
+ return !(SUBAGENT_TOOLS$1.has(name) && CHILD_START_ACKNOWLEDGEMENT.test(body));
642
676
  }
643
677
  /** Signatures of an output that reports a PASSED verification result. */
644
678
  const VERIFICATION_PASS_SIGNATURES = [
@@ -1849,6 +1883,116 @@ function isSuccessfulCodeDispatch(data) {
1849
1883
  if (Array.isArray(data.content) && data.content.some((b) => b.isError === true)) return false;
1850
1884
  return true;
1851
1885
  }
1886
+ const SUBAGENT_TOOLS = /* @__PURE__ */ new Set(["subagent", "subagent_fork"]);
1887
+ const CONTINUABLE_SUBAGENT_START = /^\s*started subagent\s+([^\s`]+)/imu;
1888
+ const BACKGROUND_SUBAGENT_JOB_START = /^\s*started background subagent job\s+([^\s`]+)/imu;
1889
+ const GENERAL_SUBAGENT_START = /^\s*started (?:background )?subagent\b/imu;
1890
+ /**
1891
+ * Whether background subagents started during the current task remain in flight.
1892
+ *
1893
+ * A background subagent returns immediately with a start receipt (`started subagent <id>`
1894
+ * or `started background subagent job <id>`) and settles later via a runtime-injected notice
1895
+ * (`source.kind === 'subagent-settled'` or a job settlement notice). Performing session
1896
+ * acceptance while subagents are in flight will always fail and steer prematurely because the
1897
+ * delegated work has not reported back yet.
1898
+ * @param events - session events.
1899
+ * @param taskStartSeq - sequence number of the current direct user task statement.
1900
+ * @returns True when at least one background subagent remains unsettled.
1901
+ */
1902
+ function hasPendingSubagents(events, taskStartSeq) {
1903
+ const relevant = events.filter((event) => event.seq >= taskStartSeq);
1904
+ const pendingContinuable = /* @__PURE__ */ new Map();
1905
+ const pendingJobs = /* @__PURE__ */ new Map();
1906
+ let anonymousPendingCount = 0;
1907
+ const calls = /* @__PURE__ */ new Map();
1908
+ for (const event of relevant) if (event.type === "tool/call") calls.set(String(event.data.callId), event);
1909
+ for (const event of relevant) {
1910
+ if (event.type === "tool/result") {
1911
+ const call = calls.get(String(event.data.message.source.callId));
1912
+ if (call && SUBAGENT_TOOLS.has(call.data.name) && event.data.error === void 0) {
1913
+ if (event.data.message.content.every((b) => b.isError !== true)) {
1914
+ const text = blockText(event.data.message.content);
1915
+ const contMatch = text.match(CONTINUABLE_SUBAGENT_START);
1916
+ const jobMatch = text.match(BACKGROUND_SUBAGENT_JOB_START);
1917
+ if (contMatch) pendingContinuable.set(contMatch[1], event.seq);
1918
+ else if (jobMatch) pendingJobs.set(jobMatch[1], event.seq);
1919
+ else if (GENERAL_SUBAGENT_START.test(text)) anonymousPendingCount += 1;
1920
+ }
1921
+ }
1922
+ } else if (CODE_DISPATCH_TYPES.has(event.type)) {
1923
+ const data = event.data;
1924
+ if (data && SUBAGENT_TOOLS.has(data.name) && isSuccessfulCodeDispatch(data)) {
1925
+ const text = blockText(data.content);
1926
+ const contMatch = text.match(CONTINUABLE_SUBAGENT_START);
1927
+ const jobMatch = text.match(BACKGROUND_SUBAGENT_JOB_START);
1928
+ if (contMatch) pendingContinuable.set(contMatch[1], event.seq);
1929
+ else if (jobMatch) pendingJobs.set(jobMatch[1], event.seq);
1930
+ else if (GENERAL_SUBAGENT_START.test(text)) anonymousPendingCount += 1;
1931
+ }
1932
+ }
1933
+ if (event.type === "user/message") {
1934
+ const source = event.data?.source;
1935
+ const text = blockText(event.data?.content);
1936
+ if (source?.kind === "subagent-settled") {
1937
+ const senderId = typeof source.senderSessionId === "string" ? source.senderSessionId : void 0;
1938
+ if (senderId && pendingContinuable.has(senderId)) pendingContinuable.delete(senderId);
1939
+ else {
1940
+ let found = false;
1941
+ for (const [id] of pendingContinuable) if (text.includes(id)) {
1942
+ pendingContinuable.delete(id);
1943
+ found = true;
1944
+ break;
1945
+ }
1946
+ if (!found) {
1947
+ if (pendingContinuable.size > 0) {
1948
+ const oldest = pendingContinuable.keys().next().value;
1949
+ if (oldest !== void 0) pendingContinuable.delete(oldest);
1950
+ } else if (anonymousPendingCount > 0) anonymousPendingCount -= 1;
1951
+ }
1952
+ }
1953
+ } else if (source?.plugin === "tool-jobs" || /background job\b.*finished/iu.test(text)) {
1954
+ for (const [jobId] of pendingJobs) if (text.includes(jobId)) {
1955
+ pendingJobs.delete(jobId);
1956
+ break;
1957
+ }
1958
+ }
1959
+ }
1960
+ if (event.type === "tool/call") {
1961
+ const name = event.data.name;
1962
+ const argsText = event.data.arguments;
1963
+ let parsedArgs = {};
1964
+ if (typeof argsText === "string") try {
1965
+ parsedArgs = JSON.parse(argsText);
1966
+ } catch {}
1967
+ else if (typeof argsText === "object" && argsText !== null) parsedArgs = argsText;
1968
+ if (name === "interrupt_agent") {
1969
+ const target = String(parsedArgs.target ?? parsedArgs.agent_id ?? "");
1970
+ if (target && pendingContinuable.has(target)) pendingContinuable.delete(target);
1971
+ } else if (name === "job_kill") {
1972
+ const jobId = String(parsedArgs.job_id ?? "");
1973
+ if (jobId && pendingJobs.has(jobId)) pendingJobs.delete(jobId);
1974
+ }
1975
+ } else if (CODE_DISPATCH_TYPES.has(event.type)) {
1976
+ const data = event.data;
1977
+ if (data) {
1978
+ const name = data.name;
1979
+ let parsedArgs = {};
1980
+ if (typeof data.arguments === "string") try {
1981
+ parsedArgs = JSON.parse(data.arguments);
1982
+ } catch {}
1983
+ else if (typeof data.arguments === "object" && data.arguments !== null) parsedArgs = data.arguments;
1984
+ if (name === "interrupt_agent") {
1985
+ const target = String(parsedArgs.target ?? parsedArgs.agent_id ?? "");
1986
+ if (target && pendingContinuable.has(target)) pendingContinuable.delete(target);
1987
+ } else if (name === "job_kill") {
1988
+ const jobId = String(parsedArgs.job_id ?? "");
1989
+ if (jobId && pendingJobs.has(jobId)) pendingJobs.delete(jobId);
1990
+ }
1991
+ }
1992
+ }
1993
+ }
1994
+ return pendingContinuable.size > 0 || pendingJobs.size > 0 || anonymousPendingCount > 0;
1995
+ }
1852
1996
  function analyzeAutoTask(events, policy, sessionId) {
1853
1997
  const taskStartSeq = latestDirectUserSeq(events);
1854
1998
  if (taskStartSeq === void 0) return {
@@ -1858,6 +2002,7 @@ function analyzeAutoTask(events, policy, sessionId) {
1858
2002
  consequentialToolCalls: 0,
1859
2003
  hasManualSessionVerification: false,
1860
2004
  manualVerificationAccepted: false,
2005
+ pendingSubagents: false,
1861
2006
  eligible: false,
1862
2007
  reason: "no-direct-user-task"
1863
2008
  };
@@ -1915,6 +2060,7 @@ function analyzeAutoTask(events, policy, sessionId) {
1915
2060
  criteria: verdict.criteria
1916
2061
  }, policy.threshold) && !stale(verdict.toSeq);
1917
2062
  });
2063
+ const pendingSubagents = hasPendingSubagents(events, taskStartSeq);
1918
2064
  if (policy.mode === "manual") return {
1919
2065
  taskStartSeq,
1920
2066
  toolCalls,
@@ -1922,6 +2068,7 @@ function analyzeAutoTask(events, policy, sessionId) {
1922
2068
  consequentialToolCalls,
1923
2069
  hasManualSessionVerification,
1924
2070
  manualVerificationAccepted,
2071
+ pendingSubagents,
1925
2072
  eligible: false,
1926
2073
  reason: "manual-mode"
1927
2074
  };
@@ -1932,9 +2079,21 @@ function analyzeAutoTask(events, policy, sessionId) {
1932
2079
  consequentialToolCalls,
1933
2080
  hasManualSessionVerification,
1934
2081
  manualVerificationAccepted,
2082
+ pendingSubagents,
1935
2083
  eligible: false,
1936
2084
  reason: "already-verified"
1937
2085
  };
2086
+ if (pendingSubagents) return {
2087
+ taskStartSeq,
2088
+ toolCalls,
2089
+ completedToolResults,
2090
+ consequentialToolCalls,
2091
+ hasManualSessionVerification,
2092
+ manualVerificationAccepted,
2093
+ pendingSubagents: true,
2094
+ eligible: false,
2095
+ reason: "pending-subagents"
2096
+ };
1938
2097
  if (consequentialToolCalls === 0) return {
1939
2098
  taskStartSeq,
1940
2099
  toolCalls,
@@ -1942,6 +2101,7 @@ function analyzeAutoTask(events, policy, sessionId) {
1942
2101
  consequentialToolCalls,
1943
2102
  hasManualSessionVerification,
1944
2103
  manualVerificationAccepted,
2104
+ pendingSubagents,
1945
2105
  eligible: false,
1946
2106
  reason: "no-consequential-work"
1947
2107
  };
@@ -1952,6 +2112,7 @@ function analyzeAutoTask(events, policy, sessionId) {
1952
2112
  consequentialToolCalls,
1953
2113
  hasManualSessionVerification,
1954
2114
  manualVerificationAccepted,
2115
+ pendingSubagents,
1955
2116
  eligible: false,
1956
2117
  reason: "no-completed-evidence"
1957
2118
  };
@@ -1962,6 +2123,7 @@ function analyzeAutoTask(events, policy, sessionId) {
1962
2123
  consequentialToolCalls,
1963
2124
  hasManualSessionVerification,
1964
2125
  manualVerificationAccepted,
2126
+ pendingSubagents,
1965
2127
  eligible: false,
1966
2128
  reason: "insufficient-tool-evidence"
1967
2129
  };
@@ -1972,6 +2134,7 @@ function analyzeAutoTask(events, policy, sessionId) {
1972
2134
  consequentialToolCalls,
1973
2135
  hasManualSessionVerification,
1974
2136
  manualVerificationAccepted,
2137
+ pendingSubagents,
1975
2138
  eligible: true,
1976
2139
  reason: policy.mode + "-eligible"
1977
2140
  };
@@ -2139,6 +2302,6 @@ function selectRouteFeedbackDetail(candidates, result, maxChars = MAX_ROUTE_FEED
2139
2302
  ].join("\n"));
2140
2303
  }
2141
2304
  //#endregion
2142
- export { verificationFailed as A, latestDirectUserSeq as C, semanticDecision as D, routedRepeats as E, ScoreCache as F, SingleFlight as I, resolveCacheFile as L, extractSession as M, sanitizeVerifierText as N, semanticReferencesVisible as O, sessionEvents as P, stableHash as R, itemBudget as S, parseSemanticRoute as T, buildSemanticRoutePrompt as _, compareRouteFeedbackDetail as a, inspectDeliveryPhase as b, selectRouteFeedbackDetail as c, AutoVerifierRouter as d, MAX_ROUTED_CHECKPOINTS as f, buildEvidenceIndex as g, boundDecision as h, automaticFeedback as i, verificationVerdict as j, semanticRouteHint as k, sessionAccepted as l, analyzeStructuredRoute as m, PROPOSAL_FEEDBACK_NOTE as n, failedAcceptanceCriteria as o, RECOVERY_FAILURE_CONTEXT_CHARS as p, analyzeAutoTask as r, isSubagentSession as s, MAX_ROUTE_FEEDBACK_CHARS as t, topScoreIndices as u, buildSemanticRouteView as v, nextDiagnosticCycleId as w, inspectRecoverySignal as x, estimateRoutedCalls as y };
2305
+ export { semanticRouteHint as A, itemBudget as C, routedRepeats as D, parseSemanticRoute as E, sessionEvents as F, ScoreCache as I, SingleFlight as L, verificationVerdict as M, extractSession as N, semanticDecision as O, sanitizeVerifierText as P, resolveCacheFile as R, inspectRecoverySignal as S, nextDiagnosticCycleId as T, buildEvidenceIndex as _, compareRouteFeedbackDetail as a, estimateRoutedCalls as b, isSubagentSession as c, topScoreIndices as d, AutoVerifierRouter as f, boundDecision as g, analyzeStructuredRoute as h, automaticFeedback as i, verificationFailed as j, semanticReferencesVisible as k, selectRouteFeedbackDetail as l, RECOVERY_FAILURE_CONTEXT_CHARS as m, PROPOSAL_FEEDBACK_NOTE as n, failedAcceptanceCriteria as o, MAX_ROUTED_CHECKPOINTS as p, analyzeAutoTask as r, hasPendingSubagents as s, MAX_ROUTE_FEEDBACK_CHARS as t, sessionAccepted as u, buildSemanticRoutePrompt as v, latestDirectUserSeq as w, inspectDeliveryPhase as x, buildSemanticRouteView as y, stableHash as z };
2143
2306
 
2144
- //# sourceMappingURL=auto-DzlnuWAr.js.map
2307
+ //# sourceMappingURL=auto-DmyrNZXK.js.map