opencode-agent-skill 15.0.0 → 15.1.1

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 (43) hide show
  1. package/README.md +5 -5
  2. package/docs/V15-MANAGED-RUNTIME.md +18 -0
  3. package/global-config/agents/verifier.md +6 -2
  4. package/lib/affected-tests.mjs +58 -8
  5. package/lib/capability-fabric.mjs +107 -48
  6. package/lib/code-intelligence/index.mjs +4 -15
  7. package/lib/code-intelligence/lsp-pool.mjs +694 -0
  8. package/lib/code-intelligence/lsp-provider.mjs +481 -67
  9. package/lib/compaction-resume-guard.mjs +327 -0
  10. package/lib/completion-auditor.mjs +20 -0
  11. package/lib/context-engine-v11.mjs +20 -7
  12. package/lib/context-manifest.mjs +38 -21
  13. package/lib/decision-policy.mjs +40 -2
  14. package/lib/evidence-store.mjs +121 -31
  15. package/lib/executable-probe.mjs +69 -0
  16. package/lib/execution-contract.mjs +29 -16
  17. package/lib/hierarchical-context.mjs +31 -3
  18. package/lib/learning-engine.mjs +164 -65
  19. package/lib/memory-engine.mjs +348 -98
  20. package/lib/model-config.mjs +86 -7
  21. package/lib/performance-fabric.mjs +354 -107
  22. package/lib/permission-policy.mjs +232 -0
  23. package/lib/pi-rpc-pool.mjs +170 -5
  24. package/lib/provider-recovery.mjs +51 -0
  25. package/lib/repo-graph.mjs +38 -5
  26. package/lib/runtime-events.mjs +31 -10
  27. package/lib/semantic-index.mjs +67 -20
  28. package/lib/skill-compiler.mjs +84 -18
  29. package/lib/subagent-artifacts.mjs +182 -0
  30. package/lib/task-policy.mjs +80 -7
  31. package/lib/trajectory.mjs +25 -1
  32. package/lib/untrusted-output.mjs +106 -0
  33. package/lib/verification-broker.mjs +32 -27
  34. package/lib/workspace-fingerprint.mjs +43 -8
  35. package/lib/workspace-hygiene.mjs +481 -0
  36. package/package.json +8 -6
  37. package/pi/extensions/ues-child-runtime.ts +103 -5
  38. package/pi/extensions/ues.ts +984 -95
  39. package/scripts/benchmark-lsp-pool.mjs +128 -0
  40. package/scripts/check-release-consistency.mjs +16 -4
  41. package/scripts/check-source-integrity.mjs +60 -1
  42. package/scripts/run-test-suite.mjs +143 -0
  43. package/scripts/smoke-package-closure.mjs +4 -0
@@ -33,17 +33,23 @@ import { findReusableVerification, listReusableVerification, recordVerification
33
33
  import { evaluateFastVerificationGate } from "../../lib/fast-verification-gate.mjs";
34
34
  import { turboFastPathDecision, turboFastTimeoutBudget } from "../../lib/turbo-fast-path.mjs";
35
35
  import { failureDelta, leafTaskPolicy } from "../../lib/leaf-runtime-optimizer.mjs";
36
+ import { classifyProviderFailure, providerRecoveryBackoffMs } from "../../lib/provider-recovery.mjs";
36
37
  import { planningRuntimeBudget, shouldSoftSteerArchitect, shouldSoftSteerPlanningRole } from "../../lib/planning-speed-policy.mjs";
37
38
  import { sourceFacingPaths, sourceGitPathspecs } from "../../lib/runtime-artifacts.mjs";
39
+ import { createSubagentArtifact, failSubagentArtifact, finalizeSubagentArtifact, listSubagentArtifacts, readSubagentArtifact } from "../../lib/subagent-artifacts.mjs";
38
40
  import { buildExecutionContract, buildFinalVerdictMatrix, captureInheritedDirtyState, detectInheritedDirtyViolations, enforcePhaseGates, executionContractPrompt, phaseArtifactPayloads, taskExplicitlyAllowsLocalEnvWrite } from "../../lib/execution-contract.mjs";
41
+ import { buildCompactionResumeGuard, checkpointDurableWorkBeforeCompaction, renderCompactionResumeGuard } from "../../lib/compaction-resume-guard.mjs";
39
42
  import { sessionNameFromUesInput, uesSessionName } from "../../lib/session-display.mjs";
40
43
  import { requireGitWorkspaceRoot, resolveGitWorkspaceRoot } from "../../lib/workspace-root.mjs";
41
44
  import { createAdaptiveDeadline } from "../../lib/activity-deadline.mjs";
42
45
  import { extractValidatedPlan } from "../../lib/plan-salvage.mjs";
43
46
  import { auditCompletion } from "../../lib/completion-auditor.mjs";
44
47
  import { mcpExecutionPolicy } from "../../lib/mcp-tool-policy.mjs";
48
+ import { PermissionPolicyStore, permissionRecoveryHint, toolPermissionRequest } from "../../lib/permission-policy.mjs";
49
+ import { analyzeUntrustedOutput, renderUntrustedOutputWarning } from "../../lib/untrusted-output.mjs";
45
50
  import { McpHealthTracker } from "../../lib/mcp-health.mjs";
46
- import { runtimeWorkspaceFingerprint, runtimeWorkspaceSnapshot } from "../../lib/workspace-fingerprint.mjs";
51
+ import { captureWorkspaceStateV2, runtimeWorkspaceFingerprint, runtimeWorkspaceSnapshot } from "../../lib/workspace-fingerprint.mjs";
52
+ import { captureWorkspaceHygieneBaseline, postRunFileHygiene, preFinalWorkspaceAudit } from "../../lib/workspace-hygiene.mjs";
47
53
  import { appendTrajectoryEvent, createTraceID } from "../../lib/trajectory.mjs";
48
54
  import {
49
55
  browserEvidenceNeeded,
@@ -53,6 +59,17 @@ import {
53
59
  } from "../../lib/browser-mcp-routing.mjs";
54
60
  import { clearRepoGraphRuntimeCache } from "../../lib/repo-graph.mjs";
55
61
  import { clearSemanticIndexRuntimeCache } from "../../lib/semantic-index.mjs";
62
+ import {
63
+ diagnoseCode,
64
+ lspOperation,
65
+ lspPoolStatus,
66
+ probeCodeIntelligence,
67
+ readAnchoredCode,
68
+ searchCodeIntelligence,
69
+ shutdownLspPool,
70
+ } from "../../lib/code-intelligence/index.mjs";
71
+ import { ingestDocument } from "../../lib/document-ingestion.mjs";
72
+ import { compactContext, expandContext, searchContext } from "../../lib/reversible-context.mjs";
56
73
  import {
57
74
  createTaskSandbox,
58
75
  integrateTaskSandbox,
@@ -158,6 +175,22 @@ const CONTEXT_CACHE_MAX = configuredCount(
158
175
  4,
159
176
  128,
160
177
  );
178
+ const PROVIDER_RECOVERY_RETRIES = (() => {
179
+ const parsed = Number(process.env.UES_PROVIDER_RECOVERY_RETRIES ?? "1");
180
+ if (!Number.isFinite(parsed)) return 1;
181
+ return Math.max(0, Math.min(2, Math.trunc(parsed)));
182
+ })();
183
+ const PROVIDER_SESSION_RESUME_RETRIES = (() => {
184
+ const parsed = Number(process.env.UES_PROVIDER_SESSION_RESUME_RETRIES ?? "1");
185
+ if (!Number.isFinite(parsed)) return 1;
186
+ return Math.max(0, Math.min(2, Math.trunc(parsed)));
187
+ })();
188
+ const PROVIDER_RECOVERY_BASE_DELAY_MS = configuredDuration(
189
+ "UES_PROVIDER_RECOVERY_BASE_DELAY_MS",
190
+ 250,
191
+ 50,
192
+ 5_000,
193
+ );
161
194
 
162
195
  function configuredBoolean(name: string, fallback = true) {
163
196
  const raw = String(process.env[name] ?? "").trim().toLowerCase();
@@ -183,6 +216,9 @@ const MCP_HEALTH = new McpHealthTracker({
183
216
  failureThreshold: 2,
184
217
  cooldownMs: configuredDuration("UES_MCP_HEALTH_COOLDOWN_MS", 15_000, 1_000, 5 * 60_000),
185
218
  });
219
+ const PERMISSION_POLICY = new PermissionPolicyStore(
220
+ path.join(getUesConfigDir(), ".ues", "permissions.json"),
221
+ );
186
222
 
187
223
  function abortActiveCliChildren() {
188
224
  let aborted = 0;
@@ -272,6 +308,10 @@ type RunResult = {
272
308
  browserTools?: string[];
273
309
  childRuntime?: "rpc" | "cli";
274
310
  workerReused?: boolean;
311
+ providerFailure?: string;
312
+ providerRecoveryAttempts?: number;
313
+ providerSessionResumeAttempts?: number;
314
+ subagentArtifact?: any;
275
315
  optimizations?: any;
276
316
  };
277
317
 
@@ -659,6 +699,7 @@ async function runAgentCli(
659
699
  idleTimeoutMs?: number;
660
700
  postToolErrorIdleTimeoutMs?: number;
661
701
  allowLocalEnvWrite?: boolean;
702
+ reuseRpcSession?: boolean;
662
703
  } = {},
663
704
  ): Promise<RunResult> {
664
705
  const config = AGENTS[agent];
@@ -719,6 +760,7 @@ async function runAgentCli(
719
760
  UES_CHILD_TOOL_OUTPUT_LIMIT: String(runtimeOptions.toolOutputLimit || 24 * 1024),
720
761
  UES_CHILD_VERIFICATION_TIMEOUT_SEC: String(runtimeOptions.verificationTimeoutSec || 300),
721
762
  UES_CHILD_ALLOW_LOCAL_ENV_WRITE: runtimeOptions.allowLocalEnvWrite ? "1" : "0",
763
+ UES_CHILD_EXTERNAL_TOOL_NAMES: extraTools.join(","),
722
764
  },
723
765
  shell: false,
724
766
  detached: process.platform !== "win32",
@@ -1007,11 +1049,17 @@ async function runAgentCli(
1007
1049
  }
1008
1050
 
1009
1051
 
1052
+ const RPC_PROMPT_PATH_CACHE = new Map<AgentName, string>();
1053
+
1010
1054
  function rpcPromptPath(agent: AgentName) {
1055
+ const cached = RPC_PROMPT_PATH_CACHE.get(agent);
1056
+ if (cached && fs.existsSync(cached)) return cached;
1057
+
1011
1058
  const dir = path.join(os.tmpdir(), "ues-pi-rpc-prompts");
1012
1059
  fs.mkdirSync(dir, { recursive: true });
1013
1060
  const file = path.join(dir, agent + ".md");
1014
1061
  fs.writeFileSync(file, getAgentPrompt(agent), { encoding: "utf8", mode: 0o600 });
1062
+ RPC_PROMPT_PATH_CACHE.set(agent, file);
1015
1063
  return file;
1016
1064
  }
1017
1065
 
@@ -1044,6 +1092,7 @@ async function runAgentRpc(
1044
1092
  idleTimeoutMs?: number;
1045
1093
  postToolErrorIdleTimeoutMs?: number;
1046
1094
  allowLocalEnvWrite?: boolean;
1095
+ reuseRpcSession?: boolean;
1047
1096
  } = {},
1048
1097
  ): Promise<RunResult> {
1049
1098
  const config = AGENTS[agent];
@@ -1124,6 +1173,7 @@ async function runAgentRpc(
1124
1173
  UES_CHILD_TOOL_OUTPUT_LIMIT: String(runtimeOptions.toolOutputLimit || 24 * 1024),
1125
1174
  UES_CHILD_VERIFICATION_TIMEOUT_SEC: String(runtimeOptions.verificationTimeoutSec || 300),
1126
1175
  UES_CHILD_ALLOW_LOCAL_ENV_WRITE: runtimeOptions.allowLocalEnvWrite ? "1" : "0",
1176
+ UES_CHILD_EXTERNAL_TOOL_NAMES: extraTools.join(","),
1127
1177
  },
1128
1178
  },
1129
1179
  taskInput,
@@ -1135,6 +1185,7 @@ async function runAgentRpc(
1135
1185
  activityWindowMs,
1136
1186
  idleTimeoutMs,
1137
1187
  postToolErrorIdleTimeoutMs,
1188
+ reuseSession: runtimeOptions.reuseRpcSession === true,
1138
1189
  onEvent: (event: any) => {
1139
1190
  lastActivityAt = Date.now();
1140
1191
  if (event.type === "tool_execution_start") {
@@ -1182,13 +1233,13 @@ async function runAgentRpc(
1182
1233
  );
1183
1234
 
1184
1235
  const message = rpc.message;
1185
- const output = extractAssistantText(message) || rpc.stderr || "(no assistant output)";
1186
- return {
1236
+ const assistantText = extractAssistantText(message);
1237
+ const baseResult: RunResult = {
1187
1238
  agent,
1188
1239
  task,
1189
1240
  cwd,
1190
- exitCode: 0,
1191
- output: cap(output, 100 * 1024),
1241
+ exitCode: message?.stopReason === "error" ? 1 : 0,
1242
+ output: cap(assistantText || rpc.stderr || "(no assistant output)", 100 * 1024),
1192
1243
  stderr: cap(String(rpc.stderr || ""), 64 * 1024),
1193
1244
  model: message?.model || model,
1194
1245
  stopReason: message?.stopReason,
@@ -1200,6 +1251,16 @@ async function runAgentRpc(
1200
1251
  childRuntime: "rpc",
1201
1252
  workerReused: rpc.workerReused === true,
1202
1253
  };
1254
+ const providerDecision = classifyProviderFailure(baseResult);
1255
+ if (providerDecision.transient) {
1256
+ return {
1257
+ ...baseResult,
1258
+ exitCode: 1,
1259
+ providerFailure: providerDecision.reason || "empty-provider-response",
1260
+ errorMessage: baseResult.errorMessage || providerDecision.message || "Provider returned no usable assistant content",
1261
+ };
1262
+ }
1263
+ return baseResult;
1203
1264
  } catch (error) {
1204
1265
  const message = error instanceof Error ? error.message : String(error);
1205
1266
  if (detectedHang) {
@@ -1284,54 +1345,137 @@ async function runAgent(
1284
1345
  idleTimeoutMs?: number;
1285
1346
  postToolErrorIdleTimeoutMs?: number;
1286
1347
  allowLocalEnvWrite?: boolean;
1348
+ reuseRpcSession?: boolean;
1287
1349
  } = {},
1288
1350
  ): Promise<RunResult> {
1289
- if (CHILD_RUNTIME !== "cli") {
1351
+ const runOnce = async (): Promise<RunResult> => {
1352
+ if (CHILD_RUNTIME !== "cli") {
1353
+ try {
1354
+ return await runAgentRpc(
1355
+ agent, task, cwd, model, thinkingLevel, signal, onProgress, extraTools, runtimeOptions,
1356
+ );
1357
+ } catch (error) {
1358
+ if (CHILD_RUNTIME === "rpc") throw error;
1359
+ // Auto mode may fall back only when RPC failed before delegated work started.
1360
+ if ((error as any)?.uesRpcPhase && (error as any).uesRpcPhase !== "startup") throw error;
1361
+ try {
1362
+ onProgress?.({
1363
+ agent, elapsedMs: 0, idleMs: 0, toolCalls: 0, model, phase: "running",
1364
+ note: "RPC startup unavailable; falling back to isolated CLI child",
1365
+ });
1366
+ } catch {}
1367
+ }
1368
+ }
1369
+ return runAgentCli(
1370
+ agent, task, cwd, model, thinkingLevel, signal, onProgress, extraTools, runtimeOptions,
1371
+ );
1372
+ };
1373
+
1374
+ let result = await runOnce();
1375
+ let recoveryAttempts = 0;
1376
+ let sessionResumeAttempts = 0;
1377
+ let providerDecision = classifyProviderFailure(result);
1378
+
1379
+ while (
1380
+ providerDecision.transient && providerDecision.safeSessionResume &&
1381
+ result.childRuntime === "rpc" &&
1382
+ sessionResumeAttempts < PROVIDER_SESSION_RESUME_RETRIES && !signal?.aborted
1383
+ ) {
1384
+ sessionResumeAttempts += 1;
1290
1385
  try {
1291
- return await runAgentRpc(
1386
+ onProgress?.({
1387
+ agent, elapsedMs: 0, idleMs: 0, toolCalls: Number(result.toolCalls || 0),
1388
+ model: result.model || model, phase: "running",
1389
+ note: "provider returned no usable content after tool execution; resuming the same RPC session " +
1390
+ sessionResumeAttempts + "/" + PROVIDER_SESSION_RESUME_RETRIES,
1391
+ });
1392
+ } catch {}
1393
+ const delayMs = providerRecoveryBackoffMs(sessionResumeAttempts, {
1394
+ baseMs: PROVIDER_RECOVERY_BASE_DELAY_MS, maxMs: 2_000,
1395
+ });
1396
+ if (delayMs > 0) await new Promise((resolve) => setTimeout(resolve, delayMs));
1397
+
1398
+ const priorToolCalls = Number(result.toolCalls || 0);
1399
+ const priorToolNames = Array.isArray(result.toolNames) ? result.toolNames : [];
1400
+ try {
1401
+ const resumed = await runAgentRpc(
1292
1402
  agent,
1293
- task,
1403
+ [
1404
+ "Continue the current delegated task from this existing RPC session after a transient provider failure.",
1405
+ "Do not restart the task and do not repeat tool calls that already completed.",
1406
+ "Use the current conversation, workspace state, and tool evidence as authoritative.",
1407
+ "Continue from the next unfinished step, then return the normal role report/verdict.",
1408
+ ].join(" "),
1294
1409
  cwd,
1295
- model,
1410
+ result.model || model,
1296
1411
  thinkingLevel,
1297
1412
  signal,
1298
1413
  onProgress,
1299
1414
  extraTools,
1300
- runtimeOptions,
1415
+ { ...runtimeOptions, reuseRpcSession: true },
1301
1416
  );
1417
+ result = {
1418
+ ...resumed,
1419
+ task,
1420
+ toolCalls: priorToolCalls + Number(resumed.toolCalls || 0),
1421
+ toolNames: [...new Set([...priorToolNames, ...(resumed.toolNames || [])])],
1422
+ };
1423
+ providerDecision = classifyProviderFailure(result);
1302
1424
  } catch (error) {
1303
- if (CHILD_RUNTIME === "rpc") throw error;
1304
- // Auto mode may fall back only when RPC failed before the delegated task
1305
- // started. In-task failures must not cause a blind second execution.
1306
- if ((error as any)?.uesRpcPhase && (error as any).uesRpcPhase !== "startup") {
1307
- throw error;
1308
- }
1309
1425
  try {
1310
1426
  onProgress?.({
1311
- agent,
1312
- elapsedMs: 0,
1313
- idleMs: 0,
1314
- toolCalls: 0,
1315
- model,
1316
- phase: "running",
1317
- note: "RPC startup unavailable; falling back to isolated CLI child",
1427
+ agent, elapsedMs: 0, idleMs: 0, toolCalls: priorToolCalls,
1428
+ model: result.model || model, phase: "running",
1429
+ note: "same-session provider recovery unavailable; preserving prior evidence without replay",
1318
1430
  });
1319
1431
  } catch {}
1432
+ break;
1320
1433
  }
1321
1434
  }
1322
- return runAgentCli(
1323
- agent,
1324
- task,
1325
- cwd,
1326
- model,
1327
- thinkingLevel,
1328
- signal,
1329
- onProgress,
1330
- extraTools,
1331
- runtimeOptions,
1332
- );
1333
- }
1334
1435
 
1436
+ while (
1437
+ providerDecision.transient && providerDecision.safeReplay &&
1438
+ recoveryAttempts < PROVIDER_RECOVERY_RETRIES && !signal?.aborted
1439
+ ) {
1440
+ recoveryAttempts += 1;
1441
+ try {
1442
+ onProgress?.({
1443
+ agent, elapsedMs: 0, idleMs: 0, toolCalls: Number(result.toolCalls || 0),
1444
+ model: result.model || model, phase: "running",
1445
+ note: "provider returned no usable content; safe fresh-session retry " +
1446
+ recoveryAttempts + "/" + PROVIDER_RECOVERY_RETRIES,
1447
+ });
1448
+ } catch {}
1449
+ const delayMs = providerRecoveryBackoffMs(recoveryAttempts, {
1450
+ baseMs: PROVIDER_RECOVERY_BASE_DELAY_MS, maxMs: 2_000,
1451
+ });
1452
+ if (delayMs > 0) await new Promise((resolve) => setTimeout(resolve, delayMs));
1453
+ result = await runOnce();
1454
+ providerDecision = classifyProviderFailure(result);
1455
+ }
1456
+
1457
+ if (providerDecision.transient) {
1458
+ const recoveryNote = providerDecision.safeReplay
1459
+ ? "UES provider recovery exhausted after " + recoveryAttempts +
1460
+ " bounded fresh-session retry attempt(s); task remains failed instead of being reported as success."
1461
+ : providerDecision.safeSessionResume
1462
+ ? "UES same-session provider recovery exhausted or was unavailable after " + sessionResumeAttempts +
1463
+ " attempt(s). Completed tool side effects were preserved and were not blindly replayed."
1464
+ : "UES provider recovery stopped safely without replaying completed side effects.";
1465
+ result = {
1466
+ ...result,
1467
+ exitCode: result.exitCode === 0 ? 1 : result.exitCode,
1468
+ output: [result.output, "", "[UES provider recovery] " + recoveryNote].filter(Boolean).join("\n"),
1469
+ providerFailure: providerDecision.reason || result.providerFailure || "empty-provider-response",
1470
+ };
1471
+ }
1472
+
1473
+ return {
1474
+ ...result,
1475
+ providerRecoveryAttempts: recoveryAttempts,
1476
+ providerSessionResumeAttempts: sessionResumeAttempts,
1477
+ };
1478
+ }
1335
1479
 
1336
1480
  function roleForAgent(agent: AgentName) {
1337
1481
  return agent.replace(/^ues-/, "");
@@ -1382,6 +1526,11 @@ function parseStructuredReport(output: string) {
1382
1526
  };
1383
1527
  }
1384
1528
 
1529
+ function acceptanceEvidenceStatusPresent(run: any) {
1530
+ const value = String(run?.report?.sections?.["acceptance-criteria-proven"] || "");
1531
+ return /(?:^|\n)\s*(?:[-*]\s*)?(?:VERIFIED|INFERRED|UNKNOWN)\s*:/im.test(value);
1532
+ }
1533
+
1385
1534
  function taskRecord(task: string) {
1386
1535
  return {
1387
1536
  id: "pi-dispatch",
@@ -1510,8 +1659,24 @@ async function runRoutedAgent(
1510
1659
  taskPolicyOverride?: any,
1511
1660
  contextCacheNamespace?: string,
1512
1661
  ): Promise<RunResult> {
1662
+ const routedStartedAt = Date.now();
1513
1663
  const role = roleForAgent(agent);
1514
1664
  const traceRoot = requireGitWorkspaceRoot(cwd, "UES specialist");
1665
+ const workspaceSnapshotStartedAt = Date.now();
1666
+ let agentWorkspaceState: any = null;
1667
+ let workspaceState: any = {
1668
+ cacheable: false,
1669
+ fingerprint: "unknown",
1670
+ changedFiles: [],
1671
+ };
1672
+ try {
1673
+ agentWorkspaceState = captureWorkspaceStateV2(cwd);
1674
+ workspaceState = runtimeWorkspaceSnapshot(cwd, { workspaceState: agentWorkspaceState });
1675
+ } catch {}
1676
+ const agentHygieneBaseline = captureWorkspaceHygieneBaseline(cwd, {
1677
+ workspaceState: agentWorkspaceState,
1678
+ });
1679
+ const workspaceSnapshotMs = Date.now() - workspaceSnapshotStartedAt;
1515
1680
  const browserRequested = browserEvidenceNeeded(task, role);
1516
1681
  const browserTools = browserRequested
1517
1682
  ? selectBrowserToolsForTask(HOST_BROWSER_TOOL_NAMES, task, role)
@@ -1545,6 +1710,8 @@ async function runRoutedAgent(
1545
1710
  modelTier: selection.tier,
1546
1711
  profile: taskPolicy.executionProfile,
1547
1712
  risk: taskPolicy.risk,
1713
+ decisionConfidence: taskPolicy.decision?.confidence ?? null,
1714
+ decisionReason: taskPolicy.decision?.reason ?? null,
1548
1715
  browserRequested,
1549
1716
  }).catch(() => {});
1550
1717
  }
@@ -1573,14 +1740,6 @@ async function runRoutedAgent(
1573
1740
  ? undefined
1574
1741
  : inheritedThinking;
1575
1742
 
1576
- let workspaceState: any = {
1577
- cacheable: false,
1578
- fingerprint: "unknown",
1579
- changedFiles: [],
1580
- };
1581
- try {
1582
- workspaceState = runtimeWorkspaceSnapshot(cwd);
1583
- } catch {}
1584
1743
  const workspaceFingerprint = String(workspaceState.fingerprint || "unknown");
1585
1744
 
1586
1745
  let enrichedTask = task;
@@ -1590,6 +1749,8 @@ async function runRoutedAgent(
1590
1749
  let affectedTests: any = null;
1591
1750
  let reusableVerification: any = null;
1592
1751
  let contextCacheHit = false;
1752
+ let contextPerformance: any = null;
1753
+ const contextBuildStartedAt = Date.now();
1593
1754
  try {
1594
1755
  if (fastBoundedContext) {
1595
1756
  contextQuality = { schemaVersion: 1, profile: "fast-bounded", bounded: true };
@@ -1650,41 +1811,42 @@ async function runRoutedAgent(
1650
1811
  }
1651
1812
  }
1652
1813
 
1653
- if (MICRO_SKILLS_ENABLED) {
1654
- microSkills = await compileSkillContext(taskPolicy, role, {
1655
- maxSkills: taskPolicy.maxSkills,
1656
- totalChars: taskPolicy.executionProfile === "fast" ? 1800 : 3200,
1657
- }).catch(() => null);
1658
- }
1659
-
1660
- if (
1814
+ const [microSkillResult, affectedTestResult, reusableVerificationResult] = await Promise.all([
1815
+ MICRO_SKILLS_ENABLED
1816
+ ? compileSkillContext(taskPolicy, role, {
1817
+ maxSkills: taskPolicy.maxSkills,
1818
+ totalChars: taskPolicy.executionProfile === "fast" ? 1800 : 3200,
1819
+ taskText: task,
1820
+ }).catch(() => null)
1821
+ : Promise.resolve(null),
1661
1822
  AFFECTED_TEST_HINTS_ENABLED &&
1662
1823
  ["executor", "debugger", "verifier", "integration-verifier"].includes(role)
1663
- ) {
1664
- affectedTests = await resolveAffectedTests(cwd, {
1665
- limit: 10,
1666
- changedFiles: workspaceState.changedFiles || [],
1667
- ...(workspaceState.cacheable === true && workspaceFingerprint !== "unknown"
1668
- ? { workspaceFingerprint }
1669
- : {}),
1670
- }).catch(() => null);
1671
- }
1672
-
1673
- if (
1824
+ ? resolveAffectedTests(cwd, {
1825
+ limit: 10,
1826
+ changedFiles: workspaceState.changedFiles || [],
1827
+ ...(workspaceState.cacheable === true && workspaceFingerprint !== "unknown"
1828
+ ? { workspaceFingerprint }
1829
+ : {}),
1830
+ }).catch(() => null)
1831
+ : Promise.resolve(null),
1674
1832
  ["verifier", "integration-verifier"].includes(role) &&
1675
1833
  !["high", "critical"].includes(String(taskPolicy.risk || "").toLowerCase())
1676
- ) {
1677
- reusableVerification = await listReusableVerification(cwd, {
1678
- limit: 8,
1679
- maxAgeMs: 30 * 60_000,
1680
- previewBytes: 2200,
1681
- ...(workspaceState.cacheable === true && workspaceFingerprint !== "unknown"
1682
- ? { workspaceFingerprint }
1683
- : {}),
1684
- }).catch(() => null);
1685
- }
1834
+ ? listReusableVerification(cwd, {
1835
+ limit: 8,
1836
+ maxAgeMs: 30 * 60_000,
1837
+ previewBytes: 2200,
1838
+ ...(workspaceState.cacheable === true && workspaceFingerprint !== "unknown"
1839
+ ? { workspaceFingerprint }
1840
+ : {}),
1841
+ }).catch(() => null)
1842
+ : Promise.resolve(null),
1843
+ ]);
1844
+ microSkills = microSkillResult;
1845
+ affectedTests = affectedTestResult;
1846
+ reusableVerification = reusableVerificationResult;
1686
1847
 
1687
1848
  contextQuality = pack.contextQuality;
1849
+ contextPerformance = pack.performance || null;
1688
1850
  enrichedTask = [
1689
1851
  task,
1690
1852
  "",
@@ -1723,6 +1885,7 @@ async function runRoutedAgent(
1723
1885
  enrichedTask += "\n\n## Previous failed verification\n" + cap(recentFailure, 5000);
1724
1886
  }
1725
1887
  }
1888
+ const contextBuildMs = Date.now() - contextBuildStartedAt;
1726
1889
 
1727
1890
  if (browserRequested) {
1728
1891
  enrichedTask += browserTools.length
@@ -1747,7 +1910,34 @@ async function runRoutedAgent(
1747
1910
  taskChars: task.length,
1748
1911
  });
1749
1912
  const startedAt = Date.now();
1750
- const result = await runAgent(
1913
+ const artifactRoot = await taskSandboxOwnerRoot(cwd).catch(() => null) || traceRoot;
1914
+ const childArtifact = await createSubagentArtifact(artifactRoot, {
1915
+ agent,
1916
+ role,
1917
+ attempt,
1918
+ task,
1919
+ traceID,
1920
+ model: selectedModel,
1921
+ modelTier: selection.tier,
1922
+ workspaceFingerprint,
1923
+ }).catch(() => null);
1924
+ if (childArtifact?.handle) {
1925
+ try {
1926
+ onProgress?.({
1927
+ agent,
1928
+ elapsedMs: 0,
1929
+ idleMs: 0,
1930
+ toolCalls: 0,
1931
+ model: selectedModel,
1932
+ phase: "running",
1933
+ note: `subagent handle ${childArtifact.handle}; durable status ${childArtifact.file}`,
1934
+ });
1935
+ } catch {}
1936
+ }
1937
+ let result: RunResult;
1938
+ const modelRunStartedAt = Date.now();
1939
+ try {
1940
+ result = await runAgent(
1751
1941
  agent,
1752
1942
  enrichedTask,
1753
1943
  cwd,
@@ -1801,8 +1991,56 @@ async function runRoutedAgent(
1801
1991
  allowLocalEnvWrite:
1802
1992
  taskPolicy.localEnvWriteExplicitlyAllowed === true ||
1803
1993
  taskExplicitlyAllowsLocalEnvWrite(task),
1804
- },
1805
- );
1994
+ },
1995
+ );
1996
+ } catch (error) {
1997
+ if (childArtifact?.handle) {
1998
+ await failSubagentArtifact(artifactRoot, childArtifact.handle, error).catch(() => null);
1999
+ }
2000
+ throw error;
2001
+ }
2002
+ const modelRunMs = Date.now() - modelRunStartedAt;
2003
+ const hygieneStartedAt = Date.now();
2004
+ const postRunHygiene = await postRunFileHygiene(cwd, {
2005
+ baseline: agentHygieneBaseline,
2006
+ taskText: task,
2007
+ allowSourceMutations: WRITE_AGENTS.has(agent),
2008
+ autoClean: true,
2009
+ }).catch((error) => ({
2010
+ schemaVersion: 1,
2011
+ safe: false,
2012
+ changed: [],
2013
+ created: [],
2014
+ removed: [],
2015
+ findings: [{
2016
+ kind: "hygiene-audit-error",
2017
+ file: ".",
2018
+ message: error instanceof Error ? error.message : String(error),
2019
+ }],
2020
+ summary: "workspace hygiene audit failed: " + (error instanceof Error ? error.message : String(error)),
2021
+ }));
2022
+ if (!postRunHygiene.safe) {
2023
+ const hygieneText = [
2024
+ "UES post-run workspace hygiene guard rejected this child run.",
2025
+ postRunHygiene.summary || "workspace hygiene failed",
2026
+ ].join("\n");
2027
+ result = {
2028
+ ...result,
2029
+ exitCode: result.exitCode === 0 ? 2 : result.exitCode,
2030
+ stopReason: "error",
2031
+ errorMessage: hygieneText,
2032
+ output: [result.output, "", hygieneText].filter(Boolean).join("\n"),
2033
+ };
2034
+ }
2035
+
2036
+ const hygieneMs = Date.now() - hygieneStartedAt;
2037
+ const finalizedChildArtifact = childArtifact?.handle
2038
+ ? await finalizeSubagentArtifact(artifactRoot, childArtifact.handle, {
2039
+ ...result,
2040
+ durationMs: Date.now() - startedAt,
2041
+ verdict: verdictFromOutput(result.output),
2042
+ }).catch(() => null)
2043
+ : null;
1806
2044
  const enrichedResult: RunResult = {
1807
2045
  ...result,
1808
2046
  task,
@@ -1833,10 +2071,32 @@ async function runRoutedAgent(
1833
2071
  turboFastStrategy: turboFast.strategy,
1834
2072
  turboFastTimeouts: turboFast.eligible ? TURBO_FAST_TIMEOUTS : null,
1835
2073
  planningRuntimeBudget: planningBudget,
2074
+ affectedTestInventorySource: affectedTests?.inventorySource || null,
2075
+ contextPerformance,
2076
+ latencyMs: {
2077
+ workspaceSnapshot: workspaceSnapshotMs,
2078
+ contextBuild: contextBuildMs,
2079
+ modelRun: modelRunMs,
2080
+ hygiene: hygieneMs,
2081
+ total: Date.now() - routedStartedAt,
2082
+ },
1836
2083
  },
1837
2084
  verdict: verdictFromOutput(result.output),
1838
2085
  report: parseStructuredReport(result.output),
1839
2086
  durationMs: Date.now() - startedAt,
2087
+ subagentArtifact: finalizedChildArtifact ? {
2088
+ handle: finalizedChildArtifact.handle,
2089
+ status: finalizedChildArtifact.status,
2090
+ file: finalizedChildArtifact.file,
2091
+ taskRef: finalizedChildArtifact.taskRef,
2092
+ outputRef: finalizedChildArtifact.result?.outputRef || null,
2093
+ resume: finalizedChildArtifact.resume || null,
2094
+ } : childArtifact ? {
2095
+ handle: childArtifact.handle,
2096
+ status: childArtifact.status,
2097
+ file: childArtifact.file,
2098
+ taskRef: childArtifact.taskRef,
2099
+ } : null,
1840
2100
  };
1841
2101
  if (traceID) {
1842
2102
  await appendTrajectoryEvent(traceRoot, traceID, "agent.completed", {
@@ -2813,8 +3073,16 @@ export default function (pi: ExtensionAPI) {
2813
3073
  const AUTO_ADMISSION_ENABLED = !["0", "false", "off"].includes(
2814
3074
  String(process.env.UES_AUTO_ADMIT || "1").trim().toLowerCase(),
2815
3075
  );
2816
- const UES_PARENT_TOOL_NAMES = new Set(["ues_cli", "ues_execute", "ues_service", "ues_dispatch"]);
3076
+ const UES_PARENT_TOOL_NAMES = new Set(["ues_cli", "ues_execute", "ues_service", "ues_session", "ues_dispatch"]);
3077
+ const ALWAYS_ON_PARENT_TOOLS = new Set(["ues_code"]);
2817
3078
  let normalActiveTools: string[] | null = null;
3079
+ let parentRunToolCalls = 0;
3080
+ let parentRunLastAssistant: any = null;
3081
+ let parentProviderRecoveryConsecutive = 0;
3082
+ let parentProviderRecoveryTotal = 0;
3083
+ let parentProviderRecoveryPending = false;
3084
+ const PARENT_PROVIDER_RECOVERY_MAX_CONSECUTIVE = 1;
3085
+ const PARENT_PROVIDER_RECOVERY_MAX_TOTAL = 3;
2818
3086
 
2819
3087
  const currentNonUesTools = () =>
2820
3088
  pi.getActiveTools().filter((name) => !UES_PARENT_TOOL_NAMES.has(String(name)));
@@ -2848,6 +3116,40 @@ export default function (pi: ExtensionAPI) {
2848
3116
  deactivateParentUesTools();
2849
3117
  });
2850
3118
 
3119
+ pi.on("session_before_compact", async (event, ctx) => {
3120
+ const root = resolveGitWorkspaceRoot(ctx.cwd || "");
3121
+ if (!root) return undefined;
3122
+ await checkpointDurableWorkBeforeCompaction(root, {
3123
+ reason: event.reason,
3124
+ maxWorkspaces: 3,
3125
+ }).catch(() => []);
3126
+ return undefined;
3127
+ });
3128
+
3129
+ pi.on("session_compact", async (event, ctx) => {
3130
+ const root = resolveGitWorkspaceRoot(ctx.cwd || "");
3131
+ if (!root) return;
3132
+ const packet = await buildCompactionResumeGuard(root, {
3133
+ reason: event.reason,
3134
+ maxWorkspaces: 3,
3135
+ }).catch(() => null);
3136
+ if (!packet?.workspaces?.length) return;
3137
+ const content = renderCompactionResumeGuard(packet);
3138
+ if (!content) return;
3139
+ pi.sendMessage({
3140
+ customType: "ues-durable-resume-guard",
3141
+ content,
3142
+ display: false,
3143
+ details: {
3144
+ schemaVersion: packet.schemaVersion || 1,
3145
+ reason: event.reason,
3146
+ willRetry: event.willRetry,
3147
+ workspaceCount: packet.workspaceCount,
3148
+ source: packet.source,
3149
+ },
3150
+ }, { triggerTurn: false });
3151
+ });
3152
+
2851
3153
  pi.on("session_shutdown", async () => {
2852
3154
  directControllerAbort?.abort();
2853
3155
  directControllerAbort = null;
@@ -2861,6 +3163,7 @@ export default function (pi: ExtensionAPI) {
2861
3163
  MCP_HEALTH.clear();
2862
3164
  abortActiveCliChildren();
2863
3165
  await stopAllServices().catch(() => []);
3166
+ await shutdownLspPool().catch(() => ({ stopped: 0, remaining: 0 }));
2864
3167
  await RPC_POOL.stopAll().catch(() => {});
2865
3168
  for (const dir of [...ACTIVE_TASK_SANDBOXES.keys()]) {
2866
3169
  const ownerRoot = await taskSandboxOwnerRoot(dir).catch(() => null);
@@ -2966,13 +3269,27 @@ export default function (pi: ExtensionAPI) {
2966
3269
  return { action: "continue" };
2967
3270
  }
2968
3271
 
2969
- const steered = await RPC_POOL.steerActive(text).catch(() => ({
2970
- accepted: false,
2971
- reason: "steer-failed",
2972
- active: 0,
2973
- }));
2974
- if (steered.accepted) {
2975
- try { ctx.ui.notify("UES: steering message forwarded to the active child", "info"); } catch {}
3272
+ const streamingBehavior = String(event.streamingBehavior || "");
3273
+ const forwarded = streamingBehavior === "followUp"
3274
+ ? await RPC_POOL.followUpActive(text).catch(() => ({
3275
+ accepted: false,
3276
+ reason: "follow-up-failed",
3277
+ active: 0,
3278
+ }))
3279
+ : await RPC_POOL.steerActive(text).catch(() => ({
3280
+ accepted: false,
3281
+ reason: "steer-failed",
3282
+ active: 0,
3283
+ }));
3284
+ if (forwarded.accepted) {
3285
+ try {
3286
+ ctx.ui.notify(
3287
+ streamingBehavior === "followUp"
3288
+ ? "UES: follow-up queued for the active child"
3289
+ : "UES: steering message forwarded to the active child",
3290
+ "info",
3291
+ );
3292
+ } catch {}
2976
3293
  return { action: "handled" };
2977
3294
  }
2978
3295
 
@@ -2982,19 +3299,109 @@ export default function (pi: ExtensionAPI) {
2982
3299
  });
2983
3300
 
2984
3301
  pi.on("before_agent_start", async () => {
3302
+ // Pi may start another provider request inside the same parent run when
3303
+ // agent_before_settle asks to continue. Preserve recovery accounting for
3304
+ // that continuation, but reset it for a genuinely new parent run.
3305
+ if (parentProviderRecoveryPending) {
3306
+ parentProviderRecoveryPending = false;
3307
+ parentRunLastAssistant = null;
3308
+ } else {
3309
+ parentRunToolCalls = 0;
3310
+ parentRunLastAssistant = null;
3311
+ parentProviderRecoveryConsecutive = 0;
3312
+ parentProviderRecoveryTotal = 0;
3313
+ }
2985
3314
  if (uesModeActive()) activateParentUesTools();
2986
3315
  else deactivateParentUesTools();
2987
3316
  });
2988
3317
 
3318
+ pi.on("message_end", async (event) => {
3319
+ if ((event as any)?.message?.role !== "assistant") return;
3320
+ parentRunLastAssistant = (event as any).message;
3321
+
3322
+ // A substantive assistant response proves the previous empty-response
3323
+ // incident recovered. Reset only the consecutive incident budget; keep the
3324
+ // total run budget bounded so a flaky provider cannot loop forever.
3325
+ const text = extractAssistantText(parentRunLastAssistant).trim();
3326
+ if (text && parentRunLastAssistant?.stopReason !== "error") {
3327
+ parentProviderRecoveryConsecutive = 0;
3328
+ parentProviderRecoveryPending = false;
3329
+ }
3330
+ });
3331
+
3332
+ pi.on("agent_before_settle", async (event) => {
3333
+ if (
3334
+ uesModeActive() ||
3335
+ parentProviderRecoveryConsecutive >= PARENT_PROVIDER_RECOVERY_MAX_CONSECUTIVE ||
3336
+ parentProviderRecoveryTotal >= PARENT_PROVIDER_RECOVERY_MAX_TOTAL
3337
+ ) {
3338
+ return undefined;
3339
+ }
3340
+
3341
+ const assistantText = extractAssistantText(parentRunLastAssistant);
3342
+ const decision = classifyProviderFailure({
3343
+ output: assistantText || "(no assistant output)",
3344
+ errorMessage: parentRunLastAssistant?.errorMessage,
3345
+ stopReason: parentRunLastAssistant?.stopReason,
3346
+ toolCalls: parentRunToolCalls,
3347
+ noAssistantMessage: !parentRunLastAssistant,
3348
+ });
3349
+ if (!decision.transient) return undefined;
3350
+
3351
+ parentProviderRecoveryConsecutive += 1;
3352
+ parentProviderRecoveryTotal += 1;
3353
+ parentProviderRecoveryPending = true;
3354
+ const afterTools = parentRunToolCalls > 0;
3355
+ const recoveryMessage = afterTools
3356
+ ? [
3357
+ "UES parent provider recovery: the previous provider response was empty after completed tool calls.",
3358
+ "Continue from the current conversation and existing tool results.",
3359
+ "Do not restart the task and do not repeat tool calls that already completed unless fresh verification is strictly required.",
3360
+ "Resume from the next unfinished step and finish the requested work/report.",
3361
+ ].join(" ")
3362
+ : [
3363
+ "UES parent provider recovery: the previous provider response was empty before any tool side effect.",
3364
+ "Retry the current request once using the existing conversation context and return a complete response.",
3365
+ ].join(" ");
3366
+
3367
+ return {
3368
+ entries: [
3369
+ ...(event.entries || []),
3370
+ {
3371
+ type: "custom_message",
3372
+ customType: "ues-parent-provider-recovery",
3373
+ content: recoveryMessage,
3374
+ display: false,
3375
+ details: {
3376
+ schemaVersion: 2,
3377
+ incidentAttempt: parentProviderRecoveryConsecutive,
3378
+ maxIncidentAttempts: PARENT_PROVIDER_RECOVERY_MAX_CONSECUTIVE,
3379
+ totalAttempts: parentProviderRecoveryTotal,
3380
+ maxTotalAttempts: PARENT_PROVIDER_RECOVERY_MAX_TOTAL,
3381
+ reason: decision.reason,
3382
+ toolCalls: parentRunToolCalls,
3383
+ safeReplay: decision.safeReplay,
3384
+ safeSessionResume: decision.safeSessionResume,
3385
+ },
3386
+ },
3387
+ ],
3388
+ continue: true,
3389
+ };
3390
+ });
3391
+
2989
3392
  pi.on("agent_end", async () => {
2990
3393
  promptUesActive = false;
3394
+ parentProviderRecoveryPending = false;
3395
+ parentProviderRecoveryConsecutive = 0;
3396
+ parentProviderRecoveryTotal = 0;
2991
3397
  deactivateParentUesTools();
2992
3398
  });
2993
3399
 
2994
3400
  pi.on("tool_call", async (event, ctx) => {
2995
3401
  const toolName = String(event.toolName || "");
3402
+ if (!uesModeActive()) parentRunToolCalls += 1;
2996
3403
  if (!uesModeActive()) {
2997
- if (toolName.startsWith("ues_")) {
3404
+ if (toolName.startsWith("ues_") && !ALWAYS_ON_PARENT_TOOLS.has(toolName)) {
2998
3405
  return {
2999
3406
  block: true,
3000
3407
  reason: "UES parent tools are hidden outside admitted UES runs. Submit a normal engineering task or start an explicit /ues-* command.",
@@ -3002,11 +3409,48 @@ export default function (pi: ExtensionAPI) {
3002
3409
  }
3003
3410
  return undefined;
3004
3411
  }
3412
+ const permissionRequest = toolPermissionRequest(toolName, (event as any).input || {});
3413
+ const configuredPermission: any = await PERMISSION_POLICY.evaluate(permissionRequest, {
3414
+ agent: "ues-parent",
3415
+ }).catch((error) => ({
3416
+ configured: true,
3417
+ decision: null,
3418
+ error: error instanceof Error ? error.message : String(error),
3419
+ }));
3420
+ if (configuredPermission.error) {
3421
+ return {
3422
+ block: true,
3423
+ reason: "UES permission policy is invalid: " + configuredPermission.error,
3424
+ };
3425
+ }
3426
+ const permissionEffect = configuredPermission?.decision?.effect;
3427
+ let permissionApproved = false;
3428
+ if (permissionEffect === "deny") {
3429
+ return {
3430
+ block: true,
3431
+ reason: permissionRecoveryHint(permissionRequest, configuredPermission.decision, { effect: "deny" }),
3432
+ };
3433
+ }
3434
+ if (permissionEffect === "ask") {
3435
+ const allowed = await approveRisk(
3436
+ ctx,
3437
+ permissionRequest.resources.join("\n"),
3438
+ "permission:" + permissionRequest.action,
3439
+ );
3440
+ if (!allowed) {
3441
+ return {
3442
+ block: true,
3443
+ reason: permissionRecoveryHint(permissionRequest, configuredPermission.decision, { effect: "ask" }),
3444
+ };
3445
+ }
3446
+ permissionApproved = true;
3447
+ }
3448
+
3005
3449
  if (toolName !== "bash" && toolName !== "powershell") {
3006
3450
  const allTools = typeof (pi as any).getAllTools === "function" ? (pi as any).getAllTools() : [];
3007
3451
  const descriptor = allTools.find((tool: any) => String(tool?.name || "") === toolName);
3008
3452
  const policy = mcpExecutionPolicy(descriptor || { name: toolName });
3009
- if (policy.confirmationRequired) {
3453
+ if (policy.confirmationRequired && !permissionApproved) {
3010
3454
  const allowed = await approveRisk(ctx, `MCP/tool call: ${toolName}`, `mcp-destructive:${toolName}`);
3011
3455
  if (!allowed) return { block: true, reason: `Blocked by UES MCP destructive-hint gate: ${toolName}` };
3012
3456
  }
@@ -3025,8 +3469,10 @@ export default function (pi: ExtensionAPI) {
3025
3469
  }
3026
3470
  const risk = destructiveShellRisk(command);
3027
3471
  if (!risk.risky) return undefined;
3028
- const allowed = await approveRisk(ctx, command, risk.id || "destructive");
3029
- if (!allowed) return { block: true, reason: `Blocked by UES safety gate: ${risk.id}` };
3472
+ if (!permissionApproved) {
3473
+ const allowed = await approveRisk(ctx, command, risk.id || "destructive");
3474
+ if (!allowed) return { block: true, reason: `Blocked by UES safety gate: ${risk.id}` };
3475
+ }
3030
3476
  return undefined;
3031
3477
  });
3032
3478
 
@@ -3034,14 +3480,222 @@ export default function (pi: ExtensionAPI) {
3034
3480
  if (!uesModeActive()) return undefined;
3035
3481
  const toolName = String((event as any).toolName || "");
3036
3482
  if (!toolName || toolName === "bash" || toolName === "powershell") return undefined;
3483
+ const resultText = toolResultText(event);
3484
+ const allTools = typeof (pi as any).getAllTools === "function" ? (pi as any).getAllTools() : [];
3485
+ const descriptor = allTools.find((tool: any) => String(tool?.name || "") === toolName);
3486
+ const policy = mcpExecutionPolicy(descriptor || { name: toolName });
3037
3487
  MCP_HEALTH.finish(
3038
3488
  String((event as any).toolCallId || ""),
3039
3489
  {
3040
3490
  isError: (event as any).isError === true,
3041
- text: toolResultText(event),
3491
+ text: resultText,
3042
3492
  },
3043
3493
  );
3044
- return undefined;
3494
+
3495
+ const externalBoundary =
3496
+ policy.externalEvidenceBoundary === true ||
3497
+ HOST_BROWSER_TOOL_NAMES.includes(toolName);
3498
+ if (!externalBoundary || !resultText) return undefined;
3499
+
3500
+ const analysis = analyzeUntrustedOutput(resultText, { source: toolName });
3501
+ if (!analysis.flagged) return undefined;
3502
+ const originalContent = Array.isArray((event as any).content)
3503
+ ? (event as any).content
3504
+ : [{ type: "text", text: resultText }];
3505
+ return {
3506
+ content: [
3507
+ { type: "text", text: renderUntrustedOutputWarning(analysis, { source: toolName }) },
3508
+ ...originalContent,
3509
+ ],
3510
+ details: {
3511
+ ...((event as any).details && typeof (event as any).details === "object" ? (event as any).details : {}),
3512
+ uesUntrustedOutputBoundary: analysis,
3513
+ },
3514
+ isError: (event as any).isError === true,
3515
+ usage: (event as any).usage,
3516
+ };
3517
+ });
3518
+
3519
+ // Always-on, read-only intelligence for normal Pi conversations.
3520
+ // Keep this outside UES_PARENT_TOOL_NAMES so session_start does not hide it.
3521
+ pi.registerTool({
3522
+ name: "ues_code",
3523
+ label: "UES Code Intelligence Lite",
3524
+ description:
3525
+ "Always-on read-only UES code intelligence for normal Pi chats. Provides bounded semantic/AST search, anchored reads, persistent LSP navigation/diagnostics, document ingestion, and reversible context access without starting the UES controller or a specialist child.",
3526
+ parameters: Type.Object({
3527
+ action: Type.Union([
3528
+ Type.Literal("status"),
3529
+ Type.Literal("search"),
3530
+ Type.Literal("read"),
3531
+ Type.Literal("diagnostics"),
3532
+ Type.Literal("definition"),
3533
+ Type.Literal("references"),
3534
+ Type.Literal("symbols"),
3535
+ Type.Literal("hover"),
3536
+ Type.Literal("rename-preview"),
3537
+ Type.Literal("incoming-calls"),
3538
+ Type.Literal("outgoing-calls"),
3539
+ Type.Literal("document"),
3540
+ Type.Literal("context-expand"),
3541
+ Type.Literal("context-search"),
3542
+ ]),
3543
+ file: Type.Optional(Type.String()),
3544
+ query: Type.Optional(Type.String()),
3545
+ structuralPattern: Type.Optional(Type.String()),
3546
+ language: Type.Optional(Type.String()),
3547
+ startLine: Type.Optional(Type.Number({ minimum: 1 })),
3548
+ endLine: Type.Optional(Type.Number({ minimum: 1 })),
3549
+ line: Type.Optional(Type.Number({ minimum: 1 })),
3550
+ character: Type.Optional(Type.Number({ minimum: 1 })),
3551
+ newName: Type.Optional(Type.String({ minLength: 1, maxLength: 512 })),
3552
+ includeDeclaration: Type.Optional(Type.Boolean()),
3553
+ ref: Type.Optional(Type.String()),
3554
+ maxBytes: Type.Optional(Type.Number({ minimum: 1, maximum: 128000 })),
3555
+ }),
3556
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
3557
+ try {
3558
+ let result: any;
3559
+ if (params.action === "status") {
3560
+ result = probeCodeIntelligence(params.file || "");
3561
+ result = {
3562
+ ...result,
3563
+ mode: "parent-lite",
3564
+ controllerStarted: false,
3565
+ childSpawned: false,
3566
+ lsp: {
3567
+ ...result.lsp,
3568
+ persistentPool: {
3569
+ ...lspPoolStatus({ includeSessions: false, persistent: true }),
3570
+ policy: { enabled: true, source: "parent-lite" },
3571
+ },
3572
+ },
3573
+ };
3574
+ } else if (params.action === "search") {
3575
+ if (!params.query) throw new Error("ues_code search requires query");
3576
+ result = await searchCodeIntelligence(ctx.cwd, params.query, {
3577
+ structuralPattern: params.structuralPattern,
3578
+ language: params.language,
3579
+ file: params.file,
3580
+ maxResults: 12,
3581
+ });
3582
+ result.mode = "parent-lite";
3583
+ } else if (params.action === "read") {
3584
+ if (!params.file) throw new Error("ues_code read requires file");
3585
+ const startLine = Math.max(1, Math.trunc(Number(params.startLine || 1)));
3586
+ const endLine = Math.max(startLine, Math.min(startLine + 399, Math.trunc(Number(params.endLine || startLine + 199))));
3587
+ const read = await readAnchoredCode(ctx.cwd, params.file, { startLine, endLine });
3588
+ return {
3589
+ content: [{ type: "text", text: [
3590
+ `file: ${read.file}; lines: ${read.startLine}-${read.endLine}/${read.lineCount}; sourceHash: ${read.sourceHash}`,
3591
+ "",
3592
+ read.text,
3593
+ ].join("\n") }],
3594
+ details: {
3595
+ action: params.action,
3596
+ mode: "parent-lite",
3597
+ controllerStarted: false,
3598
+ childSpawned: false,
3599
+ file: read.file,
3600
+ sourceHash: read.sourceHash,
3601
+ startLine: read.startLine,
3602
+ endLine: read.endLine,
3603
+ },
3604
+ };
3605
+ } else if (params.action === "diagnostics") {
3606
+ if (!params.file) throw new Error("ues_code diagnostics requires file");
3607
+ result = await diagnoseCode(ctx.cwd, params.file, {
3608
+ timeoutMs: 5000,
3609
+ maxResults: 80,
3610
+ persistent: true,
3611
+ });
3612
+ } else if (["definition", "references", "symbols", "hover", "rename-preview", "incoming-calls", "outgoing-calls"].includes(params.action)) {
3613
+ if (!params.file) throw new Error(`ues_code ${params.action} requires file`);
3614
+ if (params.action === "rename-preview" && !params.newName) throw new Error("ues_code rename-preview requires newName");
3615
+ result = await lspOperation(ctx.cwd, params.file, params.action, {
3616
+ line: params.line || 1,
3617
+ character: params.character || 1,
3618
+ newName: params.newName,
3619
+ includeDeclaration: params.includeDeclaration,
3620
+ timeoutMs: 7000,
3621
+ maxResults: 120,
3622
+ persistent: true,
3623
+ });
3624
+ } else if (params.action === "document") {
3625
+ if (!params.file) throw new Error("ues_code document requires file");
3626
+ const document = await ingestDocument(ctx.cwd, params.file, {
3627
+ maxBytes: Math.min(Number(params.maxBytes || 4 * 1024 * 1024), 4 * 1024 * 1024),
3628
+ });
3629
+ const block = await compactContext(ctx.cwd, document.markdown, {
3630
+ kind: "document-ingestion",
3631
+ source: document.file,
3632
+ summary: `Normalized document from ${document.provider}`,
3633
+ });
3634
+ result = {
3635
+ provider: document.provider,
3636
+ file: document.file,
3637
+ bytes: document.bytes,
3638
+ optionalDependency: document.optionalDependency,
3639
+ contextRef: block.ref,
3640
+ originalChars: block.originalChars,
3641
+ summary: block.levels.T1,
3642
+ };
3643
+ } else if (params.action === "context-expand") {
3644
+ if (!params.ref) throw new Error("ues_code context-expand requires ref");
3645
+ const expanded = await expandContext(ctx.cwd, params.ref, { maxBytes: params.maxBytes || 16000 });
3646
+ return {
3647
+ content: [{ type: "text", text: expanded.content }],
3648
+ details: {
3649
+ action: params.action,
3650
+ mode: "parent-lite",
3651
+ controllerStarted: false,
3652
+ childSpawned: false,
3653
+ ref: expanded.ref,
3654
+ start: expanded.start,
3655
+ returnedBytes: expanded.returnedBytes,
3656
+ truncated: expanded.truncated,
3657
+ },
3658
+ };
3659
+ } else if (params.action === "context-search") {
3660
+ if (!params.ref || !params.query) throw new Error("ues_code context-search requires ref and query");
3661
+ result = await searchContext(ctx.cwd, params.ref, params.query, {
3662
+ maxBytes: params.maxBytes || 512000,
3663
+ maxMatches: 12,
3664
+ });
3665
+ } else {
3666
+ throw new Error("unsupported ues_code action");
3667
+ }
3668
+
3669
+ const payload = {
3670
+ ...result,
3671
+ mode: result?.mode || "parent-lite",
3672
+ controllerStarted: false,
3673
+ childSpawned: false,
3674
+ };
3675
+ const encoded = JSON.stringify(payload, null, 2);
3676
+ return {
3677
+ content: [{ type: "text", text: encoded.length <= 32000 ? encoded : encoded.slice(0, 32000) + "\n...[bounded by ues_code parent-lite]" }],
3678
+ details: {
3679
+ action: params.action,
3680
+ mode: "parent-lite",
3681
+ controllerStarted: false,
3682
+ childSpawned: false,
3683
+ bounded: encoded.length > 32000,
3684
+ },
3685
+ };
3686
+ } catch (error) {
3687
+ return {
3688
+ content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
3689
+ details: {
3690
+ action: params.action,
3691
+ mode: "parent-lite",
3692
+ controllerStarted: false,
3693
+ childSpawned: false,
3694
+ },
3695
+ isError: true,
3696
+ };
3697
+ }
3698
+ },
3045
3699
  });
3046
3700
 
3047
3701
  pi.registerTool({
@@ -3197,6 +3851,60 @@ export default function (pi: ExtensionAPI) {
3197
3851
  },
3198
3852
  });
3199
3853
 
3854
+ pi.registerTool({
3855
+ name: "ues_session",
3856
+ label: "UES Session Control",
3857
+ description:
3858
+ "Control the single active Pi RPC specialist session without shell orchestration. Supports state inspection, steer vs follow-up queueing, abort, queue clearing, model/thinking changes, compaction, and bounded wait. Fails closed when zero or multiple child sessions are active.",
3859
+ parameters: Type.Object({
3860
+ action: Type.Union([
3861
+ Type.Literal("status"),
3862
+ Type.Literal("get-state"),
3863
+ Type.Literal("steer"),
3864
+ Type.Literal("follow-up"),
3865
+ Type.Literal("abort"),
3866
+ Type.Literal("clear-queue"),
3867
+ Type.Literal("set-model"),
3868
+ Type.Literal("set-thinking"),
3869
+ Type.Literal("compact"),
3870
+ Type.Literal("wait"),
3871
+ ]),
3872
+ message: Type.Optional(Type.String({ maxLength: 12000 })),
3873
+ provider: Type.Optional(Type.String({ maxLength: 120 })),
3874
+ modelId: Type.Optional(Type.String({ maxLength: 240 })),
3875
+ thinkingLevel: Type.Optional(Type.String({ maxLength: 40 })),
3876
+ compactInstructions: Type.Optional(Type.String({ maxLength: 12000 })),
3877
+ timeoutMs: Type.Optional(Type.Number({ minimum: 500, maximum: 1800000 })),
3878
+ }),
3879
+ async execute(_toolCallId, params) {
3880
+ try {
3881
+ const action = String(params.action || "status");
3882
+ const result = action === "status"
3883
+ ? { ok: true, action, ...RPC_POOL.status() }
3884
+ : await RPC_POOL.controlActive(action, {
3885
+ message: params.message,
3886
+ provider: params.provider,
3887
+ modelId: params.modelId,
3888
+ level: params.thinkingLevel,
3889
+ customInstructions: params.compactInstructions,
3890
+ timeoutMs: params.timeoutMs,
3891
+ });
3892
+ return {
3893
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
3894
+ details: result,
3895
+ isError: result?.ok === false,
3896
+ };
3897
+ } catch (error) {
3898
+ const message = error instanceof Error ? error.message : String(error);
3899
+ return {
3900
+ content: [{ type: "text", text: message }],
3901
+ details: { action: params.action, error: message },
3902
+ isError: true,
3903
+ };
3904
+ }
3905
+ },
3906
+ });
3907
+
3200
3908
  const uesExecuteTool: any = {
3201
3909
  name: "ues_execute",
3202
3910
  label: "UES Execute",
@@ -3212,7 +3920,13 @@ export default function (pi: ExtensionAPI) {
3212
3920
  const cwd = requireGitWorkspaceRoot(params.cwd || ctx.cwd, "ues_execute");
3213
3921
  const inheritedModel = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined;
3214
3922
  const inheritedThinking = ctx.thinkingLevel as string | undefined;
3215
- const inheritedDirty = captureInheritedDirtyState(cwd);
3923
+ const controllerWorkspaceState = captureWorkspaceStateV2(cwd);
3924
+ const inheritedDirty = captureInheritedDirtyState(cwd, {
3925
+ workspaceState: controllerWorkspaceState,
3926
+ });
3927
+ const controllerHygieneBaseline = captureWorkspaceHygieneBaseline(cwd, {
3928
+ workspaceState: controllerWorkspaceState,
3929
+ });
3216
3930
  const executionContract = buildExecutionContract(params.task, inheritedDirty);
3217
3931
  const contractPrompt = executionContractPrompt(executionContract);
3218
3932
  const suppliedPolicy = (params as any).__taskPolicy;
@@ -3243,6 +3957,8 @@ export default function (pi: ExtensionAPI) {
3243
3957
  profile: policy.executionProfile,
3244
3958
  risk: policy.risk,
3245
3959
  mode: policy.mode,
3960
+ decisionConfidence: policy.decision?.confidence ?? null,
3961
+ decisionReason: policy.decision?.reason ?? null,
3246
3962
  inheritedDirtyCount: executionContract.inheritedDirty?.paths?.length || 0,
3247
3963
  explicitPhaseCount: executionContract.phases?.length || 0,
3248
3964
  localEnvWriteExplicitlyAllowed: executionContract.localEnvWriteExplicitlyAllowed === true,
@@ -3430,8 +4146,8 @@ export default function (pi: ExtensionAPI) {
3430
4146
  "",
3431
4147
  "## Acceptance criteria proven",
3432
4148
  deterministicPass
3433
- ? "All explicitly requested whitelisted Git inspection commands completed successfully."
3434
- : "The requested deterministic inspection did not fully pass.",
4149
+ ? "VERIFIED: All explicitly requested whitelisted Git inspection commands completed successfully."
4150
+ : "UNKNOWN: The requested deterministic inspection did not fully pass.",
3435
4151
  "",
3436
4152
  "## Failures",
3437
4153
  failureText,
@@ -3491,6 +4207,27 @@ export default function (pi: ExtensionAPI) {
3491
4207
  1,
3492
4208
  );
3493
4209
  if (isAbortedRun(inspection)) return abortedResponse(inspection, "read-only-inspection");
4210
+ if (
4211
+ inspection.exitCode === 0 &&
4212
+ inspection.verdict === "PASS" &&
4213
+ !acceptanceEvidenceStatusPresent(inspection)
4214
+ ) {
4215
+ inspection = await run(
4216
+ "ues-verifier",
4217
+ [
4218
+ "READ-ONLY VERIFICATION FORMAT RECOVERY. The previous verifier returned PASS but omitted mandatory evidence-status prefixes.",
4219
+ "Do not edit files. Re-check only what is needed to support the existing verdict.",
4220
+ "In ## Acceptance criteria proven, prefix every requested criterion with exactly VERIFIED:, INFERRED:, or UNKNOWN:.",
4221
+ "INFERRED or UNKNOWN criteria must also be listed under ## Unresolved gaps and cannot support PASS.",
4222
+ "",
4223
+ "Inspection request:",
4224
+ params.task,
4225
+ ].join("\n"),
4226
+ 1,
4227
+ "Previous verifier PASS omitted evidence-status markers.",
4228
+ );
4229
+ if (isAbortedRun(inspection)) return abortedResponse(inspection, "read-only-verification-format-recovery");
4230
+ }
3494
4231
  }
3495
4232
 
3496
4233
  const after = runtimeWorkspaceSnapshot(cwd);
@@ -3505,6 +4242,7 @@ export default function (pi: ExtensionAPI) {
3505
4242
  workspaceSnapshot: after,
3506
4243
  behavioralReceipts: [],
3507
4244
  requireBehavioralReceipt: false,
4245
+ requireClaimEvidenceStatus: true,
3508
4246
  });
3509
4247
  if (!unchanged) {
3510
4248
  completionAudit.passed = false;
@@ -4043,6 +4781,56 @@ export default function (pi: ExtensionAPI) {
4043
4781
  };
4044
4782
  }
4045
4783
 
4784
+ const finalWriteScope = [...new Set(
4785
+ structuredPlan.tasks.flatMap((task: any) => taskWriteFiles(task)),
4786
+ )];
4787
+ const preFinalAudit = await preFinalWorkspaceAudit(cwd, {
4788
+ baseline: controllerHygieneBaseline,
4789
+ taskText: params.task,
4790
+ allowedPaths: finalWriteScope,
4791
+ strictScope: true,
4792
+ allowSourceMutations: true,
4793
+ }).catch((error) => ({
4794
+ safe: false,
4795
+ summary: "pre-final workspace audit failed: " + (error instanceof Error ? error.message : String(error)),
4796
+ findings: [],
4797
+ }));
4798
+ if (!preFinalAudit.safe) {
4799
+ if (durableWork) {
4800
+ await durableRecordIntegration(
4801
+ cwd,
4802
+ durableWork.slug,
4803
+ "PARTIAL",
4804
+ preFinalAudit.summary || "pre-final workspace hygiene failed",
4805
+ signal,
4806
+ ).catch(() => {});
4807
+ }
4808
+ return {
4809
+ content: [{
4810
+ type: "text",
4811
+ text: [
4812
+ "UES pre-final workspace audit blocked PASS.",
4813
+ "The final repository contains an undeclared, transient, or Unicode-unsafe change.",
4814
+ "",
4815
+ preFinalAudit.summary || "workspace hygiene failed",
4816
+ ].join("\n"),
4817
+ }],
4818
+ details: {
4819
+ mode: "execute",
4820
+ policy,
4821
+ steps,
4822
+ structuredPlan,
4823
+ scheduled,
4824
+ durableWork,
4825
+ verdictMatrix,
4826
+ executionContract,
4827
+ preFinalAudit,
4828
+ traceID,
4829
+ },
4830
+ isError: true,
4831
+ };
4832
+ }
4833
+
4046
4834
  let durableFinalization: any = null;
4047
4835
  if (durableWork) {
4048
4836
  const finalEvidence = finalEvidenceForContract;
@@ -4219,7 +5007,7 @@ export default function (pi: ExtensionAPI) {
4219
5007
  agent: "ues-deterministic-verifier", task: params.task, cwd, exitCode: 0,
4220
5008
  output: ["FAST bounded verification reused fresh behavioral evidence captured at the tool boundary.", ...fastGate.behavioralReceipts.map((item: any) => "- " + item.command), "", "UES_VERDICT: PASS"].join("\n"),
4221
5009
  stderr: "", verdict: "PASS", durationMs: 0, toolCalls: 0, toolNames: [],
4222
- report: { schemaVersion: 1, valid: true, verdict: "PASS", sections: { "checks-run": fastGate.behavioralReceipts.map((item: any) => item.command).join("\n"), "acceptance-criteria-proven": "Fresh behavioral verification receipt(s) exist at the post-implementation workspace fingerprint.", "completion-evidence": "Deterministic PASS receipt captured after this implementation attempt." } },
5010
+ report: { schemaVersion: 1, valid: true, verdict: "PASS", sections: { "checks-run": fastGate.behavioralReceipts.map((item: any) => item.command).join("\n"), "acceptance-criteria-proven": "VERIFIED: Fresh behavioral verification receipt(s) exist at the post-implementation workspace fingerprint.", "completion-evidence": "Deterministic PASS receipt captured after this implementation attempt." } },
4223
5011
  optimizations: { fastDeterministicVerification: true, behavioralReceiptCount: fastGate.behavioralReceipts.length },
4224
5012
  };
4225
5013
  steps.push(verification);
@@ -4237,6 +5025,30 @@ export default function (pi: ExtensionAPI) {
4237
5025
  ].join("\n"), attempt, recentFailure || undefined,
4238
5026
  );
4239
5027
  if (isAbortedRun(verification)) return abortedResponse(verification, "verification");
5028
+ if (
5029
+ verification.exitCode === 0 &&
5030
+ verification.verdict === "PASS" &&
5031
+ !acceptanceEvidenceStatusPresent(verification)
5032
+ ) {
5033
+ verification = await run(
5034
+ "ues-verifier",
5035
+ [
5036
+ "VERIFICATION FORMAT RECOVERY. The previous verifier returned PASS but omitted mandatory evidence-status prefixes.",
5037
+ "Do not edit files and do not re-run broad checks. Re-check only what is necessary to support the verdict.",
5038
+ "In ## Acceptance criteria proven, prefix every requested criterion with exactly VERIFIED:, INFERRED:, or UNKNOWN:.",
5039
+ "INFERRED or UNKNOWN criteria must also appear under ## Unresolved gaps and cannot support PASS.",
5040
+ "",
5041
+ "Original task:",
5042
+ params.task,
5043
+ "",
5044
+ "Previous verifier output (not proof by itself):",
5045
+ cap(verification.output, 5000),
5046
+ ].join("\n"),
5047
+ attempt,
5048
+ "Previous verifier PASS omitted evidence-status markers.",
5049
+ );
5050
+ if (isAbortedRun(verification)) return abortedResponse(verification, "verification-format-recovery");
5051
+ }
4240
5052
  }
4241
5053
  const verified = verification.exitCode === 0 && verification.verdict === "PASS";
4242
5054
  if (!verified) {
@@ -4323,6 +5135,7 @@ export default function (pi: ExtensionAPI) {
4323
5135
  workspaceSnapshot: completionSnapshot,
4324
5136
  behavioralReceipts: freshReceipts,
4325
5137
  requireBehavioralReceipt: policy.requireBehavioralReceipt !== false,
5138
+ requireClaimEvidenceStatus: true,
4326
5139
  });
4327
5140
  if (!completionAudit.passed) {
4328
5141
  recentFailure = "Completion auditor rejected PASS: " + completionAudit.failures.join(", ");
@@ -4381,6 +5194,37 @@ export default function (pi: ExtensionAPI) {
4381
5194
  };
4382
5195
  }
4383
5196
 
5197
+ const preFinalAudit = await preFinalWorkspaceAudit(cwd, {
5198
+ baseline: controllerHygieneBaseline,
5199
+ taskText: params.task,
5200
+ strictScope: false,
5201
+ allowSourceMutations: true,
5202
+ }).catch((error) => ({
5203
+ safe: false,
5204
+ summary: "pre-final workspace audit failed: " + (error instanceof Error ? error.message : String(error)),
5205
+ findings: [],
5206
+ }));
5207
+ if (!preFinalAudit.safe) {
5208
+ recentFailure = "Pre-final workspace audit rejected PASS: " + (preFinalAudit.summary || "workspace hygiene failed");
5209
+ await recordRuntimeOutcome(implementation, params.task, false, attempt - 1);
5210
+ if (attempt < maxAttempts) continue;
5211
+ return {
5212
+ content: [{ type: "text", text: recentFailure }],
5213
+ details: {
5214
+ mode: "execute",
5215
+ policy,
5216
+ steps,
5217
+ attempts: attempt,
5218
+ completionAudit,
5219
+ verdictMatrix,
5220
+ executionContract,
5221
+ preFinalAudit,
5222
+ traceID,
5223
+ },
5224
+ isError: true,
5225
+ };
5226
+ }
5227
+
4384
5228
  await recordRuntimeOutcome(implementation, params.task, true, attempt - 1);
4385
5229
  const memory = await rememberVerifiedTask(cwd, params.task, verification, integrationResult);
4386
5230
  const final = steps.at(-1);
@@ -4425,9 +5269,17 @@ export default function (pi: ExtensionAPI) {
4425
5269
  "Package root: " + PACKAGE_ROOT,
4426
5270
  "Child runtime: " + CHILD_RUNTIME,
4427
5271
  "Adaptive context: " + (ADAPTIVE_CONTEXT_ENABLED ? "on" : "off"),
5272
+ "Unified workspace snapshot V2: on",
5273
+ "Parallel context preparation: on",
5274
+ "Git-index affected-test inventory: on",
5275
+ "Parallel verification evidence I/O: on",
4428
5276
  "Micro skills: " + (MICRO_SKILLS_ENABLED ? "on" : "off"),
4429
5277
  "Turbo Fast Path: on",
4430
5278
  "Parent UES tools hidden outside UES runs: on",
5279
+ "Parent Code Intelligence Lite: on (always-on read-only ues_code; no controller/child)",
5280
+ "Native Pi RPC session control: on (state/steer/follow-up/abort/model/thinking/compact/wait)",
5281
+ "Permission deny-and-continue recovery: on",
5282
+ "Provider empty-response recovery: on (per-incident parent retry + bounded total + child RPC recovery; no blind replay after tools)",
4431
5283
  "Zero-friction engineering admission: " + (AUTO_ADMISSION_ENABLED ? "on (native / auto / high-risk + safe continuation)" : "off"),
4432
5284
  "Git-root artifact guard: on",
4433
5285
  "Inherited dirty-work guard: on",
@@ -4435,6 +5287,9 @@ export default function (pi: ExtensionAPI) {
4435
5287
  "Portable temp-path guard: on",
4436
5288
  "Explicit phase barriers: on",
4437
5289
  "Independent final verdict matrix: on",
5290
+ "Unicode source hygiene: blocking bidi/zero-width/control/homoglyph audit",
5291
+ "Post-run file hygiene: transient cleanup + read-only mutation guard",
5292
+ "Pre-final workspace audit: on",
4438
5293
  "Disk hygiene: bounded + auto-clean",
4439
5294
  "Writer concurrency: " + MAX_WRITER_CONCURRENCY,
4440
5295
  ].join("\n");
@@ -4766,9 +5621,11 @@ export default function (pi: ExtensionAPI) {
4766
5621
  name: "ues_dispatch",
4767
5622
  label: "UES Dispatch",
4768
5623
  description:
4769
- "Run bundled UES specialist agents in isolated child Pi processes. Supports single, parallel, or chain mode. Parallel writer agents fail closed unless each writer has an explicit distinct cwd/worktree. Available agents: " +
5624
+ "Run bundled UES specialist agents in isolated child Pi processes, or inspect durable child handles with action=status/list. Every child run writes a small artifact with exact task/output evidence references. Supports single, parallel, or chain mode. Parallel writer agents fail closed unless each writer has an explicit distinct cwd/worktree. Available agents: " +
4770
5625
  Object.keys(AGENTS).join(", "),
4771
5626
  parameters: Type.Object({
5627
+ action: Type.Optional(Type.Union([Type.Literal("run"), Type.Literal("status"), Type.Literal("list")])),
5628
+ handle: Type.Optional(Type.String({ description: "Subagent artifact handle for status action" })),
4772
5629
  agent: Type.Optional(Type.String({ description: "Agent name for single mode" })),
4773
5630
  task: Type.Optional(Type.String({ description: "Task for single mode" })),
4774
5631
  cwd: Type.Optional(Type.String({ description: "Working directory for single mode" })),
@@ -4777,6 +5634,39 @@ export default function (pi: ExtensionAPI) {
4777
5634
  }),
4778
5635
  async execute(_toolCallId, params, signal, onUpdate, ctx) {
4779
5636
  refreshHostBrowserToolNames(pi);
5637
+ const action = String(params.action || "run");
5638
+ const baseCwd = ctx.cwd;
5639
+ if (action === "status") {
5640
+ if (!params.handle) {
5641
+ return {
5642
+ content: [{ type: "text", text: "ues_dispatch action=status requires handle." }],
5643
+ details: { mode: "status" },
5644
+ isError: true,
5645
+ };
5646
+ }
5647
+ try {
5648
+ const root = requireGitWorkspaceRoot(baseCwd, "ues_dispatch status");
5649
+ const artifact = await readSubagentArtifact(root, params.handle);
5650
+ return {
5651
+ content: [{ type: "text", text: JSON.stringify(artifact, null, 2) }],
5652
+ details: { mode: "status", artifact },
5653
+ };
5654
+ } catch (error) {
5655
+ return {
5656
+ content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
5657
+ details: { mode: "status", handle: params.handle },
5658
+ isError: true,
5659
+ };
5660
+ }
5661
+ }
5662
+ if (action === "list") {
5663
+ const root = requireGitWorkspaceRoot(baseCwd, "ues_dispatch list");
5664
+ const artifacts = await listSubagentArtifacts(root, { limit: 20 });
5665
+ return {
5666
+ content: [{ type: "text", text: JSON.stringify(artifacts, null, 2) }],
5667
+ details: { mode: "list", artifacts },
5668
+ };
5669
+ }
4780
5670
  const hasSingle = Boolean(params.agent && params.task);
4781
5671
  const hasParallel = Boolean(params.tasks?.length);
4782
5672
  const hasChain = Boolean(params.chain?.length);
@@ -4791,7 +5681,6 @@ export default function (pi: ExtensionAPI) {
4791
5681
  const validateAgent = (name: string): name is AgentName => name in AGENTS;
4792
5682
  const model = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined;
4793
5683
  const thinking = ctx.thinkingLevel as string | undefined;
4794
- const baseCwd = ctx.cwd;
4795
5684
 
4796
5685
  if (hasSingle) {
4797
5686
  if (!validateAgent(params.agent!)) {