From 608682fd66994e69e331b73604ad75e0b1bf92bf Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 26 Jul 2026 17:46:23 +0200 Subject: [PATCH] fix: avoid colliding with the next task when the gap is too small The min-spacing fallback spread from the lower bound and could hand a batch item the exact position of the following task, which the api's conflict repair then scatters. Address pr-swarm finding. --- frontend/src/helpers/calculateItemPosition.ts | 4 ++-- frontend/src/helpers/calculateTaskPosition.test.ts | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/frontend/src/helpers/calculateItemPosition.ts b/frontend/src/helpers/calculateItemPosition.ts index 6d1f7f828..94b497848 100644 --- a/frontend/src/helpers/calculateItemPosition.ts +++ b/frontend/src/helpers/calculateItemPosition.ts @@ -60,9 +60,9 @@ export const calculateItemPositions = ( const spacing = (positionAfter - base) / (count + 1) // The gap is too small to subdivide without the values colliding after the JSON - // round-trip. Give up on staying inside it and only keep the batch itself ordered. + // round-trip. Spread past positionAfter on purpose so the batch doesn't collide with it. if (spacing < MIN_POSITION_SPACING) { - return spread(base, MIN_POSITION_SPACING) + return spread(Math.max(base, positionAfter), MIN_POSITION_SPACING) } return spread(base, spacing) diff --git a/frontend/src/helpers/calculateTaskPosition.test.ts b/frontend/src/helpers/calculateTaskPosition.test.ts index 1afea1a03..b7be702b1 100644 --- a/frontend/src/helpers/calculateTaskPosition.test.ts +++ b/frontend/src/helpers/calculateTaskPosition.test.ts @@ -82,6 +82,13 @@ describe('calculateItemPositions', () => { expect(positions).toEqual([...positions].sort((a, b) => a - b)) }) + it('should not collide with the following item when there is nothing before and the gap is too small', () => { + const positions = calculateItemPositions(7, null, 0.05) + expect(positions).not.toContain(0.05) + expect(new Set(positions).size).toBe(7) + expect(positions).toEqual([...positions].sort((a, b) => a - b)) + }) + it('should keep distinct positions after a JSON round-trip', () => { const positions = calculateItemPositions(10, null, 1) const deserialized = JSON.parse(JSON.stringify(positions))