Live CortexUI Surface

This block renders live CortexUI contract metadata in the docs DOM so AI View can inspect real machine-readable elements instead of only code examples.

AI View can now inspect a live status region, form fields, actions, and table entities on every docs page.
AI-addressable docs entities
ItemState
Search docsReady
Inspect metadataVisible in AI View

Determinism vs Heuristics

There are two ways to build an AI agent that operates a web interface. The first is heuristic: teach the agent to guess intelligently. The second is deterministic: give the agent a contract it can rely on. These two approaches produce fundamentally different systems, with fundamentally different reliability profiles.

The Heuristic Approach

This is what AI agents do today when operating interfaces that were designed without machine operability in mind:

  1. Find a button that looks like it saves. Scan the DOM for elements that could be save actions. Look for buttons near forms. Look for buttons with labels containing "Save," "Submit," "Confirm," "Update." Weight them by visual prominence, position, and proximity to the form fields that need to be submitted.

  2. Decide the likely candidate. The button says "Save" — probably right. The button has class btn-primary — high confidence. The button is at the bottom of the form — consistent with submit pattern. Accept the candidate.

  3. Click it — hope for the best. Execute the click. The interaction is taken. Whatever happens next is the outcome.

  4. Check if something changed. Scan the DOM for evidence of success. Did a success toast appear? Did the URL change? Did the page re-render? If a spinner appeared and then disappeared, assume success. If the form fields are now non-editable, assume success. Apply heuristics to the outcome observation.

  5. Report success or failure. Based on the outcome heuristics, emit a result. If nothing clearly changed, report uncertainty or retry.

This process is sophisticated. Modern LLMs are quite good at it. In controlled conditions, on simple applications, it achieves high accuracy. The problem is not the AI's intelligence — it is the structural limitations of heuristic reasoning.

The Cost of Heuristics

Wrong buttons get clicked. The save button and the cancel button might both match the heuristics for "prominent button near a form." The agent picks one. If it picks wrong, the form is discarded instead of saved.

Success is misdetected. A spinner that disappears might mean the operation completed successfully, or it might mean the operation failed with an error that's displayed elsewhere, or it might mean the request timed out. The heuristic cannot distinguish these cases reliably.

Failure is missed. Validation errors displayed as inline text next to form fields — common in well-designed forms — may not match the agent's heuristic for "failure indicator." The agent reports success while the form remained invalid.

Retries cause double-submissions. When an agent cannot confirm success, it retries. If the first attempt actually succeeded, the retry submits twice. In e-commerce this means duplicate orders. In financial applications this means duplicate transactions. In any application with non-idempotent operations, retries have real consequences.

The agent degrades as UI changes. Every time the interface evolves — new button placement, new label copy, new visual treatment for success states — the heuristics that worked yesterday may fail today. The agent's reliability is inversely correlated with the rate of UI change. In active development environments, the agent becomes unreliable in direct proportion to how actively the product is being improved.

Warning

Heuristic agents are not a temporary problem that better AI models will solve. Even a perfect vision model is limited by what information is available in the visual representation. If the interface doesn't declare its state, no amount of intelligence can read state that isn't expressed. Determinism requires structured data, not just better models.

The Deterministic Approach

The same workflow, implemented against a CortexUI interface:

  1. Find [data-ai-action="save-profile"]. No inference required. The element with this attribute is the save-profile action. There is exactly one of them. The selector is stable across deployments, redesigns, and i18n changes.

  2. Check data-ai-state="idle". The element's current state is declared. idle means available. No visual inference about grayed-out colors or disabled appearances. The contract says the action is available; the action is available.

  3. Click it — it transitions to loading. The element's state updates as the operation proceeds. loading is a declared state, not inferred from spinner visibility. The agent knows the operation is in progress.

  4. The element transitions to success. The declared state confirms completion. Simultaneously, an action_completed event is emitted to the runtime event log.

  5. Check event log: action_completed with result: "success". Structured outcome confirmation. Not scraped from the DOM, not inferred from visual changes — explicitly emitted by the application as part of its contract.

Heuristic                         Deterministic
─────────────────────────────────────────────────────────────────
"Find the Save button"            [data-ai-action="save-profile"]
"It says Save, probably right"    Contract is explicit, no inference
"Check if it's clickable"         data-ai-state="idle"
"Click it, hope for the best"     Click it, observe state transition
"Spinner disappeared = success?"  data-ai-state="success"
"Look for success message"        action_completed { result: "success" }
"Retry if uncertain"              Certainty is structural, no retry needed

No ambiguity at any step. The agent is not guessing — it is reading a contract.

The Type System Parallel

This distinction maps precisely onto a debate that the programming languages community resolved decades ago: dynamic typing versus static typing.

Dynamic typing works in many cases. Python and JavaScript are hugely successful. But they produce a class of errors that only appear at runtime, often in production, when the wrong type of value reaches a function that cannot handle it. The error is not detected until the moment of failure.

Static typing makes contracts explicit. The type system catches mismatches before the code runs. A function that expects a string cannot receive an integer without the compiler flagging it. The contract is verified continuously, not just at the moment of failure.

Dynamic typing works until it doesn't. Type systems make contracts explicit. data-ai-* is type-checking for UI interactions.

The heuristic approach to AI-UI interaction is dynamic typing: it works most of the time, fails in unpredictable ways, and the failures are hard to detect systematically. The deterministic approach is static typing: the contract is declared, the agent reads the contract, the interaction is verified at every step.

This is not a performance argument — heuristic approaches are often computationally expensive relative to deterministic ones. It is a reliability argument. Deterministic systems fail loudly and predictably when they fail. Heuristic systems fail quietly and unpredictably, which is the worst failure mode in automated systems operating on behalf of users.

Note

The analogy extends to tooling. Type systems enable IDEs to provide autocomplete, catch errors before runtime, and support safe refactoring. Machine-readable UI contracts enable agents to enumerate available actions, verify preconditions before acting, and confirm outcomes without DOM scraping — the same class of tooling benefit applied to UI interaction.

When Determinism Is Not Possible

CortexUI acknowledges that not every interface can be fully contracted immediately. Legacy codebases, third-party components, and incrementally migrated applications will have sections that lack machine-readable contracts. For these cases, heuristic approaches remain a fallback.

But the goal is to shrink the footprint of heuristic reasoning over time, not to accept it as a permanent baseline. Every component that gains a data-ai-action attribute removes one source of inference from the agent's workflow. Every form that gains data-ai-field-type attributes removes one source of guess. Every state that gains data-ai-state removes one visual heuristic.

The transition from heuristic to deterministic is incremental. The benefit is not binary — it accumulates with every element that is brought into the contract. Even a partially contracted interface is more reliable than a fully heuristic one.

The Reliability Guarantee

The core promise of the deterministic approach is a reliability guarantee that heuristic approaches cannot offer: if the contract is correct, the agent will always act correctly, regardless of how the visual interface changes.

The visual design can evolve freely. Button colors, layouts, labels, component implementations — all of these can change without any impact on agent reliability, as long as the data-ai-* attributes are preserved. The agent is coupled to the contract, not to the appearance.

This is the same guarantee that a stable API provides: the interface can be reimplemented, optimized, and extended, but as long as the contract is honored, all existing consumers continue to work. Determinism makes UI as stable as an API, for the operators that rely on it.