agent-council 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4455c4fa8668f774bdfe685a0737f29232ed75bd6eaaa579888c5fac1b2efd7d
4
+ data.tar.gz: c743c3cf1d4af4e976bb81397629d2aa452267d8eff9e7a06d7cd03688c64296
5
+ SHA512:
6
+ metadata.gz: 8e1a7061f620b37a70475da386ed0f33ec706d5b317856b3fb86ed77cacec70abca70ff4e6eb1b9bf78396ab89f1999e115b54da0d2220f12a6d7624c3b4370e
7
+ data.tar.gz: 3f8deed0e2aad46ccc093f07d74bc0d574fb21ef46fcc607b10b484ccde2817689f0731bbcb0920d2edaa0c29786623635f53ec9eb417409e8bc2cb50b5611d0
data/DESIGN.md ADDED
@@ -0,0 +1,378 @@
1
+ # Design
2
+
3
+ ## 1. Goal
4
+
5
+ The long-term goal is to collect genuinely different viewpoints on the same question from multiple harness/model instances, and, because every instance gets the identical task, to compare those instances against each other on speed, token usage, cost, and quality.
6
+
7
+ This repository is the first step: it varies only the models, under a single harness (Pi). Harness diversity comes later (§18).
8
+
9
+ It is packaged as a gem for easy installation, but it is intentionally not a general-purpose framework.
10
+
11
+ agent-council is a small Ruby CLI that runs the **same prompt** through several AI model/provider combinations using the Pi coding-agent harness and saves each final response to a deterministic Markdown file.
12
+
13
+ The objective is utility, not completeness. Given a config (§5), one command:
14
+
15
+ ```bash
16
+ agent-council prompt.md
17
+ ```
18
+
19
+ quickly gets independent reports from several models.
20
+
21
+ ---
22
+
23
+ ## 2. Why
24
+
25
+ Different models often produce materially different analyses of the same codebase or problem.
26
+
27
+ Typical prompts include:
28
+
29
+ - What is the best way to resolve this issue?
30
+ - Give me a comprehensive state-of-the-codebase analysis.
31
+ - Identify important codebase issues needing attention.
32
+ - What architectural or maintainability problems should we address?
33
+
34
+ We want each model to receive the same substantive prompt so that differences in results come from the models themselves.
35
+
36
+ agent-council does not rank or debate the responses; synthesis is limited to the optional consolidator (§12).
37
+
38
+ It simply obtains and preserves them.
39
+
40
+ ---
41
+
42
+ ## 3. Core Principle
43
+
44
+ Each ensemble member receives the same substantive prompt.
45
+
46
+ For example:
47
+
48
+ ```text
49
+ prompt.md
50
+ |
51
+ +-------------+-------------+
52
+ | | |
53
+ v v v
54
+ Pi + Claude Pi + Kimi Pi + GLM
55
+ | | |
56
+ v v v
57
+ report report report
58
+ ```
59
+
60
+ ---
61
+
62
+ ## 4. Architecture
63
+
64
+ Pi is the only harness.
65
+
66
+ The Ruby program owns orchestration and invokes Pi once per configured provider/model combination.
67
+
68
+ ```text
69
+ Ruby CLI
70
+ |
71
+ +-- Pi + model A
72
+ +-- Pi + model B
73
+ +-- Pi + model C
74
+ +-- Pi + model D
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 5. Configuration
80
+
81
+ A simple YAML file defines the ensemble.
82
+
83
+ Example:
84
+
85
+ ```yaml
86
+ agents:
87
+ - provider: anthropic
88
+ model: MODEL_ID_HERE
89
+
90
+ - provider: openai
91
+ model: MODEL_ID_HERE
92
+
93
+ - provider: opencode-go
94
+ model: MODEL_ID_HERE
95
+
96
+ - provider: zai
97
+ model: MODEL_ID_HERE
98
+
99
+ consolidator: # optional; synthesizes the agents' reports (§12)
100
+ provider: anthropic
101
+ model: MODEL_ID_HERE
102
+ ```
103
+
104
+ Exact provider and model identifiers must be verified against the installed Pi version.
105
+
106
+ They belong in configuration because available models and names change frequently.
107
+
108
+ ---
109
+
110
+ ## 6. CLI
111
+
112
+ Command:
113
+
114
+ ```bash
115
+ agent-council [-o DIR] PROMPT_FILE [CONFIG_FILE]
116
+ agent-council --consolidate RUN_DIR
117
+ ```
118
+
119
+ The README's [Running](README.md#running) section and `agent-council -h`
120
+ document the arguments, options, and `AGENT_COUNCIL_OPTS`. The command:
121
+
122
+ 1. reads the prompt;
123
+ 2. reads the configuration;
124
+ 3. launches all configured analyst runs;
125
+ 4. saves each successful result as its agent finishes;
126
+ 5. waits for all of them, then prints a concise success/failure summary;
127
+ 6. runs the consolidator, if one is configured, over the saved reports.
128
+
129
+ `agent-council --consolidate RUN_DIR` runs only the
130
+ consolidation of a finished run, using the run dir's own prompt and
131
+ config copies, found through its reports' front matter (§12).
132
+
133
+ ---
134
+
135
+ ## 7. Parallel Execution
136
+
137
+ Agents run concurrently, one Ruby thread per agent, each driving one pi process.
138
+
139
+ `AgentCouncil::WorkerPool` (`lib/agent_council/worker_pool.rb`) also handles signals, keeping the main thread free to take them. The README's [Stopping a run](README.md#stopping-a-run) section describes what Ctrl-C and the other signals do; the reasons behind that behavior are:
140
+
141
+ - **Each agent leads its own process group**, so the terminal's signals reach only agent-council, which then stops the agents itself, in an orderly way, and Ctrl-Z suspends agent-council without suspending the agents under it.
142
+ - **Agents get SIGTERM and a shared grace period before being killed**, so pi can stop the commands it started; a second signal skips the wait for a user who doesn't want to.
143
+ - **agent-council then dies by the signal** rather than exiting normally, so a shell (e.g. one running it in a loop) sees it was killed and stops too. SIGQUIT exits 131 instead, since a core dump is no use here.
144
+ - **Extra SIGHUPs are ignored**, since a closing terminal can send them in pairs, and **signals agent-council was started ignoring stay ignored**, so `nohup` works.
145
+ - **SIGQUIT isn't trapped under JRuby**, where the JVM reserves it for thread dumps.
146
+
147
+ There is no job system, daemon, async framework, or workflow engine.
148
+
149
+ ---
150
+
151
+ ## 8. Prompt Identity
152
+
153
+ agent-council does not:
154
+
155
+ - assign different roles to the analysts;
156
+ - customize analytical instructions per model;
157
+ - ask models to identify themselves;
158
+ - add model-specific output instructions.
159
+
160
+ Execution metadata stays outside the substantive prompt: the per-agent scratch path is in the system-prompt scaffolding, and model identity is in the report's front matter.
161
+
162
+ ---
163
+
164
+ ## 9. Prompt Delivery
165
+
166
+ The prompt is piped to pi on stdin, never interpolated into a command line, so it may be large and contain:
167
+
168
+ - Markdown;
169
+ - source code;
170
+ - quotes;
171
+ - shell characters;
172
+ - Unicode;
173
+ - long analytical instructions.
174
+
175
+ pi is started with an argv array, not through a shell.
176
+
177
+ ---
178
+
179
+ ## 10. Repository and System Safety
180
+
181
+ Agents are analyzers, not modifiers.
182
+
183
+ The scaffolding appended to pi's system prompt (`PiHarness.scaffold_text` in `lib/agent_council/harnesses/pi_harness.rb`) states the rules agents get, and the README's [How it works](README.md#how-it-works-and-what-pi-is-told) section summarizes them. They are instructions, not enforced restrictions: the `--tools` allowlist, which activates only the tools it lists, is the only enforcement, and `bash` remains a full shell running as the user (see the README's [Safety and privacy](README.md#safety-and-privacy)). A shell is kept because investigation (`git log`, dependency inspection, running a documented command) is much of what makes an analysis useful.
184
+
185
+ The rules follow from agents running concurrently in the user's own working tree:
186
+
187
+ - **No modifying project files, git state, software, or configuration, and no persistent services**, since the agents analyze the user's real repository and environment, not a copy. If testing a proposed change would need a modified file, the agent should describe the experiment instead (this follows from the rule; the scaffolding doesn't state it separately).
188
+ - **Each agent gets its own disposable scratch directory** (also its `TMPDIR`), so agents that need temporary files don't collide with each other or leave files in the project.
189
+ - **No test suites, builds, coverage tools, application servers, or database tasks unless the prompt permits them**, since such commands can collide through shared resources a per-agent scratch directory doesn't isolate: shared databases, Redis, fixed ports, Docker resources, hard-coded temporary paths, or other process-global state. Running tests and reproducing defects can make an analysis much stronger, so a prompt may lift the rule (as `examples/prompts/review-latest-commit-prompt.md` does for tests and linters); agents then still skip commands needing shared services. Where a command is not permitted but would help, the agent describes what it would run and why.
190
+
191
+ ---
192
+
193
+ ## 11. Pi Context Behavior
194
+
195
+ Pi may automatically load project-specific context such as:
196
+
197
+ - `AGENTS.md`;
198
+ - project context files;
199
+ - skills;
200
+ - extensions;
201
+ - prompt templates.
202
+
203
+ The analyzed repository's own `.pi` resources load only if pi already trusts the project, since agent-council passes no `--approve`.
204
+
205
+ Useful real-world analysis matters more than establishing a laboratory benchmark.
206
+
207
+ Therefore Pi behaves as it normally would when analyzing a repository, except that:
208
+
209
+ - each model run is independent;
210
+ - no conversation/session state leaks between runs (`--no-session`);
211
+ - the tool list is restricted and the scaffolding appended to the system prompt (§10);
212
+ - the report-format addendum is appended to each analyst's prompt.
213
+
214
+ There is no configurable controlled-comparison mode.
215
+
216
+ ---
217
+
218
+ ## 12. Report Files
219
+
220
+ The models don't write their own report files.
221
+
222
+ Pi returns the final response to the Ruby process, which writes that text (minus any leading top-level heading), under front matter and a metadata table, to a deterministic, self-describing filename (see below).
223
+
224
+ Each run gets its own directory, a day bucket, and an `hh-mm-ss` time, created atomically with a `-2`, `-3`, ... suffix if that name is already taken, and printed when the run starts, so an in-progress or interrupted run is easy to find. [The README's "What you get" section](README.md#what-you-get) specifies the layout, filenames, query slug, and front matter; the decisions behind them are:
225
+
226
+ - **Inputs are copied into the run dir** (the prompt, config, and `analyst_format.md`, each under its own file name), so an analyst run's inputs are recoverable later. The orchestrator is versioned in git and deliberately not copied; the pi and agent-council versions, the scaffolding text, and the consolidation template are not recorded.
227
+ - **Only analysts' reports go in `reviews/`.** The consolidator's reports (normally a findings and a meta file) and the input copies sit at the run dir root.
228
+ - **Filenames are self-describing.** They carry the full timestamp, query slug, agent index (`consolidated` for the consolidator), harness, provider, and model, so a report still says what it is when copied out of the tree. The agent index keeps names unique when a provider/model is configured more than once (e.g. to get several independent analyses from one model) and sits before the harness, so filenames sort in agent order once there is more than one harness. Provider and model are sanitized like the slug but keep their case.
229
+ - **Metadata is YAML front matter written by the orchestrator**, never by the model: it gives tools structured provenance, stays readable in the terminal, and is how reports are identified, so nothing parses filenames (a consolidation's findings file, meant to be pasted elsewhere, has identifying lines in place of front matter instead). Timestamps are unquoted ISO 8601, so they parse directly as `Time` objects. Beyond the `provider` and `model` every report needs to be recognized, `--consolidate` needs the analysts' `prompt_file`, `config_file`, `run_stamp`, and `query`, and their `agent_index` to tell which configured agents have no report.
230
+ - **Measurements go in `run.json`, not front matter.** Front matter identifies a document; a run's duration and token usage are data about the run, wanted for analysis across many runs, and most tools can't read front matter without tripping over the Markdown after it. So they go in one JSON file per run dir, readable by any language's standard library or `jq`; the byline table still shows a report's own duration and usage to its readers.
231
+
232
+ The optional consolidator (a top-level `consolidator:` provider and model
233
+ in the config, §5) runs after all agents finish, as one more pi run with
234
+ the same tools and scaffolding. Its prompt is
235
+ `lib/agent_council/templates/consolidate_prompt.md` followed by the
236
+ original prompt, every analyst report labeled with its source, and the
237
+ agents without a report with their failure reasons (with `--consolidate`,
238
+ which can't know them, a note that the reason wasn't recorded). A consolidation
239
+ failure is reported but does not change a normal run's exit status
240
+ (`--consolidate`'s exit status is the consolidation's).
241
+
242
+ **The consolidated report is split into two files.** The consolidator is asked to write its findings, then a line containing only `=== META ===`, then the sections that describe the consultation (`Agent Consultants`, `Agent performance`), and the orchestrator splits the report at that line. The findings file has no front matter or orchestration tables (the consolidator's own findings may still contain tables), so it can be pasted into an AI chat without spending tokens on the rest; it carries a legend of agent number, harness, provider, and model, since the findings cite agents by number. The rest goes to a meta file. A marker line was chosen over parsing headings, which depended on the model's exact section names and on code fences, and over a JSON or YAML wrapper, where one unescaped quote or bad indent in thousands of tokens of Markdown would lose the whole report. If the marker is missing, repeated, inside a code fence, or not followed by the `Agent Consultants` heading (which makes a quoted one unlikely to be taken for the real one), or if the report no longer starts with the header written to it, the report is left unsplit, with a warning that says why, rather than guessed at, and so it is if a split file can't be written; the original single file is not kept after a successful split, to avoid duplicate text. The findings file has no front matter, so it opens with a few lines identifying its run instead, and `run.json` records the meta file, which has the front matter, next to it. The consolidator's report is first written under the meta file's name, which, being created exclusively, keeps the configuration taken against a concurrent consolidation, and then rewritten in place; a report that can't be split is renamed to the unsuffixed name, which releases the meta name, so that guard covers split reports only. Each report in the consolidator's prompt states its harness, so findings can be attributed to harness, provider, and model.
243
+
244
+ The orchestrator already knows model identity, so analysts aren't asked to report it; the consolidator gets each report's source label from the orchestrator.
245
+
246
+ ---
247
+
248
+ ## 13. Pi Output Parsing
249
+
250
+ agent-council reads pi's JSONL event stream (`--mode json`) rather than scraping human-oriented terminal output. Pi documents `message_end` as the authoritative final message of a turn, so the final response is the text of the last assistant `message_end` event that has text (a trailing text-less message doesn't hide an earlier report). Pi exits 0 even when the provider rejects the request, so a non-blank `errorMessage`, or a `stopReason` of `length`, `aborted`, or `error` (output cut off, cancelled, or failed without an `errorMessage`), counts as a failure. Only the last assistant message and the one that would be saved are checked, so an error in a turn that a later turn recovered from is not a failure. Failures are reported, not saved as reports.
251
+
252
+ Parsing extracts only that; there is no generic Pi protocol library.
253
+
254
+ The parser and the pi CLI invocation for runs live in `AgentCouncil::Harnesses::PiHarness`
255
+ (`lib/agent_council/harnesses/pi_harness.rb`), the single home of harness-
256
+ specific behavior for runs (the separate `pi-models` helper also talks to
257
+ pi); `exe/agent-council` stays harness-agnostic so a second
258
+ harness can be added as another such module under `AgentCouncil::Harnesses`.
259
+
260
+ ---
261
+
262
+ ## 14. Output Directory
263
+
264
+ Reports go into `agent-council-reports/` under the current working
265
+ directory — i.e. the repository being analyzed — so the tool can be run
266
+ from any project:
267
+
268
+ ```text
269
+ agent-council-reports/
270
+ ```
271
+
272
+ The name says which tool wrote the directory, since it lands in someone
273
+ else's tree. `-o` / `--output-dir` (given directly or in `AGENT_COUNCIL_OPTS`)
274
+ replaces only this base directory; everything beneath it is the same. The
275
+ README's [Running](README.md#running) section has the rules.
276
+
277
+ Each run writes a timestamped, day-bucketed run directory (see §12), so
278
+ repeated runs accumulate without overwriting; beyond `--consolidate` (§6),
279
+ no run management is implemented.
280
+
281
+ ---
282
+
283
+ ## 15. Basic Failure Handling
284
+
285
+ Failure handling is simple. If a Pi invocation fails, agent-council:
286
+
287
+ - prints a useful error;
288
+ - writes no report for it;
289
+ - lets the other model runs finish.
290
+
291
+ One failed model doesn't discard successful results from others. The
292
+ README's [What you get](README.md#what-you-get) section shows how
293
+ failures are reported.
294
+
295
+ There are no retries of agent-council's own (pi may retry transient provider failures), error taxonomies, fallback models, semantic report validation, or separate process/report status systems.
296
+
297
+ ---
298
+
299
+ ## 16. Repository Layout
300
+
301
+ ```text
302
+ README.md
303
+ INSTALL.md
304
+ DESIGN.md
305
+ RELEASE_NOTES.md
306
+ LICENSE.txt
307
+ REVIEW_NOTES.md # settled review findings; not shipped in the gem
308
+ CONTRIBUTING.md # contribution process; not shipped in the gem
309
+ code-review-agents.md # sample code-review ensemble recommendation
310
+ agent-council.gemspec
311
+ exe/ # executable entry points; nearly all code lives in lib/
312
+ agent-council
313
+ pi-models # helper: list models available to pi
314
+ lib/
315
+ agent_council.rb # harness-agnostic orchestration (AgentCouncil)
316
+ agent_council/
317
+ version.rb
318
+ platform.rb # windows? and the native-Windows abort (WSL is required)
319
+ pi_models.rb # backs exe/pi-models
320
+ worker_pool.rb # worker threads, agent processes, and Ctrl-C handling
321
+ harnesses/
322
+ pi_harness.rb # pi-specific behavior (AgentCouncil::Harnesses::PiHarness)
323
+ templates/ # runtime data files (resolved via __dir__, shipped in the gem)
324
+ consolidate_prompt.md # instructions template for the consolidator
325
+ analyst_format.md # report-format addendum for analysts
326
+ spec/ # RSpec; not shipped in the gem
327
+
328
+ examples/ # pure, non-runtime samples (prompts/ and configs/ ship in the gem)
329
+ prompts/
330
+ smoke-test-prompt.md
331
+ state-of-the-code-base-prompt.md
332
+ project-name-prompt.md
333
+ recommend-model-ensemble-prompt.md
334
+ review-latest-commit-prompt.md
335
+ review-docs-prompt.md
336
+ test-coverage-analysis-prompt.md
337
+ configs/
338
+ single.yml
339
+ consolidated.yml
340
+ results/ # sample output; not shipped in the gem
341
+
342
+ agent-council-reports/ # created on demand; gitignored in this repository
343
+ ```
344
+
345
+ Dev-only files (Gemfile, Rakefile, lint configs, CI workflows, `bin/setup`,
346
+ `bin/setup-hooks`, `hooks/pre-commit`) are omitted above. The gemspec's
347
+ `spec.files` is the authority on what ships.
348
+
349
+ `lib/` stays shallow, without namespaces deeper than `harnesses/`
350
+ (such as `lib/agent_council/services/...`) unless the project grows enough to
351
+ require them. A plain implementation is preferred to a speculative
352
+ framework.
353
+
354
+ ---
355
+
356
+ ## 17. Dependencies
357
+
358
+ The tool itself uses only the Ruby standard library (`yaml`, `json`, `open3`, `optparse`, `fileutils`, `tmpdir`, `shellwords`, ...); tests use RSpec.
359
+
360
+ New gems are added only if they solve a meaningful problem that would otherwise require substantial code.
361
+
362
+ ---
363
+
364
+ ## 18. Status and Future Work
365
+
366
+ agent-council is at an early stage (0.x), so it does only what its core job needs. Features we hope to add include support for more harnesses than Pi (such as Claude Code and Codex). A missing feature is usually just not built yet.
367
+
368
+ `REVIEW_NOTES.md` separately tracks review findings that were considered and don't need to be re-raised: accepted risks and non-issues.
369
+
370
+ ---
371
+
372
+ ## 19. Design Rule
373
+
374
+ Every proposed feature should pass this test:
375
+
376
+ > Does this help get independent answers to the same prompt from multiple models, or make sense of them?
377
+
378
+ If not, leave it out. Consolidation passes; a general-purpose agent framework does not.
data/INSTALL.md ADDED
@@ -0,0 +1,98 @@
1
+ # Installing agent-council from scratch
2
+
3
+ This guide is for developers comfortable with the command line who have
4
+ never used Ruby. It takes you from a bare machine to a working
5
+ `agent-council` command. Already have Ruby 3.3+ (or JRuby 10+) and
6
+ `pi`? Just run `gem install agent-council`; see the
7
+ [README](README.md#quick-start).
8
+
9
+ ## 1. Prepare your system
10
+
11
+ - **macOS and Linux:** any terminal works. Linux needs `curl` installed.
12
+ - **Windows:** native Windows is **not supported**. Everything, including
13
+ Ruby, Pi, and agent-council, must be installed and run inside
14
+ [WSL](https://learn.microsoft.com/windows/wsl/install) with Ubuntu. In
15
+ an administrator PowerShell, run `wsl --install -d Ubuntu`, restart if
16
+ asked, then open an Ubuntu terminal and follow the Linux steps below
17
+ in it. Keep your projects in the Linux filesystem (e.g. `~/projects`),
18
+ not under `/mnt/c`.
19
+
20
+ On Ubuntu/WSL, install the basics first:
21
+
22
+ ```bash
23
+ sudo apt update && sudo apt install -y curl build-essential
24
+ ```
25
+
26
+ ## 2. Install Ruby with Mise
27
+
28
+ [Mise](https://mise.jdx.dev) is a version manager for languages. It is
29
+ used here because it provides current Ruby versions, installs them in
30
+ your home directory without touching any system Ruby, and works the same
31
+ way on macOS, Linux, and WSL.
32
+
33
+ Install Mise and activate it in your shell.
34
+
35
+ Zsh:
36
+
37
+ ```zsh
38
+ curl -fsSL https://mise.run | sh
39
+ echo 'eval "$(~/.local/bin/mise activate zsh)"' >> "${ZDOTDIR:-$HOME}/.zshrc"
40
+ ```
41
+
42
+ Bash:
43
+
44
+ ```bash
45
+ curl -fsSL https://mise.run | sh
46
+ echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc
47
+ ```
48
+
49
+ On macOS, Bash reads `~/.bashrc` only if `~/.bash_profile` sources it. If
50
+ yours doesn't, add `[ -f ~/.bashrc ] && . ~/.bashrc` to `~/.bash_profile`.
51
+
52
+ Open a new terminal window (or tab) so the activation takes effect, then
53
+ install Ruby 4.0 and make it your default:
54
+
55
+ ```bash
56
+ mise use --global ruby@4.0
57
+ ```
58
+
59
+ Mise downloads a precompiled Ruby where one exists, and otherwise compiles
60
+ it, which needs a C toolchain and some libraries. If the install fails
61
+ for that reason, install the
62
+ [ruby-build suggested build environment](https://github.com/rbenv/ruby-build/wiki#suggested-build-environment)
63
+ for your system (on macOS, the Xcode command line tools: `xcode-select --install`)
64
+ and run the command again.
65
+
66
+ Verify:
67
+
68
+ ```bash
69
+ ruby -v # should print ruby 4.0.x
70
+ ```
71
+
72
+ For other install methods and details, see the
73
+ [Mise documentation](https://mise.jdx.dev/getting-started.html) and its
74
+ [Ruby page](https://mise.jdx.dev/lang/ruby.html).
75
+
76
+ ## 3. Install Pi and configure a provider
77
+
78
+ agent-council drives AI models through the
79
+ [Pi](https://github.com/earendil-works/pi) coding agent. Install Pi by
80
+ following its [installation instructions](https://github.com/earendil-works/pi),
81
+ and configure it with credentials for **at least one AI model provider**
82
+ (see [Pi's documentation](https://pi.dev/docs/latest)). Under WSL, do both
83
+ inside WSL.
84
+
85
+ ## 4. Install agent-council
86
+
87
+ ```bash
88
+ gem install agent-council
89
+ agent-council -h
90
+ ```
91
+
92
+ If the help text appears, you're done.
93
+
94
+ ## Next steps
95
+
96
+ Continue with the README's [Quick start](README.md#quick-start) to list
97
+ your models, write a config, and do your first run. You've already done its
98
+ steps for installing the prerequisites and the gem.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Keith R. Bennett
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.