When Tests and Colors Both Become Protocols

Jaeyeol Lee

Hatched by Jaeyeol Lee

May 09, 2026

10 min read

61%

0

What do a test suite and a color space have in common?

At first glance, almost nothing. One lives in software engineering, where assertions turn bugs into failing builds. The other lives in visual systems, where color spaces turn light into numbers. But both are really about the same problem: how do you make meaning travel across boundaries without collapsing into ambiguity?

That question matters because most systems fail not when they lack power, but when they lack a shared language. A test may be perfectly expressive inside one framework and useless outside it. A color may look vibrant on one device and wrong on another because its meaning was never formalized in a way that could survive translation. In both cases, the deeper issue is not representation alone. It is interoperability with intent.

The surprising lesson is this: the best abstractions are not merely containers for data or style. They are protocols for agreement. They tell different parts of a system what can be trusted, what can be transformed, and what must remain stable. Once you see that, testing and color spaces stop being separate topics. They become two versions of the same design challenge.


The real divide is not between tools, but between meanings

In software testing, there is a familiar split between styles that feel native to a framework and styles that emphasize a formal result format. One approach centers on a test block and a suite, where assertions happen inside a shared structure. Another turns outcomes into a text protocol or structured report that can move between tools. A third exposes a single assertion object, a kind of local authority that records test points one by one.

These are not just different APIs. They encode different assumptions about where meaning lives.

The first style says: meaning is inside the test harness, in the direct relationship between your code and the framework that runs it. The second says: meaning is in the output, in a format stable enough to survive beyond the original environment. The third says: meaning is in a contract of assertions, a carefully controlled interface that makes each test point explicit.

Color spaces make the same distinction in a more visual way. A color is not just a pixel value. It can be understood as device dependent, like the raw signal on a screen, or device independent, like a formal representation that can be interpreted consistently across devices. If you want reliable communication, you need a space where meaning is defined well enough to travel. If you want local flexibility, you may choose a space optimized for a particular device or pipeline.

A good protocol does not merely store information. It decides what counts as the same thing after transformation.

That is the hidden commonality. In both domains, the essential design choice is not between “more features” and “fewer features.” It is between local expressiveness and portable meaning.


Why protocols always feel a little less magical

There is a reason protocol boundaries can feel opinionated. They are. They have to be. A protocol only works if it limits what participants are allowed to assume. That restraint can feel restrictive compared with direct access to objects, functions, or raw visual values. Yet that limitation is exactly what makes interoperability possible.

Think of it like music notation. A pianist can improvise more freely than a score can describe, but a score can travel across centuries, instruments, and performers. The score is less intimate, less alive in the moment, and more boring on paper. But it is also what allows a symphony to survive beyond a single room. A formal test format works the same way. It may not capture every nuance of the original runtime, but it lets one tool generate results and another consume them later.

Color spaces embody the same tradeoff. A device-native representation can preserve immediacy and exploit hardware characteristics, but it often makes the color hard to interpret elsewhere. A standardized color space sacrifices some directness so that the notion of “this red” can survive conversion, rendering, and reuse.

This is why formal systems sometimes frustrate people. They seem to insert a layer between intention and expression. But that layer is not bureaucracy. It is translation discipline. It prevents a local convenience from becoming a global mistake.

A test framework built around a formal protocol says: I will not confuse the act of checking with the way checks are reported. A color system built around a formal space says: I will not confuse the appearance of color in one context with its identity across contexts. Both are protecting you from a category error: assuming that what is easiest to see locally is therefore what is truest globally.


The most important abstraction is not what it hides, but what it makes portable

A shallow view of abstraction says it hides complexity. That is true, but incomplete. The better view is that abstraction selects which parts of complexity deserve to become movable.

This is why some test styles revolve around suite structure and nested blocks, while others center on a single assertion object or a standardized text output. They are not merely syntactic preferences. They are different answers to the question: what should remain stable when the rest of the system changes?

In a spec style test, the structure of the suite helps humans read intent directly. The nested blocks are part of the narrative. In a protocol style, the output is the important artifact. That output can be archived, streamed, compared, or consumed by other tools. In an assertion object style, the unit of portability is the test point itself, a sharply defined interaction that can be counted and reported.

Color spaces make the same move. The exact wavelength hitting a sensor is not always the useful abstraction. The useful abstraction is the one that can be encoded, converted, and reused while preserving the aspects humans care about. A color space is not just a mathematical convenience. It is a decision about which aspects of visual experience should remain stable under change.

Here is a useful mental model: abstractions are filters for invariance.

They answer questions like:

  1. What should stay the same across tools?
  2. What should be allowed to vary?
  3. Where should loss be tolerated, and where should it not?

A test protocol says the outcome should be readable by any compliant consumer, even if the internal execution differs. A color space says the perceived relationship among colors should remain intelligible, even if the output device differs. In both cases, the abstraction is valuable not because it removes detail, but because it preserves the right detail across contexts.

The best abstractions are not the ones that simplify everything. They are the ones that make the right thing survive the journey.


A framework for choosing between local truth and transferable truth

Once you recognize the protocol problem, a practical framework emerges. Many engineering decisions can be understood as choices between local truth and transferable truth.

Local truth is what is most immediate inside a specific environment. It is usually faster, more expressive, and easier to work with in the moment. Transferable truth is what can be understood outside that environment without reinterpreting the whole system from scratch. It is often more constrained, but also more durable.

This framework helps explain why different testing styles exist and why none of them is universally best.

  • If your priority is fast, readable development inside one codebase, a suite and block based style can be ideal. It embeds meaning in a familiar structure.
  • If your priority is toolchain interoperability, archival, or reporting across environments, a formal output protocol becomes more valuable.
  • If your priority is precise, localized assertions with a uniform interface, a single assertion object can reduce ambiguity and encourage consistent checks.

The same logic applies to color management.

  • If you are optimizing for a particular device pipeline, a native representation may be enough.
  • If you need consistency across editors, browsers, displays, and export formats, a formal color space becomes essential.
  • If you want to preserve meaningful relationships among colors while allowing transformations, you need a space designed for that purpose, not just one that “looks right” in a narrow context.

The mistake people often make is to ask which abstraction is “better” in the abstract. The better question is: better at preserving what, across which boundary?

That question is more rigorous, and more useful. It reveals that the point of a protocol is not to be universal in the naive sense. It is to make a specific kind of agreement robust enough to outlive the immediate setting.


The hidden design lesson: boundaries are where intelligence lives

Most systems are not defined by their components. They are defined by their boundaries.

At the boundary, you decide what must be named, what must be serialized, what must be comparable, and what must be ignored. Boundaries are where assumptions become visible. They also determine whether a system can grow without losing coherence.

This is why both software testing and color systems reward formalization. A direct object structure shared between test and harness can be powerful, but it is also opinionated. It assumes a particular shape of collaboration. A textual protocol is more boring, but that boredom is the source of its durability. Likewise, a device-independent color representation can seem less immediate than raw display values, but it is what allows colors to survive translation across a messy real world of hardware and software.

If you are designing systems, this leads to a useful principle:

Do not formalize everything. Formalize the boundaries that need to outlive the implementation.

That principle explains why some APIs should be intimate and some should be strict. It explains why some test results should live as structured objects, while others should become portable text. It explains why some color operations should stay local to a device pipeline, while others should pass through a stable color space.

In practice, this means treating boundaries as first class design objects. Ask what happens when the thing you built must be consumed by a future version of your own system, or by a different system entirely. Ask what meaning must remain legible after conversion. Ask what should be written down, because if it is not written down, it will be reinvented badly later.


Key Takeaways

  1. Separate local convenience from portable meaning. Decide which parts of your system are for immediate use and which parts must survive translation.

  2. Treat protocols as agreements about invariance. A good protocol preserves the same important meaning across different tools, devices, or time.

  3. Choose abstractions based on boundaries, not elegance. Ask what must remain stable when the context changes, then formalize only that.

  4. Use formalism to reduce ambiguity, not creativity. Constraints at the boundary make the interior more flexible, because everyone knows what is guaranteed.

  5. When a system feels “opinionated,” check whether it is protecting portability. What looks restrictive may actually be the cost of interoperability.


The deeper lesson: meaning must be engineered to travel

The temptation in both code and design is to believe that the best representation is the one closest to raw experience. But raw experience does not scale across systems. It is too context bound. A test embedded in a framework and a color embedded in a device can be vivid in place and misleading elsewhere.

What endures is not immediacy. What endures is a disciplined translation of intent.

That is why test protocols matter, and why color spaces matter. They are not niche technical details. They are examples of a broader intellectual truth: every robust system needs a way to say, “this should mean the same thing later, somewhere else, for someone else.” That sentence is the foundation of software reliability, visual consistency, and, more broadly, any mature technology stack.

So the next time you choose between a direct object, a text protocol, a device-native representation, or a standardized space, do not ask only which is simpler. Ask which one lets meaning travel without distorting into noise. That is where the real engineering begins.

And once you start seeing systems through that lens, you realize the most important thing a framework can give you is not convenience. It is the chance to make agreement explicit.

Sources

← Back to Library

Hatch New Ideas with Glasp AI 🐣

Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)

Start Hatching 🐣