endoskeletal kernel 1 · lib 2026.09

The language

How the language works

A .esk file compiles to definition records (IR-D) and nothing else. No construct has semantics of its own: every line becomes one or more of the ten kernel records, every record renders as an English sentence, and the whole thing is checkable without running anything. This page walks through Pebble, the smallest organization that has been run.

Module header and vocabulary

pebble.eskesk
module pebble.core @ 1.0.0
  uses esk.kernel @ 1
  import lib.org         @ 2.* as org
  import lib.governance  @ 1.* as gov
  import lib.finance     @ 1.* as fin
  import lib.evidence    @ 1.* as ev
  import lib.realization @ 1.* as rz
  import lib.agents      @ 1.* as ag
  import lib.econ        @ 1.* as econ

vocabulary ws @ 1.0.0 {
  availability(r : Capability)     : claim   "availability of realization r over the observed window, in percent"
  price(c : Capability)            : claim   "per-instance monthly price of an offered compute capability"
  price-change(c : Capability)     : claim   "an offered capability's price changed"
  ScaleRequest(n : Number, projected : Quantity<currency>) : entity  "a request to run n instances"
  MigrationProposal(candidate : Capability) : entity "an Architect proposal to rebind WebService"
  Scale(n : Number)                : event external  "change the instance count of a compute realization"
  LoadTest(n : Number, rate : Number) : event external "drive synthetic load against a sandbox realization"
}

uses esk.kernel @ 1 pins the kernel. Imports bind a version range; the lockfile pins the exact content hash each range resolved to. A vocabulary declares the organization's terms and what sort each one is: a claim can be T, F, N or B; an entity is a kind of thing; an event external is something done to the world, which will always need authorization.

Scope, persona, positions

esk
scope Pebble : org.Organization {
  persona PebbleCo
  use gov.Constitution(founders = { Owner }, amendBy = Owner, quorum = 1) as Const

  position Owner      : org.Owner   { cardinality 1  eligible when self is org.Person }
  position Operations : org.Officer { cardinality 1  eligible when self is ag.Autonomous }
  position Architect  : org.Officer { cardinality 1  eligible when self is ag.Autonomous
                                      incompatible with Operations }
  position Engine     : rz.Engine   { cardinality 1 }

The scope acts through its persona, PebbleCo. Positions carry cardinality, eligibility (by party kind: a person, an autonomous agent, a program, a model-based party) and incompatibilities. The engine that runs the organization is itself a position, so its authority is granted and checked like anyone else's.

Intents and required capabilities

esk
intent Available  : org.SLO { maintain holds ws.availability(WebService) >= 99.5 %  hard }
intent Responsive : org.SLO { maintain holds ws.p95-latency(WebService)  <= 300 ms  hard }
intent Frugal                { avoid holds ws.cost(WebService) > 500 USD per month  soft weight 0.5 }

requires capability WebService {
  operation serve(request : Entity) -> response : Entity
  operation scale(n : Number) -> outcome : Claim
  guarantee eventually holds ws.Served(request)
  property  availability  >= 99.5 % per day
  property  p95-latency   <= 300 ms
  property  cost          <= 500 USD per month
  for Available, Responsive, Frugal
}

Intents say what the scope wants. hard intents must be covered by a responsible position or a required capability; soft ones carry weights or priorities for comparisons. A required capability is a contract: operations, what it may assume, what it must guarantee, and properties with thresholds. Quantities carry dimensions; comparing ms to USD is a compile error.

Norms and patterns

esk
use rz.RealizationEnvelope(holder = Operations, requirement = WebService, operation = ws.Scale,
      admissible = a.n <= 5 and holds ws.price(bound(WebService)) * a.n <= 500 USD per month) as OpsEnvelope

use org.Approval(approver = Owner, subject = ws.ScaleRequest,
      threshold = s.n > 5 or s.projected > 500 USD per month,
      deadline = 1 business-days, escalateTo = Owner) as ScaleApproval

norm OwnerBinds { power of Owner to bind | unbind _ about WebService   level collective }

norm DailyCheck {
  obligation of Operations to persona
  when occurred tick(t) and t.boundary = "day"
  aim within 2 h: occurred derive(ws.daily-status(t.day)) by Operations
  not tradeable
}

A norm has a bearer, a deontic line, a condition (when), an aim, and optionally an or-else, a level, a source, a priority and tradeability. use instantiates a library pattern: rz.RealizationEnvelope expands to one power norm, org.Approval to four (the power to decide, the duty to decide by a deadline, the escalation, and a gate that prohibits executing before approval). Every expanded record keeps expandedFrom: the pattern, package, version and use site.

Note holds ws.price(…) inside the envelope. The price claim comes from the provider, whose statements start at N under Pebble's trust policy until two daily bills agree. Until then the envelope admits nothing and Operations has to ask.

Information rules

esk
  use ev.TrustPolicy(source-kind = ev.Monitor,  base = T) as MonitorTrust
  use ev.TrustPolicy(source-kind = ws.Provider, base = N,
        promote-when = ev.ConsecutiveDailyObservations(2), vocab = { ws.price, ws.price-change }) as ProviderTrust
}

Trust policies decide what status a claim gets from its source. Your own monitors are trusted; a provider's price page is not, until your bills corroborate it. A model-based party's output gets N by default in every reference organization.

What the compiler produces

Verbalization

In Finance: when a spend request r occurs whose amount exceeds 10,000 USD, the Treasurer is obliged to r's requester to decide to approve or reject r within 2 business days; otherwise the norm SpendEscalation applies. Operational level. Source: Acme Bylaws §3.2. Conflicts resolved by specificity.verbal field of esk:norm/…SpendApproval · hashed with the record

Every record carries its rendering. A reviewer's sign-off is a decide event over the rendered text, so what people approved and what the engine runs are the same object.

IR record

IR-D (Stage 6 example)json
{"@type":"Norm","@id":"esk:norm/eu-residency","scope":"esk:scope/acme",
 "deontic":"F","bearer":"esk:pos/member",
 "aim":["exists",["var","x","Entity"],
        ["and",["has-kind",["var","x"],"fin:PersonalData"],
               ["not",["in",["custody-jurisdiction",["var","x"]],["set","EU"]]]]],
 "condition":["true"],"source":{"issuer":"esk:party/eu","ref":"GDPR art. 44–49"},
 "level":"constitutional","tradeable":false,"defeasible":false,
 "verbal":"No member may cause personal data to be held outside EU jurisdiction. Source: GDPR. Not tradeable."}

Check report

out/static-check-report.json · Meridian, excerptconsole
summary              241 records · 0 E · 11 W · 77 U · 214 I
W-SINGLE-POINT       esk:pos/Meridian.Owner has cardinality 1, no Deputy pattern, and bears … exclusive powers
W-OVERLAPPING-POWER  Meridian.OwnerSpend and Meridian.FinanceSpend overlap on decide without declared priority
E-FREEZE-COVERAGE    OpexBudget.Freeze: exceptions cover all non-tradeable obligations in scope
E-ARCH-PRODUCTION    Architect holds no bind/unbind/authorize power over any production requirement
U                    esk:cap/Meridian.Database.rpo: satisfaction depends on observed evidence — UNKNOWN until runtime

The four severities: E the spec violates the kernel and can't be enacted; W enactable but suspicious; U undecidable until the organization runs (listed so that "we don't know yet" is an output of compilation); I information, including every chain of authority.

Conditions are the whole constraint language

There's no separate policy language. Conditions combine claim tests (holds, unknown, contradicted, false), log tests (occurred, count … over, since), normative tests (violated commitment of, breached, in-force, gap) and bounded temporal operators (within, before, until). A condition that tests any claim is four-valued, and the checker warns (W-UNKNOWN-BRANCH) when no norm in scope says what happens if it evaluates to unknown.

The language has no loops, functions or string manipulation. Computation is done by capabilities, whatever realizes them, and its results come back as claims. That keeps the specification a description of what is required and what is in force, and stops it becoming a place for implementation to hide.