refactor(prompts): split the list-handler prompt per session phase
Both merge-helper ConPTY sessions loaded PromptKind.MergeHelper, so the post-handoff session received the phase 0-2 dedupe/enhance instructions and was told to ignore them by its brief alone. Split into MergeHelperTriage (phases 0-2 + handoff) and MergeHelperExecute (phases 3-5), so each session carries only its own phases. Consolidated the generic ask-the-user rule to one place per prompt, scoped Phase 5's summary to what the execute session actually knows, and moved the dedupe/enhance bilanz to the triage handoff. Regression guards assert neither prompt carries the other's phase headings and that the shared-checkout git rule stays in execute.
This commit is contained in:
@@ -905,7 +905,9 @@ public sealed class InteractiveLaunchSpecServiceTests : IDisposable
|
||||
var appendIdx = args.IndexOf("--append-system-prompt-file");
|
||||
var systemPromptPath = args[appendIdx + 1];
|
||||
Assert.Equal(Path.Combine(sessionDir, "system-prompt.md"), systemPromptPath);
|
||||
Assert.Equal(PromptFiles.ReadOrDefault(PromptKind.MergeHelper), File.ReadAllText(systemPromptPath));
|
||||
// The handoff session gets the Execute prompt (phases 3-5), NOT the Triage prompt the
|
||||
// first session ran with — otherwise it carries dedupe/enhance instructions to ignore.
|
||||
Assert.Equal(PromptFiles.ReadOrDefault(PromptKind.MergeHelperExecute), File.ReadAllText(systemPromptPath));
|
||||
|
||||
var kickoff = args[^1];
|
||||
var handoffPath = Path.Combine(sessionDir, "handoff.md");
|
||||
@@ -970,6 +972,40 @@ public sealed class InteractiveLaunchSpecServiceTests : IDisposable
|
||||
Assert.Equal(_worktreeDir, spec.Cwd);
|
||||
}
|
||||
|
||||
// Regression guard for the bug where both merge-helper builders wrote the SAME system prompt,
|
||||
// so the handoff session received the phase 0-2 (dedupe/enhance) instructions and was told to
|
||||
// ignore them by its brief alone. Each session must carry only its own phases.
|
||||
[Fact]
|
||||
public async Task MergeHelperBuilders_WriteDifferentSystemPrompts_EachScopedToItsOwnPhases()
|
||||
{
|
||||
var repo = Path.Combine(_tempDir, "repoPromptSplit");
|
||||
Directory.CreateDirectory(repo);
|
||||
|
||||
var listId = await SeedListAsync(workingDir: repo, name: "Alpha");
|
||||
var handlerTaskId = Guid.NewGuid().ToString();
|
||||
await SeedTaskAsync(handlerTaskId, listId, TaskStatus.Idle, title: "Handler");
|
||||
var survivor = Guid.NewGuid().ToString();
|
||||
await SeedTaskAsync(survivor, listId, TaskStatus.WaitingForReview, title: "Survivor");
|
||||
|
||||
var svc = BuildService();
|
||||
|
||||
var triageSpec = await svc.BuildForMergeHelperAsync(new[] { survivor }, listId, CancellationToken.None);
|
||||
var triageDir = TrackSessionDir(triageSpec);
|
||||
var executeSpec = await svc.BuildForMergeHelperHandoffAsync(handlerTaskId, new[] { survivor }, CancellationToken.None);
|
||||
var executeDir = TrackSessionDir(executeSpec);
|
||||
|
||||
var triagePrompt = File.ReadAllText(Path.Combine(triageDir, "system-prompt.md"));
|
||||
var executePrompt = File.ReadAllText(Path.Combine(executeDir, "system-prompt.md"));
|
||||
|
||||
Assert.NotEqual(triagePrompt, executePrompt);
|
||||
|
||||
Assert.Contains("## Phase 1", triagePrompt);
|
||||
Assert.DoesNotContain("## Phase 4", triagePrompt);
|
||||
|
||||
Assert.Contains("## Phase 4", executePrompt);
|
||||
Assert.DoesNotContain("## Phase 1", executePrompt);
|
||||
}
|
||||
|
||||
// Regression guard for the bug where BuildForMergeHelperHandoffAsync set MCP_TOOL_TIMEOUT to
|
||||
// an older, shorter value (200000) than every other ConPTY spec (930000) after a parallel
|
||||
// merge landed the two changes independently. Every spec this service builds must carry the
|
||||
|
||||
Reference in New Issue
Block a user