Welcome!

rngo helps you learn what your code does by simulating usage, recording everything and auditing the results.

In particular, rngo gives you

  • a specification language that describes a system's behavior
  • a CLI that verifies whether a specification holds for an instance of the system

The rngo specification language is declarative and intuitive - both you and your agent will find it easy to write. Here's an example spec:

key: my-blog
seed: 1
start: now - years(2)
end: now + minutes(5)
channels:
  db:
    type: stream
    command: sqlite3 db.sqlite
    format:
      type: sql
  api:
    format:
      type: template
      template: >-
        curl -sS -X {{data.method}} "${API_BASE_URL:-http://localhost:5173}{{{data.path}}}"
        {{#if data.body}}-H 'Content-Type: application/json' --data '{{json data.body}}'{{/if}}
    type: exec
effects:
  users.create:
    trigger: hz(100, day)
    end: now
    channel: db
    metadata:
      table: USERS
    generator:
      type: object
      properties:
        id:
          type: number
          minimum: 1
          scale: 0
          step: 1
        name:
          type: string
          pattern: .{2,64}
        email:
          type: function
          expression: "'user' + number + '@example.com'"
          variables:
            number:
              type: number
              minimum: 10000
              maximum: 99999
              scale: 0
  articles.post:
    trigger: hz(120, hour)
    start: now
    channel: api
    generator:
      type: object
      properties:
        path:
          type: constant
          value: /articles
        method:
          type: constant
          value: POST
        body:
          type: object
          properties:
            authorId:
              type: function
              expression: user.id
              variables:
                user:
                  type: reference
                  effect: users.create
            title:
              type: string
              format: .{0,100}
signals:
  api-minimum-title-length:
    type: sql
    query: >
      SELECT count(*) 
      FROM signals s
        JOIN effects e ON s.effect_id = e.id
      WHERE e.key = 'articles.post'
      AND length(e.value ->> '$.title') < 10
      AND s.data NOT LIKE '%422 Unprocessable Content%';
    expect: result == 0

You can use the rngo eval CLI command to verify that the spec holds for a running instance of my-blog, e.g.:

export API_BASE_URL=https://localhost:5000
rngo eval --spec spec.yml

This will produce output similar to:

Simulation
time: 2026-08-13 13:14:12
db: 73104 effects, 0 signals
api: 11 effects, 11 signals

Audit
api-minimum-title-length: 0 (passed)
1 passed

Next Step

Check out the quick start for a step-by-step guide to running your first spec in just a few minutes.