scema-tui 1.0.0

Scematica Omni TUI — the agent loop as a terminal console: observe a world, rank branches, seal and verify decision records.
scema-tui-1.0.0 is not a library.

scema-tui

The Scematica Omni console: the agent loop as a full-screen terminal application. Perceive a world, tick the signals that ground a goal, watch branches compete, read back the records that were sealed and whether their commitments still hold.

$ cargo install scema-tui
$ scema-tui                    # the current directory
$ scema-tui /path/to/project
$ scema-tui --once             # one pass as plain text, pipeable
$ scema-tui --snapshot 120x40  # one frame as text
$ scema-tui --palette          # what colour this terminal can actually carry

If you have scema-cli, scema tui finds this binary next to itself and hands over.

Five tabs

Answers
WORLD what is out there, and what could not be seen?
SIMULATE which branch wins, and does anything measured support it?
RECORDS what was decided, and does the record still verify?
MEMORY what has been retained, and how well did it project?
POLICY under whose preferences, and with which specialists?
  1·WORLD │ 2·SIMULATE │ 3·RECORDS │ 4·MEMORY │ 5·POLICY │        SCEMA OMNI scema-omni/0.1.0
  which branch wins, and does anything measured support it?                         ○ idle  .
────────────────────────────────────────────────────────────────────────────────────────────
┌ SIMULATION MATRIX  ·  NOT WRITTEN (would seal as c5ac7c5e) ───────────────────────────────┐
│ #   BRANCH                                GAIN   RISK   COST UNCERT REVERS  UTILITY  MEAS │
│▸  1 take: 11 marker(s) in `scema-tools`   0.22   0.40   0.10   0.00   0.70    0.125 ▰▰▰▰▰ │
│   2 give scema-cli tests                     —   0.40   0.10   0.00   0.70    0.093 ▰▰▰▰▱ │
│                                                                                           │
│ measured across the whole matrix: 35/35  (100%)   `—` = not measured; contributed nothing.│
└───────────────────────────────────────────────────────────────────────────────────────────┘

Black and violet, with soft blue for exactly one thing

Every other terminal surface in this repository has its own identity — the sniper dashboard is black and red, mesh-dashboard is indigo over slate, sdk-dashboard is the bond pipeline's green. Omni is black and violet, and that is not decoration: an operator with three of these open must be able to tell at a glance which one is making a claim about their money and which one about a decision record.

Violet specifically, because omni's whole subject is the boundary between measured and unmeasured, and that wants a palette where the interesting distinction is luminance first rather than hue first. A measured value glows; an unmeasured one recedes to a note in the same family. A red/green palette would put the emphasis on good-versus-bad, which is the wrong axis — a measured 0.00 risk and an unmeasured risk are not good and bad, they are known and unknown.

Azure appears in two places only: the branch that was chosen, and a commitment that verifies. Both are claims the agent made. An opportunity signal and a live provenance are observations and wear their own colours, because an accent that appears on every third row is not an accent, it is a second body colour.

Two rules, both mechanised

A renderer names a role, never a colour. theme.rs is the only file with a hex value in it; view.rs is the only file that maps a state to a role; render.rs places rectangles. Same split as alchem_link.theme and lib/mesh/view.ts::toneFor — a rule that encodes a claim about trust gets exactly one implementation.

Colour is decoration, never the message. NO_COLOR, a pipe, --no-color and a 16-colour terminal all produce the same text: for unmeasured, for chosen, LIVE/STALE/ABSENT for provenance, RISK/OPP /EST? for signals, EXCLUDED for a forbidden branch. A test walks every role in Depth::Mono and fails if one carries neither a modifier nor a word — a role whose entire identity is a hue disappears on a monochrome terminal, and that is a bug in the role.

--palette prints what the terminal negotiated, so an operator on an unfamiliar one can confirm that "measured" and "unmeasured" are actually distinguishable there before trusting a screen full of them.

The coverage meter is a count, not a bar

▰▰▰▱▱. One cell per term. A proportional bar renders 2/5 and 4/10 identically, and the denominator is the number that matters — a utility computed on two terms out of five and one computed on five out of five are different claims. Above twelve terms it falls back to the 30/90 label rather than to a proportional bar, for the same reason.

An empty coverage draws , never an empty meter. An empty container reads as "measured, and it is zero"; the true statement is "there was nothing here".

enter simulates. D decides.

Two keys, and a confirmation on the second.

simulate and decide compute exactly the same thing and differ only in whether they leave a trace. The only protection against a counterfactual later reading as a decision somebody made is that they are not the same keystroke — so the obvious button is the one that writes nothing, and sealing takes a capital letter and a yes.

Grounding is ticked, never inferred

The signal list is a multi-select, and what it selects is Goal::grounded_in. Nothing reads the goal text looking for a matching signal.

An earlier version of the CLI inferred grounding by keyword overlap and, on its first real run, grounded "add tests to the scema-cli crate" in a marker backlog in a different crate — because scema is a substring of every unit name in this workspace. The branch then inherited a measured expected gain from evidence that had nothing to do with it, which is exactly the laundering the simulator refuses to do on its own. A test pins that a goal naming a signal id verbatim still does not ground it.

--snapshot, and why a TUI needs one

$ scema-tui --snapshot 128x38

Draws one frame into an off-screen buffer and prints it as text. It exists because a TUI is otherwise untestable — its output is a terminal — so layout bugs are found by a human noticing a column is wrong, and ratatui's layout arithmetic underflows on small rectangles. The production failure mode is the console dying on somebody's 80-column terminal with a backtrace instead of a screen.

The crate's own tests draw every tab at four sizes and assert on the symbols, not the styles: everything here has to survive NO_COLOR anyway, so the text is what must be right, and a snapshot carrying escape sequences would churn on every palette tweak until nobody read it.

What it does not do

Act. The whole workspace ends at a decision and a record. A console that quietly gained a write path would invalidate the claim every other crate here makes about being safe to point at a live system.

Talk to a daemon. It holds no token and opens no socket; it drives the loop in-process against a local path. scema-omnid exists for the case where something remote needs to drive the loop, and folding that in would mean putting the whole pairing story on screen for no gain.

Why a separate crate

The same split mesh-dashboard / scematica-mesh makes in the bot workspace, and for the same reason: scema-agent is a library other people embed, and forcing ratatui and crossterm on a consumer that only wants the loop would be the mistake sdk-dashboard exists to avoid. The rendering lives here; the crates next door own the thinking.