August 18, 2026
In the beginning, programmers wrote machine code one opcode at a time. They had to worry about memory addresses, the physical location of the code in the memory, memory mapped peripherals, low-level timing, etc. Then, compilers made it practical to write in higher-level languages and translate those programs into machine code while the compiler worried about all of the details. Pretty soon most programmers weren't writing (or even reading) machine code at all. As programming moved up the stack, processor designers designed their instruction sets to be the target for compilers rather than to be written by humans.
Now we don't even write the high-level code because LLMs write it for us. So the obvious question is - If we were to design a programming language specifically as a target for LLM code generation rather than for humans to write, what would it look like?
My answer is: probably not radically different from a good modern programming language. We might make it more regular, explicit, and strict. We might remove redundant ways to express the same idea and make verification easier. But TypeScript, Python, Rust, and other existing languages are already perfectly workable targets for coding agents. LLMs translate English requests into them well, and compilers and tests give the agents useful feedback when they get something wrong.
In practice, when I build a web product today, writing the code is the easy part. (In fact, it has always been the easy part but LLMs have made it fast.) The friction is everything around it: creating cloud resources, setting up user accounts, configuring domains, moving secrets between providers, preparing test environments, deploying releases, setting up analytics, and figuring out what users are trying to tell me after the product ships.
The missing tool in the LLM era is a way to turn intent into a living product. The programming environment currently ends at the edge of the repository, while the product does not.
The first idea is to include more of the product in infrastructure as code. Terraform can already manage cloud resources and domains. There is no conceptual reason that the same model could not cover an authentication provider, a payment provider, environment variables, analytics projects, and most other external services. Database schemas have their own declarative tools. Deployment workflows can be expressed as configuration. Much of the structure of a product can be represented as desired state:
this database should exist with this schema
this service should run in this region
this domain should point at this deployment
this application should accept Google sign-in
this environment should have access to this secret
While Terraform is good at expressing desired state and reconciling the difference between desired and actual state, not everything in a sofware product is state. Behavior remains better expressed as code. If a new account should receive a trial, create an organization, send a welcome email, and schedule an onboarding reminder, an LLM can already translate that English into ordinary application code. We do not need every workflow to become a Terraform resource.
There are other pieces of a software product that are neither state nor behavior. “Find out why exports started failing yesterday” is an investigation. “Compare these complaints with the latest deployment” is analysis. “Rotate this credential” is an operation. “Show me whether the fix improved the error rate” is observation over time.
Trying to force all of that into one giant configuration language would make the language worse, and would not make the product easier to operate.
The idea is a single workspace where a person or an agent can build and operate the whole software product. The official name for these sorts of tools will probably end up being Integrated Product Environment, but in my mind I've been calling it an Everything Multiplexer because its most obvious interface would be a large flexible surface full of panels. Like tmux but for everything.
Those panels could show the code, terminals, Git history, provider websites, the product itself, databases, deployments, analytics, logs, user feedback, and conversations with coding agents such as Claude Code, Codex, and Grok Build. Some would be purpose-built interfaces. Others would be existing websites opened with the user's normal login. The agent could inspect and control the panels, rearrange the workspace for the current task, and delegate code changes to coding agents working inside the relevant repositories.
An IPE should be able to inspect and, where appropriate, operate:
An IDE is organized around source files and a repository. It integrates the tools needed to turn those files into a program: editor, compiler, debugger, test runner, and version control, which was a major improvement over interacting with each tool separately. The IDE did not replace the compiler or debugger, it put them in one environment, gave them shared context, and let a developer move among them without continually reconstructing what was happening.
An IPE is the same kind of expansion again. The object at its center is the running software product, not just its code. Most of the systems listed above already have good specialized tools, and the IPE should not replace Git, Terraform, AWS, Planet Scale, Vercel, a database console, or an observability provider. It should make them jointly visible and jointly operable.
The layout would be dynamic. A developer could ask for the production error cluster beside the deployment that introduced it, open the relevant file and Git diff underneath, and keep a coding-agent conversation next to a live reproduction of the product. During a migration, the database might take most of the screen. During sign-in debugging, the authentication provider and the product UI might sit side by side. During product triage, user feedback and observability might be the main workspace.
The panels are the visible part, but the IPE cannot just be a large collection of browser tabs. It also has to understand how the things in those panels relate, which brings us to...
Consider a user report saying that exports hang. While investigating, the agent might assemble something like this:
feedback item 52
was submitted by user 71
during session 941
against production deployment dpl_123
running Git commit abc789
producing trace 4182
after database migration 0063
Those facts may live in six different systems.
At this point it's tempting to reach for a graph database and start chucking data in. We could define types and edges, start linking them up and attaching metadata, make nice queries, etc. It would be fun, and at the beginning of my career I would have done that. The real world is too detailed and dynamic for this to work though, plus most of these relationships only really matter in the context of a particular task. That temporary model does not need to be stored forever. The source systems are still the source of truth, and the agent can build a fresh model the next time it needs one.
It is, however, necessary to store something about these relationships. I think there are three different kinds of memory involved.
Working memory is the temporary model assembled by an agent for whatever is happening now. The export example above belongs here.
Working memory can disappear when the task is finished. It is generated by and belongs in the agent thread that did the task. It can contain evidence, hypotheses, plans, failed approaches, intermediate results, and whatever temporary structure helps the agent think. Most of that does not need to become permanent product knowledge.
Episodic memory should be a journal of things that happened in the product. A user feedback item should be sumarized and saved as an episode in the product journal. If we do a new vercel deployment, that should be summarized and recorded as an episode. The difficult question is what counts as one episode. A user report can start an investigation, which starts a coding-agent thread, which produces a patch and a test run, which leads to a deployment, which changes a metric. If we put all of that into one growing entry, the entry may never have a clear ending. If we ask an LLM to decide which story each new event belongs to, it will make arbitrary grouping decisions that are difficult to understand or correct.
Instead, episodes should have mechanical boundaries. Many product events already come in naturally bounded units: one feedback item, one coding-agent thread, one test run, one deployment, one migration, one refund, or one alert. Each of those can produce its own English summary with a source ID and a timestamp. An episode can be revised while the underlying object changes—a deployment can move from building to ready, for example—but it should not grow merely because some different event appears related.
Other sources are continuous and too fine-grained to record one at a time. A single log line, page view, or sign-in is rarely an interesting episode. Those sources can be summarized in deterministic time buckets: errors over five minutes, sign-ins over an hour, or usage over a day. The raw events remain in the systems that own them.
The result is a mostly chronological journal of summaries of events that have occured in the product. They can be disconnected and incoherent, but they should be specific and should contain links to the underlying data.
The IPE should maintain an English description of the product: which repositories and services make it up, where it runs, which providers it uses, how authentication and billing work, where important data lives, and how the pieces fit together. It would be something like AGENTS.md, but for the whole product instead of one codebase.
This description should also contain the parts of the product's history that still matter. It might say that export failures reported in one feedback episode led to an investigation in a coding-agent episode and a fix in a deployment episode; that the fix later caused a latency increase visible in a telemetry episode; and that a second change resolved it. It can refer back to the individual episode IDs, deployments, threads, and other source records when the details matter.
This is where aggregation and interpretation belong. Product memory tells stories. It can identify recurring failure modes, preserve the reasons behind architectural decisions, summarize user and business trends, and retain lessons that should affect future work.
The product memory should be generated and kept up to date by the IPE from the episode journal, the live product, and its existing description. It can be revised when important events arrive and on a regular asynchronous cadence. It should rewrite and compress itself rather than growing forever, allowing obsolete details to fall away while retaining the history that explains the current product.
Trying to define an HCL-like language for the entire product asks too much of the language. The product is too broad, and the kinds of facts worth remembering will keep changing.
English is less precise than an X-as-code format, but it is much more flexible and expressive. It also leaves out details and makes tacit assumptions. In this case that is generally a feature: the result is far more compact, and omitted details can usually be recovered from the source system if they are ever needed.
These memories exist to be used by agents. The top agent and the coding agents it delegates to should be able to read the product description, consult the episode records, and work within the current task memory. Exactly when that context is loaded or queried is an implementation detail.
At the center of the IPE is the top agent. It operates through the IPE across repositories, providers, deployments, telemetry, user feedback, and the product itself. It preserves the larger context and delegates bounded code changes to coding agents working inside individual tasks or repositories. Its conversation becomes the common input surface for the product: the programmer describes what they want, and the top agent works out which systems and tools are involved.
The top agent is a role, not a new agent implementation. Most of the time it could be an instance of Claude Code, Codex, Grok Build, or whatever general-purpose agent is best at the moment, given access to the IPE's memory and tools. The coding agents it delegates to could be other instances of those same systems. The IPE supplies the product-wide context, integrations, interface, and authority boundaries; it does not need to reimplement the agents' reasoning and coding machinery.
The best integrations will use APIs, which provide structured data and reliable actions. When a provider exposes useful functionality only through its website, the IPE can open the site with the user's existing session and operate it through a constrained browser adapter. Unsupported sites can still appear as human-operated panels. Integration does not have to be all or nothing.
Observability, analytics, and user feedback are all evidence about the same running product. The agent should be able to connect a complaint to a session, an error, and a deployment; investigate it; delegate a fix; and then observe whether the fix helped. These connections should retain references to the original evidence rather than replacing it with a detached summary.
Giving one agent access to the whole product also makes the IPE potentially the most privileged application on the developer's machine. The answer cannot be to tell the model to be careful. The execution layer must enforce permissions, distinguish read-only investigation from consequential actions, and request narrow approval when necessary. Agents should normally manipulate secret references and bindings rather than plaintext values, allowing a credential broker to move a secret without placing it in model context.
The idea is broad enough to become vague, so I think several constraints are important.
The product is the primary object. Repositories, machines, providers, and dashboards are resources attached to a product. They should not each become a separate universe in the UI.
One action path for humans and agents. When practical, an agent action should use the same underlying operation as the visible control. A hidden automation path that behaves differently from the UI will eventually produce results nobody can explain.
Observe, act, then observe again. External state changes. An agent should act against a current observation and inspect the result before continuing. This matters especially for browser control and production operations.
Preserve provenance. Every important fact should carry its source and observation time. “The deployment is healthy” means little if it came from a stale dashboard snapshot.
Enforce authority outside the model. Prompts can explain policy, but the action layer must enforce it. Models propose actions; trusted code decides whether those actions are allowed.
Partial integration should still be useful. The system should not require a complete model of the product before it can show a provider panel or connect one feedback item to one deployment. It can assemble useful context one relationship at a time.
The IDE did not succeed by replacing compilers, shells, and debuggers with one enormous implementation. It succeeded by making them parts of one coherent environment organized around the program being developed. The IPE should do the same thing one level up. Existing tools, including coding agents, keep their specialized responsibilities. The environment connects them around the product, gives a human and an agent shared context, and provides a controlled way to move from observation to action.
The visible result may look like an everything multiplexer: many surfaces on one large canvas, rearranged for the work at hand. Underneath, though, the important pieces are the product's memory and the capability system that lets the agent act safely.
We started by asking what a programming language would look like in the LLM era. Rather than designing a new programming language though, we should expand the definition of programming itself. LLMs now make it feasable to automate and integrate the whole product - the code, infrastructure, providers, data, users, and continuing operation.
So basically keep the languages but expand what we can automate.