Skip to content
Back to skills

Renyi

ASecurity

Write, check, format, test and run Renyi programs (files ending in .ry). Renyi is the scripting language for AI agents; a program's effects are declared in its signatures, checked before it runs, limited while it runs and recorded as it runs. Use whenever a task writes or changes a .ry file or automates something in Renyi.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 14, 2026
ai-agentspythonsqlapi

Works with

  • api
  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 14, 2026

npx -y skills add renyi-lang/renyi --skill renyi --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Renyi?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Renyi
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/renyi-lang-renyi/badge)](https://www.skillsdirectory.com/skills/renyi-lang-renyi)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: renyi
description: Write, check, format, test and run Renyi programs (files ending in .ry). Renyi is the scripting language for AI agents; a program's effects are declared in its signatures, checked before it runs, limited while it runs and recorded as it runs. Use whenever a task writes or changes a .ry file or automates something in Renyi.
---

# Renyi

Read `cheatsheet.md` beside this file before writing a line of Renyi:
it is the whole language on one page and the authority on its spelling.
When the `renyi` MCP server is connected, `cheat_sheet` is the same
page and `library_lookup` finds a library declaration by name or by a
few words; look a function up before calling it, so that its name and
its arguments are not invented.

## The loop

1. Write one module per file: `module <name>` with a `purpose:` line,
   the imports, the types, the functions, and `main` last with the
   `needs` line that declares every effect the program may have.
2. `renyi check <file>`: every diagnostic carries a `fix:` line; apply
   it. The exit code is 1 while an error remains.
3. `renyi format <file>`: the canonical layout, the only one.
4. `renyi test <file>`: every `example:` line and every `test` block.
5. `renyi run <file> [arguments]`: `main`, under the grant its `needs`
   line declares; exit 1 when it fails, 2 on a crash.

A function with effects is tested through a recording: write a `test`
whose head carries `needs` and `replays "fixtures/<name>.json"`, run it
once live with `renyi test --refresh "<test name>" <file>`, and keep the
file it writes beside the program; from then on `renyi test` answers the
test's calls from it and touches nothing outside the process.

## What the checker refuses that other languages allow

Each rule is an error with a fix in the diagnostic; the code is in
parentheses.

- A module and every public function carry a `purpose:` line, in prose
  (`purpose-missing`). Write one on every type too.
- A value name is lower snake case and at least two characters
  (`single-letter-identifier`), and is not one of the 88 reserved words
  (`reserved-word`; reference section 17). The ones that bite as names:
  `sum`, `count`, `first`, `at`, `to`, `in`, `by`, `with`, `within`,
  `tags`, `all`, `any`, `one`, `most`, `least`, `run`, `self`, `some`,
  `type`, `group` and `power`; after a dot they are fine
  (`items.first()`).
- A call with one argument names nothing; a call with two or more names
  every argument, in declaration order (`argument-name`,
  `argument-order`): `recent_commits(directory: here, limit: 50)`.
- Every binding is read (`unused-binding`): a `let`, a parameter, a loop
  variable or a pattern binding that is never used is an error. A name
  is bound once per function (`shadowing`): no reuse of a name.
- A call whose result is not used is an error (`unused-result`); the
  usual fix is `change items to items.append(item)`. `ignore` discards
  the result of a call that has effects.
- Both operands of an arithmetic operator have one numeric type
  (`type-mismatch`), and `/` does not divide two `Integer`s
  (`integer-division`): `dividend.quotient(divisor)` and
  `dividend.remainder(divisor)`.
- A call that can fail or answer `nothing` is read with `otherwise` or
  matched with `success` and `failure` (`missing-otherwise`); there are
  no exceptions. `otherwise fail` on a `maybe` value has no error to pass
  on (`otherwise-fail-maybe`): give a default, `otherwise fail with
  <Error>(...)`, `otherwise return`, `otherwise continue` or `otherwise
  crash with "<reason>"`.
- The `otherwise` that guards a value stays on the line of that value
  (`otherwise-line`); a long statement breaks inside parentheses
  instead, and `renyi format` does the breaking.
- `example:` lines belong to pure functions only (`example-effects`);
  `check` belongs in a `test` block (`check-outside-test`).
- Every capability a body uses, directly or through a call, is in the
  function's `needs` (`capability-missing`); a test's `needs` covers its
  body likewise. A budget is `at most <n> per second|minute|hour|day|run`
  after the capability: `network.http("api.example.com") at most 60 per
  minute`.
- A line is at most 100 columns (`line-width`, a warning); no tabs, no
  carriage returns (`tab`, `crlf`); `renyi format` wraps inside
  parentheses, and a `purpose:` line is shortened by hand.
- An empty list literal names its type: `let mutable items: List of
  Item be []`. A record decodes from JSON with `can FromJson` and
  encodes with `can ToJson`. A library type is imported by name:
  `import std.filesystem exposing Path, FileError`; the module's
  functions are called qualified: `filesystem.read_text(path)`.
- There is no `=`, no `==`, no `null` and no anonymous function
  (`equals-sign`, `symbolic-operator`): `let total be 0`, `is`,
  `nothing`, a named function passed by name.

## A module

```
module log_triage
  purpose: Rank the error codes of a log file by how often they fired.

import std.console
import std.environment
import std.filesystem exposing Path, FileError

public type Entry
  purpose: One ERROR line: its timestamp, its code and its message.
  has timestamp: Text
  has code: Text
  has message: Text
end

public function parse_error(line: Text) returns maybe Entry
  purpose: The entry of a line "timestamp ERROR code message"; nothing for any other line.
  example: parse_error("2026-10-07T10:00:00 INFO started") is nothing

  let words be line.split(" ")
  if words.length() is less than 4 then return nothing end
  let level be words.at(1) otherwise return nothing
  if level is not "ERROR" then return nothing end
  let timestamp be words.at(0) otherwise return nothing
  let code be words.at(2) otherwise return nothing
  return Entry(timestamp: timestamp, code: code, message: words.drop(3).join(" "))
end

public function main() or fails with FileError needs console, environment, filesystem.read("data")
  purpose: Print every error entry of the log named by the argument (data/app.log).

  let arguments be environment.arguments()
  let name be arguments.at(0) otherwise "data/app.log"
  let text be filesystem.read_text(Path(name)) otherwise fail
  for each line in text.lines()
    let entry be parse_error(line) otherwise continue
    console.print("{entry.code}: {entry.message}")
  end
end
```

## The commands

| Command | What it does |
|---------|--------------|
| `renyi check [--json] [--strict] <file>...` | the diagnostics, each with its fix; exit 1 on an error |
| `renyi format [--check] <file>...` | the canonical layout; `--check` only reports |
| `renyi test [--strict] [--refresh <name>] [--explain] <file>...` | every example and test; `--refresh` records one test live |
| `renyi run [options] <file> [arguments]` | `main` under its grant; `--explain` narrates, `--manifest` prints the run manifest, `--replay <recording>` answers every effect from a recording |
| `renyi record [--to <file>] <file> [arguments]` | `main`, with every effect's arguments and result written to a recording |
| `renyi reproduce <recording>` | the same run from the recording, the outcome and the output compared byte for byte |
| `renyi index [--json] [--budgets] [--chunks [--language]] [path]` | the project map: every definition with its effects, failures and metrics; `--chunks` the map as chunks for retrieval by embedding (JSON Lines), `--language` the language's documents and library the same way |
| `renyi tools <file>` | the manifest of every function marked `expose as tool`, as JSON Schema |
| `renyi mcp [path]` | the same answers over the Model Context Protocol |

The standard library modules are `console`, `csv`, `environment`,
`filesystem`, `foreign`, `http`, `json`, `process`, `python`, `random`,
`regex`, `screen`, `server`, `sqlite` and `time`, each under `std.`; the prelude's types,
`Text`, `Integer`, `Decimal`, `Float`, `Boolean`, `Bytes`, `List of`,
`Map of ... to`, `Set of`, `Pair of`, `Range`, `Duration` and `maybe`,
need no import.

Files in this skill

  • SKILL.md7.8 KB
  • cheatsheet.md11.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.