Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions extensions/taskplane/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4225,14 +4225,23 @@ export async function executeOrchBatch(
"info",
);

// TP-040: Emit merge_success event
// TP-040: Emit merge_success event.
//
// `waveIndex` is the segment-round index (0-based), and the supervisor
// formatter renders the (N/M) counter using `waveIndex + 1` for N.
// For unit consistency we therefore pair it with the segment-level
// `batchState.totalWaves` (segment-expanded round count), not
// `taskLevelWaveCount` (pre-expansion). Using the task-level count as
// the denominator while the numerator counts segment rounds produced
// `(4/3)`, `(5/3)`, `(6/3)` style overflow once segments expanded —
// see issue #562.
emitEvent(
stateRoot,
{
...buildEngineEventBase("merge_success", batchState.batchId, waveIdx, batchState.phase),
laneCount: mergedCount,
durationMs: mergeResult.totalDurationMs,
totalWaves: taskLevelWaveCount,
totalWaves: batchState.totalWaves,
},
onEngineEvent,
);
Expand Down
27 changes: 27 additions & 0 deletions extensions/tests/supervisor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,33 @@ describe("5.x — formatEventNotification", () => {
expect(text).toContain("42");
});

it("5.8a: merge_success counter denominator stays >= numerator across segment-expanded waves (regression for #562)", () => {
// Polyrepo scenario from #562: 3 task-level waves expand into 6
// segment-level merge rounds. The engine emits one merge_success
// per segment round, with waveIndex = segment-round index (0..5)
// and totalWaves = segment-expanded round count (6). The formatter
// must therefore render (1/6) through (6/6), never (4/3), (5/3),
// or (6/3) as observed in the bug report.
const denominator = 6;
for (let waveIdx = 0; waveIdx < denominator; waveIdx++) {
const event = {
timestamp: "t",
type: "merge_success" as any,
batchId: "b",
waveIndex: waveIdx,
totalWaves: denominator,
};
const text = formatEventNotification(event, "supervised");
const expectedNumerator = waveIdx + 1;
expect(text).toContain(`(${expectedNumerator}/${denominator})`);
// Belt-and-suspenders: the bug surfaced as a numerator that
// exceeded the denominator. Pin that the rendered text never
// contains `(N/3)` for any N — the only valid denominator in
// the segment-expanded case is the segment count.
expect(text).not.toMatch(/\(\d+\/3\)/);
}
});

it("5.9: formats merge_failed differently for autonomous vs interactive", () => {
const event = {
timestamp: "t",
Expand Down