"Ultimately we do have two colors."
If you consider this a color, we don't have two colors. We have millions.
As I said, it is not that such a concept would be useless; I use it all the time. But it's not "color" any more.
"Do you not read that as "two colors"?"
That is in response to a completely different question about the cheapness of goroutines, not coloration.
Coloration is much stronger than you seem to be understanding. It is not "oh, this function requires that parameter and that one does not, so they must be different colors". It is that you can't correctly run an async function from within a synchronous one and vice versa in the languages in which these are considered completely different things (which does not include Go). While conversion is ultimately possible, it is expensive and high-consquence. If you have a hard time seeing that because, say, a sync function can "simply" bring up an async execution engine for its async calls and an async function can "simply" spawn an entire OS thread to run sync code and collect the results through a promise, consider nesting such an approach arbitrarily deeply as a deep call stack alternates between async and sync calls, which is 100% realistic. It becomes more clear how high-consequence this is if you remember that such programming language constructs must be able to compose essentially arbitrarily deeply.
Context parameters can be satisfied by no-context functions simply by passing "context.Background()", and the result is low-consequence. The code does not come apart at the seams, the code using contexts simply ends up not having any data come from the background (empty) context and the background context will never generate a cancellation event, which is apparently what the caller wants since they are asking for that more-or-less explicitly. If that is not what the caller wants, "ctx, cancelF := context.WithTimout(context.Background(), time.Second)" is also trivially available, correct, and low-consequence. If you define coloration down to this level, you completely lose the entire point of the original essay, which is the high-effort, high-consequence effects of bridging sync and async code. Defining colors down to "This function takes a file pointer, thus it is 'file pointer colored'" is profoundly missing the entire point. The idea of function color is useful precisely because it is limited to only certain high-cost conversions, not spread so thin as to cover literally every function parameter. Contexts aren't very special; it is literally easier come up with one if you don't have one ("context.Background()") than it is to come up with an integer, in which you must actually pick one. It isn't anywhere near special enough to justify being called a "color" any more than a file pointer, or a database connection, or any of hundreds of other resource types, most of which impose more constraints on the code than contexts.