Dependencies can have lower computed urgency than the tasks they block.
Taskwarrior supports marking tasks as dependent on other tasks, as described on this 'Best Practices' page.
For example:
task ID modify depends:OTHER_ID
The blocking nature of the relationship between the two tasks this is meant to represent means that the dependency should always have a higher urgency than the dependent task.
Taskwarrior does add a weight to the urgency of a task, as shown by the alterations to urgency when the depends relationship is added in the following example:
$ task pro:test add "dependent"
Created task 75.
$ task pro:test add "dependency"
Created task 76.
$ task pro:test
ID Age Project Description Urg
75 10s test dependent 1
76 7s test dependency 1
$ task 75 mod depends:76
Modifying task 75 'dependent'.
Modified 1 task.
$ task pro:test
ID Age Deps Project Description Urg
76 22s test dependency 9
75 25s 76 test dependent -4
So as expected, marking one task as dependent on another will modify urgencies such that the dependency has higher urgency than the dependent.
However, if other factors boost the urgency of the dependent, this change is not reflected in the dependency's urgency. For example, if we raise the priority of the dependent and give it a deadline:
$ task mod 75 priority:H
Modifying task 75 'dependent'.
Modified 1 task.
$ task 75 mod due:eod
Modifying task 75 'dependent'.
Modified 1 task.
$ task pro:test
ID Age Deps P Project Due Description Urg
75 15min 76 H test 12h dependent 10.6
76 15min test dependency 9
The urgency of the dependent was boosted, but the dependency's urgency was unchanged. The relative urgencies no longer reflect the blocking relationship between the two tasks. A user who has carefully input the dependency and trusts the system to track these relative urgencies is misled by what is reported and must do additional mental work to identify and account for the system's error.
Does Taskwarrior support alternatives to the default urgency calculation? It seems that the default urgency calculation is a weighted-sum based on various attributes, as described here.
Modifying, e.g., urgency.blocked.coefficient and urgency.blocking.coefficient could decrease the chances that a blocking relationship would be misrepresented, but a mathematical model of urgency more complex than weighted-sum would be necessary to guarantee that the blocking relationship are reflected by urgency without overwhelming the other factors.
Mathematically, there are ways of combining the depends relationship data with the existing urgency coefficients -- excluding the 'blocked' & 'blocking' coefficients -- to compute urgencies that have a similar character to the existing urgency calculation while always respecting blocking relationships.
Perhaps something from linear algebra, for example, can elegantly keep the general character of the current model, while incorporating the guarantee that dependencies will have higher urgency than their dependents. Or, a more discrete procedure can certainly do it, replacing the 'blocked' and 'blocking' coefficients while guaranteeing that urgency will properly order dependencies.
If Taskwarrior does have a means of supporting alternative urgency calculation methods, then maybe someday I'll get to this. I'm reminded of the need for it every time I use the depends feature.
Note: The following hack is a partial work-around for handling this issue:
urgency.blocked.coefficient = -256.0 # blocked by other tasks
urgency.user.tag.next.coefficient = 128.0 # +next tag
urgency.due.coefficient = 64.0 # overdue or near due date
urgency.uda.priority.H.coefficient = 32.0 # high Priority
urgency.uda.priority.M.coefficient = 16.0 # medium Priority
urgency.uda.priority.L.coefficient = 8.0 # low Priority
urgency.active.coefficient = 4.0 # already started tasks
urgency.age.coefficient = 2.0 # coefficient for age
urgency.blocking.coefficient = 1.0 # blocking other tasks
urgency.scheduled.coefficient = 0.0 # scheduled tasks
urgency.annotations.coefficient = 0.0 # has annotations
urgency.tags.coefficient = 0.0 # has tags
urgency.project.coefficient = 0.0 # assigned to any project
urgency.user.project.My Project.coefficient = 0.0 # assigned to project:"My Project"
urgency.waiting.coefficient = 0.0 # waiting task
Contrary to taskwarrior recommendations, this intentionally uses coefficients which dominate all terms of lower priority.
This at least guarantees that prerequisites appear before blocked tasks. The main issue is that in computing the urgency of a given prerequisite, the relative urgency of the tasks it blocks are not factored in. Suppose task A blocks task B, for example, and task B is due soon. The high urgency of task B's pending due date should be reflected in the urgency of task A. Though, no configuration changes that I am aware of can incorporate that.
The main issue is that in computing the urgency of a given prerequisite, the relative urgency of the tasks it blocks are not factored in. Suppose task A blocks task B, for example, and task B is due soon. The high urgency of task B's pending due date should be reflected in the urgency of task A. Though, no configuration changes that I am aware of can incorporate that.
Have you looked at urgency.inherit as outlined in man taskrc?
$ man taskrc ... urgency.inherit=0 Not actually a coefficient. When enabled, blocking tasks inherit the highest urgency value found in the tasks they block. This is done recursively. It is recommended to set urgency.blocking.coefficient and urgency.blocked.coefficient to 0.0 in order for this setting to be the most useful.
Following its advice and setting both urgency.blocking.coefficient and urgency.blocked.coefficient to 0 means you will effectively not see this, because the dependency will simply inherit its most urgent child's value. You can still leave those two udas set to what you want, but I think the original contributor of the feature does not, so you might have to play around with it to get good values.
I for one am not sure I agree with the original contributor's reasoning, as without the blocking coefficient, there is no way of representing the fact that a long and involved project of high priority tasks has some urgency in and of itself that may not be accounted for by inheritance alone.
Say I have long-term project X and then project Y that is less important but that has a near due date. Now in general we should not set due dates such that they have wiggle room - if there is flexibility in a due date, it doesn't exist; due dates are for when something must be done, scheduling is for the other kind. Regardless of this, it may still very much be the case that if push comes to shove, I would want to prioritize project X, regardless of the due date of the task in project Y. I can think of many things in my life like this, sometimes external due dates just aren't that important relative to working on something more open-ended that you need to work on. (Other times, of course, they are).
Now, I could just modify the projects themselves to have a UDA - but this seems fairly ad-hoc. It's far better IMO if I can automate that; if I wanted to question everything for myself each time I wouldn't use a task tracker with modifiable heuristics, I would use some notebooks divided by project (and this for me is more intentional than the alternative - other people hate the idea of distancing themselves from the decisions).
Equally, I feel someone may disagree with my own reasoning, and prefer to do it ad-hoc - a project with lots of planned tasks may not convey any importance to them, rather just a lot of work. For me, if I were to have projects like that that I didn't necessarily intend to carry out, I would relegate them to a 'brainstorming' context or similar. I want my tasklisk for commitments and intentions.
I think the default settings should be:
urgency.inherit=1
urgency.blocking.coefficient=0
urgency.blocked.coefficient=0
This would reflect the usual meaning of "blocking" and is more user-friendly.
I am inclined to agree at this point in time.
Re. my earlier rambles, I think realistically all that stuff has to instead be managed with tags, projects, and other UDAs to modify urgency (though it is no small difficulty arriving at sane numbers). Given it wasn't relevant to the initial question, it was superfluous and unhelpful - I apologize very belatedly.
I guess the part that should be modified is only this one:
https://github.com/GothenburgBitFactory/taskwarrior/blob/e9c6c6c846c932eea9fb46894779e10ef1f30a52/src/Context.cpp#L156-L165
Here is a pull-request for this part