Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependencies can have lower computed urgency than the tasks they block. #3111

Open
mherzl opened this issue May 29, 2023 · 5 comments · May be fixed by #3482
Open

Dependencies can have lower computed urgency than the tasks they block. #3111

mherzl opened this issue May 29, 2023 · 5 comments · May be fixed by #3482

Comments

@mherzl
Copy link

mherzl commented May 29, 2023

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.

@mherzl mherzl changed the title dependencies can have lower urgency than their dependents Dependencies can have lower urgency than their dependents May 29, 2023
@mherzl mherzl changed the title Dependencies can have lower urgency than their dependents Dependencies can have lower urgency than their dependents. May 29, 2023
@mherzl mherzl changed the title Dependencies can have lower urgency than their dependents. Dependencies can have lower urgency than the tasks they block. May 29, 2023
@mherzl mherzl changed the title Dependencies can have lower urgency than the tasks they block. Dependencies can have lower computed urgency than the tasks they block. May 29, 2023
@mherzl
Copy link
Author

mherzl commented Jun 18, 2023

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.

@ashprice
Copy link

ashprice commented Jul 12, 2023

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.

@00sapo
Copy link

00sapo commented Jun 12, 2024

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.

@ashprice
Copy link

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.

@00sapo
Copy link

00sapo commented Jun 14, 2024

I guess the part that should be modified is only this one:

taskwarrior/src/Context.cpp

Lines 156 to 165 in e9c6c6c

"urgency.blocking.coefficient=8.0 # Urgency coefficient for blocking tasks\n"
"urgency.active.coefficient=4.0 # Urgency coefficient for active tasks\n"
"urgency.scheduled.coefficient=5.0 # Urgency coefficient for scheduled tasks\n"
"urgency.age.coefficient=2.0 # Urgency coefficient for age\n"
"urgency.annotations.coefficient=1.0 # Urgency coefficient for annotations\n"
"urgency.tags.coefficient=1.0 # Urgency coefficient for tags\n"
"urgency.project.coefficient=1.0 # Urgency coefficient for projects\n"
"urgency.blocked.coefficient=-5.0 # Urgency coefficient for blocked tasks\n"
"urgency.waiting.coefficient=-3.0 # Urgency coefficient for waiting status\n"
"urgency.inherit=0 # Recursively inherit highest urgency value from blocked tasks\n"

Here is a pull-request for this part

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants