opencode-agent-skill 14.4.0 → 15.0.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 (44) hide show
  1. package/README.md +33 -15
  2. package/docs/PI-COMPAT.md +151 -2
  3. package/docs/V15-MANAGED-RUNTIME.md +128 -0
  4. package/global-config/agents/architect.md +63 -1
  5. package/global-config/agents/executor.md +7 -0
  6. package/global-config/agents/plan-checker.md +8 -1
  7. package/global-config/agents/verifier.md +3 -3
  8. package/global-config/skills/database-engineering/references/workflow.md +15 -0
  9. package/global-config/skills/engineering-orchestrator/references/long-horizon.md +21 -11
  10. package/lib/activity-deadline.mjs +70 -0
  11. package/lib/adaptive-context-budget.mjs +25 -5
  12. package/lib/affected-tests.mjs +1 -1
  13. package/lib/capability-fabric.mjs +17 -0
  14. package/lib/completion-auditor.mjs +25 -5
  15. package/lib/evidence-store.mjs +92 -8
  16. package/lib/execution-contract.mjs +579 -0
  17. package/lib/leaf-runtime-optimizer.mjs +76 -0
  18. package/lib/pi-child-invocation.mjs +65 -0
  19. package/lib/pi-rpc-pool.mjs +61 -9
  20. package/lib/plan-salvage.mjs +124 -0
  21. package/lib/planning-speed-policy.mjs +131 -0
  22. package/lib/repo-graph.mjs +1 -1
  23. package/lib/repo-inspect.mjs +1 -0
  24. package/lib/runtime-artifacts.mjs +42 -0
  25. package/lib/runtime-events.mjs +33 -1
  26. package/lib/safety.mjs +1 -0
  27. package/lib/semantic-index.mjs +1 -1
  28. package/lib/service-manager.mjs +526 -0
  29. package/lib/session-display.mjs +49 -0
  30. package/lib/task-graph.mjs +87 -0
  31. package/lib/task-policy.mjs +150 -4
  32. package/lib/trajectory.mjs +111 -1
  33. package/lib/turbo-fast-path.mjs +44 -0
  34. package/lib/workspace-fingerprint.mjs +2 -11
  35. package/lib/workspace-root.mjs +49 -0
  36. package/lib/worktree-sandbox.mjs +234 -11
  37. package/package.json +8 -5
  38. package/pi/extensions/ues-child-runtime.ts +145 -2
  39. package/pi/extensions/ues.ts +1760 -160
  40. package/scripts/check-release-consistency.mjs +25 -2
  41. package/scripts/check-source-integrity.mjs +471 -4
  42. package/scripts/eval-pi.mjs +76 -36
  43. package/scripts/smoke-pi-extension.mjs +1 -1
  44. package/pi/prompts/ues-run.md +0 -17
@@ -7,15 +7,16 @@ import { fileURLToPath } from "node:url";
7
7
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
8
8
  import { Type } from "typebox";
9
9
  import { destructiveShellRisk } from "../../lib/safety.mjs";
10
- import { classifyEngineeringTask, shouldRunDedicatedDiagnosis } from "../../lib/task-policy.mjs";
10
+ import { automaticUesAdmission, automaticUesContinuation, classifyEngineeringTask, deterministicReadOnlyGitCommands, shouldRunDedicatedDiagnosis } from "../../lib/task-policy.mjs";
11
11
  import { resolveCapabilityModel } from "../../lib/model-policy.mjs";
12
12
  import { readModelPolicy, recordModelPerformance } from "../../lib/model-config.mjs";
13
13
  import { getUesConfigDir } from "../../lib/runtime-config.mjs";
14
14
  import { buildAdaptiveTaskContext } from "../../lib/context-engine-v11.mjs";
15
15
  import { recordVerifiedTaskMemory } from "../../lib/memory-engine.mjs";
16
- import { computeSafeWaves, taskVerificationCommands, taskWriteFiles, validatePlan } from "../../lib/task-graph.mjs";
16
+ import { computeSafeWaves, normalizePlanForValidation, taskVerificationCommands, taskWriteFiles, validatePlan } from "../../lib/task-graph.mjs";
17
17
  import { planDynamicWorkflow } from "../../lib/dynamic-workflow.mjs";
18
18
  import { compactReversibleOutput } from "../../lib/performance-fabric.mjs";
19
+ import { gcEvidenceStore } from "../../lib/evidence-store.mjs";
19
20
  import {
20
21
  createToolOutputAccumulator,
21
22
  detectHungToolEvidence,
@@ -24,11 +25,21 @@ import {
24
25
  } from "../../lib/process-hang-detector.mjs";
25
26
  import { runSupervisedProcess, terminateProcessTree } from "../../lib/process-supervisor.mjs";
26
27
  import { PiRpcWorkerPool } from "../../lib/pi-rpc-pool.mjs";
28
+ import { resolvePiChildInvocation } from "../../lib/pi-child-invocation.mjs";
27
29
  import { adaptiveContextBudget } from "../../lib/adaptive-context-budget.mjs";
28
30
  import { clearSkillCompilerCache, compileSkillContext } from "../../lib/skill-compiler.mjs";
29
31
  import { clearAffectedTestCache, resolveAffectedTests } from "../../lib/affected-tests.mjs";
30
32
  import { findReusableVerification, listReusableVerification, recordVerification } from "../../lib/verification-broker.mjs";
31
33
  import { evaluateFastVerificationGate } from "../../lib/fast-verification-gate.mjs";
34
+ import { turboFastPathDecision, turboFastTimeoutBudget } from "../../lib/turbo-fast-path.mjs";
35
+ import { failureDelta, leafTaskPolicy } from "../../lib/leaf-runtime-optimizer.mjs";
36
+ import { planningRuntimeBudget, shouldSoftSteerArchitect, shouldSoftSteerPlanningRole } from "../../lib/planning-speed-policy.mjs";
37
+ import { sourceFacingPaths, sourceGitPathspecs } from "../../lib/runtime-artifacts.mjs";
38
+ import { buildExecutionContract, buildFinalVerdictMatrix, captureInheritedDirtyState, detectInheritedDirtyViolations, enforcePhaseGates, executionContractPrompt, phaseArtifactPayloads, taskExplicitlyAllowsLocalEnvWrite } from "../../lib/execution-contract.mjs";
39
+ import { sessionNameFromUesInput, uesSessionName } from "../../lib/session-display.mjs";
40
+ import { requireGitWorkspaceRoot, resolveGitWorkspaceRoot } from "../../lib/workspace-root.mjs";
41
+ import { createAdaptiveDeadline } from "../../lib/activity-deadline.mjs";
42
+ import { extractValidatedPlan } from "../../lib/plan-salvage.mjs";
32
43
  import { auditCompletion } from "../../lib/completion-auditor.mjs";
33
44
  import { mcpExecutionPolicy } from "../../lib/mcp-tool-policy.mjs";
34
45
  import { McpHealthTracker } from "../../lib/mcp-health.mjs";
@@ -47,14 +58,37 @@ import {
47
58
  integrateTaskSandbox,
48
59
  removeTaskSandbox,
49
60
  rollbackTaskSandbox,
61
+ pruneOrphanTaskSandboxes,
62
+ taskSandboxOwnerRoot,
50
63
  } from "../../lib/worktree-sandbox.mjs";
64
+ import {
65
+ looksLikeLongRunningServiceCommand,
66
+ restartService,
67
+ serviceLogs,
68
+ serviceStatus,
69
+ startService,
70
+ stopAllServices,
71
+ stopService,
72
+ waitForService,
73
+ } from "../../lib/service-manager.mjs";
51
74
 
52
75
  const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
76
+ const PACKAGE_VERSION = (() => {
77
+ try {
78
+ return String(JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, "package.json"), "utf8"))?.version || "unknown");
79
+ } catch {
80
+ return "unknown";
81
+ }
82
+ })();
53
83
  const OCSKILL_BIN = path.join(PACKAGE_ROOT, "bin", "ocskill.mjs");
54
84
  const CHILD_RUNTIME_EXTENSION = path.join(PACKAGE_ROOT, "pi", "extensions", "ues-child-runtime.ts");
55
85
  const AGENT_DIR = path.join(PACKAGE_ROOT, "global-config", "agents");
56
86
  const MAX_PARALLEL_TASKS = 8;
57
87
  const MAX_CONCURRENCY = 4;
88
+ const MAX_WRITER_CONCURRENCY = Math.max(
89
+ 1,
90
+ Math.min(4, Number(process.env.UES_MAX_WRITER_CONCURRENCY || (process.platform === "win32" ? 2 : 3))),
91
+ );
58
92
  const OUTPUT_LIMIT = 512 * 1024;
59
93
 
60
94
  function configuredDuration(name: string, fallback: number, min: number, max: number) {
@@ -93,6 +127,12 @@ const POST_TOOL_ERROR_IDLE_TIMEOUT_MS = configuredDuration(
93
127
  5_000,
94
128
  5 * 60_000,
95
129
  );
130
+ const TURBO_FAST_TIMEOUTS = turboFastTimeoutBudget({
131
+ hardTimeoutMs: configuredDuration("UES_FAST_CHILD_HARD_TIMEOUT_MS", 180_000, 30_000, 10 * 60_000),
132
+ idleTimeoutMs: configuredDuration("UES_FAST_CHILD_IDLE_TIMEOUT_MS", 60_000, 20_000, 5 * 60_000),
133
+ postToolErrorIdleTimeoutMs: configuredDuration("UES_FAST_POST_TOOL_ERROR_IDLE_TIMEOUT_MS", 30_000, 5_000, 2 * 60_000),
134
+ verificationTimeoutSec: configuredDuration("UES_FAST_VERIFICATION_TIMEOUT_SEC", 90, 30, 300),
135
+ });
96
136
  const MODEL_VISIBLE_OUTPUT_LIMIT = configuredDuration(
97
137
  "UES_MODEL_VISIBLE_OUTPUT_LIMIT",
98
138
  64 * 1024,
@@ -160,6 +200,7 @@ function abortActiveCliChildren() {
160
200
 
161
201
  let HOST_BROWSER_TOOL_NAMES: string[] = [];
162
202
  const CONTEXT_PACK_CACHE = new Map<string, any>();
203
+ const ACTIVE_TASK_SANDBOXES = new Map<string, string>();
163
204
 
164
205
  function configuredBrowserToolNames() {
165
206
  return String(process.env.UES_BROWSER_MCP_TOOL_NAMES || "")
@@ -257,6 +298,8 @@ function getAgentPrompt(agent: AgentName) {
257
298
  "- Do not call OpenCode-only dispatch tools such as \`ues.dispatch_task\` or \`ues.dispatch_parallel\`.",
258
299
  "- Respect the original role's edit/read-only boundary and return evidence to the parent Pi session.",
259
300
  "- Prefer ues_code for bounded semantic/AST search, hash-anchored reads and optional LSP diagnostics. Writer roles may use ues_code_edit only after an anchored read; stale anchors must be re-read rather than fuzzily retried.",
301
+ "- Never launch a persistent dev server/watcher in foreground bash/powershell. Use ues_service start, wait-ready/status/logs, then stop; the runtime blocks common foreground-service commands to prevent hangs.",
302
+ "- On Windows, never pass /tmp or /var/tmp paths between Pi file tools and bash/powershell: their path namespaces may differ. Keep temporary transforms inside one shell pipeline, or use an ignored repository-local scratch path such as .ues-cache/tmp for cross-tool scratch.",
260
303
  "- For PDF/DOCX/PPTX/XLSX evidence, ues_code action=document may use optional MarkItDown when installed; do not install it unless that capability is needed.",
261
304
  "",
262
305
  ].join("\n");
@@ -272,16 +315,8 @@ function getAgentPrompt(agent: AgentName) {
272
315
  }
273
316
 
274
317
  function getPiInvocation(args: string[]): { command: string; args: string[] } {
275
- const currentScript = process.argv[1];
276
- const isBunVirtualScript = currentScript?.startsWith("/$bunfs/root/");
277
- if (currentScript && !isBunVirtualScript && fs.existsSync(currentScript)) {
278
- return { command: process.execPath, args: [currentScript, ...args] };
279
- }
280
-
281
- const execName = path.basename(process.execPath).toLowerCase();
282
- const isGenericRuntime = /^(node|bun)(\.exe)?$/.test(execName);
283
- if (!isGenericRuntime) return { command: process.execPath, args };
284
- return { command: "pi", args };
318
+ const invocation = resolvePiChildInvocation(args);
319
+ return { command: invocation.command, args: invocation.args };
285
320
  }
286
321
 
287
322
  function extractAssistantText(message: any): string {
@@ -345,6 +380,83 @@ async function runOcskillJson(args: string[], cwd: string, signal?: AbortSignal)
345
380
  }
346
381
  }
347
382
 
383
+ async function persistExecutionContractArtifacts(dir: string, contract: any) {
384
+ if (!contract || !dir) return null;
385
+ const phasesDir = path.join(dir, "phases");
386
+ await fs.promises.mkdir(phasesDir, { recursive: true });
387
+ await fs.promises.writeFile(
388
+ path.join(dir, "EXECUTION_CONTRACT.json"),
389
+ JSON.stringify(contract, null, 2) + "\n",
390
+ "utf8",
391
+ );
392
+ await fs.promises.writeFile(
393
+ path.join(phasesDir, "MANIFEST.json"),
394
+ JSON.stringify({
395
+ schemaVersion: 1,
396
+ taskHash: contract.taskHash,
397
+ phaseCount: contract.phases?.length || 0,
398
+ artifacts: phaseArtifactPayloads(contract).map((item: any) => item.file),
399
+ }, null, 2) + "\n",
400
+ "utf8",
401
+ );
402
+ for (const item of phaseArtifactPayloads(contract)) {
403
+ const target = path.join(dir, item.file);
404
+ await fs.promises.mkdir(path.dirname(target), { recursive: true });
405
+ await fs.promises.writeFile(target, JSON.stringify(item.value, null, 2) + "\n", "utf8");
406
+ }
407
+ return {
408
+ contract: path.join(dir, "EXECUTION_CONTRACT.json"),
409
+ manifest: path.join(phasesDir, "MANIFEST.json"),
410
+ phaseCount: contract.phases?.length || 0,
411
+ };
412
+ }
413
+
414
+ async function finalizeExecutionContractArtifacts(
415
+ dir: string,
416
+ contract: any,
417
+ verdictMatrix: any,
418
+ evidence: string,
419
+ ) {
420
+ if (!dir || !contract) return null;
421
+ const payload = {
422
+ schemaVersion: 1,
423
+ verdictMatrix,
424
+ evidence: cap(evidence || "", 12000),
425
+ finalizedAt: new Date().toISOString(),
426
+ };
427
+ await fs.promises.writeFile(
428
+ path.join(dir, "FINAL_VERDICTS.json"),
429
+ JSON.stringify(payload, null, 2) + "\n",
430
+ "utf8",
431
+ );
432
+
433
+ for (const item of phaseArtifactPayloads(contract)) {
434
+ const phaseText = String(item.value.title || "") + "\n" + String(item.value.sourceBody || "");
435
+ let status = verdictMatrix?.source === "SOURCE_PASS" ? "VERIFIED" : "NOT_VERIFIED";
436
+ if (/device|expo go|thiết bị/i.test(phaseText) && verdictMatrix?.device !== "DEVICE_PASS") {
437
+ status = "NOT_VERIFIED";
438
+ }
439
+ if (/(?:cleanup|fixture|database|db|dữ liệu)/i.test(phaseText) && contract.gates?.dbClean === true && verdictMatrix?.dbClean !== "DB_CLEAN_PASS") {
440
+ status = "NOT_VERIFIED";
441
+ }
442
+ if (/(?:runtime|smoke|e2e|integration|typecheck|lint|test|verify|xác minh|kiểm tra)/i.test(phaseText) && contract.gates?.runtime === true && verdictMatrix?.runtime !== "RUNTIME_PASS") {
443
+ status = "NOT_VERIFIED";
444
+ }
445
+ const target = path.join(dir, item.file);
446
+ await fs.promises.writeFile(
447
+ target,
448
+ JSON.stringify({
449
+ ...item.value,
450
+ status,
451
+ finalVerdicts: verdictMatrix,
452
+ evidence: [cap(evidence || "", 6000)],
453
+ }, null, 2) + "\n",
454
+ "utf8",
455
+ );
456
+ }
457
+ return payload;
458
+ }
459
+
348
460
  async function initializeDurableControllerWork(
349
461
  root: string,
350
462
  originalTask: string,
@@ -540,9 +652,22 @@ async function runAgentCli(
540
652
  compactToolOutput?: boolean;
541
653
  toolOutputLimit?: number;
542
654
  verificationTimeoutSec?: number;
655
+ hardTimeoutMs?: number;
656
+ absoluteHardTimeoutMs?: number;
657
+ activityExtensionMs?: number;
658
+ activityWindowMs?: number;
659
+ idleTimeoutMs?: number;
660
+ postToolErrorIdleTimeoutMs?: number;
661
+ allowLocalEnvWrite?: boolean;
543
662
  } = {},
544
663
  ): Promise<RunResult> {
545
664
  const config = AGENTS[agent];
665
+ const hardTimeoutMs = Number(runtimeOptions.hardTimeoutMs || CHILD_HARD_TIMEOUT_MS);
666
+ const absoluteHardTimeoutMs = Number(runtimeOptions.absoluteHardTimeoutMs || hardTimeoutMs);
667
+ const activityExtensionMs = Number(runtimeOptions.activityExtensionMs || 0);
668
+ const activityWindowMs = Number(runtimeOptions.activityWindowMs || Math.max(5_000, Math.min(activityExtensionMs || hardTimeoutMs, 30_000)));
669
+ const idleTimeoutMs = Number(runtimeOptions.idleTimeoutMs || CHILD_IDLE_TIMEOUT_MS);
670
+ const postToolErrorIdleTimeoutMs = Number(runtimeOptions.postToolErrorIdleTimeoutMs || POST_TOOL_ERROR_IDLE_TIMEOUT_MS);
546
671
  const args: string[] = [
547
672
  "--mode", "json", "-p", "--no-session",
548
673
  // Keep extension discovery enabled so custom model providers (for example
@@ -559,6 +684,7 @@ async function runAgentCli(
559
684
  const allowedTools = [...new Set([
560
685
  ...config.tools,
561
686
  ...codeIntelligenceTools,
687
+ "ues_service",
562
688
  ...extraTools,
563
689
  ...(runtimeOptions.compactToolOutput ? ["ues_evidence_get"] : []),
564
690
  ])];
@@ -588,9 +714,11 @@ async function runAgentCli(
588
714
  env: {
589
715
  ...process.env,
590
716
  UES_CHILD_PROCESS: "1",
717
+ UES_CHILD_AGENT: agent,
591
718
  UES_CHILD_TOOL_COMPACTION: runtimeOptions.compactToolOutput ? "1" : "0",
592
719
  UES_CHILD_TOOL_OUTPUT_LIMIT: String(runtimeOptions.toolOutputLimit || 24 * 1024),
593
720
  UES_CHILD_VERIFICATION_TIMEOUT_SEC: String(runtimeOptions.verificationTimeoutSec || 300),
721
+ UES_CHILD_ALLOW_LOCAL_ENV_WRITE: runtimeOptions.allowLocalEnvWrite ? "1" : "0",
594
722
  },
595
723
  shell: false,
596
724
  detached: process.platform !== "win32",
@@ -599,6 +727,12 @@ async function runAgentCli(
599
727
  });
600
728
  const childStartedAt = Date.now();
601
729
  let lastActivityAt = childStartedAt;
730
+ const adaptiveDeadline = createAdaptiveDeadline({
731
+ hardTimeoutMs,
732
+ absoluteHardTimeoutMs,
733
+ activityExtensionMs,
734
+ activityWindowMs,
735
+ }, childStartedAt);
602
736
  let buffer = "";
603
737
  let settled = false;
604
738
  let heartbeatTimer: ReturnType<typeof setInterval> | null = null;
@@ -722,19 +856,20 @@ async function runAgentCli(
722
856
  heartbeatTimer.unref?.();
723
857
  watchdogTimer = setInterval(() => {
724
858
  const now = Date.now();
725
- if (now - childStartedAt >= CHILD_HARD_TIMEOUT_MS) {
859
+ const deadline = adaptiveDeadline.shouldAbort(now, lastActivityAt);
860
+ if (deadline.abort) {
726
861
  terminateForTimeout("hard");
727
862
  return;
728
863
  }
729
864
  if (
730
865
  lastToolErrorAt > 0 &&
731
- now - lastToolErrorAt >= POST_TOOL_ERROR_IDLE_TIMEOUT_MS &&
732
- now - lastActivityAt >= POST_TOOL_ERROR_IDLE_TIMEOUT_MS
866
+ now - lastToolErrorAt >= postToolErrorIdleTimeoutMs &&
867
+ now - lastActivityAt >= postToolErrorIdleTimeoutMs
733
868
  ) {
734
869
  terminateForTimeout("post-tool-error");
735
870
  return;
736
871
  }
737
- if (now - lastActivityAt >= CHILD_IDLE_TIMEOUT_MS) {
872
+ if (now - lastActivityAt >= idleTimeoutMs) {
738
873
  terminateForTimeout("idle");
739
874
  }
740
875
  }, 1000);
@@ -787,8 +922,13 @@ async function runAgentCli(
787
922
  lastToolErrorEvidence = "";
788
923
  }
789
924
  }
790
- if (event.type === "message_update" && event.usage) {
791
- usage = event.usage;
925
+ if (event.type === "message_update") {
926
+ if (event.usage) usage = event.usage;
927
+ if (event.message?.role === "assistant") {
928
+ const partial = extractAssistantText(event.message);
929
+ if (partial) output = partial;
930
+ seenModel = event.message.model || seenModel;
931
+ }
792
932
  }
793
933
  if (event.type === "message_end" && event.message) {
794
934
  const text = extractAssistantText(event.message);
@@ -897,9 +1037,22 @@ async function runAgentRpc(
897
1037
  compactToolOutput?: boolean;
898
1038
  toolOutputLimit?: number;
899
1039
  verificationTimeoutSec?: number;
1040
+ hardTimeoutMs?: number;
1041
+ absoluteHardTimeoutMs?: number;
1042
+ activityExtensionMs?: number;
1043
+ activityWindowMs?: number;
1044
+ idleTimeoutMs?: number;
1045
+ postToolErrorIdleTimeoutMs?: number;
1046
+ allowLocalEnvWrite?: boolean;
900
1047
  } = {},
901
1048
  ): Promise<RunResult> {
902
1049
  const config = AGENTS[agent];
1050
+ const hardTimeoutMs = Number(runtimeOptions.hardTimeoutMs || CHILD_HARD_TIMEOUT_MS);
1051
+ const absoluteHardTimeoutMs = Number(runtimeOptions.absoluteHardTimeoutMs || hardTimeoutMs);
1052
+ const activityExtensionMs = Number(runtimeOptions.activityExtensionMs || 0);
1053
+ const activityWindowMs = Number(runtimeOptions.activityWindowMs || Math.max(5_000, Math.min(activityExtensionMs || hardTimeoutMs, 30_000)));
1054
+ const idleTimeoutMs = Number(runtimeOptions.idleTimeoutMs || CHILD_IDLE_TIMEOUT_MS);
1055
+ const postToolErrorIdleTimeoutMs = Number(runtimeOptions.postToolErrorIdleTimeoutMs || POST_TOOL_ERROR_IDLE_TIMEOUT_MS);
903
1056
  const args: string[] = [
904
1057
  "--mode", "rpc", "--no-session",
905
1058
  "--no-skills", "--no-prompt-templates", "--no-context-files",
@@ -907,8 +1060,13 @@ async function runAgentRpc(
907
1060
  ];
908
1061
  if (model) args.push("--model", model);
909
1062
  if (thinkingLevel) args.push("--thinking", thinkingLevel);
1063
+ const codeIntelligenceTools = WRITE_AGENTS.has(agent)
1064
+ ? ["ues_code", "ues_code_edit"]
1065
+ : ["ues_code"];
910
1066
  const allowedTools = [...new Set([
911
1067
  ...config.tools,
1068
+ ...codeIntelligenceTools,
1069
+ "ues_service",
912
1070
  ...extraTools,
913
1071
  ...(runtimeOptions.compactToolOutput ? ["ues_evidence_get"] : []),
914
1072
  ])];
@@ -924,6 +1082,7 @@ async function runAgentRpc(
924
1082
  Boolean(runtimeOptions.compactToolOutput),
925
1083
  Number(runtimeOptions.toolOutputLimit || 0),
926
1084
  Number(runtimeOptions.verificationTimeoutSec || 0),
1085
+ Boolean(runtimeOptions.allowLocalEnvWrite),
927
1086
  ]);
928
1087
  const taskInput = `Task: ${task}\n`;
929
1088
  const startedAt = Date.now();
@@ -960,17 +1119,22 @@ async function runAgentRpc(
960
1119
  env: {
961
1120
  ...process.env,
962
1121
  UES_CHILD_PROCESS: "1",
1122
+ UES_CHILD_AGENT: agent,
963
1123
  UES_CHILD_TOOL_COMPACTION: runtimeOptions.compactToolOutput ? "1" : "0",
964
1124
  UES_CHILD_TOOL_OUTPUT_LIMIT: String(runtimeOptions.toolOutputLimit || 24 * 1024),
965
1125
  UES_CHILD_VERIFICATION_TIMEOUT_SEC: String(runtimeOptions.verificationTimeoutSec || 300),
1126
+ UES_CHILD_ALLOW_LOCAL_ENV_WRITE: runtimeOptions.allowLocalEnvWrite ? "1" : "0",
966
1127
  },
967
1128
  },
968
1129
  taskInput,
969
1130
  {
970
1131
  signal,
971
- hardTimeoutMs: CHILD_HARD_TIMEOUT_MS,
972
- idleTimeoutMs: CHILD_IDLE_TIMEOUT_MS,
973
- postToolErrorIdleTimeoutMs: POST_TOOL_ERROR_IDLE_TIMEOUT_MS,
1132
+ hardTimeoutMs,
1133
+ absoluteHardTimeoutMs,
1134
+ activityExtensionMs,
1135
+ activityWindowMs,
1136
+ idleTimeoutMs,
1137
+ postToolErrorIdleTimeoutMs,
974
1138
  onEvent: (event: any) => {
975
1139
  lastActivityAt = Date.now();
976
1140
  if (event.type === "tool_execution_start") {
@@ -1072,12 +1236,16 @@ async function runAgentRpc(
1072
1236
  if ((error as any)?.uesRpcPhase === "runtime") {
1073
1237
  const timeout = /hard-timeout|idle-timeout/i.test(message);
1074
1238
  const toolStall = /post-tool-error-stall/i.test(message);
1239
+ const partialOutput = extractAssistantText((error as any)?.partialMessage);
1240
+ const recoveredOutput = partialOutput
1241
+ ? partialOutput + "\n\n[UES transport note: " + message + "]"
1242
+ : message;
1075
1243
  return {
1076
1244
  agent,
1077
1245
  task,
1078
1246
  cwd,
1079
1247
  exitCode: timeout ? 124 : toolStall ? 125 : 1,
1080
- output: message,
1248
+ output: recoveredOutput,
1081
1249
  stderr: message,
1082
1250
  model,
1083
1251
  stopReason: timeout ? "timeout" : toolStall ? "tool-error-stall" : "rpc-runtime-error",
@@ -1109,6 +1277,13 @@ async function runAgent(
1109
1277
  compactToolOutput?: boolean;
1110
1278
  toolOutputLimit?: number;
1111
1279
  verificationTimeoutSec?: number;
1280
+ hardTimeoutMs?: number;
1281
+ absoluteHardTimeoutMs?: number;
1282
+ activityExtensionMs?: number;
1283
+ activityWindowMs?: number;
1284
+ idleTimeoutMs?: number;
1285
+ postToolErrorIdleTimeoutMs?: number;
1286
+ allowLocalEnvWrite?: boolean;
1112
1287
  } = {},
1113
1288
  ): Promise<RunResult> {
1114
1289
  if (CHILD_RUNTIME !== "cli") {
@@ -1251,9 +1426,37 @@ function cachedContextKey(
1251
1426
  role: string,
1252
1427
  budget: number,
1253
1428
  fingerprint = "unknown",
1429
+ namespace = cwd,
1254
1430
  ) {
1255
1431
  const auxStamp = runtimeContextAuxStamp(cwd);
1256
- return [cwd, fingerprint, auxStamp, role, String(budget), task].join("\u0000");
1432
+ return [path.resolve(namespace), fingerprint, auxStamp, role, String(budget), task].join("\u0000");
1433
+ }
1434
+
1435
+ function deepExplorationContract(role: string) {
1436
+ const common = [
1437
+ "## UES DEEP bounded exploration",
1438
+ "Quality gates remain unchanged. Reduce latency by avoiding duplicate discovery, not by skipping evidence.",
1439
+ "Use the supplied runtime context pack, hierarchy, ranked references and declared files before broad repository exploration.",
1440
+ "Prefer targeted ues_code/direct reads. Do not inventory the repository or repeat unchanged reads unless a named evidence gap requires it.",
1441
+ ];
1442
+ if (role === "architect") {
1443
+ common.push(
1444
+ "Stop exploring once every planned task has exact repository-relative scope, dependency ordering, observable acceptance, concrete verification, and risk/rollback coverage.",
1445
+ );
1446
+ } else if (role === "plan-checker") {
1447
+ common.push(
1448
+ "Inspect only disputed or unproven plan properties; once each blocking property is proven or rejected, return PASS/REVISE immediately.",
1449
+ );
1450
+ } else if (role === "executor") {
1451
+ common.push(
1452
+ "Start with declared task files and direct consumers/tests only. Once the safe minimal edit is supported by evidence, implement and spend remaining effort on fresh verification rather than more discovery.",
1453
+ );
1454
+ } else if (role === "debugger") {
1455
+ common.push(
1456
+ "Investigate only the concrete failure path and nearest evidence needed to reject/confirm the active hypothesis; avoid general repository surveys.",
1457
+ );
1458
+ }
1459
+ return common.join("\n");
1257
1460
  }
1258
1461
 
1259
1462
  function compactContextPack(pack: any, recentFailure?: string) {
@@ -1304,20 +1507,23 @@ async function runRoutedAgent(
1304
1507
  signal?: AbortSignal,
1305
1508
  onProgress?: Parameters<typeof runAgent>[6],
1306
1509
  traceID?: string,
1510
+ taskPolicyOverride?: any,
1511
+ contextCacheNamespace?: string,
1307
1512
  ): Promise<RunResult> {
1308
1513
  const role = roleForAgent(agent);
1514
+ const traceRoot = requireGitWorkspaceRoot(cwd, "UES specialist");
1309
1515
  const browserRequested = browserEvidenceNeeded(task, role);
1310
1516
  const browserTools = browserRequested
1311
1517
  ? selectBrowserToolsForTask(HOST_BROWSER_TOOL_NAMES, task, role)
1312
1518
  : [];
1313
- const taskPolicy = classifyEngineeringTask(task);
1314
- const fastBoundedContext =
1315
- attempt === 1 &&
1316
- taskPolicy.executionProfile === "fast" &&
1317
- taskPolicy.singleFileBounded === true &&
1318
- taskPolicy.risk === "low" &&
1319
- ["executor", "verifier"].includes(role) &&
1320
- !browserRequested;
1519
+ const taskPolicy = taskPolicyOverride || classifyEngineeringTask(task);
1520
+ const turboFast = turboFastPathDecision(taskPolicy, {
1521
+ role,
1522
+ attempt,
1523
+ browserRequested,
1524
+ visualRequired: visualEvidenceNeeded(task),
1525
+ });
1526
+ const fastBoundedContext = turboFast.eligible;
1321
1527
  const budgetDecision = adaptiveContextBudget(taskPolicy, role, attempt, {
1322
1528
  disabled: !ADAPTIVE_CONTEXT_ENABLED,
1323
1529
  });
@@ -1332,7 +1538,7 @@ async function runRoutedAgent(
1332
1538
  const modelPolicy = await readModelPolicy(getUesConfigDir());
1333
1539
  const selection = resolveCapabilityModel(role, attempt, task, taskPolicy, modelPolicy);
1334
1540
  if (traceID) {
1335
- await appendTrajectoryEvent(cwd, traceID, "agent.started", {
1541
+ await appendTrajectoryEvent(traceRoot, traceID, "agent.started", {
1336
1542
  agent,
1337
1543
  role,
1338
1544
  attempt,
@@ -1397,12 +1603,17 @@ async function runRoutedAgent(
1397
1603
  : "Verify every explicit acceptance clause independently. Read the final diff/target file, then run a narrow behavioral check. Compilation or syntax alone is not proof. If any enumerated edge/error/idempotency/non-mutation case lacks fresh executable evidence, return FAIL.",
1398
1604
  ].join("\n");
1399
1605
  } else {
1606
+ const cacheBudgetKey =
1607
+ ["architect", "plan-checker"].includes(role)
1608
+ ? Number(budgetDecision.baseBudget || budgetDecision.budget)
1609
+ : budgetDecision.budget;
1400
1610
  const cacheKey = cachedContextKey(
1401
1611
  cwd,
1402
1612
  task,
1403
1613
  role,
1404
- budgetDecision.budget,
1614
+ cacheBudgetKey,
1405
1615
  workspaceFingerprint,
1616
+ contextCacheNamespace || cwd,
1406
1617
  );
1407
1618
  const cacheableContext =
1408
1619
  workspaceState.cacheable === true &&
@@ -1431,8 +1642,9 @@ async function runRoutedAgent(
1431
1642
  cwd,
1432
1643
  task,
1433
1644
  role,
1434
- budgetDecision.budget,
1645
+ cacheBudgetKey,
1435
1646
  workspaceFingerprint,
1647
+ contextCacheNamespace || cwd,
1436
1648
  );
1437
1649
  if (postBuildKey !== cacheKey) rememberContextPack(postBuildKey, pack);
1438
1650
  }
@@ -1499,6 +1711,10 @@ async function runRoutedAgent(
1499
1711
  row.stdoutPreview ? ` preview: ${cap(String(row.stdoutPreview).replace(/\s+/g, " "), 900)}` : "",
1500
1712
  ].filter(Boolean).join("\n")).join("\n")
1501
1713
  : "",
1714
+ taskPolicy.executionProfile === "deep" &&
1715
+ ["architect", "plan-checker", "executor", "debugger"].includes(role)
1716
+ ? "\n" + deepExplorationContract(role)
1717
+ : "",
1502
1718
  ].filter(Boolean).join("\n");
1503
1719
  }
1504
1720
  } catch (error) {
@@ -1525,6 +1741,11 @@ async function runRoutedAgent(
1525
1741
  ].join("\n");
1526
1742
  }
1527
1743
 
1744
+ const planningBudget = planningRuntimeBudget(role, attempt, {
1745
+ executionProfile: taskPolicy.executionProfile,
1746
+ risk: taskPolicy.risk,
1747
+ taskChars: task.length,
1748
+ });
1528
1749
  const startedAt = Date.now();
1529
1750
  const result = await runAgent(
1530
1751
  agent,
@@ -1546,13 +1767,40 @@ async function runRoutedAgent(
1546
1767
  ? 24 * 1024
1547
1768
  : 48 * 1024,
1548
1769
  verificationTimeoutSec:
1549
- taskPolicy.risk === "high"
1550
- ? 900
1551
- : taskPolicy.executionProfile === "fast"
1552
- ? 120
1553
- : taskPolicy.executionProfile === "standard"
1554
- ? 300
1555
- : 600,
1770
+ turboFast.eligible
1771
+ ? TURBO_FAST_TIMEOUTS.verificationTimeoutSec
1772
+ : taskPolicy.risk === "high"
1773
+ ? 900
1774
+ : taskPolicy.executionProfile === "fast"
1775
+ ? 120
1776
+ : taskPolicy.executionProfile === "standard"
1777
+ ? 300
1778
+ : 600,
1779
+ hardTimeoutMs:
1780
+ turboFast.eligible
1781
+ ? TURBO_FAST_TIMEOUTS.hardTimeoutMs
1782
+ : planningBudget?.hardTimeoutMs || CHILD_HARD_TIMEOUT_MS,
1783
+ absoluteHardTimeoutMs:
1784
+ turboFast.eligible
1785
+ ? TURBO_FAST_TIMEOUTS.hardTimeoutMs
1786
+ : planningBudget?.absoluteHardTimeoutMs || CHILD_HARD_TIMEOUT_MS,
1787
+ activityExtensionMs:
1788
+ turboFast.eligible ? 0 : planningBudget?.activityExtensionMs || 0,
1789
+ activityWindowMs:
1790
+ turboFast.eligible ? 0 : planningBudget?.activityWindowMs || 0,
1791
+ idleTimeoutMs:
1792
+ turboFast.eligible
1793
+ ? TURBO_FAST_TIMEOUTS.idleTimeoutMs
1794
+ : planningBudget?.idleTimeoutMs || CHILD_IDLE_TIMEOUT_MS,
1795
+ postToolErrorIdleTimeoutMs:
1796
+ turboFast.eligible
1797
+ ? TURBO_FAST_TIMEOUTS.postToolErrorIdleTimeoutMs
1798
+ : planningBudget?.idleTimeoutMs
1799
+ ? Math.min(POST_TOOL_ERROR_IDLE_TIMEOUT_MS, planningBudget.idleTimeoutMs)
1800
+ : POST_TOOL_ERROR_IDLE_TIMEOUT_MS,
1801
+ allowLocalEnvWrite:
1802
+ taskPolicy.localEnvWriteExplicitlyAllowed === true ||
1803
+ taskExplicitlyAllowsLocalEnvWrite(task),
1556
1804
  },
1557
1805
  );
1558
1806
  const enrichedResult: RunResult = {
@@ -1581,13 +1829,17 @@ async function runRoutedAgent(
1581
1829
  !["high", "critical"].includes(String(taskPolicy.risk || "").toLowerCase()),
1582
1830
  runtimeContextBudget: budgetDecision.budget,
1583
1831
  baseContextBudget: budgetDecision.baseBudget,
1832
+ turboFastPath: turboFast.eligible,
1833
+ turboFastStrategy: turboFast.strategy,
1834
+ turboFastTimeouts: turboFast.eligible ? TURBO_FAST_TIMEOUTS : null,
1835
+ planningRuntimeBudget: planningBudget,
1584
1836
  },
1585
1837
  verdict: verdictFromOutput(result.output),
1586
1838
  report: parseStructuredReport(result.output),
1587
1839
  durationMs: Date.now() - startedAt,
1588
1840
  };
1589
1841
  if (traceID) {
1590
- await appendTrajectoryEvent(cwd, traceID, "agent.completed", {
1842
+ await appendTrajectoryEvent(traceRoot, traceID, "agent.completed", {
1591
1843
  agent,
1592
1844
  role,
1593
1845
  attempt,
@@ -1683,19 +1935,64 @@ function extractMarkedJson(output: string, marker: string) {
1683
1935
  return null;
1684
1936
  }
1685
1937
 
1686
- async function sandboxChangedFiles(dir: string, base: string, signal?: AbortSignal) {
1687
- const intent = await runProcess("git", ["add", "-N", "."], dir, signal);
1688
- if (intent.exitCode !== 0) {
1689
- throw new Error(intent.stderr || intent.stdout || "git add -N failed");
1938
+ function sandboxSourceIntentBatches(values: string[]) {
1939
+ const batches: string[][] = [];
1940
+ let batch: string[] = [];
1941
+ let chars = 0;
1942
+ for (const value of sourceFacingPaths(values)) {
1943
+ const cost = value.length + 3;
1944
+ if (batch.length && (batch.length >= 64 || chars + cost > 12_000)) {
1945
+ batches.push(batch);
1946
+ batch = [];
1947
+ chars = 0;
1948
+ }
1949
+ batch.push(value);
1950
+ chars += cost;
1690
1951
  }
1691
- const diff = await runProcess("git", ["diff", "--name-only", base, "--"], dir, signal);
1952
+ if (batch.length) batches.push(batch);
1953
+ return batches;
1954
+ }
1955
+
1956
+ async function sandboxIntentToAddSourceFiles(dir: string, signal?: AbortSignal) {
1957
+ const pathspecs = sourceGitPathspecs();
1958
+ const untracked = await runProcess(
1959
+ "git",
1960
+ ["ls-files", "--others", "--exclude-standard", "-z", "--", ...pathspecs],
1961
+ dir,
1962
+ signal,
1963
+ );
1964
+ if (untracked.exitCode !== 0) {
1965
+ throw new Error(untracked.stderr || untracked.stdout || "git ls-files for intent-to-add failed");
1966
+ }
1967
+
1968
+ const candidates = sourceFacingPaths(
1969
+ untracked.stdout
1970
+ .split("\0")
1971
+ .map((value) => value.replaceAll("\\", "/"))
1972
+ .filter(Boolean),
1973
+ );
1974
+ for (const batch of sandboxSourceIntentBatches(candidates)) {
1975
+ const intent = await runProcess("git", ["add", "-N", "--", ...batch], dir, signal);
1976
+ if (intent.exitCode !== 0) {
1977
+ throw new Error(intent.stderr || intent.stdout || "git add -N failed");
1978
+ }
1979
+ }
1980
+ return candidates;
1981
+ }
1982
+
1983
+ async function sandboxChangedFiles(dir: string, base: string, signal?: AbortSignal) {
1984
+ const pathspecs = sourceGitPathspecs();
1985
+ await sandboxIntentToAddSourceFiles(dir, signal);
1986
+ const diff = await runProcess("git", ["diff", "--name-only", base, "--", ...pathspecs], dir, signal);
1692
1987
  if (diff.exitCode !== 0) {
1693
1988
  throw new Error(diff.stderr || diff.stdout || "git diff --name-only failed");
1694
1989
  }
1695
- return diff.stdout
1696
- .split(/\r?\n/)
1697
- .map((value) => value.trim().replaceAll("\\", "/"))
1698
- .filter(Boolean);
1990
+ return sourceFacingPaths(
1991
+ diff.stdout
1992
+ .split(/\r?\n/)
1993
+ .map((value) => value.trim().replaceAll("\\", "/"))
1994
+ .filter(Boolean),
1995
+ );
1699
1996
  }
1700
1997
 
1701
1998
  async function cleanupSandboxes(
@@ -1704,19 +2001,39 @@ async function cleanupSandboxes(
1704
2001
  ) {
1705
2002
  for (const item of prepared) {
1706
2003
  if (!item.sandbox?.dir) continue;
1707
- await removeTaskSandbox(root, item.sandbox.dir, {
1708
- force: true,
1709
- deleteBranch: true,
1710
- }).catch(() => {});
2004
+ const resolved = path.resolve(item.sandbox.dir);
2005
+ try {
2006
+ await removeTaskSandbox(root, resolved, {
2007
+ force: true,
2008
+ deleteBranch: true,
2009
+ });
2010
+ ACTIVE_TASK_SANDBOXES.delete(resolved);
2011
+ } catch {}
1711
2012
  }
1712
2013
  }
1713
2014
 
2015
+ async function cleanupTraceSandboxes(root: string, traceID: string) {
2016
+ const targets = [...ACTIVE_TASK_SANDBOXES.entries()]
2017
+ .filter(([, ownerTrace]) => ownerTrace === traceID)
2018
+ .map(([dir]) => dir);
2019
+ let removed = 0;
2020
+ for (const dir of targets) {
2021
+ try {
2022
+ await removeTaskSandbox(root, dir, { force: true, deleteBranch: true });
2023
+ ACTIVE_TASK_SANDBOXES.delete(dir);
2024
+ removed += 1;
2025
+ } catch {}
2026
+ }
2027
+ return removed;
2028
+ }
2029
+
1714
2030
  async function executeStructuredPlan(input: {
1715
2031
  plan: any;
1716
2032
  root: string;
1717
2033
  inheritedModel?: string;
1718
2034
  inheritedThinking?: string;
1719
2035
  maxAttempts: number;
2036
+ rootPolicy?: any;
1720
2037
  durableSlug?: string;
1721
2038
  traceID?: string;
1722
2039
  signal?: AbortSignal;
@@ -1789,6 +2106,7 @@ async function executeStructuredPlan(input: {
1789
2106
  for (let waveIndex = 0; waveIndex < safe.waves.length; waveIndex++) {
1790
2107
  const ids = safe.waves[waveIndex];
1791
2108
  let lastWaveFailure = "";
2109
+ const failureByTask = new Map<string, string>();
1792
2110
 
1793
2111
  for (let attempt = 1; attempt <= input.maxAttempts; attempt++) {
1794
2112
  const prepared: Array<{
@@ -1807,12 +2125,13 @@ async function executeStructuredPlan(input: {
1807
2125
  let cwd = input.root;
1808
2126
  let sandbox: any = undefined;
1809
2127
 
1810
- if (gitCapable) {
2128
+ if (gitCapable && writeFiles.length > 0) {
1811
2129
  const slug = "runtime-" + randomUUID().slice(0, 8) + "-w" + waveIndex + "-a" + attempt;
1812
2130
  sandbox = await createTaskSandbox(input.root, slug, id, {
1813
2131
  inheritDirtyRoot: true,
1814
2132
  });
1815
2133
  cwd = sandbox.dir;
2134
+ ACTIVE_TASK_SANDBOXES.set(path.resolve(sandbox.dir), String(input.traceID || "structured"));
1816
2135
  }
1817
2136
 
1818
2137
  prepared.push({ task, cwd, sandbox, writeFiles });
@@ -1830,22 +2149,37 @@ async function executeStructuredPlan(input: {
1830
2149
  }
1831
2150
 
1832
2151
  let completed = 0;
2152
+ const writerCount = prepared.filter((item) => item.writeFiles.length > 0).length;
2153
+ const waveConcurrency = !gitCapable
2154
+ ? 1
2155
+ : writerCount > 0
2156
+ ? Math.min(MAX_CONCURRENCY, MAX_WRITER_CONCURRENCY)
2157
+ : MAX_CONCURRENCY;
1833
2158
  const waveResults = await mapLimit(
1834
2159
  prepared,
1835
- gitCapable ? MAX_CONCURRENCY : 1,
2160
+ waveConcurrency,
1836
2161
  async (item) => {
1837
2162
  const taskText = [
1838
2163
  "Execute exactly this structured plan task.",
1839
2164
  "Do not broaden file scope. If the declared write file list is empty, do not edit files.",
2165
+ "Start with the declared files/interfaces and supplied context. Do not inventory the repository. Use targeted symbol/path search only for a concrete unresolved acceptance or dependency gap; once the safe edit is understood, implement and verify instead of continuing discovery.",
1840
2166
  "",
1841
2167
  JSON.stringify(item.task, null, 2),
1842
2168
  "",
1843
- "Overall goal:",
1844
- String(input.plan.goal || ""),
1845
- lastWaveFailure
1846
- ? "\nFresh failure evidence from the previous wave attempt:\n" + cap(lastWaveFailure, 7000)
1847
- : "",
2169
+ "Parent goal (context only; never broaden this leaf task):",
2170
+ cap(String(input.plan.goal || ""), 700),
2171
+ input.rootPolicy?.executionContractPrompt || "",
1848
2172
  ].filter(Boolean).join("\n");
2173
+ const leafPolicy = leafTaskPolicy(item.task, input.rootPolicy || {});
2174
+ const taskFailure = failureByTask.get(String(item.task.id)) || "";
2175
+ const leafVisualRequired = visualEvidenceNeeded(taskText);
2176
+ const leafFastDecision = turboFastPathDecision(leafPolicy, {
2177
+ role: "executor",
2178
+ attempt,
2179
+ browserRequested: browserEvidenceNeeded(taskText, "executor"),
2180
+ visualRequired: leafVisualRequired,
2181
+ });
2182
+ const leafAttemptStartedAt = Date.now();
1849
2183
 
1850
2184
  const plannedExecution: any = dynamicTaskByID.get(item.task.id);
1851
2185
  const deterministicReadOnly =
@@ -1978,8 +2312,8 @@ async function executeStructuredPlan(input: {
1978
2312
  "",
1979
2313
  "Overall goal:",
1980
2314
  String(input.plan.goal || ""),
1981
- lastWaveFailure
1982
- ? "\nFresh failure evidence from the previous wave attempt:\n" + cap(lastWaveFailure, 7000)
2315
+ taskFailure
2316
+ ? "\nFresh task-local failure delta from the previous attempt:\n" + cap(taskFailure, 4200)
1983
2317
  : "",
1984
2318
  ].filter(Boolean).join("\n"),
1985
2319
  item.cwd,
@@ -1990,6 +2324,8 @@ async function executeStructuredPlan(input: {
1990
2324
  input.signal,
1991
2325
  undefined,
1992
2326
  input.traceID,
2327
+ leafPolicy,
2328
+ input.root,
1993
2329
  );
1994
2330
  results.push({
1995
2331
  wave: waveIndex,
@@ -2027,8 +2363,8 @@ async function executeStructuredPlan(input: {
2027
2363
  };
2028
2364
  }
2029
2365
 
2030
- let focusedFailure = lastWaveFailure;
2031
- if (attempt > 1 && runtimeFailureNeedsDiagnosis(lastWaveFailure)) {
2366
+ let focusedFailure = taskFailure;
2367
+ if (attempt > 1 && runtimeFailureNeedsDiagnosis(taskFailure)) {
2032
2368
  const diagnosis = await runRoutedAgent(
2033
2369
  "ues-debugger",
2034
2370
  [
@@ -2038,16 +2374,18 @@ async function executeStructuredPlan(input: {
2038
2374
  JSON.stringify(item.task, null, 2),
2039
2375
  "",
2040
2376
  "Previous runtime failure:",
2041
- cap(lastWaveFailure, 7000),
2377
+ cap(taskFailure, 4200),
2042
2378
  ].join("\n"),
2043
2379
  item.cwd,
2044
2380
  input.inheritedModel,
2045
2381
  input.inheritedThinking,
2046
2382
  attempt,
2047
- lastWaveFailure,
2383
+ taskFailure,
2048
2384
  input.signal,
2049
2385
  undefined,
2050
2386
  input.traceID,
2387
+ leafPolicy,
2388
+ input.root,
2051
2389
  );
2052
2390
  results.push({
2053
2391
  wave: waveIndex,
@@ -2070,16 +2408,15 @@ async function executeStructuredPlan(input: {
2070
2408
  }
2071
2409
  }
2072
2410
 
2411
+ const retryDelta = failureDelta(focusedFailure || taskFailure);
2073
2412
  const implementation = await runRoutedAgent(
2074
2413
  "ues-executor",
2075
- taskText + (focusedFailure && focusedFailure !== lastWaveFailure
2076
- ? "\n\nFocused diagnosis before retry:\n" + cap(focusedFailure, 7000)
2077
- : ""),
2414
+ taskText,
2078
2415
  item.cwd,
2079
2416
  input.inheritedModel,
2080
2417
  input.inheritedThinking,
2081
2418
  attempt,
2082
- lastWaveFailure || undefined,
2419
+ retryDelta || undefined,
2083
2420
  input.signal,
2084
2421
  (progress) => {
2085
2422
  input.onUpdate?.({
@@ -2093,8 +2430,10 @@ async function executeStructuredPlan(input: {
2093
2430
  });
2094
2431
  },
2095
2432
  input.traceID,
2433
+ leafPolicy,
2434
+ input.root,
2096
2435
  );
2097
- results.push({ wave: waveIndex, attempt, task: item.task.id, phase: "execute", ...implementation });
2436
+ results.push({ wave: waveIndex, attempt, task: item.task.id, phase: "execute", leafPolicy, ...implementation });
2098
2437
 
2099
2438
  if (implementation.exitCode !== 0 || implementation.stopReason === "error") {
2100
2439
  if (!isAbortedRun(implementation)) {
@@ -2114,7 +2453,75 @@ async function executeStructuredPlan(input: {
2114
2453
  };
2115
2454
  }
2116
2455
 
2117
- const verification = await runRoutedAgent(
2456
+ let verification: RunResult;
2457
+ let leafFastGate: any = null;
2458
+ if (leafFastDecision.eligible) {
2459
+ const snapshot = runtimeWorkspaceSnapshot(item.cwd);
2460
+ const receipts = await listReusableVerification(item.cwd, {
2461
+ limit: 12,
2462
+ maxAgeMs: 10 * 60_000,
2463
+ previewBytes: 2200,
2464
+ ...(snapshot.cacheable === true && snapshot.fingerprint
2465
+ ? { workspaceFingerprint: snapshot.fingerprint }
2466
+ : {}),
2467
+ }).catch(() => ({ results: [] }));
2468
+ leafFastGate = evaluateFastVerificationGate({
2469
+ policy: leafPolicy,
2470
+ implementation,
2471
+ receipts: receipts?.results || [],
2472
+ attemptStartedAtMs: leafAttemptStartedAt,
2473
+ visualRequired: leafVisualRequired,
2474
+ });
2475
+ }
2476
+
2477
+ if (leafFastGate?.passed === true) {
2478
+ verification = {
2479
+ agent: "ues-deterministic-verifier",
2480
+ task: taskText,
2481
+ cwd: item.cwd,
2482
+ exitCode: 0,
2483
+ output: [
2484
+ "Per-leaf Turbo verification reused fresh behavioral evidence captured after this leaf implementation.",
2485
+ ...leafFastGate.behavioralReceipts.map((entry: any) => "- " + entry.command),
2486
+ "",
2487
+ "UES_VERDICT: PASS",
2488
+ ].join("\n"),
2489
+ stderr: "",
2490
+ verdict: "PASS",
2491
+ durationMs: 0,
2492
+ toolCalls: 0,
2493
+ toolNames: [],
2494
+ report: {
2495
+ schemaVersion: 1,
2496
+ valid: true,
2497
+ verdict: "PASS",
2498
+ sections: {
2499
+ "checks-run": leafFastGate.behavioralReceipts.map((entry: any) => entry.command).join("\n"),
2500
+ "acceptance-criteria-proven": "Fresh behavioral receipt(s) exist at the post-implementation workspace fingerprint.",
2501
+ "completion-evidence": "Deterministic per-leaf PASS after this implementation attempt.",
2502
+ },
2503
+ },
2504
+ optimizations: {
2505
+ perLeafTurbo: true,
2506
+ behavioralReceiptCount: leafFastGate.behavioralReceipts.length,
2507
+ },
2508
+ };
2509
+ input.onUpdate?.({
2510
+ content: [{
2511
+ type: "text",
2512
+ text: `UES Per-Leaf Turbo: ${item.task.id} reused ${leafFastGate.behavioralReceipts.length} fresh behavioral receipt(s); skipped verifier model turn`,
2513
+ }],
2514
+ details: {
2515
+ wave: waveIndex,
2516
+ attempt,
2517
+ task: item.task.id,
2518
+ phase: "leaf-turbo-verified",
2519
+ leafPolicy,
2520
+ leafFastGate,
2521
+ },
2522
+ });
2523
+ } else {
2524
+ verification = await runRoutedAgent(
2118
2525
  "ues-verifier",
2119
2526
  [
2120
2527
  "Verify exactly this structured plan task in the current isolated worktree.",
@@ -2141,8 +2548,11 @@ async function executeStructuredPlan(input: {
2141
2548
  });
2142
2549
  },
2143
2550
  input.traceID,
2551
+ leafPolicy,
2552
+ input.root,
2144
2553
  );
2145
- results.push({ wave: waveIndex, attempt, task: item.task.id, phase: "verify", ...verification });
2554
+ }
2555
+ results.push({ wave: waveIndex, attempt, task: item.task.id, phase: "verify", leafPolicy, leafFastGate, ...verification });
2146
2556
  const passed = verification.exitCode === 0 && verification.verdict === "PASS";
2147
2557
  if (!isAbortedRun(verification)) {
2148
2558
  await recordRuntimeOutcome(implementation, taskText, passed, attempt - 1);
@@ -2188,8 +2598,12 @@ async function executeStructuredPlan(input: {
2188
2598
 
2189
2599
  const failed = waveResults.filter((item) => !item.passed);
2190
2600
  if (failed.length) {
2601
+ for (const row of failed) {
2602
+ const rawFailure = row.verification?.output || row.implementation?.output || "unknown failure";
2603
+ failureByTask.set(String(row.item?.task?.id || "unknown"), failureDelta(rawFailure));
2604
+ }
2191
2605
  lastWaveFailure = failed
2192
- .map((item) => item.verification?.output || item.implementation?.output || "unknown failure")
2606
+ .map((item) => failureByTask.get(String(item.item?.task?.id || "unknown")) || "unknown failure")
2193
2607
  .join("\n\n---\n\n");
2194
2608
  await failDurablePrepared(prepared, lastWaveFailure);
2195
2609
  await cleanupSandboxes(input.root, prepared);
@@ -2207,9 +2621,9 @@ async function executeStructuredPlan(input: {
2207
2621
  };
2208
2622
  }
2209
2623
 
2210
- if (!gitCapable) {
2211
- // Without Git worktrees the safe graph is still serialized. Verification above
2212
- // is the evidence gate; changes already exist in the root working directory.
2624
+ if (!gitCapable || prepared.every((item) => !item.sandbox?.dir)) {
2625
+ // Read-only waves do not need a duplicate Git worktree. Their fresh
2626
+ // verifier evidence is enough as long as the workspace stays unchanged.
2213
2627
  await completeDurableWave(waveResults);
2214
2628
  break;
2215
2629
  }
@@ -2217,13 +2631,21 @@ async function executeStructuredPlan(input: {
2217
2631
  const actualByTask = new Map<string, string[]>();
2218
2632
  let scopeFailure = "";
2219
2633
  for (const item of prepared) {
2634
+ if (!item.sandbox?.dir) {
2635
+ actualByTask.set(item.task.id, []);
2636
+ continue;
2637
+ }
2220
2638
  const changed = await sandboxChangedFiles(item.sandbox.dir, item.sandbox.integrationBase, input.signal);
2221
2639
  actualByTask.set(item.task.id, changed);
2222
2640
  const allowed = new Set(item.writeFiles);
2223
2641
  const unexpected = changed.filter((file) => !allowed.has(file));
2224
2642
  if (unexpected.length) {
2225
- scopeFailure +=
2226
- `${item.task.id}: changed files outside declared write scope: ${unexpected.join(", ")}\n`;
2643
+ const scopeMessage =
2644
+ `${item.task.id}: changed real source files outside declared write scope: ${unexpected.join(", ")}. ` +
2645
+ "On retry, revert or avoid these files and satisfy the task strictly within its declared write scope. " +
2646
+ "Do not silently broaden scope.";
2647
+ failureByTask.set(String(item.task.id), failureDelta(scopeMessage, { maxChars: 2200 }));
2648
+ scopeFailure += scopeMessage + "\n";
2227
2649
  }
2228
2650
  }
2229
2651
 
@@ -2232,7 +2654,12 @@ async function executeStructuredPlan(input: {
2232
2654
  for (const file of changed) {
2233
2655
  const previous = changedOwners.get(file);
2234
2656
  if (previous && previous !== taskID) {
2235
- scopeFailure += `wave conflict: ${previous} and ${taskID} both changed ${file}\n`;
2657
+ const conflictMessage = `wave conflict: ${previous} and ${taskID} both changed real source file ${file}`;
2658
+ const previousFailure = failureByTask.get(previous) || "";
2659
+ const currentFailure = failureByTask.get(taskID) || "";
2660
+ failureByTask.set(previous, failureDelta([previousFailure, conflictMessage].filter(Boolean).join("\n"), { maxChars: 2200 }));
2661
+ failureByTask.set(taskID, failureDelta([currentFailure, conflictMessage].filter(Boolean).join("\n"), { maxChars: 2200 }));
2662
+ scopeFailure += conflictMessage + "\n";
2236
2663
  } else {
2237
2664
  changedOwners.set(file, taskID);
2238
2665
  }
@@ -2260,6 +2687,7 @@ async function executeStructuredPlan(input: {
2260
2687
  const integrated: Array<{ item: any; receipt: any }> = [];
2261
2688
  try {
2262
2689
  for (const item of prepared) {
2690
+ if (!item.sandbox?.dir) continue;
2263
2691
  const receipt = await integrateTaskSandbox(input.root, item.sandbox.dir, { keep: true });
2264
2692
  integrated.push({ item, receipt });
2265
2693
  integrations.push({ wave: waveIndex, task: item.task.id, ...receipt });
@@ -2379,7 +2807,52 @@ export default function (pi: ExtensionAPI) {
2379
2807
  // controller inside specialist workers.
2380
2808
  if (process.env.UES_CHILD_PROCESS === "1") return;
2381
2809
 
2810
+ let directControllerAbort: AbortController | null = null;
2811
+ let promptUesActive = false;
2812
+ let directControllerRunner: ((task: string, ctx: any, admission: "command" | "automatic", admissionDecision?: any) => Promise<void>) | null = null;
2813
+ const AUTO_ADMISSION_ENABLED = !["0", "false", "off"].includes(
2814
+ String(process.env.UES_AUTO_ADMIT || "1").trim().toLowerCase(),
2815
+ );
2816
+ const UES_PARENT_TOOL_NAMES = new Set(["ues_cli", "ues_execute", "ues_service", "ues_dispatch"]);
2817
+ let normalActiveTools: string[] | null = null;
2818
+
2819
+ const currentNonUesTools = () =>
2820
+ pi.getActiveTools().filter((name) => !UES_PARENT_TOOL_NAMES.has(String(name)));
2821
+
2822
+ const deactivateParentUesTools = () => {
2823
+ const normal = currentNonUesTools();
2824
+ normalActiveTools = normal;
2825
+ try { pi.setActiveTools(normal); } catch {}
2826
+ };
2827
+
2828
+ const activateParentUesTools = () => {
2829
+ const normal = normalActiveTools || currentNonUesTools();
2830
+ const registered = new Set(
2831
+ (typeof (pi as any).getAllTools === "function" ? (pi as any).getAllTools() : [])
2832
+ .map((tool: any) => String(tool?.name || "")),
2833
+ );
2834
+ const uesTools = [...UES_PARENT_TOOL_NAMES].filter((name) => registered.has(name));
2835
+ try { pi.setActiveTools([...new Set([...normal, ...uesTools])]); } catch {}
2836
+ };
2837
+
2838
+ const uesModeActive = () =>
2839
+ promptUesActive || Boolean(directControllerAbort && !directControllerAbort.signal.aborted);
2840
+
2841
+ const syncSessionIdentity = (name: string, ctx: any) => {
2842
+ if (!name) return;
2843
+ try { pi.setSessionName(name); } catch {}
2844
+ try { ctx?.ui?.setTitle?.(name); } catch {}
2845
+ };
2846
+
2847
+ pi.on("session_start", async () => {
2848
+ deactivateParentUesTools();
2849
+ });
2850
+
2382
2851
  pi.on("session_shutdown", async () => {
2852
+ directControllerAbort?.abort();
2853
+ directControllerAbort = null;
2854
+ promptUesActive = false;
2855
+ normalActiveTools = null;
2383
2856
  CONTEXT_PACK_CACHE.clear();
2384
2857
  clearSkillCompilerCache();
2385
2858
  clearAffectedTestCache();
@@ -2387,29 +2860,44 @@ export default function (pi: ExtensionAPI) {
2387
2860
  clearSemanticIndexRuntimeCache();
2388
2861
  MCP_HEALTH.clear();
2389
2862
  abortActiveCliChildren();
2863
+ await stopAllServices().catch(() => []);
2390
2864
  await RPC_POOL.stopAll().catch(() => {});
2865
+ for (const dir of [...ACTIVE_TASK_SANDBOXES.keys()]) {
2866
+ const ownerRoot = await taskSandboxOwnerRoot(dir).catch(() => null);
2867
+ if (!ownerRoot) continue;
2868
+ await removeTaskSandbox(ownerRoot, dir, { force: true, deleteBranch: true }).catch(() => {});
2869
+ ACTIVE_TASK_SANDBOXES.delete(dir);
2870
+ }
2391
2871
  });
2392
2872
 
2393
2873
  pi.on("input", async (event, ctx) => {
2394
2874
  if (process.env.UES_CHILD_PROCESS === "1") return { action: "continue" };
2395
- if (
2396
- event.source !== "interactive" ||
2397
- !["steer", "followUp"].includes(String(event.streamingBehavior || ""))
2398
- ) {
2399
- return { action: "continue" };
2400
- }
2875
+ if (event.source !== "interactive") return { action: "continue" };
2401
2876
 
2402
2877
  const text = String(event.text || "").trim();
2403
2878
  if (!text) return { action: "continue" };
2404
2879
 
2880
+ const sessionName = sessionNameFromUesInput(text, ctx.cwd || "");
2881
+ if (sessionName) syncSessionIdentity(sessionName, ctx);
2882
+ if (/^\/ues-(?:resume|fix|feature|debug|review|audit|plan|research|critique|verify)(?:\s|$)/i.test(text)) {
2883
+ promptUesActive = true;
2884
+ activateParentUesTools();
2885
+ }
2886
+
2405
2887
  if (/^(?:stop|cancel|abort|dừng|dung|hủy|huy)(?:\s|$)/i.test(text)) {
2888
+ if (!uesModeActive()) return { action: "continue" };
2889
+ let directAborted = 0;
2890
+ if (directControllerAbort && !directControllerAbort.signal.aborted) {
2891
+ directControllerAbort.abort();
2892
+ directAborted = 1;
2893
+ }
2406
2894
  const result = await RPC_POOL.abortActive();
2407
2895
  const cliAborted = abortActiveCliChildren();
2408
- const total = result.aborted + cliAborted;
2896
+ const total = directAborted + result.aborted + cliAborted;
2409
2897
  if (total > 0) {
2410
2898
  try {
2411
2899
  ctx.ui.notify(
2412
- `UES: aborted ${total} active child worker(s)` +
2900
+ `UES: aborted ${total} active controller/child worker(s)` +
2413
2901
  (cliAborted ? ` (${cliAborted} CLI fallback)` : ""),
2414
2902
  "warning",
2415
2903
  );
@@ -2419,6 +2907,65 @@ export default function (pi: ExtensionAPI) {
2419
2907
  return { action: "continue" };
2420
2908
  }
2421
2909
 
2910
+ if (!["steer", "followUp"].includes(String(event.streamingBehavior || ""))) {
2911
+ if (directControllerAbort && !directControllerAbort.signal.aborted) {
2912
+ const continuation = automaticUesContinuation(text, { activeRun: true });
2913
+ if (continuation.forward) {
2914
+ const forwarded = await RPC_POOL.steerActive(text).catch(() => ({
2915
+ accepted: false,
2916
+ reason: "steer-failed",
2917
+ active: 0,
2918
+ }));
2919
+ if (forwarded.accepted) {
2920
+ try { ctx.ui.notify("UES: natural continuation forwarded to the active child", "info"); } catch {}
2921
+ return { action: "handled" };
2922
+ }
2923
+ try {
2924
+ ctx.ui.notify(
2925
+ "UES is already running; continuation could not be targeted safely, so the prompt was not swallowed.",
2926
+ "warning",
2927
+ );
2928
+ } catch {}
2929
+ }
2930
+ return { action: "continue" };
2931
+ }
2932
+
2933
+ if (
2934
+ AUTO_ADMISSION_ENABLED &&
2935
+ directControllerRunner &&
2936
+ !(Array.isArray((event as any).images) && (event as any).images.length > 0)
2937
+ ) {
2938
+ const preliminaryAdmission = automaticUesAdmission(text);
2939
+ const workspaceRoot = preliminaryAdmission.admit === true
2940
+ ? resolveGitWorkspaceRoot(ctx.cwd || "")
2941
+ : null;
2942
+ const admission = workspaceRoot
2943
+ ? automaticUesAdmission(text, { inGitWorkspace: true })
2944
+ : preliminaryAdmission;
2945
+ if (workspaceRoot && admission.admit === true) {
2946
+ try {
2947
+ ctx.ui.notify(
2948
+ "UES " + PACKAGE_VERSION + ": " +
2949
+ (admission.route === "guarded" ? "high-risk engineering task admitted" : "engineering task auto-admitted") +
2950
+ " (" + admission.reason + ", confidence " + admission.confidence + ")",
2951
+ admission.route === "guarded" ? "warning" : "info",
2952
+ );
2953
+ } catch {}
2954
+ void directControllerRunner(text, ctx, "automatic", admission).catch((error) => {
2955
+ try {
2956
+ ctx.ui.notify(
2957
+ "UES automatic controller failed to start: " +
2958
+ (error instanceof Error ? error.message : String(error)),
2959
+ "error",
2960
+ );
2961
+ } catch {}
2962
+ });
2963
+ return { action: "handled" };
2964
+ }
2965
+ }
2966
+ return { action: "continue" };
2967
+ }
2968
+
2422
2969
  const steered = await RPC_POOL.steerActive(text).catch(() => ({
2423
2970
  accepted: false,
2424
2971
  reason: "steer-failed",
@@ -2434,8 +2981,27 @@ export default function (pi: ExtensionAPI) {
2434
2981
  return { action: "continue" };
2435
2982
  });
2436
2983
 
2984
+ pi.on("before_agent_start", async () => {
2985
+ if (uesModeActive()) activateParentUesTools();
2986
+ else deactivateParentUesTools();
2987
+ });
2988
+
2989
+ pi.on("agent_end", async () => {
2990
+ promptUesActive = false;
2991
+ deactivateParentUesTools();
2992
+ });
2993
+
2437
2994
  pi.on("tool_call", async (event, ctx) => {
2438
2995
  const toolName = String(event.toolName || "");
2996
+ if (!uesModeActive()) {
2997
+ if (toolName.startsWith("ues_")) {
2998
+ return {
2999
+ block: true,
3000
+ reason: "UES parent tools are hidden outside admitted UES runs. Submit a normal engineering task or start an explicit /ues-* command.",
3001
+ };
3002
+ }
3003
+ return undefined;
3004
+ }
2439
3005
  if (toolName !== "bash" && toolName !== "powershell") {
2440
3006
  const allTools = typeof (pi as any).getAllTools === "function" ? (pi as any).getAllTools() : [];
2441
3007
  const descriptor = allTools.find((tool: any) => String(tool?.name || "") === toolName);
@@ -2449,6 +3015,14 @@ export default function (pi: ExtensionAPI) {
2449
3015
  }
2450
3016
 
2451
3017
  const command = String((event.input as any)?.command || "");
3018
+ if (looksLikeLongRunningServiceCommand(command)) {
3019
+ return {
3020
+ block: true,
3021
+ reason:
3022
+ "UES detected a likely long-running foreground service command. " +
3023
+ "Use ues_service start/wait-ready/logs/stop so Pi can continue without blocking on the server process.",
3024
+ };
3025
+ }
2452
3026
  const risk = destructiveShellRisk(command);
2453
3027
  if (!risk.risky) return undefined;
2454
3028
  const allowed = await approveRisk(ctx, command, risk.id || "destructive");
@@ -2457,6 +3031,7 @@ export default function (pi: ExtensionAPI) {
2457
3031
  });
2458
3032
 
2459
3033
  pi.on("tool_result", async (event) => {
3034
+ if (!uesModeActive()) return undefined;
2460
3035
  const toolName = String((event as any).toolName || "");
2461
3036
  if (!toolName || toolName === "bash" || toolName === "powershell") return undefined;
2462
3037
  MCP_HEALTH.finish(
@@ -2479,7 +3054,7 @@ export default function (pi: ExtensionAPI) {
2479
3054
  cwd: Type.Optional(Type.String({ description: "Working directory; defaults to the current Pi cwd" })),
2480
3055
  }),
2481
3056
  async execute(_toolCallId, params, signal, _onUpdate, ctx) {
2482
- const cwd = path.resolve(params.cwd || ctx.cwd);
3057
+ const cwd = requireGitWorkspaceRoot(params.cwd || ctx.cwd, "ues_cli");
2483
3058
  const separator = params.args.indexOf("--");
2484
3059
  if (separator >= 0 && separator < params.args.length - 1) {
2485
3060
  const command = params.args.slice(separator + 1).join(" ");
@@ -2538,6 +3113,91 @@ export default function (pi: ExtensionAPI) {
2538
3113
  });
2539
3114
 
2540
3115
  pi.registerTool({
3116
+ name: "ues_service",
3117
+ label: "UES Managed Service",
3118
+ description:
3119
+ "Start and manage long-running dev servers/watchers without blocking Pi. Uses shell-free execution, bounded logs, readiness probes, evidence snapshots, and session cleanup. For start/restart, command is the executable only (for example node or npm); put every argument in args.",
3120
+ parameters: Type.Object({
3121
+ action: Type.Union([
3122
+ Type.Literal("start"),
3123
+ Type.Literal("wait-ready"),
3124
+ Type.Literal("status"),
3125
+ Type.Literal("logs"),
3126
+ Type.Literal("stop"),
3127
+ Type.Literal("restart"),
3128
+ ]),
3129
+ name: Type.String({ minLength: 1, maxLength: 64 }),
3130
+ command: Type.Optional(Type.String({ minLength: 1 })),
3131
+ args: Type.Optional(Type.Array(Type.String(), { maxItems: 128 })),
3132
+ cwd: Type.Optional(Type.String()),
3133
+ readyPort: Type.Optional(Type.Number({ minimum: 1, maximum: 65535 })),
3134
+ readyHost: Type.Optional(Type.String({ maxLength: 255 })),
3135
+ readyLog: Type.Optional(Type.String({ maxLength: 512 })),
3136
+ timeoutMs: Type.Optional(Type.Number({ minimum: 100, maximum: 600000 })),
3137
+ lifetimeMs: Type.Optional(Type.Number({ minimum: 10000, maximum: 7200000 })),
3138
+ idleTimeoutMs: Type.Optional(Type.Number({ minimum: 5000, maximum: 3600000 })),
3139
+ maxChars: Type.Optional(Type.Number({ minimum: 256, maximum: 128000 })),
3140
+ }),
3141
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
3142
+ try {
3143
+ const hostCwd = path.resolve(ctx.cwd);
3144
+ const serviceRoot = requireGitWorkspaceRoot(hostCwd, "ues_service");
3145
+ const requestedServiceCwd = params.cwd
3146
+ ? path.relative(serviceRoot, path.resolve(hostCwd, params.cwd)) || "."
3147
+ : path.relative(serviceRoot, hostCwd) || ".";
3148
+ let result: any;
3149
+ if (params.action === "start") {
3150
+ if (!params.command) throw new Error("ues_service start requires command");
3151
+ const riskText = [params.command, ...(params.args || [])].join(" ");
3152
+ const risk = destructiveShellRisk(riskText);
3153
+ if (risk.risky) throw new Error(`UES service safety blocked ${risk.id || "destructive"} command`);
3154
+ result = await startService(serviceRoot, {
3155
+ name: params.name,
3156
+ command: params.command,
3157
+ args: params.args || [],
3158
+ cwd: requestedServiceCwd,
3159
+ readyPort: params.readyPort,
3160
+ readyHost: params.readyHost,
3161
+ readyLog: params.readyLog,
3162
+ timeoutMs: params.timeoutMs,
3163
+ lifetimeMs: params.lifetimeMs,
3164
+ idleTimeoutMs: params.idleTimeoutMs,
3165
+ });
3166
+ } else if (params.action === "wait-ready") {
3167
+ result = await waitForService(serviceRoot, params.name, { timeoutMs: params.timeoutMs });
3168
+ } else if (params.action === "status") {
3169
+ result = await serviceStatus(serviceRoot, params.name);
3170
+ } else if (params.action === "logs") {
3171
+ result = await serviceLogs(serviceRoot, params.name, { maxChars: params.maxChars, evidence: true });
3172
+ } else if (params.action === "stop") {
3173
+ result = await stopService(serviceRoot, params.name, { timeoutMs: params.timeoutMs });
3174
+ } else if (params.action === "restart") {
3175
+ result = await restartService(serviceRoot, params.name, {
3176
+ timeoutMs: params.timeoutMs,
3177
+ lifetimeMs: params.lifetimeMs,
3178
+ idleTimeoutMs: params.idleTimeoutMs,
3179
+ });
3180
+ } else {
3181
+ throw new Error("Unknown ues_service action");
3182
+ }
3183
+ const failed =
3184
+ (params.action === "start" || params.action === "wait-ready") && result?.ready !== true;
3185
+ return {
3186
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
3187
+ details: result,
3188
+ isError: failed,
3189
+ };
3190
+ } catch (error) {
3191
+ return {
3192
+ content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
3193
+ details: { action: params.action, name: params.name },
3194
+ isError: true,
3195
+ };
3196
+ }
3197
+ },
3198
+ });
3199
+
3200
+ const uesExecuteTool: any = {
2541
3201
  name: "ues_execute",
2542
3202
  label: "UES Execute",
2543
3203
  description:
@@ -2549,16 +3209,55 @@ export default function (pi: ExtensionAPI) {
2549
3209
  }),
2550
3210
  async execute(_toolCallId, params, signal, onUpdate, ctx) {
2551
3211
  const hostBrowserTools = refreshHostBrowserToolNames(pi);
2552
- const cwd = path.resolve(params.cwd || ctx.cwd);
3212
+ const cwd = requireGitWorkspaceRoot(params.cwd || ctx.cwd, "ues_execute");
2553
3213
  const inheritedModel = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined;
2554
3214
  const inheritedThinking = ctx.thinkingLevel as string | undefined;
2555
- const policy = classifyEngineeringTask(params.task);
2556
- const traceID = createTraceID("ues-execute");
3215
+ const inheritedDirty = captureInheritedDirtyState(cwd);
3216
+ const executionContract = buildExecutionContract(params.task, inheritedDirty);
3217
+ const contractPrompt = executionContractPrompt(executionContract);
3218
+ const suppliedPolicy = (params as any).__taskPolicy;
3219
+ const basePolicy =
3220
+ suppliedPolicy && typeof suppliedPolicy === "object"
3221
+ ? suppliedPolicy
3222
+ : classifyEngineeringTask(params.task);
3223
+ const policy = {
3224
+ ...basePolicy,
3225
+ localEnvWriteExplicitlyAllowed: executionContract.localEnvWriteExplicitlyAllowed === true,
3226
+ executionContractPrompt: contractPrompt,
3227
+ };
3228
+ const traceID = String((params as any).__traceID || createTraceID("ues-execute"));
3229
+ const orphanCleanup = await pruneOrphanTaskSandboxes(cwd, {
3230
+ minAgeMs: 5 * 60_000,
3231
+ legacyMinAgeMs: 30 * 60_000,
3232
+ ownedMinAgeMs: 60_000,
3233
+ reclaimOwnerPid: process.pid,
3234
+ protectedDirs: [...ACTIVE_TASK_SANDBOXES.keys()],
3235
+ }).catch(() => ({ removed: [], skipped: [], sidecarsRemoved: [] }));
3236
+ if (orphanCleanup.removed?.length) {
3237
+ onUpdate?.({
3238
+ content: [{ type: "text", text: `UES sandbox cleanup: removed ${orphanCleanup.removed.length} orphan worktree(s)` }],
3239
+ details: { mode: "execute", phase: "sandbox-cleanup", orphanCleanup },
3240
+ });
3241
+ }
2557
3242
  await appendTrajectoryEvent(cwd, traceID, "controller.started", {
2558
3243
  profile: policy.executionProfile,
2559
3244
  risk: policy.risk,
2560
3245
  mode: policy.mode,
3246
+ inheritedDirtyCount: executionContract.inheritedDirty?.paths?.length || 0,
3247
+ explicitPhaseCount: executionContract.phases?.length || 0,
3248
+ localEnvWriteExplicitlyAllowed: executionContract.localEnvWriteExplicitlyAllowed === true,
2561
3249
  }).catch(() => {});
3250
+ if ((executionContract.inheritedDirty?.paths?.length || 0) > 0 || (executionContract.phases?.length || 0) > 0) {
3251
+ onUpdate?.({
3252
+ content: [{
3253
+ type: "text",
3254
+ text:
3255
+ `UES contract: inherited dirty ${executionContract.inheritedDirty?.paths?.length || 0}; ` +
3256
+ `explicit phases ${executionContract.phases?.length || 0}; local .env write ${executionContract.localEnvWriteExplicitlyAllowed ? "authorized" : "blocked"}`,
3257
+ }],
3258
+ details: { mode: "execute", phase: "execution-contract", executionContract, traceID },
3259
+ });
3260
+ }
2562
3261
  const browserLaneRequested =
2563
3262
  browserEvidenceNeeded(params.task, "executor") || visualEvidenceNeeded(params.task);
2564
3263
  if (browserLaneRequested) {
@@ -2603,9 +3302,16 @@ export default function (pi: ExtensionAPI) {
2603
3302
  });
2604
3303
 
2605
3304
  const run = async (agent: AgentName, task: string, attempt = 1, failure?: string) => {
3305
+ const planningBudget = planningRuntimeBudget(roleForAgent(agent), attempt, {
3306
+ executionProfile: policy.executionProfile,
3307
+ risk: policy.risk,
3308
+ taskChars: task.length,
3309
+ });
3310
+ let softSteerSent = false;
3311
+ const governedTask = [task, "", contractPrompt].filter(Boolean).join("\n");
2606
3312
  const result = await runRoutedAgent(
2607
3313
  agent,
2608
- task,
3314
+ governedTask,
2609
3315
  cwd,
2610
3316
  inheritedModel,
2611
3317
  inheritedThinking,
@@ -2613,6 +3319,30 @@ export default function (pi: ExtensionAPI) {
2613
3319
  failure,
2614
3320
  signal,
2615
3321
  (progress) => {
3322
+ if (
3323
+ !softSteerSent &&
3324
+ (
3325
+ (agent === "ues-architect" && shouldSoftSteerArchitect(progress, planningBudget)) ||
3326
+ (agent === "ues-plan-checker" && shouldSoftSteerPlanningRole(progress, planningBudget))
3327
+ )
3328
+ ) {
3329
+ softSteerSent = true;
3330
+ const steerText =
3331
+ agent === "ues-architect"
3332
+ ? "Stop repository exploration now. Use the evidence already gathered and emit the required UES_PLAN_JSON object immediately as the next substantive output. Do not start new broad searches or delay the JSON behind prose."
3333
+ : "Stop broad validation now. Check only unresolved declared paths and dependencies, then return the verdict immediately. End with exactly UES_VERDICT: PASS or UES_VERDICT: REVISE.";
3334
+ void RPC_POOL.steerActive(steerText).catch(() => ({ accepted: false }));
3335
+ onUpdate?.({
3336
+ content: [{
3337
+ type: "text",
3338
+ text:
3339
+ agent === "ues-architect"
3340
+ ? "UES planning fast-stop: architect evidence budget reached; requesting immediate plan emission"
3341
+ : "UES planning fast-stop: plan-checker budget reached; requesting immediate verdict",
3342
+ }],
3343
+ details: { mode: "execute", phase: "planning-soft-steer", policy, progress, planningBudget, traceID },
3344
+ });
3345
+ }
2616
3346
  onUpdate?.({
2617
3347
  content: [{
2618
3348
  type: "text",
@@ -2627,6 +3357,7 @@ export default function (pi: ExtensionAPI) {
2627
3357
  });
2628
3358
  },
2629
3359
  traceID,
3360
+ policy,
2630
3361
  );
2631
3362
  steps.push(result);
2632
3363
  onUpdate?.({
@@ -2639,6 +3370,176 @@ export default function (pi: ExtensionAPI) {
2639
3370
  return result;
2640
3371
  };
2641
3372
 
3373
+ if (policy.readOnly === true) {
3374
+ const before = runtimeWorkspaceSnapshot(cwd);
3375
+ const deterministicChecks = deterministicReadOnlyGitCommands(params.task);
3376
+ let inspection: any;
3377
+
3378
+ if (deterministicChecks.length > 0) {
3379
+ const rows: any[] = [];
3380
+ for (const spec of deterministicChecks) {
3381
+ const result = await runProcess(spec.command, spec.args, cwd, signal);
3382
+ if (result.exitCode === 130 || result.stopReason === "aborted") {
3383
+ const aborted: any = {
3384
+ agent: "ues-deterministic-read-only",
3385
+ task: params.task,
3386
+ cwd,
3387
+ exitCode: 130,
3388
+ output: "Deterministic read-only command aborted: " + spec.label,
3389
+ stderr: result.stderr || "",
3390
+ verdict: null,
3391
+ durationMs: result.durationMs || 0,
3392
+ toolCalls: 0,
3393
+ toolNames: [],
3394
+ report: parseStructuredReport(""),
3395
+ stopReason: "aborted",
3396
+ };
3397
+ steps.push(aborted);
3398
+ return abortedResponse(aborted, "read-only-deterministic-check");
3399
+ }
3400
+ rows.push({
3401
+ ...spec,
3402
+ exitCode: result.exitCode,
3403
+ stdout: cap(result.stdout || "", 8000),
3404
+ stderr: cap(result.stderr || "", 4000),
3405
+ });
3406
+ }
3407
+
3408
+ const afterChecks = runtimeWorkspaceSnapshot(cwd);
3409
+ const unchangedAfterChecks =
3410
+ before.cacheable === true &&
3411
+ afterChecks.cacheable === true &&
3412
+ before.fingerprint === afterChecks.fingerprint;
3413
+ const failedRows = rows.filter((row) => Number(row.exitCode) !== 0);
3414
+ const deterministicPass = failedRows.length === 0 && unchangedAfterChecks;
3415
+ const checksText = rows.map((row) => {
3416
+ const payload = [row.stdout, row.stderr].filter(Boolean).join("\n").trim() || "(no output)";
3417
+ return [
3418
+ row.label + " — exit " + row.exitCode,
3419
+ payload,
3420
+ ].join("\n");
3421
+ }).join("\n\n");
3422
+ const failureText = [
3423
+ ...failedRows.map((row) => row.label + " exited " + row.exitCode),
3424
+ ...(unchangedAfterChecks ? [] : ["read-only workspace fingerprint changed"]),
3425
+ ].join("\n") || "None.";
3426
+
3427
+ const output = [
3428
+ "## Checks run",
3429
+ checksText,
3430
+ "",
3431
+ "## Acceptance criteria proven",
3432
+ deterministicPass
3433
+ ? "All explicitly requested whitelisted Git inspection commands completed successfully."
3434
+ : "The requested deterministic inspection did not fully pass.",
3435
+ "",
3436
+ "## Failures",
3437
+ failureText,
3438
+ "",
3439
+ "## Unresolved gaps",
3440
+ "None.",
3441
+ "",
3442
+ "## Checks not run",
3443
+ "None.",
3444
+ "",
3445
+ "## Completion evidence",
3446
+ "UES executed " + rows.length + " command-only read-only Git check(s) directly and compared the source workspace fingerprint before and after.",
3447
+ "",
3448
+ "UES_VERDICT: " + (deterministicPass ? "PASS" : "FAIL"),
3449
+ ].join("\n");
3450
+
3451
+ inspection = {
3452
+ agent: "ues-deterministic-read-only",
3453
+ task: params.task,
3454
+ cwd,
3455
+ exitCode: deterministicPass ? 0 : 1,
3456
+ output,
3457
+ stderr: "",
3458
+ verdict: deterministicPass ? "PASS" : "FAIL",
3459
+ durationMs: 0,
3460
+ toolCalls: rows.length,
3461
+ toolNames: rows.map((row) => row.label),
3462
+ report: parseStructuredReport(output),
3463
+ optimizations: {
3464
+ deterministicReadOnlyGit: true,
3465
+ checkCount: rows.length,
3466
+ },
3467
+ };
3468
+ steps.push(inspection);
3469
+ onUpdate?.({
3470
+ content: [{
3471
+ type: "text",
3472
+ text: "UES read-only fast path: executed " + rows.length + " whitelisted Git check(s) deterministically; skipped verifier model turn",
3473
+ }],
3474
+ details: { mode: "execute", phase: "read-only-deterministic", policy, traceID, checks: rows.map((row) => row.label) },
3475
+ });
3476
+ } else {
3477
+ inspection = await run(
3478
+ "ues-verifier",
3479
+ [
3480
+ "READ-ONLY INSPECTION MODE. Do not edit, create, delete, stage, commit, install dependencies, or start persistent services.",
3481
+ "Use only the narrowest read-only commands and source inspection needed to answer the request.",
3482
+ "Fresh command output is valid completion evidence for an inspection task; do not require behavioral tests when the user did not request a code change.",
3483
+ "Return exactly these H2 sections: ## Checks run, ## Acceptance criteria proven, ## Failures, ## Unresolved gaps, ## Checks not run, ## Completion evidence.",
3484
+ "Write exactly None in Failures and Unresolved gaps when there is no real requested failure or gap.",
3485
+ "End with exactly UES_VERDICT: PASS or UES_VERDICT: FAIL.",
3486
+ "Explicitly verify that source-facing workspace state is unchanged before returning PASS.",
3487
+ "",
3488
+ "Inspection request:",
3489
+ params.task,
3490
+ ].join("\n"),
3491
+ 1,
3492
+ );
3493
+ if (isAbortedRun(inspection)) return abortedResponse(inspection, "read-only-inspection");
3494
+ }
3495
+
3496
+ const after = runtimeWorkspaceSnapshot(cwd);
3497
+ const unchanged =
3498
+ before.cacheable === true &&
3499
+ after.cacheable === true &&
3500
+ before.fingerprint === after.fingerprint;
3501
+ const completionAudit = auditCompletion({
3502
+ verification: inspection,
3503
+ requireIntegration: false,
3504
+ requireVisual: false,
3505
+ workspaceSnapshot: after,
3506
+ behavioralReceipts: [],
3507
+ requireBehavioralReceipt: false,
3508
+ });
3509
+ if (!unchanged) {
3510
+ completionAudit.passed = false;
3511
+ completionAudit.failures = [...new Set([
3512
+ ...(completionAudit.failures || []),
3513
+ "read-only-workspace-mutated",
3514
+ ])];
3515
+ }
3516
+
3517
+ if (!completionAudit.passed) {
3518
+ return {
3519
+ content: [{
3520
+ type: "text",
3521
+ text: "UES read-only inspection did not pass: " + completionAudit.failures.join(", ") +
3522
+ "\n\n" + inspection.output,
3523
+ }],
3524
+ details: { mode: "execute", policy, steps, completionAudit, traceID },
3525
+ isError: true,
3526
+ };
3527
+ }
3528
+
3529
+ return {
3530
+ content: [{
3531
+ type: "text",
3532
+ text: [
3533
+ "UES read-only inspection PASS.",
3534
+ "Workspace source fingerprint remained unchanged.",
3535
+ "",
3536
+ inspection.output,
3537
+ ].join("\n"),
3538
+ }],
3539
+ details: { mode: "execute", policy, steps, completionAudit, traceID },
3540
+ };
3541
+ }
3542
+
2642
3543
  if (shouldRunDedicatedDiagnosis(policy, 1)) {
2643
3544
  const diagnosis = await run("ues-debugger", params.task, 1);
2644
3545
  if (isAbortedRun(diagnosis)) return abortedResponse(diagnosis, "diagnosis");
@@ -2657,9 +3558,14 @@ export default function (pi: ExtensionAPI) {
2657
3558
  params.task,
2658
3559
  "",
2659
3560
  "Produce an implementation plan grounded in the current repository. Include exact files/interfaces, dependencies, risk controls, rollback notes, acceptance criteria and verification commands.",
2660
- "For deterministic scheduling, end with UES_PLAN_JSON: followed by one valid JSON object with schemaVersion=1, goal, and tasks.",
3561
+ "For deterministic scheduling, emit UES_PLAN_JSON: followed by one valid JSON object with schemaVersion=1, goal, and tasks as the first substantive output. Do not delay the JSON behind long prose.",
2661
3562
  "Each task must have id, title, summary, dependsOn, files ({create,modify,test,delete,read}), acceptance, verification, and risk.",
3563
+ executionContract.phases?.length
3564
+ ? "PHASE CONTRACT: every execution task must include an integer phase matching one explicit execution PHASE number from the user request. Constraint/guardrail-only phases are invariants, not fake tasks. Do not omit, merge away, or invent execution phases. UES will add deterministic previous-phase barriers after validation."
3565
+ : "",
3566
+ "STRICT JSON CONTRACT: acceptance and verification are non-empty arrays of strings. risk is exactly one of low|medium|high|critical. Put descriptive risk prose in riskNotes. verificationCommands is optional and does not replace verification.",
2662
3567
  "Declare every file a task may write. Do not invent files: inspect the repository first.",
3568
+ "DEEP efficiency rule: use the supplied runtime context/ranked references first; do not inventory the whole repository or re-read unchanged files. You have a bounded planning budget: prefer at most one targeted lookup per unresolved boundary, then emit the plan. Stop exploration once exact task scope, dependencies, acceptance, verification, and risk/rollback are grounded.",
2663
3569
  ].join("\n");
2664
3570
 
2665
3571
  let architect = await run(
@@ -2669,70 +3575,237 @@ export default function (pi: ExtensionAPI) {
2669
3575
  recentFailure || undefined,
2670
3576
  );
2671
3577
  if (isAbortedRun(architect)) return abortedResponse(architect, "planning");
2672
- if (architect.exitCode !== 0 || architect.stopReason === "error") {
2673
- return {
2674
- content: [{ type: "text", text: `Architecture pass failed:\n\n${architect.output}` }],
2675
- details: { mode: "execute", policy, steps },
2676
- isError: true,
2677
- };
2678
- }
2679
3578
 
2680
- structuredPlan = extractMarkedJson(architect.output, "UES_PLAN_JSON:");
2681
- let structuredValidation = structuredPlan ? validatePlan(structuredPlan) : null;
3579
+ let planCandidate = extractValidatedPlan(architect.output);
3580
+ structuredPlan = planCandidate.plan;
3581
+ let structuredValidation = planCandidate.validation;
2682
3582
 
2683
- if (
2684
- (policy.mode === "long-horizon" || policy.profile?.durableState === true) &&
2685
- (!structuredPlan || structuredValidation?.valid !== true)
2686
- ) {
2687
- const repairEvidence = [
2688
- "The first architecture pass did not produce a valid UES_PLAN_JSON plan.",
2689
- structuredValidation ? JSON.stringify(structuredValidation, null, 2) : "UES_PLAN_JSON marker or JSON object was missing.",
2690
- "Return a corrected repository-grounded plan with the required marker and schema.",
2691
- ].join("\n");
2692
- architect = await run("ues-architect", planInstruction, 2, repairEvidence);
2693
- if (isAbortedRun(architect)) return abortedResponse(architect, "plan-repair");
2694
- structuredPlan = extractMarkedJson(architect.output, "UES_PLAN_JSON:");
2695
- structuredValidation = structuredPlan ? validatePlan(structuredPlan) : null;
2696
- if (
2697
- architect.exitCode !== 0 ||
2698
- architect.stopReason === "error" ||
2699
- !structuredPlan ||
2700
- structuredValidation?.valid !== true
2701
- ) {
2702
- return {
3583
+ if (planCandidate.salvaged && structuredValidation?.valid === true) {
3584
+ onUpdate?.({
3585
+ content: [{
3586
+ type: "text",
3587
+ text: `UES planning salvage: recovered a valid plan from ${planCandidate.source} architect output`,
3588
+ }],
3589
+ details: {
3590
+ mode: "execute",
3591
+ phase: "planning-salvage",
3592
+ source: planCandidate.source,
3593
+ traceID,
3594
+ },
3595
+ });
3596
+ }
3597
+
3598
+ const firstPlanValid =
3599
+ structuredPlan &&
3600
+ structuredValidation?.valid === true;
3601
+
3602
+ if (!firstPlanValid) {
3603
+ const recoveryEvidence = failureDelta([
3604
+ architect.exitCode !== 0 || architect.stopReason
3605
+ ? "Previous architect pass stopped before a valid plan: " + String(architect.stopReason || architect.exitCode)
3606
+ : "Previous architect pass returned an invalid plan.",
3607
+ structuredValidation
3608
+ ? JSON.stringify(structuredValidation, null, 2)
3609
+ : "UES_PLAN_JSON marker or valid JSON object was missing.",
3610
+ "RECOVERY RULE: do not restart repository exploration. Reuse the existing context/evidence, perform at most one targeted lookup for any blocking gap, then return the corrected plan immediately.",
3611
+ "acceptance and verification must be non-empty string arrays; risk must be low|medium|high|critical; descriptive prose belongs in riskNotes.",
3612
+ ].join("\n"), { maxChars: 4200 });
3613
+
3614
+ architect = await run("ues-architect", planInstruction, 2, recoveryEvidence);
3615
+ if (isAbortedRun(architect)) return abortedResponse(architect, "plan-recovery");
3616
+ planCandidate = extractValidatedPlan(architect.output);
3617
+ structuredPlan = planCandidate.plan;
3618
+ structuredValidation = planCandidate.validation;
3619
+ if (planCandidate.salvaged && structuredValidation?.valid === true) {
3620
+ onUpdate?.({
2703
3621
  content: [{
2704
3622
  type: "text",
2705
- text: "Long-horizon plan could not be converted into a valid deterministic task graph.\n\n" +
2706
- (structuredValidation ? JSON.stringify(structuredValidation, null, 2) : architect.output),
3623
+ text: `UES planning salvage: recovery produced a valid ${planCandidate.source} plan`,
2707
3624
  }],
2708
- details: { mode: "execute", policy, steps, structuredPlan, structuredValidation },
2709
- isError: true,
2710
- };
3625
+ details: {
3626
+ mode: "execute",
3627
+ phase: "planning-salvage",
3628
+ source: planCandidate.source,
3629
+ traceID,
3630
+ },
3631
+ });
2711
3632
  }
2712
3633
  }
2713
3634
 
2714
- const planCheck = await run(
2715
- "ues-plan-checker",
2716
- [
2717
- "Validate the following inline plan against the current repository. If persistent SPEC/PLAN files do not exist yet, evaluate this inline plan directly instead of failing only because those files are absent.",
2718
- "",
2719
- "Original task:",
2720
- params.task,
2721
- "",
2722
- "Inline plan:",
2723
- structuredPlan ? JSON.stringify(structuredPlan, null, 2) : architect.output,
2724
- ].join("\n"),
2725
- 1,
2726
- );
3635
+ if (
3636
+ !structuredPlan ||
3637
+ structuredValidation?.valid !== true
3638
+ ) {
3639
+ return {
3640
+ content: [{
3641
+ type: "text",
3642
+ text: "Long-horizon planning exhausted its bounded fast-planning recovery without a valid deterministic task graph.\n\n" +
3643
+ (structuredValidation ? JSON.stringify(structuredValidation, null, 2) : architect.output),
3644
+ }],
3645
+ details: { mode: "execute", policy, steps, structuredPlan, structuredValidation },
3646
+ isError: true,
3647
+ };
3648
+ }
3649
+
3650
+ let phaseGate = enforcePhaseGates(structuredPlan, executionContract);
3651
+ if (phaseGate.valid !== true) {
3652
+ const phaseRevisionEvidence = failureDelta([
3653
+ "The deterministic explicit-phase gate rejected the plan.",
3654
+ "Do not rescan the repository. Revise only phase assignment/coverage/dependencies.",
3655
+ "Every execution task must include an integer phase. Every explicit execution PHASE must have at least one task. Constraint-only phases are invariants, not tasks.",
3656
+ "Phase gate errors:",
3657
+ phaseGate.errors.join("\n"),
3658
+ "Current plan:",
3659
+ JSON.stringify(structuredPlan, null, 2),
3660
+ ].join("\n"), { maxChars: 6200 });
3661
+ const phaseRevisedArchitect = await run(
3662
+ "ues-architect",
3663
+ planInstruction,
3664
+ 2,
3665
+ phaseRevisionEvidence,
3666
+ );
3667
+ if (isAbortedRun(phaseRevisedArchitect)) {
3668
+ return abortedResponse(phaseRevisedArchitect, "phase-plan-auto-revise");
3669
+ }
3670
+ const phaseRevisedCandidate = extractValidatedPlan(phaseRevisedArchitect.output);
3671
+ if (phaseRevisedCandidate.plan && phaseRevisedCandidate.validation?.valid === true) {
3672
+ const revisedPhaseGate = enforcePhaseGates(
3673
+ phaseRevisedCandidate.plan,
3674
+ executionContract,
3675
+ );
3676
+ if (revisedPhaseGate.valid === true) {
3677
+ architect = phaseRevisedArchitect;
3678
+ structuredPlan = revisedPhaseGate.plan;
3679
+ structuredValidation = phaseRevisedCandidate.validation;
3680
+ phaseGate = revisedPhaseGate;
3681
+ onUpdate?.({
3682
+ content: [{
3683
+ type: "text",
3684
+ text: "UES phase gate: auto-revised phase coverage/dependencies once and recovered a valid gated plan",
3685
+ }],
3686
+ details: { mode: "execute", phase: "phase-plan-auto-revise", phaseGate, traceID },
3687
+ });
3688
+ } else {
3689
+ phaseGate = revisedPhaseGate;
3690
+ }
3691
+ }
3692
+ }
3693
+ if (phaseGate.valid !== true) {
3694
+ return {
3695
+ content: [{
3696
+ type: "text",
3697
+ text:
3698
+ "Explicit phase contract gate did not pass after bounded auto-recovery. UES will not flatten or skip user-declared phases.\n\n" +
3699
+ phaseGate.errors.join("\n"),
3700
+ }],
3701
+ details: { mode: "execute", policy, steps, structuredPlan, phaseGate, executionContract },
3702
+ isError: true,
3703
+ };
3704
+ }
3705
+ structuredPlan = phaseGate.plan;
3706
+
3707
+ const buildPlanCheckTask = () => [
3708
+ "Validate the following inline plan against the current repository. If persistent SPEC/PLAN files do not exist yet, evaluate this inline plan directly instead of failing only because those files are absent.",
3709
+ "Use declared files and dependencies first. Do not inventory the repository. Resolve only concrete grounding gaps, then return the verdict.",
3710
+ "",
3711
+ "Original task:",
3712
+ params.task,
3713
+ "",
3714
+ "Inline plan:",
3715
+ structuredPlan ? JSON.stringify(structuredPlan, null, 2) : architect.output,
3716
+ ].join("\n");
3717
+
3718
+ let planCheckTask = buildPlanCheckTask();
3719
+ let planCheck = await run("ues-plan-checker", planCheckTask, 1);
2727
3720
  if (isAbortedRun(planCheck)) return abortedResponse(planCheck, "plan-verification");
3721
+
3722
+ const planCheckTransportFailure =
3723
+ planCheck.verdict !== "PASS" &&
3724
+ planCheck.verdict !== "REVISE" &&
3725
+ (
3726
+ planCheck.exitCode !== 0 ||
3727
+ /hard-timeout|idle-timeout|UES RPC hard-timeout|UES RPC idle-timeout/i.test(
3728
+ String(planCheck.output || "") + "\n" +
3729
+ String(planCheck.stderr || "") + "\n" +
3730
+ String(planCheck.stopReason || ""),
3731
+ )
3732
+ );
3733
+
3734
+ if (planCheckTransportFailure) {
3735
+ const planCheckRecoveryEvidence = failureDelta([
3736
+ "Previous plan-checker runtime failure:",
3737
+ String(planCheck.output || planCheck.stderr || planCheck.stopReason || "unknown"),
3738
+ "Reuse warm context. Do not scan broadly. Check only unresolved declared paths/dependencies and return PASS or REVISE.",
3739
+ ].join("\n"), { maxChars: 2600 });
3740
+
3741
+ planCheck = await run(
3742
+ "ues-plan-checker",
3743
+ planCheckTask,
3744
+ 2,
3745
+ planCheckRecoveryEvidence,
3746
+ );
3747
+ if (isAbortedRun(planCheck)) return abortedResponse(planCheck, "plan-verification-recovery");
3748
+ }
3749
+
3750
+ if (planCheck.verdict === "REVISE") {
3751
+ const revisionEvidence = failureDelta([
3752
+ "The independent plan-checker requested a bounded revision.",
3753
+ "Do not restart broad repository exploration. Change only the rejected plan claims/scope.",
3754
+ "Plan-checker feedback:",
3755
+ String(planCheck.output || ""),
3756
+ "Current plan:",
3757
+ JSON.stringify(structuredPlan, null, 2),
3758
+ ].join("\n"), { maxChars: 5200 });
3759
+
3760
+ const revisedArchitect = await run(
3761
+ "ues-architect",
3762
+ planInstruction,
3763
+ 2,
3764
+ revisionEvidence,
3765
+ );
3766
+ if (isAbortedRun(revisedArchitect)) return abortedResponse(revisedArchitect, "plan-auto-revise");
3767
+ const revisedCandidate = extractValidatedPlan(revisedArchitect.output);
3768
+ if (revisedCandidate.plan && revisedCandidate.validation?.valid === true) {
3769
+ architect = revisedArchitect;
3770
+ structuredPlan = revisedCandidate.plan;
3771
+ structuredValidation = revisedCandidate.validation;
3772
+ planCheckTask = buildPlanCheckTask();
3773
+ onUpdate?.({
3774
+ content: [{ type: "text", text: "UES plan gate: auto-revised the rejected plan; re-checking once" }],
3775
+ details: { mode: "execute", phase: "plan-auto-revise", policy, traceID },
3776
+ });
3777
+ planCheck = await run(
3778
+ "ues-plan-checker",
3779
+ planCheckTask,
3780
+ 2,
3781
+ failureDelta(String(planCheck.output || ""), { maxChars: 2600 }),
3782
+ );
3783
+ if (isAbortedRun(planCheck)) return abortedResponse(planCheck, "plan-auto-revise-check");
3784
+ }
3785
+ }
3786
+
3787
+ const finalPhaseGate = enforcePhaseGates(structuredPlan, executionContract);
3788
+ if (finalPhaseGate.valid !== true) {
3789
+ return {
3790
+ content: [{
3791
+ type: "text",
3792
+ text:
3793
+ "Plan revision lost the deterministic explicit-phase contract. UES will not execute it.\n\n" +
3794
+ finalPhaseGate.errors.join("\n"),
3795
+ }],
3796
+ details: { mode: "execute", policy, steps, structuredPlan, finalPhaseGate, executionContract },
3797
+ isError: true,
3798
+ };
3799
+ }
3800
+ structuredPlan = finalPhaseGate.plan;
3801
+
2728
3802
  if (planCheck.exitCode !== 0 || planCheck.verdict !== "PASS") {
2729
3803
  return {
2730
- content: [{ type: "text", text: `Plan gate did not pass:\n\n${planCheck.output}` }],
3804
+ content: [{ type: "text", text: `Plan gate did not pass after bounded auto-recovery:\n\n${planCheck.output}` }],
2731
3805
  details: { mode: "execute", policy, steps, structuredPlan },
2732
3806
  isError: true,
2733
3807
  };
2734
3808
  }
2735
-
2736
3809
  const durableRequested =
2737
3810
  policy.mode === "long-horizon" || policy.profile?.durableState === true;
2738
3811
  if (durableRequested) {
@@ -2754,6 +3827,10 @@ export default function (pi: ExtensionAPI) {
2754
3827
  planCheck.output,
2755
3828
  signal,
2756
3829
  );
3830
+ durableWork.executionArtifacts = await persistExecutionContractArtifacts(
3831
+ durableWork.dir,
3832
+ executionContract,
3833
+ );
2757
3834
  onUpdate?.({
2758
3835
  content: [{
2759
3836
  type: "text",
@@ -2787,6 +3864,7 @@ export default function (pi: ExtensionAPI) {
2787
3864
  inheritedModel,
2788
3865
  inheritedThinking,
2789
3866
  maxAttempts,
3867
+ rootPolicy: policy,
2790
3868
  durableSlug: durableWork?.slug,
2791
3869
  traceID,
2792
3870
  signal,
@@ -2893,12 +3971,81 @@ export default function (pi: ExtensionAPI) {
2893
3971
  }
2894
3972
  }
2895
3973
 
3974
+ const verdictMatrix = buildFinalVerdictMatrix(params.task, {
3975
+ contract: executionContract,
3976
+ primaryPass: true,
3977
+ integrationPass: true,
3978
+ primaryOutput: (scheduled.results || [])
3979
+ .map((row: any) => row?.verification?.output || row?.implementation?.output || "")
3980
+ .filter(Boolean)
3981
+ .join("\n"),
3982
+ integrationOutput: integration.output,
3983
+ visualOutput: visualResult?.output || "",
3984
+ primaryChecks: (scheduled.results || [])
3985
+ .flatMap((row: any) => Object.values(row?.verification?.report?.sections || {}))
3986
+ .filter(Boolean)
3987
+ .join("\n"),
3988
+ integrationChecks: integration.report?.sections?.["checks-run"] || "",
3989
+ visualChecks: visualResult?.report?.sections?.["checks-run"] || "",
3990
+ });
3991
+
3992
+ const finalEvidenceForContract = [
3993
+ integration.output,
3994
+ visualResult?.output || "",
3995
+ ].filter(Boolean).join("\n\n--- VISUAL ---\n\n");
3996
+
3997
+ if (verdictMatrix.final !== "PASS") {
3998
+ if (durableWork) {
3999
+ await durableRecordIntegration(
4000
+ cwd,
4001
+ durableWork.slug,
4002
+ "PARTIAL",
4003
+ finalEvidenceForContract,
4004
+ signal,
4005
+ ).catch(() => {});
4006
+ await finalizeExecutionContractArtifacts(
4007
+ durableWork.dir,
4008
+ executionContract,
4009
+ verdictMatrix,
4010
+ finalEvidenceForContract,
4011
+ ).catch(() => null);
4012
+ }
4013
+ const deviceOnlyPending =
4014
+ verdictMatrix.final === "SOURCE_RUNTIME_PASS_DEVICE_NOT_VERIFIED";
4015
+ return {
4016
+ content: [{
4017
+ type: "text",
4018
+ text: [
4019
+ deviceOnlyPending
4020
+ ? "UES source/runtime verification passed, but requested real-device verification is still pending."
4021
+ : "UES deterministic final gate is not fully verified.",
4022
+ "",
4023
+ verdictMatrix.source,
4024
+ verdictMatrix.runtime,
4025
+ verdictMatrix.dbClean,
4026
+ verdictMatrix.device,
4027
+ "",
4028
+ integration.output,
4029
+ ].join("\n"),
4030
+ }],
4031
+ details: {
4032
+ mode: "execute",
4033
+ policy,
4034
+ steps,
4035
+ structuredPlan,
4036
+ scheduled,
4037
+ durableWork,
4038
+ verdictMatrix,
4039
+ executionContract,
4040
+ traceID,
4041
+ },
4042
+ isError: !deviceOnlyPending,
4043
+ };
4044
+ }
4045
+
2896
4046
  let durableFinalization: any = null;
2897
4047
  if (durableWork) {
2898
- const finalEvidence = [
2899
- integration.output,
2900
- visualResult?.output || "",
2901
- ].filter(Boolean).join("\n\n--- VISUAL ---\n\n");
4048
+ const finalEvidence = finalEvidenceForContract;
2902
4049
  try {
2903
4050
  durableFinalization = await durableRecordIntegration(
2904
4051
  cwd,
@@ -2921,6 +4068,15 @@ export default function (pi: ExtensionAPI) {
2921
4068
  }
2922
4069
  }
2923
4070
 
4071
+ if (durableWork) {
4072
+ await finalizeExecutionContractArtifacts(
4073
+ durableWork.dir,
4074
+ executionContract,
4075
+ verdictMatrix,
4076
+ finalEvidenceForContract,
4077
+ ).catch(() => null);
4078
+ }
4079
+
2924
4080
  const memoryFiles = [...new Set(structuredPlan.tasks.flatMap((task: any) => taskWriteFiles(task)))];
2925
4081
  const memory = durableWork
2926
4082
  ? durableFinalization?.finalized?.memory || null
@@ -2932,6 +4088,10 @@ export default function (pi: ExtensionAPI) {
2932
4088
  `UES scheduled execution PASS across ${structuredPlan.tasks.length} task(s).`,
2933
4089
  `Safe waves: ${scheduled.schedule?.safeWaves?.length || 0}; integrations: ${scheduled.integrations?.length || 0}.`,
2934
4090
  durableWork ? `Durable state: .ues-work/${durableWork.slug} finalized with fresh integration receipt.` : "",
4091
+ verdictMatrix.source,
4092
+ verdictMatrix.runtime,
4093
+ verdictMatrix.dbClean,
4094
+ verdictMatrix.device,
2935
4095
  "",
2936
4096
  integration.output,
2937
4097
  ].join("\n"),
@@ -2946,6 +4106,8 @@ export default function (pi: ExtensionAPI) {
2946
4106
  memory,
2947
4107
  durableWork,
2948
4108
  durableFinalization,
4109
+ verdictMatrix,
4110
+ executionContract,
2949
4111
  traceID,
2950
4112
  },
2951
4113
  };
@@ -2979,18 +4141,19 @@ export default function (pi: ExtensionAPI) {
2979
4141
  recentFailure = diagnosis.output;
2980
4142
  }
2981
4143
 
2982
- const fastBoundedLane =
2983
- policy.executionProfile === "fast" &&
2984
- policy.singleFileBounded === true &&
2985
- policy.risk === "low" &&
2986
- !visualEvidenceNeeded(params.task) &&
2987
- !browserEvidenceNeeded(params.task, "executor");
4144
+ const fastDecision = turboFastPathDecision(policy, {
4145
+ role: "executor",
4146
+ attempt,
4147
+ browserRequested: browserEvidenceNeeded(params.task, "executor"),
4148
+ visualRequired: visualEvidenceNeeded(params.task),
4149
+ });
4150
+ const fastBoundedLane = fastDecision.eligible;
2988
4151
  const fastAttemptStartedAt = Date.now();
2989
4152
  const executorTask = [
2990
4153
  params.task,
2991
4154
  recentFailure ? "\nEvidence from diagnosis/previous failed verification:\n" + cap(recentFailure, 7000) : "",
2992
4155
  fastBoundedLane
2993
- ? "\nFAST bounded rule: stay on the named file, implement every explicit branch, and produce fresh behavioral evidence before handoff. Prefer one focused project-native test command. If no JS/TS test exists, use a temporary .ues-cache/fast-acceptance.test.mjs and run node --test .ues-cache/fast-acceptance.test.mjs so the controller can independently reuse the successful tool-boundary receipt. Cover every enumerated error, boundary, idempotency and non-mutation case; syntax/build alone is insufficient."
4156
+ ? "\nFAST bounded rule: stay on the named target file. Read that file first; do not inventory the repository or run broad searches unless the target is missing or direct evidence proves wider scope. Make the smallest edit, then run one focused behavioral check and stop once a fresh PASS receipt covers every explicit branch. If no project-native JS/TS test exists, use one temporary .ues-cache/fast-acceptance.test.mjs probe, run node --test .ues-cache/fast-acceptance.test.mjs, and remove only that probe afterwards. Syntax/build alone is insufficient."
2994
4157
  : "",
2995
4158
  "\nImplement the smallest coherent change. Do not push, publish, deploy, rewrite history, or broaden scope without evidence.",
2996
4159
  ].filter(Boolean).join("\n");
@@ -3008,6 +4171,37 @@ export default function (pi: ExtensionAPI) {
3008
4171
  continue;
3009
4172
  }
3010
4173
 
4174
+ const inheritedDirtyCheck = detectInheritedDirtyViolations(
4175
+ cwd,
4176
+ executionContract.inheritedDirty,
4177
+ executionContract.approvedInheritedDirtyPaths || [],
4178
+ );
4179
+ if (!inheritedDirtyCheck.safe) {
4180
+ await recordRuntimeOutcome(implementation, params.task, false, attempt - 1);
4181
+ return {
4182
+ content: [{
4183
+ type: "text",
4184
+ text: [
4185
+ "UES inherited dirty-work guard stopped completion.",
4186
+ "The implementation changed pre-existing dirty source work that was not explicitly authorized by the original task.",
4187
+ "UES will not auto-restore or overwrite these files.",
4188
+ "",
4189
+ ...inheritedDirtyCheck.violations.map((item: any) => "- " + item.path),
4190
+ ].join("\n"),
4191
+ }],
4192
+ details: {
4193
+ mode: "execute",
4194
+ policy,
4195
+ steps,
4196
+ attempts: attempt,
4197
+ executionContract,
4198
+ inheritedDirtyCheck,
4199
+ traceID,
4200
+ },
4201
+ isError: true,
4202
+ };
4203
+ }
4204
+
3011
4205
  let verification: RunResult;
3012
4206
  let fastGate: any = null;
3013
4207
  if (fastBoundedLane) {
@@ -3029,7 +4223,10 @@ export default function (pi: ExtensionAPI) {
3029
4223
  optimizations: { fastDeterministicVerification: true, behavioralReceiptCount: fastGate.behavioralReceipts.length },
3030
4224
  };
3031
4225
  steps.push(verification);
3032
- onUpdate?.({ content: [{ type: "text", text: "UES FAST verifier: reused " + fastGate.behavioralReceipts.length + " fresh behavioral receipt(s); skipped an extra verifier model turn" }], details: { mode: "execute", policy, fastGate, traceID } });
4226
+ onUpdate?.({
4227
+ content: [{ type: "text", text: "UES Turbo Fast Path: reused " + fastGate.behavioralReceipts.length + " fresh behavioral receipt(s); skipped verifier model turn" }],
4228
+ details: { mode: "execute", phase: "turbo-fast-verified", policy, fastGate, fastDecision, traceID },
4229
+ });
3033
4230
  } else {
3034
4231
  verification = await run(
3035
4232
  "ues-verifier",
@@ -3125,7 +4322,7 @@ export default function (pi: ExtensionAPI) {
3125
4322
  requireVisual: visualEvidenceNeeded(params.task),
3126
4323
  workspaceSnapshot: completionSnapshot,
3127
4324
  behavioralReceipts: freshReceipts,
3128
- requireBehavioralReceipt: true,
4325
+ requireBehavioralReceipt: policy.requireBehavioralReceipt !== false,
3129
4326
  });
3130
4327
  if (!completionAudit.passed) {
3131
4328
  recentFailure = "Completion auditor rejected PASS: " + completionAudit.failures.join(", ");
@@ -3138,6 +4335,52 @@ export default function (pi: ExtensionAPI) {
3138
4335
  };
3139
4336
  }
3140
4337
 
4338
+ const verdictMatrix = buildFinalVerdictMatrix(params.task, {
4339
+ contract: executionContract,
4340
+ primaryPass: true,
4341
+ integrationPass: integrationResult ? true : undefined,
4342
+ primaryOutput: verification.output,
4343
+ integrationOutput: integrationResult?.output || "",
4344
+ visualOutput: visualResult?.output || "",
4345
+ primaryChecks: verification.report?.sections?.["checks-run"] || "",
4346
+ integrationChecks: integrationResult?.report?.sections?.["checks-run"] || "",
4347
+ visualChecks: visualResult?.report?.sections?.["checks-run"] || "",
4348
+ });
4349
+
4350
+ if (verdictMatrix.final !== "PASS") {
4351
+ await recordRuntimeOutcome(implementation, params.task, false, attempt - 1);
4352
+ const deviceOnlyPending =
4353
+ verdictMatrix.final === "SOURCE_RUNTIME_PASS_DEVICE_NOT_VERIFIED";
4354
+ return {
4355
+ content: [{
4356
+ type: "text",
4357
+ text: [
4358
+ deviceOnlyPending
4359
+ ? "UES source/runtime verification passed, but requested real-device verification is still pending."
4360
+ : "UES deterministic final gate is not fully verified.",
4361
+ "",
4362
+ verdictMatrix.source,
4363
+ verdictMatrix.runtime,
4364
+ verdictMatrix.dbClean,
4365
+ verdictMatrix.device,
4366
+ "",
4367
+ integrationResult?.output || verification.output,
4368
+ ].join("\n"),
4369
+ }],
4370
+ details: {
4371
+ mode: "execute",
4372
+ policy,
4373
+ steps,
4374
+ attempts: attempt,
4375
+ completionAudit,
4376
+ verdictMatrix,
4377
+ executionContract,
4378
+ traceID,
4379
+ },
4380
+ isError: !deviceOnlyPending,
4381
+ };
4382
+ }
4383
+
3141
4384
  await recordRuntimeOutcome(implementation, params.task, true, attempt - 1);
3142
4385
  const memory = await rememberVerifiedTask(cwd, params.task, verification, integrationResult);
3143
4386
  const final = steps.at(-1);
@@ -3147,11 +4390,15 @@ export default function (pi: ExtensionAPI) {
3147
4390
  text: [
3148
4391
  `UES execution PASS after ${attempt} attempt(s).`,
3149
4392
  `Policy: ${policy.executionProfile}/${policy.risk}; model tier: ${implementation.modelTier || "default"}.`,
4393
+ verdictMatrix.source,
4394
+ verdictMatrix.runtime,
4395
+ verdictMatrix.dbClean,
4396
+ verdictMatrix.device,
3150
4397
  "",
3151
4398
  final?.output || verification.output,
3152
4399
  ].join("\n"),
3153
4400
  }],
3154
- details: { mode: "execute", policy, steps, attempts: attempt, memory, completionAudit, traceID },
4401
+ details: { mode: "execute", policy, steps, attempts: attempt, memory, completionAudit, verdictMatrix, executionContract, traceID },
3155
4402
  };
3156
4403
  }
3157
4404
 
@@ -3164,6 +4411,355 @@ export default function (pi: ExtensionAPI) {
3164
4411
  isError: true,
3165
4412
  };
3166
4413
  },
4414
+ };
4415
+ pi.registerTool(uesExecuteTool);
4416
+
4417
+ // Extension commands are resolved before prompt templates in Pi. Registering
4418
+ // /ues-run here makes controller admission deterministic: weak models never
4419
+ // have to remember to call ues_execute themselves.
4420
+ pi.registerCommand("ues-status", {
4421
+ description: "Show the loaded UES runtime version and current session policy basics",
4422
+ handler: async (_args, ctx) => {
4423
+ const status = [
4424
+ "UES runtime: " + PACKAGE_VERSION,
4425
+ "Package root: " + PACKAGE_ROOT,
4426
+ "Child runtime: " + CHILD_RUNTIME,
4427
+ "Adaptive context: " + (ADAPTIVE_CONTEXT_ENABLED ? "on" : "off"),
4428
+ "Micro skills: " + (MICRO_SKILLS_ENABLED ? "on" : "off"),
4429
+ "Turbo Fast Path: on",
4430
+ "Parent UES tools hidden outside UES runs: on",
4431
+ "Zero-friction engineering admission: " + (AUTO_ADMISSION_ENABLED ? "on (native / auto / high-risk + safe continuation)" : "off"),
4432
+ "Git-root artifact guard: on",
4433
+ "Inherited dirty-work guard: on",
4434
+ "Local .env mutation guard: on",
4435
+ "Portable temp-path guard: on",
4436
+ "Explicit phase barriers: on",
4437
+ "Independent final verdict matrix: on",
4438
+ "Disk hygiene: bounded + auto-clean",
4439
+ "Writer concurrency: " + MAX_WRITER_CONCURRENCY,
4440
+ ].join("\n");
4441
+ pi.sendMessage({
4442
+ customType: "ues-runtime-status",
4443
+ content: status,
4444
+ display: true,
4445
+ details: { version: PACKAGE_VERSION, packageRoot: PACKAGE_ROOT, childRuntime: CHILD_RUNTIME },
4446
+ }, { triggerTurn: false });
4447
+ try { ctx.ui.notify("UES runtime " + PACKAGE_VERSION + " loaded", "info"); } catch {}
4448
+ },
4449
+ });
4450
+
4451
+ pi.registerCommand("ues-clean", {
4452
+ description: "Safely remove stale UES task sandboxes and orphan metadata for the current repository",
4453
+ handler: async (_args, ctx) => {
4454
+ if (uesModeActive()) {
4455
+ try { ctx.ui.notify("UES cleanup refused while a UES task is active", "warning"); } catch {}
4456
+ return;
4457
+ }
4458
+ let workspaceRoot: string;
4459
+ try {
4460
+ workspaceRoot = requireGitWorkspaceRoot(ctx.cwd, "/ues-clean");
4461
+ } catch (error) {
4462
+ const message = error instanceof Error ? error.message : String(error);
4463
+ pi.sendMessage({
4464
+ customType: "ues-cleanup-result",
4465
+ content: "UES cleanup refused unsafe workspace.\n" + message,
4466
+ display: true,
4467
+ details: { error: message },
4468
+ }, { triggerTurn: false });
4469
+ try { ctx.ui.notify(message, "error"); } catch {}
4470
+ return;
4471
+ }
4472
+ const cleanup = await pruneOrphanTaskSandboxes(workspaceRoot, {
4473
+ minAgeMs: 5 * 60_000,
4474
+ legacyMinAgeMs: 30 * 60_000,
4475
+ ownedMinAgeMs: 0,
4476
+ reclaimOwnerPid: process.pid,
4477
+ protectedDirs: [...ACTIVE_TASK_SANDBOXES.keys()],
4478
+ }).catch((error) => ({
4479
+ removed: [],
4480
+ skipped: [],
4481
+ sidecarsRemoved: [],
4482
+ error: error instanceof Error ? error.message : String(error),
4483
+ }));
4484
+ const removed = Number(cleanup?.removed?.length || 0);
4485
+ const sidecars = Number(cleanup?.sidecarsRemoved?.length || 0);
4486
+ const skipped = Number(cleanup?.skipped?.length || 0);
4487
+ await stopAllServices(workspaceRoot).catch(() => []);
4488
+ const transientDirs = [".ues-traces", ".ues-services", ".ues-dashboard"];
4489
+ const removedRuntimeDirs: string[] = [];
4490
+ for (const name of transientDirs) {
4491
+ const target = path.join(workspaceRoot, name);
4492
+ if (!fs.existsSync(target)) continue;
4493
+ await fs.promises.rm(target, { recursive: true, force: true }).catch(() => {});
4494
+ if (!fs.existsSync(target)) removedRuntimeDirs.push(name);
4495
+ }
4496
+
4497
+ const cacheDir = path.join(workspaceRoot, ".ues-cache");
4498
+ const removedCacheEntries: string[] = [];
4499
+ if (fs.existsSync(cacheDir)) {
4500
+ const entries = await fs.promises.readdir(cacheDir, { withFileTypes: true }).catch(() => []);
4501
+ for (const entry of entries) {
4502
+ if (entry.name === "evidence-v1") continue;
4503
+ if (
4504
+ entry.name === "semantic-index-v1.json" ||
4505
+ entry.name.startsWith("semantic-index-v1.json.") ||
4506
+ entry.name === "verification-broker-v1.json" ||
4507
+ entry.name.startsWith("verification-broker-v1.json.")
4508
+ ) {
4509
+ await fs.promises.rm(path.join(cacheDir, entry.name), { recursive: true, force: true }).catch(() => {});
4510
+ removedCacheEntries.push(entry.name);
4511
+ }
4512
+ }
4513
+ }
4514
+ const evidenceGc = await gcEvidenceStore(workspaceRoot, {
4515
+ maxBytes: 96 * 1024 * 1024,
4516
+ maxEntries: 600,
4517
+ maxAgeDays: 14,
4518
+ }).catch((error) => ({
4519
+ removed: [],
4520
+ removedCount: 0,
4521
+ protectedEntries: 0,
4522
+ protectedBytes: 0,
4523
+ error: error instanceof Error ? error.message : String(error),
4524
+ }));
4525
+
4526
+ if (fs.existsSync(cacheDir)) {
4527
+ const remaining = await fs.promises.readdir(cacheDir).catch(() => ["unknown"]);
4528
+ if (remaining.length === 0) await fs.promises.rm(cacheDir, { recursive: true, force: true }).catch(() => {});
4529
+ }
4530
+
4531
+ const text = [
4532
+ "UES cleanup complete.",
4533
+ "Removed sandboxes: " + removed,
4534
+ "Removed orphan metadata: " + sidecars,
4535
+ "Removed transient runtime dirs: " + (removedRuntimeDirs.join(", ") || "none"),
4536
+ "Removed rebuildable cache entries: " + (removedCacheEntries.length || 0),
4537
+ "Pruned evidence blobs: " + Number(evidenceGc?.removedCount || 0),
4538
+ "Protected verified-memory evidence: " + Number(evidenceGc?.protectedEntries || 0),
4539
+ "Protected/recent entries kept: " + skipped,
4540
+ "Preserved durable state: .ues-work, .ues-memory, .ues-learning, .ues-evals and verified-memory evidence",
4541
+ cleanup?.baseRemoved ? "Sandbox base directory removed because it is empty." : "",
4542
+ cleanup?.error ? "Error: " + cleanup.error : "",
4543
+ ].filter(Boolean).join("\n");
4544
+ pi.sendMessage({
4545
+ customType: "ues-cleanup-result",
4546
+ content: text,
4547
+ display: true,
4548
+ details: { ...cleanup, removedRuntimeDirs, removedCacheEntries, evidenceGc },
4549
+ }, { triggerTurn: false });
4550
+ try {
4551
+ ctx.ui.notify(
4552
+ "UES cleanup removed/pruned " +
4553
+ (removed + sidecars + removedRuntimeDirs.length + removedCacheEntries.length + Number(evidenceGc?.removedCount || 0)) +
4554
+ " stale/transient artifact(s)",
4555
+ "info",
4556
+ );
4557
+ } catch {}
4558
+ },
4559
+ });
4560
+
4561
+ directControllerRunner = async (task, ctx, admission, admissionDecision) => {
4562
+ if (directControllerAbort && !directControllerAbort.signal.aborted) {
4563
+ try { ctx.ui.notify("UES controller is already running in this session", "warning"); } catch {}
4564
+ return;
4565
+ }
4566
+
4567
+ let workspaceRoot: string;
4568
+ try {
4569
+ workspaceRoot = requireGitWorkspaceRoot(ctx.cwd, admission === "automatic" ? "automatic UES admission" : "/ues-run");
4570
+ } catch (error) {
4571
+ const message = error instanceof Error ? error.message : String(error);
4572
+ pi.sendMessage({
4573
+ customType: "ues-controller-result",
4574
+ content: message,
4575
+ display: true,
4576
+ details: { controllerUsed: false, controllerPass: false, reason: "unsafe-workspace-root" },
4577
+ }, { triggerTurn: false });
4578
+ try { ctx.ui.notify(message, "error"); } catch {}
4579
+ return;
4580
+ }
4581
+
4582
+ const abort = new AbortController();
4583
+ directControllerAbort = abort;
4584
+ const directTraceID = createTraceID(admission === "automatic" ? "ues-auto" : "ues-run");
4585
+ syncSessionIdentity(uesSessionName("run", task, workspaceRoot), ctx);
4586
+ let result: any;
4587
+ let lastProgressNoticeAt = 0;
4588
+ let lastProgressKey = "";
4589
+ try {
4590
+ const directPolicy =
4591
+ admissionDecision?.policy && typeof admissionDecision.policy === "object"
4592
+ ? admissionDecision.policy
4593
+ : classifyEngineeringTask(task);
4594
+ const routeLabel =
4595
+ admission === "automatic"
4596
+ ? admissionDecision?.route === "guarded"
4597
+ ? "high-risk auto controller started ("
4598
+ : "auto controller started ("
4599
+ : "controller started (";
4600
+ try {
4601
+ ctx.ui.notify(
4602
+ "UES " + PACKAGE_VERSION + ": " + routeLabel +
4603
+ String(directPolicy.executionProfile || directPolicy.mode || "unknown") +
4604
+ "/" + String(directPolicy.risk || "unknown") + ")",
4605
+ admissionDecision?.route === "guarded" ? "warning" : "info",
4606
+ );
4607
+ } catch {}
4608
+ result = await uesExecuteTool.execute(
4609
+ `ues-run-${randomUUID()}`,
4610
+ { task, cwd: workspaceRoot, __traceID: directTraceID, __taskPolicy: directPolicy },
4611
+ abort.signal,
4612
+ (update: any) => {
4613
+ const text = (update?.content || [])
4614
+ .filter((part: any) => part?.type === "text" && typeof part.text === "string")
4615
+ .map((part: any) => part.text)
4616
+ .join("\n")
4617
+ .trim();
4618
+ if (text) {
4619
+ try { ctx.ui.setStatus("ues-run", cap(text, 180)); } catch {}
4620
+ }
4621
+
4622
+ const progress = update?.details?.progress;
4623
+ if (progress) {
4624
+ const progressKey = String(progress.agent || "") + ":" + String(update?.details?.phase || "");
4625
+ const now = Date.now();
4626
+ const phaseChanged = progressKey && progressKey !== lastProgressKey;
4627
+ const heartbeatDue = now - lastProgressNoticeAt >= 60_000;
4628
+ if (phaseChanged || heartbeatDue) {
4629
+ const message =
4630
+ "UES: " + String(progress.agent || "worker") +
4631
+ " running " + Math.round(Number(progress.elapsedMs || 0) / 1000) + "s" +
4632
+ " (idle " + Math.round(Number(progress.idleMs || 0) / 1000) + "s, tools " +
4633
+ Number(progress.toolCalls || 0) +
4634
+ (progress.activeTool ? ", " + String(progress.activeTool) : "") + ")";
4635
+ try {
4636
+ ctx.ui.notify(
4637
+ message,
4638
+ Number(progress.idleMs || 0) >= 45_000 ? "warning" : "info",
4639
+ );
4640
+ } catch {}
4641
+ lastProgressNoticeAt = now;
4642
+ lastProgressKey = progressKey;
4643
+ }
4644
+ }
4645
+
4646
+ if (process.env.UES_EVAL_DIRECT_TELEMETRY === "1") {
4647
+ process.stderr.write(JSON.stringify({
4648
+ type: "ues_controller_progress",
4649
+ phase: update?.details?.phase || null,
4650
+ task: update?.details?.task || null,
4651
+ agent: progress?.agent || null,
4652
+ elapsedMs: Number(progress?.elapsedMs || 0),
4653
+ idleMs: Number(progress?.idleMs || 0),
4654
+ toolCalls: Number(progress?.toolCalls || 0),
4655
+ activeTool: progress?.activeTool || null,
4656
+ note: progress?.note || null,
4657
+ text: text ? cap(text, 240) : null,
4658
+ }) + "\n");
4659
+ }
4660
+ },
4661
+ ctx,
4662
+ );
4663
+ } catch (error) {
4664
+ result = {
4665
+ content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
4666
+ details: { mode: "execute", reason: "direct-controller-exception" },
4667
+ isError: true,
4668
+ };
4669
+ } finally {
4670
+ const traceRemoved = await cleanupTraceSandboxes(workspaceRoot, directTraceID).catch(() => 0);
4671
+ const staleCleanup = await pruneOrphanTaskSandboxes(workspaceRoot, {
4672
+ minAgeMs: 5 * 60_000,
4673
+ legacyMinAgeMs: 30 * 60_000,
4674
+ ownedMinAgeMs: 0,
4675
+ reclaimOwnerPid: process.pid,
4676
+ protectedDirs: [...ACTIVE_TASK_SANDBOXES.keys()],
4677
+ }).catch(() => ({ removed: [], skipped: [], sidecarsRemoved: [] }));
4678
+ const cleaned =
4679
+ Number(traceRemoved || 0) +
4680
+ Number(staleCleanup?.removed?.length || 0) +
4681
+ Number(staleCleanup?.sidecarsRemoved?.length || 0);
4682
+ if (cleaned > 0) {
4683
+ try { ctx.ui.notify("UES cleanup: removed " + cleaned + " stale sandbox artifact(s)", "info"); } catch {}
4684
+ }
4685
+ if (directControllerAbort === abort) directControllerAbort = null;
4686
+ try { ctx.ui.setStatus("ues-run", undefined); } catch {}
4687
+ }
4688
+
4689
+ const content = (result?.content || [])
4690
+ .filter((part: any) => part?.type === "text" && typeof part.text === "string")
4691
+ .map((part: any) => part.text)
4692
+ .join("\n")
4693
+ .trim() || "(UES controller returned no text)";
4694
+ const controllerPass = result?.isError !== true;
4695
+
4696
+ if (process.env.UES_EVAL_DIRECT_TELEMETRY === "1") {
4697
+ const details = result?.details || null;
4698
+ const telemetryDetails = details
4699
+ ? {
4700
+ mode: details.mode,
4701
+ attempts: details.attempts,
4702
+ policy: details.policy
4703
+ ? {
4704
+ mode: details.policy.mode,
4705
+ executionProfile: details.policy.executionProfile,
4706
+ risk: details.policy.risk,
4707
+ }
4708
+ : null,
4709
+ steps: Array.isArray(details.steps)
4710
+ ? details.steps.map((step: any) => ({
4711
+ agent: step?.agent,
4712
+ exitCode: step?.exitCode,
4713
+ optimizations: step?.optimizations || null,
4714
+ usage: step?.usage || null,
4715
+ toolCalls: Number(step?.toolCalls || 0),
4716
+ toolNames: Array.isArray(step?.toolNames) ? step.toolNames : [],
4717
+ }))
4718
+ : [],
4719
+ }
4720
+ : null;
4721
+ process.stderr.write(JSON.stringify({
4722
+ type: "ues_controller_direct",
4723
+ controllerUsed: true,
4724
+ controllerPass,
4725
+ details: telemetryDetails,
4726
+ }) + "\n");
4727
+ }
4728
+
4729
+ pi.sendMessage({
4730
+ customType: "ues-controller-result",
4731
+ content,
4732
+ display: true,
4733
+ details: {
4734
+ controllerUsed: true,
4735
+ controllerPass,
4736
+ admission,
4737
+ admissionRoute: admissionDecision?.route || (admission === "command" ? "command" : "auto"),
4738
+ admissionConfidence: admissionDecision?.confidence || null,
4739
+ admissionReason: admissionDecision?.reason || null,
4740
+ ...(result?.details || {}),
4741
+ },
4742
+ });
4743
+
4744
+ try {
4745
+ ctx.ui.notify(
4746
+ controllerPass ? "UES " + PACKAGE_VERSION + ": verified controller run completed" : "UES " + PACKAGE_VERSION + ": controller run failed verification",
4747
+ controllerPass ? "info" : "error",
4748
+ );
4749
+ } catch {}
4750
+
4751
+ };
4752
+
4753
+ pi.registerCommand("ues-run", {
4754
+ description: "Run an engineering task directly through the deterministic UES controller",
4755
+ handler: async (args, ctx) => {
4756
+ const task = String(args || "").trim();
4757
+ if (!task) {
4758
+ try { ctx.ui.notify("Usage: /ues-run <engineering task>", "warning"); } catch {}
4759
+ return;
4760
+ }
4761
+ await directControllerRunner?.(task, ctx, "command");
4762
+ },
3167
4763
  });
3168
4764
 
3169
4765
  pi.registerTool({
@@ -3293,7 +4889,11 @@ export default function (pi: ExtensionAPI) {
3293
4889
  }
3294
4890
 
3295
4891
  let completed = 0;
3296
- const results = await mapLimit(tasks, MAX_CONCURRENCY, async (item) => {
4892
+ const dispatchHasWriters = tasks.some((item) => WRITE_AGENTS.has(item.agent));
4893
+ const dispatchConcurrency = dispatchHasWriters
4894
+ ? Math.min(MAX_CONCURRENCY, MAX_WRITER_CONCURRENCY)
4895
+ : MAX_CONCURRENCY;
4896
+ const results = await mapLimit(tasks, dispatchConcurrency, async (item) => {
3297
4897
  const result = await runRoutedAgent(
3298
4898
  item.agent as AgentName,
3299
4899
  item.task,