Nova CLI

nova — единая точка входа в инструментарий языка Nova. Заменяет run_tests.ps1 / run_tests.sh / regen_runtime.ps1 (см. Plan 28).

Версия: 0.1.0 (bootstrap). Бинарник публикуется как nova (Cargo package nova, crate nova-cli).


Quickstart

# Inside a Nova project (sibling nova.toml present). Modules live at the
# package root — there is no `src/` directory (D78).
nova check                       # type-check whole workspace
nova check encoding/             # walk a directory recursively
nova check lib.nv                # single file

nova build app.nv -o app         # compile to a native binary (the way to run code)
./app                            # then execute it
nova add mathlib --path ../mathlib   # add a dependency, update nova.lock.toml
nova info mathlib                # a dependency's effect-surface
nova test nova_tests             # compile + run all nova_tests/
nova test nova_tests/plan118     # a single subdirectory
nova test std nova_tests         # multiple paths: std/ + nova_tests/
nova test --filter basics        # substring subset

nova doc lib.nv                  # markdown to stdout
nova doc . --format json         # D107 JSON schema
nova doc . --check --strict      # CI doc validation

nova bench run bench.nv          # run benchmarks
nova contracts verify foo.nv     # SMT-verify contracts

Интерпретатора нет. Nova компилируется в C — команды nova run для запуска нет. Чтобы выполнить программу — nova build, затем запусти бинарник; для тестов — nova test. См. nova run ниже.


Установка и сборка

nova-cli живёт в nova-cli/ рядом с compiler-codegen/. Рабочее пространство не используется (см. Plan 28 — оба крейта самостоятельные).

# Debug build (default, opt-level=0)
cargo build --manifest-path nova-cli/Cargo.toml

# Release (opt-level=2, LTO thin)
cargo build --release --manifest-path nova-cli/Cargo.toml

# With the Z3 backend for contracts (Plan 33.1)
cargo build --release --manifest-path nova-cli/Cargo.toml --features z3-backend

Получаешь:

  • nova-cli/target/{debug,release}/nova[.exe]
  • nova-cli/target/{debug,release}/migrate_plan60[.exe]
  • nova-cli/target/{debug,release}/migrate_plan65[.exe]

nova имеет зависимость по пути на nova_codegen (../compiler-codegen) — пересборка компилятора автоматически перекомпилирует CLI.


Глобальные флаги

Применяются ко всем подкомандам:

ФлагЗначенияОписание
--colorauto (по умолчанию), always, neverУправление ANSI-цветами. См. Plan 36 R10.

Автоопределение цвета (приоритет от высокого к низкому):

  1. CLI --color always|never — принудительно
  2. CLICOLOR_FORCE=1 → always
  3. NO_COLOR (любое значение) → never (no-color.org)
  4. CLICOLOR=0 → never
  5. CI=true → never
  6. TERM=dumb → never
  7. По умолчанию — включено

Тюнинг field-cache (advanced)

Каждая подкоманда также принимает «ручки» field-caching из Plan 123. Это флаги для диагностики (forensic) и запасного выхода (escape hatch) — значения по умолчанию корректны для обычного использования; трогать их нужно только при расследовании регрессии codegen-кэша.

ФлагЭффект
--no-field-cacheПолностью выключить field caching (== NOVA_FIELD_CACHE=0)
--no-field-cache-licmВыключить фазу LICM (D218)
--no-field-cache-pureВыключить фазу pure-call cache (D219)
--no-field-cache-chainВыключить фазу chain cache (D217 V4)
--no-field-cache-ipaВыключить IPA-refinements (D223 V7.1)
--field-cache-threshold NМин. чтений @field для кэша (по умолчанию 2)
--field-cache-licm-threshold NМин. чтений внутри цикла (по умолчанию 2)
--field-cache-pure-threshold NМин. вызовов @method() (по умолчанию 2)
--field-cache-chain-threshold NМин. вхождений цепочки (по умолчанию 2)
--field-cache-max NЛимит на функцию по всем слоям (по умолчанию 8)
--field-cache-licm-max NЛимит на цикл для LICM (по умолчанию 4)
--field-cache-chain-depth NМакс. глубина цепочки (по умолчанию 4, мин. 2)
--field-cache-ipa-iter NЛимит итеративного замыкания IPA (по умолчанию 10)

nova check дополнительно открывает --explain-cache, --telemetry-cache, --telemetry-json, --telemetry-baseline FILE, --telemetry-gate-affected-drop F и --telemetry-gate-caches-drop F для отчётов по анализу кэша и CI-проверок на регрессии.

Флаги field-cache опущены в таблицах ниже (по командам) ради читаемости; считай, что их полное семейство принимает каждая команда.


Коды выхода

Cargo-конвенция (Plan 36 R7):

КодЗначение
0Успех
1Диагностическая ошибка (ошибка типизации, упавший тест, нарушение контракта и т.п.)
2Ошибка использования (неверный флаг, файл не найден, не .nv, нет nova.toml)
101Внутренняя паника (через std::panic::set_hook для единообразия на разных платформах)

nova doc --diff дополнительно использует 3 = критическое изменение уровня патча (см. nova doc).


Поиск корня проекта

Большинство команд ищут nova.toml снизу вверх от CWD. Логика вынесена в nova_codegen::test_runner::find_repo_root_from:

  1. Идём от CWD вверх до корня файловой системы
  2. На каждом уровне читаем nova.toml если есть
  3. Если в нём есть [workspace] — это и есть корень (корень рабочего пространства), останавливаемся
  4. Иначе запоминаем последний найденный nova.toml и идём дальше
  5. Если найден корень с [workspace] — возвращаем его, иначе — самый верхний nova.toml

Это поведение с учётом рабочего пространства (workspace-aware; D78 AD6, Plan 35) — защищает от ситуации, когда вложенный nova_tests/nova.toml затмил настоящий корень.

Если nova.toml не найден — код выхода 2:

error: nova.toml not found — are you inside a Nova project?

Пути, разрешаемые от корня рабочего пространства:

  • <root>/nova_tests/ — корпус тестов
  • <root>/std/ — стандартная библиотека
  • <root>/compiler-codegen/ — include-пути C-runtime
  • <root>/compiler-codegen/nova_rt/ — runtime sources (libuv, GC)
  • <root>/target/last-test-results.json — кеш --rerun-failed

Команды

nova check

Проверка типов одного или нескольких .nv файлов / директорий. Plan 36 MVP — заменяет nova-codegen check.

nova check [PATHS...] [--jobs N] [-q|-v] [--list] [--format human|short]
           [--include-runtime] [--skip PATTERN]...

Позиционные аргументы:

  • PATHS — список файлов или директорий. Если пусто — корень рабочего пространства (рекурсивно). Файл должен иметь расширение .nv, иначе код выхода 2.

Флаги:

ФлагПо умолчаниюОписание
--jobs N0 (= num_cpus)Параллельных воркеров
-q, --quietoffТолько FAIL-строки и сводку
-v, --verboseoffДополнительная информация (время выполнения)
--listoffПоказать список файлов, не проверяя
--formathumanhuman (цветной) или short (file:line:col: msg для grep)
--include-runtimeoffВключить std/runtime/ (автосгенерированный, по умолчанию пропускается)
--skip PATTERN[]Пропустить файлы по подстроке (повторяемый)

Жёстко зашитый пропуск (всегда исключаются):

  • target/, node_modules/, vendor/
  • .git/, .hg/, .svn/
  • директории, начинающиеся с _ или .
  • std/runtime/ (переопределяется через --include-runtime)

Поведение:

  • Дедупликация через canonicalize
  • Сортировка для детерминизма
  • Параллельный обход через thread::scope + mpsc-канал
  • Пофайловые предупреждения (yellow: warning:) после ok:-строки
  • Сводка: pass=N fail=N warnings=N (X.YYs)
  • Код выхода 1 при любом FAIL, 2 при ошибке использования

--format short:

lib.nv: ok
parser.nv:42:5: error: type mismatch

--format human (по умолчанию):

ok: lib.nv
FAIL: parser.nv
  parser.nv:42:5: type mismatch

JSON / SARIF / JUnit форматы зарезервированы под подплан 36.A, сейчас не реализованы.


nova run

Сейчас НЕ поддерживается. Интерпретатор с обходом дерева отключён.

nova run остаётся видимой подкомандой, но при вызове падает с ошибкой и направляет на путь C-codegen:

nova run FILE
error: the Nova interpreter (`nova run`) is currently NOT supported.
Use `nova build <file>` to compile to an executable, or `nova test` to
compile and run tests (both via C codegen).

(код выхода 1).

Nova компилируется в C; поддерживаемого интерпретатора нет. Чтобы выполнить программу — nova build и запусти полученный бинарник; чтобы скомпилировать и прогнать тесты — nova test / nova test-build.


nova add

Добавить зависимость в [dependencies] nova.toml текущего пакета и обновить nova.lock.toml (Plan 03.1).

nova add NAME (--path DIR | --git URL [--tag T | --branch B | --rev R | --version REQ])
ФлагОписание
NAMEИмя зависимости — должно совпадать с [package].name пакета-зависимости
--path DIRЛокальная зависимость по пути (другой пакет на диске)
--git URLGit-зависимость (URL репозитория)
--tag TGit-пин: тег (только с --git)
--branch BGit-пин: ветка (только с --git)
--rev RGit-пин: коммит / ревизия (только с --git)
--version REQGit-пин: semver-диапазон, напр. ^1.2 (только с --git, Plan 03.2)
  • --path и --git взаимоисключающие; ровно один обязателен.
  • --tag / --branch / --rev / --version взаимоисключающие; опциональны (без пина — ветка по умолчанию, в lock всё равно пишется точный коммит).
  • --version выбирает наибольший подходящий semver-тег репозитория и пишет в nova.lock.toml и версию, и коммит.
  • Правит секцию [dependencies] (создаёт при отсутствии). Дубль имени → код выхода 2.
  • После правки запускает синхронизацию lock: материализует git-зависимость в кэше и пишет разрешённый коммит в nova.lock.toml.
  • Работает только внутри пакета (nova.toml с [package]), не на голом [workspace]-манифесте.
nova add mathlib --path ../mathlib
nova add gitlib  --git https://example.org/gitlib.nv --tag v1.0.0
nova add libfoo  --git https://example.org/libfoo.nv --version "^1.2"

nova update

Переразрешить git-зависимости и обновить nova.lock.toml (Plan 03.1 / 03.2).

nova update [NAME] [--precise NAME@VERSION]
  • NAME — конкретная git-зависимость для обновления. Без аргумента — все git-зависимости.
  • Снимает целевые git-записи из nova.lock.toml, затем переразрешает: пины по ветке и тегу берут текущий коммит, version-диапазоны — наибольший подходящий тег. Остальные остаются зафиксированными (воспроизводимость).
  • --precise NAME@VERSION — зафиксировать version-диапазонную git-зависимость на точной версии (напр. nova update --precise libfoo@1.2.0). Резолвер обязан согласовать её с остальным деревом, иначе — конфликт.
  • path-зависимости пинов не имеют — такой аргумент отвергается с пояснением.

nova info

Показать effect-surface пакета — агрегированные эффекты его публичного API (Plan 03.4 / D140). Nova-уникальное: в Cargo/npm узнать, что зависимость ходит в сеть, без аудита кода невозможно.

nova info TARGET [--format human|json] [--diff BASE [--fail-on-new]]
ФлагОписание
TARGETПуть к пакету (.nv-файл / каталог) либо имя зависимости из [dependencies] текущего пакета
--formathuman (по умолчанию) или json
--diff BASEСравнить effect-surface TARGET с BASE (путь либо зависимость) — добавленные/убранные эффекты
--fail-on-newС --diff: ненулевой код выхода при появлении новых эффектов (CI-проверка против дрейфа цепочки поставок)
  • Effect-surface = объединение эффектов всех export-функций (D28 — публичные функции объявляют эффекты явно → surface точна без межпроцедурного анализа). Приватные функции не входят.
  • --diff — сигнал цепочки поставок: Net/Fs, появившиеся в patch/minor-релизе ранее «чистого» API, — красный флаг.
nova info ./mylib                    # effect-surface of a local package
nova info somedep                    # of a declared dependency
nova info somedep --format json
nova info ./v2 --diff ./v1 --fail-on-new   # CI: fail if v2 added effects

Ограниченные по правам зависимости. Зависимость можно ограничить через forbid в nova.toml:

[dependencies]
parser = { git = "https://example.org/parser.nv", forbid = ["Net", "Fs"] }

nova build вычисляет effect-surface зависимости и проваливает сборку, если она использует запрещённый эффект — песочница на уровне типов (сильнее моделей разрешений в рантайме). См. D63 / D140.


nova build

Скомпилировать один .nv-файл в нативный бинарник (через C-бэкенд).

nova build FILE [-o OUTPUT] [--mode dev|release] [--toolchain auto|clang|msvc|gcc]
           [--vcvars PATH] [--clang PATH] [--timeout SECS] [--keep-artifacts]
           [--mono-depth N]

Только один файл за раз-o принимает один путь. Для многофайловых проектов используй import внутри точки входа.

Аргументы:

ФлагПо умолчаниюОписание
FILEТочка входа .nv с fn main
-o OUTPUT<name>[.exe] в CWDПуть к выходному бинарнику
--modedevdev (без оптимизации) или release (-O2 + LTO)
--toolchainautoauto (Clang → MSVC → GCC), clang, msvc, gcc
--vcvarsauto через vswhereПуть к vcvars64.bat (Windows)
--clangавтоопределениеПуть к clang.exe
--timeout120Таймаут компиляции в секундах
--keep-artifactsoffНе удалять .c/.exe/.obj в tmp
--mono-depth N500 (или NOVA_MONO_DEPTH)Лимит глубины инстанциации при мономорфизации (Plan 48)

Временная директория: $TEMP/nova_tests/build/<path-hash>/ (Windows) или $TMPDIR/nova_tests/build/<path-hash>/ (Unix). Хеш через DefaultHasher от абсолютного пути файла — обеспечивает уникальность без криптозависимости.

Pipeline:

  1. parse + typecheck + infer_effects
  2. CEmitter::emit_module → C-код
  3. detect_toolchain() (с автоопределением vcvars)
  4. detect_or_build_libuv() — runtime может зависеть от libuv
  5. compile_c_to_exe(&tc, &build_opts, timeout)
  6. Копирование exe → -o или CWD
  7. Удаление tmp (если не --keep-artifacts)

nova test

Запуск тестов из директории или файла. Plan 28 (вместе с Plan 26, Plan 27, Plan 34).

nova test [PATH]... [--filter SUBSTR] [--jobs N] [--format text|json|tap|junit]
          [--mode dev|release] [--toolchain auto|clang|msvc|gcc]
          [--vcvars PATH] [--clang PATH] [--timeout SECS] [-v|-q]
          [--results-file PATH] [--rerun-failed] [--retries N]
          [--keep-artifacts] [--gc boehm|malloc]
          [--list] [--filter-from PATH] [--shuffle [SEED]]
          [--skip PATTERN]... [--mono-depth N]
          [--positive] [--compile-error] [--panic] [--timeout-type]
          [--exit] [--slow] [--full]

Аргументы:

ФлагПо умолчаниюОписание
PATH...— (обязательный)Файлы и/или директории с тестами (минимум один)
--filter SUBSTRФильтр по отображаемому имени (подстрока)
--jobs N0 (= num_cpus)Параллельные воркеры
--formattexttext, json, tap, junit
--modedevdev или release
--toolchainautoauto, clang, msvc, gcc
--vcvarsautoПуть к vcvars64.bat
--clangautoПуть к clang.exe
--timeout60Таймаут на тест (секунды)
-v, --verboseoffВывод проходящих тестов
-q, --quietoffТолько FAIL-строки и сводку
--results-file PATH<root>/target/last-test-results.jsonКуда писать результаты
--rerun-failedoffПерезапустить только проваленные/по таймауту из последнего прогона
--retries N0Повторов на временных сбоях (гонки AV и т.п.)
--keep-artifactsoffНе удалять .c/.exe/.obj
--gcboehmboehm (по умолчанию) или malloc (только для внутреннего использования)
--listoffСписок тестов без запуска
--filter-from PATHФайл с именами тестов (по одному на строку, точное совпадение)
--shuffle [SEED]offСлучайный порядок; опциональный seed для воспроизводимости
--skip PATTERN[]Пропустить тесты по подстроке имени или пути (повторяемый)
--mono-depth N500 (или env)Лимит глубины инстанциации при мономорфизации
--positiveon (по умолчанию)Выбрать позитивные тесты (без EXPECT_*-маркера). По умолчанию, когда не задан ни один флаг категории.
--compile-erroroffВыбрать тесты EXPECT_COMPILE_ERROR.
--panicoffВыбрать тесты EXPECT_RUNTIME_PANIC.
--timeout-typeoffВыбрать тесты EXPECT_TIMEOUT.
--exitoffВыбрать тесты EXPECT_EXIT_CODE.
--slowoffДополнительно включить *_slow.nv (любого типа). Алиас: --include-slow.
--fulloffВсе типы + slow (--positive --compile-error --panic --timeout-type --exit --slow).

Флаги категорий (Plan 169.1.1, D304) аддитивны — несколько флагов объединяют свои наборы тестов (OR). Без флага категории по умолчанию выбираются только позитивные, быстрые (не медленные) тесты. Тип теста определяется по первому EXPECT_*-маркеру в заголовке файла (первые 30 строк), а не по папке — поэтому негативные тесты находятся даже вне neg/.

Несколько путей (Plan 36.D.1): передавать любое количество путей — директорий и/или файлов. Минимум один путь обязателен (Plan 172.6). Чтобы добавить std/:

nova test nova_tests             # nova_tests/ only
nova test std nova_tests         # std/ + nova_tests/ together
nova test nova_tests/plan118     # specific subdirectory

Отображаемое имя формируется как путь от текущего рабочего каталога (cwd): nova_tests/plan118/t1_parse_ok вместо абсолютного пути.

Форматы вывода:

  • text — человекочитаемый, цветной, в stdout
  • json — массив объектов с полями name, status, duration_ms, stderr
  • tap — Test Anything Protocol v13
  • junit — JUnit XML (для CI-агрегаторов)

--rerun-failed: читает --results-file, выбирает записи с status != "pass", фильтрует набор, запускает только их.

EXPECT-маркеры в тестовых файлах (см. docs/dev/test-conventions.md):

  • // EXPECT: <stdout-line> — точное совпадение строки
  • // EXPECT_STDERR: <line> — для stderr
  • // EXPECT_COMPILE_ERROR: <substring> — должно упасть при компиляции
  • // EXPECT_RUNTIME_ERROR: <substring> — panic с подстрокой
  • // REQUIRES_SMT_BACKEND — пропуск если SMT недоступен

nova test-build

Сборка + запуск одного тестового файла. Используется IDE / CI для точечной отладки.

nova test-build FILE [--mode dev|release] [--toolchain auto|clang|msvc|gcc]
                [--vcvars PATH] [--clang PATH] [--timeout SECS]
                [--keep-artifacts] [--gc boehm|malloc] [--mono-depth N]
ФлагПо умолчаниюОписание
FILEПуть к .nv-тесту
--modedevСм. nova test
--toolchainauto
--vcvarsauto
--clangauto
--timeout60
--keep-artifactsoff
--gcboehm
--mono-depth N500

Эквивалентно nova test <FILE>, но без механизмов массового запуска (одиночный exe, один тест-блок в файле).


nova regen-runtime

Регенерация std/runtime/*.nv стабов из реестра рантайма компилятора. Заменяет regen_runtime.ps1.

nova regen-runtime [--check]
ФлагПо умолчаниюОписание
--checkoffТолько сравнить — код выхода 1, если файлы расходятся с реестром (CI-проверка)

Под капотом — nova_codegen::codegen::runtime_registry::all() + render каждого модуля. См. Plan 13.


nova doc

Документация уровня production (Plan 45 / D107). Markdown / JSON / HTML

  • doc-tests + покрытие + мутационное тестирование + watch + режим рабочего пространства.
nova doc [FILE] [--format markdown|json|html] [--json-schema]
         [--include-private] [--test] [--check] [--watch]
         [--coverage [--coverage-threshold PERCENT]] [--jobs N]
         [--diff OLD NEW] [--scrape-examples WORKSPACE]
         [--strict] [--mutate-contracts [--real-exec]]
         [--output-dir DIR]

Аргументы:

ФлагПо умолчаниюОписание
FILE— (обязателен кроме --json-schema).nv файл или директория
--formatmarkdownmarkdown, json (D107 schema), html
--json-schemaoffВывести встроенную JSON Schema 2020-12 и выйти
--include-privateoffВключить неэкспортируемые элементы
--testoffЗапустить doc-tests (Plan 45)
--checkoffПроверить без рендера (битые ссылки, отсутствующие сводки)
--watchoffПовторный рендер по опросу mtime (500 мс); Ctrl-C для выхода
--coverageoffМетрики покрытия (% элементов со сводкой)
--coverage-threshold NCI-проверка: код выхода 1, если coverage% < N
--jobs N0 (= num_cpus)Параллельных задач разбора для рабочего пространства
--diff OLD NEWСравнить два JSON-вывода (определение semver-изменений)
--scrape-examples WORKSPACEПривязать 3 самых частых примера использования к каждой функции
--strictoffПредупреждения → ошибки (CI)
--mutate-contractsoffМутационное тестирование для контрактов (уникальная фича Nova)
--real-execoffРеально исполнять мутантов (требует --mutate-contracts)
--output-dir DIRМногостраничный HTML; только с --format html

Exit-коды для --diff OLD NEW:

КодЗначение
0Нет ломающих изменений
1Мажорное изменение (ломающее)
2Минорное изменение (аддитивное)
3Патч-изменение (косметическое)

Mutation testing (--mutate-contracts):

Генерирует мутанты для каждой функции с контрактами:

  • >>=, <<=
  • ==!=
  • Дроп requires/ensures

По умолчанию — текстовая эвристика (~1 мс/мутант). С --real-exec — запускает мутированные doc-tests через test_runner (~100 мс/мутант, гарантия реального срабатывания).

Поддерживаемые форматы документации в /// см. Plan 45 (D107).


nova doc-query

DSL-запросы к JSON-выводу nova doc --format json (Plan 45). Фундамент для MCP-сервера (nova doc-mcp).

nova doc-query JSON_FILE [QUERY]

Синтаксис query: key=value,key=value,...

КлючЗначения
kindfn, type, effect, protocol, module, …
namesubstring
moduleточный путь модуля
module-prefixпрефикс пути
capabilitycapability-name
effecteffect-name
has-contractstrue, false
verifiedtrue, false
stabilitystable, unstable, experimental
deprecatedtrue, false

Примеры:

nova doc . --format json > out.json
nova doc-query out.json "kind=fn,capability=pure"
nova doc-query out.json "name=add,has-contracts=true"
nova doc-query out.json "module-prefix=std,effect=Fs"

Пустой запрос → весь файл как есть.


nova doc-mcp

MCP-сервер (Model Context Protocol) — JSON-RPC через stdio или HTTP (Plan 45). Совместим с MCP-клиентами (Claude Code, MCP Inspector).

nova doc-mcp FILE [--port PORT]
ФлагПо умолчаниюОписание
FILE.nv-исходник или заранее сгенерированный .json
--port PORT— (stdio)HTTP-режим на 127.0.0.1:PORT, POST /mcp

Инструменты (экспортируются через tools/list):

  • query_items(query) — поиск через DSL (nova doc-query)
  • list_modules() — список путей модулей
  • get_item(item_id) — полный JSON одного элемента

Протокол: MCP-клиент шлёт initializetools/listtools/call.


nova contracts

Инспекция и верификация контрактов (Plan 33 / D24). Вывод — JSON (AI-friendly schema, см. docs/contracts-diag-schema.json).

nova contracts <SUBCOMMAND>

nova contracts list

Список всех контрактов в файле.

nova contracts list FILE

nova contracts verify

SMT-верификация контрактов. Вывод — JSON.

nova contracts verify FILE [--backend BACKEND]
ФлагПо умолчаниюОписание
FILE.nv файл
--backend BACKENDenv NOVA_SMT_BACKENDПереопределяет SMT-бэкенд (trivial, z3)

Z3-бэкенд: требует build с --features z3-backend. См. Plan 33.1.

nova contracts suggest

Предложения для контрактов с помощью AI (стабы).

nova contracts suggest FILE FN_NAME

nova contracts counterexample

Контрпример для падающего контракта.

nova contracts counterexample FILE FN_NAME [--contract-id N]
ФлагПо умолчаниюОписание
FN_NAMEИмя функции
--contract-id N0Индекс контракта (0-based)

nova bench

Инфраструктура бенчмарков (Plan 57 — MVP+A+B+C+D+E+F+G+H закрыты). Лучше Criterion (Rust) / testing.B+benchstat (Go) / tinybench (TS) по ряду параметров. См. docs/dev/bench-conventions.md.

nova bench <SUBCOMMAND>

Подкоманды: run, diff, gate, calibrate, cpu-instr-check, membw-check, hyperfine, callgrind, callgrind-check, runner-branch, history-anomalies, remote, corpus, history-add, history-list, history-squash, dashboard.

nova bench run

Запустить bench "..." { measure { ... } } декларации.

nova bench run FILE [--filter PATTERN] [--samples N] [--warmup-ms MS]
                    [--time-budget SECS] [--gc boehm|malloc]
                    [--mode release|dev] [--toolchain auto|clang|msvc|gcc]
                    [--vcvars PATH] [--clang PATH]
                    [--compile-timeout SECS] [--run-timeout SECS]
                    [--keep-artifacts] [--mono-depth N]
                    [--out PATH] [--out-csv PATH] [--out-md PATH]
                    [--out-criterion DIR] [--profile MODE OUT]
                    [--histogram]
ФлагПо умолчаниюОписание
FILE.nv файл с bench "..." блоками
--filter PATTERNЧасти имён бенчмарков через запятую
--samples N100Переопределяет число замеров
--warmup-ms500Длительность прогрева в мс
--time-budget10Бюджет на каждый bench в секундах
--gcboehmСм. nova test
--modereleaserelease (рекомендуется) или dev
--toolchainautoСм. nova build
--compile-timeout120Таймаут компиляции
--run-timeout600Таймаут запуска bench-процесса
--out PATHЗаписать JSON v1
--out-csv PATHЗаписать CSV
--out-md PATHMarkdown (для комментария в PR)
--out-criterion DIRJSON-layout, совместимый с Criterion
--profile MODE OUTпрофиль cpu/heap/gc, требует samply для cpu
--histogramoffASCII-гистограмма на каждый bench

Форматы вывода:

  • --out (JSON v1): полная схема с метаданными (git SHA, toolchain, модель CPU)
  • --out-criterion: <dir>/<safe-name>/new/{estimates,sample,benchmark}.json, совместимо с cargo-criterion --message-format=criterion
  • --out-md: markdown-таблица для PR
  • --histogram: 40 корзин, Unicode-блоки, медиана и границы Тьюки

Profile-режимы:

  • cpu — заворачивает в samply (нужен cargo install samply)
  • heapNOVA_BENCH_HEAP_SAMPLE_MS=10
  • gcNOVA_BENCH_GC_TRACE=1

nova bench diff

Сравнение двух bench-результатов. t-критерий Уэлча, геометрическое среднее (geomean delta), проверка воспроизводимости.

nova bench diff BASELINE NEW [--format terminal|markdown|json]
                              [--explain [--ai-config PATH] [--ai-max-tokens N]
                                         [--ai-dry-run]]
                              [--baseline-sha SHA] [--new-sha SHA]
ФлагПо умолчаниюОписание
BASELINE, NEWJSON-файлы (nova bench run --out)
--formatterminalterminal, markdown, json
--explainoffAI-интерпретация регрессий (Plan 57.F.2, по желанию)
--ai-config PATH~/.nova-ai.tomlПуть к конфигу AI
--ai-max-tokens4000Переопределяет максимум токенов
--ai-dry-runoffПечатает тело запроса без вызова API
--baseline-sha, --new-shaauto из JSONGit SHA для контекста

--explain использует system curl (без RustCrypto-стека) и требует NOVA_AI_API_KEY или конфигурацию.

nova bench gate

CI-проверка: применяет пороги из bench.toml. Код выхода 0 = проход, 1 = регрессия.

nova bench gate BASELINE NEW [--config PATH] [--noise PATH]
ФлагПо умолчаниюОписание
--config./bench.tomlПуть к bench.toml
--noise./.nova-bench-noise.json если естьАвтокалибруемый уровень шума (см. calibrate)

nova bench calibrate

Автокалибровка уровня шума из ≥2 повторных прогонов того же baseline (Plan 57.A.3).

nova bench calibrate RUNS... [--out PATH]
ФлагПо умолчаниюОписание
RUNS...≥2 JSON-результата одного и того же source
--out.nova-bench-noise.jsonКуда записать уровень шума

Файл привязан к машине; в git добавлять не нужно.

nova bench cpu-instr-check

Диагностика доступности счётчика инструкций CPU (Plan 57.B.4).

nova bench cpu-instr-check

Linux: проверяет perf_event_open + измеряет известный цикл. Прочие ОС: печатает заглушку.

nova bench membw-check

Диагностика измерения пропускной способности памяти (Plan 57.F.3).

nova bench membw-check

Linux: опрашивает /sys/devices/uncore_imc_* + счётчик промахов LLC. Прочие ОС: заглушка.

nova bench hyperfine

Замер времени по типу Hyperfine для нескольких бинарников — измерение по настенным часам произвольных команд (Plan 57.H.2). Вывод совместим с nova bench diff.

nova bench hyperfine SPECS... [--warmup N] [--samples N]
                              [--timeout SECS] [--workdir PATH] [--out PATH]
ФлагПо умолчаниюОписание
SPECS...≥1"name=binary args..." или просто "binary args..."
--warmup3Прогревочные запуски (отбрасываются)
--samples10Замеряемые запуски
--timeout300Таймаут на команду
--workdir PATHCWD для команд
--out PATHstdoutJSON-вывод

Пример:

nova bench hyperfine \
  "old=./nova-old build large.nv" \
  "new=./nova-new build large.nv" \
  --samples 10 --warmup 2 --out result.json

nova bench callgrind

Запуск под Valgrind Callgrind — детерминированный подсчёт инструкций CPU (Plan 57.H.3). Кроссплатформенный запасной путь к perf_event_open (только Linux). Работает на macOS + Linux при наличии valgrind.

nova bench callgrind BINARY [ARGS...] [--cache-sim] [--workdir PATH] [--out PATH]
ФлагПо умолчаниюОписание
BINARYПуть к исполняемому файлу
ARGS...Аргументы исполняемого файла
--cache-simoffСчётчики промахов I1/D1/LL (медленнее)
--workdir PATHCWD для команды
--out PATHJSON CallgrindResult

nova bench callgrind-check

Проверка наличия и версии valgrind.

nova bench callgrind-check

nova bench runner-branch

Печатает рекомендованное имя ветки истории на основе переменной окружения NOVA_BENCH_RUNNER_ID (Plan 57.D.4 — CI-матрица из нескольких раннеров).

nova bench runner-branch

Возвращает bench-history, если переменная окружения не задана, иначе bench-history-<id>.

nova bench history-anomalies

Обнаружение точек изменения (changepoints) в рядах медианных значений за историю через алгоритм PELT (Plan 57.E.5). Идентифицирует режимы с отклонением ≥5%.

nova bench history-anomalies [--branch BRANCH] [--format text|json]
ФлагПо умолчаниюОписание
--branchauto (с учётом NOVA_BENCH_RUNNER_ID)Ветка истории
--formattexttext или json

nova bench remote

Распределённая координация бенчмарков по SSH (Plan 57.F.1).

nova bench remote <SUBCOMMAND>
nova bench remote list

Список remotes из ~/.nova-bench-remotes.toml.

nova bench remote list [--config PATH]

--config переопределяется через env NOVA_BENCH_REMOTES.

nova bench remote ping

SSH-проверка доступности одного remote.

nova bench remote ping NAME [--config PATH]
nova bench remote run

Параллельный bench на N remotes; сбор результатов.

nova bench remote run BENCH [--remotes LIST] [--gather-into DIR] [--sha SHA] [--config PATH]
ФлагПо умолчаниюОписание
BENCHПуть к .nv файлу (относительно корня репозитория на remote)
--remotesallИмена через запятую или all
--gather-intoremote-resultsКуда складывать JSON от каждого remote
--sha SHAОпциональный git SHA для checkout перед bench

nova bench corpus

Измерение времени компиляции по проходам для файла(ов) корпуса — Plan 57.C.8. Заворачивает nova build с NOVA_PERF_TIMER=1, парсит __PERF__ маркеры.

nova bench corpus PATH [--json] [--html PATH] [--echarts-url URL]
                       [--mode release|dev] [--toolchain auto|clang|msvc]
                       [--gc boehm|malloc]
ФлагПо умолчаниюОписание
PATH.nv файл или директория
--jsonoffJSON-вывод (вместо таблицы)
--html PATHHTML compiler-perf dashboard (Plan 57.D.5)
--echarts-urlhttps://cdn.jsdelivr.net/...Свой URL echarts (offline)
--moderelease
--toolchainauto
--gcboehm

nova bench history-add

Дописать JSON результата в orphan-ветку истории (Plan 57.A.1).

nova bench history-add RESULT [--branch BRANCH] [--push] [--remote NAME] [--dry-run]
ФлагПо умолчаниюОписание
RESULTJSON из nova bench run --out
--branchautoOrphan-ветка (bench-history по умолчанию)
--pushoffОтправить (push) после коммита
--remoteoriginИмя remote при --push
--dry-runoffПоказать, что было бы, без коммита

nova bench history-list

Список записей в ветке истории (сначала новые).

nova bench history-list [--branch BRANCH]

nova bench history-squash

Сжатие старых записей по политике хранения (Plan 57.C.6 — рекомендуется ежегодное сжатие).

nova bench history-squash --before-date YYYY-MM-DD [--branch BRANCH]
                          [--push] [--remote NAME] [--dry-run]
ФлагПо умолчаниюОписание
--before-date— (обязательный)Сжать всё старше этой даты UTC
--branchauto
--pushoff
--remoteorigin
--dry-runoffПоказать что было бы удалено

nova bench dashboard

Статический HTML-дашборд из истории (Plan 57.A.2).

nova bench dashboard [--history-branch BRANCH] [--out DIR] [--max-entries N] [--echarts-url URL]
ФлагПо умолчаниюОписание
--history-branchautoВетка истории
--outdashboardКаталог вывода
--max-entries200Максимум записей (сначала новые)
--echarts-urljsdelivr URLСвой URL echarts (offline = локально)

Генерирует index.html + bench-<safe>.html на каждый bench + data.json.

Семейство nova bench также открывает диагностические подкоманды field-cache (реальное измерение по настенным часам влияния field-cache из Plan 123), cpu-instr-check, membw-check и callgrind-check. Флаги — через nova bench <sub> --help.


nova consume-analyze

Анализатор покрытия consume-типов (Plan 100.8 / D7). Сканирует файл или директорию, собирает все consume-типизированные биндинги и сообщает, сколько из них покрыто через consume-методы (Cleanup.@cleanup, D188) или defer. Полезно как CI-проверка гигиены.

nova consume-analyze PATH [--format human|json] [--fail-on-uncovered]
ФлагПо умолчаниюОписание
PATH.nv файл или директория для анализа
--formathumanhuman или json
--fail-on-uncoveredoffНенулевой код выхода при наличии непокрытого consume-биндинга (CI-проверка)

Коды выхода:

КодЗначение
0Все consume-биндинги покрыты
1Найдены непокрытые биндинги
2Ошибка использования

Переменные окружения

VarИспользуется вЭффект
NOVA_CODEGEN(зарезервировано)Переопределяет путь к бинарнику nova-codegen
NOVA_MONO_DEPTHbuild, test, test-build, benchЛимит мономорфизационных инстанциаций (по умолчанию 500)
NOVA_REACH_DCEbuild, test, test-buildReachability-codegen DCE (Plan 159, D283). Не задана / ≠0ON (по умолчанию): в C эмитится только достижимое от main. =0OFF: байт-идентичное до-159 поведение (эмитить всё) — запасной вариант для диагностики чрезмерного вырезания
NOVA_HOMEadd, build (git-deps)Корень кэша git-зависимостей; по умолчанию ~/.nova (кэш в <NOVA_HOME>/git, глобальный конфиг прокси в <NOVA_HOME>/config.toml)
NOVA_OFFLINEadd, build (git-deps)=1 → запрет сети (clone/fetch); сборка только из готового кэша
NOVA_PKG_PROXYadd, build (git-deps)HTTP(S)-прокси для скачивания пакетов (План 233 §1). Слоями, первый существующий выигрывает: (1) env NOVA_PKG_PROXY, либо стандартные HTTPS_PROXY/HTTP_PROXY (git уважает их сам); (2) [net] proxy = "..." в НЕкоммитимом nova.override.toml рядом с nova.toml; (3) [net] proxy = "..." в глобальном ~/.nova/config.toml (либо <NOVA_HOME>/config.toml). В коммитимом nova.toml НЕ поддержан — прокси это свойство машины/CI, не пакета
NOVA_SMT_BACKENDcontractsSMT-бэкенд (trivial, z3)
NOVA_PERF_TIMERbench corpus (auto-set)Включает __PERF__ маркеры в компиляторе
NOVA_PERF_TIMER_AGGREGATEbench corpusАгрегирует __PERF__ по проходам
NOVA_BENCH_RUNNER_IDbench history-*, runner-branchCI-матрица из нескольких раннеров; используется в имени ветки
NOVA_BENCH_REMOTESbench remoteПереопределяет путь к .nova-bench-remotes.toml
NOVA_BENCH_FILTERbench run (auto-set)Пробрасывается в bench-процесс
NOVA_BENCH_SAMPLESbench run (auto-set)Переопределяет число замеров
NOVA_BENCH_WARMUP_NSbench run (auto-set)Прогрев в наносекундах
NOVA_BENCH_TIME_BUDGET_NSbench run (auto-set)Бюджет времени в наносекундах
NOVA_BENCH_HEAP_SAMPLE_MSbench run --profile heapИнтервал замеров в мс
NOVA_BENCH_GC_TRACEbench run --profile gcВключает трассировку GC
NOVA_AI_PROVIDERbench diff --explainAI-провайдер (anthropic, openai, …)
NOVA_AI_MODELbench diff --explainПереопределяет модель
NOVA_AI_API_KEYbench diff --explainAPI-ключ (или ~/.nova-ai.toml)
NOVA_C_COMPILERbench reproРеальный путь к компилятору (фиксируется в метаданных)
NOVA_SHAbench repro (compile-time option_env!)Git SHA nova бинарника
NO_COLORglobalОтключить ANSI цвета
CLICOLORglobal=0 → отключить
CLICOLOR_FORCEglobal=1 → принудительно включить
CIglobal=true → отключить цвета
TERMglobal=dumb → отключить цвета
TEMPWindowsВременная директория для артефактов build/test
TMPDIRUnixТо же

Migration-бинарники

Отдельные разовые инструменты в nova-cli/src/bin/. Сохраняются в репозитории как справочник для будущих планов атомарного API-rename.

migrate_plan60

Лексерная миграция size-аксессоров в стиле полей в форму методов (D117 / Plan 60):

expr.len      → expr.len()
expr.is_empty → expr.is_empty()
expr.byte_len → expr.byte_len()
expr.cap      → expr.capacity()
expr.capacity → expr.capacity()

Условия пропуска: предыдущий значимый токен == = (присваивание значения метода: let f = arr.len).

migrate_plan60 [--apply] [--dry-run] [--md] [--paths DIR...]
ФлагПо умолчаниюОписание
--dry-run(по умолчанию)Только показать diff
--applyoffРеально записать
--mdoffВключить .md файлы (переписывание внутри ```nova / ```nv блоков)
--paths DIR...std/, nova_tests/, examples/Список директорий

Переписывание на уровне токенов — комментарии / пробелы / форматирование сохраняются 1:1.

migrate_plan65

Лексерная миграция Time.after(<lit>)ChanReader.close_after(Duration.from_*(<lit>)) (Plan 65 AD11):

Time.after(<INT>)    → ChanReader.close_after(Duration.from_millis(<INT>))
Time.after(<FLOAT>)  → ChanReader.close_after(Duration.from_secs_f64(<FLOAT>))
Time.after(<expr>)   → left as-is + // MIGRATE_MANUAL: Plan 65 — non-literal arg
migrate_plan65 [--apply] [--dry-run] [--md] [--paths DIR...]

Exit codes (специальный набор):

КодЗначение
0Изменений не требуется (idempotent)
1Эмитированы ручные маркеры — CI-проверка провалена
2Изменения применены (или были бы применены в dry-run)

С учётом токенов через nova_codegen::lexer — пропускает строки и комментарии естественным образом.


Связанные документы