SHAPE

SHIFT

Back to homepage

Code Is A Projection

For decades we have behaved as though code is the software.

It is not.

Code is a projection of software.

That sounds abstract until you look at a rewrite. Replace a React application with SwiftUI. Replace a Node service with Rust. Replace a dashboard with a voice flow and an agent tool. Every file can change. Every function can change. The build system, package graph, runtime, and language can all change.

Yet if users can still authenticate, permissions are still enforced, the same state changes happen under the same authority, accessibility still works, latency remains inside the same promise, and every invariant still holds, then the software did not disappear.

The implementation changed.

The object survived.

The object was never the text. It was the set of identities, constraints, effects, proofs, and user-facing promises that the text happened to satisfy.

We have been versioning the shadow and calling it the object.

Projection HubOne Object, Many Projections
Object

Login Flow

A durable object made from identity, state, policy, effects, interface obligations, and runtime proof.

React

components, hooks, routes

SwiftUI

views, bindings, actions

CLI

prompts, flags, terminal output

Agent Tool

capability, dry run, execution receipt

Tests

assertions and browser probes

Docs

human operating model

The same software object can project into code, interfaces, tests, docs, and agent actions. A serious projection owes evidence back to the object.

The Projection Mistake

Today's tools treat source code as the canonical representation.

Everything else is secondary.

Documentation is commentary. Tests are checks. Screenshots are artifacts. Accessibility trees are derived views. Agent plans are external instructions. Runtime telemetry is an after-the-fact observation. The running application is what the code produced this time.

That model is useful. It gives us editors, compilers, linters, diffs, packages, review, and deployment.

But it is too shallow for software that needs to move across languages, runtimes, interfaces, and agents.

Consider the login flow.

Where does it live?

Not in one file. Not in one function. Not even in one repository. It exists across routing, authentication, browser behavior, UI state, storage, analytics, accessibility semantics, operational policy, tests, docs, and user expectation.

The code is one place where that reality becomes visible.

It is not the reality.

Projection SourceStable object
Login Flow
Identity
login.start, login.complete, session.currentUserStable handles let different projections know they are talking about the same thing.
Policy
anonymous users may request auth; authenticated users may create a sessionAuthority is part of the software, not just a branch inside a handler.
Effects
issue token, update session, redirect, write audit eventThe outside world touched by the flow has to remain bounded.
Interface
input method, focus path, error recovery, accessible nameThe user-facing shape is a semantic obligation, not decoration.
Proof
type gate, auth gate, browser probe, accessibility snapshot, receiptA projection is trusted only when it can explain what survived.
A feature is a semantic object spread across many representations. Code is one materialization of that object.

The Shape Beneath The Code

Every representation reveals part of the same underlying object.

A compiler projects it as an executable program. A browser projects it as DOM, pixels, events, layout, focus, and network effects. A screen reader projects it as accessibility nodes and actions. A test suite projects it as executable claims. Git projects it as lines. An agent projects it as a plan with possible actions.

None of those views is the whole software.

They are lenses.

This is why the question "what changed?" is often badly formed. A line changed. A function changed. A layout changed. A dependency changed. But the more important question is which semantic claim changed.

Did identity change? Did authority change? Did observable behavior change? Did a proof go stale? Did the runtime promise narrow or widen? Did a projection lose something the old one could express?

That is the real diff.

Semantic LayersThe Object Is A Stack Of Claims
LayerClaimConstraintProof
01IntentThe user can complete the login flowtask state, recovery path, success conditionworkflow oracle
02AuthorityOnly valid actors can create a sessionroles, capabilities, effects, audit eventpolicy gate
03InterfaceThe flow is operable in this bodyfocus, labels, errors, layout, eventsbrowser probe
04ProgramThe projection executes the contracttypes, imports, state, errors, effectscompiler and test gate
05HistoryThis change descends from the object it claims to preservesource spans, ids, hashes, receipts, lossesprojection receipt
The durable object is not one tree. It is a stack of claims that different projections expose, preserve, weaken, or prove.

A Projection Needs Receipts

If code is a projection, then a rewrite is not trusted just because it compiles.

It needs a receipt.

The receipt says what the projection claims to preserve, what it changed, which proof it produced, and where the target could not express the source without loss.

That is the difference between a translation and a semantic projection.

Translation produces new code.

Projection produces new code plus an account of the object that survived.

Projection ReceiptWhat A Projection Has To Explain
SurfaceClaimRequired proofCurrent evidenceRoute
ProvedIdentityThis is the same featureStable ids and source mapsAction id, route id, state id, public symbolPreserve
RequiredAuthorityThe same actors can do the same thingsPolicy and capability gateRole checks, effect permissions, auth receiptGate
RequiredBehaviorThe workflow still means the same thingState and effect comparisonReads, writes, outputs, failure pathsCompare
RequiredInterfaceThe user can still operate itRuntime interface probeDOM, focus, accessibility, layout, event traceProbe
MissingLossThe target did not hide a semantic downgradeLoss reportMissing type, weaker runtime, unsupported controlReview
A projection is admitted because it can explain which claims survived, which claims still need proof, and which claims were lost.

Why Merge Feels Blind

Traditional merge operates on text because text is treated as the object.

That gives us a useful baseline. Text has exact bytes, lines, spans, hashes, comments, and history. Those should not disappear.

But text is a low-resolution view of meaning.

When two people or agents edit the same feature, they rarely disagree about characters. They disagree about a semantic object from two angles.

One branch changes ownership. Another changes behavior. Another changes a public contract. Another moves layout. Another changes accessibility. Another changes performance. Text merge can notice overlap, but it cannot explain whether the same object still satisfies both branches.

Semantic merge starts from a different question:

is there a valid output projection
that satisfies base + branch A + branch B?

That makes merge less like splicing files and more like admitting a new projection of the software object.

The Useful Intermediate Is The Object
1export function LoginButton({ login, disabled }) {2  return (3    <button disabled={disabled} onClick={login}>4      Sign in5    </button>6  );7}
One projectionThe component syntax is a concrete body for an action, an enabled state, a label, and an event boundary.
The intermediate object is not a prettier AST. It is where source, target, runtime proof, and loss accounting can talk about the same thing.

Constraints Outlive Implementations

Implementations change constantly.

Constraints change slowly.

The user must be able to authenticate. Permissions must be enforced. Keyboard navigation must work. Sensitive data must not leak. Public contracts must not break silently. Payment authority must not widen because a UI was translated. A visual projection must not claim equivalence without runtime evidence.

Those are closer to the identity of the software than the implementation is.

Files are still useful. Text is still useful. Code review is still useful. The mistake is not using files. The mistake is letting the file be the deepest thing the system can name.

A serious semantic layer does not delete code. It puts code in its proper place.

Code becomes a renderer.

One renderer among several.

Code Is One Compilation Target

Once software is understood as a semantic object, code becomes one compilation target.

Not the only one.

The same object might project into React, SwiftUI, HTML, CSS, JavaScript, Rust, a CLI, a voice flow, a Playwright probe, a documentation page, an agent action, an audit timeline, or a temporary workbench for one incident.

That does not mean all projections are equally good. It means the system can ask a sharper question:

what form should this software take here,
and what proof does that form owe?

That is the downstream change.

Software stops being a pile of files that occasionally produce behavior. It becomes a constraint-bearing object that can take different bodies under evidence.

This is why semantic merge, runtime proof, superset languages, plugin contracts, and shapeshifting interfaces are the same project at different scales.

They all require the same move:

stop treating the projection as the source of truth
start naming the object that projections must preserve

Files Still Matter

The lazy version of this argument says files go away.

They probably do not.

HTML did not disappear because the DOM exists. SQL did not disappear because query planners exist. Source code will not disappear because semantic graphs exist.

But source code can stop carrying the whole burden.

It can be a human-writable body. A lowering target. A review surface. A debugging surface. A portable serialization. A way to make the semantic object concrete enough to execute.

The deepest representation becomes the thing that survives translation, merge, refactor, runtime projection, agent delegation, and UI reshaping.

That is the object.

Code is how the object becomes executable in one world.

Software is what remains recognizable when that world changes.