Fixing starting times command by command and globally
Maintaining bidirectional relationships
Rather than this check:
    if not self._command.has_task(self):
        raise ValueError(&quot;orphaned task&quot;)

it would be better to mark the task as orphaned by nulling out its command. In other words,
def remove_task(self, task):
    &quot;&quot;&quot;
    Remove the task from this command.  After calling this, 
    the task is orphaned and the reference to the task should be discarded.
    &quot;&quot;&quot;
    task.command = None
    self.tasks.remove(task)

Having command as a simple, &quot;public&quot;, possibly-None member on Task is simpler. At most, I would give this a type hint of Optional[Command] in the constructor.
Types
Don't call date date; that's a commonly used class in a built-in library.
deadline should probably be of type datetime (not date), and duration should be of type timedelta, not int.