Autonomy mode selector
The LOA ladder for the active scope. The climb arms; the descent is immediate.
Live · compact · framed
Production posture in a framed surface. Single tactical row, active rung inline. Tap the chevron to disclose the full rail for a mode change. Climbing arms on first tap, commits on the second within three seconds; descent is immediate. Escape disarms.
Expanded
The full rail, no disclosure. Use in training surfaces and review screens where the LOA hierarchy must remain visible.
Embedded · unframed
The default posture. No bezel, no background fill — the control inherits the host surface’s chrome. Armed state surfaces in the rung label and the rail’s ghost pointer, not in the frame.
Anatomy
Header carries the scope and platform. The active rung — or the full rail when disclosed — sits below. Chevron pointer marks the active position.
AUTONOMY label, scope + platform breadcrumb, and the disclosure chevron in compact mode.
In compact-collapsed posture, the active rung is the only one shown. Three-tier mono — index, label, authority.
Filled Ember needle on the active rung. Inactive rungs read as hairline scale ticks.
The destination rung's label swaps to CONFIRM in Ember and a ghost chevron pulses on the rail. In framed mode the bezel goes Ember too.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| scope | AutonomyScope | — | Command-context scope the ladder applies to. See Command contexts for the type definition. |
| platform | string | — | Optional context label rendered in the header. |
| rungs | AutonomyRung[] | — | Caller-supplied LOA taxonomy, ordered lowest to highest authority-to-machine. Pass DEFAULT_RUNGS for the loop-position default ladder, or substitute your programme's taxonomy. |
| activeKey | string | — | The key of the currently active rung. |
| onTransition | (toKey: string) => void | — | Fires when a transition commits. The consent gesture is internal — by the time your handler runs, the operator has confirmed (or descended, which is always immediate). |
| consent | boolean | true | Require an armed second gesture to commit a climb toward more machine authority. Descending toward the operator always bypasses this. |
| disabled | boolean | false | Disable all controls. Use only when no platform is live. |
| compact | boolean | true | Production glance state — single tactical row with the active rung inline. A chevron discloses the full rail. Set false for docs / training surfaces. |
| framed | boolean | false | Standalone-instrument chrome: hairline bezel + surface fill. Default embed-friendly; inherits the host surface's chrome. Set true for docs heroes, modal / popover deployments, or any context where the control is the dominant visual. |
| className | string | — | Forwarded to the root container. |
Types
AutonomyRungOne rung of an autonomy ladder. The taxonomy is caller-supplied — there is no settled industry LOA vocabulary, so RC3 stays neutral on it.
interface AutonomyRung {
key: string; // stable identifier, e.g. "supervised"
index: string; // rail label, e.g. "L1"
label: string; // display label, rendered in caps, e.g. "SUPERVISED"
authority: string; // loop-position, e.g. "OP-IN-LOOP" or "SYSTEM AI"
blurb?: string; // optional one-line meaning
}DEFAULT_RUNGSRe-exported from the component module so consumers can adopt the default or use it as a starting point. Pass your own array when your programme uses a different LOA model.
// Task-agnostic default ladder. Loop-position language; replace with your taxonomy.
const DEFAULT_RUNGS: AutonomyRung[] = [
{ key: "manual", index: "L0", label: "MANUAL", authority: "OPERATOR", blurb: "Operator commands and acts." },
{ key: "supervised", index: "L1", label: "SUPERVISED", authority: "OP-IN-LOOP", blurb: "System acts; operator monitors every step and can take over instantly." },
{ key: "delegated", index: "L2", label: "DELEGATED", authority: "OP-ON-LOOP", blurb: "System acts and decides routine steps; operator approves key decisions." },
{ key: "autonomous", index: "L3", label: "AUTONOMOUS", authority: "SYSTEM AI", blurb: "System AI acts within mission intent; operator out of the loop." },
];Wiring
Wire onTransition to your backend's mode-change endpoint. The consent gesture is internal; your handler only sees committed transitions.
<AutonomyModeSelector
scope="platform"
platform="UGV-04"
rungs={DEFAULT_RUNGS}
activeKey={currentRung}
onTransition={(toKey) => {
// commit the transition to your backend.
// the consent gesture has already passed by the time you see this.
autonomyAPI.requestMode(toKey);
}}
/>Behavioural rule
Deliberate transitions
Authority does not change by accident. Climbing toward more machine authority is an armed, two-tap commit. Descent is immediate, so the safety escape is never gated.
Taxonomy is caller-supplied
No settled LOA vocabulary exists — Sheridan, NASA LACES, and the service formulations all differ. Rungs are a prop. The default ladder describes loop position, not driving; swap it for the taxonomy your programme uses.
| Index | Label | Authority | Meaning |
|---|---|---|---|
| L0 | MANUAL | OPERATOR | Operator commands and acts. |
| L1 | SUPERVISED | OP-IN-LOOP | System acts; operator monitors every step and can take over instantly. |
| L2 | DELEGATED | OP-ON-LOOP | System acts and decides routine steps; operator approves key decisions. |
| L3 | AUTONOMOUS | SYSTEM AI | System AI acts within mission intent; operator out of the loop. |
Accessibility
| Radiogroup | The rail is a `role="radiogroup"` named by scope. Each rung is a `role="radio"` with `aria-checked` reflecting the active mode. |
|---|---|
| Disclosure | The compact chevron is a button with `aria-expanded` and `aria-controls` pointing at the rail. It does not commit a mode change. |
| Armed state | An arming rung updates its `aria-label` to "Confirm transition to <label>" so screen readers announce that a second gesture is required. |
| Keyboard | Enter or Space selects. Escape disarms. The active rung is disabled — there is no transition to itself. |
| Colour and meaning | The Ember pointer is never the only signal — the index, label, and authority line carry the meaning for operators with colour-vision differences. |
| Disabled | The `disabled` prop dims the control and blocks every transition. Use only when no platform is live — never to mask an error. |
JavaFX
Ships in the PRIZM JavaFX library for thick-client C3 apps as Rc3AutonomyModeSelector (extends VBox). Run the gallery to see it natively.
import design.prizm.fx.rc3.Rc3AutonomyModeSelector;
Rc3AutonomyModeSelector()| Member | Type | Default | Description |
|---|---|---|---|
| Scope | enum | — | PLATFORM / GROUP / SWARM / MISSION — header context. |
| AutonomyRung | record(String key, index, label, authority, blurb) | — | A ladder rung; blurb optional. |
| DEFAULT_RUNGS | List<AutonomyRung> | — | L0 MANUAL → L3 AUTONOMOUS, task-agnostic. |
| setRungs | (List<AutonomyRung>) → void | — | Ordered lowest → highest authority-to-machine. |
| setActiveKey / getActiveKey | (String) / () → String | — | The active rung; setting it resets any pending consent. |
| setOnTransition | (Consumer<String>) → void | — | Fires with the target key on commit (controlled — the caller updates activeKey). |
| setConsent | (boolean) → void | true | Arm-on-climb gate; descent is always immediate. |
| setCompact | (boolean) → void | true | Glance row + disclosure vs the full rail. |
| setFramed | (boolean) → void | false | Hairline bezel + surface fill. |
Vertical notched rail with an Ember chevron pointer (inlined so it reads honestly with or without the pack accent). Honours behavioural invariant 4. Mirrors components/rc3/autonomy-mode-selector.tsx.
Usage
Default to compact in production — operators glance the active rung; the ladder discloses only when a mode change is in hand. Leave the control unframed when it sits inside a host surface that already carries chrome. Use the framed posture only when the control is floating or dominant — modal overlays, popovers, single-panel dashboards. Mark only the active rung with Ember. Never let the climb commit on a single tap; never gate the descent.