flood(): a zero-duration event silently blocks gap flooding between its neighbours

Abierto
#201 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 10 días

@TimeToBuildBob ya está trabajando en esto.

Desde el 7/11/2026.

  • #202 de @TimeToBuildBob — abierto

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
55/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
python
Área
backend

Línea de trabajo

Start with aw_transform/flood.py and trace how events are normalized before the adjacent-pair flooding loop. Add a regression test alongside the flood tests for the provided zero-duration marker example, and check the behavior with the default pulsetime. Done means the gap is handled consistently and the result is idempotent; the issue leaves whether zero-duration events should be preserved as an open semantic question.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Found this while fuzzing flood() with zero-duration events (after the #165 changes, but I rebuilt the pre-#165 code and it's the same there, so not a regression).

tl;dr: a zero-duration event between two events blocks the gap between those events from being flooded, even though the zero-duration event itself never appears in the output.

Repro on master, default pulsetime=5:

from datetime import datetime, timedelta, timezone
from aw_core.models import Event
from aw_transform.flood import flood

now = datetime(2026, 1, 1, tzinfo=timezone.utc)
def ev(off, dur, tag):
    return Event(timestamp=now + timedelta(seconds=off),
                 duration=timedelta(seconds=dur), data={"t": tag})

# Two events with a 2s gap (16 -> 18), flooded normally:
flood([ev(9, 1, "b"), ev(9, 7, "c"), ev(18, 1, "a")])
# -> 9s+8s ("c"), 17s+2s ("a")    gap filled at midpoint, 10s total

# Same events, plus a zero-duration event in between:
flood([ev(9, 1, "b"), ev(9, 7, "c"), ev(12, 0, "marker"), ev(18, 1, "a")])
# -> 9s+7s ("c"), 18s+1s ("a")     gap NOT filled, 8s total

The marker never shows up in the output (the normalization pass filters out zero-duration events), but it still ate both pairwise slots: the zip(events[:-1], events[1:]) loop only looks at adjacent pairs, so the (c, a) pair is never considered for flooding.

Side effect: flood() isn't idempotent at default pulsetime — a second pass fills the gap, because by then the zero-duration event is gone:

p1 = flood([ev(9, 1, "b"), ev(9, 7, "c"), ev(12, 0, "marker"), ev(18, 1, "a")])
p2 = flood(p1)
# p1: 9s+7s ("c"), 18s+1s ("a")
# p2: 9s+8s ("c"), 17s+2s ("a")   <- different

test_flood_idempotent doesn't catch this since it runs with pulsetime=0.

Possible fix direction: drop/skip duration<=0 events before the pairwise pass. But that's really a semantic question (should zero-duration events be preserved in the output at all? aw-server-rust's flood filters them out entirely), so filing this as an issue first rather than jumping to a PR.

Duplicate check: looked through the flood-related issues/PRs (#73, #105, #135, #139, #142-#146, #165) and none seem to cover this.

Lenguaje dominante
Python
Estrellas
65
Forks
74
Merge medio
6 d 10 h
PR fusionados (30 d)
9

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de ActivityWatch/aw-core

Todos los issues de ActivityWatch/aw-core

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.