It also works. ;-) With the old algorithm if you has two goals scheduled
and interrupted the earlier one, the tasks for the second goal weren't
moved up. The code to find active and idled tickets was weak and
fragile and not worth fixing since it was also slow. In general, this
new approach handles a lot less data, defers getting ticket details as
long as possible, and gets them for many fewer tickets. In my
playground, I used to query 150 tickets (basically, everything in the
database) and now I query 4-5 tickets (the active set). I expect that
ratio to scale to production. Since querying for ticket details was the
longest part of rescheduling, this is much, much faster than the old
approach.

Before a date was either explicit or not. Values in the database
(actual start/finish dates, previously scheduled values, and explicit
user-supplied values) were all explicit so a test for "better" between
an old schedule table value and a new actual value were not resolved.
Now each source of a date has a different precedence so we have enough
information to resolve a conflict.

The way dates were calculated, we should not have seen conflicts in
new values, only in the explicit ones. This change allows an actual
start to be higher precedence than a previously-scheduled finish.
However, there is still the potential conflict between items of the
same precedence.

Two actual values should never be wrong (we can't finish before we start)

Two scheduled values should never be wrong if we never save bad values

If two user-supplied values are wrong, it's data entry, not

algorithm. We could validate this away but we don't currently even
allow explicit start dates.

For ALAP we update resource limits going from finish to start. The
direction of comparision between a possible date and the resource limit
has a different sense than for ASAP; one uses < and > and the other uses

and <. We can't pass operators to the generic schedule function so we
pass a comparison function.

An ASAP scheduler would try to schedule, which requires scheduling B,
then C, then D. When resource leveling, they will happen one after the
other. The way the existing algorithm bubbles up finish dates, Group A
gets a finish of 3 and that is assigned to the group owner, Mickey.

Now the scheduler tries to schedule E. Checking the resource limits, it
thinks Mickey isn't available until 3 and scheduled E from 3 to 4,
leaving Mickey idle for three units at the start of the schedule.

Since there is no scheduled work in a group, the owner's availability is
not affected by the work done in the children. This change skips
consideration and update resource limits if a task has children.

It has been demonstrated, that by typing a carefully crafted email address on
registration time a malicious user could trigger arbitrary JavaScript code
right after logging-in for the first time.

A successful exploit, like the one demonstrated by security researcher
'ayoub nait lamine', requires the email verification process to be configured
and enabled, but standard registration verification check for email input
(part of acct_mgr.register.RegExpCheck) disabled or configured to
non-default, rather permissive values at the same time.

Please note, that the default recommended configuration for the registration
procedure includes the aforementioned check on registration time, and will
prevent unsane user input in the first place.