Skip to content

Commit 2be757f

Browse files
authored
Merge pull request #81 from managedcode/codex/epic-12-embedded-runtime
Implement embedded runtime epic
2 parents eb898fd + dc97cb8 commit 2be757f

28 files changed

+1836
-89
lines changed

AGENTS.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,11 @@ For this app:
152152
- `DotPilot/DotPilot.csproj` keeps `GenerateDocumentationFile=true` with `CS1591` suppressed so `IDE0005` stays enforceable in CI across all target frameworks without inventing command-line-only build flags
153153
- architecture work must keep a vertical-slice shape: each feature owns its contracts, orchestration, and tests behind clear boundaries instead of growing a shared horizontal service layer
154154
- keep the Uno app project presentation-only; domain, runtime host, orchestration, integrations, and persistence code must live in separate class-library projects so UI composition does not mix with feature implementation
155+
- when the user asks to implement an epic, the delivery branch and PR must cover all of that epic's direct child issues that belong to the requested scope, not just one child issue with a partial close-out
156+
- epic implementation PRs must include automated tests for every direct child issue they claim to cover, plus the broader runtime and UI regressions required by the touched flows
157+
- do not claim an epic is implemented unless every direct child issue in the requested scope is both realized in code and covered by automated tests; partial coverage is not an acceptable close-out
155158
- structure both `DotPilot.Tests` and `DotPilot.UITests` by vertical slice and explicit harness boundaries; do not keep test files in one flat project-root pile
156-
- the first embedded Orleans host cut must use `UseLocalhostClustering` plus in-memory grain storage and reminders; do not introduce remote clustering or external durable stores until a later backlog item explicitly requires them
159+
- the first embedded Orleans runtime cut must use `UseLocalhostClustering` together with in-memory Orleans grain storage and in-memory reminders; do not introduce remote clustering or external durable stores until a later backlog item explicitly requires them, and keep durable resume/replay outside Orleans storage until the cluster topology is intentionally upgraded
157160
- GitHub is the backlog, not the product: use issues and PRs only to drive task scope and traceability, and never copy GitHub issue text, labels, workflow language, or tracker metadata into production code, runtime snapshots, or user-facing UI
158161
- never claim an epic is complete until its current GitHub scope is verified against the live issue graph; check which issues are real children versus issues that merely depend on the epic or belong to a different parent epic
159162
- Desktop responsiveness is a product requirement: avoid synchronous probe, filesystem, network, or process work on UI-facing construction and navigation paths so the app stays fast and immediately reactive

Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<PackageVersion Include="coverlet.collector" Version="8.0.0" />
1313
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
1414
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
15+
<PackageVersion Include="Microsoft.Agents.AI.Workflows" Version="1.0.0-rc4" />
1516
<PackageVersion Include="Microsoft.Orleans.Core.Abstractions" Version="10.0.1" />
1617
<PackageVersion Include="Microsoft.Orleans.Persistence.Memory" Version="10.0.1" />
1718
<PackageVersion Include="Microsoft.Orleans.Reminders" Version="10.0.1" />

DotPilot.Core/Features/RuntimeCommunication/RuntimeCommunicationProblemCode.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ public enum RuntimeCommunicationProblemCode
1010
RuntimeHostUnavailable,
1111
OrchestrationUnavailable,
1212
PolicyRejected,
13+
SessionArchiveMissing,
14+
ResumeCheckpointMissing,
15+
SessionArchiveCorrupted,
1316
}

DotPilot.Core/Features/RuntimeCommunication/RuntimeCommunicationProblems.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ public static class RuntimeCommunicationProblems
1616
private const string RuntimeHostUnavailableDetail = "The embedded runtime host is unavailable for the requested operation.";
1717
private const string OrchestrationUnavailableDetail = "The orchestration runtime is unavailable for the requested operation.";
1818
private const string PolicyRejectedFormat = "The requested action was rejected by policy: {0}.";
19+
private const string SessionArchiveMissingFormat = "No persisted runtime session archive exists for session {0}.";
20+
private const string ResumeCheckpointMissingFormat = "Session {0} does not have a checkpoint that can be resumed.";
21+
private const string SessionArchiveCorruptedFormat = "Session {0} has corrupted persisted runtime state.";
1922

2023
public static Problem InvalidPrompt()
2124
{
@@ -86,6 +89,33 @@ public static Problem PolicyRejected(string policyName)
8689
HttpStatusCode.Forbidden);
8790
}
8891

92+
public static Problem SessionArchiveMissing(SessionId sessionId)
93+
{
94+
return CreateProblem(
95+
RuntimeCommunicationProblemCode.SessionArchiveMissing,
96+
SessionArchiveMissingFormat,
97+
sessionId.ToString(),
98+
HttpStatusCode.NotFound);
99+
}
100+
101+
public static Problem ResumeCheckpointMissing(SessionId sessionId)
102+
{
103+
return CreateProblem(
104+
RuntimeCommunicationProblemCode.ResumeCheckpointMissing,
105+
ResumeCheckpointMissingFormat,
106+
sessionId.ToString(),
107+
HttpStatusCode.Conflict);
108+
}
109+
110+
public static Problem SessionArchiveCorrupted(SessionId sessionId)
111+
{
112+
return CreateProblem(
113+
RuntimeCommunicationProblemCode.SessionArchiveCorrupted,
114+
SessionArchiveCorruptedFormat,
115+
sessionId.ToString(),
116+
HttpStatusCode.InternalServerError);
117+
}
118+
89119
private static Problem CreateProblem(
90120
RuntimeCommunicationProblemCode code,
91121
string detailFormat,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
namespace DotPilot.Core.Features.RuntimeFoundation;
2+
3+
public sealed record EmbeddedRuntimeTrafficTransitionDescriptor(
4+
string Source,
5+
string Target,
6+
IReadOnlyList<string> SourceMethods,
7+
IReadOnlyList<string> TargetMethods,
8+
bool IsReentrant);
9+
10+
public sealed record EmbeddedRuntimeTrafficPolicySnapshot(
11+
int IssueNumber,
12+
string IssueLabel,
13+
string Summary,
14+
string MermaidDiagram,
15+
IReadOnlyList<EmbeddedRuntimeTrafficTransitionDescriptor> AllowedTransitions);
16+
17+
public sealed record EmbeddedRuntimeTrafficProbe(
18+
Type SourceGrainType,
19+
string SourceMethod,
20+
Type TargetGrainType,
21+
string TargetMethod);
22+
23+
public sealed record EmbeddedRuntimeTrafficDecision(
24+
bool IsAllowed,
25+
string MermaidDiagram);
26+
27+
public interface IEmbeddedRuntimeTrafficPolicyCatalog
28+
{
29+
EmbeddedRuntimeTrafficPolicySnapshot GetSnapshot();
30+
31+
EmbeddedRuntimeTrafficDecision Evaluate(EmbeddedRuntimeTrafficProbe probe);
32+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
using DotPilot.Core.Features.ControlPlaneDomain;
12
using ManagedCode.Communication;
23

34
namespace DotPilot.Core.Features.RuntimeFoundation;
45

56
public interface IAgentRuntimeClient
67
{
78
ValueTask<Result<AgentTurnResult>> ExecuteAsync(AgentTurnRequest request, CancellationToken cancellationToken);
9+
10+
ValueTask<Result<AgentTurnResult>> ResumeAsync(AgentTurnResumeRequest request, CancellationToken cancellationToken);
11+
12+
ValueTask<Result<RuntimeSessionArchive>> GetSessionArchiveAsync(SessionId sessionId, CancellationToken cancellationToken);
813
}

DotPilot.Core/Features/RuntimeFoundation/RuntimeFoundationIssues.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ public static class RuntimeFoundationIssues
99
public const int CommunicationContracts = 23;
1010
public const int EmbeddedOrleansHost = 24;
1111
public const int AgentFrameworkRuntime = 25;
12+
public const int GrainTrafficPolicy = 26;
13+
public const int SessionPersistence = 27;
1214

1315
public static string FormatIssueLabel(int issueNumber) => string.Concat(IssuePrefix, issueNumber);
1416
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using DotPilot.Core.Features.ControlPlaneDomain;
2+
3+
namespace DotPilot.Core.Features.RuntimeFoundation;
4+
5+
public sealed record AgentTurnResumeRequest(
6+
SessionId SessionId,
7+
ApprovalState ApprovalState,
8+
string Summary);
9+
10+
public sealed record RuntimeSessionReplayEntry(
11+
string Kind,
12+
string Summary,
13+
SessionPhase Phase,
14+
ApprovalState ApprovalState,
15+
DateTimeOffset RecordedAt);
16+
17+
public sealed record RuntimeSessionArchive(
18+
SessionId SessionId,
19+
string WorkflowSessionId,
20+
SessionPhase Phase,
21+
ApprovalState ApprovalState,
22+
DateTimeOffset UpdatedAt,
23+
string? CheckpointId,
24+
IReadOnlyList<RuntimeSessionReplayEntry> Replay,
25+
IReadOnlyList<ArtifactDescriptor> Artifacts);

DotPilot.Runtime.Host/Features/RuntimeFoundation/EmbeddedRuntimeHostBuilderExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public static IHostBuilder UseDotPilotEmbeddedRuntime(
2020
services.AddSingleton(resolvedOptions);
2121
services.AddSingleton<EmbeddedRuntimeHostCatalog>();
2222
services.AddSingleton<IEmbeddedRuntimeHostCatalog>(serviceProvider => serviceProvider.GetRequiredService<EmbeddedRuntimeHostCatalog>());
23+
services.AddSingleton<IEmbeddedRuntimeTrafficPolicyCatalog, EmbeddedRuntimeTrafficPolicyCatalog>();
2324
services.AddHostedService<EmbeddedRuntimeHostLifecycleService>();
2425
});
2526

DotPilot.Runtime.Host/Features/RuntimeFoundation/EmbeddedRuntimeHostNames.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ internal static class EmbeddedRuntimeHostNames
77
public const int DefaultSiloPort = 11_111;
88
public const int DefaultGatewayPort = 30_000;
99
public const string GrainStorageProviderName = "runtime-foundation-memory";
10+
public const string ClientSourceName = "Client";
11+
public const string ClientSourceMethodName = "Invoke";
1012
public const string SessionStateName = "session";
1113
public const string WorkspaceStateName = "workspace";
1214
public const string FleetStateName = "fleet";

0 commit comments

Comments
 (0)