random_name_generator 4.0.3 → 4.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7374613642f2111c5c4f4cff427d6ee2c88a99cacc5d4755b2eed1584c293b7
4
- data.tar.gz: 78e17730bcaa7e74632f7c2063caeb0f4b31cc7f8de61435ca872969dede788c
3
+ metadata.gz: 0a9a162ecd9a8953ea3383bc847dcc18a8a61506b5802ea4cd8f94daeaaf5f9b
4
+ data.tar.gz: 746bcfeb89b0506e7cb7f03e92f6805efc9d2493fd603bd46b363f24888089f0
5
5
  SHA512:
6
- metadata.gz: 409911e7d194ebabe10d1d88d44df023a6025092100885db770742f0f4a1b1fe3a538a37f67a20fb966a67f7d415c5d541311c232ab981bed751c387f4e7b231
7
- data.tar.gz: b60b0794a0fb21bfd45c3b641bc16a9a5f38fe9d105a86ca73e63ad80a6e130376ad377a124b76df5d148037b9503a963caafbbe143150c511c377da3e834add
6
+ metadata.gz: bc4d3f93f9945579b0e984ee0badd0c6ba96e52fa52239eee8300d6b17d0490f2390337b695e8fc34fde8eca49c6b9bd9197a5403c5538967f0c6d2244743b6b
7
+ data.tar.gz: 4af48dfe789cd3517f0256418f3378a0ba078c2c9b55acbad2dfbc6353b6a9f1d0453778b67c2afe8c56963018cedc66fc54c9dba4b09b048c0dd3f484ff364f
@@ -0,0 +1,5 @@
1
+ # Decisions
2
+
3
+ * [Randomness is injected, never global](injected-randomness.md) - generators take a `random:` keyword so specs can seed them; `srand` and global state are banned.
4
+ * [slop is a runtime dependency](slop-runtime-dependency.md) - the CLI ships inside the gem, so its option parser must be in the gemspec.
5
+ * [Ruby 3.4 is the floor](ruby-3-4-minimum.md) - version 4.0.0 dropped Ruby 3.0–3.3; CI tests 3.4, 4.0, and head.
@@ -0,0 +1,41 @@
1
+ ---
2
+ type: Decision
3
+ title: Randomness is injected, never global
4
+ description: Generators take a `random:` keyword so specs can seed them; `srand` and global state are banned.
5
+ tags: [decision, testing, api]
6
+ timestamp: 2026-07-26T00:00:00Z
7
+ ---
8
+
9
+ # Decision
10
+
11
+ Every sampling point that can be controlled takes an injected `Random`:
12
+
13
+ ```ruby
14
+ RandomNameGenerator::Generator.new(lang, random: Random.new(seed))
15
+ RandomNameGenerator.pick_number_of_syllables(random: Random.new(seed))
16
+ ```
17
+
18
+ `Generator` stores it as `@rnd` and passes it to every `Array#sample` call in
19
+ the composition path. Specs that need determinism pass a seeded `Random` —
20
+ they never call `srand` or otherwise touch global randomness.
21
+
22
+ # Why
23
+
24
+ Global `srand` is process-wide: one spec seeding it changes the behavior of
25
+ every later example, and parallel or reordered runs stop being reproducible.
26
+ An injected `Random` scopes determinism to the object that needs it.
27
+
28
+ # Limits
29
+
30
+ Two entry points remain non-seedable because they sample the *language* with a
31
+ bare `Array#sample`: `RandomNameGenerator.flip_mode` and
32
+ `.flip_mode_cyrillic`. Their specs assert on type and shape rather than on a
33
+ specific name. Also note that `compose` with no argument draws its syllable
34
+ count from `pick_number_of_syllables`'s **default** `Random.new` — for a fully
35
+ deterministic name, pass the count explicitly.
36
+
37
+ See [Generator](/library/generator.md) and [the module](/library/module.md).
38
+
39
+ # Citations
40
+
41
+ [1] [CLAUDE.md — Conventions](https://github.com/folkengine/random_name_generator/blob/main/CLAUDE.md)
@@ -0,0 +1,34 @@
1
+ ---
2
+ type: Decision
3
+ title: Ruby 3.4 is the floor
4
+ description: Version 4.0.0 dropped Ruby 3.0–3.3; CI tests 3.4, 4.0, and head.
5
+ tags: [decision, ruby, ci]
6
+ timestamp: 2026-07-26T00:00:00Z
7
+ ---
8
+
9
+ # Decision
10
+
11
+ `required_ruby_version >= 3.4.0` as of gem version **4.0.0** (2026-07-18).
12
+ `.tool-versions` pins the development interpreter to `ruby 3.4.10`, and
13
+ RuboCop's `TargetRubyVersion` is `3.4`.
14
+
15
+ Support for Ruby 3.0 through 3.3 was dropped in the same release, alongside
16
+ dependency bumps (`rake ~> 13.4`, `rexml`, `concurrent-ruby`).
17
+
18
+ # CI matrix
19
+
20
+ `.github/workflows/ruby.yml` runs the full gate on `3.4`, `4.0`, and `head`.
21
+ `head` is `continue-on-error: true` — it exists to catch 4.1 regressions early
22
+ without letting a broken nightly red the build. See
23
+ [build and test](/development/build-and-test.md).
24
+
25
+ # Implications
26
+
27
+ The floor is a hard constraint on new code: 3.4-and-later syntax is fine, and
28
+ the four decimal places of `.tool-versions` should track whatever patch the
29
+ CI `3.4` job resolves to. Raising the floor again is a **major** version bump.
30
+
31
+ # Citations
32
+
33
+ [1] [CHANGELOG.md — 4.0.0](https://github.com/folkengine/random_name_generator/blob/main/CHANGELOG.md)
34
+ [2] [.github/workflows/ruby.yml](https://github.com/folkengine/random_name_generator/blob/main/.github/workflows/ruby.yml)
@@ -0,0 +1,34 @@
1
+ ---
2
+ type: Decision
3
+ title: slop is a runtime dependency
4
+ description: The CLI ships inside the gem, so its option parser must be in the gemspec — a Gemfile entry is invisible to installed gems.
5
+ tags: [decision, packaging, cli]
6
+ timestamp: 2026-07-26T00:00:00Z
7
+ ---
8
+
9
+ # Decision
10
+
11
+ `slop ~> 4.10` is declared with `spec.add_dependency` in
12
+ `random_name_generator.gemspec`, not merely in the `Gemfile`.
13
+
14
+ # Why
15
+
16
+ `exe/random_name_generator` ships as a gem executable and does
17
+ `require "slop"` at the top. A `Gemfile` entry only affects development in
18
+ this checkout; it is not carried into the published gem. Without the gemspec
19
+ dependency, `gem install random_name_generator` followed by
20
+ `random_name_generator -g` fails with `LoadError` on a machine that happens
21
+ not to have slop.
22
+
23
+ The gemspec carries an inline comment saying exactly this, so the classification
24
+ survives future dependency cleanups.
25
+
26
+ # Scope
27
+
28
+ This applies to anything the shipped [CLI](/interfaces/cli.md) or `lib/`
29
+ requires at runtime. Test and lint tooling (rspec, rubocop, reek, rake) stays
30
+ in the Gemfile — those are correctly development-only.
31
+
32
+ # Citations
33
+
34
+ [1] [random_name_generator.gemspec](https://github.com/folkengine/random_name_generator/blob/main/random_name_generator.gemspec)
@@ -0,0 +1,55 @@
1
+ ---
2
+ type: Playbook
3
+ title: Build, test, and lint
4
+ description: The commands that gate a change, and what each one enforces.
5
+ tags: [development, testing, ci]
6
+ timestamp: 2026-07-26T00:00:00Z
7
+ ---
8
+
9
+ # The gate
10
+
11
+ ```shell
12
+ bundle exec rake # => spec, then rubocop
13
+ ```
14
+
15
+ `rake default` is `%i[spec rubocop]`. Reek is wired as its own task
16
+ (`rake reek`, `fail_on_error: true`) but is **not** part of the default task —
17
+ run it deliberately.
18
+
19
+ | Command | Purpose |
20
+ |---------|---------|
21
+ | `bundle exec rspec` | Tests. One example: `bundle exec rspec spec/random_name_generator_spec.rb:42`. |
22
+ | `bundle exec rubocop` | Lint. `-A` to autocorrect. |
23
+ | `bundle exec reek` | Smell detection, configured by `config.reek`. |
24
+ | `bin/console` | IRB with the gem loaded. |
25
+ | `bundle exec rake build` | Builds the `.gem` into `pkg/`. |
26
+ | `bundle exec exe/random_name_generator -g` | Run the [CLI](/interfaces/cli.md) from the checkout. |
27
+
28
+ # Test layout
29
+
30
+ - `spec/random_name_generator_spec.rb` — module constants, factory methods,
31
+ and `Generator` behavior. Generators for the four base languages are built
32
+ once in a `before(:all)` block.
33
+ - `spec/random_name_generator/syllable_spec.rb` — parsing and adjacency rules.
34
+ - `spec/languages/*.txt` — fixtures that pin format edges (blank lines, a
35
+ one-syllable-per-bucket file, every flag combination, and an unsatisfiable
36
+ file that must raise). See
37
+ [the syllable file format](/formats/syllable-file-format.md).
38
+
39
+ `spec_helper.rb` disables RSpec monkey patching, forces `expect` syntax, and
40
+ persists example status to `.rspec_status`.
41
+
42
+ # CI
43
+
44
+ `.github/workflows/ruby.yml` runs `bundle exec rake` on pushes to `main`,
45
+ `v*` tags, and every pull request, against a matrix of Ruby `3.4`, `4.0`, and
46
+ `head`. The `head` job is `continue-on-error` — a broken nightly must not red
47
+ the run — and installs uncached with the latest bundler, since pairing a fixed
48
+ gem cache with a moving interpreter causes `CorruptBundlerInstallError`.
49
+
50
+ Overcommit hooks are configured in `.overcommit.yml`.
51
+
52
+ # Citations
53
+
54
+ [1] [Rakefile](https://github.com/folkengine/random_name_generator/blob/main/Rakefile)
55
+ [2] [.github/workflows/ruby.yml](https://github.com/folkengine/random_name_generator/blob/main/.github/workflows/ruby.yml)
@@ -0,0 +1,58 @@
1
+ ---
2
+ type: Convention
3
+ title: Code conventions
4
+ description: Style, smell, and testing rules this repo enforces — RuboCop is the source of truth.
5
+ tags: [development, style, lint]
6
+ timestamp: 2026-07-26T00:00:00Z
7
+ ---
8
+
9
+ # RuboCop is the arbiter
10
+
11
+ `.rubocop.yml` settles style questions; don't relitigate them in review.
12
+
13
+ | Setting | Value |
14
+ |---------|-------|
15
+ | `TargetRubyVersion` | 3.4, `NewCops: enable` |
16
+ | String literals | **double quotes** (including in interpolation) |
17
+ | `Layout/LineLength` | 180 |
18
+ | `Metrics/MethodLength` | 11 |
19
+ | `Metrics/ClassLength` | disabled |
20
+ | `Metrics/BlockLength` | excluded for `spec/**/*` |
21
+ | `Style/HashSyntax` | shorthand `either` |
22
+
23
+ Plugins: `rubocop-rspec`, `rubocop-rake`.
24
+
25
+ RSpec cops are relaxed where the existing spec style needs it —
26
+ `BeforeAfterAll` and `InstanceVariable` are disabled (the specs build shared
27
+ generators in `before(:all)`), `MultipleExpectations` is off, and
28
+ `NestedGroups` allows 5.
29
+
30
+ Every source file carries `# frozen_string_literal: true`.
31
+
32
+ # Reek
33
+
34
+ `config.reek` disables `IrresponsibleModule` and `TooManyMethods`, caps
35
+ instance variables at 10, and caps statements at 8 (excluding `initialize`).
36
+ Where a class legitimately exceeds a smell threshold, it carries an inline
37
+ `:reek:` annotation rather than a config exemption — e.g. `:reek:TooManyConstants`
38
+ on [the module](/library/module.md) and `:reek:TooManyMethods` on
39
+ [Syllable](/library/syllable.md).
40
+
41
+ # Testing
42
+
43
+ - `expect` syntax only; monkey patching disabled.
44
+ - Fixtures live in `spec/languages/`, never inline.
45
+ - Never use `srand` or global randomness for determinism — pass a seeded
46
+ `Random`. See [injected randomness](/decisions/injected-randomness.md).
47
+
48
+ # Shape of the code
49
+
50
+ Pure file-in / string-out: no network, no threads, no mutable global state
51
+ beyond the shared `File` constants. Keeping it that way is what makes the
52
+ library trivially embeddable.
53
+
54
+ # Citations
55
+
56
+ [1] [.rubocop.yml](https://github.com/folkengine/random_name_generator/blob/main/.rubocop.yml)
57
+ [2] [config.reek](https://github.com/folkengine/random_name_generator/blob/main/config.reek)
58
+ [3] [CLAUDE.md](https://github.com/folkengine/random_name_generator/blob/main/CLAUDE.md)
@@ -0,0 +1,5 @@
1
+ # Development
2
+
3
+ * [Build, test, and lint](build-and-test.md) - the commands that gate a change, and what each one enforces.
4
+ * [Code conventions](conventions.md) - style, smell, and testing rules; RuboCop is the source of truth.
5
+ * [Releasing the gem](release.md) - version bump, changelog, and the rake release path to RubyGems.
@@ -0,0 +1,44 @@
1
+ ---
2
+ type: Playbook
3
+ title: Releasing the gem
4
+ description: Version bump, changelog, and the rake release path to RubyGems.
5
+ resource: https://rubygems.org/gems/random_name_generator
6
+ tags: [development, release, packaging]
7
+ timestamp: 2026-07-26T00:00:00Z
8
+ ---
9
+
10
+ The gem is published as
11
+ [random_name_generator](https://rubygems.org/gems/random_name_generator) under
12
+ LGPL-3.0. Current version: **4.0.4** (`lib/random_name_generator/version.rb`).
13
+
14
+ # Steps
15
+
16
+ 1. Bump `RandomNameGenerator::VERSION` in `lib/random_name_generator/version.rb`
17
+ — the gemspec reads it, so it is the single source of truth.
18
+ 2. Add a CHANGELOG entry under a `## <version> - <YYYY-MM-DD>` heading.
19
+ 3. Run the gate: `bundle exec rake` (see
20
+ [build and test](/development/build-and-test.md)).
21
+ 4. `bundle exec rake release` — tags, pushes commits and the tag, and pushes
22
+ the `.gem` to RubyGems. Pushing a `v*` tag also triggers CI.
23
+
24
+ `rubygems_mfa_required` is set in the gemspec metadata, so the push requires
25
+ MFA.
26
+
27
+ # Packaging notes
28
+
29
+ - `spec.files` comes from `git ls-files`, minus `test/`, `spec/`, and
30
+ `features/` — an untracked language file will **not** ship.
31
+ - `bindir` is `exe`; executables are derived from tracked files there.
32
+ - `required_ruby_version >= 3.4.0` — see
33
+ [the Ruby floor](/decisions/ruby-3-4-minimum.md).
34
+ - `slop ~> 4.10` is a runtime dependency, not a development one — see
35
+ [why](/decisions/slop-runtime-dependency.md).
36
+
37
+ `bundle exec rake install` installs the gem locally, which is how you get a
38
+ bare `random_name_generator` command on `PATH` for testing the
39
+ [CLI](/interfaces/cli.md).
40
+
41
+ # Citations
42
+
43
+ [1] [random_name_generator.gemspec](https://github.com/folkengine/random_name_generator/blob/main/random_name_generator.gemspec)
44
+ [2] [CHANGELOG.md](https://github.com/folkengine/random_name_generator/blob/main/CHANGELOG.md)
@@ -0,0 +1,3 @@
1
+ # Formats
2
+
3
+ * [Syllable file format (.txt)](syllable-file-format.md) - line-oriented grammar for language files: one syllable per line, a position sigil, and optional adjacency flags.
@@ -0,0 +1,69 @@
1
+ ---
2
+ type: File Format
3
+ title: Syllable file format (.txt)
4
+ description: Line-oriented grammar for language files — one syllable per line, a position sigil, and optional adjacency flags.
5
+ tags: [format, domain, languages]
6
+ timestamp: 2026-07-26T00:00:00Z
7
+ ---
8
+
9
+ The syllable file is the domain data of this project; everything in
10
+ `lib/` is machinery for reading it. The format is deliberately plain text so a
11
+ language can be authored, diffed, and reviewed by hand.
12
+
13
+ # Schema
14
+
15
+ One syllable per line. Blank lines are ignored. Leading/trailing whitespace is
16
+ stripped and the whole line is downcased.
17
+
18
+ ```
19
+ [sigil]syllable [flag] [flag]
20
+ ```
21
+
22
+ | Element | Values | Meaning |
23
+ |---------|--------|---------|
24
+ | sigil | `-` | Prefix — may only appear first in a name. |
25
+ | | `+` | Suffix — may only appear last. |
26
+ | | *(none)* | Middle. |
27
+ | syllable | any characters | The text contributed to the name. |
28
+ | flags | `+v` | The **next** syllable must start with a vowel. |
29
+ | | `+c` | The next syllable must start with a consonant. |
30
+ | | `-v` | The **previous** syllable must end with a vowel. |
31
+ | | `-c` | The previous syllable must end with a consonant. |
32
+
33
+ Flags are whitespace-separated and order-independent. `+v`/`+c` are mutually
34
+ exclusive (first wins), as are `-v`/`-c`.
35
+
36
+ ```
37
+ -ang +c prefix "ang", next syllable must begin with a consonant
38
+ bryn middle, unconstrained
39
+ +wen -c suffix "wen", only after a syllable ending in a consonant
40
+ ```
41
+
42
+ # Authoring constraints
43
+
44
+ - **All three buckets must be non-empty.** A file with no suffixes cannot
45
+ compose a name of two or more syllables.
46
+ - **Flags must be satisfiable.** If some syllable's `+v` has no vowel-initial
47
+ candidate in the middle or suffix bucket, composition raises `ArgumentError`
48
+ at generation time, not load time — see [Generator](/library/generator.md).
49
+ Sparse buckets plus aggressive flags is the usual cause.
50
+ - Use flags only where the phonetics actually demand them. Most lines in the
51
+ bundled languages carry none.
52
+
53
+ # Where the files live
54
+
55
+ Curated languages are in `lib/languages/`; edgier or less polished sets are in
56
+ `lib/languages/experimental/`. Cyrillic variants use the `-ru.txt` suffix and
57
+ rely on `Syllable`'s Cyrillic character classes. See the
58
+ [language catalog](/languages/catalog.md) and
59
+ [adding a language](/languages/adding-a-language.md).
60
+
61
+ Test fixtures in `spec/languages/` exercise the edges of the format:
62
+ `test-blank.txt` (blank lines), `test-micro.txt` (one syllable per bucket, no
63
+ trailing newline), `test-tiny.txt` (every flag combination), and
64
+ `test-incompatible.txt` (a file whose flags cannot be satisfied).
65
+
66
+ # Citations
67
+
68
+ [1] [Syllable class documentation](https://github.com/folkengine/random_name_generator/blob/main/lib/random_name_generator/syllable.rb)
69
+ [2] [java-random-name-generator](https://github.com/folkengine/java-random-name-generator) — the port's origin; the format is inherited from it.
data/.okf/index.md ADDED
@@ -0,0 +1,19 @@
1
+ ---
2
+ okf_version: '0.1'
3
+ ---
4
+
5
+ # random_name_generator Knowledge Bundle
6
+
7
+ Knowledge about the `random_name_generator` Ruby gem — how names are composed
8
+ from syllable files, what ships, and how to work on it.
9
+
10
+ * [Overview](overview.md) - the project at a glance: shape, properties, and where to start.
11
+
12
+ # Areas
13
+
14
+ * [library/](library/) - the Ruby API: module, Generator, Syllable.
15
+ * [formats/](formats/) - the syllable file format that drives everything.
16
+ * [languages/](languages/) - the shipped syllable files and how to add one.
17
+ * [interfaces/](interfaces/) - the command line executable.
18
+ * [development/](development/) - build, test, lint, and release.
19
+ * [decisions/](decisions/) - choices worth not re-deriving.
@@ -0,0 +1,65 @@
1
+ ---
2
+ type: CLI
3
+ title: random_name_generator (executable)
4
+ description: The slop-based command line interface — one boolean flag per language, printing a two-name pair.
5
+ resource: https://github.com/folkengine/random_name_generator/blob/main/exe/random_name_generator
6
+ tags: [cli, interface]
7
+ timestamp: 2026-07-26T00:00:00Z
8
+ ---
9
+
10
+ ```shell
11
+ $ bundle exec exe/random_name_generator [-egrkbfcxdß?]
12
+ $ random_name_generator --german-curse # after `bundle exec rake install`
13
+ Dummkopfischpopelsepp Schnoddmistmann
14
+ ```
15
+
16
+ The script always prints **two** composed names separated by a space —
17
+ a first and last name — each with a randomly drawn syllable count.
18
+
19
+ # Flags
20
+
21
+ | Flag | Long | Selects |
22
+ |------|------|---------|
23
+ | `-e` | `--elven` | `ELVEN` (or `ELVEN_RU` with `-c`) |
24
+ | `-g` | `--goblin` | `GOBLIN` / `GOBLIN_RU` |
25
+ | `-r` | `--roman` | `ROMAN` / `ROMAN_RU` |
26
+ | `-k` | `--klingon` | `KLINGON` |
27
+ | `-b` | `--belter` | `BELTER` |
28
+ | `-x` | `--xrated` | `CURSE` *[NEEDS WORK]* |
29
+ | `-d` | `--demonic` | `DEMONIC` |
30
+ | `-ß` | `--german-curse` | `GERMAN_CURSE` *[NEEDS WORK]* |
31
+ | `-c` | `--cyrillic` | Switches to the Cyrillic branch; alone it means `FANTASY_RU`. |
32
+ | `-f` | `--flipmode` | Random language per name; honors `-c`. |
33
+ | `-?` | `--help` | Prints the slop usage block. |
34
+
35
+ With no flags, the default is `FANTASY`.
36
+
37
+ # Selection semantics
38
+
39
+ Language selection is a straight run of `if` assignments against a `lang`
40
+ variable initialized to `FANTASY`, split into a Cyrillic and a non-Cyrillic
41
+ branch. Consequences worth knowing:
42
+
43
+ - **Last flag in source order wins**, not last on the command line —
44
+ `-e -g` yields Goblin because the `GOBLIN` assignment comes after `ELVEN`.
45
+ - The Cyrillic branch only knows Elven, Goblin, and Roman, so `-c -k`,
46
+ `-c -b`, `-c -d` etc. fall through to `FANTASY_RU`.
47
+ - `-f` short-circuits language selection entirely; `-?` short-circuits
48
+ everything but `-f`.
49
+ - There is **no flag for Welsh** — see the
50
+ [language catalog](/languages/catalog.md).
51
+
52
+ The CLI exposes no syllable-count option; every name uses
53
+ `RandomNameGenerator.pick_number_of_syllables`.
54
+
55
+ # Packaging
56
+
57
+ Option parsing uses [slop](https://rubygems.org/gems/slop), which is therefore
58
+ a **runtime** dependency of the gem, not merely a Gemfile entry — see
59
+ [that decision](/decisions/slop-runtime-dependency.md). The gemspec sets
60
+ `bindir = "exe"` and derives `executables` from the tracked files under it.
61
+
62
+ # Citations
63
+
64
+ [1] [exe/random_name_generator](https://github.com/folkengine/random_name_generator/blob/main/exe/random_name_generator)
65
+ [2] [README — Installation](https://github.com/folkengine/random_name_generator/blob/main/README.md)
@@ -0,0 +1,3 @@
1
+ # Interfaces
2
+
3
+ * [random_name_generator (executable)](cli.md) - the slop-based command line interface: one boolean flag per language, printing a two-name pair.
@@ -0,0 +1,59 @@
1
+ ---
2
+ type: Playbook
3
+ title: Adding a language
4
+ description: The five touch points a new syllable file has to reach, and the lang-gen skill that automates them.
5
+ tags: [languages, playbook, contributing]
6
+ timestamp: 2026-07-26T00:00:00Z
7
+ ---
8
+
9
+ A language is not just a file — it has to be registered, exercised, and
10
+ documented. Missing one of these is the usual review comment.
11
+
12
+ # Steps
13
+
14
+ 1. **Write the `.txt`.** Follow the
15
+ [syllable file format](/formats/syllable-file-format.md). Curated languages
16
+ go in `lib/languages/`; edgy or unpolished ones in
17
+ `lib/languages/experimental/`. Cyrillic variants take the `-ru.txt` suffix.
18
+ 2. **Register the `File` constant** in `lib/random_name_generator.rb`, grouped
19
+ with its peers (plain / Cyrillic / experimental).
20
+ 3. **Add a CLI flag** in `exe/random_name_generator` if the language is
21
+ user-facing — both the `o.bool` declaration and the assignment in the
22
+ correct branch of the Cyrillic conditional. See [the CLI](/interfaces/cli.md).
23
+ 4. **Add a spec** to `spec/random_name_generator_spec.rb`. A smoke test that
24
+ composes names at each syllable count is enough to catch an unsatisfiable
25
+ flag set, which otherwise only surfaces at runtime.
26
+ 5. **Document it** — README (with a link to the file) and CHANGELOG.
27
+
28
+ # Verification
29
+
30
+ Beyond the spec, check that all three buckets are non-empty and that names
31
+ actually compose at 1..5 syllables:
32
+
33
+ ```shell
34
+ bundle exec ruby -Ilib -e '
35
+ require "random_name_generator"
36
+ g = RandomNameGenerator.new(RandomNameGenerator::WELSH)
37
+ (1..5).each { |n| puts "#{n}: #{Array.new(5) { g.compose(n) }.join(" ")}" }
38
+ '
39
+ ```
40
+
41
+ Then run the gate: `bundle exec rake` — see
42
+ [build and test](/development/build-and-test.md).
43
+
44
+ # The lang-gen skill
45
+
46
+ `.claude/skills/lang-gen/SKILL.md` automates the whole flow from a plain-English
47
+ theme, e.g. `/lang-gen Klingon words of joy`. It derives the slug, constant,
48
+ and destination directory (routing edgy themes to `experimental/`), authors the
49
+ three buckets with adjacency flags, performs steps 2–5, and samples names to
50
+ verify. `GERMAN_CURSE` was generated this way.
51
+
52
+ A portable text version of the same prompt lives at
53
+ `docs/superpowers/specs/2026-07-19-lang-gen-portable-prompt.md` for use outside
54
+ Claude Code.
55
+
56
+ # Citations
57
+
58
+ [1] [CLAUDE.md — Adding a language](https://github.com/folkengine/random_name_generator/blob/main/CLAUDE.md)
59
+ [2] [README — lang-gen](https://github.com/folkengine/random_name_generator/blob/main/README.md)
@@ -0,0 +1,70 @@
1
+ ---
2
+ type: Catalog
3
+ title: Language catalog
4
+ description: Every bundled syllable file — its constant, path, CLI flag, and bucket sizes.
5
+ tags: [languages, data, catalog]
6
+ timestamp: 2026-07-26T00:00:00Z
7
+ ---
8
+
9
+ Fourteen syllable files ship with the gem. Each is bound to a `File` constant
10
+ on [the module](/library/module.md) and, where user-facing, to a
11
+ [CLI](/interfaces/cli.md) flag.
12
+
13
+ # Curated languages
14
+
15
+ | Constant | File | CLI | pre / mid / suf |
16
+ |----------|------|-----|-----------------|
17
+ | `FANTASY` | `lib/languages/fantasy.txt` | *(default)* | 179 / 153 / 18 |
18
+ | `ELVEN` | `lib/languages/elven.txt` | `-e` | 36 / 21 / 27 |
19
+ | `GOBLIN` | `lib/languages/goblin.txt` | `-g` | 19 / 13 / 16 |
20
+ | `ROMAN` | `lib/languages/roman.txt` | `-r` | 15 / 10 / 10 |
21
+ | `KLINGON` | `lib/languages/klingon.txt` | `-k` | 40 / 35 / 36 |
22
+ | `BELTER` | `lib/languages/belter.txt` | `-b` | 35 / 40 / 27 |
23
+ | `WELSH` | `lib/languages/welsh.txt` | *(none)* | 35 / 32 / 24 |
24
+
25
+ `WELSH` is reachable from the library but has **no CLI flag** — the one gap
26
+ between the constant set and `exe/random_name_generator`.
27
+
28
+ # Cyrillic variants
29
+
30
+ Same four base styles, transliterated into Cyrillic syllables. They work
31
+ because `Syllable::VOWELS` and `CONSONANTS` include the Cyrillic alphabet
32
+ (see [Syllable](/library/syllable.md)).
33
+
34
+ | Constant | File | CLI | pre / mid / suf |
35
+ |----------|------|-----|-----------------|
36
+ | `FANTASY_RU` | `lib/languages/fantasy-ru.txt` | `-c` | 180 / 157 / 19 |
37
+ | `ELVEN_RU` | `lib/languages/elven-ru.txt` | `-c -e` | 36 / 21 / 27 |
38
+ | `GOBLIN_RU` | `lib/languages/goblin-ru.txt` | `-c -g` | 19 / 13 / 16 |
39
+ | `ROMAN_RU` | `lib/languages/roman-ru.txt` | `-c -r` | 15 / 10 / 10 |
40
+
41
+ The Cyrillic set is what `-c` selects, and it is also the pool for
42
+ `RandomNameGenerator.flip_mode_cyrillic`. `KLINGON`, `BELTER`, and `WELSH`
43
+ have no Cyrillic counterpart, so `-c -k` silently yields `FANTASY_RU`.
44
+
45
+ # Experimental languages
46
+
47
+ Edgier, less curated sets under `lib/languages/experimental/`. Opt-in only.
48
+
49
+ | Constant | File | CLI | pre / mid / suf |
50
+ |----------|------|-----|-----------------|
51
+ | `CURSE` | `experimental/curse.txt` | `-x` | 24 / 7 / 32 |
52
+ | `DEMONIC` | `experimental/demonic.txt` | `-d` | 111 / 64 / 73 |
53
+ | `GERMAN_CURSE` | `experimental/german-curse.txt` | `-ß` | 105 / 98 / 127 |
54
+
55
+ `CURSE` and `GERMAN_CURSE` are marked `[NEEDS WORK]` in the CLI help.
56
+ `CURSE`'s middle bucket holds only 7 syllables, so names of three or more
57
+ syllables repeat heavily. `GERMAN_CURSE` was produced by the `lang-gen` skill
58
+ and is the worked example for [adding a language](/languages/adding-a-language.md).
59
+
60
+ # Flip mode
61
+
62
+ `RandomNameGenerator.flip_mode` samples only `FANTASY`, `ELVEN`, `GOBLIN`, and
63
+ `ROMAN` — the four original styles. New languages are **not** picked up by
64
+ flip mode automatically; the arrays in `lib/random_name_generator.rb` are
65
+ hard-coded.
66
+
67
+ # Citations
68
+
69
+ [1] [lib/random_name_generator.rb](https://github.com/folkengine/random_name_generator/blob/main/lib/random_name_generator.rb)
70
+ [2] [README — Usage](https://github.com/folkengine/random_name_generator/blob/main/README.md)
@@ -0,0 +1,4 @@
1
+ # Languages
2
+
3
+ * [Language catalog](catalog.md) - every bundled syllable file: its constant, path, CLI flag, and bucket sizes.
4
+ * [Adding a language](adding-a-language.md) - the five touch points a new syllable file has to reach, and the lang-gen skill that automates them.