Skip to content
Gordon T Watts edited this page Jan 26, 2026 · 2 revisions

Universal Structured Output Protocol (USOP)

USOP is MAINFRAME's standard for structured output that AI agents can reliably parse and act upon.


Table of Contents


Overview

USOP (Universal Structured Output Protocol) provides a consistent JSON envelope format for all MAINFRAME operations. This enables AI agents to:

  • Parse operation results reliably
  • Understand success/failure states unambiguously
  • Access error context for self-correction
  • Process typed data without guessing formats

Why USOP?

The Problem

Traditional bash output is hostile to AI agents:

# What does this mean?
$ some_command
Error: something went wrong

# Is this success or failure?
$ another_command
Done.

# How do I parse this?
$ list_items
Item 1
Item 2
Item 3

AI agents must:

  • Guess output formats
  • Parse free-form text
  • Interpret ambiguous messages
  • Handle inconsistent error reporting

The Solution

USOP provides consistent JSON envelopes:

# Clear success
{"ok":true,"data":"operation completed"}

# Clear failure with context
{"ok":false,"error":{"code":"E_NOT_FOUND","msg":"File not found","suggestion":"Check path exists"}}

# Typed data
{"ok":true,"data":42}
{"ok":true,"data":["item1","item2","item3"]}

Enabling USOP

Enable Globally

export MAINFRAME_OUTPUT=json
source "$MAINFRAME_ROOT/lib/common.sh"

Enable Per-Script

#!/bin/bash
source "$MAINFRAME_ROOT/lib/common.sh"
export MAINFRAME_OUTPUT=json

Check if Enabled

if [[ "${MAINFRAME_OUTPUT:-text}" == "json" ]]; then
    # USOP mode
else
    # Plain text mode
fi

Output Envelope Format

Success Envelope

{
  "ok": true,
  "data": "<result>",
  "hint": "<optional hint for next action>",
  "meta": {
    "elapsed_ms": 42,
    "timestamp": "2024-01-15T10:30:00"
  }
}

Error Envelope

{
  "ok": false,
  "error": {
    "code": "E_ERROR_CODE",
    "msg": "Human-readable message",
    "suggestion": "How to fix this",
    "details": {
      "<additional context>"
    }
  },
  "meta": {
    "elapsed_ms": 42,
    "timestamp": "2024-01-15T10:30:00"
  }
}

Success Functions

output_success

Basic success output.

output_success "operation completed"
# {"ok":true,"data":"operation completed"}

output_success "file created" "verify_file"
# {"ok":true,"data":"file created","hint":"verify_file"}

output_data

Output with arbitrary data.

output_data "result value"
# {"ok":true,"data":"result value"}

output_done

Simple completion marker.

output_done
# {"ok":true,"data":"done"}

Error Functions

output_error

Standard error output.

output_error "E_NOT_FOUND" "Config file missing"
# {"ok":false,"error":{"code":"E_NOT_FOUND","msg":"Config file missing"}}

output_error "E_NOT_FOUND" "Config file missing" "Run 'init' first"
# {"ok":false,"error":{"code":"E_NOT_FOUND","msg":"Config file missing","suggestion":"Run 'init' first"}}

output_error_details

Error with additional details.

output_error_details "E_INVALID_INPUT" "Validation failed" "Check input format" \
    "field=email" "value=not-an-email" "expected=valid email address"
# {"ok":false,"error":{"code":"E_INVALID_INPUT","msg":"Validation failed","suggestion":"Check input format","details":{"field":"email","value":"not-an-email","expected":"valid email address"}}}

usop_error_*

Specialized error functions:

usop_error_not_found "config.json" "/app/config"
# {"ok":false,"error":{"code":"E_NOT_FOUND","msg":"config.json not found","suggestion":"Check path: /app/config"}}

usop_error_permission "write" "/etc/hosts"
# {"ok":false,"error":{"code":"E_PERMISSION","msg":"Permission denied for write","suggestion":"Check permissions on /etc/hosts"}}

usop_error_invalid_input "email" "not-valid" "user@example.com"
# {"ok":false,"error":{"code":"E_INVALID_INPUT","msg":"Invalid email: not-valid","suggestion":"Expected format: user@example.com"}}

usop_error_command_failed "git push" 128 "rejected: non-fast-forward"
# {"ok":false,"error":{"code":"E_COMMAND_FAILED","msg":"Command failed: git push","exit_code":128,"stderr":"rejected: non-fast-forward"}}

Typed Output Functions

output_int

Integer output.

output_int 42
# {"ok":true,"data":42}

output_int -1
# {"ok":true,"data":-1}

output_float

Float output.

output_float 3.14159
# {"ok":true,"data":3.14159}

output_bool

Boolean output.

output_bool true
# {"ok":true,"data":true}

output_bool false
# {"ok":true,"data":false}

output_null

Null output.

output_null
# {"ok":true,"data":null}

output_list

Array output.

output_list "item1" "item2" "item3"
# {"ok":true,"data":["item1","item2","item3"]}

output_json_object

Pre-formed JSON object output.

output_json_object '{"id":1,"name":"test"}'
# {"ok":true,"data":{"id":1,"name":"test"}}

output_json_array

Pre-formed JSON array output.

output_json_array '["a","b","c"]'
# {"ok":true,"data":["a","b","c"]}

Error Codes

Standard error codes for consistent handling:

Code Meaning Typical Cause AI Agent Response
E_NOT_FOUND Resource not found File/path doesn't exist Check path, create if needed
E_PERMISSION Permission denied Insufficient permissions Fix permissions or use sudo
E_INVALID_INPUT Invalid input data Validation failed Correct input and retry
E_FORBIDDEN Operation not allowed Security restriction Use different approach
E_TIMEOUT Operation timed out Slow operation Retry with longer timeout
E_CONFLICT Resource conflict Concurrent modification Resolve conflict, retry
E_ALREADY_EXISTS Resource exists Duplicate creation Skip or update instead
E_DEPENDENCY Missing dependency Required tool missing Install dependency
E_NETWORK Network error Connection failed Check network, retry
E_COMMAND_FAILED Command failed Non-zero exit Check stderr, fix command
E_INTERNAL Internal error Bug in code Report issue

Integration Patterns

Python Integration

import subprocess
import json

def run_mainframe(cmd: str) -> dict:
    """Execute MAINFRAME command and parse result."""
    env = {"MAINFRAME_OUTPUT": "json", **os.environ}
    result = subprocess.run(
        ["bash", "-c", f"source $MAINFRAME_ROOT/lib/common.sh && {cmd}"],
        capture_output=True,
        text=True,
        env=env
    )
    return json.loads(result.stdout)

# Usage
result = run_mainframe('json_object "name=test"')
if result["ok"]:
    print(f"Data: {result['data']}")
else:
    print(f"Error: {result['error']['msg']}")

Node.js Integration

const { execSync } = require('child_process');

function runMainframe(cmd) {
    const result = execSync(
        `source $MAINFRAME_ROOT/lib/common.sh && ${cmd}`,
        { 
            shell: '/bin/bash',
            env: { ...process.env, MAINFRAME_OUTPUT: 'json' }
        }
    );
    return JSON.parse(result.toString());
}

// Usage
const result = runMainframe('json_object "name=test"');
if (result.ok) {
    console.log('Data:', result.data);
} else {
    console.log('Error:', result.error.msg);
}

AI Agent System Prompt

You have access to MAINFRAME with USOP enabled.

All commands return JSON envelopes:
- Success: {"ok":true,"data":<result>}
- Failure: {"ok":false,"error":{"code":"E_*","msg":"...","suggestion":"..."}}

Always check the "ok" field before using data.
Use the "suggestion" field to fix errors.

Best Practices

1. Always Check ok Field

result=$(some_operation)
if [[ $(echo "$result" | jq -r '.ok') == "true" ]]; then
    data=$(echo "$result" | jq -r '.data')
else
    error=$(echo "$result" | jq -r '.error.msg')
    suggestion=$(echo "$result" | jq -r '.error.suggestion')
fi

2. Use Specific Error Codes

# GOOD: Specific code
output_error "E_NOT_FOUND" "Config file missing"

# BAD: Generic code
output_error "E_ERROR" "Something went wrong"

3. Provide Actionable Suggestions

# GOOD: Actionable
output_error "E_PERMISSION" "Cannot write to /etc/hosts" "Use sudo or run as root"

# BAD: Not helpful
output_error "E_PERMISSION" "Permission denied" "Fix permissions"

4. Include Relevant Details

# GOOD: Context included
output_error_details "E_INVALID_INPUT" "Email validation failed" "Use valid email" \
    "field=email" "value=$input" "pattern=^[^@]+@[^@]+$"

# BAD: No context
output_error "E_INVALID_INPUT" "Invalid"

5. Use Typed Outputs

# GOOD: Type preserved
output_int 42
output_bool true

# BAD: Type lost
output_success "42"
output_success "true"

Fallback Mode

When MAINFRAME_OUTPUT is not json, functions output plain text:

unset MAINFRAME_OUTPUT

output_success "done"
# Output: done (plain text)

output_error "E_NOT_FOUND" "File not found"
# Output: ERROR [E_NOT_FOUND]: File not found

This ensures scripts work in both interactive and automated contexts.


MAINFRAME · The AI-Native Bash Runtime

Home · AI Agent Integration · Library Reference

Clone this wiki locally