Delegation & Outsourcing
Markets and factories are two examples of widespread recursive patterns in software. There's another prominent pattern that I've mentioned a number of times across various posts, and that is the handshake agreement.
The concept behind the handshake agreement is simple - a system (or primitive) needs to trust the output of another system in order to keep one or more of its promises. Handshake agreements are pivotal to the transformation of code into digital experiences, to reading local data from a device, fetching data from the cloud, and navigating the web. Handshake agreements are essential in enabling the division of labour and the formation of increasingly complex plans. The violation of these agreements is the number one cause of issues. When developers investigate issues, one of the first things they are doing is verifying that their understanding of applicable agreements is correct.
The examples of handshake agreements that I just raised are in the context of digital factories and digital products but there are also handshake agreements at other layers of software delivery.
We can see this more clearly by inspecting the division of labour for modern software applications more closely. It is common practice to divide contemporary software development professionals into more specialised buckets. A modern software project may be comprised of developers that specialise in mobile, front-end web, backend, data analysis - we could go on, and we could also be more granular than this.
Armed with the knowledge that developers have specialties that map to the roles distinct computer systems play in the delivery of digital products, it should be straightforward to imagine that not only are there handshake agreements between those systems, there are also mirroring handshake agreements between those developers at the project layer. The mobile developer writes a plan that has the mobile app expect a particular response, and the backend developer writes a plan that has an API deliver that particular response.
Project-level handshake agreements may involve multiple parties or businesses. For example, a software project's staff may include embedded consultants, contractors, and perhaps even entire companies in the case of co-development arrangements.
Delegation and outsourcing are not restricted to human beings. Software programs are a performance of automated work, which may or may not have intermediary checkpoints where humans make decisions. As I wrote in infrastructure, the preparation of new versions is a relatively common automated process today.
The automation of the writing of code was until quite recently, extremely limited. In a manner that mirrors the transformation of code into digital experiences, traditional code generation takes files that conform to a structured format and produce new files from them based on a number of parameters. The utility of these template files is relatively independent from The Plan for software (I.e. these templates may have utility across various distinct projects), it is often much more closely aligned with concerns of particular technology choices in digital supply chains e.g. coding languages and frameworks, and ensuring that the catalogue of technical primitives that application developers manage conform to a set of expected behaviours.
By contrast, the use of large language models as a means of production in software development tends to be aligned with either the concerns of digital products (by describing its output) or by concerns of The Plan in terms of experiential primitives such as pages and widgets rather than technical primitives. At least on paper, this seems to open the door for software developers to produce systems beyond their traditional buckets, or for an entirely new class of software developers without a traditional background to produce working software.
This way of working is to some extent an act of outsourcing. You can ask a person (or a machine) to write code for you, and there is an implied handshake agreement that they will do so in precisely the manner in which you asked. One of the key differences between language models for code generation and the more traditional means of automated code generation is that the language model cannot be trusted to produce the same code in response to the same request, which in a way makes the process more human-shaped in a manner that has traditionally been characterised as negative. When the same input is guaranteed to produce the same output through some process, we call it deterministic. For decades, determinism in computer systems has been the bedrock of technological evolution, and it is what software developers rely on to relate cause and effect in complex systems.
Just as I wrote in the post about mining for new primitives, how language mode workflows will ultimately evolve out remains quite difficult to predict.
What I can say since my remarks in the post about mining for primitives is that I have seen some models perform more adeptly than I had anticipated at breaking large unknown problems into a sequence of smaller known problems, circumventing at least to some extent the concerns that I had about ownership and access rights as a barrier. On the flip side, recently market and societal forces seem to be having a substantial and negative influence on their performance, effectively forcing smaller increments of work and more iterations. Add this to the pile of hints that software delivery is not merely technical.
This serves as a reminder that when we delegate or outsource our problems we are not reducing scope or complexity, only our direct engagement.
Delegation has a strong connection to commoditisation and the hiring problem. Many software projects are significantly differentiated in their digital factories and project infrastructure even if they are not significantly differentiated in their digital product. There may be a market of developers who are familiar with some of a project's primitives but the market of developers who are familiar with concerns such as a particular project's software plan and how it has evolved over time, and why technology choices were made is much smaller, and in many circumstances it has a size of zero.
When developers leave a project (or a project leaves them as can happen in outsourcing) there is more often than not a permanent and irrecoverable destruction of value. This is because the production of code involves a broad integration of concerns (see the potential about code for more) that are unlikely to be resolved in an identical manner between any two developers with identical knowledge and experience, let alone two developers with significant differences in knowledge and experience. In practice, this has a very significant influence on the formation of future versions of software plans. This can be the case even when there is a “house style”, and strong adherence to solving particular problems of code in a standardised way.
This is not to say that new developers cannot add value. It is more the case that digital systems are complex and multifaceted, difficult to concretely observe and dynamic, as are the foundations that they are built on, and knowledge of their histories expedites delivery in significant if not tangible ways.
Until next time.