I'm not sure we can or will make a distinction on this level.

Allow me to explain task completion and failure by example:

Say we have a build task, this is a task which checks out sources, builds them and uploads results to S3 as build artifacts. The build task have the following possible outcomes:
 * `completed` **successfully**, meaning the binaries where built and uploaded to S3.
 * `completed` **unsuccessfully**, meaning sources didn't build, but an error log of what went wrong is uploaded to S3.
 * `failed` because worker didn't respond before `taken_until` expired, and this occured for all retries allowed.
 * `failed` because the task deadline was reached before a worker completed the task.
 * `failed` because somebody canceled the task.

So if the build fails that doesn't mean that the task failed. A task only fails if the worker misbehaves. This is the worker process crashed, or the machine the worker process lived on crashed, or the worker machine suddenly lost network connectivity. Or the spot instance went away. This is for errors that cannot be reported. Failures should only happen by timeout.

A task where the build fails due to syntax errors in the code, or something shouldn't be left to timeout... If the worker can report that something went wrong, then the task completed it didn't fail. It may not have completed successfully, though, but this is task specific and the queue does not deal with retries at this level.