opencode-agent-skill 14.4.0 → 15.1.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 (53) hide show
  1. package/README.md +34 -16
  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 +38 -5
  13. package/lib/capability-fabric.mjs +17 -0
  14. package/lib/code-intelligence/index.mjs +3 -2
  15. package/lib/code-intelligence/lsp-provider.mjs +326 -52
  16. package/lib/compaction-resume-guard.mjs +255 -0
  17. package/lib/completion-auditor.mjs +25 -5
  18. package/lib/context-engine-v11.mjs +20 -7
  19. package/lib/evidence-store.mjs +92 -8
  20. package/lib/execution-contract.mjs +592 -0
  21. package/lib/leaf-runtime-optimizer.mjs +76 -0
  22. package/lib/memory-engine.mjs +189 -16
  23. package/lib/performance-fabric.mjs +262 -107
  24. package/lib/pi-child-invocation.mjs +65 -0
  25. package/lib/pi-rpc-pool.mjs +61 -9
  26. package/lib/plan-salvage.mjs +124 -0
  27. package/lib/planning-speed-policy.mjs +131 -0
  28. package/lib/repo-graph.mjs +1 -1
  29. package/lib/repo-inspect.mjs +1 -0
  30. package/lib/runtime-artifacts.mjs +42 -0
  31. package/lib/runtime-events.mjs +33 -1
  32. package/lib/safety.mjs +1 -0
  33. package/lib/semantic-index.mjs +1 -1
  34. package/lib/service-manager.mjs +526 -0
  35. package/lib/session-display.mjs +49 -0
  36. package/lib/subagent-artifacts.mjs +182 -0
  37. package/lib/task-graph.mjs +87 -0
  38. package/lib/task-policy.mjs +150 -4
  39. package/lib/trajectory.mjs +111 -1
  40. package/lib/turbo-fast-path.mjs +44 -0
  41. package/lib/verification-broker.mjs +32 -27
  42. package/lib/workspace-fingerprint.mjs +45 -19
  43. package/lib/workspace-hygiene.mjs +481 -0
  44. package/lib/workspace-root.mjs +49 -0
  45. package/lib/worktree-sandbox.mjs +234 -11
  46. package/package.json +8 -5
  47. package/pi/extensions/ues-child-runtime.ts +170 -4
  48. package/pi/extensions/ues.ts +2063 -188
  49. package/scripts/check-release-consistency.mjs +25 -2
  50. package/scripts/check-source-integrity.mjs +471 -4
  51. package/scripts/eval-pi.mjs +76 -36
  52. package/scripts/smoke-pi-extension.mjs +1 -1
  53. 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,15 +25,28 @@ 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 { createSubagentArtifact, failSubagentArtifact, finalizeSubagentArtifact, listSubagentArtifacts, readSubagentArtifact } from "../../lib/subagent-artifacts.mjs";
39
+ import { buildExecutionContract, buildFinalVerdictMatrix, captureInheritedDirtyState, detectInheritedDirtyViolations, enforcePhaseGates, executionContractPrompt, phaseArtifactPayloads, taskExplicitlyAllowsLocalEnvWrite } from "../../lib/execution-contract.mjs";
40
+ import { buildCompactionResumeGuard, checkpointDurableWorkBeforeCompaction, renderCompactionResumeGuard } from "../../lib/compaction-resume-guard.mjs";
41
+ import { sessionNameFromUesInput, uesSessionName } from "../../lib/session-display.mjs";
42
+ import { requireGitWorkspaceRoot, resolveGitWorkspaceRoot } from "../../lib/workspace-root.mjs";
43
+ import { createAdaptiveDeadline } from "../../lib/activity-deadline.mjs";
44
+ import { extractValidatedPlan } from "../../lib/plan-salvage.mjs";
32
45
  import { auditCompletion } from "../../lib/completion-auditor.mjs";
33
46
  import { mcpExecutionPolicy } from "../../lib/mcp-tool-policy.mjs";
34
47
  import { McpHealthTracker } from "../../lib/mcp-health.mjs";
35
- import { runtimeWorkspaceFingerprint, runtimeWorkspaceSnapshot } from "../../lib/workspace-fingerprint.mjs";
48
+ import { captureWorkspaceStateV2, runtimeWorkspaceFingerprint, runtimeWorkspaceSnapshot } from "../../lib/workspace-fingerprint.mjs";
49
+ import { captureWorkspaceHygieneBaseline, postRunFileHygiene, preFinalWorkspaceAudit } from "../../lib/workspace-hygiene.mjs";
36
50
  import { appendTrajectoryEvent, createTraceID } from "../../lib/trajectory.mjs";
37
51
  import {
38
52
  browserEvidenceNeeded,
@@ -47,14 +61,37 @@ import {
47
61
  integrateTaskSandbox,
48
62
  removeTaskSandbox,
49
63
  rollbackTaskSandbox,
64
+ pruneOrphanTaskSandboxes,
65
+ taskSandboxOwnerRoot,
50
66
  } from "../../lib/worktree-sandbox.mjs";
67
+ import {
68
+ looksLikeLongRunningServiceCommand,
69
+ restartService,
70
+ serviceLogs,
71
+ serviceStatus,
72
+ startService,
73
+ stopAllServices,
74
+ stopService,
75
+ waitForService,
76
+ } from "../../lib/service-manager.mjs";
51
77
 
52
78
  const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
79
+ const PACKAGE_VERSION = (() => {
80
+ try {
81
+ return String(JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, "package.json"), "utf8"))?.version || "unknown");
82
+ } catch {
83
+ return "unknown";
84
+ }
85
+ })();
53
86
  const OCSKILL_BIN = path.join(PACKAGE_ROOT, "bin", "ocskill.mjs");
54
87
  const CHILD_RUNTIME_EXTENSION = path.join(PACKAGE_ROOT, "pi", "extensions", "ues-child-runtime.ts");
55
88
  const AGENT_DIR = path.join(PACKAGE_ROOT, "global-config", "agents");
56
89
  const MAX_PARALLEL_TASKS = 8;
57
90
  const MAX_CONCURRENCY = 4;
91
+ const MAX_WRITER_CONCURRENCY = Math.max(
92
+ 1,
93
+ Math.min(4, Number(process.env.UES_MAX_WRITER_CONCURRENCY || (process.platform === "win32" ? 2 : 3))),
94
+ );
58
95
  const OUTPUT_LIMIT = 512 * 1024;
59
96
 
60
97
  function configuredDuration(name: string, fallback: number, min: number, max: number) {
@@ -93,6 +130,12 @@ const POST_TOOL_ERROR_IDLE_TIMEOUT_MS = configuredDuration(
93
130
  5_000,
94
131
  5 * 60_000,
95
132
  );
133
+ const TURBO_FAST_TIMEOUTS = turboFastTimeoutBudget({
134
+ hardTimeoutMs: configuredDuration("UES_FAST_CHILD_HARD_TIMEOUT_MS", 180_000, 30_000, 10 * 60_000),
135
+ idleTimeoutMs: configuredDuration("UES_FAST_CHILD_IDLE_TIMEOUT_MS", 60_000, 20_000, 5 * 60_000),
136
+ postToolErrorIdleTimeoutMs: configuredDuration("UES_FAST_POST_TOOL_ERROR_IDLE_TIMEOUT_MS", 30_000, 5_000, 2 * 60_000),
137
+ verificationTimeoutSec: configuredDuration("UES_FAST_VERIFICATION_TIMEOUT_SEC", 90, 30, 300),
138
+ });
96
139
  const MODEL_VISIBLE_OUTPUT_LIMIT = configuredDuration(
97
140
  "UES_MODEL_VISIBLE_OUTPUT_LIMIT",
98
141
  64 * 1024,
@@ -160,6 +203,7 @@ function abortActiveCliChildren() {
160
203
 
161
204
  let HOST_BROWSER_TOOL_NAMES: string[] = [];
162
205
  const CONTEXT_PACK_CACHE = new Map<string, any>();
206
+ const ACTIVE_TASK_SANDBOXES = new Map<string, string>();
163
207
 
164
208
  function configuredBrowserToolNames() {
165
209
  return String(process.env.UES_BROWSER_MCP_TOOL_NAMES || "")
@@ -231,6 +275,7 @@ type RunResult = {
231
275
  browserTools?: string[];
232
276
  childRuntime?: "rpc" | "cli";
233
277
  workerReused?: boolean;
278
+ subagentArtifact?: any;
234
279
  optimizations?: any;
235
280
  };
236
281
 
@@ -257,6 +302,8 @@ function getAgentPrompt(agent: AgentName) {
257
302
  "- Do not call OpenCode-only dispatch tools such as \`ues.dispatch_task\` or \`ues.dispatch_parallel\`.",
258
303
  "- Respect the original role's edit/read-only boundary and return evidence to the parent Pi session.",
259
304
  "- 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.",
305
+ "- 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.",
306
+ "- 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
307
  "- 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
308
  "",
262
309
  ].join("\n");
@@ -272,16 +319,8 @@ function getAgentPrompt(agent: AgentName) {
272
319
  }
273
320
 
274
321
  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 };
322
+ const invocation = resolvePiChildInvocation(args);
323
+ return { command: invocation.command, args: invocation.args };
285
324
  }
286
325
 
287
326
  function extractAssistantText(message: any): string {
@@ -345,6 +384,83 @@ async function runOcskillJson(args: string[], cwd: string, signal?: AbortSignal)
345
384
  }
346
385
  }
347
386
 
387
+ async function persistExecutionContractArtifacts(dir: string, contract: any) {
388
+ if (!contract || !dir) return null;
389
+ const phasesDir = path.join(dir, "phases");
390
+ await fs.promises.mkdir(phasesDir, { recursive: true });
391
+ await fs.promises.writeFile(
392
+ path.join(dir, "EXECUTION_CONTRACT.json"),
393
+ JSON.stringify(contract, null, 2) + "\n",
394
+ "utf8",
395
+ );
396
+ await fs.promises.writeFile(
397
+ path.join(phasesDir, "MANIFEST.json"),
398
+ JSON.stringify({
399
+ schemaVersion: 1,
400
+ taskHash: contract.taskHash,
401
+ phaseCount: contract.phases?.length || 0,
402
+ artifacts: phaseArtifactPayloads(contract).map((item: any) => item.file),
403
+ }, null, 2) + "\n",
404
+ "utf8",
405
+ );
406
+ for (const item of phaseArtifactPayloads(contract)) {
407
+ const target = path.join(dir, item.file);
408
+ await fs.promises.mkdir(path.dirname(target), { recursive: true });
409
+ await fs.promises.writeFile(target, JSON.stringify(item.value, null, 2) + "\n", "utf8");
410
+ }
411
+ return {
412
+ contract: path.join(dir, "EXECUTION_CONTRACT.json"),
413
+ manifest: path.join(phasesDir, "MANIFEST.json"),
414
+ phaseCount: contract.phases?.length || 0,
415
+ };
416
+ }
417
+
418
+ async function finalizeExecutionContractArtifacts(
419
+ dir: string,
420
+ contract: any,
421
+ verdictMatrix: any,
422
+ evidence: string,
423
+ ) {
424
+ if (!dir || !contract) return null;
425
+ const payload = {
426
+ schemaVersion: 1,
427
+ verdictMatrix,
428
+ evidence: cap(evidence || "", 12000),
429
+ finalizedAt: new Date().toISOString(),
430
+ };
431
+ await fs.promises.writeFile(
432
+ path.join(dir, "FINAL_VERDICTS.json"),
433
+ JSON.stringify(payload, null, 2) + "\n",
434
+ "utf8",
435
+ );
436
+
437
+ for (const item of phaseArtifactPayloads(contract)) {
438
+ const phaseText = String(item.value.title || "") + "\n" + String(item.value.sourceBody || "");
439
+ let status = verdictMatrix?.source === "SOURCE_PASS" ? "VERIFIED" : "NOT_VERIFIED";
440
+ if (/device|expo go|thiết bị/i.test(phaseText) && verdictMatrix?.device !== "DEVICE_PASS") {
441
+ status = "NOT_VERIFIED";
442
+ }
443
+ if (/(?:cleanup|fixture|database|db|dữ liệu)/i.test(phaseText) && contract.gates?.dbClean === true && verdictMatrix?.dbClean !== "DB_CLEAN_PASS") {
444
+ status = "NOT_VERIFIED";
445
+ }
446
+ 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") {
447
+ status = "NOT_VERIFIED";
448
+ }
449
+ const target = path.join(dir, item.file);
450
+ await fs.promises.writeFile(
451
+ target,
452
+ JSON.stringify({
453
+ ...item.value,
454
+ status,
455
+ finalVerdicts: verdictMatrix,
456
+ evidence: [cap(evidence || "", 6000)],
457
+ }, null, 2) + "\n",
458
+ "utf8",
459
+ );
460
+ }
461
+ return payload;
462
+ }
463
+
348
464
  async function initializeDurableControllerWork(
349
465
  root: string,
350
466
  originalTask: string,
@@ -540,9 +656,22 @@ async function runAgentCli(
540
656
  compactToolOutput?: boolean;
541
657
  toolOutputLimit?: number;
542
658
  verificationTimeoutSec?: number;
659
+ hardTimeoutMs?: number;
660
+ absoluteHardTimeoutMs?: number;
661
+ activityExtensionMs?: number;
662
+ activityWindowMs?: number;
663
+ idleTimeoutMs?: number;
664
+ postToolErrorIdleTimeoutMs?: number;
665
+ allowLocalEnvWrite?: boolean;
543
666
  } = {},
544
667
  ): Promise<RunResult> {
545
668
  const config = AGENTS[agent];
669
+ const hardTimeoutMs = Number(runtimeOptions.hardTimeoutMs || CHILD_HARD_TIMEOUT_MS);
670
+ const absoluteHardTimeoutMs = Number(runtimeOptions.absoluteHardTimeoutMs || hardTimeoutMs);
671
+ const activityExtensionMs = Number(runtimeOptions.activityExtensionMs || 0);
672
+ const activityWindowMs = Number(runtimeOptions.activityWindowMs || Math.max(5_000, Math.min(activityExtensionMs || hardTimeoutMs, 30_000)));
673
+ const idleTimeoutMs = Number(runtimeOptions.idleTimeoutMs || CHILD_IDLE_TIMEOUT_MS);
674
+ const postToolErrorIdleTimeoutMs = Number(runtimeOptions.postToolErrorIdleTimeoutMs || POST_TOOL_ERROR_IDLE_TIMEOUT_MS);
546
675
  const args: string[] = [
547
676
  "--mode", "json", "-p", "--no-session",
548
677
  // Keep extension discovery enabled so custom model providers (for example
@@ -559,6 +688,7 @@ async function runAgentCli(
559
688
  const allowedTools = [...new Set([
560
689
  ...config.tools,
561
690
  ...codeIntelligenceTools,
691
+ "ues_service",
562
692
  ...extraTools,
563
693
  ...(runtimeOptions.compactToolOutput ? ["ues_evidence_get"] : []),
564
694
  ])];
@@ -588,9 +718,11 @@ async function runAgentCli(
588
718
  env: {
589
719
  ...process.env,
590
720
  UES_CHILD_PROCESS: "1",
721
+ UES_CHILD_AGENT: agent,
591
722
  UES_CHILD_TOOL_COMPACTION: runtimeOptions.compactToolOutput ? "1" : "0",
592
723
  UES_CHILD_TOOL_OUTPUT_LIMIT: String(runtimeOptions.toolOutputLimit || 24 * 1024),
593
724
  UES_CHILD_VERIFICATION_TIMEOUT_SEC: String(runtimeOptions.verificationTimeoutSec || 300),
725
+ UES_CHILD_ALLOW_LOCAL_ENV_WRITE: runtimeOptions.allowLocalEnvWrite ? "1" : "0",
594
726
  },
595
727
  shell: false,
596
728
  detached: process.platform !== "win32",
@@ -599,6 +731,12 @@ async function runAgentCli(
599
731
  });
600
732
  const childStartedAt = Date.now();
601
733
  let lastActivityAt = childStartedAt;
734
+ const adaptiveDeadline = createAdaptiveDeadline({
735
+ hardTimeoutMs,
736
+ absoluteHardTimeoutMs,
737
+ activityExtensionMs,
738
+ activityWindowMs,
739
+ }, childStartedAt);
602
740
  let buffer = "";
603
741
  let settled = false;
604
742
  let heartbeatTimer: ReturnType<typeof setInterval> | null = null;
@@ -722,19 +860,20 @@ async function runAgentCli(
722
860
  heartbeatTimer.unref?.();
723
861
  watchdogTimer = setInterval(() => {
724
862
  const now = Date.now();
725
- if (now - childStartedAt >= CHILD_HARD_TIMEOUT_MS) {
863
+ const deadline = adaptiveDeadline.shouldAbort(now, lastActivityAt);
864
+ if (deadline.abort) {
726
865
  terminateForTimeout("hard");
727
866
  return;
728
867
  }
729
868
  if (
730
869
  lastToolErrorAt > 0 &&
731
- now - lastToolErrorAt >= POST_TOOL_ERROR_IDLE_TIMEOUT_MS &&
732
- now - lastActivityAt >= POST_TOOL_ERROR_IDLE_TIMEOUT_MS
870
+ now - lastToolErrorAt >= postToolErrorIdleTimeoutMs &&
871
+ now - lastActivityAt >= postToolErrorIdleTimeoutMs
733
872
  ) {
734
873
  terminateForTimeout("post-tool-error");
735
874
  return;
736
875
  }
737
- if (now - lastActivityAt >= CHILD_IDLE_TIMEOUT_MS) {
876
+ if (now - lastActivityAt >= idleTimeoutMs) {
738
877
  terminateForTimeout("idle");
739
878
  }
740
879
  }, 1000);
@@ -787,8 +926,13 @@ async function runAgentCli(
787
926
  lastToolErrorEvidence = "";
788
927
  }
789
928
  }
790
- if (event.type === "message_update" && event.usage) {
791
- usage = event.usage;
929
+ if (event.type === "message_update") {
930
+ if (event.usage) usage = event.usage;
931
+ if (event.message?.role === "assistant") {
932
+ const partial = extractAssistantText(event.message);
933
+ if (partial) output = partial;
934
+ seenModel = event.message.model || seenModel;
935
+ }
792
936
  }
793
937
  if (event.type === "message_end" && event.message) {
794
938
  const text = extractAssistantText(event.message);
@@ -897,9 +1041,22 @@ async function runAgentRpc(
897
1041
  compactToolOutput?: boolean;
898
1042
  toolOutputLimit?: number;
899
1043
  verificationTimeoutSec?: number;
1044
+ hardTimeoutMs?: number;
1045
+ absoluteHardTimeoutMs?: number;
1046
+ activityExtensionMs?: number;
1047
+ activityWindowMs?: number;
1048
+ idleTimeoutMs?: number;
1049
+ postToolErrorIdleTimeoutMs?: number;
1050
+ allowLocalEnvWrite?: boolean;
900
1051
  } = {},
901
1052
  ): Promise<RunResult> {
902
1053
  const config = AGENTS[agent];
1054
+ const hardTimeoutMs = Number(runtimeOptions.hardTimeoutMs || CHILD_HARD_TIMEOUT_MS);
1055
+ const absoluteHardTimeoutMs = Number(runtimeOptions.absoluteHardTimeoutMs || hardTimeoutMs);
1056
+ const activityExtensionMs = Number(runtimeOptions.activityExtensionMs || 0);
1057
+ const activityWindowMs = Number(runtimeOptions.activityWindowMs || Math.max(5_000, Math.min(activityExtensionMs || hardTimeoutMs, 30_000)));
1058
+ const idleTimeoutMs = Number(runtimeOptions.idleTimeoutMs || CHILD_IDLE_TIMEOUT_MS);
1059
+ const postToolErrorIdleTimeoutMs = Number(runtimeOptions.postToolErrorIdleTimeoutMs || POST_TOOL_ERROR_IDLE_TIMEOUT_MS);
903
1060
  const args: string[] = [
904
1061
  "--mode", "rpc", "--no-session",
905
1062
  "--no-skills", "--no-prompt-templates", "--no-context-files",
@@ -907,8 +1064,13 @@ async function runAgentRpc(
907
1064
  ];
908
1065
  if (model) args.push("--model", model);
909
1066
  if (thinkingLevel) args.push("--thinking", thinkingLevel);
1067
+ const codeIntelligenceTools = WRITE_AGENTS.has(agent)
1068
+ ? ["ues_code", "ues_code_edit"]
1069
+ : ["ues_code"];
910
1070
  const allowedTools = [...new Set([
911
1071
  ...config.tools,
1072
+ ...codeIntelligenceTools,
1073
+ "ues_service",
912
1074
  ...extraTools,
913
1075
  ...(runtimeOptions.compactToolOutput ? ["ues_evidence_get"] : []),
914
1076
  ])];
@@ -924,6 +1086,7 @@ async function runAgentRpc(
924
1086
  Boolean(runtimeOptions.compactToolOutput),
925
1087
  Number(runtimeOptions.toolOutputLimit || 0),
926
1088
  Number(runtimeOptions.verificationTimeoutSec || 0),
1089
+ Boolean(runtimeOptions.allowLocalEnvWrite),
927
1090
  ]);
928
1091
  const taskInput = `Task: ${task}\n`;
929
1092
  const startedAt = Date.now();
@@ -960,17 +1123,22 @@ async function runAgentRpc(
960
1123
  env: {
961
1124
  ...process.env,
962
1125
  UES_CHILD_PROCESS: "1",
1126
+ UES_CHILD_AGENT: agent,
963
1127
  UES_CHILD_TOOL_COMPACTION: runtimeOptions.compactToolOutput ? "1" : "0",
964
1128
  UES_CHILD_TOOL_OUTPUT_LIMIT: String(runtimeOptions.toolOutputLimit || 24 * 1024),
965
1129
  UES_CHILD_VERIFICATION_TIMEOUT_SEC: String(runtimeOptions.verificationTimeoutSec || 300),
1130
+ UES_CHILD_ALLOW_LOCAL_ENV_WRITE: runtimeOptions.allowLocalEnvWrite ? "1" : "0",
966
1131
  },
967
1132
  },
968
1133
  taskInput,
969
1134
  {
970
1135
  signal,
971
- hardTimeoutMs: CHILD_HARD_TIMEOUT_MS,
972
- idleTimeoutMs: CHILD_IDLE_TIMEOUT_MS,
973
- postToolErrorIdleTimeoutMs: POST_TOOL_ERROR_IDLE_TIMEOUT_MS,
1136
+ hardTimeoutMs,
1137
+ absoluteHardTimeoutMs,
1138
+ activityExtensionMs,
1139
+ activityWindowMs,
1140
+ idleTimeoutMs,
1141
+ postToolErrorIdleTimeoutMs,
974
1142
  onEvent: (event: any) => {
975
1143
  lastActivityAt = Date.now();
976
1144
  if (event.type === "tool_execution_start") {
@@ -1072,12 +1240,16 @@ async function runAgentRpc(
1072
1240
  if ((error as any)?.uesRpcPhase === "runtime") {
1073
1241
  const timeout = /hard-timeout|idle-timeout/i.test(message);
1074
1242
  const toolStall = /post-tool-error-stall/i.test(message);
1243
+ const partialOutput = extractAssistantText((error as any)?.partialMessage);
1244
+ const recoveredOutput = partialOutput
1245
+ ? partialOutput + "\n\n[UES transport note: " + message + "]"
1246
+ : message;
1075
1247
  return {
1076
1248
  agent,
1077
1249
  task,
1078
1250
  cwd,
1079
1251
  exitCode: timeout ? 124 : toolStall ? 125 : 1,
1080
- output: message,
1252
+ output: recoveredOutput,
1081
1253
  stderr: message,
1082
1254
  model,
1083
1255
  stopReason: timeout ? "timeout" : toolStall ? "tool-error-stall" : "rpc-runtime-error",
@@ -1109,6 +1281,13 @@ async function runAgent(
1109
1281
  compactToolOutput?: boolean;
1110
1282
  toolOutputLimit?: number;
1111
1283
  verificationTimeoutSec?: number;
1284
+ hardTimeoutMs?: number;
1285
+ absoluteHardTimeoutMs?: number;
1286
+ activityExtensionMs?: number;
1287
+ activityWindowMs?: number;
1288
+ idleTimeoutMs?: number;
1289
+ postToolErrorIdleTimeoutMs?: number;
1290
+ allowLocalEnvWrite?: boolean;
1112
1291
  } = {},
1113
1292
  ): Promise<RunResult> {
1114
1293
  if (CHILD_RUNTIME !== "cli") {
@@ -1251,9 +1430,37 @@ function cachedContextKey(
1251
1430
  role: string,
1252
1431
  budget: number,
1253
1432
  fingerprint = "unknown",
1433
+ namespace = cwd,
1254
1434
  ) {
1255
1435
  const auxStamp = runtimeContextAuxStamp(cwd);
1256
- return [cwd, fingerprint, auxStamp, role, String(budget), task].join("\u0000");
1436
+ return [path.resolve(namespace), fingerprint, auxStamp, role, String(budget), task].join("\u0000");
1437
+ }
1438
+
1439
+ function deepExplorationContract(role: string) {
1440
+ const common = [
1441
+ "## UES DEEP bounded exploration",
1442
+ "Quality gates remain unchanged. Reduce latency by avoiding duplicate discovery, not by skipping evidence.",
1443
+ "Use the supplied runtime context pack, hierarchy, ranked references and declared files before broad repository exploration.",
1444
+ "Prefer targeted ues_code/direct reads. Do not inventory the repository or repeat unchanged reads unless a named evidence gap requires it.",
1445
+ ];
1446
+ if (role === "architect") {
1447
+ common.push(
1448
+ "Stop exploring once every planned task has exact repository-relative scope, dependency ordering, observable acceptance, concrete verification, and risk/rollback coverage.",
1449
+ );
1450
+ } else if (role === "plan-checker") {
1451
+ common.push(
1452
+ "Inspect only disputed or unproven plan properties; once each blocking property is proven or rejected, return PASS/REVISE immediately.",
1453
+ );
1454
+ } else if (role === "executor") {
1455
+ common.push(
1456
+ "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.",
1457
+ );
1458
+ } else if (role === "debugger") {
1459
+ common.push(
1460
+ "Investigate only the concrete failure path and nearest evidence needed to reject/confirm the active hypothesis; avoid general repository surveys.",
1461
+ );
1462
+ }
1463
+ return common.join("\n");
1257
1464
  }
1258
1465
 
1259
1466
  function compactContextPack(pack: any, recentFailure?: string) {
@@ -1304,20 +1511,39 @@ async function runRoutedAgent(
1304
1511
  signal?: AbortSignal,
1305
1512
  onProgress?: Parameters<typeof runAgent>[6],
1306
1513
  traceID?: string,
1514
+ taskPolicyOverride?: any,
1515
+ contextCacheNamespace?: string,
1307
1516
  ): Promise<RunResult> {
1517
+ const routedStartedAt = Date.now();
1308
1518
  const role = roleForAgent(agent);
1519
+ const traceRoot = requireGitWorkspaceRoot(cwd, "UES specialist");
1520
+ const workspaceSnapshotStartedAt = Date.now();
1521
+ let agentWorkspaceState: any = null;
1522
+ let workspaceState: any = {
1523
+ cacheable: false,
1524
+ fingerprint: "unknown",
1525
+ changedFiles: [],
1526
+ };
1527
+ try {
1528
+ agentWorkspaceState = captureWorkspaceStateV2(cwd);
1529
+ workspaceState = runtimeWorkspaceSnapshot(cwd, { workspaceState: agentWorkspaceState });
1530
+ } catch {}
1531
+ const agentHygieneBaseline = captureWorkspaceHygieneBaseline(cwd, {
1532
+ workspaceState: agentWorkspaceState,
1533
+ });
1534
+ const workspaceSnapshotMs = Date.now() - workspaceSnapshotStartedAt;
1309
1535
  const browserRequested = browserEvidenceNeeded(task, role);
1310
1536
  const browserTools = browserRequested
1311
1537
  ? selectBrowserToolsForTask(HOST_BROWSER_TOOL_NAMES, task, role)
1312
1538
  : [];
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;
1539
+ const taskPolicy = taskPolicyOverride || classifyEngineeringTask(task);
1540
+ const turboFast = turboFastPathDecision(taskPolicy, {
1541
+ role,
1542
+ attempt,
1543
+ browserRequested,
1544
+ visualRequired: visualEvidenceNeeded(task),
1545
+ });
1546
+ const fastBoundedContext = turboFast.eligible;
1321
1547
  const budgetDecision = adaptiveContextBudget(taskPolicy, role, attempt, {
1322
1548
  disabled: !ADAPTIVE_CONTEXT_ENABLED,
1323
1549
  });
@@ -1332,7 +1558,7 @@ async function runRoutedAgent(
1332
1558
  const modelPolicy = await readModelPolicy(getUesConfigDir());
1333
1559
  const selection = resolveCapabilityModel(role, attempt, task, taskPolicy, modelPolicy);
1334
1560
  if (traceID) {
1335
- await appendTrajectoryEvent(cwd, traceID, "agent.started", {
1561
+ await appendTrajectoryEvent(traceRoot, traceID, "agent.started", {
1336
1562
  agent,
1337
1563
  role,
1338
1564
  attempt,
@@ -1367,14 +1593,6 @@ async function runRoutedAgent(
1367
1593
  ? undefined
1368
1594
  : inheritedThinking;
1369
1595
 
1370
- let workspaceState: any = {
1371
- cacheable: false,
1372
- fingerprint: "unknown",
1373
- changedFiles: [],
1374
- };
1375
- try {
1376
- workspaceState = runtimeWorkspaceSnapshot(cwd);
1377
- } catch {}
1378
1596
  const workspaceFingerprint = String(workspaceState.fingerprint || "unknown");
1379
1597
 
1380
1598
  let enrichedTask = task;
@@ -1384,6 +1602,8 @@ async function runRoutedAgent(
1384
1602
  let affectedTests: any = null;
1385
1603
  let reusableVerification: any = null;
1386
1604
  let contextCacheHit = false;
1605
+ let contextPerformance: any = null;
1606
+ const contextBuildStartedAt = Date.now();
1387
1607
  try {
1388
1608
  if (fastBoundedContext) {
1389
1609
  contextQuality = { schemaVersion: 1, profile: "fast-bounded", bounded: true };
@@ -1397,12 +1617,17 @@ async function runRoutedAgent(
1397
1617
  : "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
1618
  ].join("\n");
1399
1619
  } else {
1620
+ const cacheBudgetKey =
1621
+ ["architect", "plan-checker"].includes(role)
1622
+ ? Number(budgetDecision.baseBudget || budgetDecision.budget)
1623
+ : budgetDecision.budget;
1400
1624
  const cacheKey = cachedContextKey(
1401
1625
  cwd,
1402
1626
  task,
1403
1627
  role,
1404
- budgetDecision.budget,
1628
+ cacheBudgetKey,
1405
1629
  workspaceFingerprint,
1630
+ contextCacheNamespace || cwd,
1406
1631
  );
1407
1632
  const cacheableContext =
1408
1633
  workspaceState.cacheable === true &&
@@ -1431,8 +1656,9 @@ async function runRoutedAgent(
1431
1656
  cwd,
1432
1657
  task,
1433
1658
  role,
1434
- budgetDecision.budget,
1659
+ cacheBudgetKey,
1435
1660
  workspaceFingerprint,
1661
+ contextCacheNamespace || cwd,
1436
1662
  );
1437
1663
  if (postBuildKey !== cacheKey) rememberContextPack(postBuildKey, pack);
1438
1664
  }
@@ -1473,6 +1699,7 @@ async function runRoutedAgent(
1473
1699
  }
1474
1700
 
1475
1701
  contextQuality = pack.contextQuality;
1702
+ contextPerformance = pack.performance || null;
1476
1703
  enrichedTask = [
1477
1704
  task,
1478
1705
  "",
@@ -1499,6 +1726,10 @@ async function runRoutedAgent(
1499
1726
  row.stdoutPreview ? ` preview: ${cap(String(row.stdoutPreview).replace(/\s+/g, " "), 900)}` : "",
1500
1727
  ].filter(Boolean).join("\n")).join("\n")
1501
1728
  : "",
1729
+ taskPolicy.executionProfile === "deep" &&
1730
+ ["architect", "plan-checker", "executor", "debugger"].includes(role)
1731
+ ? "\n" + deepExplorationContract(role)
1732
+ : "",
1502
1733
  ].filter(Boolean).join("\n");
1503
1734
  }
1504
1735
  } catch (error) {
@@ -1507,6 +1738,7 @@ async function runRoutedAgent(
1507
1738
  enrichedTask += "\n\n## Previous failed verification\n" + cap(recentFailure, 5000);
1508
1739
  }
1509
1740
  }
1741
+ const contextBuildMs = Date.now() - contextBuildStartedAt;
1510
1742
 
1511
1743
  if (browserRequested) {
1512
1744
  enrichedTask += browserTools.length
@@ -1525,8 +1757,40 @@ async function runRoutedAgent(
1525
1757
  ].join("\n");
1526
1758
  }
1527
1759
 
1760
+ const planningBudget = planningRuntimeBudget(role, attempt, {
1761
+ executionProfile: taskPolicy.executionProfile,
1762
+ risk: taskPolicy.risk,
1763
+ taskChars: task.length,
1764
+ });
1528
1765
  const startedAt = Date.now();
1529
- const result = await runAgent(
1766
+ const artifactRoot = await taskSandboxOwnerRoot(cwd).catch(() => null) || traceRoot;
1767
+ const childArtifact = await createSubagentArtifact(artifactRoot, {
1768
+ agent,
1769
+ role,
1770
+ attempt,
1771
+ task,
1772
+ traceID,
1773
+ model: selectedModel,
1774
+ modelTier: selection.tier,
1775
+ workspaceFingerprint,
1776
+ }).catch(() => null);
1777
+ if (childArtifact?.handle) {
1778
+ try {
1779
+ onProgress?.({
1780
+ agent,
1781
+ elapsedMs: 0,
1782
+ idleMs: 0,
1783
+ toolCalls: 0,
1784
+ model: selectedModel,
1785
+ phase: "running",
1786
+ note: `subagent handle ${childArtifact.handle}; durable status ${childArtifact.file}`,
1787
+ });
1788
+ } catch {}
1789
+ }
1790
+ let result: RunResult;
1791
+ const modelRunStartedAt = Date.now();
1792
+ try {
1793
+ result = await runAgent(
1530
1794
  agent,
1531
1795
  enrichedTask,
1532
1796
  cwd,
@@ -1546,15 +1810,90 @@ async function runRoutedAgent(
1546
1810
  ? 24 * 1024
1547
1811
  : 48 * 1024,
1548
1812
  verificationTimeoutSec:
1549
- taskPolicy.risk === "high"
1550
- ? 900
1551
- : taskPolicy.executionProfile === "fast"
1552
- ? 120
1553
- : taskPolicy.executionProfile === "standard"
1554
- ? 300
1555
- : 600,
1556
- },
1557
- );
1813
+ turboFast.eligible
1814
+ ? TURBO_FAST_TIMEOUTS.verificationTimeoutSec
1815
+ : taskPolicy.risk === "high"
1816
+ ? 900
1817
+ : taskPolicy.executionProfile === "fast"
1818
+ ? 120
1819
+ : taskPolicy.executionProfile === "standard"
1820
+ ? 300
1821
+ : 600,
1822
+ hardTimeoutMs:
1823
+ turboFast.eligible
1824
+ ? TURBO_FAST_TIMEOUTS.hardTimeoutMs
1825
+ : planningBudget?.hardTimeoutMs || CHILD_HARD_TIMEOUT_MS,
1826
+ absoluteHardTimeoutMs:
1827
+ turboFast.eligible
1828
+ ? TURBO_FAST_TIMEOUTS.hardTimeoutMs
1829
+ : planningBudget?.absoluteHardTimeoutMs || CHILD_HARD_TIMEOUT_MS,
1830
+ activityExtensionMs:
1831
+ turboFast.eligible ? 0 : planningBudget?.activityExtensionMs || 0,
1832
+ activityWindowMs:
1833
+ turboFast.eligible ? 0 : planningBudget?.activityWindowMs || 0,
1834
+ idleTimeoutMs:
1835
+ turboFast.eligible
1836
+ ? TURBO_FAST_TIMEOUTS.idleTimeoutMs
1837
+ : planningBudget?.idleTimeoutMs || CHILD_IDLE_TIMEOUT_MS,
1838
+ postToolErrorIdleTimeoutMs:
1839
+ turboFast.eligible
1840
+ ? TURBO_FAST_TIMEOUTS.postToolErrorIdleTimeoutMs
1841
+ : planningBudget?.idleTimeoutMs
1842
+ ? Math.min(POST_TOOL_ERROR_IDLE_TIMEOUT_MS, planningBudget.idleTimeoutMs)
1843
+ : POST_TOOL_ERROR_IDLE_TIMEOUT_MS,
1844
+ allowLocalEnvWrite:
1845
+ taskPolicy.localEnvWriteExplicitlyAllowed === true ||
1846
+ taskExplicitlyAllowsLocalEnvWrite(task),
1847
+ },
1848
+ );
1849
+ } catch (error) {
1850
+ if (childArtifact?.handle) {
1851
+ await failSubagentArtifact(artifactRoot, childArtifact.handle, error).catch(() => null);
1852
+ }
1853
+ throw error;
1854
+ }
1855
+ const modelRunMs = Date.now() - modelRunStartedAt;
1856
+ const hygieneStartedAt = Date.now();
1857
+ const postRunHygiene = await postRunFileHygiene(cwd, {
1858
+ baseline: agentHygieneBaseline,
1859
+ taskText: task,
1860
+ allowSourceMutations: WRITE_AGENTS.has(agent),
1861
+ autoClean: true,
1862
+ }).catch((error) => ({
1863
+ schemaVersion: 1,
1864
+ safe: false,
1865
+ changed: [],
1866
+ created: [],
1867
+ removed: [],
1868
+ findings: [{
1869
+ kind: "hygiene-audit-error",
1870
+ file: ".",
1871
+ message: error instanceof Error ? error.message : String(error),
1872
+ }],
1873
+ summary: "workspace hygiene audit failed: " + (error instanceof Error ? error.message : String(error)),
1874
+ }));
1875
+ if (!postRunHygiene.safe) {
1876
+ const hygieneText = [
1877
+ "UES post-run workspace hygiene guard rejected this child run.",
1878
+ postRunHygiene.summary || "workspace hygiene failed",
1879
+ ].join("\n");
1880
+ result = {
1881
+ ...result,
1882
+ exitCode: result.exitCode === 0 ? 2 : result.exitCode,
1883
+ stopReason: "error",
1884
+ errorMessage: hygieneText,
1885
+ output: [result.output, "", hygieneText].filter(Boolean).join("\n"),
1886
+ };
1887
+ }
1888
+
1889
+ const hygieneMs = Date.now() - hygieneStartedAt;
1890
+ const finalizedChildArtifact = childArtifact?.handle
1891
+ ? await finalizeSubagentArtifact(artifactRoot, childArtifact.handle, {
1892
+ ...result,
1893
+ durationMs: Date.now() - startedAt,
1894
+ verdict: verdictFromOutput(result.output),
1895
+ }).catch(() => null)
1896
+ : null;
1558
1897
  const enrichedResult: RunResult = {
1559
1898
  ...result,
1560
1899
  task,
@@ -1581,13 +1920,39 @@ async function runRoutedAgent(
1581
1920
  !["high", "critical"].includes(String(taskPolicy.risk || "").toLowerCase()),
1582
1921
  runtimeContextBudget: budgetDecision.budget,
1583
1922
  baseContextBudget: budgetDecision.baseBudget,
1923
+ turboFastPath: turboFast.eligible,
1924
+ turboFastStrategy: turboFast.strategy,
1925
+ turboFastTimeouts: turboFast.eligible ? TURBO_FAST_TIMEOUTS : null,
1926
+ planningRuntimeBudget: planningBudget,
1927
+ affectedTestInventorySource: affectedTests?.inventorySource || null,
1928
+ contextPerformance,
1929
+ latencyMs: {
1930
+ workspaceSnapshot: workspaceSnapshotMs,
1931
+ contextBuild: contextBuildMs,
1932
+ modelRun: modelRunMs,
1933
+ hygiene: hygieneMs,
1934
+ total: Date.now() - routedStartedAt,
1935
+ },
1584
1936
  },
1585
1937
  verdict: verdictFromOutput(result.output),
1586
1938
  report: parseStructuredReport(result.output),
1587
1939
  durationMs: Date.now() - startedAt,
1940
+ subagentArtifact: finalizedChildArtifact ? {
1941
+ handle: finalizedChildArtifact.handle,
1942
+ status: finalizedChildArtifact.status,
1943
+ file: finalizedChildArtifact.file,
1944
+ taskRef: finalizedChildArtifact.taskRef,
1945
+ outputRef: finalizedChildArtifact.result?.outputRef || null,
1946
+ resume: finalizedChildArtifact.resume || null,
1947
+ } : childArtifact ? {
1948
+ handle: childArtifact.handle,
1949
+ status: childArtifact.status,
1950
+ file: childArtifact.file,
1951
+ taskRef: childArtifact.taskRef,
1952
+ } : null,
1588
1953
  };
1589
1954
  if (traceID) {
1590
- await appendTrajectoryEvent(cwd, traceID, "agent.completed", {
1955
+ await appendTrajectoryEvent(traceRoot, traceID, "agent.completed", {
1591
1956
  agent,
1592
1957
  role,
1593
1958
  attempt,
@@ -1683,19 +2048,64 @@ function extractMarkedJson(output: string, marker: string) {
1683
2048
  return null;
1684
2049
  }
1685
2050
 
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");
2051
+ function sandboxSourceIntentBatches(values: string[]) {
2052
+ const batches: string[][] = [];
2053
+ let batch: string[] = [];
2054
+ let chars = 0;
2055
+ for (const value of sourceFacingPaths(values)) {
2056
+ const cost = value.length + 3;
2057
+ if (batch.length && (batch.length >= 64 || chars + cost > 12_000)) {
2058
+ batches.push(batch);
2059
+ batch = [];
2060
+ chars = 0;
2061
+ }
2062
+ batch.push(value);
2063
+ chars += cost;
2064
+ }
2065
+ if (batch.length) batches.push(batch);
2066
+ return batches;
2067
+ }
2068
+
2069
+ async function sandboxIntentToAddSourceFiles(dir: string, signal?: AbortSignal) {
2070
+ const pathspecs = sourceGitPathspecs();
2071
+ const untracked = await runProcess(
2072
+ "git",
2073
+ ["ls-files", "--others", "--exclude-standard", "-z", "--", ...pathspecs],
2074
+ dir,
2075
+ signal,
2076
+ );
2077
+ if (untracked.exitCode !== 0) {
2078
+ throw new Error(untracked.stderr || untracked.stdout || "git ls-files for intent-to-add failed");
2079
+ }
2080
+
2081
+ const candidates = sourceFacingPaths(
2082
+ untracked.stdout
2083
+ .split("\0")
2084
+ .map((value) => value.replaceAll("\\", "/"))
2085
+ .filter(Boolean),
2086
+ );
2087
+ for (const batch of sandboxSourceIntentBatches(candidates)) {
2088
+ const intent = await runProcess("git", ["add", "-N", "--", ...batch], dir, signal);
2089
+ if (intent.exitCode !== 0) {
2090
+ throw new Error(intent.stderr || intent.stdout || "git add -N failed");
2091
+ }
1690
2092
  }
1691
- const diff = await runProcess("git", ["diff", "--name-only", base, "--"], dir, signal);
2093
+ return candidates;
2094
+ }
2095
+
2096
+ async function sandboxChangedFiles(dir: string, base: string, signal?: AbortSignal) {
2097
+ const pathspecs = sourceGitPathspecs();
2098
+ await sandboxIntentToAddSourceFiles(dir, signal);
2099
+ const diff = await runProcess("git", ["diff", "--name-only", base, "--", ...pathspecs], dir, signal);
1692
2100
  if (diff.exitCode !== 0) {
1693
2101
  throw new Error(diff.stderr || diff.stdout || "git diff --name-only failed");
1694
2102
  }
1695
- return diff.stdout
1696
- .split(/\r?\n/)
1697
- .map((value) => value.trim().replaceAll("\\", "/"))
1698
- .filter(Boolean);
2103
+ return sourceFacingPaths(
2104
+ diff.stdout
2105
+ .split(/\r?\n/)
2106
+ .map((value) => value.trim().replaceAll("\\", "/"))
2107
+ .filter(Boolean),
2108
+ );
1699
2109
  }
1700
2110
 
1701
2111
  async function cleanupSandboxes(
@@ -1704,11 +2114,30 @@ async function cleanupSandboxes(
1704
2114
  ) {
1705
2115
  for (const item of prepared) {
1706
2116
  if (!item.sandbox?.dir) continue;
1707
- await removeTaskSandbox(root, item.sandbox.dir, {
1708
- force: true,
1709
- deleteBranch: true,
1710
- }).catch(() => {});
2117
+ const resolved = path.resolve(item.sandbox.dir);
2118
+ try {
2119
+ await removeTaskSandbox(root, resolved, {
2120
+ force: true,
2121
+ deleteBranch: true,
2122
+ });
2123
+ ACTIVE_TASK_SANDBOXES.delete(resolved);
2124
+ } catch {}
2125
+ }
2126
+ }
2127
+
2128
+ async function cleanupTraceSandboxes(root: string, traceID: string) {
2129
+ const targets = [...ACTIVE_TASK_SANDBOXES.entries()]
2130
+ .filter(([, ownerTrace]) => ownerTrace === traceID)
2131
+ .map(([dir]) => dir);
2132
+ let removed = 0;
2133
+ for (const dir of targets) {
2134
+ try {
2135
+ await removeTaskSandbox(root, dir, { force: true, deleteBranch: true });
2136
+ ACTIVE_TASK_SANDBOXES.delete(dir);
2137
+ removed += 1;
2138
+ } catch {}
1711
2139
  }
2140
+ return removed;
1712
2141
  }
1713
2142
 
1714
2143
  async function executeStructuredPlan(input: {
@@ -1717,6 +2146,7 @@ async function executeStructuredPlan(input: {
1717
2146
  inheritedModel?: string;
1718
2147
  inheritedThinking?: string;
1719
2148
  maxAttempts: number;
2149
+ rootPolicy?: any;
1720
2150
  durableSlug?: string;
1721
2151
  traceID?: string;
1722
2152
  signal?: AbortSignal;
@@ -1789,6 +2219,7 @@ async function executeStructuredPlan(input: {
1789
2219
  for (let waveIndex = 0; waveIndex < safe.waves.length; waveIndex++) {
1790
2220
  const ids = safe.waves[waveIndex];
1791
2221
  let lastWaveFailure = "";
2222
+ const failureByTask = new Map<string, string>();
1792
2223
 
1793
2224
  for (let attempt = 1; attempt <= input.maxAttempts; attempt++) {
1794
2225
  const prepared: Array<{
@@ -1807,12 +2238,13 @@ async function executeStructuredPlan(input: {
1807
2238
  let cwd = input.root;
1808
2239
  let sandbox: any = undefined;
1809
2240
 
1810
- if (gitCapable) {
2241
+ if (gitCapable && writeFiles.length > 0) {
1811
2242
  const slug = "runtime-" + randomUUID().slice(0, 8) + "-w" + waveIndex + "-a" + attempt;
1812
2243
  sandbox = await createTaskSandbox(input.root, slug, id, {
1813
2244
  inheritDirtyRoot: true,
1814
2245
  });
1815
2246
  cwd = sandbox.dir;
2247
+ ACTIVE_TASK_SANDBOXES.set(path.resolve(sandbox.dir), String(input.traceID || "structured"));
1816
2248
  }
1817
2249
 
1818
2250
  prepared.push({ task, cwd, sandbox, writeFiles });
@@ -1830,22 +2262,37 @@ async function executeStructuredPlan(input: {
1830
2262
  }
1831
2263
 
1832
2264
  let completed = 0;
2265
+ const writerCount = prepared.filter((item) => item.writeFiles.length > 0).length;
2266
+ const waveConcurrency = !gitCapable
2267
+ ? 1
2268
+ : writerCount > 0
2269
+ ? Math.min(MAX_CONCURRENCY, MAX_WRITER_CONCURRENCY)
2270
+ : MAX_CONCURRENCY;
1833
2271
  const waveResults = await mapLimit(
1834
2272
  prepared,
1835
- gitCapable ? MAX_CONCURRENCY : 1,
2273
+ waveConcurrency,
1836
2274
  async (item) => {
1837
2275
  const taskText = [
1838
2276
  "Execute exactly this structured plan task.",
1839
2277
  "Do not broaden file scope. If the declared write file list is empty, do not edit files.",
2278
+ "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
2279
  "",
1841
2280
  JSON.stringify(item.task, null, 2),
1842
2281
  "",
1843
- "Overall goal:",
1844
- String(input.plan.goal || ""),
1845
- lastWaveFailure
1846
- ? "\nFresh failure evidence from the previous wave attempt:\n" + cap(lastWaveFailure, 7000)
1847
- : "",
2282
+ "Parent goal (context only; never broaden this leaf task):",
2283
+ cap(String(input.plan.goal || ""), 700),
2284
+ input.rootPolicy?.executionContractPrompt || "",
1848
2285
  ].filter(Boolean).join("\n");
2286
+ const leafPolicy = leafTaskPolicy(item.task, input.rootPolicy || {});
2287
+ const taskFailure = failureByTask.get(String(item.task.id)) || "";
2288
+ const leafVisualRequired = visualEvidenceNeeded(taskText);
2289
+ const leafFastDecision = turboFastPathDecision(leafPolicy, {
2290
+ role: "executor",
2291
+ attempt,
2292
+ browserRequested: browserEvidenceNeeded(taskText, "executor"),
2293
+ visualRequired: leafVisualRequired,
2294
+ });
2295
+ const leafAttemptStartedAt = Date.now();
1849
2296
 
1850
2297
  const plannedExecution: any = dynamicTaskByID.get(item.task.id);
1851
2298
  const deterministicReadOnly =
@@ -1978,8 +2425,8 @@ async function executeStructuredPlan(input: {
1978
2425
  "",
1979
2426
  "Overall goal:",
1980
2427
  String(input.plan.goal || ""),
1981
- lastWaveFailure
1982
- ? "\nFresh failure evidence from the previous wave attempt:\n" + cap(lastWaveFailure, 7000)
2428
+ taskFailure
2429
+ ? "\nFresh task-local failure delta from the previous attempt:\n" + cap(taskFailure, 4200)
1983
2430
  : "",
1984
2431
  ].filter(Boolean).join("\n"),
1985
2432
  item.cwd,
@@ -1990,6 +2437,8 @@ async function executeStructuredPlan(input: {
1990
2437
  input.signal,
1991
2438
  undefined,
1992
2439
  input.traceID,
2440
+ leafPolicy,
2441
+ input.root,
1993
2442
  );
1994
2443
  results.push({
1995
2444
  wave: waveIndex,
@@ -2027,8 +2476,8 @@ async function executeStructuredPlan(input: {
2027
2476
  };
2028
2477
  }
2029
2478
 
2030
- let focusedFailure = lastWaveFailure;
2031
- if (attempt > 1 && runtimeFailureNeedsDiagnosis(lastWaveFailure)) {
2479
+ let focusedFailure = taskFailure;
2480
+ if (attempt > 1 && runtimeFailureNeedsDiagnosis(taskFailure)) {
2032
2481
  const diagnosis = await runRoutedAgent(
2033
2482
  "ues-debugger",
2034
2483
  [
@@ -2038,16 +2487,18 @@ async function executeStructuredPlan(input: {
2038
2487
  JSON.stringify(item.task, null, 2),
2039
2488
  "",
2040
2489
  "Previous runtime failure:",
2041
- cap(lastWaveFailure, 7000),
2490
+ cap(taskFailure, 4200),
2042
2491
  ].join("\n"),
2043
2492
  item.cwd,
2044
2493
  input.inheritedModel,
2045
2494
  input.inheritedThinking,
2046
2495
  attempt,
2047
- lastWaveFailure,
2496
+ taskFailure,
2048
2497
  input.signal,
2049
2498
  undefined,
2050
2499
  input.traceID,
2500
+ leafPolicy,
2501
+ input.root,
2051
2502
  );
2052
2503
  results.push({
2053
2504
  wave: waveIndex,
@@ -2070,16 +2521,15 @@ async function executeStructuredPlan(input: {
2070
2521
  }
2071
2522
  }
2072
2523
 
2524
+ const retryDelta = failureDelta(focusedFailure || taskFailure);
2073
2525
  const implementation = await runRoutedAgent(
2074
2526
  "ues-executor",
2075
- taskText + (focusedFailure && focusedFailure !== lastWaveFailure
2076
- ? "\n\nFocused diagnosis before retry:\n" + cap(focusedFailure, 7000)
2077
- : ""),
2527
+ taskText,
2078
2528
  item.cwd,
2079
2529
  input.inheritedModel,
2080
2530
  input.inheritedThinking,
2081
2531
  attempt,
2082
- lastWaveFailure || undefined,
2532
+ retryDelta || undefined,
2083
2533
  input.signal,
2084
2534
  (progress) => {
2085
2535
  input.onUpdate?.({
@@ -2093,8 +2543,10 @@ async function executeStructuredPlan(input: {
2093
2543
  });
2094
2544
  },
2095
2545
  input.traceID,
2546
+ leafPolicy,
2547
+ input.root,
2096
2548
  );
2097
- results.push({ wave: waveIndex, attempt, task: item.task.id, phase: "execute", ...implementation });
2549
+ results.push({ wave: waveIndex, attempt, task: item.task.id, phase: "execute", leafPolicy, ...implementation });
2098
2550
 
2099
2551
  if (implementation.exitCode !== 0 || implementation.stopReason === "error") {
2100
2552
  if (!isAbortedRun(implementation)) {
@@ -2114,7 +2566,75 @@ async function executeStructuredPlan(input: {
2114
2566
  };
2115
2567
  }
2116
2568
 
2117
- const verification = await runRoutedAgent(
2569
+ let verification: RunResult;
2570
+ let leafFastGate: any = null;
2571
+ if (leafFastDecision.eligible) {
2572
+ const snapshot = runtimeWorkspaceSnapshot(item.cwd);
2573
+ const receipts = await listReusableVerification(item.cwd, {
2574
+ limit: 12,
2575
+ maxAgeMs: 10 * 60_000,
2576
+ previewBytes: 2200,
2577
+ ...(snapshot.cacheable === true && snapshot.fingerprint
2578
+ ? { workspaceFingerprint: snapshot.fingerprint }
2579
+ : {}),
2580
+ }).catch(() => ({ results: [] }));
2581
+ leafFastGate = evaluateFastVerificationGate({
2582
+ policy: leafPolicy,
2583
+ implementation,
2584
+ receipts: receipts?.results || [],
2585
+ attemptStartedAtMs: leafAttemptStartedAt,
2586
+ visualRequired: leafVisualRequired,
2587
+ });
2588
+ }
2589
+
2590
+ if (leafFastGate?.passed === true) {
2591
+ verification = {
2592
+ agent: "ues-deterministic-verifier",
2593
+ task: taskText,
2594
+ cwd: item.cwd,
2595
+ exitCode: 0,
2596
+ output: [
2597
+ "Per-leaf Turbo verification reused fresh behavioral evidence captured after this leaf implementation.",
2598
+ ...leafFastGate.behavioralReceipts.map((entry: any) => "- " + entry.command),
2599
+ "",
2600
+ "UES_VERDICT: PASS",
2601
+ ].join("\n"),
2602
+ stderr: "",
2603
+ verdict: "PASS",
2604
+ durationMs: 0,
2605
+ toolCalls: 0,
2606
+ toolNames: [],
2607
+ report: {
2608
+ schemaVersion: 1,
2609
+ valid: true,
2610
+ verdict: "PASS",
2611
+ sections: {
2612
+ "checks-run": leafFastGate.behavioralReceipts.map((entry: any) => entry.command).join("\n"),
2613
+ "acceptance-criteria-proven": "Fresh behavioral receipt(s) exist at the post-implementation workspace fingerprint.",
2614
+ "completion-evidence": "Deterministic per-leaf PASS after this implementation attempt.",
2615
+ },
2616
+ },
2617
+ optimizations: {
2618
+ perLeafTurbo: true,
2619
+ behavioralReceiptCount: leafFastGate.behavioralReceipts.length,
2620
+ },
2621
+ };
2622
+ input.onUpdate?.({
2623
+ content: [{
2624
+ type: "text",
2625
+ text: `UES Per-Leaf Turbo: ${item.task.id} reused ${leafFastGate.behavioralReceipts.length} fresh behavioral receipt(s); skipped verifier model turn`,
2626
+ }],
2627
+ details: {
2628
+ wave: waveIndex,
2629
+ attempt,
2630
+ task: item.task.id,
2631
+ phase: "leaf-turbo-verified",
2632
+ leafPolicy,
2633
+ leafFastGate,
2634
+ },
2635
+ });
2636
+ } else {
2637
+ verification = await runRoutedAgent(
2118
2638
  "ues-verifier",
2119
2639
  [
2120
2640
  "Verify exactly this structured plan task in the current isolated worktree.",
@@ -2141,8 +2661,11 @@ async function executeStructuredPlan(input: {
2141
2661
  });
2142
2662
  },
2143
2663
  input.traceID,
2664
+ leafPolicy,
2665
+ input.root,
2144
2666
  );
2145
- results.push({ wave: waveIndex, attempt, task: item.task.id, phase: "verify", ...verification });
2667
+ }
2668
+ results.push({ wave: waveIndex, attempt, task: item.task.id, phase: "verify", leafPolicy, leafFastGate, ...verification });
2146
2669
  const passed = verification.exitCode === 0 && verification.verdict === "PASS";
2147
2670
  if (!isAbortedRun(verification)) {
2148
2671
  await recordRuntimeOutcome(implementation, taskText, passed, attempt - 1);
@@ -2188,8 +2711,12 @@ async function executeStructuredPlan(input: {
2188
2711
 
2189
2712
  const failed = waveResults.filter((item) => !item.passed);
2190
2713
  if (failed.length) {
2714
+ for (const row of failed) {
2715
+ const rawFailure = row.verification?.output || row.implementation?.output || "unknown failure";
2716
+ failureByTask.set(String(row.item?.task?.id || "unknown"), failureDelta(rawFailure));
2717
+ }
2191
2718
  lastWaveFailure = failed
2192
- .map((item) => item.verification?.output || item.implementation?.output || "unknown failure")
2719
+ .map((item) => failureByTask.get(String(item.item?.task?.id || "unknown")) || "unknown failure")
2193
2720
  .join("\n\n---\n\n");
2194
2721
  await failDurablePrepared(prepared, lastWaveFailure);
2195
2722
  await cleanupSandboxes(input.root, prepared);
@@ -2207,9 +2734,9 @@ async function executeStructuredPlan(input: {
2207
2734
  };
2208
2735
  }
2209
2736
 
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.
2737
+ if (!gitCapable || prepared.every((item) => !item.sandbox?.dir)) {
2738
+ // Read-only waves do not need a duplicate Git worktree. Their fresh
2739
+ // verifier evidence is enough as long as the workspace stays unchanged.
2213
2740
  await completeDurableWave(waveResults);
2214
2741
  break;
2215
2742
  }
@@ -2217,13 +2744,21 @@ async function executeStructuredPlan(input: {
2217
2744
  const actualByTask = new Map<string, string[]>();
2218
2745
  let scopeFailure = "";
2219
2746
  for (const item of prepared) {
2747
+ if (!item.sandbox?.dir) {
2748
+ actualByTask.set(item.task.id, []);
2749
+ continue;
2750
+ }
2220
2751
  const changed = await sandboxChangedFiles(item.sandbox.dir, item.sandbox.integrationBase, input.signal);
2221
2752
  actualByTask.set(item.task.id, changed);
2222
2753
  const allowed = new Set(item.writeFiles);
2223
2754
  const unexpected = changed.filter((file) => !allowed.has(file));
2224
2755
  if (unexpected.length) {
2225
- scopeFailure +=
2226
- `${item.task.id}: changed files outside declared write scope: ${unexpected.join(", ")}\n`;
2756
+ const scopeMessage =
2757
+ `${item.task.id}: changed real source files outside declared write scope: ${unexpected.join(", ")}. ` +
2758
+ "On retry, revert or avoid these files and satisfy the task strictly within its declared write scope. " +
2759
+ "Do not silently broaden scope.";
2760
+ failureByTask.set(String(item.task.id), failureDelta(scopeMessage, { maxChars: 2200 }));
2761
+ scopeFailure += scopeMessage + "\n";
2227
2762
  }
2228
2763
  }
2229
2764
 
@@ -2232,7 +2767,12 @@ async function executeStructuredPlan(input: {
2232
2767
  for (const file of changed) {
2233
2768
  const previous = changedOwners.get(file);
2234
2769
  if (previous && previous !== taskID) {
2235
- scopeFailure += `wave conflict: ${previous} and ${taskID} both changed ${file}\n`;
2770
+ const conflictMessage = `wave conflict: ${previous} and ${taskID} both changed real source file ${file}`;
2771
+ const previousFailure = failureByTask.get(previous) || "";
2772
+ const currentFailure = failureByTask.get(taskID) || "";
2773
+ failureByTask.set(previous, failureDelta([previousFailure, conflictMessage].filter(Boolean).join("\n"), { maxChars: 2200 }));
2774
+ failureByTask.set(taskID, failureDelta([currentFailure, conflictMessage].filter(Boolean).join("\n"), { maxChars: 2200 }));
2775
+ scopeFailure += conflictMessage + "\n";
2236
2776
  } else {
2237
2777
  changedOwners.set(file, taskID);
2238
2778
  }
@@ -2260,6 +2800,7 @@ async function executeStructuredPlan(input: {
2260
2800
  const integrated: Array<{ item: any; receipt: any }> = [];
2261
2801
  try {
2262
2802
  for (const item of prepared) {
2803
+ if (!item.sandbox?.dir) continue;
2263
2804
  const receipt = await integrateTaskSandbox(input.root, item.sandbox.dir, { keep: true });
2264
2805
  integrated.push({ item, receipt });
2265
2806
  integrations.push({ wave: waveIndex, task: item.task.id, ...receipt });
@@ -2379,7 +2920,86 @@ export default function (pi: ExtensionAPI) {
2379
2920
  // controller inside specialist workers.
2380
2921
  if (process.env.UES_CHILD_PROCESS === "1") return;
2381
2922
 
2923
+ let directControllerAbort: AbortController | null = null;
2924
+ let promptUesActive = false;
2925
+ let directControllerRunner: ((task: string, ctx: any, admission: "command" | "automatic", admissionDecision?: any) => Promise<void>) | null = null;
2926
+ const AUTO_ADMISSION_ENABLED = !["0", "false", "off"].includes(
2927
+ String(process.env.UES_AUTO_ADMIT || "1").trim().toLowerCase(),
2928
+ );
2929
+ const UES_PARENT_TOOL_NAMES = new Set(["ues_cli", "ues_execute", "ues_service", "ues_dispatch"]);
2930
+ let normalActiveTools: string[] | null = null;
2931
+
2932
+ const currentNonUesTools = () =>
2933
+ pi.getActiveTools().filter((name) => !UES_PARENT_TOOL_NAMES.has(String(name)));
2934
+
2935
+ const deactivateParentUesTools = () => {
2936
+ const normal = currentNonUesTools();
2937
+ normalActiveTools = normal;
2938
+ try { pi.setActiveTools(normal); } catch {}
2939
+ };
2940
+
2941
+ const activateParentUesTools = () => {
2942
+ const normal = normalActiveTools || currentNonUesTools();
2943
+ const registered = new Set(
2944
+ (typeof (pi as any).getAllTools === "function" ? (pi as any).getAllTools() : [])
2945
+ .map((tool: any) => String(tool?.name || "")),
2946
+ );
2947
+ const uesTools = [...UES_PARENT_TOOL_NAMES].filter((name) => registered.has(name));
2948
+ try { pi.setActiveTools([...new Set([...normal, ...uesTools])]); } catch {}
2949
+ };
2950
+
2951
+ const uesModeActive = () =>
2952
+ promptUesActive || Boolean(directControllerAbort && !directControllerAbort.signal.aborted);
2953
+
2954
+ const syncSessionIdentity = (name: string, ctx: any) => {
2955
+ if (!name) return;
2956
+ try { pi.setSessionName(name); } catch {}
2957
+ try { ctx?.ui?.setTitle?.(name); } catch {}
2958
+ };
2959
+
2960
+ pi.on("session_start", async () => {
2961
+ deactivateParentUesTools();
2962
+ });
2963
+
2964
+ pi.on("session_before_compact", async (event, ctx) => {
2965
+ const root = resolveGitWorkspaceRoot(ctx.cwd || "");
2966
+ if (!root) return undefined;
2967
+ await checkpointDurableWorkBeforeCompaction(root, {
2968
+ reason: event.reason,
2969
+ maxWorkspaces: 3,
2970
+ }).catch(() => []);
2971
+ return undefined;
2972
+ });
2973
+
2974
+ pi.on("session_compact", async (event, ctx) => {
2975
+ const root = resolveGitWorkspaceRoot(ctx.cwd || "");
2976
+ if (!root) return;
2977
+ const packet = await buildCompactionResumeGuard(root, {
2978
+ reason: event.reason,
2979
+ maxWorkspaces: 3,
2980
+ }).catch(() => null);
2981
+ if (!packet?.workspaces?.length) return;
2982
+ const content = renderCompactionResumeGuard(packet);
2983
+ if (!content) return;
2984
+ pi.sendMessage({
2985
+ customType: "ues-durable-resume-guard",
2986
+ content,
2987
+ display: false,
2988
+ details: {
2989
+ schemaVersion: 1,
2990
+ reason: event.reason,
2991
+ willRetry: event.willRetry,
2992
+ workspaceCount: packet.workspaceCount,
2993
+ source: packet.source,
2994
+ },
2995
+ }, { triggerTurn: false });
2996
+ });
2997
+
2382
2998
  pi.on("session_shutdown", async () => {
2999
+ directControllerAbort?.abort();
3000
+ directControllerAbort = null;
3001
+ promptUesActive = false;
3002
+ normalActiveTools = null;
2383
3003
  CONTEXT_PACK_CACHE.clear();
2384
3004
  clearSkillCompilerCache();
2385
3005
  clearAffectedTestCache();
@@ -2387,29 +3007,44 @@ export default function (pi: ExtensionAPI) {
2387
3007
  clearSemanticIndexRuntimeCache();
2388
3008
  MCP_HEALTH.clear();
2389
3009
  abortActiveCliChildren();
3010
+ await stopAllServices().catch(() => []);
2390
3011
  await RPC_POOL.stopAll().catch(() => {});
3012
+ for (const dir of [...ACTIVE_TASK_SANDBOXES.keys()]) {
3013
+ const ownerRoot = await taskSandboxOwnerRoot(dir).catch(() => null);
3014
+ if (!ownerRoot) continue;
3015
+ await removeTaskSandbox(ownerRoot, dir, { force: true, deleteBranch: true }).catch(() => {});
3016
+ ACTIVE_TASK_SANDBOXES.delete(dir);
3017
+ }
2391
3018
  });
2392
3019
 
2393
3020
  pi.on("input", async (event, ctx) => {
2394
3021
  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
- }
3022
+ if (event.source !== "interactive") return { action: "continue" };
2401
3023
 
2402
3024
  const text = String(event.text || "").trim();
2403
3025
  if (!text) return { action: "continue" };
2404
3026
 
3027
+ const sessionName = sessionNameFromUesInput(text, ctx.cwd || "");
3028
+ if (sessionName) syncSessionIdentity(sessionName, ctx);
3029
+ if (/^\/ues-(?:resume|fix|feature|debug|review|audit|plan|research|critique|verify)(?:\s|$)/i.test(text)) {
3030
+ promptUesActive = true;
3031
+ activateParentUesTools();
3032
+ }
3033
+
2405
3034
  if (/^(?:stop|cancel|abort|dừng|dung|hủy|huy)(?:\s|$)/i.test(text)) {
3035
+ if (!uesModeActive()) return { action: "continue" };
3036
+ let directAborted = 0;
3037
+ if (directControllerAbort && !directControllerAbort.signal.aborted) {
3038
+ directControllerAbort.abort();
3039
+ directAborted = 1;
3040
+ }
2406
3041
  const result = await RPC_POOL.abortActive();
2407
3042
  const cliAborted = abortActiveCliChildren();
2408
- const total = result.aborted + cliAborted;
3043
+ const total = directAborted + result.aborted + cliAborted;
2409
3044
  if (total > 0) {
2410
3045
  try {
2411
3046
  ctx.ui.notify(
2412
- `UES: aborted ${total} active child worker(s)` +
3047
+ `UES: aborted ${total} active controller/child worker(s)` +
2413
3048
  (cliAborted ? ` (${cliAborted} CLI fallback)` : ""),
2414
3049
  "warning",
2415
3050
  );
@@ -2419,6 +3054,65 @@ export default function (pi: ExtensionAPI) {
2419
3054
  return { action: "continue" };
2420
3055
  }
2421
3056
 
3057
+ if (!["steer", "followUp"].includes(String(event.streamingBehavior || ""))) {
3058
+ if (directControllerAbort && !directControllerAbort.signal.aborted) {
3059
+ const continuation = automaticUesContinuation(text, { activeRun: true });
3060
+ if (continuation.forward) {
3061
+ const forwarded = await RPC_POOL.steerActive(text).catch(() => ({
3062
+ accepted: false,
3063
+ reason: "steer-failed",
3064
+ active: 0,
3065
+ }));
3066
+ if (forwarded.accepted) {
3067
+ try { ctx.ui.notify("UES: natural continuation forwarded to the active child", "info"); } catch {}
3068
+ return { action: "handled" };
3069
+ }
3070
+ try {
3071
+ ctx.ui.notify(
3072
+ "UES is already running; continuation could not be targeted safely, so the prompt was not swallowed.",
3073
+ "warning",
3074
+ );
3075
+ } catch {}
3076
+ }
3077
+ return { action: "continue" };
3078
+ }
3079
+
3080
+ if (
3081
+ AUTO_ADMISSION_ENABLED &&
3082
+ directControllerRunner &&
3083
+ !(Array.isArray((event as any).images) && (event as any).images.length > 0)
3084
+ ) {
3085
+ const preliminaryAdmission = automaticUesAdmission(text);
3086
+ const workspaceRoot = preliminaryAdmission.admit === true
3087
+ ? resolveGitWorkspaceRoot(ctx.cwd || "")
3088
+ : null;
3089
+ const admission = workspaceRoot
3090
+ ? automaticUesAdmission(text, { inGitWorkspace: true })
3091
+ : preliminaryAdmission;
3092
+ if (workspaceRoot && admission.admit === true) {
3093
+ try {
3094
+ ctx.ui.notify(
3095
+ "UES " + PACKAGE_VERSION + ": " +
3096
+ (admission.route === "guarded" ? "high-risk engineering task admitted" : "engineering task auto-admitted") +
3097
+ " (" + admission.reason + ", confidence " + admission.confidence + ")",
3098
+ admission.route === "guarded" ? "warning" : "info",
3099
+ );
3100
+ } catch {}
3101
+ void directControllerRunner(text, ctx, "automatic", admission).catch((error) => {
3102
+ try {
3103
+ ctx.ui.notify(
3104
+ "UES automatic controller failed to start: " +
3105
+ (error instanceof Error ? error.message : String(error)),
3106
+ "error",
3107
+ );
3108
+ } catch {}
3109
+ });
3110
+ return { action: "handled" };
3111
+ }
3112
+ }
3113
+ return { action: "continue" };
3114
+ }
3115
+
2422
3116
  const steered = await RPC_POOL.steerActive(text).catch(() => ({
2423
3117
  accepted: false,
2424
3118
  reason: "steer-failed",
@@ -2434,8 +3128,27 @@ export default function (pi: ExtensionAPI) {
2434
3128
  return { action: "continue" };
2435
3129
  });
2436
3130
 
3131
+ pi.on("before_agent_start", async () => {
3132
+ if (uesModeActive()) activateParentUesTools();
3133
+ else deactivateParentUesTools();
3134
+ });
3135
+
3136
+ pi.on("agent_end", async () => {
3137
+ promptUesActive = false;
3138
+ deactivateParentUesTools();
3139
+ });
3140
+
2437
3141
  pi.on("tool_call", async (event, ctx) => {
2438
3142
  const toolName = String(event.toolName || "");
3143
+ if (!uesModeActive()) {
3144
+ if (toolName.startsWith("ues_")) {
3145
+ return {
3146
+ block: true,
3147
+ reason: "UES parent tools are hidden outside admitted UES runs. Submit a normal engineering task or start an explicit /ues-* command.",
3148
+ };
3149
+ }
3150
+ return undefined;
3151
+ }
2439
3152
  if (toolName !== "bash" && toolName !== "powershell") {
2440
3153
  const allTools = typeof (pi as any).getAllTools === "function" ? (pi as any).getAllTools() : [];
2441
3154
  const descriptor = allTools.find((tool: any) => String(tool?.name || "") === toolName);
@@ -2449,6 +3162,14 @@ export default function (pi: ExtensionAPI) {
2449
3162
  }
2450
3163
 
2451
3164
  const command = String((event.input as any)?.command || "");
3165
+ if (looksLikeLongRunningServiceCommand(command)) {
3166
+ return {
3167
+ block: true,
3168
+ reason:
3169
+ "UES detected a likely long-running foreground service command. " +
3170
+ "Use ues_service start/wait-ready/logs/stop so Pi can continue without blocking on the server process.",
3171
+ };
3172
+ }
2452
3173
  const risk = destructiveShellRisk(command);
2453
3174
  if (!risk.risky) return undefined;
2454
3175
  const allowed = await approveRisk(ctx, command, risk.id || "destructive");
@@ -2457,6 +3178,7 @@ export default function (pi: ExtensionAPI) {
2457
3178
  });
2458
3179
 
2459
3180
  pi.on("tool_result", async (event) => {
3181
+ if (!uesModeActive()) return undefined;
2460
3182
  const toolName = String((event as any).toolName || "");
2461
3183
  if (!toolName || toolName === "bash" || toolName === "powershell") return undefined;
2462
3184
  MCP_HEALTH.finish(
@@ -2479,7 +3201,7 @@ export default function (pi: ExtensionAPI) {
2479
3201
  cwd: Type.Optional(Type.String({ description: "Working directory; defaults to the current Pi cwd" })),
2480
3202
  }),
2481
3203
  async execute(_toolCallId, params, signal, _onUpdate, ctx) {
2482
- const cwd = path.resolve(params.cwd || ctx.cwd);
3204
+ const cwd = requireGitWorkspaceRoot(params.cwd || ctx.cwd, "ues_cli");
2483
3205
  const separator = params.args.indexOf("--");
2484
3206
  if (separator >= 0 && separator < params.args.length - 1) {
2485
3207
  const command = params.args.slice(separator + 1).join(" ");
@@ -2538,6 +3260,91 @@ export default function (pi: ExtensionAPI) {
2538
3260
  });
2539
3261
 
2540
3262
  pi.registerTool({
3263
+ name: "ues_service",
3264
+ label: "UES Managed Service",
3265
+ description:
3266
+ "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.",
3267
+ parameters: Type.Object({
3268
+ action: Type.Union([
3269
+ Type.Literal("start"),
3270
+ Type.Literal("wait-ready"),
3271
+ Type.Literal("status"),
3272
+ Type.Literal("logs"),
3273
+ Type.Literal("stop"),
3274
+ Type.Literal("restart"),
3275
+ ]),
3276
+ name: Type.String({ minLength: 1, maxLength: 64 }),
3277
+ command: Type.Optional(Type.String({ minLength: 1 })),
3278
+ args: Type.Optional(Type.Array(Type.String(), { maxItems: 128 })),
3279
+ cwd: Type.Optional(Type.String()),
3280
+ readyPort: Type.Optional(Type.Number({ minimum: 1, maximum: 65535 })),
3281
+ readyHost: Type.Optional(Type.String({ maxLength: 255 })),
3282
+ readyLog: Type.Optional(Type.String({ maxLength: 512 })),
3283
+ timeoutMs: Type.Optional(Type.Number({ minimum: 100, maximum: 600000 })),
3284
+ lifetimeMs: Type.Optional(Type.Number({ minimum: 10000, maximum: 7200000 })),
3285
+ idleTimeoutMs: Type.Optional(Type.Number({ minimum: 5000, maximum: 3600000 })),
3286
+ maxChars: Type.Optional(Type.Number({ minimum: 256, maximum: 128000 })),
3287
+ }),
3288
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
3289
+ try {
3290
+ const hostCwd = path.resolve(ctx.cwd);
3291
+ const serviceRoot = requireGitWorkspaceRoot(hostCwd, "ues_service");
3292
+ const requestedServiceCwd = params.cwd
3293
+ ? path.relative(serviceRoot, path.resolve(hostCwd, params.cwd)) || "."
3294
+ : path.relative(serviceRoot, hostCwd) || ".";
3295
+ let result: any;
3296
+ if (params.action === "start") {
3297
+ if (!params.command) throw new Error("ues_service start requires command");
3298
+ const riskText = [params.command, ...(params.args || [])].join(" ");
3299
+ const risk = destructiveShellRisk(riskText);
3300
+ if (risk.risky) throw new Error(`UES service safety blocked ${risk.id || "destructive"} command`);
3301
+ result = await startService(serviceRoot, {
3302
+ name: params.name,
3303
+ command: params.command,
3304
+ args: params.args || [],
3305
+ cwd: requestedServiceCwd,
3306
+ readyPort: params.readyPort,
3307
+ readyHost: params.readyHost,
3308
+ readyLog: params.readyLog,
3309
+ timeoutMs: params.timeoutMs,
3310
+ lifetimeMs: params.lifetimeMs,
3311
+ idleTimeoutMs: params.idleTimeoutMs,
3312
+ });
3313
+ } else if (params.action === "wait-ready") {
3314
+ result = await waitForService(serviceRoot, params.name, { timeoutMs: params.timeoutMs });
3315
+ } else if (params.action === "status") {
3316
+ result = await serviceStatus(serviceRoot, params.name);
3317
+ } else if (params.action === "logs") {
3318
+ result = await serviceLogs(serviceRoot, params.name, { maxChars: params.maxChars, evidence: true });
3319
+ } else if (params.action === "stop") {
3320
+ result = await stopService(serviceRoot, params.name, { timeoutMs: params.timeoutMs });
3321
+ } else if (params.action === "restart") {
3322
+ result = await restartService(serviceRoot, params.name, {
3323
+ timeoutMs: params.timeoutMs,
3324
+ lifetimeMs: params.lifetimeMs,
3325
+ idleTimeoutMs: params.idleTimeoutMs,
3326
+ });
3327
+ } else {
3328
+ throw new Error("Unknown ues_service action");
3329
+ }
3330
+ const failed =
3331
+ (params.action === "start" || params.action === "wait-ready") && result?.ready !== true;
3332
+ return {
3333
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
3334
+ details: result,
3335
+ isError: failed,
3336
+ };
3337
+ } catch (error) {
3338
+ return {
3339
+ content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
3340
+ details: { action: params.action, name: params.name },
3341
+ isError: true,
3342
+ };
3343
+ }
3344
+ },
3345
+ });
3346
+
3347
+ const uesExecuteTool: any = {
2541
3348
  name: "ues_execute",
2542
3349
  label: "UES Execute",
2543
3350
  description:
@@ -2549,16 +3356,61 @@ export default function (pi: ExtensionAPI) {
2549
3356
  }),
2550
3357
  async execute(_toolCallId, params, signal, onUpdate, ctx) {
2551
3358
  const hostBrowserTools = refreshHostBrowserToolNames(pi);
2552
- const cwd = path.resolve(params.cwd || ctx.cwd);
3359
+ const cwd = requireGitWorkspaceRoot(params.cwd || ctx.cwd, "ues_execute");
2553
3360
  const inheritedModel = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined;
2554
3361
  const inheritedThinking = ctx.thinkingLevel as string | undefined;
2555
- const policy = classifyEngineeringTask(params.task);
2556
- const traceID = createTraceID("ues-execute");
3362
+ const controllerWorkspaceState = captureWorkspaceStateV2(cwd);
3363
+ const inheritedDirty = captureInheritedDirtyState(cwd, {
3364
+ workspaceState: controllerWorkspaceState,
3365
+ });
3366
+ const controllerHygieneBaseline = captureWorkspaceHygieneBaseline(cwd, {
3367
+ workspaceState: controllerWorkspaceState,
3368
+ });
3369
+ const executionContract = buildExecutionContract(params.task, inheritedDirty);
3370
+ const contractPrompt = executionContractPrompt(executionContract);
3371
+ const suppliedPolicy = (params as any).__taskPolicy;
3372
+ const basePolicy =
3373
+ suppliedPolicy && typeof suppliedPolicy === "object"
3374
+ ? suppliedPolicy
3375
+ : classifyEngineeringTask(params.task);
3376
+ const policy = {
3377
+ ...basePolicy,
3378
+ localEnvWriteExplicitlyAllowed: executionContract.localEnvWriteExplicitlyAllowed === true,
3379
+ executionContractPrompt: contractPrompt,
3380
+ };
3381
+ const traceID = String((params as any).__traceID || createTraceID("ues-execute"));
3382
+ const orphanCleanup = await pruneOrphanTaskSandboxes(cwd, {
3383
+ minAgeMs: 5 * 60_000,
3384
+ legacyMinAgeMs: 30 * 60_000,
3385
+ ownedMinAgeMs: 60_000,
3386
+ reclaimOwnerPid: process.pid,
3387
+ protectedDirs: [...ACTIVE_TASK_SANDBOXES.keys()],
3388
+ }).catch(() => ({ removed: [], skipped: [], sidecarsRemoved: [] }));
3389
+ if (orphanCleanup.removed?.length) {
3390
+ onUpdate?.({
3391
+ content: [{ type: "text", text: `UES sandbox cleanup: removed ${orphanCleanup.removed.length} orphan worktree(s)` }],
3392
+ details: { mode: "execute", phase: "sandbox-cleanup", orphanCleanup },
3393
+ });
3394
+ }
2557
3395
  await appendTrajectoryEvent(cwd, traceID, "controller.started", {
2558
3396
  profile: policy.executionProfile,
2559
3397
  risk: policy.risk,
2560
3398
  mode: policy.mode,
3399
+ inheritedDirtyCount: executionContract.inheritedDirty?.paths?.length || 0,
3400
+ explicitPhaseCount: executionContract.phases?.length || 0,
3401
+ localEnvWriteExplicitlyAllowed: executionContract.localEnvWriteExplicitlyAllowed === true,
2561
3402
  }).catch(() => {});
3403
+ if ((executionContract.inheritedDirty?.paths?.length || 0) > 0 || (executionContract.phases?.length || 0) > 0) {
3404
+ onUpdate?.({
3405
+ content: [{
3406
+ type: "text",
3407
+ text:
3408
+ `UES contract: inherited dirty ${executionContract.inheritedDirty?.paths?.length || 0}; ` +
3409
+ `explicit phases ${executionContract.phases?.length || 0}; local .env write ${executionContract.localEnvWriteExplicitlyAllowed ? "authorized" : "blocked"}`,
3410
+ }],
3411
+ details: { mode: "execute", phase: "execution-contract", executionContract, traceID },
3412
+ });
3413
+ }
2562
3414
  const browserLaneRequested =
2563
3415
  browserEvidenceNeeded(params.task, "executor") || visualEvidenceNeeded(params.task);
2564
3416
  if (browserLaneRequested) {
@@ -2603,9 +3455,16 @@ export default function (pi: ExtensionAPI) {
2603
3455
  });
2604
3456
 
2605
3457
  const run = async (agent: AgentName, task: string, attempt = 1, failure?: string) => {
3458
+ const planningBudget = planningRuntimeBudget(roleForAgent(agent), attempt, {
3459
+ executionProfile: policy.executionProfile,
3460
+ risk: policy.risk,
3461
+ taskChars: task.length,
3462
+ });
3463
+ let softSteerSent = false;
3464
+ const governedTask = [task, "", contractPrompt].filter(Boolean).join("\n");
2606
3465
  const result = await runRoutedAgent(
2607
3466
  agent,
2608
- task,
3467
+ governedTask,
2609
3468
  cwd,
2610
3469
  inheritedModel,
2611
3470
  inheritedThinking,
@@ -2613,6 +3472,30 @@ export default function (pi: ExtensionAPI) {
2613
3472
  failure,
2614
3473
  signal,
2615
3474
  (progress) => {
3475
+ if (
3476
+ !softSteerSent &&
3477
+ (
3478
+ (agent === "ues-architect" && shouldSoftSteerArchitect(progress, planningBudget)) ||
3479
+ (agent === "ues-plan-checker" && shouldSoftSteerPlanningRole(progress, planningBudget))
3480
+ )
3481
+ ) {
3482
+ softSteerSent = true;
3483
+ const steerText =
3484
+ agent === "ues-architect"
3485
+ ? "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."
3486
+ : "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.";
3487
+ void RPC_POOL.steerActive(steerText).catch(() => ({ accepted: false }));
3488
+ onUpdate?.({
3489
+ content: [{
3490
+ type: "text",
3491
+ text:
3492
+ agent === "ues-architect"
3493
+ ? "UES planning fast-stop: architect evidence budget reached; requesting immediate plan emission"
3494
+ : "UES planning fast-stop: plan-checker budget reached; requesting immediate verdict",
3495
+ }],
3496
+ details: { mode: "execute", phase: "planning-soft-steer", policy, progress, planningBudget, traceID },
3497
+ });
3498
+ }
2616
3499
  onUpdate?.({
2617
3500
  content: [{
2618
3501
  type: "text",
@@ -2627,6 +3510,7 @@ export default function (pi: ExtensionAPI) {
2627
3510
  });
2628
3511
  },
2629
3512
  traceID,
3513
+ policy,
2630
3514
  );
2631
3515
  steps.push(result);
2632
3516
  onUpdate?.({
@@ -2639,27 +3523,202 @@ export default function (pi: ExtensionAPI) {
2639
3523
  return result;
2640
3524
  };
2641
3525
 
2642
- if (shouldRunDedicatedDiagnosis(policy, 1)) {
2643
- const diagnosis = await run("ues-debugger", params.task, 1);
2644
- if (isAbortedRun(diagnosis)) return abortedResponse(diagnosis, "diagnosis");
2645
- if (diagnosis.exitCode !== 0 || diagnosis.stopReason === "error") {
2646
- return {
2647
- content: [{ type: "text", text: `Diagnosis failed:\n\n${diagnosis.output}` }],
2648
- details: { mode: "execute", policy, steps },
2649
- isError: true,
2650
- };
2651
- }
2652
- recentFailure = diagnosis.output;
2653
- }
3526
+ if (policy.readOnly === true) {
3527
+ const before = runtimeWorkspaceSnapshot(cwd);
3528
+ const deterministicChecks = deterministicReadOnlyGitCommands(params.task);
3529
+ let inspection: any;
3530
+
3531
+ if (deterministicChecks.length > 0) {
3532
+ const rows: any[] = [];
3533
+ for (const spec of deterministicChecks) {
3534
+ const result = await runProcess(spec.command, spec.args, cwd, signal);
3535
+ if (result.exitCode === 130 || result.stopReason === "aborted") {
3536
+ const aborted: any = {
3537
+ agent: "ues-deterministic-read-only",
3538
+ task: params.task,
3539
+ cwd,
3540
+ exitCode: 130,
3541
+ output: "Deterministic read-only command aborted: " + spec.label,
3542
+ stderr: result.stderr || "",
3543
+ verdict: null,
3544
+ durationMs: result.durationMs || 0,
3545
+ toolCalls: 0,
3546
+ toolNames: [],
3547
+ report: parseStructuredReport(""),
3548
+ stopReason: "aborted",
3549
+ };
3550
+ steps.push(aborted);
3551
+ return abortedResponse(aborted, "read-only-deterministic-check");
3552
+ }
3553
+ rows.push({
3554
+ ...spec,
3555
+ exitCode: result.exitCode,
3556
+ stdout: cap(result.stdout || "", 8000),
3557
+ stderr: cap(result.stderr || "", 4000),
3558
+ });
3559
+ }
2654
3560
 
2655
- if (policy.requirePlanCheck) {
2656
- const planInstruction = [
3561
+ const afterChecks = runtimeWorkspaceSnapshot(cwd);
3562
+ const unchangedAfterChecks =
3563
+ before.cacheable === true &&
3564
+ afterChecks.cacheable === true &&
3565
+ before.fingerprint === afterChecks.fingerprint;
3566
+ const failedRows = rows.filter((row) => Number(row.exitCode) !== 0);
3567
+ const deterministicPass = failedRows.length === 0 && unchangedAfterChecks;
3568
+ const checksText = rows.map((row) => {
3569
+ const payload = [row.stdout, row.stderr].filter(Boolean).join("\n").trim() || "(no output)";
3570
+ return [
3571
+ row.label + " — exit " + row.exitCode,
3572
+ payload,
3573
+ ].join("\n");
3574
+ }).join("\n\n");
3575
+ const failureText = [
3576
+ ...failedRows.map((row) => row.label + " exited " + row.exitCode),
3577
+ ...(unchangedAfterChecks ? [] : ["read-only workspace fingerprint changed"]),
3578
+ ].join("\n") || "None.";
3579
+
3580
+ const output = [
3581
+ "## Checks run",
3582
+ checksText,
3583
+ "",
3584
+ "## Acceptance criteria proven",
3585
+ deterministicPass
3586
+ ? "All explicitly requested whitelisted Git inspection commands completed successfully."
3587
+ : "The requested deterministic inspection did not fully pass.",
3588
+ "",
3589
+ "## Failures",
3590
+ failureText,
3591
+ "",
3592
+ "## Unresolved gaps",
3593
+ "None.",
3594
+ "",
3595
+ "## Checks not run",
3596
+ "None.",
3597
+ "",
3598
+ "## Completion evidence",
3599
+ "UES executed " + rows.length + " command-only read-only Git check(s) directly and compared the source workspace fingerprint before and after.",
3600
+ "",
3601
+ "UES_VERDICT: " + (deterministicPass ? "PASS" : "FAIL"),
3602
+ ].join("\n");
3603
+
3604
+ inspection = {
3605
+ agent: "ues-deterministic-read-only",
3606
+ task: params.task,
3607
+ cwd,
3608
+ exitCode: deterministicPass ? 0 : 1,
3609
+ output,
3610
+ stderr: "",
3611
+ verdict: deterministicPass ? "PASS" : "FAIL",
3612
+ durationMs: 0,
3613
+ toolCalls: rows.length,
3614
+ toolNames: rows.map((row) => row.label),
3615
+ report: parseStructuredReport(output),
3616
+ optimizations: {
3617
+ deterministicReadOnlyGit: true,
3618
+ checkCount: rows.length,
3619
+ },
3620
+ };
3621
+ steps.push(inspection);
3622
+ onUpdate?.({
3623
+ content: [{
3624
+ type: "text",
3625
+ text: "UES read-only fast path: executed " + rows.length + " whitelisted Git check(s) deterministically; skipped verifier model turn",
3626
+ }],
3627
+ details: { mode: "execute", phase: "read-only-deterministic", policy, traceID, checks: rows.map((row) => row.label) },
3628
+ });
3629
+ } else {
3630
+ inspection = await run(
3631
+ "ues-verifier",
3632
+ [
3633
+ "READ-ONLY INSPECTION MODE. Do not edit, create, delete, stage, commit, install dependencies, or start persistent services.",
3634
+ "Use only the narrowest read-only commands and source inspection needed to answer the request.",
3635
+ "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.",
3636
+ "Return exactly these H2 sections: ## Checks run, ## Acceptance criteria proven, ## Failures, ## Unresolved gaps, ## Checks not run, ## Completion evidence.",
3637
+ "Write exactly None in Failures and Unresolved gaps when there is no real requested failure or gap.",
3638
+ "End with exactly UES_VERDICT: PASS or UES_VERDICT: FAIL.",
3639
+ "Explicitly verify that source-facing workspace state is unchanged before returning PASS.",
3640
+ "",
3641
+ "Inspection request:",
3642
+ params.task,
3643
+ ].join("\n"),
3644
+ 1,
3645
+ );
3646
+ if (isAbortedRun(inspection)) return abortedResponse(inspection, "read-only-inspection");
3647
+ }
3648
+
3649
+ const after = runtimeWorkspaceSnapshot(cwd);
3650
+ const unchanged =
3651
+ before.cacheable === true &&
3652
+ after.cacheable === true &&
3653
+ before.fingerprint === after.fingerprint;
3654
+ const completionAudit = auditCompletion({
3655
+ verification: inspection,
3656
+ requireIntegration: false,
3657
+ requireVisual: false,
3658
+ workspaceSnapshot: after,
3659
+ behavioralReceipts: [],
3660
+ requireBehavioralReceipt: false,
3661
+ });
3662
+ if (!unchanged) {
3663
+ completionAudit.passed = false;
3664
+ completionAudit.failures = [...new Set([
3665
+ ...(completionAudit.failures || []),
3666
+ "read-only-workspace-mutated",
3667
+ ])];
3668
+ }
3669
+
3670
+ if (!completionAudit.passed) {
3671
+ return {
3672
+ content: [{
3673
+ type: "text",
3674
+ text: "UES read-only inspection did not pass: " + completionAudit.failures.join(", ") +
3675
+ "\n\n" + inspection.output,
3676
+ }],
3677
+ details: { mode: "execute", policy, steps, completionAudit, traceID },
3678
+ isError: true,
3679
+ };
3680
+ }
3681
+
3682
+ return {
3683
+ content: [{
3684
+ type: "text",
3685
+ text: [
3686
+ "UES read-only inspection PASS.",
3687
+ "Workspace source fingerprint remained unchanged.",
3688
+ "",
3689
+ inspection.output,
3690
+ ].join("\n"),
3691
+ }],
3692
+ details: { mode: "execute", policy, steps, completionAudit, traceID },
3693
+ };
3694
+ }
3695
+
3696
+ if (shouldRunDedicatedDiagnosis(policy, 1)) {
3697
+ const diagnosis = await run("ues-debugger", params.task, 1);
3698
+ if (isAbortedRun(diagnosis)) return abortedResponse(diagnosis, "diagnosis");
3699
+ if (diagnosis.exitCode !== 0 || diagnosis.stopReason === "error") {
3700
+ return {
3701
+ content: [{ type: "text", text: `Diagnosis failed:\n\n${diagnosis.output}` }],
3702
+ details: { mode: "execute", policy, steps },
3703
+ isError: true,
3704
+ };
3705
+ }
3706
+ recentFailure = diagnosis.output;
3707
+ }
3708
+
3709
+ if (policy.requirePlanCheck) {
3710
+ const planInstruction = [
2657
3711
  params.task,
2658
3712
  "",
2659
3713
  "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.",
3714
+ "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
3715
  "Each task must have id, title, summary, dependsOn, files ({create,modify,test,delete,read}), acceptance, verification, and risk.",
3716
+ executionContract.phases?.length
3717
+ ? "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."
3718
+ : "",
3719
+ "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
3720
  "Declare every file a task may write. Do not invent files: inspect the repository first.",
3721
+ "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
3722
  ].join("\n");
2664
3723
 
2665
3724
  let architect = await run(
@@ -2669,70 +3728,237 @@ export default function (pi: ExtensionAPI) {
2669
3728
  recentFailure || undefined,
2670
3729
  );
2671
3730
  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
3731
 
2680
- structuredPlan = extractMarkedJson(architect.output, "UES_PLAN_JSON:");
2681
- let structuredValidation = structuredPlan ? validatePlan(structuredPlan) : null;
3732
+ let planCandidate = extractValidatedPlan(architect.output);
3733
+ structuredPlan = planCandidate.plan;
3734
+ let structuredValidation = planCandidate.validation;
2682
3735
 
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 {
3736
+ if (planCandidate.salvaged && structuredValidation?.valid === true) {
3737
+ onUpdate?.({
3738
+ content: [{
3739
+ type: "text",
3740
+ text: `UES planning salvage: recovered a valid plan from ${planCandidate.source} architect output`,
3741
+ }],
3742
+ details: {
3743
+ mode: "execute",
3744
+ phase: "planning-salvage",
3745
+ source: planCandidate.source,
3746
+ traceID,
3747
+ },
3748
+ });
3749
+ }
3750
+
3751
+ const firstPlanValid =
3752
+ structuredPlan &&
3753
+ structuredValidation?.valid === true;
3754
+
3755
+ if (!firstPlanValid) {
3756
+ const recoveryEvidence = failureDelta([
3757
+ architect.exitCode !== 0 || architect.stopReason
3758
+ ? "Previous architect pass stopped before a valid plan: " + String(architect.stopReason || architect.exitCode)
3759
+ : "Previous architect pass returned an invalid plan.",
3760
+ structuredValidation
3761
+ ? JSON.stringify(structuredValidation, null, 2)
3762
+ : "UES_PLAN_JSON marker or valid JSON object was missing.",
3763
+ "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.",
3764
+ "acceptance and verification must be non-empty string arrays; risk must be low|medium|high|critical; descriptive prose belongs in riskNotes.",
3765
+ ].join("\n"), { maxChars: 4200 });
3766
+
3767
+ architect = await run("ues-architect", planInstruction, 2, recoveryEvidence);
3768
+ if (isAbortedRun(architect)) return abortedResponse(architect, "plan-recovery");
3769
+ planCandidate = extractValidatedPlan(architect.output);
3770
+ structuredPlan = planCandidate.plan;
3771
+ structuredValidation = planCandidate.validation;
3772
+ if (planCandidate.salvaged && structuredValidation?.valid === true) {
3773
+ onUpdate?.({
2703
3774
  content: [{
2704
3775
  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),
3776
+ text: `UES planning salvage: recovery produced a valid ${planCandidate.source} plan`,
2707
3777
  }],
2708
- details: { mode: "execute", policy, steps, structuredPlan, structuredValidation },
2709
- isError: true,
2710
- };
3778
+ details: {
3779
+ mode: "execute",
3780
+ phase: "planning-salvage",
3781
+ source: planCandidate.source,
3782
+ traceID,
3783
+ },
3784
+ });
2711
3785
  }
2712
3786
  }
2713
3787
 
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
- );
3788
+ if (
3789
+ !structuredPlan ||
3790
+ structuredValidation?.valid !== true
3791
+ ) {
3792
+ return {
3793
+ content: [{
3794
+ type: "text",
3795
+ text: "Long-horizon planning exhausted its bounded fast-planning recovery without a valid deterministic task graph.\n\n" +
3796
+ (structuredValidation ? JSON.stringify(structuredValidation, null, 2) : architect.output),
3797
+ }],
3798
+ details: { mode: "execute", policy, steps, structuredPlan, structuredValidation },
3799
+ isError: true,
3800
+ };
3801
+ }
3802
+
3803
+ let phaseGate = enforcePhaseGates(structuredPlan, executionContract);
3804
+ if (phaseGate.valid !== true) {
3805
+ const phaseRevisionEvidence = failureDelta([
3806
+ "The deterministic explicit-phase gate rejected the plan.",
3807
+ "Do not rescan the repository. Revise only phase assignment/coverage/dependencies.",
3808
+ "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.",
3809
+ "Phase gate errors:",
3810
+ phaseGate.errors.join("\n"),
3811
+ "Current plan:",
3812
+ JSON.stringify(structuredPlan, null, 2),
3813
+ ].join("\n"), { maxChars: 6200 });
3814
+ const phaseRevisedArchitect = await run(
3815
+ "ues-architect",
3816
+ planInstruction,
3817
+ 2,
3818
+ phaseRevisionEvidence,
3819
+ );
3820
+ if (isAbortedRun(phaseRevisedArchitect)) {
3821
+ return abortedResponse(phaseRevisedArchitect, "phase-plan-auto-revise");
3822
+ }
3823
+ const phaseRevisedCandidate = extractValidatedPlan(phaseRevisedArchitect.output);
3824
+ if (phaseRevisedCandidate.plan && phaseRevisedCandidate.validation?.valid === true) {
3825
+ const revisedPhaseGate = enforcePhaseGates(
3826
+ phaseRevisedCandidate.plan,
3827
+ executionContract,
3828
+ );
3829
+ if (revisedPhaseGate.valid === true) {
3830
+ architect = phaseRevisedArchitect;
3831
+ structuredPlan = revisedPhaseGate.plan;
3832
+ structuredValidation = phaseRevisedCandidate.validation;
3833
+ phaseGate = revisedPhaseGate;
3834
+ onUpdate?.({
3835
+ content: [{
3836
+ type: "text",
3837
+ text: "UES phase gate: auto-revised phase coverage/dependencies once and recovered a valid gated plan",
3838
+ }],
3839
+ details: { mode: "execute", phase: "phase-plan-auto-revise", phaseGate, traceID },
3840
+ });
3841
+ } else {
3842
+ phaseGate = revisedPhaseGate;
3843
+ }
3844
+ }
3845
+ }
3846
+ if (phaseGate.valid !== true) {
3847
+ return {
3848
+ content: [{
3849
+ type: "text",
3850
+ text:
3851
+ "Explicit phase contract gate did not pass after bounded auto-recovery. UES will not flatten or skip user-declared phases.\n\n" +
3852
+ phaseGate.errors.join("\n"),
3853
+ }],
3854
+ details: { mode: "execute", policy, steps, structuredPlan, phaseGate, executionContract },
3855
+ isError: true,
3856
+ };
3857
+ }
3858
+ structuredPlan = phaseGate.plan;
3859
+
3860
+ const buildPlanCheckTask = () => [
3861
+ "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.",
3862
+ "Use declared files and dependencies first. Do not inventory the repository. Resolve only concrete grounding gaps, then return the verdict.",
3863
+ "",
3864
+ "Original task:",
3865
+ params.task,
3866
+ "",
3867
+ "Inline plan:",
3868
+ structuredPlan ? JSON.stringify(structuredPlan, null, 2) : architect.output,
3869
+ ].join("\n");
3870
+
3871
+ let planCheckTask = buildPlanCheckTask();
3872
+ let planCheck = await run("ues-plan-checker", planCheckTask, 1);
2727
3873
  if (isAbortedRun(planCheck)) return abortedResponse(planCheck, "plan-verification");
3874
+
3875
+ const planCheckTransportFailure =
3876
+ planCheck.verdict !== "PASS" &&
3877
+ planCheck.verdict !== "REVISE" &&
3878
+ (
3879
+ planCheck.exitCode !== 0 ||
3880
+ /hard-timeout|idle-timeout|UES RPC hard-timeout|UES RPC idle-timeout/i.test(
3881
+ String(planCheck.output || "") + "\n" +
3882
+ String(planCheck.stderr || "") + "\n" +
3883
+ String(planCheck.stopReason || ""),
3884
+ )
3885
+ );
3886
+
3887
+ if (planCheckTransportFailure) {
3888
+ const planCheckRecoveryEvidence = failureDelta([
3889
+ "Previous plan-checker runtime failure:",
3890
+ String(planCheck.output || planCheck.stderr || planCheck.stopReason || "unknown"),
3891
+ "Reuse warm context. Do not scan broadly. Check only unresolved declared paths/dependencies and return PASS or REVISE.",
3892
+ ].join("\n"), { maxChars: 2600 });
3893
+
3894
+ planCheck = await run(
3895
+ "ues-plan-checker",
3896
+ planCheckTask,
3897
+ 2,
3898
+ planCheckRecoveryEvidence,
3899
+ );
3900
+ if (isAbortedRun(planCheck)) return abortedResponse(planCheck, "plan-verification-recovery");
3901
+ }
3902
+
3903
+ if (planCheck.verdict === "REVISE") {
3904
+ const revisionEvidence = failureDelta([
3905
+ "The independent plan-checker requested a bounded revision.",
3906
+ "Do not restart broad repository exploration. Change only the rejected plan claims/scope.",
3907
+ "Plan-checker feedback:",
3908
+ String(planCheck.output || ""),
3909
+ "Current plan:",
3910
+ JSON.stringify(structuredPlan, null, 2),
3911
+ ].join("\n"), { maxChars: 5200 });
3912
+
3913
+ const revisedArchitect = await run(
3914
+ "ues-architect",
3915
+ planInstruction,
3916
+ 2,
3917
+ revisionEvidence,
3918
+ );
3919
+ if (isAbortedRun(revisedArchitect)) return abortedResponse(revisedArchitect, "plan-auto-revise");
3920
+ const revisedCandidate = extractValidatedPlan(revisedArchitect.output);
3921
+ if (revisedCandidate.plan && revisedCandidate.validation?.valid === true) {
3922
+ architect = revisedArchitect;
3923
+ structuredPlan = revisedCandidate.plan;
3924
+ structuredValidation = revisedCandidate.validation;
3925
+ planCheckTask = buildPlanCheckTask();
3926
+ onUpdate?.({
3927
+ content: [{ type: "text", text: "UES plan gate: auto-revised the rejected plan; re-checking once" }],
3928
+ details: { mode: "execute", phase: "plan-auto-revise", policy, traceID },
3929
+ });
3930
+ planCheck = await run(
3931
+ "ues-plan-checker",
3932
+ planCheckTask,
3933
+ 2,
3934
+ failureDelta(String(planCheck.output || ""), { maxChars: 2600 }),
3935
+ );
3936
+ if (isAbortedRun(planCheck)) return abortedResponse(planCheck, "plan-auto-revise-check");
3937
+ }
3938
+ }
3939
+
3940
+ const finalPhaseGate = enforcePhaseGates(structuredPlan, executionContract);
3941
+ if (finalPhaseGate.valid !== true) {
3942
+ return {
3943
+ content: [{
3944
+ type: "text",
3945
+ text:
3946
+ "Plan revision lost the deterministic explicit-phase contract. UES will not execute it.\n\n" +
3947
+ finalPhaseGate.errors.join("\n"),
3948
+ }],
3949
+ details: { mode: "execute", policy, steps, structuredPlan, finalPhaseGate, executionContract },
3950
+ isError: true,
3951
+ };
3952
+ }
3953
+ structuredPlan = finalPhaseGate.plan;
3954
+
2728
3955
  if (planCheck.exitCode !== 0 || planCheck.verdict !== "PASS") {
2729
3956
  return {
2730
- content: [{ type: "text", text: `Plan gate did not pass:\n\n${planCheck.output}` }],
3957
+ content: [{ type: "text", text: `Plan gate did not pass after bounded auto-recovery:\n\n${planCheck.output}` }],
2731
3958
  details: { mode: "execute", policy, steps, structuredPlan },
2732
3959
  isError: true,
2733
3960
  };
2734
3961
  }
2735
-
2736
3962
  const durableRequested =
2737
3963
  policy.mode === "long-horizon" || policy.profile?.durableState === true;
2738
3964
  if (durableRequested) {
@@ -2754,6 +3980,10 @@ export default function (pi: ExtensionAPI) {
2754
3980
  planCheck.output,
2755
3981
  signal,
2756
3982
  );
3983
+ durableWork.executionArtifacts = await persistExecutionContractArtifacts(
3984
+ durableWork.dir,
3985
+ executionContract,
3986
+ );
2757
3987
  onUpdate?.({
2758
3988
  content: [{
2759
3989
  type: "text",
@@ -2787,6 +4017,7 @@ export default function (pi: ExtensionAPI) {
2787
4017
  inheritedModel,
2788
4018
  inheritedThinking,
2789
4019
  maxAttempts,
4020
+ rootPolicy: policy,
2790
4021
  durableSlug: durableWork?.slug,
2791
4022
  traceID,
2792
4023
  signal,
@@ -2893,12 +4124,131 @@ export default function (pi: ExtensionAPI) {
2893
4124
  }
2894
4125
  }
2895
4126
 
4127
+ const verdictMatrix = buildFinalVerdictMatrix(params.task, {
4128
+ contract: executionContract,
4129
+ primaryPass: true,
4130
+ integrationPass: true,
4131
+ primaryOutput: (scheduled.results || [])
4132
+ .map((row: any) => row?.verification?.output || row?.implementation?.output || "")
4133
+ .filter(Boolean)
4134
+ .join("\n"),
4135
+ integrationOutput: integration.output,
4136
+ visualOutput: visualResult?.output || "",
4137
+ primaryChecks: (scheduled.results || [])
4138
+ .flatMap((row: any) => Object.values(row?.verification?.report?.sections || {}))
4139
+ .filter(Boolean)
4140
+ .join("\n"),
4141
+ integrationChecks: integration.report?.sections?.["checks-run"] || "",
4142
+ visualChecks: visualResult?.report?.sections?.["checks-run"] || "",
4143
+ });
4144
+
4145
+ const finalEvidenceForContract = [
4146
+ integration.output,
4147
+ visualResult?.output || "",
4148
+ ].filter(Boolean).join("\n\n--- VISUAL ---\n\n");
4149
+
4150
+ if (verdictMatrix.final !== "PASS") {
4151
+ if (durableWork) {
4152
+ await durableRecordIntegration(
4153
+ cwd,
4154
+ durableWork.slug,
4155
+ "PARTIAL",
4156
+ finalEvidenceForContract,
4157
+ signal,
4158
+ ).catch(() => {});
4159
+ await finalizeExecutionContractArtifacts(
4160
+ durableWork.dir,
4161
+ executionContract,
4162
+ verdictMatrix,
4163
+ finalEvidenceForContract,
4164
+ ).catch(() => null);
4165
+ }
4166
+ const deviceOnlyPending =
4167
+ verdictMatrix.final === "SOURCE_RUNTIME_PASS_DEVICE_NOT_VERIFIED";
4168
+ return {
4169
+ content: [{
4170
+ type: "text",
4171
+ text: [
4172
+ deviceOnlyPending
4173
+ ? "UES source/runtime verification passed, but requested real-device verification is still pending."
4174
+ : "UES deterministic final gate is not fully verified.",
4175
+ "",
4176
+ verdictMatrix.source,
4177
+ verdictMatrix.runtime,
4178
+ verdictMatrix.dbClean,
4179
+ verdictMatrix.device,
4180
+ "",
4181
+ integration.output,
4182
+ ].join("\n"),
4183
+ }],
4184
+ details: {
4185
+ mode: "execute",
4186
+ policy,
4187
+ steps,
4188
+ structuredPlan,
4189
+ scheduled,
4190
+ durableWork,
4191
+ verdictMatrix,
4192
+ executionContract,
4193
+ traceID,
4194
+ },
4195
+ isError: !deviceOnlyPending,
4196
+ };
4197
+ }
4198
+
4199
+ const finalWriteScope = [...new Set(
4200
+ structuredPlan.tasks.flatMap((task: any) => taskWriteFiles(task)),
4201
+ )];
4202
+ const preFinalAudit = await preFinalWorkspaceAudit(cwd, {
4203
+ baseline: controllerHygieneBaseline,
4204
+ taskText: params.task,
4205
+ allowedPaths: finalWriteScope,
4206
+ strictScope: true,
4207
+ allowSourceMutations: true,
4208
+ }).catch((error) => ({
4209
+ safe: false,
4210
+ summary: "pre-final workspace audit failed: " + (error instanceof Error ? error.message : String(error)),
4211
+ findings: [],
4212
+ }));
4213
+ if (!preFinalAudit.safe) {
4214
+ if (durableWork) {
4215
+ await durableRecordIntegration(
4216
+ cwd,
4217
+ durableWork.slug,
4218
+ "PARTIAL",
4219
+ preFinalAudit.summary || "pre-final workspace hygiene failed",
4220
+ signal,
4221
+ ).catch(() => {});
4222
+ }
4223
+ return {
4224
+ content: [{
4225
+ type: "text",
4226
+ text: [
4227
+ "UES pre-final workspace audit blocked PASS.",
4228
+ "The final repository contains an undeclared, transient, or Unicode-unsafe change.",
4229
+ "",
4230
+ preFinalAudit.summary || "workspace hygiene failed",
4231
+ ].join("\n"),
4232
+ }],
4233
+ details: {
4234
+ mode: "execute",
4235
+ policy,
4236
+ steps,
4237
+ structuredPlan,
4238
+ scheduled,
4239
+ durableWork,
4240
+ verdictMatrix,
4241
+ executionContract,
4242
+ preFinalAudit,
4243
+ traceID,
4244
+ },
4245
+ isError: true,
4246
+ };
4247
+ }
4248
+
2896
4249
  let durableFinalization: any = null;
2897
4250
  if (durableWork) {
2898
- const finalEvidence = [
2899
- integration.output,
2900
- visualResult?.output || "",
2901
- ].filter(Boolean).join("\n\n--- VISUAL ---\n\n");
4251
+ const finalEvidence = finalEvidenceForContract;
2902
4252
  try {
2903
4253
  durableFinalization = await durableRecordIntegration(
2904
4254
  cwd,
@@ -2921,6 +4271,15 @@ export default function (pi: ExtensionAPI) {
2921
4271
  }
2922
4272
  }
2923
4273
 
4274
+ if (durableWork) {
4275
+ await finalizeExecutionContractArtifacts(
4276
+ durableWork.dir,
4277
+ executionContract,
4278
+ verdictMatrix,
4279
+ finalEvidenceForContract,
4280
+ ).catch(() => null);
4281
+ }
4282
+
2924
4283
  const memoryFiles = [...new Set(structuredPlan.tasks.flatMap((task: any) => taskWriteFiles(task)))];
2925
4284
  const memory = durableWork
2926
4285
  ? durableFinalization?.finalized?.memory || null
@@ -2932,6 +4291,10 @@ export default function (pi: ExtensionAPI) {
2932
4291
  `UES scheduled execution PASS across ${structuredPlan.tasks.length} task(s).`,
2933
4292
  `Safe waves: ${scheduled.schedule?.safeWaves?.length || 0}; integrations: ${scheduled.integrations?.length || 0}.`,
2934
4293
  durableWork ? `Durable state: .ues-work/${durableWork.slug} finalized with fresh integration receipt.` : "",
4294
+ verdictMatrix.source,
4295
+ verdictMatrix.runtime,
4296
+ verdictMatrix.dbClean,
4297
+ verdictMatrix.device,
2935
4298
  "",
2936
4299
  integration.output,
2937
4300
  ].join("\n"),
@@ -2946,6 +4309,8 @@ export default function (pi: ExtensionAPI) {
2946
4309
  memory,
2947
4310
  durableWork,
2948
4311
  durableFinalization,
4312
+ verdictMatrix,
4313
+ executionContract,
2949
4314
  traceID,
2950
4315
  },
2951
4316
  };
@@ -2979,18 +4344,19 @@ export default function (pi: ExtensionAPI) {
2979
4344
  recentFailure = diagnosis.output;
2980
4345
  }
2981
4346
 
2982
- const fastBoundedLane =
2983
- policy.executionProfile === "fast" &&
2984
- policy.singleFileBounded === true &&
2985
- policy.risk === "low" &&
2986
- !visualEvidenceNeeded(params.task) &&
2987
- !browserEvidenceNeeded(params.task, "executor");
4347
+ const fastDecision = turboFastPathDecision(policy, {
4348
+ role: "executor",
4349
+ attempt,
4350
+ browserRequested: browserEvidenceNeeded(params.task, "executor"),
4351
+ visualRequired: visualEvidenceNeeded(params.task),
4352
+ });
4353
+ const fastBoundedLane = fastDecision.eligible;
2988
4354
  const fastAttemptStartedAt = Date.now();
2989
4355
  const executorTask = [
2990
4356
  params.task,
2991
4357
  recentFailure ? "\nEvidence from diagnosis/previous failed verification:\n" + cap(recentFailure, 7000) : "",
2992
4358
  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."
4359
+ ? "\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
4360
  : "",
2995
4361
  "\nImplement the smallest coherent change. Do not push, publish, deploy, rewrite history, or broaden scope without evidence.",
2996
4362
  ].filter(Boolean).join("\n");
@@ -3008,6 +4374,37 @@ export default function (pi: ExtensionAPI) {
3008
4374
  continue;
3009
4375
  }
3010
4376
 
4377
+ const inheritedDirtyCheck = detectInheritedDirtyViolations(
4378
+ cwd,
4379
+ executionContract.inheritedDirty,
4380
+ executionContract.approvedInheritedDirtyPaths || [],
4381
+ );
4382
+ if (!inheritedDirtyCheck.safe) {
4383
+ await recordRuntimeOutcome(implementation, params.task, false, attempt - 1);
4384
+ return {
4385
+ content: [{
4386
+ type: "text",
4387
+ text: [
4388
+ "UES inherited dirty-work guard stopped completion.",
4389
+ "The implementation changed pre-existing dirty source work that was not explicitly authorized by the original task.",
4390
+ "UES will not auto-restore or overwrite these files.",
4391
+ "",
4392
+ ...inheritedDirtyCheck.violations.map((item: any) => "- " + item.path),
4393
+ ].join("\n"),
4394
+ }],
4395
+ details: {
4396
+ mode: "execute",
4397
+ policy,
4398
+ steps,
4399
+ attempts: attempt,
4400
+ executionContract,
4401
+ inheritedDirtyCheck,
4402
+ traceID,
4403
+ },
4404
+ isError: true,
4405
+ };
4406
+ }
4407
+
3011
4408
  let verification: RunResult;
3012
4409
  let fastGate: any = null;
3013
4410
  if (fastBoundedLane) {
@@ -3029,7 +4426,10 @@ export default function (pi: ExtensionAPI) {
3029
4426
  optimizations: { fastDeterministicVerification: true, behavioralReceiptCount: fastGate.behavioralReceipts.length },
3030
4427
  };
3031
4428
  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 } });
4429
+ onUpdate?.({
4430
+ content: [{ type: "text", text: "UES Turbo Fast Path: reused " + fastGate.behavioralReceipts.length + " fresh behavioral receipt(s); skipped verifier model turn" }],
4431
+ details: { mode: "execute", phase: "turbo-fast-verified", policy, fastGate, fastDecision, traceID },
4432
+ });
3033
4433
  } else {
3034
4434
  verification = await run(
3035
4435
  "ues-verifier",
@@ -3125,7 +4525,7 @@ export default function (pi: ExtensionAPI) {
3125
4525
  requireVisual: visualEvidenceNeeded(params.task),
3126
4526
  workspaceSnapshot: completionSnapshot,
3127
4527
  behavioralReceipts: freshReceipts,
3128
- requireBehavioralReceipt: true,
4528
+ requireBehavioralReceipt: policy.requireBehavioralReceipt !== false,
3129
4529
  });
3130
4530
  if (!completionAudit.passed) {
3131
4531
  recentFailure = "Completion auditor rejected PASS: " + completionAudit.failures.join(", ");
@@ -3138,6 +4538,83 @@ export default function (pi: ExtensionAPI) {
3138
4538
  };
3139
4539
  }
3140
4540
 
4541
+ const verdictMatrix = buildFinalVerdictMatrix(params.task, {
4542
+ contract: executionContract,
4543
+ primaryPass: true,
4544
+ integrationPass: integrationResult ? true : undefined,
4545
+ primaryOutput: verification.output,
4546
+ integrationOutput: integrationResult?.output || "",
4547
+ visualOutput: visualResult?.output || "",
4548
+ primaryChecks: verification.report?.sections?.["checks-run"] || "",
4549
+ integrationChecks: integrationResult?.report?.sections?.["checks-run"] || "",
4550
+ visualChecks: visualResult?.report?.sections?.["checks-run"] || "",
4551
+ });
4552
+
4553
+ if (verdictMatrix.final !== "PASS") {
4554
+ await recordRuntimeOutcome(implementation, params.task, false, attempt - 1);
4555
+ const deviceOnlyPending =
4556
+ verdictMatrix.final === "SOURCE_RUNTIME_PASS_DEVICE_NOT_VERIFIED";
4557
+ return {
4558
+ content: [{
4559
+ type: "text",
4560
+ text: [
4561
+ deviceOnlyPending
4562
+ ? "UES source/runtime verification passed, but requested real-device verification is still pending."
4563
+ : "UES deterministic final gate is not fully verified.",
4564
+ "",
4565
+ verdictMatrix.source,
4566
+ verdictMatrix.runtime,
4567
+ verdictMatrix.dbClean,
4568
+ verdictMatrix.device,
4569
+ "",
4570
+ integrationResult?.output || verification.output,
4571
+ ].join("\n"),
4572
+ }],
4573
+ details: {
4574
+ mode: "execute",
4575
+ policy,
4576
+ steps,
4577
+ attempts: attempt,
4578
+ completionAudit,
4579
+ verdictMatrix,
4580
+ executionContract,
4581
+ traceID,
4582
+ },
4583
+ isError: !deviceOnlyPending,
4584
+ };
4585
+ }
4586
+
4587
+ const preFinalAudit = await preFinalWorkspaceAudit(cwd, {
4588
+ baseline: controllerHygieneBaseline,
4589
+ taskText: params.task,
4590
+ strictScope: false,
4591
+ allowSourceMutations: true,
4592
+ }).catch((error) => ({
4593
+ safe: false,
4594
+ summary: "pre-final workspace audit failed: " + (error instanceof Error ? error.message : String(error)),
4595
+ findings: [],
4596
+ }));
4597
+ if (!preFinalAudit.safe) {
4598
+ recentFailure = "Pre-final workspace audit rejected PASS: " + (preFinalAudit.summary || "workspace hygiene failed");
4599
+ await recordRuntimeOutcome(implementation, params.task, false, attempt - 1);
4600
+ if (attempt < maxAttempts) continue;
4601
+ return {
4602
+ content: [{ type: "text", text: recentFailure }],
4603
+ details: {
4604
+ mode: "execute",
4605
+ policy,
4606
+ steps,
4607
+ attempts: attempt,
4608
+ completionAudit,
4609
+ verdictMatrix,
4610
+ executionContract,
4611
+ preFinalAudit,
4612
+ traceID,
4613
+ },
4614
+ isError: true,
4615
+ };
4616
+ }
4617
+
3141
4618
  await recordRuntimeOutcome(implementation, params.task, true, attempt - 1);
3142
4619
  const memory = await rememberVerifiedTask(cwd, params.task, verification, integrationResult);
3143
4620
  const final = steps.at(-1);
@@ -3147,11 +4624,15 @@ export default function (pi: ExtensionAPI) {
3147
4624
  text: [
3148
4625
  `UES execution PASS after ${attempt} attempt(s).`,
3149
4626
  `Policy: ${policy.executionProfile}/${policy.risk}; model tier: ${implementation.modelTier || "default"}.`,
4627
+ verdictMatrix.source,
4628
+ verdictMatrix.runtime,
4629
+ verdictMatrix.dbClean,
4630
+ verdictMatrix.device,
3150
4631
  "",
3151
4632
  final?.output || verification.output,
3152
4633
  ].join("\n"),
3153
4634
  }],
3154
- details: { mode: "execute", policy, steps, attempts: attempt, memory, completionAudit, traceID },
4635
+ details: { mode: "execute", policy, steps, attempts: attempt, memory, completionAudit, verdictMatrix, executionContract, traceID },
3155
4636
  };
3156
4637
  }
3157
4638
 
@@ -3164,15 +4645,373 @@ export default function (pi: ExtensionAPI) {
3164
4645
  isError: true,
3165
4646
  };
3166
4647
  },
4648
+ };
4649
+ pi.registerTool(uesExecuteTool);
4650
+
4651
+ // Extension commands are resolved before prompt templates in Pi. Registering
4652
+ // /ues-run here makes controller admission deterministic: weak models never
4653
+ // have to remember to call ues_execute themselves.
4654
+ pi.registerCommand("ues-status", {
4655
+ description: "Show the loaded UES runtime version and current session policy basics",
4656
+ handler: async (_args, ctx) => {
4657
+ const status = [
4658
+ "UES runtime: " + PACKAGE_VERSION,
4659
+ "Package root: " + PACKAGE_ROOT,
4660
+ "Child runtime: " + CHILD_RUNTIME,
4661
+ "Adaptive context: " + (ADAPTIVE_CONTEXT_ENABLED ? "on" : "off"),
4662
+ "Unified workspace snapshot V2: on",
4663
+ "Parallel context preparation: on",
4664
+ "Git-index affected-test inventory: on",
4665
+ "Parallel verification evidence I/O: on",
4666
+ "Micro skills: " + (MICRO_SKILLS_ENABLED ? "on" : "off"),
4667
+ "Turbo Fast Path: on",
4668
+ "Parent UES tools hidden outside UES runs: on",
4669
+ "Zero-friction engineering admission: " + (AUTO_ADMISSION_ENABLED ? "on (native / auto / high-risk + safe continuation)" : "off"),
4670
+ "Git-root artifact guard: on",
4671
+ "Inherited dirty-work guard: on",
4672
+ "Local .env mutation guard: on",
4673
+ "Portable temp-path guard: on",
4674
+ "Explicit phase barriers: on",
4675
+ "Independent final verdict matrix: on",
4676
+ "Unicode source hygiene: blocking bidi/zero-width/control/homoglyph audit",
4677
+ "Post-run file hygiene: transient cleanup + read-only mutation guard",
4678
+ "Pre-final workspace audit: on",
4679
+ "Disk hygiene: bounded + auto-clean",
4680
+ "Writer concurrency: " + MAX_WRITER_CONCURRENCY,
4681
+ ].join("\n");
4682
+ pi.sendMessage({
4683
+ customType: "ues-runtime-status",
4684
+ content: status,
4685
+ display: true,
4686
+ details: { version: PACKAGE_VERSION, packageRoot: PACKAGE_ROOT, childRuntime: CHILD_RUNTIME },
4687
+ }, { triggerTurn: false });
4688
+ try { ctx.ui.notify("UES runtime " + PACKAGE_VERSION + " loaded", "info"); } catch {}
4689
+ },
4690
+ });
4691
+
4692
+ pi.registerCommand("ues-clean", {
4693
+ description: "Safely remove stale UES task sandboxes and orphan metadata for the current repository",
4694
+ handler: async (_args, ctx) => {
4695
+ if (uesModeActive()) {
4696
+ try { ctx.ui.notify("UES cleanup refused while a UES task is active", "warning"); } catch {}
4697
+ return;
4698
+ }
4699
+ let workspaceRoot: string;
4700
+ try {
4701
+ workspaceRoot = requireGitWorkspaceRoot(ctx.cwd, "/ues-clean");
4702
+ } catch (error) {
4703
+ const message = error instanceof Error ? error.message : String(error);
4704
+ pi.sendMessage({
4705
+ customType: "ues-cleanup-result",
4706
+ content: "UES cleanup refused unsafe workspace.\n" + message,
4707
+ display: true,
4708
+ details: { error: message },
4709
+ }, { triggerTurn: false });
4710
+ try { ctx.ui.notify(message, "error"); } catch {}
4711
+ return;
4712
+ }
4713
+ const cleanup = await pruneOrphanTaskSandboxes(workspaceRoot, {
4714
+ minAgeMs: 5 * 60_000,
4715
+ legacyMinAgeMs: 30 * 60_000,
4716
+ ownedMinAgeMs: 0,
4717
+ reclaimOwnerPid: process.pid,
4718
+ protectedDirs: [...ACTIVE_TASK_SANDBOXES.keys()],
4719
+ }).catch((error) => ({
4720
+ removed: [],
4721
+ skipped: [],
4722
+ sidecarsRemoved: [],
4723
+ error: error instanceof Error ? error.message : String(error),
4724
+ }));
4725
+ const removed = Number(cleanup?.removed?.length || 0);
4726
+ const sidecars = Number(cleanup?.sidecarsRemoved?.length || 0);
4727
+ const skipped = Number(cleanup?.skipped?.length || 0);
4728
+ await stopAllServices(workspaceRoot).catch(() => []);
4729
+ const transientDirs = [".ues-traces", ".ues-services", ".ues-dashboard"];
4730
+ const removedRuntimeDirs: string[] = [];
4731
+ for (const name of transientDirs) {
4732
+ const target = path.join(workspaceRoot, name);
4733
+ if (!fs.existsSync(target)) continue;
4734
+ await fs.promises.rm(target, { recursive: true, force: true }).catch(() => {});
4735
+ if (!fs.existsSync(target)) removedRuntimeDirs.push(name);
4736
+ }
4737
+
4738
+ const cacheDir = path.join(workspaceRoot, ".ues-cache");
4739
+ const removedCacheEntries: string[] = [];
4740
+ if (fs.existsSync(cacheDir)) {
4741
+ const entries = await fs.promises.readdir(cacheDir, { withFileTypes: true }).catch(() => []);
4742
+ for (const entry of entries) {
4743
+ if (entry.name === "evidence-v1") continue;
4744
+ if (
4745
+ entry.name === "semantic-index-v1.json" ||
4746
+ entry.name.startsWith("semantic-index-v1.json.") ||
4747
+ entry.name === "verification-broker-v1.json" ||
4748
+ entry.name.startsWith("verification-broker-v1.json.")
4749
+ ) {
4750
+ await fs.promises.rm(path.join(cacheDir, entry.name), { recursive: true, force: true }).catch(() => {});
4751
+ removedCacheEntries.push(entry.name);
4752
+ }
4753
+ }
4754
+ }
4755
+ const evidenceGc = await gcEvidenceStore(workspaceRoot, {
4756
+ maxBytes: 96 * 1024 * 1024,
4757
+ maxEntries: 600,
4758
+ maxAgeDays: 14,
4759
+ }).catch((error) => ({
4760
+ removed: [],
4761
+ removedCount: 0,
4762
+ protectedEntries: 0,
4763
+ protectedBytes: 0,
4764
+ error: error instanceof Error ? error.message : String(error),
4765
+ }));
4766
+
4767
+ if (fs.existsSync(cacheDir)) {
4768
+ const remaining = await fs.promises.readdir(cacheDir).catch(() => ["unknown"]);
4769
+ if (remaining.length === 0) await fs.promises.rm(cacheDir, { recursive: true, force: true }).catch(() => {});
4770
+ }
4771
+
4772
+ const text = [
4773
+ "UES cleanup complete.",
4774
+ "Removed sandboxes: " + removed,
4775
+ "Removed orphan metadata: " + sidecars,
4776
+ "Removed transient runtime dirs: " + (removedRuntimeDirs.join(", ") || "none"),
4777
+ "Removed rebuildable cache entries: " + (removedCacheEntries.length || 0),
4778
+ "Pruned evidence blobs: " + Number(evidenceGc?.removedCount || 0),
4779
+ "Protected verified-memory evidence: " + Number(evidenceGc?.protectedEntries || 0),
4780
+ "Protected/recent entries kept: " + skipped,
4781
+ "Preserved durable state: .ues-work, .ues-memory, .ues-learning, .ues-evals and verified-memory evidence",
4782
+ cleanup?.baseRemoved ? "Sandbox base directory removed because it is empty." : "",
4783
+ cleanup?.error ? "Error: " + cleanup.error : "",
4784
+ ].filter(Boolean).join("\n");
4785
+ pi.sendMessage({
4786
+ customType: "ues-cleanup-result",
4787
+ content: text,
4788
+ display: true,
4789
+ details: { ...cleanup, removedRuntimeDirs, removedCacheEntries, evidenceGc },
4790
+ }, { triggerTurn: false });
4791
+ try {
4792
+ ctx.ui.notify(
4793
+ "UES cleanup removed/pruned " +
4794
+ (removed + sidecars + removedRuntimeDirs.length + removedCacheEntries.length + Number(evidenceGc?.removedCount || 0)) +
4795
+ " stale/transient artifact(s)",
4796
+ "info",
4797
+ );
4798
+ } catch {}
4799
+ },
4800
+ });
4801
+
4802
+ directControllerRunner = async (task, ctx, admission, admissionDecision) => {
4803
+ if (directControllerAbort && !directControllerAbort.signal.aborted) {
4804
+ try { ctx.ui.notify("UES controller is already running in this session", "warning"); } catch {}
4805
+ return;
4806
+ }
4807
+
4808
+ let workspaceRoot: string;
4809
+ try {
4810
+ workspaceRoot = requireGitWorkspaceRoot(ctx.cwd, admission === "automatic" ? "automatic UES admission" : "/ues-run");
4811
+ } catch (error) {
4812
+ const message = error instanceof Error ? error.message : String(error);
4813
+ pi.sendMessage({
4814
+ customType: "ues-controller-result",
4815
+ content: message,
4816
+ display: true,
4817
+ details: { controllerUsed: false, controllerPass: false, reason: "unsafe-workspace-root" },
4818
+ }, { triggerTurn: false });
4819
+ try { ctx.ui.notify(message, "error"); } catch {}
4820
+ return;
4821
+ }
4822
+
4823
+ const abort = new AbortController();
4824
+ directControllerAbort = abort;
4825
+ const directTraceID = createTraceID(admission === "automatic" ? "ues-auto" : "ues-run");
4826
+ syncSessionIdentity(uesSessionName("run", task, workspaceRoot), ctx);
4827
+ let result: any;
4828
+ let lastProgressNoticeAt = 0;
4829
+ let lastProgressKey = "";
4830
+ try {
4831
+ const directPolicy =
4832
+ admissionDecision?.policy && typeof admissionDecision.policy === "object"
4833
+ ? admissionDecision.policy
4834
+ : classifyEngineeringTask(task);
4835
+ const routeLabel =
4836
+ admission === "automatic"
4837
+ ? admissionDecision?.route === "guarded"
4838
+ ? "high-risk auto controller started ("
4839
+ : "auto controller started ("
4840
+ : "controller started (";
4841
+ try {
4842
+ ctx.ui.notify(
4843
+ "UES " + PACKAGE_VERSION + ": " + routeLabel +
4844
+ String(directPolicy.executionProfile || directPolicy.mode || "unknown") +
4845
+ "/" + String(directPolicy.risk || "unknown") + ")",
4846
+ admissionDecision?.route === "guarded" ? "warning" : "info",
4847
+ );
4848
+ } catch {}
4849
+ result = await uesExecuteTool.execute(
4850
+ `ues-run-${randomUUID()}`,
4851
+ { task, cwd: workspaceRoot, __traceID: directTraceID, __taskPolicy: directPolicy },
4852
+ abort.signal,
4853
+ (update: any) => {
4854
+ const text = (update?.content || [])
4855
+ .filter((part: any) => part?.type === "text" && typeof part.text === "string")
4856
+ .map((part: any) => part.text)
4857
+ .join("\n")
4858
+ .trim();
4859
+ if (text) {
4860
+ try { ctx.ui.setStatus("ues-run", cap(text, 180)); } catch {}
4861
+ }
4862
+
4863
+ const progress = update?.details?.progress;
4864
+ if (progress) {
4865
+ const progressKey = String(progress.agent || "") + ":" + String(update?.details?.phase || "");
4866
+ const now = Date.now();
4867
+ const phaseChanged = progressKey && progressKey !== lastProgressKey;
4868
+ const heartbeatDue = now - lastProgressNoticeAt >= 60_000;
4869
+ if (phaseChanged || heartbeatDue) {
4870
+ const message =
4871
+ "UES: " + String(progress.agent || "worker") +
4872
+ " running " + Math.round(Number(progress.elapsedMs || 0) / 1000) + "s" +
4873
+ " (idle " + Math.round(Number(progress.idleMs || 0) / 1000) + "s, tools " +
4874
+ Number(progress.toolCalls || 0) +
4875
+ (progress.activeTool ? ", " + String(progress.activeTool) : "") + ")";
4876
+ try {
4877
+ ctx.ui.notify(
4878
+ message,
4879
+ Number(progress.idleMs || 0) >= 45_000 ? "warning" : "info",
4880
+ );
4881
+ } catch {}
4882
+ lastProgressNoticeAt = now;
4883
+ lastProgressKey = progressKey;
4884
+ }
4885
+ }
4886
+
4887
+ if (process.env.UES_EVAL_DIRECT_TELEMETRY === "1") {
4888
+ process.stderr.write(JSON.stringify({
4889
+ type: "ues_controller_progress",
4890
+ phase: update?.details?.phase || null,
4891
+ task: update?.details?.task || null,
4892
+ agent: progress?.agent || null,
4893
+ elapsedMs: Number(progress?.elapsedMs || 0),
4894
+ idleMs: Number(progress?.idleMs || 0),
4895
+ toolCalls: Number(progress?.toolCalls || 0),
4896
+ activeTool: progress?.activeTool || null,
4897
+ note: progress?.note || null,
4898
+ text: text ? cap(text, 240) : null,
4899
+ }) + "\n");
4900
+ }
4901
+ },
4902
+ ctx,
4903
+ );
4904
+ } catch (error) {
4905
+ result = {
4906
+ content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
4907
+ details: { mode: "execute", reason: "direct-controller-exception" },
4908
+ isError: true,
4909
+ };
4910
+ } finally {
4911
+ const traceRemoved = await cleanupTraceSandboxes(workspaceRoot, directTraceID).catch(() => 0);
4912
+ const staleCleanup = await pruneOrphanTaskSandboxes(workspaceRoot, {
4913
+ minAgeMs: 5 * 60_000,
4914
+ legacyMinAgeMs: 30 * 60_000,
4915
+ ownedMinAgeMs: 0,
4916
+ reclaimOwnerPid: process.pid,
4917
+ protectedDirs: [...ACTIVE_TASK_SANDBOXES.keys()],
4918
+ }).catch(() => ({ removed: [], skipped: [], sidecarsRemoved: [] }));
4919
+ const cleaned =
4920
+ Number(traceRemoved || 0) +
4921
+ Number(staleCleanup?.removed?.length || 0) +
4922
+ Number(staleCleanup?.sidecarsRemoved?.length || 0);
4923
+ if (cleaned > 0) {
4924
+ try { ctx.ui.notify("UES cleanup: removed " + cleaned + " stale sandbox artifact(s)", "info"); } catch {}
4925
+ }
4926
+ if (directControllerAbort === abort) directControllerAbort = null;
4927
+ try { ctx.ui.setStatus("ues-run", undefined); } catch {}
4928
+ }
4929
+
4930
+ const content = (result?.content || [])
4931
+ .filter((part: any) => part?.type === "text" && typeof part.text === "string")
4932
+ .map((part: any) => part.text)
4933
+ .join("\n")
4934
+ .trim() || "(UES controller returned no text)";
4935
+ const controllerPass = result?.isError !== true;
4936
+
4937
+ if (process.env.UES_EVAL_DIRECT_TELEMETRY === "1") {
4938
+ const details = result?.details || null;
4939
+ const telemetryDetails = details
4940
+ ? {
4941
+ mode: details.mode,
4942
+ attempts: details.attempts,
4943
+ policy: details.policy
4944
+ ? {
4945
+ mode: details.policy.mode,
4946
+ executionProfile: details.policy.executionProfile,
4947
+ risk: details.policy.risk,
4948
+ }
4949
+ : null,
4950
+ steps: Array.isArray(details.steps)
4951
+ ? details.steps.map((step: any) => ({
4952
+ agent: step?.agent,
4953
+ exitCode: step?.exitCode,
4954
+ optimizations: step?.optimizations || null,
4955
+ usage: step?.usage || null,
4956
+ toolCalls: Number(step?.toolCalls || 0),
4957
+ toolNames: Array.isArray(step?.toolNames) ? step.toolNames : [],
4958
+ }))
4959
+ : [],
4960
+ }
4961
+ : null;
4962
+ process.stderr.write(JSON.stringify({
4963
+ type: "ues_controller_direct",
4964
+ controllerUsed: true,
4965
+ controllerPass,
4966
+ details: telemetryDetails,
4967
+ }) + "\n");
4968
+ }
4969
+
4970
+ pi.sendMessage({
4971
+ customType: "ues-controller-result",
4972
+ content,
4973
+ display: true,
4974
+ details: {
4975
+ controllerUsed: true,
4976
+ controllerPass,
4977
+ admission,
4978
+ admissionRoute: admissionDecision?.route || (admission === "command" ? "command" : "auto"),
4979
+ admissionConfidence: admissionDecision?.confidence || null,
4980
+ admissionReason: admissionDecision?.reason || null,
4981
+ ...(result?.details || {}),
4982
+ },
4983
+ });
4984
+
4985
+ try {
4986
+ ctx.ui.notify(
4987
+ controllerPass ? "UES " + PACKAGE_VERSION + ": verified controller run completed" : "UES " + PACKAGE_VERSION + ": controller run failed verification",
4988
+ controllerPass ? "info" : "error",
4989
+ );
4990
+ } catch {}
4991
+
4992
+ };
4993
+
4994
+ pi.registerCommand("ues-run", {
4995
+ description: "Run an engineering task directly through the deterministic UES controller",
4996
+ handler: async (args, ctx) => {
4997
+ const task = String(args || "").trim();
4998
+ if (!task) {
4999
+ try { ctx.ui.notify("Usage: /ues-run <engineering task>", "warning"); } catch {}
5000
+ return;
5001
+ }
5002
+ await directControllerRunner?.(task, ctx, "command");
5003
+ },
3167
5004
  });
3168
5005
 
3169
5006
  pi.registerTool({
3170
5007
  name: "ues_dispatch",
3171
5008
  label: "UES Dispatch",
3172
5009
  description:
3173
- "Run bundled UES specialist agents in isolated child Pi processes. Supports single, parallel, or chain mode. Parallel writer agents fail closed unless each writer has an explicit distinct cwd/worktree. Available agents: " +
5010
+ "Run bundled UES specialist agents in isolated child Pi processes, or inspect durable child handles with action=status/list. Every child run writes a small artifact with exact task/output evidence references. Supports single, parallel, or chain mode. Parallel writer agents fail closed unless each writer has an explicit distinct cwd/worktree. Available agents: " +
3174
5011
  Object.keys(AGENTS).join(", "),
3175
5012
  parameters: Type.Object({
5013
+ action: Type.Optional(Type.Union([Type.Literal("run"), Type.Literal("status"), Type.Literal("list")])),
5014
+ handle: Type.Optional(Type.String({ description: "Subagent artifact handle for status action" })),
3176
5015
  agent: Type.Optional(Type.String({ description: "Agent name for single mode" })),
3177
5016
  task: Type.Optional(Type.String({ description: "Task for single mode" })),
3178
5017
  cwd: Type.Optional(Type.String({ description: "Working directory for single mode" })),
@@ -3181,6 +5020,39 @@ export default function (pi: ExtensionAPI) {
3181
5020
  }),
3182
5021
  async execute(_toolCallId, params, signal, onUpdate, ctx) {
3183
5022
  refreshHostBrowserToolNames(pi);
5023
+ const action = String(params.action || "run");
5024
+ const baseCwd = ctx.cwd;
5025
+ if (action === "status") {
5026
+ if (!params.handle) {
5027
+ return {
5028
+ content: [{ type: "text", text: "ues_dispatch action=status requires handle." }],
5029
+ details: { mode: "status" },
5030
+ isError: true,
5031
+ };
5032
+ }
5033
+ try {
5034
+ const root = requireGitWorkspaceRoot(baseCwd, "ues_dispatch status");
5035
+ const artifact = await readSubagentArtifact(root, params.handle);
5036
+ return {
5037
+ content: [{ type: "text", text: JSON.stringify(artifact, null, 2) }],
5038
+ details: { mode: "status", artifact },
5039
+ };
5040
+ } catch (error) {
5041
+ return {
5042
+ content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
5043
+ details: { mode: "status", handle: params.handle },
5044
+ isError: true,
5045
+ };
5046
+ }
5047
+ }
5048
+ if (action === "list") {
5049
+ const root = requireGitWorkspaceRoot(baseCwd, "ues_dispatch list");
5050
+ const artifacts = await listSubagentArtifacts(root, { limit: 20 });
5051
+ return {
5052
+ content: [{ type: "text", text: JSON.stringify(artifacts, null, 2) }],
5053
+ details: { mode: "list", artifacts },
5054
+ };
5055
+ }
3184
5056
  const hasSingle = Boolean(params.agent && params.task);
3185
5057
  const hasParallel = Boolean(params.tasks?.length);
3186
5058
  const hasChain = Boolean(params.chain?.length);
@@ -3195,7 +5067,6 @@ export default function (pi: ExtensionAPI) {
3195
5067
  const validateAgent = (name: string): name is AgentName => name in AGENTS;
3196
5068
  const model = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined;
3197
5069
  const thinking = ctx.thinkingLevel as string | undefined;
3198
- const baseCwd = ctx.cwd;
3199
5070
 
3200
5071
  if (hasSingle) {
3201
5072
  if (!validateAgent(params.agent!)) {
@@ -3293,7 +5164,11 @@ export default function (pi: ExtensionAPI) {
3293
5164
  }
3294
5165
 
3295
5166
  let completed = 0;
3296
- const results = await mapLimit(tasks, MAX_CONCURRENCY, async (item) => {
5167
+ const dispatchHasWriters = tasks.some((item) => WRITE_AGENTS.has(item.agent));
5168
+ const dispatchConcurrency = dispatchHasWriters
5169
+ ? Math.min(MAX_CONCURRENCY, MAX_WRITER_CONCURRENCY)
5170
+ : MAX_CONCURRENCY;
5171
+ const results = await mapLimit(tasks, dispatchConcurrency, async (item) => {
3297
5172
  const result = await runRoutedAgent(
3298
5173
  item.agent as AgentName,
3299
5174
  item.task,