feat(worker): build/test the merge preview, not just the post-merge merge

preview_merge could only see file-overlap cleanliness via git merge-tree, never
whether the result compiles -- the two costliest findings of the 2026-08-06 batch
run were both merge-tree-clean but build-broken. When a list has a verify command
configured, a clean preview is now additionally materialized (via a commit-tree +
detached scratch worktree, outside the real repo, always cleaned up) and
built/tested there, without ever touching the real working tree.

preview_merge always attempts a verify run when a command is configured;
preview_merge_set only does when its new runVerify parameter is set (default off),
so a set preview never starts N builds unasked. The post-merge verify gate is
unchanged.
This commit is contained in:
mika kuns
2026-08-10 12:10:17 +02:00
parent 6a2a19cc9e
commit effece3a41
8 changed files with 475 additions and 28 deletions
+6 -1
View File
@@ -88,7 +88,12 @@ public record ForceRemoveResultDto(bool Removed, string? Reason);
public record PlanningMergeConflictStateDto(string PlanningTaskId, string SubtaskId);
public record PendingQuestionDto(string TaskId, string QuestionId, string Question);
public record MergeResultDto(string Status, IReadOnlyList<string> ConflictFiles, string? ErrorMessage);
public record MergePreviewDto(string Status, IReadOnlyList<string> ConflictFiles, int ChangedFileCount);
// Verify* fields are always null on this path today -- the UI's live mergeability indicator never
// requests a verify run (that would mean an unrequested build on every preview poll); they exist so
// MergePreviewDto matches TaskMergeService.MergePreviewResult should a caller opt in later.
public record MergePreviewDto(
string Status, IReadOnlyList<string> ConflictFiles, int ChangedFileCount,
int? VerifyExitCode = null, long? VerifyDurationMs = null, string? VerifyOutputTail = null);
public record MergeTargetsDto(string DefaultBranch, IReadOnlyList<string> LocalBranches);
public record MergeConflictDocumentsDto(string TaskId, IReadOnlyList<ConflictDocumentDto> Files);
public record ConflictDocumentDto(string Path, bool IsBinary, IReadOnlyList<MergeSegmentDto> Segments);