@assuredloop/orca-bot-kit 0.25.4 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -128,8 +128,8 @@ obk up --bots /path/to/my-bots
128
128
  that file and the rule units, `CLAUDE.md` as a symlink to it, and a `.gitignore`
129
129
  for `work/`.
130
130
  `session add` writes one session into `bot.yaml`: its harness (the bot's unless
131
- it says otherwise), model, effort, context window, approval level, start prompt,
132
- work dir and any extra arguments for the harness. A start prompt is either text
131
+ it says otherwise), model, effort, context window, start prompt,
132
+ work dir and any extra arguments for the harness, and the approval level. A start prompt is either text
133
133
  (`--prompt`) or, when it is long, a file in the bot home the session points at
134
134
  (`--prompt-file prompts/reviewer.md`), and it reaches the harness as written,
135
135
  apart from two things the kit does on purpose: blank space at either end is
@@ -138,7 +138,18 @@ note about it. Anything you leave out is the
138
138
  harness's own default; the kit names no model of its own. The approval level is
139
139
  `auto` — the harness's real auto mode — unless you ask for `ask` or, in those
140
140
  words, `dangerously-skip`
141
- ([ADR 0015](docs/adr/0015-three-approval-levels-auto-by-default.md)).
141
+ ([ADR 0015](docs/adr/0015-three-approval-levels-auto-by-default.md)). Only
142
+ `obk permission approval` changes it, after your yes: `session add` and
143
+ `session change` take no approval, and refuse an extra argument that sets one
144
+ ([ADR 0037](docs/adr/0037-permission-changes-and-risky-operations-have-commands-of-their-own.md)).
145
+
146
+ Every bot gets the kit's default permission rules, written by the kit with
147
+ nobody asked: its own commands for this bots folder, reading a long message,
148
+ `git add` and `git commit`, and Orca's `orca orchestration check --run`
149
+ ([ADR 0036](docs/adr/0036-the-kit-writes-every-bots-default-permission-rules.md)).
150
+ `obk permission`, `obk retire`, `obk pause` and `obk init` are not in the set,
151
+ and keep your yes. A rule beyond the set is written by `obk permission allow`,
152
+ after your yes to the exact rule.
142
153
 
143
154
  Neither command touches Orca. `obk up` is what makes it all real there: an Orca
144
155
  project per bot, a tab per session, each started at the bot home with its own
@@ -443,6 +454,11 @@ Bot Father does these for you when you ask; these are the commands it runs.
443
454
 
444
455
  ```sh
445
456
  obk bot change --bots /path/to/my-bots --bot api-bot --charter "…"
457
+ obk bot change --bots /path/to/my-bots --bot api-bot --role-cap reviewer=2
458
+ obk permission allow --bots /path/to/my-bots --bot api-bot --rule 'Bash(gh pr merge:*)'
459
+ obk permission disallow --bots /path/to/my-bots --bot api-bot --rule 'Bash(gh pr merge:*)'
460
+ obk permission approval --bots /path/to/my-bots --bot api-bot --session daily --approval ask
461
+ obk permission approval --bots /path/to/my-bots --bot api-bot --temps --approval dangerously-skip
446
462
  obk session change --bots /path/to/my-bots --bot api-bot --session daily --model opus
447
463
  obk skills remove --bots /path/to/my-bots --bot api-bot --skill kit:obk-tdd
448
464
  obk pause --bots /path/to/my-bots --bot api-bot [--session daily]
@@ -643,13 +659,14 @@ npm run mutate # the mutation audit, on what your branch changed
643
659
 
644
660
  The tests come in two layers, and every test file belongs to one of them.
645
661
 
646
- `npm test` is `test/*.test.js`: unit tests and end-to-end runs of the CLI in a
647
- throwaway folder, with a fake `orca` on PATH. It needs nothing but Node, so
648
- [GitHub Actions](.github/workflows/ci.yml) runs it on every pull request, split
649
- into shards that run side by side, on Node 25.8.0, the current line. A release
650
- runs every shard on 25.8.0 and again on 24.21.0, the floor `engines.node`
651
- promises users, with only the kit's own dependencies installed, before anything
652
- is published.
662
+ `npm test` is `test/*.test.js` and `test/dev/*.test.js`: unit tests and
663
+ end-to-end runs of the CLI in a throwaway folder, with a fake `orca` on PATH. It
664
+ needs nothing but Node, so [GitHub Actions](.github/workflows/ci.yml) runs it on
665
+ every pull request, split into shards that run side by side, on Node 25.8.0, the
666
+ current line. A release runs every shard on 25.8.0 and again on 24.21.0, the
667
+ floor `engines.node` promises users, with only the kit's own dependencies
668
+ installed, before anything is published. The floor leaves out `test/dev/`, the
669
+ tests that need a development tool.
653
670
 
654
671
  `npm run test:system` is `test/system/*.test.js`: the real `obk` against the
655
672
  real Orca and the real harnesses on your own machine. No CI runner can do that,
package/SETUP.md CHANGED
@@ -128,11 +128,12 @@ tab, which is a plain shell for work across the whole fleet.
128
128
  Read everything it prints. Three parts of it matter to them:
129
129
 
130
130
  - **what it created** — say it in a sentence, not as a file listing;
131
- - **the permission rules it says wait for their yes**, when Bot Father runs on
132
- Claude Code: its mail through the kit, reading a long message beside the
133
- bots folder, and its commits, so auto mode does not stop it for those. Show
134
- them the rules word for word and ask. Only on a yes, run the one command
135
- `init` printed for them; on a no, run nothing, and nothing is written;
131
+ - **the permission rules it wrote**: the kit's default set, so auto mode does
132
+ not stop Bot Father for the kit's own commands, reading a long message
133
+ beside the bots folder, and its commits. The kit writes this set for every
134
+ bot, with nobody asked. Say in a sentence what it allows, and that
135
+ `obk permission`, `obk retire`, `obk pause` and `obk init` are not in it and
136
+ keep their yes;
136
137
  - **anything it says about Orca's own default launch arguments.** Orca adds
137
138
  these to every agent it launches, relaunches and resumes. When they carry a
138
139
  permission bypass, every session runs in that mode whatever approval level the
@@ -228,8 +229,8 @@ home. The kit never makes a git worktree, so
228
229
  `2. New worktree` is never the answer.
229
230
 
230
231
  A bot's own temporary sessions are answered by their maker, through the kit, so
231
- that one narrow permission rule allows it rather than a rule to type into any
232
- tab. On Codex's hooks review, the maker runs
232
+ that a narrow permission rule of the kit's default set allows it rather than a
233
+ rule to type into any tab. On Codex's hooks review, the maker runs
233
234
  `obk temp trust-hooks --bots <their path> --name <session>`. On Claude Code's
234
235
  `Teach auto mode` screen, it runs `obk temp answer --bots <their path> --name <session>`.
235
236
  That command reads the screen and answers only when it holds one of the two
@@ -237,16 +238,35 @@ shapes in the table exactly as the kit knows it: Esc for the 2.1.283 form, and
237
238
  **2. Not now** for the 2.1.289 list. On the list it sends the arrows, reads the
238
239
  screen again, and sends the return only with the selection on **2. Not now**.
239
240
  It refuses any other screen, types nothing then, and prints what it saw.
240
- Afterwards it checks that the screen has gone. In
241
- auto mode the maker's bot needs this rule, with the kit's full CLI path for
242
- `<kit>`, as the command's own output prints it:
241
+ Afterwards it checks that the screen has gone. The kit's default set allows
242
+ both commands for every bot, so there is nothing to ask the user. The rules
243
+ are these, with the kit's full CLI path for `<kit>`, as the command's own
244
+ output prints it:
243
245
 
244
246
  ```text
245
- Bash(<kit> temp answer:*)
247
+ Bash(<kit> temp answer --bots <their path>:*)
248
+ Bash(<kit> temp trust-hooks --bots <their path>:*)
246
249
  ```
247
250
 
248
- Ask the user, and only after their yes run
249
- `obk bot change --bots <their path> --bot <bot> --allow 'Bash(<kit> temp answer:*)'`.
251
+ A long-lived session's two screens go through the kit as well, not through the
252
+ keys. On Codex's hooks review, run
253
+ `obk session trust-hooks --bots <their path> --bot <bot> --session <session>`.
254
+ On Claude Code's `Teach auto mode` screen, run
255
+ `obk session answer --bots <their path> --bot <bot> --session <session>`.
256
+ A long-lived session is Bot Father's, so run them from outside the fleet's tabs,
257
+ as you do here, or from a Bot Father session. A session of any other bot is
258
+ refused. They make the same checks as the temp commands. Before either
259
+ trust-hooks command trusts hooks, the kit checks that the hooks on the review
260
+ are its own: the bot's `.codex/hooks.json` holds only the kit's hooks, and the
261
+ count on the screen is the number of the kit's hooks that Codex does not trust
262
+ yet. When it refuses, it says what it saw: type nothing, and tell them what it
263
+ said. Use the keys in the table for the screens the kit does not answer.
264
+ The kit reads Codex's trust from the caller's `CODEX_HOME`, else `~/.codex`;
265
+ a bot run under another `CODEX_HOME` is outside what the kit can see.
266
+ The kit also records the extra arguments it launched each session with, and
267
+ refuses when they mention hooks, or when there is no record. A Codex that
268
+ someone started again by hand in that tab, with other flags, is outside what
269
+ the kit records.
250
270
 
251
271
  **Anything you do not recognise: type nothing.** Tell them what is on the
252
272
  screen and which tab it is in, and wait. A keypress into a menu you have not read
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assuredloop/orca-bot-kit",
3
- "version": "0.25.4",
3
+ "version": "0.26.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,8 +23,9 @@
23
23
  "SETUP.md"
24
24
  ],
25
25
  "scripts": {
26
- "test": "node --test test/*.test.js",
27
- "test:shard": "node --test --test-shard=$SHARD test/*.test.js",
26
+ "test": "node --test test/*.test.js test/dev/*.test.js",
27
+ "test:shard": "node --test --test-shard=$SHARD test/*.test.js test/dev/*.test.js",
28
+ "test:floor": "node --test --test-shard=$SHARD test/*.test.js",
28
29
  "test:system": "node scripts/test-system.js",
29
30
  "mutate": "node scripts/mutate.js"
30
31
  },
package/rules/limits.md CHANGED
@@ -17,6 +17,6 @@ publishing, releasing, spending money, anything another person receives.
17
17
  When something you were told to use is missing (a model, a tool, a file), say
18
18
  so and ask. Quietly using a different one hides the change.
19
19
 
20
- Permission rules in a harness's settings or rules files are the kit's to write,
21
- after the user's yes to the exact rules: `"${OBK_CLI:-obk}" bot change --allow <rule>` or
22
- `--disallow <rule>`. Never edit one in or out yourself, Bot Father included.
20
+ Permission rules and approvals are the kit's to write: its default set at once,
21
+ anything else after the user's yes to it, by `"${OBK_CLI:-obk}" permission allow`,
22
+ `disallow` or `approval`. Never edit one in or out yourself, Bot Father included.
package/rules/mail.md CHANGED
@@ -8,6 +8,10 @@ To reach another session, ask the kit for the road rather than guessing an
8
8
  address: `"${OBK_CLI:-obk}" message to --bots <bots> --to <bot>/<session>`. It
9
9
  answers with the address and the command that carries it.
10
10
 
11
+ If your harness refuses a message, do not send it again by another road. Tell
12
+ your maker or your user, with the harness's reason. A refusal can mean a missing
13
+ permission rule, which they can add through the kit after the user's yes.
14
+
11
15
  Mail is queued, not an interruption. Read it when you finish what you are on.
12
16
 
13
17
  Ask for a reply when you need one, and send one when you were asked for one.
@@ -194,7 +194,7 @@ The kit's command line does the writing, and the files belong to the user:
194
194
  source add` records where online skills come from and `obk skills fetch`
195
195
  clones them, `obk skills add` puts one on a bot, `obk skills build` links
196
196
  them, and `obk up` opens what is missing in Orca. `obk bot change` gives a
197
- bot a new charter, `obk session change` changes a session's settings, and
197
+ bot a new charter or a role's cap, `obk session change` changes a session's settings, and
198
198
  `obk skills remove` takes a skill off a list (then `obk skills build`). `obk
199
199
  pause` stops a bot or a session for now and `obk unpause` brings it back;
200
200
  `obk retire` ends one. After `obk up`, `obk restart` or `obk unpause`, read
@@ -206,16 +206,15 @@ Run `obk --help` for the flags of the version actually installed rather than
206
206
  trusting a line you remember.
207
207
 
208
208
  A bot needs a few permission rules so that auto mode, or Codex's sandbox and
209
- reviewer, does not stop it for what the kit's own rules tell it to do: its
210
- mail through the kit, reading a long message kept beside the bots folder, and
211
- its commits. `obk bot create`, `obk up` and `obk rules build` list the rules
212
- still waiting for a bot and give one command that allows them. Show the user
213
- those rules word for word and say in a line what each lets the bot do. Run the
214
- command only after their yes: it records the yes in the bot's `bot.yaml` and
215
- writes the rules into its settings, or for Codex into its
216
- `.codex/rules/obk.rules`. On a no, run nothing, and nothing is written. When
217
- the kit lists new rules for a bot later, ask again. Never write a permission
218
- rule into a settings or rules file by hand.
209
+ reviewer, does not stop it for what the kit's own rules tell it to do: the
210
+ kit's own commands, reading a long message kept beside the bots folder, and
211
+ its commits. The kit writes this default set itself, with nobody asked:
212
+ `obk bot create`, `obk up` and `obk rules build` add each default rule a bot
213
+ does not have yet to its `bot.yaml` and its settings, or for Codex its
214
+ `.codex/rules/obk.rules`, and say which rules they wrote. The set leaves out
215
+ the commands that keep the user's yes: `obk permission`, `obk retire`, `obk
216
+ pause` and `obk init`. Never write a permission rule into a settings or rules
217
+ file by hand.
219
218
 
220
219
  The charter decides what else the bot needs. What it lets the bot do without
221
220
  asking, such as merging pull requests, auto mode or Codex's sandbox can still
@@ -228,14 +227,14 @@ Spell them in Claude Code's form for a Codex bot too, `Bash(<command>:*)`: the
228
227
  kit writes Codex's own form of each, and says which ones Codex has none for,
229
228
  such as an `Edit` rule or one exact command.
230
229
  Show the user the list word for word, with a line on what each lets the bot do,
231
- and only after their yes run `obk bot change --allow`, once per rule they said
232
- yes to. On a no, run nothing. `obk bot change --charter` names the rules the
230
+ and only after their yes run `obk permission allow --rule <rule>`, once per
231
+ rule they said yes to. On a no, run nothing. `obk bot change --charter` names the rules the
233
232
  bot is allowed now; say which of them the new charter no longer grants, show
234
233
  each word for word, and ask whether to take it back. Only after their yes run
235
- `obk bot change --disallow`, once per rule, which takes it out of `bot.yaml`
234
+ `obk permission disallow --rule <rule>`, once per rule, which takes it out of `bot.yaml`
236
235
  and the bot's settings or Codex rules; on a no, run nothing, and it stays
237
236
  allowed. A rule the user added to a settings file by hand is theirs to take
238
- out; the kit refuses it. Keep
237
+ out; the kit refuses it, and it refuses a rule of its own default set too. Keep
239
238
  each rule narrow: a program and what it does. The kit refuses a rule that lets
240
239
  the bot run any command, a program with any arguments, or a shell or
241
240
  interpreter with any arguments; a user who wants one for a bot adds it to that
@@ -331,9 +330,21 @@ into any tab. The same goes for Claude Code's `Teach auto mode` screen on a
331
330
  temporary session you made: answer it with `obk temp answer --bots <bots>
332
331
  --name <session>`. It answers only a shape in the table exactly as the kit
333
332
  knows it (Esc on the 2.1.283 form, 2. Not now on the 2.1.289 list, the return
334
- only after a second look), refuses any other screen, and checks that it went. Its
335
- rule is `Bash(<kit> temp answer:*)`, `<kit>` the kit's CLI path as the
336
- command prints it; ask the user before `obk bot change --allow` adds it.
333
+ only after a second look), refuses any other screen, and checks that it went. The kit's
334
+ default set allows it, as it allows `obk temp trust-hooks`.
335
+
336
+ A long-lived session's two screens go through the kit too: Codex's hooks
337
+ review with `obk session trust-hooks --bots <bots> --bot <bot> --session
338
+ <session>`, and Claude Code's `Teach auto mode` screen with `obk session
339
+ answer --bots <bots> --bot <bot> --session <session>`. A long-lived session is
340
+ Bot Father's: the caller is a Bot Father session or the user, from outside the
341
+ fleet's tabs, and a session of any other bot is refused. They make the same
342
+ checks as the temp commands. Before either trust-hooks command trusts hooks,
343
+ it checks that the hooks on the review are the kit's own: the bot's
344
+ `.codex/hooks.json` holds only the kit's, and the count on the screen is the
345
+ number of the kit's hooks Codex does not trust yet. A refusal says what it
346
+ saw; then type nothing and take it to the user. The keys in the table are for
347
+ the screens the kit does not answer.
337
348
 
338
349
  Where the kit says no session came up, the shell swallowed the launch line,
339
350
  usually while it was asking its own question. Answer the shell, then close
package/src/book.js CHANGED
@@ -28,6 +28,9 @@ const HEADER = `# What Orca calls this bot on this machine, and where each of it
28
28
  # \`rules\` is a stamp of the bot's AGENTS.md as the session last read it, so a
29
29
  # change to it after the session started can be told apart.
30
30
  #
31
+ # \`launched_with\` is the extra arguments the kit typed on the session's last
32
+ # launch line, as bot.yaml's extra_args gave them then.
33
+ #
31
34
  # \`retired\` holds what the book knew about each session \`obk retire\` took off
32
35
  # the bot, with when, so the conversations it had are still accounted for.
33
36
  #
package/src/bot.js CHANGED
@@ -11,7 +11,7 @@ import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSy
11
11
  import os from 'node:os';
12
12
  import path from 'node:path';
13
13
  import { isDeepStrictEqual } from 'node:util';
14
- import { parse, parseDocument, stringify } from 'yaml';
14
+ import { isSeq, parse, parseDocument, stringify } from 'yaml';
15
15
 
16
16
  import { DEFAULT_APPROVAL, HARNESSES, harnessOf, sessionTrouble } from './launch.js';
17
17
 
@@ -161,6 +161,9 @@ export function readBot(home, name = path.basename(home)) {
161
161
  allow: bot.allow,
162
162
  // The roles its temporary sessions can be made in, judged by tempRoles.
163
163
  ...(bot.temp_roles === undefined ? {} : { temp_roles: bot.temp_roles }),
164
+ // The widest approval its temporary sessions may be made at, the user's yes
165
+ // kept by `permission approval --temps` (ADR 0037).
166
+ ...(bot.temp_approval === undefined ? {} : { temp_approval: bot.temp_approval }),
164
167
  // A paused bot is one `obk up` leaves closed; its sessions keep their book.
165
168
  ...(bot.paused === true ? { paused: true } : {}),
166
169
  sessions: sessions.map((session) => {
@@ -278,10 +281,10 @@ export function changeBot(bots, bot, { charter }) {
278
281
  /**
279
282
  * The bot's `allow` list as it is, after refusing what `allowRules` or
280
283
  * `disallowRules` would refuse: an empty rule, or a list already there that is
281
- * not a list of rules. Asked before anything is written, so a refused `bot
282
- * change` changes nothing, its charter included.
284
+ * not a list of rules. Asked before anything is written, so a refused
285
+ * `permission allow` or `permission disallow` changes nothing.
283
286
  */
284
- export function allowedNow(bots, bot, rules, flag = '--allow') {
287
+ export function allowedNow(bots, bot, rules, flag = '--rule') {
285
288
  if (rules.some((rule) => rule.trim() === '')) {
286
289
  throw new Error(`${flag} is empty. Give it the exact permission rule the user said yes to, such as Bash(git add:*).`);
287
290
  }
@@ -320,7 +323,7 @@ export function allowRules(bots, bot, rules, { write = true } = {}) {
320
323
  * false it only refuses what the edit would refuse, and writes nothing.
321
324
  */
322
325
  export function disallowRules(bots, bot, rules, { write = true } = {}) {
323
- const { home, was } = allowedNow(bots, bot, rules, '--disallow');
326
+ const { home, was } = allowedNow(bots, bot, rules);
324
327
  const disallowed = [...new Set(rules)];
325
328
  const allow = was.filter((rule) => !disallowed.includes(rule));
326
329
  editBot(bots, bot, `take back ${disallowed.join(', ')} for ${bot}`, (doc) => doc.set('allow', allow), (before) => ({ ...before, allow }), write);
@@ -357,6 +360,58 @@ export function changeSession(bots, bot, name, settings) {
357
360
  return { bot, home, session };
358
361
  }
359
362
 
363
+ /**
364
+ * Record the widest approval the bot's temporary sessions may be made at,
365
+ * `level`, as `temp_approval` (ADR 0037). Returns { bot, home, level }.
366
+ */
367
+ export function setTempApproval(bots, bot, level) {
368
+ editBot(bots, bot, `let ${bot}'s temporary sessions be made at ${level}`, (doc) => doc.set('temp_approval', level), (was) => ({ ...was, temp_approval: level }));
369
+ return { bot, home: botDir(bots, bot), level };
370
+ }
371
+
372
+ /**
373
+ * Set the caps of roles in the bot's `temp_roles`: `caps` is a list of
374
+ * `[role, cap]`, a cap of undefined taking it off. A role written as a list of
375
+ * options becomes a mapping that holds that list as `options` beside its cap.
376
+ * A role the bot does not have is refused before anything is written. Returns
377
+ * { bot, home, caps }. With `write` false it only refuses what the edit would
378
+ * refuse, and writes nothing.
379
+ */
380
+ export function setRoleCaps(bots, bot, caps, { write = true } = {}) {
381
+ const home = existingBot(bots, bot);
382
+ const roles = readBot(home, bot).temp_roles;
383
+ const file = path.join(home, BOT_YAML);
384
+ for (const [role] of caps) {
385
+ if (roles === null || typeof roles !== 'object' || Array.isArray(roles) || !Object.hasOwn(roles, role)) {
386
+ const has = roles !== null && typeof roles === 'object' && !Array.isArray(roles) ? Object.keys(roles) : [];
387
+ throw new Error(`${bot} has no temporary-session role called ${role} in ${file}${has.length === 0 ? ', and no temp_roles at all' : `. It has: ${has.join(', ')}`}. Nothing was changed.`);
388
+ }
389
+ }
390
+ const capped = (written, cap) => {
391
+ const { cap: was, ...rest } = Array.isArray(written) ? { options: written } : written;
392
+ return cap === undefined ? rest : { ...rest, cap };
393
+ };
394
+ editBot(bots, bot, `set the caps of ${caps.map(([role]) => role).join(', ')}`, (doc) => {
395
+ for (const [role, cap] of caps) {
396
+ const node = doc.getIn(['temp_roles', role], true);
397
+ if (isSeq(node)) {
398
+ doc.setIn(['temp_roles', role], doc.createNode(capped(node.toJSON(), cap)));
399
+ } else if (cap === undefined) {
400
+ doc.deleteIn(['temp_roles', role, 'cap']);
401
+ } else {
402
+ doc.setIn(['temp_roles', role, 'cap'], cap);
403
+ }
404
+ }
405
+ }, (was) => ({
406
+ ...was,
407
+ temp_roles: Object.fromEntries(Object.entries(was.temp_roles).map(([role, written]) => {
408
+ const asked = caps.findLast(([one]) => one === role);
409
+ return [role, asked === undefined ? written : capped(written, asked[1])];
410
+ })),
411
+ }), write);
412
+ return { bot, home, caps };
413
+ }
414
+
360
415
  /**
361
416
  * Mark the bot `bot`, or its session `name`, paused or not. Returns whether
362
417
  * the file changed. A paused bot or session is one `obk up` leaves closed.
@@ -497,7 +552,7 @@ export const SESSION_FIELDS = [
497
552
  ];
498
553
 
499
554
  /** Everything the top of a bot's own file can hold. */
500
- const BOT_FIELDS = ['name', 'harness', 'charter', 'rules', 'skills', 'allow', 'sessions', 'paused', 'temp_roles'];
555
+ const BOT_FIELDS = ['name', 'harness', 'charter', 'rules', 'skills', 'allow', 'sessions', 'paused', 'temp_roles', 'temp_approval'];
501
556
 
502
557
  /**
503
558
  * The keys in a bot's file that the kit does not know, and so that nothing