06 · LLM Boundaries¶
The entire neural surface of a Horismos deployment is two step types, both declared in the ontology, both with typed contracts, both fully traced. This document is the contract for each.
PerceptionStep: NL → typed instances¶
What the runtime does¶
1. Collect target classes from horis:extracts (:Patient, :Symptom)
2. Derive a JSON Schema from those classes (see mapping below)
3. ONE Bridge call: input text + schema, output forced into the schema
4. Confidence check: result.confidence ≥ horis:confidence ?
no → follow horis:fallback edge. The LLM never guesses.
5. Validation gate: every proposed instance through the World gate
violations → structured feedback → bounded retry (horis:retries, default 2)
still failing → horis:fallback
6. Assert (provenance: perception, confidence attached per fact)
Schema derivation (ontology → JSON Schema)¶
| Ontology | JSON Schema |
|---|---|
| Class with properties | object with properties; required from cardinality 1.. |
xsd:decimal + horis:min/max |
number with minimum/maximum |
horis:unit "bpm" |
description carries the unit ("value in bpm") |
horis:oneOf ( … ) |
enum of IRIs (local names) |
| Subclass tree under an extract target | enum of the tree's local names — the LLM picks from the closed symptom vocabulary, it cannot invent :Heartburn-ish |
horis:assignedBy horis:RulesOnly |
omitted from the schema entirely — unrepresentable in the LLM's output |
horis:pattern |
pattern |
The schema is derived fresh from the loaded ontology at load time and cached; it is never hand-written and cannot drift from the ontology.
Confidence¶
The Bridge reports one confidence per call (provider-specific derivation, doc 08; the mock backend makes it scriptable for tests). Per-fact confidences are attached when the provider supports them, else the call confidence is inherited by each fact. Confidence is metadata, not truth: it gates acceptance and is recorded in trace and proof provenance; it never weights inference. There is no fuzzy logic in Horismos.
What perception cannot do¶
- Set
horis:RulesOnlyproperties (schema omission + gate enforcement, two layers). - Create classes, properties, or rules.
- Trigger tools or transitions — it returns facts; the workflow decides what's next.
- Retry unboundedly or "try a different phrasing" — bounded retries, then fallback.
The structured-input bypass — the primary path for standards-hydrated input¶
Perception is for language. Structured sources skip it entirely:
world.assert_(Patient(heart_rate=128, ...)) # provenance: api
Same gate, same downstream behavior. A deployment fed only by monitors and EHR feeds runs with no Bridge configured at all — CI enforces this configuration works (the anti-wrapper gate, doc 14).
Under the bounded-projection pivot (PRPs/PRP-000-vision-positioning.md), this
bypass is promoted to the primary structured-input path for a standards-hydrated
deployment: an Adapter's ExternalSnapshot (FHIR resources, repository/tool observations
— PRPs/PRP-008-standards-host-integration/01-objective.md) is admitted exactly this
way, with provenance api, never through perception. Mapping a FHIR resource or repo
observation into ontology facts is deterministic adapter code, checked before runtime —
never a perception shortcut. An LLM never infers what a structured standard resource
means; that would smuggle judgment into what is supposed to be a mechanical conversion,
exactly the discipline this document already holds perception itself to.
NarrationStep: proof → NL¶
The inverse transducer: renders a deterministic result for a human audience.
:Explain a horis:NarrationStep ;
horis:narrates [ horis:property :acuity ] ;
horis:audience "charge-nurse" ;
horis:model "claude:claude-fable-5" ;
horis:next :Done .
Contract:
- Input to the model: the rendered proof tree (doc 04) + audience + style rules. Not the raw world, not the conversation, not the NL input.
- Output: prose. It is attached to the trace as
narration, clearly marked as generated, and never asserted into the World. - The proof remains the authoritative explanation; narration is its presentation. Auditors read the proof; humans in the loop read the narration; they must agree because one is generated from the other — and only from the other.
- Narration failure (timeout, refusal) is non-fatal by default: the step falls back
to the mechanical
proof.render()text.horis:required truemakes it fatal.
Where the neural surface ends¶
Everything not listed in this document is symbolic. In particular, these are not LLM operations in Horismos: rule evaluation, workflow transitions, tool selection, tool argument construction, precondition checks, conflict resolution, verification, retraction, queries. If a future feature proposes adding a neural step type, it must come with this document's level of contract: typed input, typed output, gate, fallback, trace visibility.
Candidate-artifact authoring¶
A useful coding agent necessarily generates novel source text, patches, commands, and
sometimes filenames — content an ordinary ActionStep cannot fit, because the current
contract says the model never constructs tool arguments (doc 07). Pretending free-form
code generation is a normal ActionStep would weaken the neural-proposes/symbolic-decides
principle by stealth. The honest extension, captain-adopted alongside the bounded-
projection pivot (decisions/captain-pivot-ruling.md item 3) and owned jointly by
PRPs/PRP-007-authoring-agent.md (vocabulary) and PRPs/PRP-008-standards-host-
integration/01-objective.md (runtime): a candidate-artifact boundary. Model output is a typed
patch/file/command proposal envelope, not a tool argument; deterministic policy
validates target paths, base hashes, syntax, and permissions; a sandbox executes required
tests/checks; only then does a symbolic authorization step permit application. Semantic
correctness of the generated content remains a review/test claim — the boundary proves the
proposal was policy-legal and passed its declared checks, never that the code is right.
horismos-host::artifact implements the runtime half of this boundary; PRP-007 retains the authoring-side
envelope vocabulary and generation semantics. The runtime consumes the envelope as opaque
typed data rather than inventing an eval-shaped escape hatch.