Compliance

RAIS Compliance

Verify that any server is RAIS Protocol v1 compliant using the rais-compliance CLI.

Run compliance tests

npx rais-compliance http://localhost:3001/api/chat

Don't have a server yet? Start the built-in mock server:

npx rais-compliance serve
# → http://localhost:3001/api/chat
 
# Then in another terminal:
npx rais-compliance http://localhost:3001/api/chat

Example output:

RAIS Protocol v1 Compliance Test
Endpoint: http://localhost:3001/api/chat

  MUST (normative)
    headers.content-type           ✓ Content-Type is text/event-stream
    headers.cache-control          ✓ Cache-Control: no-cache present
    events.format                  ✓ All 12 data lines are valid JSON
    events.text-type               ✓ All 10 text events have a "text" string field
    events.done                    ✓ Exactly one done event, last in stream
    events.no-after-done           ✓ No events emitted after done
    events.has-text-tokens         ✓ Received 10 text token(s)

  SHOULD (recommended)
    headers.accel-buffering        ⚠ X-Accel-Buffering header not set
    events.sse-id                  ⚠ No id: fields — add SSE event IDs for reconnect safety

  ⚠  2 warned · 7 passed

  RAIS v1 Core compliant (warnings present)
  Fix warnings to reach RAIS v1 Recommended

Custom test messages

npx rais-compliance http://localhost:3001/api/chat \
  --messages '[{"role":"user","content":"Respond with one sentence."}]'

Certification levels

LevelCriteria
RAIS v1 CoreAll MUST tests pass
RAIS v1 RecommendedAll MUST + SHOULD tests pass
RAIS v1 FullRecommended + reconnect support (id: + Last-Event-ID)

What gets tested

MUST (failures block certification)

TestWhat it checks
headers.content-typeResponse has Content-Type: text/event-stream
headers.cache-controlResponse has Cache-Control: no-cache
events.formatEvery data: line is valid JSON
events.text-typeEvery text event has a text string field
events.doneStream ends with exactly one done event
events.no-after-doneNo events emitted after done
events.has-text-tokensAt least one text token received

SHOULD (warnings only)

TestWhat it checks
headers.accel-bufferingX-Accel-Buffering: no is set (nginx proxy safety)
events.sse-idEvents have id: fields for reconnect support

Fixing common failures

⚠️

Missing Content-Type: text/event-stream — Set this header before writing any response body. In Express: res.setHeader('Content-Type', 'text/event-stream'). In Next.js: include it in the Response headers.

⚠️

No done event — Your server must emit data: {"type":"done"}\n\n when the LLM finishes. Without it, clients wait forever for a stream that is already complete.

X-Accel-Buffering warning — Only needed when running behind nginx. Add X-Accel-Buffering: no to prevent nginx from buffering the SSE stream. Without it, nginx may hold events until its buffer fills.

Mock server scenarios

Use the built-in mock server to test specific edge cases:

npx rais-compliance serve --scenario slow       # 200ms between tokens — test buffer logic
npx rais-compliance serve --scenario error      # partial stream then error event
npx rais-compliance serve --scenario malformed  # non-JSON lines + unknown event types
npx rais-compliance serve --scenario chunked    # events split across network writes
npx rais-compliance serve --scenario no-done    # intentional compliance failure — no done event
npx rais-compliance serve --port 4000           # custom port
ScenarioExpected result
normalRAIS v1 Recommended
slowAll MUST pass
errorAll MUST pass — error terminates stream correctly
malformedAll MUST pass — malformed lines skipped gracefully
chunkedAll MUST pass — buffer logic correct
no-doneevents.done FAILS — intentional

Full compliance checklist

The complete normative checklist is in rais-spec/COMPLIANCE.md (opens in a new tab).

The formal specification is in rais-spec/SPEC.md (opens in a new tab).