OUAS

Validation Pipeline

The core security mechanism that guarantees AI agents can never break your application.

Overview

The most significant risk of allowing AI to mutate a User Interface is runtime instability. If an LLM hallucinates a non-existent component, passes a string into a number prop, or injects malicious <script> tags, traditional React applications will crash.

The OUAS Validation Pipeline sits entirely between the Agent and the UI Renderer. It acts as an impenetrable firewall, strictly parsing every incoming Layout Config against the Component Manifest.


The 3-Step Validation Process

When a Layout Config is submitted, the pipeline runs synchronously in the following order:

1. Component Reference Validation

The pipeline traverses the submitted layout tree. For every id found, it checks if that exact id exists in the Manifest. If an agent hallucinates a component (e.g., "id": "MagicButton"), the pipeline immediately halts and returns an E_UNKNOWN_COMPONENT error.

2. Prop Type & Schema Validation

For every resolved component, the pipeline extracts the submitted props and validates them against the JSON Schema defined in the Manifest.

  • Are all required props present?
  • Are strings actually strings?
  • Do enum values strictly match the allowed array of options?

3. Slot & Hierarchy Constraint Validation

Finally, the pipeline checks the structural integrity of the UI tree. If a component defines a slot that only accepts ["TaskCard"], and the agent attempts to render a ["Sidebar"] inside it, the pipeline rejects the mutation with an E_INVALID_CHILD error.


Deterministic Error Handling

Because OUAS is designed for autonomous agents, the Validation Pipeline does not just silently fail. It returns highly structured, deterministic error codes that the agent can read and use to self-correct in subsequent attempts.

validation-error.json
{
"valid": false,
"errors": [
  {
    "code": "E_INVALID_PROP_TYPE",
    "path": "payload.children[0].props.count",
    "message": "Expected type 'number' for prop 'count', received 'string'.",
    "context": {
      "expected": "number",
      "received": "string"
    }
  }
]
}

Was this helpful?