How decisions get made
Needs, not vendors
An Endoskeletal specification says what the organization needs and why. It never says how. The compiler works out the full set of properties a capability must have from the rules and goals around it. It then judges every way of providing it on measured evidence, and it is indifferent to which of several equivalent answers ends up bound.
This page follows one need through the whole process: an audit trail that Northwind's enterprise customers can search and trust.
What a compiler is, and what this one does
Compilers exist so that people can say what they mean and leave the how to a program. Grace Hopper's A-0 in 1952 and FORTRAN in 1957 made the case: write formulas, not machine instructions, and let the compiler produce code nearly as good as a specialist would write by hand. Every compiler since has done some version of the same jobs:
- Parse. Turn text into structure.
- Check. Reject programs that can't mean anything, such as a type mismatch or an undefined name, before they ever run.
- Infer. Work out what was left unsaid. Type inference derives the type of a value from how it is used, so the programmer doesn't have to write it.
- Optimize under the as-if rule. Replace code with cheaper code only when the observable behavior is provably the same.
- Select and link for a target. Choose among equivalent instruction sequences using a cost model of the specific machine, and resolve references to libraries.
Two later developments matter here. Just-in-time compilers, like the ones inside the JVM and JavaScript engines, watch a program run, compile the hot paths into fast specialized code guarded by assumptions, and fall back to the slower general path the moment an assumption breaks. And compiler writers learned not to trust data sheets: tools like llvm-exegesis measure instruction timings on the real chip, and projects like uops.info publish measurements because vendor manuals are incomplete.
Classic compilerEndoskeletal
- sourceC, Rust, Java.esk specneeds, rules
- parsesyntax treeparserecords
- type checkreject nonsensecheckfelicity: E W U
- infertypes from usagederiveneeds from the rules
- optimizeas-if rulesearchequivalent designs
- selectCPU cost modelrankthe org's own objective
- link→ binarybindby a party with authority
↻ When evidence changes, it goes back to “derive” and compiles again.
Text description of this diagram
Two rows of seven stages. A classic compiler: source, parse, type check, infer types, optimize under the as-if rule, select instructions with a cost model of the CPU, link into a binary. The Endoskeletal compiler: the .esk specification, parse into records, felicity check, derive needs from norms and intents, search for equivalent realizations, rank them by the organization's own objective, and bind by a party with authority. Dotted lines pair each stage with its counterpart. A loop from bind back to derive shows that the Endoskeletal compiler reruns whenever evidence changes.
Each job has a direct counterpart when the target is an organization:
| In a classic compiler | In the Endoskeletal compiler |
|---|---|
| Source program | The specification: seats, rules, goals and needs, in .esk |
| Target machine: a CPU | Everything available to run the organization: people, programs, models and providers, with their prices, terms and limits |
| Type checking | Felicity checking: every rule has a bearer, every power traces back to the constitution, every term is defined |
| Type inference | Need derivation: a capability's properties inferred from the rules and goals it serves |
| The as-if rule | Equivalence: any realization that satisfies every derived property on evidence is a correct implementation |
| Instruction selection with a cost model | Realization search, ranked by the organization's own objective: money, attention and exit risk |
| Measured instruction timings | Measured evidence: the organization's own probes and pooled observations, not provider claims |
| Linking | Binding, by a party that holds the power to bind, recorded in the log |
| JIT guards and deoptimization | Crystallization: reasoning distilled into a program with an envelope, handing back to reasoning when an input falls outside it (how it works) |
Four things are different, and they're the reason this is a new language rather than a configuration format:
- It never stops compiling. A CPU's instruction set doesn't change after you ship. Prices, terms, outages and new offers change every week, so the compiler reruns whenever the evidence it depends on changes.
- It proposes; it doesn't bind. A CPU doesn't need to consent to being targeted. An organization does, so binding is an act that requires a power, performed by a party that holds it.
- Unknown is not assumed true. A C compiler trusts its target description. This one treats anything unproven as not permitted, and gives every unknown an owner.
- It explains itself. Every derived property, every rejected candidate and every ranking comes with its sources, in plain English.
The need, as written
This is the entire declaration. It names the operations, one guarantee, and the goals and rules the capability serves. It has no properties, no vendor and no architecture.
requires capability AuditTrail {
operation append(e : au.Event) -> receipt : Entity
operation query(t : cu.Tenant, q : Entity) -> rows : Entity
guarantee eventually holds au.retained(e)
for AuditExport, RecordsRetained, AuditIntegrity, TenantResidency, Frugal, ExitReadiness
}The for line does the work. Each intent and norm named there is already in the specification for its own reasons: a contract clause, a SOC 2 control, a residency rule, a budget. The compiler reads what each of them implies for anything that stores audit events.
What the compiler derives
Written in the spec → derived by the compiler
intent AuditExportenterprise contract § 6.1- append p99 ≤ 150 ms
- query p95 ≤ 2 s recent · ≤ 60 s older
claim ops.event-rateobserved · 30-day peak × 1.5- throughput ≥ 2,100 events/s
norm RecordsRetainedSOC 2 CC7.2 · not defeasible- retention ≥ 7 years
- single-party delete impossible, even for our adminsoften missed
norm AuditIntegrityenterprise contract § 6.3- tamper evidence verifiable by the customeroften missed
norm TenantResidencyDPA § 4 · constitutional- jurisdiction tenant region, every copy and backupoften missed
fin.Budget PlatformShareweighted by intent Frugal- cost ≤ 1,200 USD per month
norm ExitReadinessconstitutional- exit ≤ 5 days to another realization
Text description of this diagram
Seven statements in the specification imply the nine properties of AuditTrail. Properties marked “often missed” are ones a design review commonly overlooks.
- intent AuditExport (enterprise contract § 6.1) → append p99 ≤ 150 ms, query p95 ≤ 2 s recent · ≤ 60 s older
- claim ops.event-rate (observed · 30-day peak × 1.5) → throughput ≥ 2,100 events/s
- norm RecordsRetained (SOC 2 CC7.2 · not defeasible) → retention ≥ 7 years, single-party delete impossible, even for our admins
- norm AuditIntegrity (enterprise contract § 6.3) → tamper evidence verifiable by the customer
- norm TenantResidency (DPA § 4 · constitutional) → jurisdiction tenant region, every copy and backup
- fin.Budget PlatformShare (weighted by intent Frugal) → cost ≤ 1,200 USD per month
- norm ExitReadiness (constitutional) → exit ≤ 5 days to another realization
$ esk needs AuditTrail
AuditTrail · 0 properties written · 9 derived from 7 sources
append-p99 <= 150 ms ← intent AuditExport (contract § 6.1)
query-p95 <= 2 s, ≤ 90 d ← intent AuditExport (contract § 6.1)
<= 60 s, older
throughput >= 2,100 /s ← claim ops.event-rate (peak × 1.5)
retention >= 7 y ← norm RecordsRetained (soc2 CC7.2)
single-party-delete = impossible ← norm RecordsRetained
not defeasible: must be prevented, not only forbidden
tamper-evidence = verifiable-by(t) ← norm AuditIntegrity (contract § 6.3)
jurisdiction = t.region ← norm TenantResidency
every copy: replicas, backups, subprocessors
cost <= 1,200 USD/mo ← fin.Budget PlatformShare
exit <= 5 d ← norm ExitReadiness
$ esk realize AuditTrail --explain
searched 31 offers · 212 compositions · 8 survived decomposition
equivalent C A B D every condition T on evidence
fails E jurisdiction F · cost F
F single-party-delete F · tamper-evidence F · query-older F
G single-party-delete F · tamper-evidence F
unknown H terms N · retention N · single-party-delete N → not admissible
proposal: C where cu.byob(t) holds, A otherwise; B, D as fallbacks
awaiting: bind by CTO (power PlatformBinds, collective)Three of the nine are the ones design reviews miss:
- Single-party delete must be impossible, including for your own admins. RecordsRetained is a prohibition on any party and is not defeasible. A rule that can't be overridden can't rely on everyone behaving, so the compiler requires the realization to make the act impossible rather than merely forbidden. A lock that the account's root user can lift fails.
- Jurisdiction applies to every copy. TenantResidency is about custody, and custody includes replicas, backups and anyone with read access. A provider's support staff in another country count as a copy.
- Tamper evidence must be checkable by the customer. AuditIntegrity is owed to the tenant, so evidence only the operator can inspect doesn't discharge it.
The other six come from where you'd expect: latency and query speed from the contract, throughput from an observed claim (the 30-day peak with 50 % headroom, re-derived when the claim changes), retention from SOC 2, cost from the budget share, exit time from a constitutional norm.
The rules it derived them from
norm RecordsRetained {
prohibition on any Party
aim occurred execute(data.Delete, e) and e is au.Event and age(e) < 7 y
source external soc2 # "CC7.2"
level constitutional not tradeable not defeasible
}
norm AuditIntegrity {
obligation of persona to cu.Tenant
when e is au.Event and e.tenant = t
aim holds au.verifiable-by(e, t)
source external contract.Enterprise # "§ 6.3"
}
norm TenantResidency {
prohibition on any Party
aim exists x : Entity . x.tenant = t and custody-jurisdiction(x) != t.region
level constitutional not tradeable
}
-- what the compiler may believe about a provider's own description of itself
use ev.TrustPolicy(
source-kind = pv.Provider,
base = N,
promote-when = ev.ConfirmedByOwnProbe(within = 14 d)
or ev.CorroboratedBy(3, independent = true),
vocab = { pv.latency, pv.throughput, pv.immutability, pv.residency }
) as ProviderSelfReports
position SecOfficer : org.Officer {
cardinality 1
incompatible with PlatformLead
}What providers say is not evidence
A provider is authoritative about its own price list, terms and deprecations. It is not authoritative about its own latency, durability, immutability or residency. Under the ProviderSelfReports policy above, those claims start at N (unknown). They become T only when the organization's own probe confirms them, or when three independent organizations report the same measurement through the pool.
| candidate | terms | append | throughput | retention | delete | tamper | jurisdiction | query recent | query older | cost | exit |
|---|---|---|---|---|---|---|---|---|---|---|---|
| A Locked object storage + queue + embedded queryequivalent | T: standard use | T: 24 ms, to the existing queue | T: 9,000/s measured | T: compliance-mode lock, 7 y | T: lock binds the root account too | T: daily Merkle root sent to each tenant | T: EU and US buckets, replication off · provider says “multi-region by default”: switched off and verified | T: 1.4 s over tenant/day partitions | T: 3.1 s | T: 410 USD | T: 2 d, open columnar files |
| B Search cluster we already run (90 d) + an email-journaling archiveequivalent | T: § 3.4 permits application-generated records | T: 31 ms, to the existing queue | T: 5,500/s | T: WORM from ingest, 7 y | T: archive is write-once from ingest | T: RFC 3161 receipt per record | T: EU and US data centres, subprocessors listed | T: 0.6 s from the cluster | T: 4.2 s · provider says “search in milliseconds”: measured 4.2 s, still inside 60 s | T: 430 USD (one archive seat per tenant) | T: 4 d, EML + JSON export |
| C Customer-held buckets, for tenants who opt inequivalent | T: BYOB addendum signed by the tenant | T: 24 ms, to the existing queue | T: 9,000/s | T: tenant lock policy, checked daily | T: Northwind holds no delete right at all | T: the customer holds the records | T: the tenant's own region | T: 1.9 s via a delegated read role | T: 3.6 s | T: 60 USD for 38 tenants | T: 0 d, they already have it |
| D Two providers, two roots, held by incompatible seatsequivalent | T: standard use | T: 29 ms | T: 7,000/s | T: governance lock at both providers | T: needs both roots; no party may hold both | T: cross-provider hash comparison, published | T: EU at both providers | T: 1.6 s | T: 3.4 s | T: 380 USD | T: 1 d |
| E Managed audit-log servicefails | T: standard use | T: 40 ms | T: 20,000/s | T: 7 y plan | T: immutable plan | T: signed exports | F: US support subprocessor has read access · provider says “EU data residency” | T: 0.4 s | T: 0.9 s | F: 3,400 USD | T: 3 d |
| F Our observability vendor's log archive (already under contract)fails | T: standard use | T: 60 ms | T: 50,000/s | T: archive tier, 7 y | F: an account admin can purge | F: nothing the customer can check | T: EU site available | T: 0.8 s, hot tier | F: rehydration takes 4–9 h · provider says “searchable archives” | T: 220 USD | T: 2 d |
| G Append-only table in the primary Postgresfails | T: standard use | T: 6 ms | T: 3,000/s | T: by policy | F: a superuser can drop the table | F: nothing the customer can check | T: EU and US clusters | T: 1.1 s | T: 12 s | T: 90 USD | T: 1 d |
| H A provider's new “immutable tables” (preview)unknown · not permitted | N: preview terms exclude production data | T: 35 ms | N: no independent observation | N: says 7 y; no evidence · provider says “WORM compliance” | N: no evidence · provider says “cannot be deleted” | N: unknown | T: EU region | T: 1.0 s | N: unmeasured | T: 300 USD | N: unknown |
A Locked object storage + queue + embedded query equivalent
- ✓terms permit this use standard use
- ✓append p99 ≤ 150 ms 24 ms, to the existing queue
- ✓throughput ≥ 2,100/s 9,000/s measured
- ✓retention ≥ 7 y compliance-mode lock, 7 y
- ✓single-party delete impossible lock binds the root account too
- ✓customer-verifiable tamper evidence daily Merkle root sent to each tenant
- ✓jurisdiction of all copies EU and US buckets, replication offprovider says “multi-region by default”: switched off and verified
- ✓query p95 ≤ 2 s (≤ 90 d) 1.4 s over tenant/day partitions
- ✓query p95 ≤ 60 s (older) 3.1 s
- ✓cost ≤ 1,200 USD/mo 410 USD
- ✓exit ≤ 5 d 2 d, open columnar files
B Search cluster we already run (90 d) + an email-journaling archive equivalent
- ✓terms permit this use § 3.4 permits application-generated records
- ✓append p99 ≤ 150 ms 31 ms, to the existing queue
- ✓throughput ≥ 2,100/s 5,500/s
- ✓retention ≥ 7 y WORM from ingest, 7 y
- ✓single-party delete impossible archive is write-once from ingest
- ✓customer-verifiable tamper evidence RFC 3161 receipt per record
- ✓jurisdiction of all copies EU and US data centres, subprocessors listed
- ✓query p95 ≤ 2 s (≤ 90 d) 0.6 s from the cluster
- ✓query p95 ≤ 60 s (older) 4.2 sprovider says “search in milliseconds”: measured 4.2 s, still inside 60 s
- ✓cost ≤ 1,200 USD/mo 430 USD (one archive seat per tenant)
- ✓exit ≤ 5 d 4 d, EML + JSON export
C Customer-held buckets, for tenants who opt in equivalent
- ✓terms permit this use BYOB addendum signed by the tenant
- ✓append p99 ≤ 150 ms 24 ms, to the existing queue
- ✓throughput ≥ 2,100/s 9,000/s
- ✓retention ≥ 7 y tenant lock policy, checked daily
- ✓single-party delete impossible Northwind holds no delete right at all
- ✓customer-verifiable tamper evidence the customer holds the records
- ✓jurisdiction of all copies the tenant's own region
- ✓query p95 ≤ 2 s (≤ 90 d) 1.9 s via a delegated read role
- ✓query p95 ≤ 60 s (older) 3.6 s
- ✓cost ≤ 1,200 USD/mo 60 USD for 38 tenants
- ✓exit ≤ 5 d 0 d, they already have it
D Two providers, two roots, held by incompatible seats equivalent
- ✓terms permit this use standard use
- ✓append p99 ≤ 150 ms 29 ms
- ✓throughput ≥ 2,100/s 7,000/s
- ✓retention ≥ 7 y governance lock at both providers
- ✓single-party delete impossible needs both roots; no party may hold both
- ✓customer-verifiable tamper evidence cross-provider hash comparison, published
- ✓jurisdiction of all copies EU at both providers
- ✓query p95 ≤ 2 s (≤ 90 d) 1.6 s
- ✓query p95 ≤ 60 s (older) 3.4 s
- ✓cost ≤ 1,200 USD/mo 380 USD
- ✓exit ≤ 5 d 1 d
E Managed audit-log service fails
- ✓terms permit this use standard use
- ✓append p99 ≤ 150 ms 40 ms
- ✓throughput ≥ 2,100/s 20,000/s
- ✓retention ≥ 7 y 7 y plan
- ✓single-party delete impossible immutable plan
- ✓customer-verifiable tamper evidence signed exports
- ✗jurisdiction of all copies US support subprocessor has read accessprovider says “EU data residency”
- ✓query p95 ≤ 2 s (≤ 90 d) 0.4 s
- ✓query p95 ≤ 60 s (older) 0.9 s
- ✗cost ≤ 1,200 USD/mo 3,400 USD
- ✓exit ≤ 5 d 3 d
F Our observability vendor's log archive (already under contract) fails
- ✓terms permit this use standard use
- ✓append p99 ≤ 150 ms 60 ms
- ✓throughput ≥ 2,100/s 50,000/s
- ✓retention ≥ 7 y archive tier, 7 y
- ✗single-party delete impossible an account admin can purge
- ✗customer-verifiable tamper evidence nothing the customer can check
- ✓jurisdiction of all copies EU site available
- ✓query p95 ≤ 2 s (≤ 90 d) 0.8 s, hot tier
- ✗query p95 ≤ 60 s (older) rehydration takes 4–9 hprovider says “searchable archives”
- ✓cost ≤ 1,200 USD/mo 220 USD
- ✓exit ≤ 5 d 2 d
G Append-only table in the primary Postgres fails
- ✓terms permit this use standard use
- ✓append p99 ≤ 150 ms 6 ms
- ✓throughput ≥ 2,100/s 3,000/s
- ✓retention ≥ 7 y by policy
- ✗single-party delete impossible a superuser can drop the table
- ✗customer-verifiable tamper evidence nothing the customer can check
- ✓jurisdiction of all copies EU and US clusters
- ✓query p95 ≤ 2 s (≤ 90 d) 1.1 s
- ✓query p95 ≤ 60 s (older) 12 s
- ✓cost ≤ 1,200 USD/mo 90 USD
- ✓exit ≤ 5 d 1 d
H A provider's new “immutable tables” (preview) unknown · not permitted
- ?terms permit this use preview terms exclude production data
- ✓append p99 ≤ 150 ms 35 ms
- ?throughput ≥ 2,100/s no independent observation
- ?retention ≥ 7 y says 7 y; no evidenceprovider says “WORM compliance”
- ?single-party delete impossible no evidenceprovider says “cannot be deleted”
- ?customer-verifiable tamper evidence unknown
- ✓jurisdiction of all copies EU region
- ✓query p95 ≤ 2 s (≤ 90 d) 1.0 s
- ?query p95 ≤ 60 s (older) unmeasured
- ✓cost ≤ 1,200 USD/mo 300 USD
- ?exit ≤ 5 d unknown
✓ true on evidence✗ false? unknownprovider claim contradicted by measurement
Three things in this table only show up because claims were checked:
- E advertises EU data residency. Its subprocessor list gives a US support team read access, so jurisdiction is F.
- F advertises searchable archives. A probe measured 4 to 9 hours to rehydrate an archived month, so query speed for older records is F.
- H advertises WORM compliance for a preview feature. No one has measured it and the preview terms exclude production data, so it is N. N is not permission: H isn't rejected, it waits, owned, until evidence arrives.
Claims are also not always wrong in the provider's disfavor. B's archive says “search in milliseconds” and measured 4.2 seconds, which is well inside the 60 seconds required for records older than 90 days. The engine uses the measured number either way.
Four equivalent designs
Each of these satisfies every derived property on evidence, so each is a correct implementation of the same specification. Only one of them resembles something you'd find in an architecture review.
Locked object storage, a queue you already run, and a query engine with no servers
Why it isn’t obvious. An architect reaches for a database or a logging product. Nothing here is a logging product: the lock provides immutability, the batch layout provides query speed, the published root provides tamper evidence.
Why it counts. Compliance-mode locks can't be lifted by the account's root user, which is exactly what the not-defeasible retention norm requires.
The search cluster you already pay for, plus an email-journaling archive
Why it isn’t obvious. Email archives are sold to legal teams, not engineers. They already provide write-once retention, legal hold, per-custodian search and regional data centres; a tenant becomes a custodian.
Why it counts. Admissible only because the archive's terms (§ 3.4) permit application-generated records. That clause is a recorded claim with a source; if it changes, this design drops out.
Let the customer hold the records
Why it isn’t obvious. The instinct is to store more carefully. This moves custody to the party that wants the guarantee: Northwind can't delete what it never controls, and residency is the customer's own choice.
Why it counts. Equivalent only for tenants who sign the bring-your-own-bucket addendum, which transfers the retention duty to them. The engine binds it per tenant: 38 of 120 today.
Two cheap stores at two providers, and an org rule instead of a feature
Why it isn’t obvious. Neither store is immutable. The guarantee comes from the org chart: the two root credentials sit in positions declared incompatible, so no single party can hold both, and a deletion at one provider shows up in the published hash comparison.
Why it counts. The compiler can prove single-party deletion is impossible because the incompatibility is a norm it checks on every appointment. Structure substitutes for a product feature.
Choosing among equivalents
Equivalence is decided by the properties. The choice among equivalents is decided by the organization's own objective, which is itself in the specification: money, logged human attention, and exit risk, each priced.
Ranked on the organization’s own objective: money, plus logged human attention at 2.50 USD a minute, plus exit risk at 40 USD per day of exit time.
moneyattentionexit risk
The engine proposes; it doesn't bind. The Architect's proposal is to bind C for every tenant where cu.byob(t) holds and A for everyone else, keeping B and D warm as fallbacks. The CTO holds the power to bind AuditTrail, and exercises it. The bind is one event in the log, with the whole argument attached: the derivation, the evidence behind every cell of the table, and the ranking.
What stays fixed when the implementation changes
Suppose the object store in A raises its price by 60 %. A price change is a trusted lifecycle claim, so Reconsider fires. B now ranks first for tenants outside the opt-in group; the Architect proposes the swap, the CTO binds it, and the migration runs as ordinary commitments with deadlines. Across that change:
- not one line of the specification changes;
- every norm keeps holding, because B was admissible under all of them before it was chosen;
- the audit history is continuous, because the log records which realization held each event;
- every tenant's query interface stays the same, because it is the capability's operation, not a vendor API.
That is what separating needs from implementation buys you. Infrastructure code describes one implementation and has to be rewritten to change it. A specification describes the need, and any implementation that satisfies it on evidence is interchangeable with any other.
How the search stays lawful
A composition search that finds an email archive can find many things. Three constraints keep it honest:
- Terms are a property like any other. Design B is admissible because a specific clause (§ 3.4) permits application-generated records. That clause is a recorded claim with a source. If the provider changes it, the claim changes and B drops out on the next evaluation.
- Probes run inside the terms. Every measurement comes from an experiment with its own budget and duration, and
WithinTermsprohibits probing anything the contract doesn't permit. See Capability discovery. - Unknown never counts as yes. Any condition at N makes a candidate inadmissible, however attractive its price. Unknown conditions get an owner and a deadline, so candidates like H come back when evidence does.
More compositions of this kind, including a backup archive used as object storage and a relay plus a store used as a queue, are on Non-obvious solutions. How measurements are shared across organizations is on Learn once, apply everywhere.