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. --- src/Agent.Windows/Recovery/TransactionalFileEditor.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/Agent.Windows/Recovery') diff --git a/src/Agent.Windows/Recovery/TransactionalFileEditor.cs b/src/Agent.Windows/Recovery/TransactionalFileEditor.cs index 25c949d..ff4ac5a 100644 --- a/src/Agent.Windows/Recovery/TransactionalFileEditor.cs +++ b/src/Agent.Windows/Recovery/TransactionalFileEditor.cs @@ -11,7 +11,7 @@ public sealed class TransactionalFileEditor(TaskResourceJournal journal, string public FileEditTransaction Replace(string path, ReadOnlySpan content, string? expectedSha256 = null) { - string canonical = CanonicalPath.Resolve(path, requireExisting: false); + string canonical = ResolvedPath.Resolve(path, requireExisting: false); bool existed = File.Exists(canonical); byte[]? original = existed ? File.ReadAllBytes(canonical) : null; string originalHash = original is null ? string.Empty : Convert.ToHexString(SHA256.HashData(original)); @@ -45,7 +45,7 @@ public sealed class TransactionalFileEditor(TaskResourceJournal journal, string public FileDeleteTransaction Delete(string path, string? expectedSha256 = null) { - string canonical = CanonicalPath.Resolve(path); + string canonical = ResolvedPath.Resolve(path); byte[] original = File.ReadAllBytes(canonical); string originalHash = Convert.ToHexString(SHA256.HashData(original)); if (expectedSha256 is not null && !originalHash.Equals(NormalizeHash(expectedSha256), StringComparison.Ordinal)) @@ -71,7 +71,7 @@ public sealed class TransactionalFileEditor(TaskResourceJournal journal, string public DirectoryMkdirTransaction Mkdir(string path) { - string canonical = CanonicalPath.Resolve(path, requireExisting: false); + string canonical = ResolvedPath.Resolve(path, requireExisting: false); bool existed = Directory.Exists(canonical); if (existed) throw new InvalidOperationException($"Directory already exists: '{canonical}'."); if (File.Exists(canonical)) throw new InvalidOperationException($"A file exists at the target path: '{canonical}'."); @@ -83,7 +83,7 @@ public sealed class TransactionalFileEditor(TaskResourceJournal journal, string public DirectoryRmdirTransaction Rmdir(string path) { - string canonical = CanonicalPath.Resolve(path); + string canonical = ResolvedPath.Resolve(path); if (!Directory.Exists(canonical)) throw new DirectoryNotFoundException($"Directory does not exist: '{canonical}'."); if (Directory.EnumerateFileSystemEntries(canonical, "*", SearchOption.TopDirectoryOnly).Any()) throw new ToolValidationException("Directory is not empty. Remove contents first before removing the directory."); @@ -95,8 +95,8 @@ public sealed class TransactionalFileEditor(TaskResourceJournal journal, string public FileRenameTransaction Rename(string sourcePath, string destinationPath) { - string source = CanonicalPath.Resolve(sourcePath); - string destination = CanonicalPath.Resolve(destinationPath, requireExisting: false); + string source = ResolvedPath.Resolve(sourcePath); + string destination = ResolvedPath.Resolve(destinationPath, requireExisting: false); if (!File.Exists(source)) throw new FileNotFoundException($"Source file does not exist: '{source}'."); if (File.Exists(destination)) throw new ToolValidationException($"Destination already exists: '{destination}'. Rename overwrite is not allowed."); if (!source.StartsWith(System.IO.Path.GetPathRoot(source)!, StringComparison.OrdinalIgnoreCase) || -- cgit v1.2.3