Atoms, Facts, and Intents
The Containment Architecture in Detail
Section titled “The Containment Architecture in Detail”JacqOS’s runtime containment works because evidence, derived truth, and proposed actions are kept strictly separate. When a runtime agent proposes an intent, the platform can check it against invariants precisely because facts are derived from observations through explicit, traceable rules — not mixed together in mutable state. When a development-time AI generates those rules, you can verify behavior through fixtures and provenance precisely because each plane is independently inspectable.
Everything flows through one cycle:
Observation → Atoms → Facts → Intents → Effects → (new Observations)Each stage is a separate durable plane — a distinct storage layer with its own semantics. Keeping them separate is what makes both runtime safety and authoring verification possible.
The Six Durable Planes
Section titled “The Six Durable Planes”| Plane | What it holds |
|---|---|
| Observation | Append-only evidence that something happened |
| BlobRef | Content-addressed handle for large raw payloads |
| AtomBatch | Deterministic flattening of one observation into semantic atoms |
| Fact | Derived truth record with provenance (assertions and retractions) |
| Intent | Derived request to perform an external action |
| Effect | Execution lifecycle of an intent plus resulting observations |
Observations: Append-Only Evidence
Section titled “Observations: Append-Only Evidence”Observations are the ground truth. A booking webhook, an API response, a timer tick, an LLM completion — each arrives as an immutable observation appended to the lineage log.
Every observation carries:
- A unique observation reference
- A
kindclassifier (e.g."booking.request","slot.status") - A raw payload (JSON, text, or a
BlobReffor large data) - Ingestion metadata (timestamp, source)
Observations are never modified or deleted. They are the evidence layer — they record what the outside world said, not what the system believes about it.
Atoms: Deterministic Extraction
Section titled “Atoms: Deterministic Extraction”Rhai mappers turn each observation into a batch of atoms — typed key-value pairs that form the structural boundary between messy external data and the semantic logic layer.
fn map_observation(obs) { let atoms = []; if obs.kind == "booking.request" { let body = parse_json(obs.payload); atoms.push(atom("booking.email", body.email)); atoms.push(atom("booking.slot_id", body.slot_id)); atoms.push(atom("booking.name", body.patient_name)); } atoms}Atom extraction is deterministic. The same observation always produces the same atoms. A mapper cannot read facts, derive intents, or access external resources — it receives one observation and returns atoms, nothing more.
The canonical mapper export is the portable contract for this boundary. Two different mapper implementations that produce the same canonical export converge on the same mapper_output_digest. You can refactor mapper code freely without changing semantics.
Atoms enter the ontology through the built-in atom() relation:
rule booking_request(req, email, slot) :- atom(req, "booking.email", email), atom(req, "booking.slot_id", slot).Facts: Derived Truth with Provenance
Section titled “Facts: Derived Truth with Provenance”Facts are what the system currently believes, derived from atoms and other facts through .dh ontology rules. Every fact carries full provenance — which observations, atoms, and rules contributed to its existence.
Facts support two operations:
- Assertions — adding new derived truth
- Retractions — removing previously derived truth when evidence changes
rule assert booking_confirmed(req, slot) :- atom(obs, "reserve.succeeded", "true"), atom(obs, "reserve.request_id", req), atom(obs, "reserve.slot_id", slot).
rule retract slot_available(slot) :- booking_confirmed(_, slot).When new observations arrive, the evaluator reaches a new fixed point and materializes fact deltas — which facts were asserted, which were retracted, and why. The provenance chain for every fact traces all the way back to the raw observations that produced it.
This is where invariant review operates. Humans declare constraints over facts, and the evaluator proves they hold across every scenario. You read the invariant, not the rules that derive the facts.
Intents: Derived Action Requests
Section titled “Intents: Derived Action Requests”Intents are facts with a special prefix — intent. — that the shell intercepts as requests for external action. They are derived exactly like any other fact, through ontology rules.
rule intent.reserve_slot(req, slot) :- booking_request(req, _, slot), not slot_reserved(slot).Intents go through a strict lifecycle:
- Derived — the evaluator produces the intent from current facts
- Admitted — the shell durably records the intent before any external execution
- Executing — the effect runner begins the external action
- Completed — the effect result is captured as a new observation
Every intent is durably admitted before execution begins. No external action fires from a transient derivation.
Effects: The Execution Boundary
Section titled “Effects: The Execution Boundary”Effects are the execution lifecycle of admitted intents. They use declared effect capabilities:
| Capability | Purpose |
|---|---|
http.fetch | Declared outbound HTTP |
llm.complete | Explicit model call for LLM-assisted agents |
blob.put / blob.get | Large raw body storage |
timer.schedule | Request a future timer observation |
log.dev | Developer diagnostics (never canonical state) |
Guest code never mutates facts directly and never appends observations directly. Every external action goes through a declared capability. Undeclared capability use is a hard load error.
Effect results — success or failure — are captured as new observations, which closes the derivation loop and starts the cycle again.
Retry policy is explicit. Idempotent effects auto-retry on failure. Ambiguous mutations (non-idempotent requests that failed mid-execution) enter reconcile_required status for explicit human resolution. No silent auto-retry of mutations whose outcome is uncertain.
Current Truth Versus Audit History
Section titled “Current Truth Versus Audit History”The six durable planes describe the evidence and execution loop. JacqOS also keeps separate audit surfaces so current truth never gets confused with historical explanation.
| Surface | What it answers |
|---|---|
| Committed semantic snapshot | What does this evaluator currently believe at the committed head? |
| Attempt report | Why did one evaluated head commit or reject? |
| Fact plane | Which fact memberships were added or removed when a head committed? |
| Intent plane | Which intents entered or exited, and which effect records are attached to them? |
These surfaces stay distinct on purpose:
- The committed semantic snapshot is the current truth surface.
- Every evaluated head writes one attempt report, whether it commits or rejects.
- Attempt reports explain one evaluation attempt. They are not ontology facts.
- The Fact plane appends committed
addandremovedeltas for facts and contradictions. - The Intent plane appends committed
enterandexitdeltas plus the latest effect linkage for each intent contract. - Fact and Intent planes are append-only audit history, not alternate worldviews.
- Studio, verification, and crash-recovery tooling inspect these audit surfaces without turning them into hidden state.
The Cycle
Section titled “The Cycle”The derivation pipeline is not a one-shot sequence — it is a continuous loop:
┌─────────────┐│ Observation │ ← new evidence arrives (webhook, API response, effect result)└──────┬──────┘ │ Rhai mappers ▼┌─────────────┐│ Atoms │ ← deterministic semantic extraction└──────┬───────┘ │ .dh ontology rules ▼┌─────────────┐│ Facts │ ← derived truth with full provenance└──────┬───────┘ │ intent. rules ▼┌─────────────┐│ Intents │ ← derived action requests└──────┬───────┘ │ effect runner + declared capabilities ▼┌─────────────┐│ Effects │ ← execution lifecycle└──────┬───────┘ │ results captured as observations ▼ └──────────→ back to ObservationEach pass through the cycle:
- New observations arrive — either from external sources or from effect results
- Mappers extract atoms deterministically
- The evaluator reaches a new fixed point, materializing fact deltas
- New intents may be derived from the updated fact set
- The shell admits and executes intents through declared capabilities
- Effect results become new observations, and the cycle continues
The loop terminates naturally when a fixed point produces no new intents. Until then, each effect result feeds back as evidence for the next evaluation pass.
Identity Model
Section titled “Identity Model”JacqOS uses a small set of explicit, non-interchangeable identities to track what changed and why:
| Identity | Purpose |
|---|---|
lineage_id | Names one observation history |
evaluator_digest | Semantic identity for fact derivation — hash of ontology IR, mapper semantics, and helper digests |
package_digest | Frozen runtime handoff identity |
mapper_output_digest | Cross-shell evidence equivalence |
evaluator_digest is the primary semantic identity. When ontology rules, mapper logic, or helper code changes, a new digest is produced. Prompt-only changes do not affect the evaluator digest — semantic identity tracks logic, not presentation.
Next Steps
Section titled “Next Steps”- Lineages and Worldviews — observation histories and evaluator identity
- Invariant Review — how invariants replace code review
- Golden Fixtures — deterministic behavior contracts
- Visual Provenance — the zero-code debugger
- Rhai Mapper API — writing observation mappers
- Evaluation Package — the evaluator digest and package identity