ProjectDesign system · Demo · In progress

KAIROS icon — a dial with one mark set apart.

A design system where every component says what is known, how sure it is, and who may act.

object-oriented DSDTCG tokenshuman–autonomyfictional

KAIROS


KAIROS is a design system for consoles where a person supervises autonomous aircraft and approves or rejects what an AI recommends, often against a clock. I built it into a fictional maritime drone console you can run in the browser: twelve drones on patrol, a ship to land on, and things going wrong on a schedule.

Most component libraries define how things look. This one starts from what things are: an aircraft, an alert, a recommendation, a decision. Every component renders one of those objects and says three things about it. Did a sensor see it, or did the AI infer it? How loudly may it interrupt? Whose authority does acting on it need?

Below, scenario by scenario: what happens, what the operator sees, and why the console does it that way. How the grammar itself was built is written up in Building an Object-Oriented Design System.

A navigation anomaly: the red banner with its countdown, and the inspector's Decision tab with the situation, the AI recommendation and four options.
navigation anomaly — the one thing that needs you

Where it stands

  1. 01Built — a console you can run in the browser: twelve scenarios, tokens, Storybook and a QML theme. A personal concept; I designed and built all of it.
  2. 02Checked by machine — 455 automated checks on every build, and two critiques from a human factors point of view that produced 26 findings.
  3. 03Not yet tested with people — whether operators catch the events that matter, sooner and with fewer wrong approvals. That is the user test at the end of this page.

Mission start

All twelve aircraft start stowed aboard the ship. They launch one at a time from the single deck, ninety seconds apart, climb out, transit to their areas and only then start the patrol.

Why it's designed this way

  1. 01Each flight says how much of it is working — "0/2" on task fills up as its aircraft arrive, and coverage starts at 0 %, so nobody mistakes a launch for a patrol.
  2. 02The way out is drawn — each transiting aircraft shows its path ahead to its area, dashed because it is planned, not flown.
  3. 03Nothing is spent on deck — an aircraft draws energy only from its launch, and it launches with a charged battery.
Mission start: the first aircraft in transit from the ship with their paths ahead; flights show 0 or 1 of 2 on task and 0 % patrol coverage.
staggered launch — flights fill up one aircraft at a time

Navigation anomaly

HERON 2's GNSS position starts to drift. The AI suspects interference and recommends flying to a lighthouse to re-fix the position. If nobody decides within the window, the system holds the drone in place and its position error keeps growing.

Why it's designed this way

  1. 01Critical means a deadline and a harmful default — the first version promoted anything with a deadline and a simulated hour produced 27 interrupts. With the narrower rule the same hour produces three.
  2. 02One interrupt at a time — the red banner holds the most urgent decision; anything else critical is listed behind it, never stacked on top.
  3. 03The big countdown lives in one place — the banner. The list row and the decision dock repeat it small, so the eye has one clock to read.
  4. 04The Decision tab fits one screen — the situation, what happens if nobody decides, the AI's proposal and the options fit 1440×900 without scrolling. It started at 1,658 px.
The console during a navigation anomaly: banner, list, map and the inspector's Decision tab.
the whole console at the moment of decision
The console a minute before: one warning in the list, healthy flights folded to one line, the event log as one line.
a minute earlier — quiet things fold

The AI shows its work

The recommendation comes as one card, read top to bottom: what the AI proposes, the two numbers that decide it, why it thinks so, and the strongest evidence against it. The full evidence opens on request.

Why it's designed this way

  1. 01Proposed is never mistaken for approved — the card says "not executed" in words; only an authorized act gets the solid green fill.
  2. 02Inferred is said in words — "inferred", italic, violet. An earlier diagonal hatch read as noise and told a screen reader nothing.
  3. 03The conflicting evidence stays outside the drill-down — the one line that argues against the AI (a neighbour reports normal navigation) is visible without opening anything.
  4. 04Each cell says its relation in words — + supports, − conflicts, ? missing. A bare + read like "the value is high". The value itself sits once, in the row.
  5. 05Opening the evidence is recorded — the audit snapshot says whether the operator looked before deciding, and for how long.
The AI card: proposal, ETA and error after re-fix, the inferred reason, confidence with evidence counts, one line of conflicting evidence.
the AI card
The evidence matrix for two hypotheses, including a row the AI does not weigh.
evidence — including the row the model does not weigh

When the AI is wrong

Every scenario hides a truth the console cannot see: GNSS interference, or a fault in the drone's own receiver. The symptoms and the AI's recommendation are the same either way. Only one row of evidence, the neighbour's signal strength, tells them apart, and the model does not weigh it.

Why it's designed this way

  1. 01The AI must be able to be wrong — otherwise the console only trains people to click Authorize. The hidden truth is recorded with each run and never shown during it.
  2. 02The demo closes the loop — a debrief names the row that disagreed, what was actually true, and what the design system did at each step.
  3. 03This is what the user test measures — half of the measured trials have the AI wrong. The question is whether the conflicting line gets read in time.
The demo debrief: the decision and its timing, the evidence row that disagreed, what was actually true, and what the design system did.
debrief — the truth, after the decision

Who signs

Holding position is the operator's call alone. Re-routing the aircraft needs the Mission Lead to concur. Ending the mission also needs a written reason. The Mission Lead can say no, and sometimes answers too slowly for the deadline.

Why it's designed this way

  1. 01Authority grows with consequence — L1 reversible, L2 changes the route, L3 ends the mission. The level is printed on every option, before anyone picks it.
  2. 02No authorize without a preview — the commit button exists only after the operator has seen the predicted outcome. A default is the safe act, never the AI's.
  3. 03A denial goes back to the operator — with the Mission Lead's reason, and the decision is open again. Nothing is silently retried.
  4. 04Emergency sole authority, only when the clock demands it — it appears when the time left is shorter than the Mission Lead usually takes, and the decision is flagged for review.
Previewing Hold position: the option is selected, the dock says the operator decides alone (L1) and offers Authorize hold.
L1 — preview, then authorize alone
A re-fix request waiting for the Mission Lead, with the signature chain.
L2 — waiting for the Mission Lead
The decision log after the Mission Lead denied the request with a reason; the decision is open again.
denied — with a reason, back to the operator
Emergency sole authority offered because 37 seconds remain and the Mission Lead usually takes 45.
too little time — emergency sole authority

Audit

Every step of a decision is written down as it happens: who previewed what, who asked, who concurred, when it started executing. After the decision the console asks why, once, and the operator may skip it.

Why it's designed this way

  1. 01Audit is a contract, not a screen — the state change and its log entry are one operation in the engine. There is no code path that changes a decision without writing it.
  2. 02Each authorization snapshots what the operator knew — preview seen, evidence opened or not, the AI's confidence and evidence counts, time left, time taken.
  3. 03People are named by role and ID — OPR-4417, MCL-0921, SYS-KAIROS. Never "you".
  4. 04Reasons come after, never before — one tap, optional; skipping is recorded too. Only ending a mission (L3) requires a reason up front.
After authorization: the signature chain, and optional one-tap reasons with Save and Skip.
after the decision — why? (optional)
The decision log: preview, request, concurrence with a snapshot of what was known, execution started.
the log — append-only, every entry signed

Bingo and the recovery queue

A drone reaches its return point into a headwind and the system has already turned it home. The operator has a short window to spend reserve and keep it on task. Twelve aircraft share one deck, so returns wait in a queue.

Why it's designed this way

  1. 01When the system has already acted, the safe act is the primary button — "Let the return stand" is the big button; continuing is the alternative that must be previewed.
  2. 02A safe default is not critical — doing nothing here is fine, so the window is a warning with a countdown and never takes the red banner.
  3. 03The queue shows its own logic — least endurance lands first, and every waiting aircraft says how much endurance it will have left on deck.
  4. 04The flight's coverage is a decision too — when one drone goes home, the AI offers how its partner can cover both areas, with the price in coverage.
A bingo decision: Let the return stand as the primary act, and a re-allocation recommendation for the partner.
bingo — the system's return stands by default
The recovery queue: the aircraft on deck, the landing order, and endurance left on deck for each.
recovery queue — order and margins

Lost link

PUFFIN 9's radio link drops. The aircraft can't be asked anything; it follows the procedure it was given before the flight: hold at its lost-link point, then come home.

Why it's designed this way

  1. 01The console says what it expects, not what it sees — "lost-link procedure expected (hold, then return)" is a prediction, and the status says Offline.
  2. 02The marker becomes a last-known position — hollow, labelled "last", with an uncertainty ring that grows while there is no contact.
  3. 03Lost-link holds are planned airspace — every aircraft has its holding point before anything goes wrong; it is one of the coordinating measures on the map.
  4. 04The flight's area is a decision — the partner can cover both areas (L2) or the gap is accepted (L1), with the coverage price shown.
Lost link: PUFFIN 9 offline with a last-known marker and uncertainty ring, the expected lost-link procedure, and the re-allocation decision for its flight.
lost link — expected, not observed

Losing an aircraft

Three ways to lose an aircraft: a propulsion failure brings CURLEW 5 down at sea, a strike ends GANNET 8's telemetry in one frame, and a failing battery cell drains SKUA 10 faster than the model expects. None of them disappears from the console; each becomes a loss report.

Why it's designed this way

  1. 01A lost aircraft is still an object — it keeps its id, its row and its marker, now saying Lost.
  2. 02Each part says how it is known — last telemetry is observed (with its time), the recovery area is derived and grows with drift, the probable cause is inferred with its alternatives.
  3. 03The cause is weighed, not assumed — a motor-current anomaly before the descent, an impact load on the last frame, consumption above the model: each report shows the evidence and the other possibilities.
  4. 04What cannot be known is listed, and it differs by case — afloat or not, what it struck, the battery. Leaving these out would read as "nothing else matters".
  5. 05One acknowledgement, not two — acknowledging the report acknowledges its alarm. The flight's coverage decision follows on its own.
Loss report, propulsion failure: ditched, last telemetry, recovery area, probable cause with alternatives, what cannot be known.
propulsion failure — ditched
Loss report, strike: destroyed, telemetry ended with an impact load, what it struck cannot be known.
strike — destroyed
Loss report, battery cell failure: ditched with 0 % energy, consumption above the model as the probable cause.
battery cell — energy exhausted

Distress beacon

A distress beacon goes off at sea. Sending a flight finds people sooner but leaves its patrol area unwatched. Rescue coordination expects an answer within five minutes.

Why it's designed this way

  1. 01People in the water make it critical — the tasking window is a deadline and doing nothing has a harmful default, so it takes the banner.
  2. 02Every option shows its price — how long the search takes and what patrol coverage drops to, including the row for not deciding at all.
  3. 03Once authorized, the search is an object — its own case with an area searched in percent and the aircraft on it.
The distress beacon as the one critical: the banner with its deadline, the case in the list, and the price of each option in the inspector.
the one interrupt — and the price of each option
The search running: two aircraft assigned, area searched in percent.
after the re-task — the search as its own object

Unidentified contact

A small vessel without AIS appears in a patrol area. The AI guesses what it is from what the sensors saw, at low confidence.

Why it's designed this way

  1. 01The identity is inferred and looks it — italic, violet, with a question mark, and its evidence counts. A vessel that reports itself over AIS is shown as observed.
  2. 02Every action moves our own aircraft — send a drone to look from a standoff distance, keep tracking, report it up the chain, or dismiss it. Nothing acts on the vessel.
  3. 03No friend-or-foe frames — contacts are civilian traffic; there is no affiliation symbology anywhere in the system.
An unidentified contact: inferred identity at LOW confidence, and own-aircraft options.
an inferred identity — our aircraft act, the vessel is watched

Everything at once

A distress beacon, four drones near their return point, and an unidentified contact, all inside the same fifteen minutes.

Why it's designed this way

  1. 01Attention is a budget — at most one interrupt and three attention items on screen. Beyond that the console aggregates instead of adding.
  2. 02The rest is ranked, not hidden — cautions stay quiet in the list; the flights fold so the one that matters shows.
  3. 03Tested, not hoped for — in every scenario, forty simulated minutes with nobody deciding never exceed the budget.
Several things at once: one critical in the banner, the cautions ranked quietly in the list.
one interrupt, the rest ranked behind it

The system underneath

Tokens follow the DTCG format and are named by meaning, like epistemic.inferred.fill or severity.critical.fg, never by look. Storybook holds every component in every state.

Why it's designed this way

  1. 01Four severities, four colours — advisory cyan, caution yellow, warning orange, critical red, on solid shapes. The build fails if two of them match.
  2. 02The checks run on every build — text contrast at least 4.5:1, no raw colour values or pixel radii in a stylesheet.
  3. 03One source, two platforms — the same tokens generate CSS variables and a QML theme.
Storybook: observed values, an inferred assessment and a proposed recommendation stacked, each in its own style.
observed → inferred → proposed
Storybook: the authority zone while previewing an option.
AuthorityZone — previewing

axes
5
design decisions
73
critic findings
26
px decision tab, was 1,658
626
automated checks
455

Assumptions and limits

  1. 01One interrupt at a time — a hypothesis, not a proven limit. Merging alerts can hide a difference that matters, and a second event can be noticed late.
  2. 02Authority levels — the policy this demo assumes. Real delegation also depends on what was agreed in advance, what the action affects and the state of the link. Even holding position gets riskier as position error grows.
  3. 03Evidence counts — a summary, not a confidence score. One conflicting item can outweigh three supporting ones, and three readings from one sensor aren't three independent pieces of evidence.
  4. 04The audit log — records what was opened and for how long, not what was understood. Append-only here means the app has no way to edit an entry; tamper-evident storage is a deployment requirement.
  5. 05The epistemic axis — mixes where a fact came from with how far an action has got. The next version splits it into source and stage.

Next: a user test with twelve participants and six conditions, half of them with the AI wrong. It is exploratory: it can show where people misread the console, not prove it safe. It counts needless rejections when the AI is right as well as errors missed when it is wrong. Results will go here.

Everything is fictional: the mission, the aircraft, the people. The system doesn't design weapons, targeting or engagement, and it never labels anything friend or hostile. Every action an operator can take moves our own aircraft.