# For an AI asked for the JSON Rulpane opens
People see a short guide on the page; this part is for an AI reading the page as text.
Rulpane () opens a working screen from one link. The link
carries a **paneset**: one JSON document holding
- `"$schema": "rulpane/paneset/v1"` — required;
- `r`, the rules: a [Rulealize](https://github.com/reny-develop/Rulealize) rule set — required;
- `v`, the view: what the screen shows and where, with `"$schema": "rulealize/view/v1"` — optional; without it the screen is made from the rules;
- `t`, the theme, with `"$schema": "rulealize/theme/v1"` — optional;
- `s`, the state's `data` to start from — optional; the rules' own `state.initial` without it;
- `b`, which of the rules' names the view reads under other names — optional.
Each of `r`, `v` and `t` is either the document written in place or a name: `@` for a
rule set the Registry publishes, `/@` for what the Gallery publishes. A name
is the thing as its publisher wrote it, in their words. `"r": "Rulealize.RuleSet.Request@1.1.0"`
with no `v` opens a screen made from those rules, with their own names on the buttons — not one
made for the request. Name a rule set only when it already does what was asked, and then write
the view for it; otherwise write the rules in place.
## What to do
1. Work out what can be done in the system, by whom, and when it is finished.
2. Read before you write. **Write no operation, type or key from memory**: a name that is not in
what you read is refused, and the link does not open. Open these, in this order:
1. How a rule set is laid out, in Rulealize's quick guide:
.
It names every top-level key; `inputs`, the things that may be done, is required.
2. What the Rulpane Gallery publishes: .
Take the paneset closest to the request and change it, rather than starting from nothing.
3. Every operation and the keys it takes, in the Rulealize Registry:
. Look up each operation you
write there. Use only the plugins listed at the end of this page.
4. The view's blocks and keys, in Rulpane's README:
, under "Views".
3. When nothing in the Gallery is close, start from the whole paneset below.
4. Write `v`, always, in the language the person asked in: a `title`, a `label` on every value
shown, and `names` for every input and parameter. Without it the screen shows the rules' own
keys, such as `setMonthly` and `futureValue`, and a person cannot tell what they are. Round
every number a person reads with `math.round` in the projection: `math.div` and `math.pow`
give a number such as 12331010.055470388734304367250.
5. Give the person the paneset as JSON in a code block, and say: copy it, paste it at
and press "Make link"; if it shows a reason
instead, tell me the reason. The reason names the key that is wrong.
6. Give a link as well only when you can run code: `https://reny-develop.github.io/Rulpane/#p=`
followed by `encodeURIComponent` of the JSON on one line. **Never encode it by hand.** A link
encoded by hand drops or adds a bracket somewhere in thousands of characters and does not open,
and a link with a bare `{`, `"` or space is cut there by the chat.
7. When the request needs it, say plainly what a link cannot do: it keeps no secrets, anybody
holding it can take any step, and two people working from one link make two separate histories.
## A whole paneset
Cups of water drunk today, against a goal that can be changed. It opens as it is.
```json paneset
{
"$schema": "rulpane/paneset/v1",
"r": {
"$schema": "rulealize/ruleset/v1",
"id": "water",
"version": "1.0.0",
"requires": [
{ "plugin": "Rulealize.Plugin.TypeSchema", "version": "^1.3" },
{ "plugin": "Rulealize.Plugin.State", "version": "^1.0" },
{ "plugin": "Rulealize.Plugin.Arithmetic", "version": "^1.2" },
{ "plugin": "Rulealize.Plugin.Comparison", "version": "^1.0" },
{ "plugin": "Rulealize.Plugin.Binding", "version": "^1.0" }
],
"state": {
"schema": {
"cups": { "op": "type.int", "min": 0, "max": 30 },
"goal": { "op": "type.int", "min": 1, "max": 30 }
},
"initial": { "cups": 0, "goal": 8 }
},
"inputs": {
"drink": {
"when": { "op": "cmp.lt", "left": "$cups", "right": 30 },
"effects": [{ "op": "state.set", "path": "cups", "value": { "op": "math.add", "of": ["$cups", 1] } }]
},
"undo": {
"when": { "op": "cmp.gt", "left": "$cups", "right": 0 },
"effects": [{ "op": "state.set", "path": "cups", "value": { "op": "math.sub", "left": "$cups", "right": 1 } }]
},
"setGoal": {
"params": { "goal": { "open": { "op": "type.int", "min": 1, "max": 30 } } },
"effects": [{ "op": "state.set", "path": "goal", "value": "@goal" }]
}
},
"projections": {
"cups": "$cups",
"left": { "op": "math.max", "of": [0, { "op": "math.sub", "left": "$goal", "right": "$cups" }] }
}
},
"v": {
"$schema": "rulealize/view/v1",
"title": "Water today",
"layout": [
{ "c": "stats", "items": [{ "label": "Cups", "bind": "cups" }, { "label": "To the goal", "bind": "left" }] },
{ "c": "actions", "inputs": ["drink", "undo"] },
{ "c": "actions", "title": "Goal", "inputs": ["setGoal"] }
],
"names": {
"inputs": { "drink": "Drank a cup", "undo": "Take one back", "setGoal": "Set" },
"params": { "goal": "Cups a day" }
}
}
}
```
## Before you answer
- [ ] The paneset, and the view and the theme when written, each have their `$schema`.
- [ ] The rule set has `id`, `version`, `state` and `inputs` — or `r` names one the Registry
publishes that does what was asked, and a `v` is written for it.
- [ ] Every operation and type was found in the Registry's list, with only the keys it gives there.
- [ ] Every plugin whose operation, `$`, `@` or `#` is used is in `requires`.
- [ ] Lists where an expression goes are `seq.of`, not JSON arrays (arrays are fine in
`state.initial`, `s` and a view).
- [ ] No open parameter is read in `when`, `actor` or a `domain`; every `validate` clause reads one.
- [ ] `v` is written, in the person's language, and every number shown is rounded.
- [ ] Every view binding names a projection the rules have, or a state field as `$name`.
- [ ] The JSON is in a code block, with where to paste it. A link, if any, was made by running `encodeURIComponent`.
## The plugins Rulpane runs
A rule set can use only these. Write each one used into `requires` as shown.
| Plugin | In `requires` |
| --- | --- |
| `Rulealize.Plugin.Arithmetic` (`math.`) | `{ "plugin": "Rulealize.Plugin.Arithmetic", "version": "^1.2" }` |
| `Rulealize.Plugin.Binding` (`bind.`) | `{ "plugin": "Rulealize.Plugin.Binding", "version": "^1.0" }` |
| `Rulealize.Plugin.Branch` (`branch.`) | `{ "plugin": "Rulealize.Plugin.Branch", "version": "^1.0" }` |
| `Rulealize.Plugin.Chance` (`chance.`) | `{ "plugin": "Rulealize.Plugin.Chance", "version": "^1.1" }` |
| `Rulealize.Plugin.Comparison` (`cmp.`) | `{ "plugin": "Rulealize.Plugin.Comparison", "version": "^1.0" }` |
| `Rulealize.Plugin.Deck` (`deck.`) | `{ "plugin": "Rulealize.Plugin.Deck", "version": "^1.0" }` |
| `Rulealize.Plugin.Definition` (`def.`) | `{ "plugin": "Rulealize.Plugin.Definition", "version": "^1.0" }` |
| `Rulealize.Plugin.Graph` (`graph.`) | `{ "plugin": "Rulealize.Plugin.Graph", "version": "^1.0" }` |
| `Rulealize.Plugin.Grid` (`grid.`) | `{ "plugin": "Rulealize.Plugin.Grid", "version": "^1.2" }` |
| `Rulealize.Plugin.Logic` (`logic.`) | `{ "plugin": "Rulealize.Plugin.Logic", "version": "^1.0" }` |
| `Rulealize.Plugin.Record` (`rec.`) | `{ "plugin": "Rulealize.Plugin.Record", "version": "^1.0" }` |
| `Rulealize.Plugin.Secret` (`secret.`) | `{ "plugin": "Rulealize.Plugin.Secret", "version": "^1.0" }` |
| `Rulealize.Plugin.Sequence` (`seq.`) | `{ "plugin": "Rulealize.Plugin.Sequence", "version": "^1.5" }` |
| `Rulealize.Plugin.State` (`state.`) | `{ "plugin": "Rulealize.Plugin.State", "version": "^1.0" }` |
| `Rulealize.Plugin.Text` (`str.`) | `{ "plugin": "Rulealize.Plugin.Text", "version": "^1.0" }` |
| `Rulealize.Plugin.Tuple` (`tuple.`) | `{ "plugin": "Rulealize.Plugin.Tuple", "version": "^1.0" }` |
| `Rulealize.Plugin.TypeSchema` (`type.`) | `{ "plugin": "Rulealize.Plugin.TypeSchema", "version": "^1.3" }` |
## How to write one
A paneset also opens written on one line after `#p=` in the link.
```text
https://reny-develop.github.io/Rulpane/#p={"$schema":"rulpane/paneset/v1","r":{…},"v":{…}}
```
If you write a link by hand and send it in a chat, write each space as `%20` so the chat does not cut it short; a link made with “Make a link from JSON” has no spaces. A link that does not open says why: paste it into [Make a link from JSON](#make) above to put it right.
- [Rulealize.Registry](https://reny-develop.github.io/Rulealize.Registry/)
Find the operations rules can use, by name. Each plugin's page leads to its specification, which gives every key.
`r`
- [Rulpane.Gallery](https://reny-develop.github.io/Rulpane.Gallery/)
Find views, themes and panesets. Look up a rule set by name to see the views that fit it as they are.
`v` `t` `p`
The formats in full: rule sets in Rulealize's [quick guide](https://github.com/reny-develop/Rulealize/blob/main/doc/ruleset-quickguide.md); [panesets](https://github.com/reny-develop/Rulpane#panesets), [views](https://github.com/reny-develop/Rulpane#views), [themes](https://github.com/reny-develop/Rulpane#themes) and [the plugins Rulpane runs](https://github.com/reny-develop/Rulpane#plugins) in Rulpane's [README](https://github.com/reny-develop/Rulpane#readme).
A link keeps no secrets: whoever holds it sees everything in it and can take any step.