OPAL

OPAL (Operator Permission and Access Layer) is the single command surface every operator — you, an automation rule, or a connected language model — uses to make OctoMY™ do something.

The one-sentence version

Every operation in OctoMY™ that does something — capture a screenshot, pair with a robot, list mounted hives, run a diagnostic, flash firmware — is wrapped as an OPAL Task. The same task runs the same way whether you click it, schedule it, or an LLM invokes it; only the permission check changes.


Why OPAL exists

OctoMY™ is built around a hard separation between the embedded layer (real-time motor and sensor control, where mistakes are dangerous) and the strategic layer (high-level intent: "drive to the workshop, pick up the box"). See the Embedded-Strategic Barrier for the full architectural background.

OPAL is the strategic layer's interface to the embedded layer. Two consequences fall out of this:


The four pieces

Piece What it is
OpalTask One unit of work. Declares its name, parameters, required permissions, execution hints (timeout, idempotent, can-be-skipped), and the keys of the values it produces.
OpalTaskRegistry The catalog of every task the running app knows about. Tasks are registered by domain (catalog, navigation, screenshot, batch, …).
TaskPlan An ordered list of task invocations, serialisable to JSON. Steps can pass values to subsequent steps via output keys. The unit a plan author / LLM composes.
OpalTaskRuntime The executor. Runs a TaskPlan step by step on a background thread, enforces permissions, reports progress, and records the outcome to the history database.

A Task is to a button what a TaskPlan is to a workflow.


Three operators, one path

Every task invocation carries an operator type. The runtime checks permissions differently for each, but the task itself doesn't care who called it.

Operator Permission check Example
Sentient (you) None — you're the device's authority You click "Pair via QR" in the Hub
Automation (trigger / directive) Pre-approved at the time the rule was created A schedule fires "Capture all widgets" every Monday
LLM Live check against the model's granted scopes; unknown scopes prompt for approval An LLM chats "list my robots", which resolves to node.list

The same node.list task in all three cases. The same code. Different gate.


Permissions and audit

Each task declares the permission scope it needs (e.g. catalog.capture, node.create, filesystem.write). The operator's grants are checked at execution time:

Every execution — successful, failed, or denied — lands in OpalHistoryDatabase, visible in the OPAL History activity. So you can always see exactly what was done, by whom, against which Sentient and Node, with what parameters, and what came out.


Composition: TaskPlans

A single task does one thing. A TaskPlan is a JSON document chaining several:

{
  "steps": [
    {"task": "catalog.list_by_tag",  "tag": "trust"},
    {"task": "catalog.capture",      "id": "$1.results[0].id"},
    {"task": "filesystem.copy",      "from": "$2.image_path", "to": "/exports/"}
  ]
}

Outputs of one step are addressable by the next ($1.results[0].id). This is the surface LLMs use to express multi-step intent, and what the app uses internally for batch jobs and triggers.


Tasks come from domains

Each subsystem registers its own tasks into the central registry. The domains that exist today:

Domain What it controls
Catalog Browse and capture widgets (the widget catalog system)
Navigation List and open activities in the running app
Screenshot Take a screenshot of the screen or a widget
Batch List, query, and cancel background jobs
Filesystem Sandbox-restricted file operations
Directives Create, list, pause, resume, and delete trigger directives
Constellation Manage your node constellation — list, create, launch, stop
Help Search, list, outline, read, and open documentation pages
Serial Manage serial connections (list ports, open, close, configure)
BanterLab Drive the BanterLab parameter / codec / testset workflow
Shade Run LLVM-compiled compute shaders
Sentient Create / delete / select Nodes, set Sentient password, export recovery
Construct Edit a Construct scene (add / remove / rename items, set transforms)

See the OPAL reference for the per-task catalogue.


Where you see OPAL in the UI

UI surface What it shows
OPAL activity Direct task explorer — pick a task, fill its parameters, run it. The "developer's REPL" for the app.
OPAL History activity Audit log: every task that ever ran on this Sentient, parameters, outcome, who invoked it
Sentient Permissions activity Per-LLM grant list — which scopes each model has, accept/revoke individually
BatchActivity Long-running OPAL Tasks that report progress show up here
Directives activity Trigger rules that fire OPAL Task plans on a schedule or condition
LLM chat overlay Every assistant action is one or more OPAL Tasks — you see the names in the conversation transcript

Common questions

Can I write my own task? Yes — see the internal developer documentation. A task is a C++ class with a name, a parameter list, a permission scope, and an execute() method. Once registered in any of the Register<Domain>Tasks files, it's available to every operator.

Are tasks stable across versions? Task names and parameter shapes are part of the public surface and follow semantic versioning. Renames go through a deprecation window with an alias.

Can a TaskPlan be interrupted? Yes — the runtime supports cooperative cancellation. Tasks that are interruptible (most I/O-bound work) can be cancelled mid-execution; CPU-bound tasks finish their current step before stopping.

Does OPAL run only on the Hub? No — every node type (Agent, Remote, Hub) has an OPAL runtime. The set of available tasks differs by node: an Agent has access to its own actuators, a Remote can drive a paired Agent, a Hub can introspect any connected node.


Component reference

Component Role
OpalTask Base class — name, params, permissions, hints, output keys, execute()
OpalTaskRegistry Central catalog of registered tasks
OpalTaskRuntime Background executor; permission enforcement; progress; cancellation
TaskPlan Serialisable ordered list of task invocations
OpalHistoryDatabase Audit log of every execution
OPALActivity UI task explorer
OpalHistoryActivity UI for the audit log
SentientPermissionsActivity Per-LLM grant management
OpalTaskBatchWorker Bridges long OPAL Tasks into the Batch system