/model

Programs used to describe computations. Hale describes running systems.

Ownership, lifetime, concurrency, communication, supervision, and deployment are usually documented in different languages. Hale treats them as views of one program.

Code is getting cheaper. Consequences are not.

More implementations will be produced by more people and more tools. The hard part is knowing what each part may touch, publish, block on, allocate, depend on, or destroy. Hale makes those facts compiler input.

The locus is the situated part of the program

A type is data. A locus is anything that owns state or participates in flow: an application, service, connection, worker, cache, pipeline stage, or adapter.

Each locus has a parent, may own children, and owns a memory region. The ownership tree is therefore also a lifetime and failure tree. When a locus dissolves, its owned structure dissolves with it.

main locus Telemetry owns the system root deployment authority
typed broker plane subjects are above publishers and subscribers
SamplesSnapshot
locus Ingest owns socket + receive arena pinned · core 1
locus Rollup owns windows + counters pool · compute
locus Metrics owns HTTP server state pool · io
ownership and lifetime communication through a typed subject physical placement

There are three graphs, and Hale knows how they meet

Ownership

Who owns state, lifetime, children, and recovery.

Communication

Which typed subjects connect publishers and subscribers.

Placement

Where each locus executes and how each edge is realized.

Most stacks scatter those graphs across source code, runtime libraries, broker configuration, and deployment manifests. Hale keeps them separate enough to reason about and joined enough for the compiler to check.

Topics describe communication without smuggling in a mechanism

A topic is a typed, named edge. Publishers declare authority to send; subscribers declare the handler that receives. No channel handle or broker client is threaded through constructors.

pipeline.hl
topic Reading { payload: Sample; }

locus Ingest {
    bus { publish Reading; }

    fn received(s: Sample) {
        Reading <- s;
    }
}

locus Rollup {
    bus { subscribe Reading as add; }

    fn add(s: Sample) {
        // owns the rolling state
    }
}

A closed-world local edge may lower to a direct call. Other local edges use the bus. A binding can carry the same topic over a socket, shared memory, UDP, or a user-written adapter.

main locus is the architectural linker

Domain loci say what the system is. main says where its parts run and how its topic edges travel. Tests can omit bindings; production can split the same source across processes.

main.hl
main locus App {
    params {
        ingest: Ingest = Ingest { };
        rollup: Rollup = Rollup { };
    }

    placement {
        ingest: pinned(core = 1);
        rollup: cooperative(pool = compute);
    }

    bindings {
        Reading: unix("/run/readings.sock");
    }
}

Effects include causality, not only local side effects

Hale can constrain blocking, allocation, syscalls, time, entropy, publication, spawning, and recursion across a reachable call path. It can also state which subjects may transitively influence a locus, following the path through republishers on the bus graph.

dependency-contract.hl
@effects(depends: {Reading, ConfigChanged})
locus Rollup {
    bus {
        subscribe Reading as add;
        subscribe ConfigChanged as configure;
    }
}

The Hale constitution

  1. Nothing stateful is ownerless. State and lifetime have a structural home.
  2. No communication edge is ambient. It is named, typed, and authorized.
  3. Operational behavior can be surfaced. Blocking, allocation, publication, and dependence can become contracts.
  4. Failure goes somewhere structural. Recovery belongs to an owner with context.
  5. Deployment is part of the program. Placement and transport are not unrelated afterthoughts.
  6. Unknown is not proven. A hard guarantee must fail closed.
  7. Runtime change crosses declared seams. Dynamism should move between valid arrangements, not mutate the graph arbitrarily.

The direction

Hale first makes architecture declarative, then checkable, then observable. The next steps are deterministic replay and verified deployment adaptation. They are marked as RFC work, not shipped features.

shipped Describe loci, topics, ownership
shipped Check effects, causality, budgets
shipped Deploy placement and bindings
shipped Observe runtime topology and events
RFC Replay recorded deterministic execution
RFC Adapt verified deployment transitions

Continue with the guide, inspect the verification surface, or run the tour.