VaMP's Code-Centric Visualization or Putting Patches in Their Place

May 5th, 2022 by Diana Coman

Scratching that itch of a more useful visualization for a given set of patches, I've added to VaMP a view aimed at the more important people in a patch's life: its readers! This new view focuses on how a code evolves when/if various paths of patches are pursued (or not!), showing the different possible states of the whole codebase and how they are linked through patches. As a result, this new, code-centric rather than patch-centric view helps the reader to place a patch in its context, easily gain some idea as to its role as part of a whole and know at a glance where to start looking for the relevant code context beyond what the patch itself includes. By contrast, the legacy view focused on how the patches were related to one another without much regard for the code as a whole at any given time1. In short, the legacy view is what the *machine* needs in order to link patches correctly, while the new view is what supports *human* comprehension of a codebase as a whole, carving quite explicitly and one small step at a time, a place for people to contribute and collaborate, supported by machine automation but not replaced by it in any way.

Another way of describing the new visualization is that it puts patches where they belong: as links between two states of the codebase and as such merely potential paths (to take or not) or even alternatives to pick from, but certainly never some sort of central focus or all-important parts on their own. Yes, this view pushes the reader's needs and the codebase *as a whole* to the forefront at all times, while relegating changes to the code aka patches (and their writers) to a more humble and supporting role, to better reflect reality: any changes to code are at all times merely proposals and should be seen as such, not as impositions2 and all patches effectively compete with one another for readers' acceptance but no patch is ever all that important on its own or even in a group, whether that group is shaped like a tree or not. A patch becomes important (or not) through its readers, not its writer(s) and informed readers need more context than the very narrow and limited part that may be included in a patch.

As illustration, have a look at how the same set of patches is shown below, first in the legacy view (patches as nodes of the graph and arcs unlabeled) and then in the new, code-centric view (codebase states as nodes of the graph and arcs labeled according to the patch that they represent):

Above: legacy, patch-centric view focused on dependency relationships between patches: patches are nodes and arcs don't have any meaningful labels.

Above: new, code-centric view focused on the evolution of the whole codebase through the application of different patches: states of the codebase are nodes and patches are the arcs.

While most of the trees flow quite neatly even in the first image above due to VaMP's strict guarantees, there are at least two spots in there that look dubious at least: the first is the crossing dependencies between client_cooldown.shortcut, client_cooldown.patch, client_unite.patch and client_cleanup.patch; the second is the keksum tree that seems split into two components that are not linked in any way. If you check however these same parts in the second image above, aka the code-centric visualization, you'll get some better idea of what happens in fact to the code in each case. The two client patches (client_cooldown.shortcut and the client_cooldown.patch) perform a merge of two different branches of code, while the two "components" of the keccak tree represent in fact alternative paths of the same release!

None of the above is clear in the legacy view though, simply because there is no way to even show in there anything about the prerequisites of a root patch (implicitly assumed to be an empty directory, as if that even made much sense) or the results of a leaf patch (implicitly assumed to be fully defined by the sequence of patches leading to that leaf but pushing the burden of any actual checks on to the user). Since VaMP is by design loudly explicit, rather than quietly implicit, it can also show in the code-centric view both pre-requisites and results of any patch, whether root, leaf or anything in between. As a further gain, the user of the visualization can even add helpful labels to each state of the codebase so that the whole becomes more readable indeed and the names of the patch files don't end up as the sole providers of anything human-readable in the whole graph. The states of the codebase are uniquely identified and listed conveniently in a text file that the user can change as they see fit, with VaMP helpfully preserving any given labels between subsequent runs and otherwise providing some default labels where the user doesn't care or hasn't yet provided anything else.

Moving further, I plan to expand on this to further support reading, comprehension and discussion of patches in their full context. This code-centric view has been already very useful for me to get an initial overview of any set of patches but I see it otherwise as only a first and still very limited step towards a more human-friendly way of interacting with patches so that the incentives for balanced collaboration are correctly aligned for all levels of writers, readers and publishers of patches, too.

  1. This was due first of all to the limitations of the older "V" which had no notion of a whole codebase as such, nor ways to provide any guarantees as to the output of a patch. VaMP does not suffer from such limitations, so it can and does push for a more useful visualization, too. 

  2. Whether under the guise of "security updates", "must-have upgrades" or something else, the currently widespread practice really is built precisely on the idea of forceful imposition of any code changes. Not that there's anything inherently wrong with enjoying imposition either, if that's what you like. Just call it by its name instead of pretending it's something else, don't expect everyone else to have the same enjoyments as you and, even more importantly, don't try to discourage the young from even finding out that there are valid alternatives to the path you are on yourself. 

Comments feed: RSS 2.0

2 Responses to “VaMP's Code-Centric Visualization or Putting Patches in Their Place”

  1. Jacob Welsh says:

    Would the reading of the diagrams for the merge case, crisscrossed arrows or otherwise, be that the input for either client_cleanup.patch or client_unite.patch is the output of either client_cooldown.shortcut or client_cooldown.patch? And thus that the lines terminated by each of the latter two are expected to produce the same result? (Seems clear enough but just checking.)

    Those "shortcut" type patches might get quite lengthy if indeed they're accumulating the whole of the opposite line since whatever common ancestor into one patch, adapted to mesh with the changes of the shortcut's own line. I've usually found merges to be a pain, especially on the reading side since git so lubricated the write side; this approach at least brings such pains into full view.

    What might be the prerequisites of a root patch? Here I thought that having no prerequisites was the very definition of being a root.

  2. Diana Coman says:

    the input for either client_cleanup.patch or client_unite.patch is the output of either client_cooldown.shortcut or client_cooldown.patch? And thus that the lines terminated by each of the latter two are expected to produce the same result? (Seems clear enough but just checking.)

    The point there is that VaMP comes with mathematical guarantees regarding the full codebase before and after applying a patch, not expectations, no matter how reasonable they might be (e.g. files not changed by this patch are expected to therefore be the same!). It seems like a deceptively small shift of perspective but it has quite deep implications, so it's worth getting your head around it, not to mention it makes for clearer discussions of versioning. To pick just one implication that is of interest here: it enables your signature on a patch to come closer to a signing of the *meaning* of some changes (rather than the specific form that they might take in one patch or in another) since you are effectively signing a full output state of the codebase.

    To answer your question as stated though: yes, the latter two (client_cooldown.shortcut and client_cooldown.patch) apply on different states of the codebase but produce as a result the exact same state, guaranteed by full check each and every time, not just as a "reasonable" or what-have-you expectation of controlled environment + process. The patches themselves will be different, of course, but if you previously signed off on the resulting full codebase from one of them, then someone trusting your signature but having as start point a different codebase can simply produce the patch that gets their mess to the clean-state you signed on and rely on that, quite sanely.

    The above is also the reason why lengthy shortcut patches are not an issue at all. Yes, they can end up lengthy but that's not an issue at all since their "shortcut" comes from shortening the process (apply ONE patch, not 100, since now there IS guaranteed equivalence of output). The most obvious practical application of this is deployment really: at development time, there might be 100 patches until some release but that doesn't mean that all end users absolutely have to keep now at all times all those patches because otherwise-they-are-not-cool-enough or something; the maintainer/publisher/someone-reasonable makes a single "shortcut" patch which cumulates the changes while preserving, with guarantees, the intended end result and provides that as an alternative.

    What might be the prerequisites of a root patch? Here I thought that having no prerequisites was the very definition of being a root.

    I guess you have a point in that I should call them first patches rather than root patches, as there are no such things as root patches, nor were there ever - only loose terminology that is best cleaned up, too, indeed. Old V's "root" patches still had prerequisites, it's only that they were implicit (an empty directory!) and moreover, expected/trusted to be as expected rather than explicit and checked/enforced. To the point though, the prerequisite of a first patch is the state of the codebase that it requires as input ie that it starts with/from. What that is exactly is entirely up to the signer of that first patch and it literally can be anything at all until the user picks something specific and once that got picked, VaMP will duly enforce it to be exactly that and nothing else.

Leave a Reply