SHAPE

SHIFT

Back to homepage

The Language Stack Becomes A Constraint Stack

Programming languages are usually described as higher level or lower level.

That is true, but it hides the useful part.

Higher-level languages tend to expose more human and domain semantics: screens, actions, state machines, APIs, permissions, components, contracts, policies, workflows.

Lower-level languages expose more execution semantics: memory layout, ABI, registers, flags, cache behavior, interrupts, timing, device I/O, binary shape.

Those are both semantic.

They are just semantic at different altitudes.

The interesting move is to stop treating the language stack as a ladder and start treating it as a stack of constraints.

Constraint StackHigh-Level Meaning, Low-Level Obligations
LayerClaimConstraintProof
01ProductThe system offers a search workflowrole, permission, route, task statecapability map
02InterfaceThe user can operate the workflowview state, focus, layout, accessibilityruntime probe
03ProgramThe action preserves the contracttypes, effects, resources, errorscompiler gate
04MemoryValues move without invalid aliasingownership, lifetime, ABI, layoutnative checker
05MachineThe lowered code has bounded effectsregisters, flags, cycles, I/O, interruptstrace evidence
A program is not only source text. It is a pile of claims: what the product means, what the interface promises, what the program preserves, what the memory model allows, and what the machine actually does.

Abstraction Is Not One Direction

High-level code is semantic because it names intent.

show a checkout flow
only admins can approve refunds
render a keyed list of invoices
call search with a bounded capability
preserve the public User contract

Low-level code is semantic because it names obligations.

write this register
preserve this calling convention
do not clobber this flag
fit inside this timing window
read from this memory-mapped device address

The mistake is thinking that only the top has meaning.

The top has product meaning. The bottom has execution meaning. The system is trustworthy only when it can relate the two.

That is why a semantic interlingua gets strange.

It has to be high enough to hold a product contract and low enough to say what was lost when that contract was lowered into a concrete runtime.

A Stack Of Claims

The useful unit is a claim.

this view is the checkout step
this action mutates the order state
this effect reaches storage
this type shape is the public API
this adapter preserves ownership
this lowered code obeys the ABI
this routine touches the PPU register

A claim by itself is not enough. It needs a constraint and a proof.

Constraint MatrixMeaning Lives At Several Layers
SurfaceClaimRequired proofCurrent evidenceRoute
ProvedProduct intentThe user can approve a refundCapability and policy maprole, route, workflow state, audit eventPreserve contract
RequiredInterfaceThe action remains operableRuntime probeDOM, focus, accessibility, layout, event traceProbe
RequiredProgramThe API shape survivedType or declaration gateexports, schemas, callable signaturesGate
MissingNative runtimeOwnership and ABI constraints holdNative compiler and adapter evidenceborrow facts, layout, calling conventionRequire native proof
MissingMachineThe routine has bounded effectsTrace or emulator evidenceregisters, flags, memory map, cycles, I/OFail closed
The same change can be safe at one layer and unproved at another. Semantic systems should not widen a proof beyond the layer it actually covers.

Frontier Sits In The Middle

This is what makes Frontier feel both high level and low level.

It is not trying to be “above” every language in the normal abstraction sense.

It is trying to be between meanings.

It can hold a domain-level action:

action approveRefund @id("action_refund_approve") {
  input RefundApproval
  mutates Order.refundState
  requires capability finance.refund.approve
  effects audit.write, payment.refund
}

It can also hold lowering obligations:

projection nativeRefundWorker -> rust {
  preserves action_refund_approve
  requires ownership unique RefundApproval
  requires abi stable payment_gateway_v2
  proves type_gate, effect_gate
}
 
projection refundDeviceRoutine -> asm-65816 {
  preserves action_refund_approve
  touches memory $2100..$21FF
  clobbers a, x, p
  requires bank_state, cycle_trace
}

Those two snippets are not the same kind of thing.

But they can be part of the same semantic record because they are both constraints over the same claim.

One Claim, Several Constraint Layers
1action approveRefund @id("action_refund_approve") {2  input RefundApproval3  mutates Order.refundState4  requires capability finance.refund.approve5  effects audit.write, payment.refund6}
Product claimThe action names identity, state mutation, permission, and effects before any target language is chosen.
The same semantic claim can project into high-level product code, native code, and machine code. Each layer adds different obligations.

Lowering Is Constraint Accounting

Lowering is usually described as compilation.

But for semantic systems, lowering is also accounting.

It asks:

which claims survived exactly?
which claims became target-specific constraints?
which claims need runtime proof?
which claims became known losses?
which claims cannot be represented in this target?

If a React component lowers into HTML, CSS, and JavaScript, the system should not only ask whether the output runs.

It should ask whether the keys survived, whether ARIA relationships survived, whether focus behavior survived, whether layout movement is bounded, whether event handlers still point to the same capability, and whether style changes stayed inside their declared cascade region.

If Rust lowers toward WebAssembly, the system should ask which ownership facts were proved before lowering, which memory effects are visible at the host boundary, which imports and exports exist, and which host capabilities the module can reach.

If a routine lowers into assembly, the system should ask which registers it clobbers, which flags it mutates, which memory regions it touches, whether its timing matters, and whether the binary can be mapped back to the source claim.

LoweringEvery Target Adds Its Own Proof Shape
LayerClaimConstraintProof
01Reactcomponent intentprops, keys, hooks, event handlersrender and type evidence
02HTML/CSSinterface shapeDOM, ARIA, cascade, layoutbrowser probe
03Rust/Wasmnative computationownership, memory, imports, exportscompiler and host gate
04Assemblymachine behaviorregisters, flags, calls, memory refsassembler trace
05Hardwaredevice behaviorI/O registers, interrupts, cyclesemulator or probe
A lower target is not less semantic. It just asks for a different kind of evidence.

Lifting Is Loss Accounting

The reverse direction is not symmetrical.

Assembly can represent machine behavior. It cannot, by itself, tell you which product workflow the behavior belonged to.

A minified bundle can represent browser behavior. It cannot, by itself, tell you the original component boundaries with full confidence.

A database migration can represent a schema transition. It cannot, by itself, tell you every application-level invariant the old schema carried.

Lifting low-level artifacts back into the semantic layer is still useful, but the result must be humble.

binary -> instruction graph
instruction graph -> effect hints
debug symbols -> partial source identity
source maps -> stronger source identity
runtime traces -> observed behavior
missing maps -> known loss

That humility is not a weakness. It is what makes the system trustworthy.

The semantic layer should be able to say:

we know this routine writes $2115
we know it branches to write_refund
we know it clobbers A and P
we do not know that it still implements approveRefund
unless a source map or receipt binds it to that claim

Merging Changes With The Stack

Semantic merge becomes more powerful when it can look above and below the text.

But it also becomes more conservative.

A text patch might be easy to apply. A semantic patch might still be unsafe because it changed a constraint at another layer.

renamed a function
  safe if callers and public API proof rebase
 
changed a CSS selector
  safe if DOM targets and cascade proof still hold
 
changed a Rust lifetime
  safe if ownership proof still holds
 
changed an assembly routine
  safe only if register, flag, memory, timing, and symbol proof still hold

The system should not ask, “did the text merge?”

It should ask, “which claim changed, which constraints moved, and which proof is still valid?”

Merge RoutingA Merge Can Fail At Any Layer
SurfaceClaimRequired proofCurrent evidenceRoute
ProvedTextThe patch applies cleanlyLine or structural applyNo overlapping text editContinue checking
RequiredIdentityThe changed thing is the same thingSymbol, key, selector, id, or source-map proofStable semantic handleRebase or admit
RequiredContractPublic meaning survivedType, schema, declaration, or capability gateComparable output contractGate
MissingRuntimeObserved behavior survivedFocused runtime capsuleDOM, event, effect, trace, state probeProbe
MissingMachineLow-level obligations survivedAssembler, emulator, ABI, or trace evidenceMissing for timing-sensitive routineBlock
A clean text merge is only the first layer. Semantic admission follows the constraint stack until the claim is proved or the system fails closed.

The Weird Shape Is The Point

Frontier is strange because it is not trying to be only an application language, only a compiler IR, only a schema language, only a proof object, or only a runtime manifest.

It is trying to hold the semantic contract between those things.

That means it needs language features that feel high level:

capabilities
actions
views
resources
effects
policies
workflows
public contracts

And it needs language features that feel low level:

source spans
layout constraints
ownership facts
ABI boundaries
memory regions
register effects
runtime traces
known losses

That combination is not decorative.

It is what lets software become more malleable without becoming less trustworthy.

If the stack is explicit, then a system can change at the level the user means while still knowing what lower layers must prove.

If the stack is explicit, then a compiler can lower into many targets without pretending every target preserved the same meaning.

If the stack is explicit, then a merge system can admit more parallel work while refusing the parts it cannot prove.

The end state is not one perfect language above all others.

It is a shared constraint stack where languages can project, merge, interoperate, and fail closed without hiding the layer where meaning changed.