Compass CLI
Compass is the @tillo/compass command-line interface. It validates one
versioned evaluation suite and writes a local fixed-pass smoke report.
For the smoke run from this repository, see How to use Compass.
Compass requires Node.js 24 or later. The package is private. Run the built
dist/cli.js file from this repository.
The smoke command writes a fixed-pass result for every case. It does not call models or tools. It still requires a complete schema version 1 suite. The suite must contain model defaults and tool defaults.
Commands
| Command | Description |
|---|---|
run | Write a fixed-pass report for one versioned suite. |
compass <subcommand> [flags]
Global flags
These flags are available on every command.
| Flag | Description |
|---|---|
--help, -h | Show help information. |
--version, -v | Show version information. |
--wizard | Start wizard mode for a command. |
--completions <shell> | Print a shell completion script. |
--log-level <level> | Set the minimum log level. |
--completions accepts bash, zsh, fish, or sh. --log-level accepts
all, trace, debug, info, warn, warning, error, fatal, or none.
--version prints compass v followed by the version in package.json.
compass run
compass run --eval <path> [--output <directory>]
| Flag | Required | Default | Description |
|---|---|---|---|
--eval | Yes | none | Path to a versioned evaluation suite. |
--output | No | .compass/runs | Directory for local run reports. |
Paths may be relative. Compass resolves them against the current working directory.
The command reads --eval as a regular file. It decodes the file as a schema
version 1 evaluation suite. It then writes one report under --output.
The command does not use suite defaults, case tasks, or rubric text after validation. Each report case copies the suite case id and records a fixed-pass result.
Standard output
On success the command prints one JSON object, then a newline:
{
"accepted": true,
"report": "/absolute/path/to/<runId>/report.json",
"runId": "20260917T145642099Z-e572269c",
"status": "completed"
}
report is the absolute path of the written file. runId matches the report
directory name and the runId field inside the file.
Report files
The report path is:
<output-directory>/<runId>/report.json
runId is a UTC timestamp with -, :, and . removed, a hyphen, and the
first eight characters of a UUID. Example: 20260917T145642099Z-e572269c.
Compass creates the run directory with mode 0700 and the report file with mode
0600. The file contains indented JSON and a trailing newline.
The resolved run directory must stay inside the resolved output directory. If it would not, the command fails as an invalid evaluation suite.
Errors
Invalid evaluation suites write to standard error:
Invalid evaluation suite: <message>
The process exit code is 2. Compass does not write a report file.
| Condition | Message pattern |
|---|---|
Missing or unreadable --eval | Cannot read "<path>": <cause> |
--eval is not a regular file | "<path>" must be a regular file. |
| JSON or schema validation failure | The schema decoder message |
Report path would leave --output | The report path must stay inside the output directory. |
Invalid command use also exits with code 2. A missing --eval flag writes
Missing required flag: --eval to standard error.
Evaluation suite
--eval must decode as schema version 1.
| Field | Type | Constraint |
|---|---|---|
schemaVersion | integer | Must be 1. |
name | string | Must be non-empty. |
defaults.concurrency | integer | Must be 1 or greater. |
defaults.judgePasses | integer | Must be 1 or greater. |
defaults.maxIterations | integer | Must be 1 or greater. |
defaults.models.judge | string | Must be non-empty. |
defaults.models.revision | string | Must be non-empty. |
defaults.models.target | string | Must be non-empty. |
defaults.tools.allowed | array of strings | Each value must be non-empty. |
defaults.tools.mcpServices | array of strings | Each value must be non-empty. |
cases | array | Must contain at least one case. |
cases[].id | string | Must be non-empty. |
cases[].task | string | Must be non-empty. |
cases[].rubric.must | array of strings | Each value must be non-empty. |
cases[].rubric.should | array of strings | Each value must be non-empty. |
Empty arrays are valid for allowed, mcpServices, must, and should.
The smoke fixture at apps/compass/tests/fixtures/smoke-suite.json is a valid
suite:
{
"schemaVersion": 1,
"name": "compass-smoke",
"defaults": {
"models": {
"target": "amazon-bedrock/openai.gpt-5.6-sol",
"judge": "amazon-bedrock/openai.gpt-5.6-terra",
"revision": "amazon-bedrock/openai.gpt-5.6-sol"
},
"concurrency": 1,
"judgePasses": 1,
"maxIterations": 1,
"tools": {
"allowed": [],
"mcpServices": []
}
},
"cases": [
{
"id": "single-smoke-case",
"task": "Return the temporary fixed smoke result.",
"rubric": {
"must": ["reports one fixed-pass case"],
"should": []
}
}
]
}
Run report
The written report.json uses schema version 1.
| Field | Value in this smoke command |
|---|---|
accepted | true |
schemaVersion | 1 |
status | completed |
stopReason | fixed-pass |
suite | The suite name |
runId | The generated run id |
cases | One entry for each suite case, in suite order |
cases[].id | The suite case id |
cases[].result | fixed-pass |
cases[].status | passed |
usage.costUsd | 0 |
usage.inputTokens | 0 |
usage.modelCalls | 0 |
usage.outputTokens | 0 |
Example for the smoke fixture:
{
"accepted": true,
"cases": [
{
"id": "single-smoke-case",
"result": "fixed-pass",
"status": "passed"
}
],
"runId": "20260917T145642099Z-e572269c",
"schemaVersion": 1,
"status": "completed",
"stopReason": "fixed-pass",
"suite": "compass-smoke",
"usage": {
"costUsd": 0,
"inputTokens": 0,
"modelCalls": 0,
"outputTokens": 0
}
}
Exit codes
| Code | Meaning |
|---|---|
0 | The suite is valid and the report is written. |
2 | Invalid evaluation suite or invalid command use. |