Skip to content

Key Concepts

JacqOS apps host runtime AI agents inside a deterministic boundary. Agents observe the world, the platform derives a shared model, agents propose intents, and the platform proves those intents against your invariants before anything touches the outside world. The key insight: you never need to read the AI-generated rules to verify behavior. You review invariants and fixtures instead.

Everything flows through one pipeline:

Observation → Atoms → (Candidates/Proposals) → Facts → Intents → Effects → (new Observations)

Each stage is explicit, deterministic, and traceable. Here is what each one means.

An observation is append-only evidence that something happened. A webhook arrived. An API responded. A timer fired. An LLM returned a completion.

Observations are immutable. Once written, they never change. They are the single source of truth in a JacqOS app.

{"kind": "booking.request", "payload": {"email": "pat@example.com", "slot_id": "slot-42"}}
{"kind": "reserve.result", "payload": {"request_id": "req-1", "succeeded": true}}

Rhai mappers extract structured data from each observation, producing atoms — typed key-value evidence that the ontology layer can reason about.

mappings/inbound.rhai
fn map_observation(obs) {
if obs.kind == "booking.request" {
let body = parse_json(obs.payload);
[
atom("booking.email", body.email),
atom("booking.slot_id", body.slot_id),
]
} else {
[]
}
}

Atoms are the boundary between unstructured external data and the semantic logic layer.

JacqOS enforces a structural boundary for fallible AI output.

  • candidate.* is for descriptive relay (voice, vision, extraction).
  • proposal.* is for action suggestions (refunds, offers, remediations).

These are non-authoritative facts that require an explicit rule to promote them to accepted truth or executable intents.

.dh ontology rules derive facts from atoms and relay namespaces. Facts represent what the system currently believes, with full provenance back to the observations that support them.

rule booking_request(req, email, slot) :-
atom(req, "booking.email", email),
atom(req, "booking.slot_id", slot).
rule slot_reserved(slot) :-
booking_confirmed(_, slot).

Facts can be asserted (new truth) or retracted (truth withdrawn). Every fact records exactly which observations and rules produced it.

When the ontology derives a fact with the intent. prefix, JacqOS treats it as a request to perform an external action:

rule intent.reserve_slot(req, slot) :-
booking_request(req, _, slot),
not slot_reserved(slot).

Intents are declarative. The rules say what should happen. The shell decides when and how to execute it.

The shell executes intents as effects — external actions like HTTP calls, LLM completions, or timer scheduling. Each effect produces new observations, closing the loop.

The shell implements a continuous reconciliation loop: it admits derived intents, drives them to completion as effects, and appends the receipts as observations that trigger the next round of evaluation.

Effects use declared capabilities. If your app does not declare http.fetch in jacqos.toml, no HTTP calls can happen. Undeclared capability use is a hard load error.

StageWhat it isWho writes it
ObservationRaw evidenceExternal world / effects
AtomStructured extractionRhai mapper
Candidate/ProposalRelay namespacesNon-authoritative models
FactDerived truth.dh rules
IntentAction request.dh rules
EffectExecuted actionShell runtime

This pipeline is the containment architecture. Runtime agents operate inside it: they observe, they propose intents, and the platform checks every proposed transition before it becomes reality. Development-time AI generates the rules and mappers; you verify behavior through invariants and golden fixtures without ever reading the generated code.