Skip to contentRequest a demo
Documentation/Ontology

Developer guide

Build against objects, relationships, and capabilities. Keep vendor-specific behavior in integrations.

DesignArchitecture v0.1 · Implementation status is scoped by feature
On this page

An intended API and SDK boundary

The intended application programming interface (API) exposes the operational model. A software development kit (SDK) would help applications use that interface. Studio, the existing Valanor application, and other consumers should operate through the same service boundary, each within its own permissions.

Existing application APIs are implementation evidence for that application. They should not be treated as a stable public ontology interface or as proof that the standalone boundary has been delivered.

Query objects and relationships

Start with an object identity and traverse defined relationships. An application reviewing Gate B would retrieve the gate, its place in North Yard, and the camera observing it. It should not need Camera 12’s vendor API or source credentials.

Conceptual pseudocode: read the gate context
within the application's permitted site scope:
  gate = find Asset by its mapped identity "gate-b"
  place = read gate's LOCATED_AT relationship
  cameras = read gate's OBSERVED_BY relationships
  incidents = find Incident objects that AFFECT gate

  show permitted properties, sources, and freshness
  keep unknown or inaccessible context distinct

A capability query should return enough context to assess suitability. Requesting an observation at East Entrance must consider coverage, operating constraints, current availability, and permission, not just whether OBSERVE appears in a list.

Read events and historical state

An application should be able to request relevant events over a time window and ask what state was known at a particular time. Specify the object or place and distinguish observation time from ingestion time.

Conceptual pseudocode: review the earlier gate condition
context = Gate B within North Yard
window = the hour before the reported incident

read permitted events involving context during window
read recorded state of context at the incident time
include source times, receipt times, and evidence references
show any gaps or uncertainty in the record

History may be incomplete because a source was unavailable or an observation arrived late. Do not interpolate missing history into facts. A model prediction should remain separately identified by forecast time, provenance, and uncertainty.

Subscribe to permitted changes

A live application would subscribe to relevant changes after reading an initial view. Both the initial query and the update stream must respect permissions. Losing access should also stop disclosure through the stream.

Conceptual pseudocode: keep a gate view current
open the permitted Gate B view
request updates relevant to that view

when information changes:
  show the updated context and its freshness

when updates are unavailable:
  show that the view may be stale
  refresh through the authorized application interface

Request actions and inspect outcomes

A request expresses intent. It does not bypass authorization or execute a vendor command directly. The Runtime should check the actor, target, parameters, required approvals, capability constraints, and current conditions before routing accepted work.

Conceptual pseudocode: inspect Gate B
request an inspection of Gate B for the linked Task
include the actor, purpose, and required operating constraints

if permission or capability checks reject the request:
  show the reason; do not dispatch
otherwise:
  retain the action execution reference
  read updates and inspect the recorded outcome
  require suitable evidence before marking the Task complete
States an application must distinguish
MeaningWhat it does not prove
Request accepted for processingThat the integration has received a command.
Command acknowledged by an integrationThat a robot moved or a gate physically closed.
Execution reported completeThat every task completion criterion has been verified.
Outcome supported by evidenceThat the same result will hold indefinitely or for another action.
Failed, timed out, or unknownThat repeating the request is safe.

This table describes distinctions, not final API enum names. Request tracking, retry behavior, and approval requirements must be established in the eventual public contract. Never infer permission or successful completion solely from a response arriving.

Treat evidence access separately

An ontology query can return a reference to an image or video without returning the file itself. Applications must use the authorized evidence-access path and handle unavailable or expired evidence. Reading a related object does not grant unrestricted media access.

Do not move device credentials into a browser or embed vendor logic in application code. Integration authorization belongs at the appropriate service or connector boundary. The public authentication and credential-management procedure remains to be specified.

What to establish before building an integration

  • The concrete objects, relationships, and source mappings needed by the application.
  • The applicable permissions and how they apply to queries, relationships, subscriptions, actions, and evidence.
  • A versioned interface contract covering pagination, filtering, errors, compatibility, and change delivery.
  • Action safety, approval requirements, outcome evidence, and retry behavior for the actual integration.
  • Which capabilities are implemented in the target environment and which still require design or validation.

How to read these examples

Each operation runs within the requesting actor’s permitted scope. Establish the actual access contract for your environment before implementation. Device credentials belong at the integration boundary, not inside an application query.

The examples use fictional identifiers for North Yard, Gate B, and an inspection task. Object references identify records; knowing an identifier does not grant permission to read or act on it.

getObjects() and getObject()

Use a collection query when the user is exploring a site. Use a single-object lookup once the application has an authorized object reference. Return only the properties needed for the view.

Object query concepts
InputMeaning
Site scopeLimits the query to the site or sites the actor is allowed to access.
Type and property filtersSelects objects matching the question, such as Assets at East Entrance.
Requested propertiesKeeps the view focused on relevant, permitted information.
Page boundaryAllows a bounded result set. Final pagination semantics are not specified here.
Conceptual pseudocode: find and open a site asset
assets = ontology.getObjects({
  site: "north-yard",
  type: "Asset",
  filter: { name: "Gate B" },
  properties: ["name", "operatingStatus"]
})

// Names may be ambiguous. Let the user select the correct object.
gate = ontology.getObject({ object: selectedAssetReference })
show(gate.permittedProperties, gate.freshness)

An empty result means no visible matches for that query. It does not prove that the site contains no such equipment. A denied or unavailable record must not be converted into a fabricated object with default values.

getRelationships()

Relationships supply context around an object. Ask for the intended relationship direction and type rather than assuming that any nearby object is related.

Conceptual pseudocode: follow Gate B’s context
location = ontology.getRelationships({
  object: gate.reference,
  relationship: "LOCATED_AT",
  direction: "outgoing"
})

observers = ontology.getRelationships({
  object: gate.reference,
  relationship: "OBSERVED_BY",
  direction: "outgoing"
})

showPermittedContext(location, observers)

Each connected object and relationship remains subject to permissions. A permitted gate record does not automatically expose every person, incident, or evidence file associated with it.

getObservations() and getEvents()

Observations describe what a source reported or inferred. Events describe reported occurrences. Read them together when investigating, while preserving their different meanings.

Conceptual pseudocode: retrieve incident context
observations = ontology.getObservations({
  object: gate.reference,
  from: reviewWindow.start,
  to: reviewWindow.end
})

events = ontology.getEvents({
  location: eastEntrance.reference,
  from: reviewWindow.start,
  to: reviewWindow.end
})

for record in observations + events:
  show(record.source, record.observedAt, record.receivedAt)
  show(record.confidenceIfApplicable, record.evidenceReferences)

Define the time window and time basis before comparing results. An observation that arrived late may describe an earlier event. Confidence, when provided, is not a substitute for reviewing evidence and context.

getCurrentState() and getStateAt()

Current state answers what is known now. Historical state answers what is recorded for a selected point in time. Neither should hide gaps in the source record.

Conceptual pseudocode: compare current and earlier state
current = ontology.getCurrentState({ object: gate.reference })
earlier = ontology.getStateAt({
  object: gate.reference,
  at: incident.occurredAt
})

compare(current, earlier)
showFreshnessAndUnknownValues(current, earlier)
Interpret the result
ResultApplication behavior
Recent supported valueShow the value with its source time.
Stale valueDisplay the last known value as stale, not as a live reading.
No recorded state for that timeExplain the gap instead of interpolating a fact.
Corrected source reportPreserve the distinction between the earlier report and later correction.

getPredictedState()

A forecast needs a subject, a target time or horizon, and enough provenance to distinguish it from an observation. Applications should expose uncertainty and avoid treating a forecast as a confirmed future event.

Conceptual pseudocode: display a forecast separately
forecast = ontology.getPredictedState({
  object: gate.reference,
  horizon: selectedForecastWindow
})

if forecast is available:
  showAsPrediction(forecast.value, forecast.targetTime)
  show(forecast.uncertainty, forecast.provenance)
else:
  show("No supported forecast is available for this view")

getCapabilities() and executeAction()

Capabilities help an application discover which operations are suitable. An execution request still needs its own permission and operating checks. The word execute in a conceptual function name does not mean completion is synchronous or guaranteed.

Conceptual pseudocode: request an inspection
capabilities = ontology.getCapabilities({ object: agent.reference })

if supportsRequiredInspection(capabilities, task.constraints):
  request = ontology.executeAction({
    target: agent.reference,
    action: "Inspect",
    context: { task: task.reference, place: eastEntrance.reference }
  })
  showRequestForReview(request.reference)
else:
  show("No suitable inspection capability is currently available")

An application-side suitability check helps the user, but is not authorization. The service must evaluate the request again using the actor’s permissions, required approvals, availability, and current conditions.

Outcome inspection
What to inspectWhy
Acceptance or rejectionDistinguishes a valid request from work that was never authorized.
AcknowledgmentShows that the integration received a command, not that the physical outcome occurred.
Execution resultReports progress, completion, failure, or an unknown outcome.
Supporting observation or evidenceSupports a decision about whether the Task’s completion criteria were met.

Subscriptions, limits, and errors

A live-update subscription would deliver permitted changes relevant to a view. No stable subscription function name or transport is specified here. See the developer model for the intended read, update, and recovery behavior.

Conditions an application should handle
ConditionUseful response
Access deniedExplain that the operation is unavailable for this actor without leaking protected details.
No visible matchOffer a revised query, not a guessed identity.
Source stale or unavailablePreserve the last known context and clearly mark its limits.
Rate limited or temporarily unavailableFollow the published retry contract once available; do not blindly repeat physical commands.
Capability unsuitableShow the constraint preventing the requested operation.
Outcome unknownKeep the uncertainty visible and route the work for review.