i2y/ritsu/rulec
Claude Code and agent skill by i2y/ritsu
- community
Checking that the SKILL.md file is still in the repository.
Turn a table-shaped business rule into proved, dependency-free Python, TypeScript, JavaScript, Rust, Ruby, PHP, Go, Swift, Java, SQL and Wasm with rulec. Use when a shipping tariff, fee schedule, discount or coupon policy, eligibility test, period classification, or any rule that is already written as a table has to become code; when writing, editing or reviewing a `.rule` file; when a rulec diagnostic (E001-E076, E101-E140, W105, W110, W111, W114-W132, W901) has to be fixed; or when a change t…
Install
npx vskill@latest install i2y/ritsu/rulecSKILL.md
When this applies
The rule is a table, or could be written as one — a table plus, where it needs it, a little arithmetic over the inputs. Some are already tables: a tariff, a rate card, a fee schedule. Others are prose or folklore and become a table once written down: when a discount applies, whether a return is accepted, which period a date falls in, what rank a set of scores earns. The source of truth may be a spreadsheet, a published policy, a wiki page, a legacy implementation, or a person, and the job is to turn it into code someone can approve.
A process with state applies one call at a time: the table decides a step, and the caller keeps the state. It does not apply to running a workflow, to judgements about a collection ("any line is refrigerated", "three or more items"), to pattern matching on strings, or to scoring and optimisation. Flatten collection facts at the boundary and pass the scalar in; keep iteration in the caller.
Every command here is rulec's: run it as ritsu rulec <command> (through a link to ritsu named rulec, rulec <command> is the same). Whatever gen writes is held to the reference evaluator byte for byte by test. The files bundled with this skill are listed under §7: read them on demand. Every diagnostic is ritsu rulec explain <CODE>, always current, so none are bundled.
Working with rulec
You are the first user of this tool. It exists so that a business rule — a shipping tariff, a coupon policy, an eligibility test — can be written as one table, proved correct before anyone runs it, and turned into ordinary Python, TypeScript, JavaScript, Rust, Ruby, PHP, Go, Swift, Java, SQL and Wasm — or, for a host that decides whole columns at once, into NumPy: the rule as data beside one fixed evaluator.
Your job is the middle of that: take a source of truth (a published policy, a spreadsheet, a legacy implementation) and produce a .rule that passes rulec check, then generate the code and show a person what changed.
Two roles stay with people, and neither is yours:
- someone approves the table. Amounts, rounding directions, and which of two conflicting
readings is correct are business decisions. When you cannot derive an answer from the source, you ask — §6 says how.
- someone owns the application the generated function is called from.
Everything you need is reachable from the command line. rulec --help lists the commands, rulec <cmd> --help explains one, rulec explain <CODE> explains a diagnostic, and --format json gives you any of it as data. There is no step where you have to read rulec's source. Where you have no shell, rulec mcp serves the same commands as MCP tools over stdio — one tool per command, one argument per flag, the exit code at the end of every result — and this document and the references as resources.
1. The loop
Write
The grammar is reference.md, complete. The shortest useful summary: declare inputs and outputs with their units, write one table per decision, and let examples state a few cases you know the answer to.
Two declarations are mandatory and are where most first drafts fail:
- `range` on every numeric input and every `derive`. It is the universe the completeness
proof quantifies over, and the entry guard of the generated code. A rate may leave it out and is then 0% to 100%, guard included; a rate that can go above 100% declares its range.
- `round` on every numeric output, an optional one (
money[JPY]?) too. Without it the
generated code would settle fractions silently.
A few shapes are worth knowing before the first draft:
- Tables stack. A table's output column is a column of any later table, to any depth, and
one table may produce several output columns. That, plus a derive used as a column, is how a rule with interlocking conditions gets written — not by putting more into a cell.
- An output returns the binding of its own name — a
defineor a table output column
called fee is what the output fee returns. result is sugar for the first output only: naming a later one is E015, and a second result line is E016.
- An output may be `T?`: a row answers
nonefor no value, the others a value ofT. - An output may write a `range` after its `round`; one that leaves out an answer is E140.
- Combinations that cannot happen are said once.
constraint <input> <= <input>states a
relation the caller guarantees. Completeness then demands no row for what it excludes, every witness becomes a case somebody could really send, and the generated code refuses a violating input at the door (§6.1 of the grammar).
- A combination that is not a comparison is written out. `never has_tool = true, all_parts =
true says no call has all of these at once, each condition holding what a cell would, with | between the members of a set. It does what a constraint does. Over inputs read with from, or over summaries of elements, the line is held to the definitions: E142 with the request that gives the combination, E143 when it cannot be shown. A line that names an input with no from` is the caller's promise. A wrong shape is E141. Only written lines take a combination out of the tables: where E101 or W133 says the definitions never give one, the hint shows the line to write. A line that rules out nothing is W134.
- A case may carry a sequence. Where the number of things is not fixed — the rows of a tariff
sheet, the candidates a filter left — elements declares what one element carries and fold says what each verdict does next: next, stop with <value>, take_unique, take_first, keep_max <value> by <key>, plus the required empty and exhausted. The table that judges one element is checked exactly as any other table is, and an example names a sequence rather than holding one in a cell (§6.2). Every target but SQL and NumPy generates it.
- A `string` column takes a prefix and nothing else.
starts_with "CH-", "CL-"is the
one test it accepts (E110 for any other): the prefixes a column's own cells name cut the strings into finitely many classes, which is what keeps completeness decidable. Bytes, no case folding. Where the values can be listed, an enum says more.
- Counting the walk instead of folding it. `count <name>(<alias>) over <sequence> where
<column> = <value> ends the walk with a number rather than with the answer, and the rule goes on as usual — so what turns "how many matched" into a class is an ordinary table, and its boundaries are checked like any other (§6.3). The range is required: it is the universe the completeness check quantifies over **and** the cap on the sequence. sum <name>(<alias>) over <sequence> of <column> ends it with a total instead, over a column that cannot go negative, and max/min with the largest or the smallest. An average divides inside a rounding: half_up(total / max(n, 1), 1JPY)`. Folds and these mix freely, over any number of sequences; one item reading the elements of two sequences is E031.
- A field no two elements share.
building : building uniqueat the end of a field of
elements: the door refuses a sequence with two elements of one value of it, in every language. On an enum or a truth value it also caps a sum over the sequence at what each value adds once, and rulec check holds that to the sum's range, with the rows contributions add (E147). Write it where the caller really sends each value once — the buildings of a province, the members of a team — not to make E147 go away.
- Handing one amount out over several lines. `allocate(<amount>, <running total>,
<whole>) is <amount> × <running total> ÷ <whole> rounded down. Write one line's share as the share up to it minus the share up to the line before: the parts then add up to the amount exactly, odd yen included. Three names with declared ranges, nothing negative, a positive whole, and a constraint` that the running total never passes it — else E117.
- A process that goes on is decided one call at a time.
machine <name>(<alias>) over <table>
says which output the caller passes back as which input (carry), which inputs a case holds (held), where it starts and ends, and what no sequence of calls may do; check proves that over every sequence (E124–E127) with the shortest breaking one in witness.trace, and scenario is an example several calls long (§6.4); more carry lines carry numbers, flags or enums, held to always (E072, E134, E135). diff of two versions names the states a case could strand in.
- A main rule and its special case are two tables, or a table and a clause. Several tables may
define the same output, each transcribed from its own source, and the one that takes precedence says so with overrides <table> right after policy (overrides base:r3 for one labelled row). A row is labelled by a word before its first bar (r3 | … |), which is also how the trace names it. A proviso whose conditions do not line up as columns is a clause: when <column> <cell> and … (or when always), then <value>, and overrides — one row written as prose, checked and generated as a one-row table. The definitions of one output are checked together — completeness over their union, every overlap either ordered by an overrides line or reported (E105) — and doc says which is the exception (§7 of the grammar).
- A source is declared, cited and pinned. `source stamp_act = law "342AC0000000023" asof
2026-04-01 names a law on e-Gov and law ecfr "29 CFR 1910" one in the US eCFR. @stamp_act 別表第一 at the end of a table, clause, row, derive or define line says what it transcribes. rulec source fetch puts a copy of each cited fragment beside the rule and rulec source pin writes its digest; check then holds the rule to the copies (E037–E039, W119) without reading the network, and doc quotes the fragment under the definition. Any other document is source japanpost = file "…" sha256:…, with a url "…" so that fetch can bring it again and outdated can ask whether it moved on. **A document's fragments are its tables**: @japanpost table1 cites the first table in document order (a sheet, in a workbook), pinned, checked and quoted as a law's article is. The formats read are csv, md, xlsx and docx; for a PDF or a scan, fetch --via <cmd> runs an extractor as a child process and pins what it produced (rulec adapter <file.rule> --template docling` prints the shape). The rows are then held to that copy: an amount the copy does not show is E116, a number it states that no row uses is W120, and a boundary it puts on the other side of itself is E119 — the only checks that look outside the rule at all.
- A provision applied mutatis mutandis is an `apply`. `apply retirement = "retirement_pay.rule"
meaning:… uses another rule with every input bound (years = tenure, enums mapped with with term_end -> retirement_age), definitions left out with except reduction, and outputs taken under a name (allowance -> part_time_allowance). The callee is expanded into the rule under retirement:…, held to its meaning, comments aside (E040, rulec source pin writes it), and what is passed has to stay inside its ranges (E043). check and doc` show the applied
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/rulec/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/i2y/ritsu/rulec)