SelfImprovement/SandboxBuildService.cscsharp

Documentation

Lilith self-improvement (Version 7+)

Lilith can extend herself only by creating tools in three categories:

| Category | Location | Examples | |----------|----------|----------| | Core | Agent-Core | Memory, time (rare; system-level) | | Addon | Agent-Addons | Weather, C# projects, apps | | Self | Lilith | Workspace files, self-improvement |

Layout

  • ShippedSource/ — copy of src/Version7 next to the built app (MSBuild CopyShippedSource)
  • {workspace}/output/self-improvement/live — current editable source
  • {workspace}/output/self-improvement/sandbox — clone for edits and builds
  • {workspace}/output/self-improvement/backups/{timestamp} — backups before promote

Tools

1. self_improve_get_source_layout 2. self_improve_generate_tool 3. self_improve_backup_live 4. self_improve_create_sandbox 5. self_improve_build_sandbox 6. self_improve_verify_sandbox_tool 7. self_improve_promote_sandbox — copies sandbox → live, builds, restarts

Set GENESIS_REPO_ROOT to the repo root when developing from source instead of ShippedSource.

using System;using System.Diagnostics;using System.IO;using System.Text;namespace Lilith.Agent.SelfImprovement;internal static class SandboxBuildService{    public static string BuildSandboxConsole(SelfImprovementPaths paths, TimeSpan? timeout = null)    {        string project = paths.LilithConsoleProject;        if (!File.Exists(project))            throw new FileNotFoundException($"Sandbox console project not found: {project}");        return BuildProject(project, paths.Sandbox, timeout);    }    public static string BuildProject(string projectPath, string workingDirectory, TimeSpan? timeout = null) =>        RunDotnet($"build \"{projectPath}\" -c Release", workingDirectory, timeout ?? TimeSpan.FromMinutes(5));    public static string RunDesignTests(SelfImprovementPaths paths, string? filter, TimeSpan? timeout = null)    {        string project = paths.DesignTestsProject;        if (!File.Exists(project))            return "Skipped: DesignTests project not present in sandbox.";        string filterArg = string.IsNullOrWhiteSpace(filter) ? "" : $" --filter \"{filter}\"";        return RunDotnet($"test \"{project}\" -c Release{filterArg}", paths.Sandbox, timeout ?? TimeSpan.FromMinutes(5));    }    private static string RunDotnet(string arguments, string workingDirectory, TimeSpan timeout)    {        var psi = new ProcessStartInfo        {            FileName = "dotnet",            Arguments = arguments,            WorkingDirectory = workingDirectory,            RedirectStandardOutput = true,            RedirectStandardError = true,            UseShellExecute = false,            CreateNoWindow = true,        };        using var process = Process.Start(psi)            ?? throw new InvalidOperationException("Failed to start dotnet process.");        var stdout = new StringBuilder();        var stderr = new StringBuilder();        process.OutputDataReceived += (_, e) => { if (e.Data is not null) stdout.AppendLine(e.Data); };        process.ErrorDataReceived += (_, e) => { if (e.Data is not null) stderr.AppendLine(e.Data); };        process.BeginOutputReadLine();        process.BeginErrorReadLine();        if (!process.WaitForExit((int)timeout.TotalMilliseconds))        {            try { process.Kill(entireProcessTree: true); } catch { /* best effort */ }            throw new TimeoutException($"dotnet timed out after {timeout.TotalSeconds:F0}s.");        }        process.WaitForExit();        var sb = new StringBuilder();        sb.AppendLine($"Exit code: {process.ExitCode}");        if (stdout.Length > 0)            sb.AppendLine(stdout.ToString().TrimEnd());        if (stderr.Length > 0)            sb.AppendLine(stderr.ToString().TrimEnd());        return sb.ToString().TrimEnd();    }}