Thank you for your replies
Sorry, by "endogenous" I meant they're entirely derivative (i.e., task cancellation, not user events). A good reporter of a task would report when the task is cancelled or throws an error in addition to reporting positive progress. They're not intended to report the error value or other kinds of cancellation, but to reflect the processing state as incomplete but terminated in relevant flavors.
Progress reporting is a notification scheme for the underlying processing status; it can neither be divorced nor conflated. Progress reporting is not responsible for task cancellation, but the progress state reported has to reflect a cancelled or erroneous state to be helpful in diagnosing fault models in task processing and to avoid misleading clients. (And yes, the progress reported is only as good as the reporter is diligent, which can be hard when handling cancellation or errors.)
I agree that reporting this can be a real pain, and I would understand if some developers decide not to do so in some situations. (Better integration with task API's would be nice and might be called for.) But though most code doesn't follow best practice, we still try to have one where we can.
But for those developers who do want to report state accurately I'd like to give them a common approach and means to do so, to make it easier for them. Building it into the API is also the only way they can inter-operate with such reporting from other tasks written by other developers and especially libraries. (Concurrency, too, takes a village...)
It's not actionable in the sense of fixing that process (and we're expressly not trying to integrate process handling). But it will help with diagnosing and working around a broken process. It's essential to distinguish a hung process (where one task is ignoring another's cancellation) from one that is blocked (on some resource), or to avoid retrying a process that's throwing errors, because those merit 3 different responses to incompleteness.
Progress that hums along normally is not really important; clients are most concerned about progress that stalls. To me the difficulty of concurrency boils over precisely in lacking insight into incomplete states. People become concurrency-averse if they get themselves in situations they don't understand. And it could save a lot in support costs if such situations can be logged; it's precisely the non-local aggregators that should be able to do this.
Would such states be easier to stomach if a (reference) enum with associated values is not required?
If the state must be an Int, a unixy solution would be to nominate some magic negative "count" values as terminal cancellation, error (and possibly blocked, et al), with API to interpret the state as such for backwards compatibility if the states represented might change.
Or a similar Swift solution with better backwards and forwards compatibility would wrap the Int in a single (binary-compatible?) struct with appropriate semantic guarantees. (One could also imagine decomposing it, e.g., a Int split into completed and total values, but those are other concerns.)
Thanks for your patience. I think users will appreciate it.