From b56614c814b904c224315a11f9686f0d47abd3d3 Mon Sep 17 00:00:00 2001 From: tanaka takashi Date: Wed, 12 Aug 2026 05:44:54 +0900 Subject: feat: revise sandbox usability around semantic policy and LPAC process trees Rewrite the specification and design vocabulary around User Sandbox Configuration, Environment Resolution, Executable Approval, Effective Sandbox Policy, and Windows Enforcement. Move the Internal Tool catalog to the design without treating its count as a requirement, and update README, implementation planning, traceability, audit history, prompts, and the Python skill. Introduce schema_version 1 profiles, workspaces, mounts, executable aliases, network modes, and resource presets. Add local override merging, resolution and approval stores with atomic user-only persistence, fail-closed fingerprints, localized diagnostics, and executable/sandbox management CLI commands. Change Windows execution to LPAC entry approval with inherited descendant confinement. Separate read and execute ACLs, preserve protected OS DACLs, apply Job process/memory/timeout limits to the tree, enforce WFP network modes, prevent credential environment inheritance, disable out-of-tree MSBuild reuse, and harden transactional ACL/recovery cleanup. Isolate planning prompts from execution instructions, reject split coding plans that cannot satisfy task-scoped evidence, preserve configured thinking, and prevent optional task_update failures from corrupting completion checks. Add and update configuration, resolution, approval, LPAC, descendant, readonly/development, Registry/COM, WFP, recovery, .NET/Python/PowerShell process-tree, and Operational E2E coverage. Publish reproducible bundles while preserving deployment-local configuration, prompts, skills, logs, state, approvals, and resolutions. --- tests/Agent.Core.Tests/PromptAndRuntimeTests.cs | 27 ++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'tests/Agent.Core.Tests/PromptAndRuntimeTests.cs') diff --git a/tests/Agent.Core.Tests/PromptAndRuntimeTests.cs b/tests/Agent.Core.Tests/PromptAndRuntimeTests.cs index 082ea9b..b7f27e7 100644 --- a/tests/Agent.Core.Tests/PromptAndRuntimeTests.cs +++ b/tests/Agent.Core.Tests/PromptAndRuntimeTests.cs @@ -275,7 +275,7 @@ public sealed class PromptAndRuntimeTests { TaskRegistry registry = new(); var ollama = new ThinkRetryOllamaClient(succeedOnRetry: true); - var runtime = new AgentRuntime(registry, ollama, new AgentRuntimeSettings("", "en", [], "sandbox")); + var runtime = new AgentRuntime(registry, ollama, new AgentRuntimeSettings("execution-only-marker", "en", [], "sandbox")); TaskSnapshot task = registry.Enqueue("analyze", null, 0.7); registry.Transition(task.TaskId, AgentTaskState.Planning); @@ -291,6 +291,8 @@ public sealed class PromptAndRuntimeTests message.Role == "system" && message.Content.Contains("one implementation-and-verification Task", StringComparison.Ordinal)); Assert.Contains(ollama.PlanningMessages[1], message => message.Role == "system" && message.Content.Contains("Do not call or execute any Tool", StringComparison.Ordinal)); + Assert.DoesNotContain(ollama.PlanningMessages.SelectMany(static messages => messages), message => + message.Content.Contains("execution-only-marker", StringComparison.Ordinal)); } [Fact] @@ -310,6 +312,23 @@ public sealed class PromptAndRuntimeTests Assert.Equal(0, ollama.RunCalls); } + [Fact] + public async Task Split_coding_plan_is_rejected_and_retried_with_specific_correction() + { + TaskRegistry registry = new(); + var ollama = new ThinkRetryOllamaClient(succeedOnRetry: true, semanticSplitFirst: true); + var runtime = new AgentRuntime(registry, ollama, new AgentRuntimeSettings("", "en", [], "sandbox")); + TaskSnapshot task = registry.Enqueue("implement and test", null, null); + registry.Transition(task.TaskId, AgentTaskState.Planning); + + await runtime.ExecuteAsync(task.TaskId, TestContext.Current.CancellationToken); + + Assert.True(registry.TryGet(task.TaskId, null, out TaskSnapshot? completed)); + Assert.Equal(AgentTaskState.Completed, completed!.State); + Assert.Contains(ollama.PlanningMessages[1], message => message.Role == "system" && + message.Content.Contains("cannot depend on a separate file_edit Task", StringComparison.Ordinal)); + } + [Fact] public async Task Failed_context_summary_does_not_delete_original_context() { @@ -610,7 +629,7 @@ public sealed class PromptAndRuntimeTests } } - private sealed class ThinkRetryOllamaClient(bool succeedOnRetry) : IOllamaClient + private sealed class ThinkRetryOllamaClient(bool succeedOnRetry, bool semanticSplitFirst = false) : IOllamaClient { public List ThinkOverrides { get; } = []; public List Temperatures { get; } = []; @@ -623,7 +642,9 @@ public sealed class PromptAndRuntimeTests ThinkOverrides.Add(thinkOverride); Temperatures.Add(temperatureOverride); PlanningMessages.Add(messages); - string content = ThinkOverrides.Count == 2 && succeedOnRetry + string content = ThinkOverrides.Count == 1 && semanticSplitFirst + ? """{"tasks":[{"description":"edit","dependencies":[],"budget_class":"4K","optimistic_tokens":10,"most_likely_tokens":20,"pessimistic_tokens":30,"requires_external_effect":true,"required_tools":["file_edit"]},{"description":"verify and correct","dependencies":[0],"budget_class":"4K","optimistic_tokens":10,"most_likely_tokens":20,"pessimistic_tokens":30,"requires_external_effect":true,"required_tools":["file_edit","process_run"]}]}""" + : ThinkOverrides.Count == 2 && succeedOnRetry ? """ Here is the requested plan. -- cgit v1.2.3